]> granicus.if.org Git - vim/commitdiff
patch 9.0.0903: key code checker doesn't check modifyOtherKeys resource v9.0.0903
authorBram Moolenaar <Bram@vim.org>
Fri, 18 Nov 2022 21:20:25 +0000 (21:20 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 18 Nov 2022 21:20:25 +0000 (21:20 +0000)
Problem:    Key code checker doesn't check modifyOtherKeys resource.
Solution:   Request the modifyOtherKeys resource value.  Drop resource DCS
            responses.

src/term.c
src/testdir/keycode_check.vim
src/version.c

index 5377dd2a2eeee58deb530189522a4efd5b5014ff..61c2311fa38903740c2c025b50bc2880751e403a 100644 (file)
@@ -5244,6 +5244,9 @@ handle_osc(char_u *tp, char_u *argp, int len, char_u *key_name, int *slen)
  * {flag} can be '0' or '1'
  * {tail} can be Esc>\ or STERM
  *
+ * Check for resource response from xterm (and drop it):
+ * {lead}{flag}+R<hex bytes>=<value>{tail}
+ *
  * Check for cursor shape response from xterm:
  * {lead}1$r<digit> q{tail}
  *
@@ -5260,7 +5263,8 @@ handle_dcs(char_u *tp, char_u *argp, int len, char_u *key_name, int *slen)
     j = 1 + (tp[0] == ESC);
     if (len < j + 3)
        i = len; // need more chars
-    else if ((argp[1] != '+' && argp[1] != '$') || argp[2] != 'r')
+    else if ((argp[1] != '+' && argp[1] != '$')
+           || (argp[2] != 'r' && argp[2] != 'R'))
        i = 0; // no match
     else if (argp[1] == '+')
        // key code response
@@ -5269,7 +5273,8 @@ handle_dcs(char_u *tp, char_u *argp, int len, char_u *key_name, int *slen)
            if ((tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')
                    || tp[i] == STERM)
            {
-               if (i - j >= 3)
+               // handle a key code response, drop a resource response
+               if (i - j >= 3 && argp[2] == 'r')
                    got_code_from_term(tp + j, i);
                key_name[0] = (int)KS_EXTRA;
                key_name[1] = (int)KE_IGNORE;
@@ -5674,9 +5679,10 @@ check_termcode(
 
            // Check for key code response from xterm,
            // starting with <Esc>P or DCS
-           else if ((check_for_codes || rcs_status.tr_progress == STATUS_SENT)
-                   && ((tp[0] == ESC && len >= 2 && tp[1] == 'P')
-                       || tp[0] == DCS))
+           // It would only be needed with this condition:
+           //      (check_for_codes || rcs_status.tr_progress == STATUS_SENT)
+           // Now this is always done so that DCS codes don't mess up things.
+           else if ((tp[0] == ESC && len >= 2 && tp[1] == 'P') || tp[0] == DCS)
            {
                if (handle_dcs(tp, argp, len, key_name, &slen) == FAIL)
                    return -1;
index fe854d1b3d38ac635b045ad56ecc73322c431d63..de15180e96a5e2a7bbf0c2647ea2bcd1ffde252f 100644 (file)
@@ -134,7 +134,7 @@ def ActionList()
   endif
   sort(terms)
 
-  var items = ['protocol', 'version', 'status']
+  var items = ['protocol', 'version', 'status', 'resource']
              + key_entries->copy()->map((_, v) => v[1])
 
   # For each terminal compute the needed width, add two.
@@ -198,8 +198,9 @@ def DoTerm(name: string)
   if proto == 1
     &t_TI = ""
   elseif proto == 2
-    # Enable modifyOtherKeys level 2 - no status is reported
-    &t_TI = "\<Esc>[>4;2m"
+    # Enable modifyOtherKeys level 2
+    # Request the resource value: DCS + Q modifyOtherKeys ST
+    &t_TI = "\<Esc>[>4;2m" .. "\<Esc>P+Q6d6f646966794f746865724b657973\<Esc>\\"
     proto_name = 'mok2'
   elseif proto == 3
     # Enable Kitty keyboard protocol and request the status
@@ -217,9 +218,14 @@ def DoTerm(name: string)
   # Pattern that matches the line with the version response.
   const version_pattern = "\<Esc>\\[>\\d\\+;\\d\\+;\\d*c"
 
+  # Pattern that matches the resource value response:
+  #    DCS 1 + R Pt ST    valid
+  #    DCS 0 + R Pt ST    invalid
+  const resource_pattern = "\<Esc>P[01]+R.*\<Esc>\\\\"
+
   # Pattern that matches the line with the status.  Currently what terminals
   # return for the Kitty keyboard protocol.
-  const status_pattern = "\<Esc>\\[?\\d\\+u"
+  const kitty_status_pattern = "\<Esc>\\[?\\d\\+u"
 
   ch_logfile('keylog', 'w')
 
@@ -244,6 +250,7 @@ def DoTerm(name: string)
       endfor
     endif
     if reltime(startTime)->reltimefloat() > 3
+      # break out after three seconds
       break
     endif
   endwhile
@@ -257,18 +264,39 @@ def DoTerm(name: string)
   keycodes[name]['protocol'] = proto_name
   keycodes[name]['version'] = ''
   keycodes[name]['status'] = ''
+  keycodes[name]['resource'] = ''
 
   # Check the log file for a status and the version response
   ch_logfile('', '')
   var log = readfile('keylog')
   delete('keylog')
+
   for line in log
     if line =~ 'raw key input'
       var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '')
+
+      # Check for resource value response
+      if code =~ resource_pattern
+       var resource = substitute(code, '.*\(' .. resource_pattern .. '\).*', '\1', '')
+       # use the value as the resource, "=30" means zero
+       resource = substitute(resource, '.*\(=\p\+\).*', '\1', '')
+
+       if keycodes[name]['resource'] != ''
+         echomsg 'Another resource found after ' .. keycodes[name]['resource']
+       endif
+       keycodes[name]['resource'] = resource
+      endif
+
       # Check for kitty keyboard protocol status
-      if code =~ status_pattern
-       var status = substitute(code, '.*\(' .. status_pattern .. '\).*', '\1', '')
-       keycodes[name]['status'] = Literal2hex(status)
+      if code =~ kitty_status_pattern
+       var status = substitute(code, '.*\(' .. kitty_status_pattern .. '\).*', '\1', '')
+       # use the response itself as the status
+       status = Literal2hex(status)
+
+       if keycodes[name]['status'] != ''
+         echomsg 'Another status found after ' .. keycodes[name]['status']
+       endif
+       keycodes[name]['status'] = status
       endif
 
       if code =~ version_pattern
@@ -282,13 +310,23 @@ def DoTerm(name: string)
   echo "For Alt to work you may need to press the Windows/Super key as well"
   echo "When a key press doesn't get to Vim (e.g. when using Alt) press x"
 
+  # The log of ignored typeahead is left around for debugging, start with an
+  # empty file here.
+  delete('keylog-ignore')
+
   for entry in key_entries
     # Consume any typeahead.  Wait a bit for any responses to arrive.
-    sleep 100m
-    while getchar(1)
-      getchar()
+    ch_logfile('keylog-ignore', 'a')
+    while 1
       sleep 100m
+      if !getchar(1)
+       break
+      endif
+      while getchar(1)
+       getchar()
+      endwhile
     endwhile
+    ch_logfile('', '')
 
     ch_logfile('keylog', 'w')
     echo $'Press the {entry[0]} key (q to quit):'
@@ -297,13 +335,9 @@ def DoTerm(name: string)
     if r == 'q'
       break
     endif
+
     log = readfile('keylog')
-    if entry[1] == 'Tab'
-# keep a copy
-rename('keylog', 'keylog-tab')
-    else
-      delete('keylog')
-    endif
+    delete('keylog')
     if len(log) < 2
       echoerr 'failed to read result'
       return
@@ -321,7 +355,7 @@ rename('keylog', 'keylog-tab')
        code = substitute(code, cappat, '', 'g')
 
        # Remove any kitty status reply
-       code = substitute(code, status_pattern, '', 'g')
+       code = substitute(code, kitty_status_pattern, '', 'g')
        if code == ''
          continue
        endif
index ccf1d80b54af68d6dcca3b2ae7fd77a7c9b7db97..e0ba0ab9732be36d3b0641d157fc577360f4f9bb 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    903,
 /**/
     902,
 /**/