From nobody Sat Feb 7 04:47:08 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1497427129005645.6206135502691; Wed, 14 Jun 2017 00:58:49 -0700 (PDT) Received: from localhost ([::1]:47021 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dL3CR-0006he-E0 for importer@patchew.org; Wed, 14 Jun 2017 03:58:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46577) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dL3Am-0005SY-7M for qemu-devel@nongnu.org; Wed, 14 Jun 2017 03:57:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dL3Aj-0002JI-RV for qemu-devel@nongnu.org; Wed, 14 Jun 2017 03:57:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56816) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dL3Aj-0002Ic-Jo for qemu-devel@nongnu.org; Wed, 14 Jun 2017 03:57:01 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7AF9B81247; Wed, 14 Jun 2017 07:57:00 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-125.ams2.redhat.com [10.36.116.125]) by smtp.corp.redhat.com (Postfix) with ESMTP id D03F774ADF; Wed, 14 Jun 2017 07:56:57 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id AD1E816E2F; Wed, 14 Jun 2017 09:56:59 +0200 (CEST) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 7AF9B81247 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=kraxel@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 7AF9B81247 From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 14 Jun 2017 09:56:49 +0200 Message-Id: <20170614075653.26420-2-kraxel@redhat.com> In-Reply-To: <20170614075653.26420-1-kraxel@redhat.com> References: <20170614075653.26420-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 14 Jun 2017 07:57:00 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 1/5] Improve Cocoa modifier key handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Gerd Hoffmann , Ian McKellar Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Ian McKellar via Qemu-devel 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 =3D=3D 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 Message-id: 20170526233816.47627-1-ianloic@google.com Signed-off-by: Gerd Hoffmann --- 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; } } =20 +- (void) toggleModifier: (int)keycode { + // Toggle the stored state. + modifiers_state[keycode] =3D !modifiers_state[keycode]; + // Send a keyup or keydown depending on the state. + qemu_input_event_send_key_qcode(dcl->con, keycode, modifiers_state[key= code]); +} + +- (void) toggleStatefulModifier: (int)keycode { + // Toggle the stored state. + modifiers_state[keycode] =3D !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"); =20 int buttons =3D 0; - int keycode; + int keycode =3D 0; bool mouse_event =3D false; NSPoint p =3D [event locationInWindow]; =20 switch ([event type]) { case NSEventTypeFlagsChanged: - keycode =3D cocoa_keycode_to_qemu([event keyCode]); + if ([event keyCode] =3D=3D 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 =3D [event modifierFlag= s]; + + if (!!(modifiers & NSEventModifierFlagCapsLock) !=3D != !modifiers_state[Q_KEY_CODE_CAPS_LOCK]) { + [self toggleStatefulModifier:Q_KEY_CODE_CAPS_LOCK]; + } + if (!!(modifiers & NSEventModifierFlagShift) !=3D !!mo= difiers_state[Q_KEY_CODE_SHIFT]) { + [self toggleModifier:Q_KEY_CODE_SHIFT]; + } + if (!!(modifiers & NSEventModifierFlagControl) !=3D !!= modifiers_state[Q_KEY_CODE_CTRL]) { + [self toggleModifier:Q_KEY_CODE_CTRL]; + } + if (!!(modifiers & NSEventModifierFlagOption) !=3D !!m= odifiers_state[Q_KEY_CODE_ALT]) { + [self toggleModifier:Q_KEY_CODE_ALT]; + } + if (!!(modifiers & NSEventModifierFlagCommand) !=3D !!= modifiers_state[Q_KEY_CODE_META_L]) { + [self toggleModifier:Q_KEY_CODE_META_L]; + } + } + } else { + keycode =3D cocoa_keycode_to_qemu([event keyCode]); + } =20 if ((keycode =3D=3D Q_KEY_CODE_META_L || keycode =3D=3D Q_KEY_= CODE_META_R) && !isMouseGrabbed) { @@ -559,16 +602,9 @@ QemuCocoaView *cocoaView; // emulate caps lock and num lock keydown and keyup if (keycode =3D=3D Q_KEY_CODE_CAPS_LOCK || keycode =3D=3D Q_KEY_CODE_NUM_LOCK) { - qemu_input_event_send_key_qcode(dcl->con, keycode, tru= e); - qemu_input_event_send_key_qcode(dcl->con, keycode, fal= se); + [self toggleStatefulModifier:keycode]; } else if (qemu_console_is_graphic(NULL)) { - if (modifiers_state[keycode] =3D=3D 0) { // keydown - qemu_input_event_send_key_qcode(dcl->con, keycode,= true); - modifiers_state[keycode] =3D 1; - } else { // keyup - qemu_input_event_send_key_qcode(dcl->con, keycode,= false); - modifiers_state[keycode] =3D 0; - } + [self toggleModifier:keycode]; } } =20 --=20 2.9.3