From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Ian McKellar <ianloic@google.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Peter Maydell <peter.maydell@linaro.org>
Subject: [Qemu-devel] [PULL 1/7] Improve Cocoa modifier key handling
Date: Thu, 8 Jun 2017 09:07:10 +0200 [thread overview]
Message-ID: <20170608070716.2954-2-kraxel@redhat.com> (raw)
In-Reply-To: <20170608070716.2954-1-kraxel@redhat.com>
From: Ian McKellar via Qemu-devel <qemu-devel@nongnu.org>
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 <ianloic@google.com>
Message-id: 20170526233816.47627-1-ianloic@google.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/cocoa.m | 60 ++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 48 insertions(+), 12 deletions(-)
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 004ec2711c..1f010d3ae7 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
@@ -268,7 +270,7 @@ static void handleAnyDeviceErrors(Error * err)
NSWindow *fullScreenWindow;
float cx,cy,cw,ch,cdx,cdy;
CGDataProviderRef dataProviderRef;
- int modifiers_state[256];
+ BOOL modifiers_state[256];
BOOL isMouseGrabbed;
BOOL isFullscreen;
BOOL isAbsoluteEnabled;
@@ -536,18 +538,59 @@ QemuCocoaView *cocoaView;
}
}
+- (void) toggleModifier: (int)keycode {
+ // Toggle the stored state.
+ modifiers_state[keycode] = !modifiers_state[keycode];
+ // Send a keyup or keydown depending on the state.
+ qemu_input_event_send_key_qcode(dcl->con, keycode, modifiers_state[keycode]);
+}
+
+- (void) toggleStatefulModifier: (int)keycode {
+ // Toggle the stored state.
+ modifiers_state[keycode] = !modifiers_state[keycode];
+ // Generate keydown and keyup.
+ qemu_input_event_send_key_qcode(dcl->con, keycode, true);
+ qemu_input_event_send_key_qcode(dcl->con, keycode, false);
+}
+
- (void) handleEvent:(NSEvent *)event
{
COCOA_DEBUG("QemuCocoaView: handleEvent\n");
int buttons = 0;
- int keycode;
+ int keycode = 0;
bool mouse_event = false;
NSPoint p = [event locationInWindow];
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 toggleStatefulModifier: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) {
@@ -559,16 +602,9 @@ QemuCocoaView *cocoaView;
// emulate caps lock and num lock keydown and keyup
if (keycode == Q_KEY_CODE_CAPS_LOCK ||
keycode == Q_KEY_CODE_NUM_LOCK) {
- qemu_input_event_send_key_qcode(dcl->con, keycode, true);
- qemu_input_event_send_key_qcode(dcl->con, keycode, false);
+ [self toggleStatefulModifier:keycode];
} 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.9.3
next prev parent reply other threads:[~2017-06-08 7:07 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-08 7:07 [Qemu-devel] [PULL 0/7] ui patch queue Gerd Hoffmann
2017-06-08 7:07 ` Gerd Hoffmann [this message]
2017-06-08 7:07 ` [Qemu-devel] [PULL 2/7] spice: Use proper enum type for kbd led state Gerd Hoffmann
2017-06-08 7:07 ` [Qemu-devel] [PULL 3/7] gtk: prefer gtk3 over gtk2 Gerd Hoffmann
2017-06-08 7:07 ` [Qemu-devel] [PULL 4/7] sdl: prefer sdl2 over sdl1 Gerd Hoffmann
2017-06-08 7:07 ` [Qemu-devel] [PULL 5/7] gtk: add deprecation warning for gtk2 Gerd Hoffmann
2017-06-08 7:07 ` [Qemu-devel] [PULL 6/7] sdl: add deprecation warning for sdl1 Gerd Hoffmann
2017-06-08 7:07 ` [Qemu-devel] [PULL 7/7] spice: don't enter opengl mode in case another UI provides opengl support Gerd Hoffmann
2017-06-12 18:00 ` [Qemu-devel] [PULL 0/7] ui patch queue Peter Maydell
2017-06-12 18:08 ` Peter Maydell
2017-06-13 5:14 ` Thomas Huth
2017-06-13 8:26 ` Peter Maydell
2017-06-13 10:41 ` Gerd Hoffmann
2017-06-15 12:41 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170608070716.2954-2-kraxel@redhat.com \
--to=kraxel@redhat.com \
--cc=ianloic@google.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).