From patchwork Mon May 22 18:02:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev\" via" X-Patchwork-Id: 9741261 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3E58C6034C for ; Mon, 22 May 2017 18:03:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 333632842E for ; Mon, 22 May 2017 18:03:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 262F928722; Mon, 22 May 2017 18:03:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 89C182842E for ; Mon, 22 May 2017 18:03:34 +0000 (UTC) Received: from localhost ([::1]:44218 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCrg5-0005E6-8d for patchwork-qemu-devel@patchwork.kernel.org; Mon, 22 May 2017 14:03:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41046) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dCrfR-0005E0-42 for qemu-devel@nongnu.org; Mon, 22 May 2017 14:02:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dCrfN-0006tk-49 for qemu-devel@nongnu.org; Mon, 22 May 2017 14:02:53 -0400 Received: from mail-pf0-x233.google.com ([2607:f8b0:400e:c00::233]:32776) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dCrfM-0006tg-T5 for qemu-devel@nongnu.org; Mon, 22 May 2017 14:02:49 -0400 Received: by mail-pf0-x233.google.com with SMTP id e193so89455777pfh.0 for ; Mon, 22 May 2017 11:02:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=a4CwKSnyocrXZhgFsSW8YOslK8I3cEZvLJ80fN7epLE=; b=ox57F2tFoxU0YK6VJUS3r9RdqVI5/aIPkKHLuV5TsOfFeO27ZUxUQ9cxGsgjKom6+S z5xrYZDumj860PI0pOG3OImn0znF8+XhWhlPhACltrzVlGEU0x/g/+SVJUZ+uEQi1qCF lymfZZ/Pl3gksqy61N2lQUyx7SfsxK9j3XNv+aQlcF3rDEU993zO4v/lQDD5enjPNs4o ipZzfpahuwtwkAp/Ws0NwGDASa4TIDqejc6GVP+jySmZOhGpQI6v28vkscSHSMvQeznT 5SfzsdTMvG3aBEt8jQwIWj+uWyKSXbYG/rwfXyNcvTp8OUtTQa+C77i050mG9sJrJcd/ UsjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=a4CwKSnyocrXZhgFsSW8YOslK8I3cEZvLJ80fN7epLE=; b=QBrOcZa2qq4CBb4lIwboJppg2W4CzukugRSV6tP4o8zvJDfMekoZfiKLTfLH8q55of SaVA38lTT8pIfWKKykTUahYvzgWix6uRmJIukLg6SZoT3lbL0eskDXFlmlS/5qA3tC1n EynVm3RSUhKfPaHQFfWedSPRC7v1HKtt1o3AEoseXqBz75Wp9KZDRilmLMgi9vCak764 QbkxBDRJj4kee2g2ZT3roDbIoNoh9g2m0p3ku2J6fEt4KmBvG4Gjjqbvbl7Bxjo0UO3G t4OoOVPmyFteH3U6h+Jpcrv1vr+Hsrq9PbWS8w342ERRDHAS1NLMqgRPF8bs+IGgstDN mvzg== X-Gm-Message-State: AODbwcARwaj9Mdska3LpgFOX2GyOWTrVxwMf75o3kgkacbmifIVcGTDE 7l/evBaTDwDL7X9EIihvXw== X-Received: by 10.98.86.207 with SMTP id h76mr26356436pfj.205.1495476167079; Mon, 22 May 2017 11:02:47 -0700 (PDT) Received: from ianloic-macbookpro2.roam.corp.google.com.com ([100.118.190.12]) by smtp.gmail.com with ESMTPSA id 19sm9535532pfz.39.2017.05.22.11.02.45 (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 22 May 2017 11:02:45 -0700 (PDT) To: qemu-devel@nongnu.org Date: Mon, 22 May 2017 11:02:17 -0700 Message-Id: <20170522180217.18234-1-ianloic@google.com> X-Mailer: git-send-email 2.13.0.rc1.294.g07d810a77f-goog X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::233 Subject: [Qemu-devel] [PATCH 1/1] 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: , X-Patchwork-Original-From: Ian McKellar via Qemu-devel From: "Denis V. Lunev\" via" Reply-To: Ian McKellar Cc: Ian McKellar Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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]; } }