diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 12ff53c88..5b38eae32 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -68,9 +68,6 @@ extern int xpbproxy_run (void); static dispatch_queue_t eventTranslationQueue; #endif -/* Stuck modifier / button state... force release when we context switch */ -static NSEventType keyState[NUM_KEYCODES]; - extern Bool noTestExtensions; #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 @@ -194,7 +191,6 @@ static void message_kit_thread (SEL selector, NSObject *arg) { } - (void) activateX:(OSX_BOOL)state { - size_t i; DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active); if (state) { if(bgMouseLocationUpdated) { @@ -206,13 +202,13 @@ static void message_kit_thread (SEL selector, NSObject *arg) { if(darwin_all_modifier_flags) DarwinUpdateModKeys(0); - for(i=0; i < NUM_KEYCODES; i++) { - if(keyState[i] == NSKeyDown) { - DarwinSendKeyboardEvents(KeyRelease, i); - keyState[i] = NSKeyUp; - } - } - + + DarwinInputReleaseButtonsAndKeys(darwinKeyboard); + DarwinInputReleaseButtonsAndKeys(darwinPointer); + DarwinInputReleaseButtonsAndKeys(darwinTabletCursor); + DarwinInputReleaseButtonsAndKeys(darwinTabletStylus); + DarwinInputReleaseButtonsAndKeys(darwinTabletEraser); + DarwinSendDDXEvent(kXquartzDeactivate, 0); } @@ -1407,12 +1403,8 @@ static const char *untrusted_str(NSEvent *e) { } } - /* Avoid stuck keys on context switch */ - if(keyState[[e keyCode]] == [e type]) - return; - keyState[[e keyCode]] = [e type]; - - DarwinSendKeyboardEvents(([e type] == NSKeyDown) ? KeyPress : KeyRelease, [e keyCode]); + ev_type = ([e type] == NSKeyDown) ? KeyPress : KeyRelease; + DarwinSendKeyboardEvents(ev_type, [e keyCode]); break; default: break; /* for gcc */ diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index c367e3c1c..3438da116 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -434,6 +434,28 @@ static void DarwinPrepareValuators(DeviceIntPtr pDev, int *valuators, ScreenPtr // valuators[0], valuators[1], valuators[2], valuators[3], valuators[4]); } +void DarwinInputReleaseButtonsAndKeys(DeviceIntPtr pDev) { + darwinEvents_lock(); { + int i; + if (pDev->button) { + for (i = 0; i < pDev->button->numButtons; i++) { + if (BitIsOn(pDev->button->down, i)) { + QueuePointerEvents(pDev, ButtonRelease, i, POINTER_ABSOLUTE, NULL); + } + } + } + + if (pDev->key) { + for (i = 0; i < NUM_KEYCODES; i++) { + if (BitIsOn(pDev->key->down, i + MIN_KEYCODE)) { + QueueKeyboardEvents(pDev, KeyRelease, i + MIN_KEYCODE, NULL); + } + } + } + DarwinPokeEQ(); + } darwinEvents_unlock(); +} + void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y, float pressure, float tilt_x, float tilt_y) { static int darwinFakeMouseButtonDown = 0; diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h index aefb5c7bb..a44872b69 100644 --- a/hw/xquartz/darwinEvents.h +++ b/hw/xquartz/darwinEvents.h @@ -36,6 +36,7 @@ void DarwinEQFini(void); void DarwinEQEnqueue(const xEventPtr e); void DarwinEQPointerPost(DeviceIntPtr pDev, xEventPtr e); void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX); +void DarwinInputReleaseButtonsAndKeys(DeviceIntPtr pDev); void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y, float pressure, float tilt_x, float tilt_y); void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, float pointer_y,