changeset: 7075:ec6530cb0a5a
user:      Kevin McCarthy <ke...@8t8.us>
date:      Thu Jun 01 15:17:01 2017 -0700
link:      http://dev.mutt.org/hg/mutt/rev/ec6530cb0a5a

Change km_dokey() to return -2 on a timeout/sigwinch.

In some cases, such as tag-prefix or _mutt_enter_string(), it is
desirable to be able to distinguish between a timeout/sigwinch event
and an input error/abort/ctrl-g.

changeset: 7076:f26adb2b0543
user:      Kevin McCarthy <ke...@8t8.us>
date:      Thu Jun 01 15:17:05 2017 -0700
link:      http://dev.mutt.org/hg/mutt/rev/f26adb2b0543

Fix tag-prefix to not abort on $timeout.

If $timeout is set very low, then it can cancel the tag-prefix before
the user has time to press the desired command.

Change the code to set the tag flag, and then recontinue with normal
event processing instead.  Cancel on an abort, but continue with a timeout.

Thanks to Lauri Tirkkonen for reporting the issue.

diffs (294 lines):

diff -r 152d548c1bcf -r f26adb2b0543 curs_main.c
--- a/curs_main.c       Thu Jun 01 13:55:07 2017 -0700
+++ b/curs_main.c       Thu Jun 01 15:17:05 2017 -0700
@@ -580,7 +580,11 @@
 
   FOREVER
   {
-    tag = 0; /* clear the tag-prefix */
+    /* Clear the tag prefix unless we just started it.  Don't clear
+     * the prefix on a timeout (op==-2), but do clear on an abort (op==-1)
+     */
+    if (tag && op != OP_TAG_PREFIX && op != OP_TAG_PREFIX_COND && op != -2)
+      tag = 0;
 
     /* check if we need to resort the index because just about
      * any 'op' below could do mutt_enter_command(), either here or
@@ -664,13 +668,20 @@
        do_buffy_notify = 1;
     }
 
-    if (op != -1)
+    if (op >= 0)
       mutt_curs_set (0);
 
     if (menu->menu == MENU_MAIN)
     {
       index_menu_redraw (menu);
 
+      /* give visual indication that the next command is a tag- command */
+      if (tag)
+      {
+        mutt_window_mvaddstr (MuttMessageWindow, 0, 0, "tag-");
+        mutt_window_clrtoeol (MuttMessageWindow);
+      }
+
       if (menu->current < menu->max)
         menu->oldcurrent = menu->current;
       else
@@ -705,14 +716,27 @@
 
       dprint(4, (debugfile, "mutt_index_menu[%d]: Got op %d\n", __LINE__, op));
 
-      if (op == -1)
-       continue; /* either user abort or timeout */
+      /* either user abort or timeout */
+      if (op < 0)
+      {
+        if (tag)
+          mutt_window_clearline (MuttMessageWindow, 0);
+        continue;
+      }
 
       mutt_curs_set (1);
 
       /* special handling for the tag-prefix function */
-      if (op == OP_TAG_PREFIX)
+      if (op == OP_TAG_PREFIX || op == OP_TAG_PREFIX_COND)
       {
+        /* A second tag-prefix command aborts */
+        if (tag)
+        {
+          tag = 0;
+          mutt_window_clearline (MuttMessageWindow, 0);
+          continue;
+        }
+
        if (!Context)
        {
          mutt_error _("No mailbox is open.");
@@ -721,55 +745,23 @@
 
        if (!Context->tagged)
        {
-         mutt_error _("No tagged messages.");
+          if (op == OP_TAG_PREFIX)
+            mutt_error _("No tagged messages.");
+          else if (op == OP_TAG_PREFIX_COND)
+          {
+            mutt_flush_macro_to_endcond ();
+            mutt_message  _("Nothing to do.");
+          }
          continue;
        }
-       tag = 1;
 
-       /* give visual indication that the next command is a tag- command */
-       mutt_window_mvaddstr (MuttMessageWindow, 0, 0, "tag-");
-       mutt_window_clrtoeol (MuttMessageWindow);
-
-       /* get the real command */
-       if ((op = km_dokey (MENU_MAIN)) == OP_TAG_PREFIX)
-       {
-         /* abort tag sequence */
-          mutt_window_clearline (MuttMessageWindow, 0);
-         continue;
-       }
+        /* get the real command */
+        tag = 1;
+        continue;
       }
       else if (option (OPTAUTOTAG) && Context && Context->tagged)
        tag = 1;
 
-      if (op == OP_TAG_PREFIX_COND)
-      {
-       if (!Context)
-       {
-         mutt_error _("No mailbox is open.");
-         continue;
-       }
-
-       if (!Context->tagged)
-       {
-         mutt_flush_macro_to_endcond ();
-         mutt_message  _("Nothing to do.");
-         continue;
-       }
-       tag = 1;
-
-       /* give visual indication that the next command is a tag- command */
-       mutt_window_mvaddstr (MuttMessageWindow, 0, 0, "tag-");
-       mutt_window_clrtoeol (MuttMessageWindow);
-
-       /* get the real command */
-       if ((op = km_dokey (MENU_MAIN)) == OP_TAG_PREFIX)
-       {
-         /* abort tag sequence */
-         mutt_window_clearline (MuttMessageWindow, 0);
-         continue;
-       }
-      }
-
       mutt_clear_error ();
     }
     else
@@ -1342,7 +1334,7 @@
          * set CurrentMenu incorrectly when we return back to the index menu. 
*/
         menu->menu = MENU_MAIN;
 
-        if ((op = mutt_display_message (CURHDR)) == -1)
+        if ((op = mutt_display_message (CURHDR)) < 0)
        {
          unset_option (OPTNEEDRESORT);
          break;
diff -r 152d548c1bcf -r f26adb2b0543 enter.c
--- a/enter.c   Thu Jun 01 13:55:07 2017 -0700
+++ b/enter.c   Thu Jun 01 15:17:05 2017 -0700
@@ -315,9 +315,9 @@
     }
     mutt_refresh ();
 
-    if ((ch = km_dokey (MENU_EDITOR)) == -1)
+    if ((ch = km_dokey (MENU_EDITOR)) < 0)
     {
-      rv = SigWinch ? 1 : -1;
+      rv = (SigWinch && ch == -2) ? 1 : -1;
       goto bye;
     }
 
diff -r 152d548c1bcf -r f26adb2b0543 keymap.c
--- a/keymap.c  Thu Jun 01 13:55:07 2017 -0700
+++ b/keymap.c  Thu Jun 01 15:17:05 2017 -0700
@@ -418,6 +418,7 @@
  *     >0              function to execute
  *     OP_NULL         no function bound to key sequence
  *     -1              error occurred while reading input
+ *     -2              a timeout or sigwinch occurred
  */
 int km_dokey (int menu)
 {
@@ -470,7 +471,7 @@
 
     LastKey = tmp.ch;
     if (LastKey < 0)
-      return -1;
+      return LastKey;
 
     /* do we have an op already? */
     if (tmp.op)
diff -r 152d548c1bcf -r f26adb2b0543 menu.c
--- a/menu.c    Thu Jun 01 13:55:07 2017 -0700
+++ b/menu.c    Thu Jun 01 15:17:05 2017 -0700
@@ -979,19 +979,30 @@
       unset_option (OPTMENUCALLER);
       return OP_NULL;
     }
-    
-    
+
+    /* Clear the tag prefix unless we just started it.  Don't clear
+     * the prefix on a timeout (i==-2), but do clear on an abort (i==-1)
+     */
+    if (menu->tagprefix &&
+        i != OP_TAG_PREFIX && i != OP_TAG_PREFIX_COND && i != -2)
+      menu->tagprefix = 0;
+
     mutt_curs_set (0);
 
     if (menu_redraw (menu) == OP_REDRAW)
       return OP_REDRAW;
-    
+
+    /* give visual indication that the next command is a tag- command */
+    if (menu->tagprefix)
+    {
+      mutt_window_mvaddstr (menu->messagewin, 0, 0, "tag-");
+      mutt_window_clrtoeol (menu->messagewin);
+    }
+
     menu->oldcurrent = menu->current;
 
 
     /* move the cursor out of the way */
-    
-    
     if (option (OPTARROWCURSOR))
       mutt_window_move (menu->indexwin, menu->current - menu->top + 
menu->offset, 2);
     else if (option (OPTBRAILLEFRIENDLY))
@@ -1001,21 +1012,25 @@
                         menu->indexwin->cols - 1);
 
     mutt_refresh ();
-    
+
     /* try to catch dialog keys before ops */
     if (menu->dialog && menu_dialog_dokey (menu, &i) == 0)
       return i;
-                   
+
     i = km_dokey (menu->menu);
     if (i == OP_TAG_PREFIX || i == OP_TAG_PREFIX_COND)
     {
+      if (menu->tagprefix)
+      {
+        menu->tagprefix = 0;
+        mutt_window_clearline (menu->messagewin, 0);
+        continue;
+      }
+
       if (menu->tagged)
       {
-        mutt_window_mvaddstr (menu->messagewin, 0, 0, "Tag-");
-       mutt_window_clrtoeol (menu->messagewin);
-       i = km_dokey (menu->menu);
        menu->tagprefix = 1;
-        mutt_window_clearline (menu->messagewin, 0);
+        continue;
       }
       else if (i == OP_TAG_PREFIX)
       {
@@ -1031,8 +1046,6 @@
     }
     else if (menu->tagged && option (OPTAUTOTAG))
       menu->tagprefix = 1;
-    else
-      menu->tagprefix = 0;
 
     mutt_curs_set (1);
 
@@ -1045,8 +1058,12 @@
     }
 #endif
 
-    if (i == -1)
+    if (i < 0)
+    {
+      if (menu->tagprefix)
+        mutt_window_clearline (menu->messagewin, 0);
       continue;
+    }
 
     if (!menu->dialog)
       mutt_clear_error ();
diff -r 152d548c1bcf -r f26adb2b0543 pager.c
--- a/pager.c   Thu Jun 01 13:55:07 2017 -0700
+++ b/pager.c   Thu Jun 01 15:17:05 2017 -0700
@@ -2013,7 +2013,7 @@
       OldHdr = NULL;
       
     ch = km_dokey (MENU_PAGER);
-    if (ch != -1)
+    if (ch >= 0)
       mutt_clear_error ();
     mutt_curs_set (1);
 
@@ -2050,7 +2050,7 @@
       continue;
     }
 #endif
-    if (ch == -1)
+    if (ch < 0)
     {
       ch = 0;
       continue;

Reply via email to