]> granicus.if.org Git - vim/commitdiff
patch 8.2.3727: in a gnome terminal keys are recognized as mouse events v8.2.3727
authorBram Moolenaar <Bram@vim.org>
Fri, 3 Dec 2021 13:20:29 +0000 (13:20 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 3 Dec 2021 13:20:29 +0000 (13:20 +0000)
Problem:    In a gnome terminal keys are recognized as mouse events.
Solution:   Only recognize DEC mouse events when four numbers are following.
            (closes #9256)

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

index eb4dffaac38d8ad23852a725693e70ed1351ad83..c20da0c336c7ed0994b065e6a17e8650adae2bbf 100644 (file)
@@ -5412,6 +5412,8 @@ check_termcode(
                if (STRNCMP(termcodes[idx].code, tp,
                                     (size_t)(slen > len ? len : slen)) == 0)
                {
+                   int     looks_like_mouse_start = FALSE;
+
                    if (len < slen)             // got a partial sequence
                        return -1;              // need to get more chars
 
@@ -5434,15 +5436,48 @@ check_termcode(
                            }
                    }
 
-                   // The mouse termcode "ESC [" is also the prefix of
-                   // "ESC [ I" (focus gained).  Only use it when there is
-                   // no other match.  Do use it when a digit is following to
-                   // avoid waiting for more bytes.
                    if (slen == 2 && len > 2
                            && termcodes[idx].code[0] == ESC
-                           && termcodes[idx].code[1] == '['
-                           && !isdigit(tp[2]))
+                           && termcodes[idx].code[1] == '[')
+                   {
+                       // The mouse termcode "ESC [" is also the prefix of
+                       // "ESC [ I" (focus gained) and other keys.  Check some
+                       // more bytes to find out.
+                       if (!isdigit(tp[2]))
+                       {
+                           // ESC [ without number following: Only use it when
+                           // there is no other match.
+                           looks_like_mouse_start = TRUE;
+                       }
+                       else if (termcodes[idx].name[0] == KS_DEC_MOUSE)
+                       {
+                           char_u  *nr = tp + 2;
+                           int     count = 0;
+
+                           // If a digit is following it could be a key with
+                           // modifier, e.g., ESC [ 1;2P.  Can be confused
+                           // with DEC_MOUSE, which requires four numbers
+                           // following.  If not then it can't be a DEC_MOUSE
+                           // code.
+                           for (;;)
+                           {
+                               ++count;
+                               (void)getdigits(&nr);
+                               if (nr >= tp + len)
+                                   return -1;  // partial sequence
+                               if (*nr != ';')
+                                   break;
+                               ++nr;
+                               if (nr >= tp + len)
+                                   return -1;  // partial sequence
+                           }
+                           if (count < 4)
+                               continue;       // no match
+                       }
+                   }
+                   if (looks_like_mouse_start)
                    {
+                       // Only use it when there is no other match.
                        if (mouse_index_found < 0)
                            mouse_index_found = idx;
                    }
index ba02584572d4574687c75fb2744b54167af609e8..887093c8070a3e9bf95c927c96ede9af5f97b40a 100644 (file)
@@ -2039,6 +2039,28 @@ func Test_modifyOtherKeys_no_mapping()
   set timeoutlen&
 endfunc
 
+" Check that when DEC mouse codes are recognized a special key is handled.
+func Test_ignore_dec_mouse()
+
+  new
+  let save_mouse = &mouse
+  let save_term = &term
+  let save_ttymouse = &ttymouse
+  call test_override('no_query_mouse', 1)
+  set mouse=a term=gnome ttymouse=
+
+  execute "set <xF1>=\<Esc>[1;*P"
+  nnoremap <S-F1> agot it<Esc>
+  call feedkeys("\<Esc>[1;2P", 'Lx!')
+  call assert_equal('got it', getline(1))
+
+  let &mouse = save_mouse
+  let &term = save_term
+  let &ttymouse = save_ttymouse
+  call test_override('no_query_mouse', 0)
+  bwipe!
+endfunc
+
 func RunTest_mapping_shift(key, func)
   call setline(1, '')
   if a:key == '|'
index 942393992e23f116a36782d2172b97dd51c55583..184b3772a0312b321c72be609a938d259e22ba9f 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3727,
 /**/
     3726,
 /**/