Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2015-04-07 15:08:30 +0300
committerJulian Eisel <eiseljulian@gmail.com>2015-04-07 15:13:20 +0300
commitcc78664d50c6ae82d139552283ede467b0cf28cc (patch)
tree96575149c8b9fef5e8e8a3883d55f4e385deda74 /source/blender/windowmanager
parentd60ff6c112b1c5d3819676109b0080a316850eb0 (diff)
Revert Sticky Keys (and everything related to that)
Our current keymap doesn't give us enough room to make such changes in the event system. To fix small issues caused by this, we would need to do drastic changes in Blender's keymaps and internal handling. It was worth a try, but it didn't work. I can write down a more descriptive statement in a few days, but for now I need a break of this stuff.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r--source/blender/windowmanager/WM_types.h17
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c134
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c2
-rw-r--r--source/blender/windowmanager/intern/wm_window.c76
5 files changed, 83 insertions, 150 deletions
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 366d3218176..e716cd6b779 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -180,11 +180,9 @@ enum {
#define KM_NOTHING 0
#define KM_PRESS 1
#define KM_RELEASE 2
+#define KM_CLICK 3
+#define KM_DBL_CLICK 4
-/* clicktype */
-#define KM_CLICK 3 /* clicked key (click_time <= U.click_timeout) */
-#define KM_DBL_CLICK 4 /* double click - keep at 4 to avoid breakage with older key configs */
-#define KM_HOLD 5 /* held key (click_time > U.click_timeout) */
/* ************** UI Handler ***************** */
@@ -429,9 +427,7 @@ typedef struct wmEvent {
short type; /* event code itself (short, is also in keymap) */
short val; /* press, release, scrollvalue */
- short click_type; /* click, hold or double click */
int x, y; /* mouse pointer position, screen coord */
- double click_time; /* the time since keypress started */
int mval[2]; /* region mouse position, name convention pre 2.5 :) */
char utf8_buf[6]; /* from, ghost if utf8 is enabled for the platform,
* BLI_str_utf8_size() must _always_ be valid, check
@@ -439,19 +435,20 @@ typedef struct wmEvent {
char ascii; /* from ghost, fallback if utf8 isn't set */
char pad;
- bool is_key_pressed; /* is a (non-modifier) key is pressed? (keyboard, mouse, NDOF, ...) */
-
- /* previous state, used for clicktype */
+ /* previous state, used for double click and the 'click' */
short prevtype;
short prevval;
int prevx, prevy;
- double prevclick_time;
+ double prevclicktime;
int prevclickx, prevclicky;
/* modifier states */
short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */
short keymodifier; /* rawkey modifier */
+ /* set in case a KM_PRESS went by unhandled */
+ short check_click;
+
/* keymap item, set by handler (weak?) */
const char *keymap_idname;
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 8c013eb7cd4..d8ca80a62cb 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -404,7 +404,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
* to make the DBL_CLICK conversion work, we just don't send this to UI, except mouse clicks */
if (((handler->flag & WM_HANDLER_ACCEPT_DBL_CLICK) == 0) &&
(event->type != LEFTMOUSE) &&
- (event->click_type == KM_DBL_CLICK))
+ (event->val == KM_DBL_CLICK))
{
return WM_HANDLER_CONTINUE;
}
@@ -1442,7 +1442,6 @@ int WM_userdef_event_map(int kmitype)
}
-/* XXX rename to something more descriptive like wm_event_is_keymapitem_matching and use bool */
static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi)
{
int kmitype = WM_userdef_event_map(kmi->type);
@@ -1459,13 +1458,10 @@ static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi)
if (kmitype != KM_ANY)
if (winevent->type != kmitype) return 0;
-
- /* KM_ANY excludes KM_HOLD since it's time based and not a real input - filter it out */
- if (kmi->val == KM_ANY && winevent->click_type == KM_HOLD) return 0;
-
+
if (kmi->val != KM_ANY)
- if (!ELEM(kmi->val, winevent->val, winevent->click_type)) return 0;
-
+ if (winevent->val != kmi->val) return 0;
+
/* modifiers also check bits, so it allows modifier order */
if (kmi->shift != KM_ANY)
if (winevent->shift != kmi->shift && !(winevent->shift & kmi->shift)) return 0;
@@ -1512,9 +1508,8 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve
/* modal keymap checking returns handled events fine, but all hardcoded modal
* handling typically swallows all events (OPERATOR_RUNNING_MODAL).
* This bypass just disables support for double clicks in hardcoded modal handlers */
- if (event->click_type == KM_DBL_CLICK) {
+ if (event->val == KM_DBL_CLICK) {
event->val = KM_PRESS;
- event->click_type = 0;
*dbl_click_disabled = true;
}
}
@@ -1546,9 +1541,9 @@ static void wm_event_modalmap_end(wmEvent *event, bool dbl_click_disabled)
event->val = event->prevval;
event->prevval = 0;
}
- else if (dbl_click_disabled) {
- event->click_type = KM_DBL_CLICK;
- }
+ else if (dbl_click_disabled)
+ event->val = KM_DBL_CLICK;
+
}
/* Warning: this function removes a modal handler, when finished */
@@ -2026,21 +2021,47 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
/* test for CLICK events */
if (wm_action_not_handled(action)) {
wmWindow *win = CTX_wm_window(C);
-
- /* XXX check if those double click hacks can be removed/improved since click_type was introduced */
+
+ /* eventstate stores if previous event was a KM_PRESS, in case that
+ * wasn't handled, the KM_RELEASE will become a KM_CLICK */
+
+ if (win && event->val == KM_PRESS) {
+ win->eventstate->check_click = true;
+ }
+
if (win && win->eventstate->prevtype == event->type) {
- if (event->click_type == KM_DBL_CLICK) {
+
+ if ((event->val == KM_RELEASE) &&
+ (win->eventstate->prevval == KM_PRESS) &&
+ (win->eventstate->check_click == true))
+ {
+ event->val = KM_CLICK;
+
+ if (G.debug & (G_DEBUG_HANDLERS)) {
+ printf("%s: handling CLICK\n", __func__);
+ }
+
+ action |= wm_handlers_do_intern(C, event, handlers);
+
+ event->val = KM_RELEASE;
+ }
+ else if (event->val == KM_DBL_CLICK) {
event->val = KM_PRESS;
- event->click_type = 0;
action |= wm_handlers_do_intern(C, event, handlers);
/* revert value if not handled */
if (wm_action_not_handled(action)) {
- event->click_type = KM_DBL_CLICK;
+ event->val = KM_DBL_CLICK;
}
}
}
}
+ else {
+ wmWindow *win = CTX_wm_window(C);
+
+ if (win)
+ win->eventstate->check_click = 0;
+ }
}
return action;
@@ -2984,50 +3005,22 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
return NULL;
}
-/**
- * Clicktype test
- *
- * We have 3 different click_types: #KM_CLICK, #KM_HOLD# and #KM_DBL_CLICK.
- *
- * Time is used to determine, what to send. It works as follows:
- * - #KM_RELEASE && time since first #KM_PRESS < U.click_timeout --> send #KM_CLICK
- * - #KM_PRESS && time since first #KM_PRESS > U.click_timeout --> send #KM_HOLD
- * - #KM_PRESS after a #KM_RELEASE && time since previous #KM_PRESS < U.dbl_click_time --> send #KM_DBL_CLICK
- *
- * \note: only #KM_DBL_CLICK is handled here, rest in #wm_window_event_clicktype_init (wm_window.c)
- */
-static void wm_event_clicktype_init(wmWindow *win, wmEvent *event, wmEvent *event_state)
+static bool wm_event_is_double_click(wmEvent *event, wmEvent *event_state)
{
- short click_type = 0;
-
- if ((event->val == KM_PRESS) &&
- (event_state->prevval != KM_PRESS || event->prevtype != win->eventstate->prevtype))
- {
- event_state->prevclick_time = event->click_time;
- event_state->prevclickx = event->x;
- event_state->prevclicky = event->y;
- }
-
- /* double click */
- if (event->type == event_state->prevtype &&
- event_state->prevval == KM_RELEASE &&
- event->val == KM_PRESS)
+ if ((event->type == event_state->prevtype) &&
+ (event_state->prevval == KM_RELEASE) &&
+ (event->val == KM_PRESS))
{
if ((ISMOUSE(event->type) == false) || ((ABS(event->x - event_state->prevclickx)) <= 2 &&
(ABS(event->y - event_state->prevclicky)) <= 2))
{
- if ((PIL_check_seconds_timer() - event_state->prevclick_time) * 1000 < U.dbl_click_time) {
- click_type = KM_DBL_CLICK;
- if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS)) {
- printf("%s Send double click event\n", __func__);
- }
+ if ((PIL_check_seconds_timer() - event_state->prevclicktime) * 1000 < U.dbl_click_time) {
+ return true;
}
}
}
- if (click_type != event->click_type) {
- event_state->click_type = event->click_type = click_type;
- }
+ return false;
}
static void wm_event_add_mousemove(wmWindow *win, const wmEvent *event)
@@ -3159,9 +3152,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
evt->val = event.val;
evt->type = event.type;
- /* click_type */
- wm_event_clicktype_init(win, &event, evt);
-
if (win->active == 0) {
int cx, cy;
@@ -3172,6 +3162,18 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
event.y = evt->y = cy;
}
+ /* double click test */
+ if (wm_event_is_double_click(&event, evt)) {
+ if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS))
+ printf("%s Send double click\n", __func__);
+ event.val = KM_DBL_CLICK;
+ }
+ if (event.val == KM_PRESS) {
+ evt->prevclicktime = PIL_check_seconds_timer();
+ evt->prevclickx = event.x;
+ evt->prevclicky = event.y;
+ }
+
/* add to other window if event is there (not to both!) */
owin = wm_event_cursor_other_windows(wm, win, &event);
if (owin) {
@@ -3210,10 +3212,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
/* copy to event state */
evt->val = event.val;
evt->type = event.type;
-
- /* clicktype */
- wm_event_clicktype_init(win, &event, evt);
-
+
/* exclude arrow keys, esc, etc from text input */
if (type == GHOST_kEventKeyUp) {
event.ascii = '\0';
@@ -3279,6 +3278,14 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
event.keymodifier = evt->keymodifier = 0;
break;
}
+
+ /* double click test */
+ /* if previous event was same type, and previous was release, and now it presses... */
+ if (wm_event_is_double_click(&event, evt)) {
+ if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS))
+ printf("%s Send double click\n", __func__);
+ evt->val = event.val = KM_DBL_CLICK;
+ }
/* this case happens on holding a key pressed, it should not generate
* press events events with the same key as modifier */
@@ -3299,6 +3306,13 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
G.is_break = true;
}
+ /* double click test - only for press */
+ if (event.val == KM_PRESS) {
+ evt->prevclicktime = PIL_check_seconds_timer();
+ evt->prevclickx = event.x;
+ evt->prevclicky = event.y;
+ }
+
wm_event_add(win, &event);
break;
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 0a89ca113c4..82e46c1b333 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -1192,15 +1192,11 @@ int WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2)
return 0;
if (k1->val != KM_ANY && k2->val != KM_ANY) {
-
-#if 0 /* thanks to clicktype those shouldn't be needed anymore */
/* take click, press, release conflict into account */
if (k1->val == KM_CLICK && ELEM(k2->val, KM_PRESS, KM_RELEASE, KM_CLICK) == 0)
return 0;
if (k2->val == KM_CLICK && ELEM(k1->val, KM_PRESS, KM_RELEASE, KM_CLICK) == 0)
return 0;
-#endif
-
if (k1->val != k2->val)
return 0;
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 499adf5704d..2e48c840c2c 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -5149,7 +5149,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "WM_OT_debug_menu", DKEY, KM_PRESS, KM_ALT | KM_CTRL, 0);
/* menus that can be accessed anywhere in blender */
- WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_CLICK, 0, 0);
+ WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "USERPREF_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0);
/* Space switching */
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 61bddb144ae..d69cf3326b7 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -1106,76 +1106,6 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
return 1;
}
-/**
- * #KM_DBL_CLICK is set in wm_event_clicktype_init (wm_event_system.c)
- * Normally, this should be there too, but for #KM_CLICK/#KM_HOLD, we need a
- * time precision of a few milliseconds, which we can't get from there
- */
-static void wm_window_event_clicktype_init(const bContext *C)
-{
- wmWindowManager *wm = CTX_wm_manager(C);
-
- if (wm->winactive) {
- wmWindow *win = wm->winactive;
- wmEvent *event = win->eventstate;
- short click_type = event->click_type;
-
- BLI_assert(event != NULL);
-
- if ((event->type == EVENT_NONE) ||
- ((event->val == KM_NOTHING) && (event->is_key_pressed == false)))
- {
- /* nothing needs to be done here */
- return;
- }
-
- /* we always want click_type of last clicked button (to enable
- * use with modifier keys) - unnecessary for mouse though */
- if (!ISMOUSE(event->type) &&
- event->val == KM_PRESS &&
- event->type != event->keymodifier)
- {
- event->is_key_pressed = false;
- }
- else if (event->val == KM_PRESS && !event->is_key_pressed) {
- event->is_key_pressed = true;
- event->click_time = PIL_check_seconds_timer();
- }
- else if (event->val == KM_RELEASE && event->is_key_pressed) {
- event->is_key_pressed = false;
- }
- else if (event->is_key_pressed == false) {
- return;
- }
-
- /* the actual test */
- if ((PIL_check_seconds_timer() - event->click_time) * 1000 <= U.click_timeout) {
- /* for any reason some X11 systems send two release events triggering two KM_CLICK
- * events - making the rules more strict by checking for prevval resolves this */
- if (event->val == KM_RELEASE && event->prevval != KM_RELEASE) {
- click_type = KM_CLICK;
- if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS)) {
- printf("%s Send click event\n", __func__);
- }
- }
- }
- else if (event->is_key_pressed) {
- click_type = KM_HOLD;
- if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS)) {
- printf("%s Send hold event\n", __func__);
- }
-
- /* the event we send in this case is a "dummy" event - don't send value */
- event->val = KM_NOTHING;
- }
-
- /* send event with new click_type */
- if (event->click_type != click_type) {
- event->click_type = click_type;
- wm_event_add(win, event);
- }
- }
-}
/* This timer system only gives maximum 1 timer event per redraw cycle,
* to prevent queues to get overloaded.
@@ -1235,11 +1165,7 @@ void wm_window_process_events(const bContext *C)
if (hasevent)
GHOST_DispatchEvents(g_system);
-
- /* not nice to have this here, but it's the only place
- * that can call it with the needed time precision */
- wm_window_event_clicktype_init(C);
-
+
hasevent |= wm_window_timer(C);
/* no event, we sleep 5 milliseconds */