[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55952] trunk/blender/source/blender/ editors/interface: fix [#34936] Unable to select items using only the arrow keys

Campbell Barton ideasman42 at gmail.com
Thu Apr 11 04:28:34 CEST 2013


Revision: 55952
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55952
Author:   campbellbarton
Date:     2013-04-11 02:28:34 +0000 (Thu, 11 Apr 2013)
Log Message:
-----------
fix [#34936] Unable to select items using only the arrow keys

ignore small mouse motions for menu/search-box after using the keyboard to navigate.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/editors/interface/interface_intern.h

Modified: trunk/blender/source/blender/editors/interface/interface_handlers.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_handlers.c	2013-04-11 02:23:45 UTC (rev 55951)
+++ trunk/blender/source/blender/editors/interface/interface_handlers.c	2013-04-11 02:28:34 UTC (rev 55952)
@@ -84,11 +84,19 @@
 /* support dragging toggle buttons */
 #define USE_DRAG_TOGGLE
 
+/* so we can avoid very small mouse-moves from jumping away from keyboard navigation [#34936] */
+#define USE_KEYNAV_LIMIT
+
 /* proto */
 static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to);
 static void ui_add_link(bContext *C, uiBut *from, uiBut *to);
 static int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, const wmEvent *event);
 
+#ifdef USE_KEYNAV_LIMIT
+static void ui_mouse_motion_keynav_init(struct uiKeyNavLock *keynav, const wmEvent *event);
+static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEvent *event);
+#endif
+
 /***************** structs and defines ****************/
 
 #define BUTTON_TOOLTIP_DELAY        0.500
@@ -96,6 +104,8 @@
 #define MENU_SCROLL_INTERVAL        0.1
 #define BUTTON_AUTO_OPEN_THRESH     0.3
 #define BUTTON_MOUSE_TOWARDS_THRESH 1.0
+/* pixels to move the cursor to get out of keyboard navigation */
+#define BUTTON_KEYNAV_PX_LIMIT      4
 
 typedef enum uiButtonActivateType {
 	BUTTON_ACTIVATE_OVER,
@@ -2118,12 +2128,20 @@
 	bool changed = false, inbox = false, update = false;
 
 	switch (event->type) {
-		case WHEELUPMOUSE:
-		case WHEELDOWNMOUSE:
 		case MOUSEMOVE:
 		case MOUSEPAN:
-			if (data->searchbox)
+			if (data->searchbox) {
+#ifdef USE_KEYNAV_LIMIT
+				if ((event->type == MOUSEMOVE) && ui_mouse_motion_keynav_test(&block->handle->keynav_state, event)) {
+					/* pass */
+				}
+				else {
+					ui_searchbox_event(C, data->searchbox, but, event);
+				}
+#else
 				ui_searchbox_event(C, data->searchbox, but, event);
+#endif
+			}
 			
 			break;
 		case RIGHTMOUSE:
@@ -2194,8 +2212,12 @@
 				                 event->shift, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
 				retval = WM_UI_HANDLER_BREAK;
 				break;
+			case WHEELDOWNMOUSE:
 			case DOWNARROWKEY:
 				if (data->searchbox) {
+#ifdef USE_KEYNAV_LIMIT
+					ui_mouse_motion_keynav_init(&block->handle->keynav_state, event);
+#endif
 					ui_searchbox_event(C, data->searchbox, but, event);
 					break;
 				}
@@ -2205,8 +2227,12 @@
 				                 event->shift, STRCUR_JUMP_ALL);
 				retval = WM_UI_HANDLER_BREAK;
 				break;
+			case WHEELUPMOUSE:
 			case UPARROWKEY:
 				if (data->searchbox) {
+#ifdef USE_KEYNAV_LIMIT
+					ui_mouse_motion_keynav_init(&block->handle->keynav_state, event);
+#endif
 					ui_searchbox_event(C, data->searchbox, but, event);
 					break;
 				}
@@ -6727,6 +6753,26 @@
 	return menu->dotowards;
 }
 
+#ifdef USE_KEYNAV_LIMIT
+static void ui_mouse_motion_keynav_init(struct uiKeyNavLock *keynav, const wmEvent *event)
+{
+	keynav->is_keynav = true;
+	copy_v2_v2_int(keynav->event_xy, &event->x);
+}
+/**
+ * Return true if keyinput isn't blocking mouse-motion,
+ * or if the mouse-motion is enough to disable keyinput.
+ */
+static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEvent *event)
+{
+	if (keynav->is_keynav && (len_manhattan_v2v2_int(keynav->event_xy, &event->x) > BUTTON_KEYNAV_PX_LIMIT)) {
+		keynav->is_keynav = false;
+	}
+
+	return keynav->is_keynav;
+}
+#endif  /* USE_KEYNAV_LIMIT */
+
 static char ui_menu_scroll_test(uiBlock *block, int my)
 {
 	if (block->flag & (UI_BLOCK_CLIPTOP | UI_BLOCK_CLIPBOTTOM)) {
@@ -6918,6 +6964,10 @@
 
 							PASS_EVENT_TO_PARENT_IF_NONACTIVE;
 
+#ifdef USE_KEYNAV_LIMIT
+							ui_mouse_motion_keynav_init(&menu->keynav_state, event);
+#endif
+
 							but = ui_but_find_activated(ar);
 							if (but) {
 								/* is there a situation where UI_LEFT or UI_RIGHT would also change navigation direction? */
@@ -7132,6 +7182,12 @@
 			if (menu->menuretval) {
 				/* pass */
 			}
+#ifdef USE_KEYNAV_LIMIT
+			else if ((event->type == MOUSEMOVE) && ui_mouse_motion_keynav_test(&menu->keynav_state, event)) {
+				/* don't handle the mousemove if we're using key-navigation */
+				retval = WM_UI_HANDLER_BREAK;
+			}
+#endif
 			else if (event->type == ESCKEY && event->val == KM_PRESS) {
 				/* esc cancels this and all preceding menus */
 				menu->menuretval = UI_RETURN_CANCEL;

Modified: trunk/blender/source/blender/editors/interface/interface_intern.h
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_intern.h	2013-04-11 02:23:45 UTC (rev 55951)
+++ trunk/blender/source/blender/editors/interface/interface_intern.h	2013-04-11 02:28:34 UTC (rev 55952)
@@ -419,6 +419,13 @@
 
 /* interface_regions.c */
 
+struct uiKeyNavLock {
+	/* set when we're using keyinput */
+	bool is_keynav;
+	/* only used to check if we've moved the cursor */
+	int event_xy[2];
+};
+
 struct uiPopupBlockHandle {
 	/* internal */
 	struct ARegion *region;
@@ -433,6 +440,8 @@
 	
 	struct wmTimer *scrolltimer;
 
+	struct uiKeyNavLock keynav_state;
+
 	/* for operator popups */
 	struct wmOperatorType *optype;
 	ScrArea *ctx_area;




More information about the Bf-blender-cvs mailing list