[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/1] Improve Cocoa modifier key handling
From: |
Ian McKellar |
Subject: |
[Qemu-devel] [PATCH 1/1] Improve Cocoa modifier key handling |
Date: |
Mon, 22 May 2017 11:02:17 -0700 |
I had two problems with QEMU on macOS:
1) Sometimes when alt-tabbing to QEMU it would act as if the 'a' key
was pressed so I'd get 'aaaaaaaaa....'.
2) Using Sikuli to programatically send keys to the QEMU window text
like "foo_bar" would come out as "fooa-bar".
They looked similar and after much digging the problem turned out to be
the same. When QEMU's ui/cocoa.m received an NSFlagsChanged NSEvent it
looked at the keyCode to determine what modifier key changed. This
usually works fine but sometimes the keyCode is 0 and the app should
instead be looking at the modifierFlags bitmask. Key code 0 is the 'a'
key.
I added code that handles keyCode == 0 differently. It checks the
modifierFlags and if they differ from QEMU's idea of which modifier
keys are currently pressed it toggles those changed keys.
This fixes my problems and seems work fine.
Signed-off-by: Ian McKellar <address@hidden>
---
ui/cocoa.m | 48 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 207555edf7..e645befa13 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -52,6 +52,8 @@
/* macOS 10.12 deprecated many constants, #define the new names for older SDKs
*/
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
#define NSEventMaskAny NSAnyEventMask
+#define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
+#define NSEventModifierFlagShift NSShiftKeyMask
#define NSEventModifierFlagCommand NSCommandKeyMask
#define NSEventModifierFlagControl NSControlKeyMask
#define NSEventModifierFlagOption NSAlternateKeyMask
@@ -536,6 +538,16 @@ QemuCocoaView *cocoaView;
}
}
+- (void) toggleModifier: (int)keycode {
+ if (modifiers_state[keycode] == 0) { // keydown
+ qemu_input_event_send_key_qcode(dcl->con, keycode, true);
+ modifiers_state[keycode] = 1;
+ } else { // keyup
+ qemu_input_event_send_key_qcode(dcl->con, keycode, false);
+ modifiers_state[keycode] = 0;
+ }
+}
+
- (void) handleEvent:(NSEvent *)event
{
COCOA_DEBUG("QemuCocoaView: handleEvent\n");
@@ -547,7 +559,33 @@ QemuCocoaView *cocoaView;
switch ([event type]) {
case NSEventTypeFlagsChanged:
- keycode = cocoa_keycode_to_qemu([event keyCode]);
+ if ([event keyCode] == 0) {
+ // When the Cocoa keyCode is zero that means keys should be
+ // synthesized based on the values in in the eventModifiers
+ // bitmask.
+
+ if (qemu_console_is_graphic(NULL)) {
+ NSEventModifierFlags modifiers = [event modifierFlags];
+
+ if (!!(modifiers & NSEventModifierFlagCapsLock) !=
!!modifiers_state[Q_KEY_CODE_CAPS_LOCK]) {
+ [self toggleModifier:Q_KEY_CODE_CAPS_LOCK];
+ }
+ if (!!(modifiers & NSEventModifierFlagShift) !=
!!modifiers_state[Q_KEY_CODE_SHIFT]) {
+ [self toggleModifier:Q_KEY_CODE_SHIFT];
+ }
+ if (!!(modifiers & NSEventModifierFlagControl) !=
!!modifiers_state[Q_KEY_CODE_CTRL]) {
+ [self toggleModifier:Q_KEY_CODE_CTRL];
+ }
+ if (!!(modifiers & NSEventModifierFlagOption) !=
!!modifiers_state[Q_KEY_CODE_ALT]) {
+ [self toggleModifier:Q_KEY_CODE_ALT];
+ }
+ if (!!(modifiers & NSEventModifierFlagCommand) !=
!!modifiers_state[Q_KEY_CODE_META_L]) {
+ [self toggleModifier:Q_KEY_CODE_META_L];
+ }
+ }
+ } else {
+ keycode = cocoa_keycode_to_qemu([event keyCode]);
+ }
if ((keycode == Q_KEY_CODE_META_L || keycode == Q_KEY_CODE_META_R)
&& !isMouseGrabbed) {
@@ -562,13 +600,7 @@ QemuCocoaView *cocoaView;
qemu_input_event_send_key_qcode(dcl->con, keycode, true);
qemu_input_event_send_key_qcode(dcl->con, keycode, false);
} else if (qemu_console_is_graphic(NULL)) {
- if (modifiers_state[keycode] == 0) { // keydown
- qemu_input_event_send_key_qcode(dcl->con, keycode,
true);
- modifiers_state[keycode] = 1;
- } else { // keyup
- qemu_input_event_send_key_qcode(dcl->con, keycode,
false);
- modifiers_state[keycode] = 0;
- }
+ [self toggleModifier:keycode];
}
}
--
2.11.0.390.gc69c2f50cf-goog