Fix T103722: Stuck modifiers for wheel events over unfocused windows
Regression in [0] caused mouse wheel events over windows without focus to use the modifier state at the point the window was de-activated. Now un-focused windows have all events release, when focused again modifier press events are set again. [0]: 8bc76bf4b957c51ddc5a13c6305f05c64b218a27
This commit is contained in:
parent
4fcbfcfc96
commit
00ac2ddca2
@ -89,6 +89,20 @@
|
||||
*/
|
||||
#define USE_WIN_ACTIVATE
|
||||
|
||||
/**
|
||||
* When the window is de-activated, release all held modifiers.
|
||||
*
|
||||
* Needed so events generated over unfocused (non-active) windows don't have modifiers held.
|
||||
* Since modifier press/release events aren't send to unfocused windows it's best to assume
|
||||
* modifiers are not pressed. This means when modifiers *are* held, events will incorrectly
|
||||
* reported as not being held. Since this is standard behavior for Linux/MS-Window,
|
||||
* opt to use this.
|
||||
*
|
||||
* NOTE(@campbellbarton): Events generated for non-active windows are rare,
|
||||
* this happens when using the mouse-wheel over an unfocused window, see: T103722.
|
||||
*/
|
||||
#define USE_WIN_DEACTIVATE
|
||||
|
||||
/* the global to talk to ghost */
|
||||
static GHOST_SystemHandle g_system = NULL;
|
||||
#if !(defined(WIN32) || defined(__APPLE__))
|
||||
@ -1130,6 +1144,41 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt
|
||||
|
||||
switch (type) {
|
||||
case GHOST_kEventWindowDeactivate:
|
||||
#ifdef USE_WIN_DEACTIVATE
|
||||
/* Release all held modifiers before de-activating the window. */
|
||||
if (win->eventstate->modifier != 0) {
|
||||
const uint8_t keymodifier_eventstate = win->eventstate->modifier;
|
||||
const uint8_t keymodifier_l = wm_ghost_modifier_query(MOD_SIDE_LEFT);
|
||||
const uint8_t keymodifier_r = wm_ghost_modifier_query(MOD_SIDE_RIGHT);
|
||||
/* NOTE(@campbellbarton): when non-zero, there are modifiers held in
|
||||
* `win->eventstate` which are not considered held by the GHOST internal state.
|
||||
* While this should not happen, it's important all modifier held in event-state
|
||||
* receive release events. Without this, so any events generated while the window
|
||||
* is *not* active will have modifiers held. */
|
||||
const uint8_t keymodifier_unhandled = keymodifier_eventstate &
|
||||
~(keymodifier_l | keymodifier_r);
|
||||
const uint8_t keymodifier_sided[2] = {
|
||||
keymodifier_l | keymodifier_unhandled,
|
||||
keymodifier_r,
|
||||
};
|
||||
GHOST_TEventKeyData kdata = {
|
||||
.key = GHOST_kKeyUnknown,
|
||||
.utf8_buf = {'\0'},
|
||||
.is_repeat = false,
|
||||
};
|
||||
for (int i = 0; i < ARRAY_SIZE(g_modifier_table); i++) {
|
||||
if (keymodifier_eventstate & g_modifier_table[i].flag) {
|
||||
for (int side = 0; side < 2; side++) {
|
||||
if ((keymodifier_sided[side] & g_modifier_table[i].flag) == 0) {
|
||||
kdata.key = g_modifier_table[i].ghost_key_pair[side];
|
||||
wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_WIN_DEACTIVATE */
|
||||
|
||||
wm_event_add_ghostevent(wm, win, type, data);
|
||||
win->active = 0; /* XXX */
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user