ui/ncurses: Call widget process_key handlers first
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>
Thu, 21 Jul 2016 03:03:28 +0000 (13:03 +1000)
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>
Thu, 21 Jul 2016 05:39:37 +0000 (15:39 +1000)
Adding KEY_LEFT and KEY_RIGHT brought to light the problem that
widgetset_process_keys() may handle keystrokes that would have also been
handled by a widget's process_keys function. In particular the cursor
in a textbox widget could no longer be moved with the left/right keys.

This updates widgetset_process_keys() to call the focussed widget's
process_keys function before handling the key in any other way. All of
the widget process_keys functions correctly return false if the key is
not relevant to the widget except for textbox_process_key() which is
updated to ignore the main navigational keys.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
ui/ncurses/nc-widgets.c

index 8f8816ecaa7c472b33fe9c52d0e0305556b6c621..7dc2df3f1d1fc2138c001b7511bac6bfc0e8041a 100644 (file)
@@ -337,6 +337,14 @@ static bool textbox_process_key(
        case KEY_DC:
                form_driver(form, REQ_DEL_CHAR);
                break;
        case KEY_DC:
                form_driver(form, REQ_DEL_CHAR);
                break;
+       case '\t':
+       case KEY_BTAB:
+       case KEY_UP:
+       case KEY_DOWN:
+       case KEY_PPAGE:
+       case KEY_NPAGE:
+               /* Don't catch navigational keys */
+               return false;
        default:
                form_driver(form, key);
                break;
        default:
                form_driver(form, key);
                break;
@@ -1110,6 +1118,12 @@ bool widgetset_process_key(struct nc_widgetset *set, int key)
        field = current_field(set->form);
        assert(field);
 
        field = current_field(set->form);
        assert(field);
 
+       widget = field_userptr(field);
+
+       if (widget->process_key)
+               if (widget->process_key(widget, set->form, key))
+                       return true;
+
        tab = false;
 
        /* handle field change events */
        tab = false;
 
        /* handle field change events */
@@ -1136,7 +1150,6 @@ bool widgetset_process_key(struct nc_widgetset *set, int key)
                break;
        }
 
                break;
        }
 
-       widget = field_userptr(field);
        if (req) {
                widget_focus_change(widget, field, false);
                form_driver(set->form, req);
        if (req) {
                widget_focus_change(widget, field, false);
                form_driver(set->form, req);
@@ -1161,10 +1174,7 @@ bool widgetset_process_key(struct nc_widgetset *set, int key)
                return true;
        }
 
                return true;
        }
 
-       if (!widget->process_key)
-               return false;
-
-       return widget->process_key(widget, set->form, key);
+       return false;
 }
 
 static int widgetset_destructor(void *ptr)
 }
 
 static int widgetset_destructor(void *ptr)