From nobody Sat May 11 18:33:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1627665103; cv=none; d=zohomail.com; s=zohoarc; b=HxFfKlzNxf1AlpWw3KRBGSGl+sk4fn7L96KOE95M+xYcT1cZGQ8evOVvTNr14bMs8t10/e3sVBS7HR8iBd6BNWlfBzQMdtMGArk3c+Eh+DQD8swFJbQoNJIJ2weWwlvBLFVzs60ypCOR1iY+MMuSjp3yG0i5x02H0HxpkUML0Ww= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1627665103; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=U7uOpgKKbYlUukkr5zRFu+fDTpauB8ROnRQm7CX2yi0=; b=cKbXYYU/wU3psF90XSS7lzebf/LUM57KO/QJNrvJaYi4w2MTHv9uZTFjLQ07LVlZu2GyepNEb8bVhVwdKrE7cfNlMhQD6g8PeBeikfj5deBbX2vLexNqPK2yFGEjyzLPo1LwPmNY07DBYGjiBdzkmKl27F4pnMI097nDbtYn7AI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1627665103638599.2841151906412; Fri, 30 Jul 2021 10:11:43 -0700 (PDT) Received: from localhost ([::1]:40324 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9W2w-0006NB-9I for importer@patchew.org; Fri, 30 Jul 2021 13:11:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:46496) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9W1L-0004I7-Il for qemu-devel@nongnu.org; Fri, 30 Jul 2021 13:10:03 -0400 Received: from mail-qt1-x831.google.com ([2607:f8b0:4864:20::831]:46856) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9W1J-0000KC-O9 for qemu-devel@nongnu.org; Fri, 30 Jul 2021 13:10:03 -0400 Received: by mail-qt1-x831.google.com with SMTP id x9so6879738qtw.13 for ; Fri, 30 Jul 2021 10:10:01 -0700 (PDT) Received: from localhost.localdomain (d149-67-175-105.try.wideopenwest.com. [67.149.105.175]) by smtp.gmail.com with ESMTPSA id k15sm1227856qko.84.2021.07.30.10.10.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Jul 2021 10:10:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=U7uOpgKKbYlUukkr5zRFu+fDTpauB8ROnRQm7CX2yi0=; b=tbErCvpnZdH6CyKT7p27d1igTvX3ybyGVKZAIpLvy7+GJIPC0CcEQVXgdNOBPEoP04 oDIZO7kVkkHUFQ+ZfBCYJenjaJ7B+QVFbcr9KIrVB+g+qYSJCuWZYcgskFgA2LBj5GFR EZqWCSxlVJg/ZW9SZqDX2gjZiig4h4MAZ2WKyKSK8HxUuPfoAF/sUXQoVXiSMGGByQP7 N6qiWEG9F3DeKmTd2IoyOlHB1jsPw6Wqv1IITkpEOAKL9n7gis5Cd9chNtCZQOOSPEK0 AYzPAOUSWM4ir+r86LInGIw6FB3/V6b4WJ7cV3HJetMXvyKqnsfukx3ktSoLZb3bWd1A BzkQ== 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=U7uOpgKKbYlUukkr5zRFu+fDTpauB8ROnRQm7CX2yi0=; b=Pn8rgpdh+jRdyLjscIFXNWRNhhVASN2o02BCXZz+LfUiUduQN9jlOjSSq+Wzm1Y6Qp 4Gj26qBFk031HU8eztIIPJevFAmly7DCk5y8du6NEczVeA3SARjU5e8YZt7c0a5UvdTW qy4wUErcB8Ilj8sRdqbWjjoVXb5Z3GIzc1k0WhojjOQ1Rud8qK0R65yXxTst+sDLZSpD iw0xcstYN/hM5aANYZoS0uubR8w6U+ucN+gStIlYgusvOGrzBiAFVZQxxVYiLBuL4ZBt ZNo71DMZWdG7Wq22eM+2XPoQaEaykFelDtefQIijeSvUU7HBF5SpIh0Ln44oTM+Uty3A rB5Q== X-Gm-Message-State: AOAM533YLCsMqfJLFxUUzlOGLL2bVKAO/gO/fOjyf1RcR2XI46sAONXi rPHrzv5j2skqA7MrJkTGmqY= X-Google-Smtp-Source: ABdhPJwdnPcjQDb6y5yLKmF4Hu8YoQWDG0OL8Ul3EAeyZlp+j6W55hHSqnFWBat89zKbmtE4CjcbFg== X-Received: by 2002:a05:622a:10d:: with SMTP id u13mr3215372qtw.314.1627665000797; Fri, 30 Jul 2021 10:10:00 -0700 (PDT) From: John Arbuckle To: Peter Maydell , Gerd Hoffmann , Gustavo Noronha Silva , QEMU devel list Subject: [PATCH 1/2] ui/cocoa.m: Add full keyboard grab support Date: Fri, 30 Jul 2021 13:09:44 -0400 Message-Id: <20210730170945.4468-2-programmingkidx@gmail.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) In-Reply-To: <20210730170945.4468-1-programmingkidx@gmail.com> References: <20210730170945.4468-1-programmingkidx@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::831; envelope-from=programmingkidx@gmail.com; helo=mail-qt1-x831.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: John Arbuckle Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1627665105750100003 Content-Type: text/plain; charset="utf-8" There are keyboard shortcuts that are vital for use in a guest that runs Ma= c OS. These shortcuts are reserved for Mac OS use only which makes having the gue= st see them impossible on a Mac OS host - until now. This patch will enable the user to decide if the guest should see all keyboard shortcuts using a menu = item. This patch adds a new menu called Options and a new menu item called "Full Keyboard Grab". Simply selecting this menu item will turn the feature= on or off at any time. Mac OS requires the user to enable access to assistive devices to use this feature. How to do this varies with each Mac OS version. Based on patch by Gustavo Noronha Silva .=20 Signed-off-by: John Arbuckle --- ui/cocoa.m | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/ui/cocoa.m b/ui/cocoa.m index 9f72844b07..fdef9e9901 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -114,6 +114,9 @@ static void cocoa_switch(DisplayChangeListener *dcl, typedef void (^CodeBlock)(void); typedef bool (^BoolCodeBlock)(void); =20 +static CFMachPortRef eventsTap =3D NULL; +static CFRunLoopSourceRef eventsTapSource =3D NULL; + static void with_iothread_lock(CodeBlock block) { bool locked =3D qemu_mutex_iothread_locked(); @@ -332,10 +335,27 @@ - (float) cdx; - (float) cdy; - (QEMUScreen) gscreen; - (void) raiseAllKeys; +- (void) setFullGrab; @end =20 QemuCocoaView *cocoaView; =20 +// Part of the full keyboard grab system +static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, +CGEventRef cgEvent, void *userInfo) +{ + QemuCocoaView *cocoaView =3D (QemuCocoaView*) userInfo; + NSEvent* event =3D [NSEvent eventWithCGEvent:cgEvent]; + if ([cocoaView isMouseGrabbed] && [cocoaView handleEvent:event]) { + COCOA_DEBUG("Global events tap: qemu handled the event, capturing!= \n"); + return NULL; + } + COCOA_DEBUG("Global events tap: qemu did not handle the event, letting= it" + " through...\n"); + + return cgEvent; +} + @implementation QemuCocoaView - (id)initWithFrame:(NSRect)frameRect { @@ -361,6 +381,12 @@ - (void) dealloc } =20 qkbd_state_free(kbd); + if (eventsTap) { + CFRelease(eventsTap); + } + if (eventsTapSource) { + CFRelease(eventsTapSource); + } [super dealloc]; } =20 @@ -1086,6 +1112,50 @@ - (void) raiseAllKeys qkbd_state_lift_all_keys(kbd); }); } + +// Inserts the event tap. +// This enables us to receive keyboard events that Mac OS would +// otherwise not let us see - like Command-Option-Esc. +- (void) setFullGrab +{ + COCOA_DEBUG("QemuCocoaView: setFullGrab\n"); + NSString *advice =3D @"Try enabling access to assistive devices"; + CGEventMask mask =3D CGEventMaskBit(kCGEventKeyDown) | + CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventFlagsChanged); + eventsTap =3D CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, + kCGEventTapOptionDefault, mask, handleTap= Event, + self); + if (!eventsTap) { + @throw [NSException + exceptionWithName:@"Tap failure" + reason:[NSString stringWithFormat:@"%@\n%@", @"Could not " + "create event tap.", advice] + userInfo:nil]; + } else { + COCOA_DEBUG("Global events tap created! Will capture system key" + " combos.\n"); + } + + eventsTapSource =3D + CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventsTap, 0); + if (!eventsTapSource ) { + @throw [NSException + exceptionWithName:@"Tap failure" + reason:@"Could not obtain current CFRunLoop source." + userInfo:nil]; + } + CFRunLoopRef runLoop =3D CFRunLoopGetCurrent(); + if (!runLoop) { + @throw [NSException + exceptionWithName:@"Tap failure" + reason:@"Could not obtain current CFRunLoop." + userInfo:nil]; + } + + CFRunLoopAddSource(runLoop, eventsTapSource, kCFRunLoopDefaultMode); + CFRelease(eventsTapSource); +} + @end =20 =20 @@ -1117,6 +1187,7 @@ - (void)openDocumentation:(NSString *)filename; - (IBAction) do_about_menu_item: (id) sender; - (void)make_about_window; - (void)adjustSpeed:(id)sender; +- (IBAction)doFullGrab:(id)sender; @end =20 @implementation QemuCocoaAppController @@ -1569,6 +1640,35 @@ - (void)adjustSpeed:(id)sender COCOA_DEBUG("cpu throttling at %d%c\n", cpu_throttle_get_percentage(),= '%'); } =20 +// The action method to the 'Options->Full Keyboard Grab' menu item +- (IBAction)doFullGrab:(id) sender +{ + @try + { + // Set the state of the menu item + // if already checked + if ([sender state] =3D=3D NSControlStateValueOn) { + // remove runloop source + CFRunLoopSourceInvalidate(eventsTapSource); + if (!eventsTap) { + CFRelease(eventsTap); + } + [sender setState: NSControlStateValueOff]; + } + + // if not already checked + else { + [cocoaView setFullGrab]; + [sender setState: NSControlStateValueOn]; + } + } + @catch(NSException *e) { + NSBeep(); + NSLog(@"Exception in doFullGrab: %@", [e reason]); + QEMU_Alert([e reason]); + } +} + @end =20 @interface QemuApplication : NSApplication @@ -1655,6 +1755,18 @@ static void create_initial_menus(void) [menuItem setSubmenu:menu]; [[NSApp mainMenu] addItem:menuItem]; =20 + // Options menu + menu =3D [[NSMenu alloc] initWithTitle:@"Options"]; + + [menu addItem: [[[NSMenuItem alloc] initWithTitle: + @"Full Keyboard Grab" action:@selector(doFullGrab= :) + keyEquivalent:@""] autorelease]]; + + menuItem =3D [[[NSMenuItem alloc] initWithTitle:@"Options" action:nil + keyEquivalent:@""] autorelease]; + [menuItem setSubmenu:menu]; + [[NSApp mainMenu] addItem:menuItem]; + // Window menu menu =3D [[NSMenu alloc] initWithTitle:@"Window"]; [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Minimize" action:@= selector(performMiniaturize:) keyEquivalent:@"m"] autorelease]]; // Miniatu= rize --=20 2.24.3 (Apple Git-128) From nobody Sat May 11 18:33:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1627665105; cv=none; d=zohomail.com; s=zohoarc; b=XBub1X5OCSPq/Uvi32TvCJPij9XNBe02/LlAApmcvfIBxWTM4S8lwH1rd767/ok58oWRPsLYOP45+CgVhBddk4QURf23fyNrAra6hhX+bh7F8ryKwpjKaMltBoV9j62hwMFoofhEgqcSiOrs6pNFsXDB+QeKap4jcS0qkuE2hKA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1627665105; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=5MLHF0wFgQr+8nbdPu5FrLnRo+U2jUITrUSQIhFK6+s=; b=FppoJgRIEAGk8nz8D7rxwNIUElHftc3XZJNX9tFYCWXalSfIfwloNdvCvYNJHraU7Nn4IQaXqzPhIr4rhBQImRMwnQ672hf5pp9CV1TmFYMP8mMIFZjMqEIfJcor9tg7NwuvIr+J/LU1WvVzusmSRt+6x58rQ+6ZcPpLigH/HdM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1627665105021143.55801739123046; Fri, 30 Jul 2021 10:11:45 -0700 (PDT) Received: from localhost ([::1]:40434 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9W2x-0006RO-OB for importer@patchew.org; Fri, 30 Jul 2021 13:11:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:46512) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9W1R-0004M0-2o for qemu-devel@nongnu.org; Fri, 30 Jul 2021 13:10:09 -0400 Received: from mail-qt1-x82b.google.com ([2607:f8b0:4864:20::82b]:38898) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9W1M-0000MX-Id for qemu-devel@nongnu.org; Fri, 30 Jul 2021 13:10:07 -0400 Received: by mail-qt1-x82b.google.com with SMTP id h10so6900158qth.5 for ; Fri, 30 Jul 2021 10:10:04 -0700 (PDT) Received: from localhost.localdomain (d149-67-175-105.try.wideopenwest.com. [67.149.105.175]) by smtp.gmail.com with ESMTPSA id k15sm1227856qko.84.2021.07.30.10.10.03 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Jul 2021 10:10:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5MLHF0wFgQr+8nbdPu5FrLnRo+U2jUITrUSQIhFK6+s=; b=AOAAH8Dt23feHDlYqdQ1qPYGeeAaXzXyOYAW5mziLKrGmTkUaoCST9tPyKdesLUlu9 5LCrUrVWCl1lC6AbDoTrkZPSUqziHHvn8SHz4TjcLA1jHQsJZOyFPbzdEGRFIYhCmJTh 5lHxbkWYwXXyjp4fgbNod91OYhXfwlqRWM3HwIGL/68DThMwkGpi65zVW5i3S4jN6/Zf Kj79jos/2tnu+ryJc/ovS6+s1OByoDuxn9DngOLr6K9fSWNHlqk9FKTP8J1DLTuxJ+7o FI9WIR6KEKgd1S2/Mo7mUIzm+yCw08ayxkZJOz3D+PhcfD5xC9PQwjr0uvOvmOZhryk4 5nkQ== 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=5MLHF0wFgQr+8nbdPu5FrLnRo+U2jUITrUSQIhFK6+s=; b=tH7tJsDjDw/M+XSYEAnd7QIugBmAoIx9uW8IDtcJCWDAXDZypuccVEhKU51/zKkiAW oJI36cYYT2jWVPSTvyq3xtS5HJLatcp2TQE2/pvRKfuOAy9zyoZuRQR0pyWiPEFfKWrf gKSx3GU1uFi5JNIzyspJ3r4jVLbt7ytW0hSQQw1+fvi/nnNbZYGwoWRohxljvPkq3Yz7 SHUBDrvj8RAVVjW+Lq05oMYIjodmq3ifMVmGD9xz1tWij3MaYz/roYADi3cdGovvjmtO 8x8KtVNz41M03/ocH+q1kaAxKaFtzyPuxjlImc/r7y3jHPNCKAZ76mRtSCcaf0mSteOU iLpQ== X-Gm-Message-State: AOAM530mg5sAGbfB/n0nE9H97BZ5wqJZF6HUTKLaCgu2T1i86H0pfvkl KxZwHSTLKgPbweqbQ+KwrWw= X-Google-Smtp-Source: ABdhPJx2MvGjbPlbB1yU+fMjxKA2pxVR5AxD4Vi7AYd7cjgYTgYGmQjeBiiUVeQR0DNIfQZ/8Xe+jQ== X-Received: by 2002:ac8:5645:: with SMTP id 5mr3198756qtt.200.1627665003778; Fri, 30 Jul 2021 10:10:03 -0700 (PDT) From: John Arbuckle To: Peter Maydell , Gerd Hoffmann , Gustavo Noronha Silva , QEMU devel list Subject: [PATCH 2/2] ui/cocoa.m: Add ability to swap command/meta and options keys Date: Fri, 30 Jul 2021 13:09:45 -0400 Message-Id: <20210730170945.4468-3-programmingkidx@gmail.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) In-Reply-To: <20210730170945.4468-1-programmingkidx@gmail.com> References: <20210730170945.4468-1-programmingkidx@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::82b; envelope-from=programmingkidx@gmail.com; helo=mail-qt1-x82b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: John Arbuckle Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1627665105940100005 Content-Type: text/plain; charset="utf-8" For users who are use to using a Macintosh keyboard having to use a PC keyb= oard can be a pain because the Command/meta and Option/Alt keys are switched. To make life easier this option is added to allow the user to switch how the g= uest reacts to each of these keys being pushed. It can make a Macintosh keyboard= user feel almost at home with a PC keyboard. The same could be said for PC keybo= ard users who have to use a Macinosh keyboard. Based on patch by Gustavo Noronha Silva . Signed-off-by: John Arbuckle --- ui/cocoa.m | 66 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index fdef9e9901..98596d5f38 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -116,6 +116,7 @@ static void cocoa_switch(DisplayChangeListener *dcl, =20 static CFMachPortRef eventsTap =3D NULL; static CFRunLoopSourceRef eventsTapSource =3D NULL; +static bool swap_command_option_keys =3D false; =20 static void with_iothread_lock(CodeBlock block) { @@ -810,12 +811,22 @@ - (bool) handleEventLocked:(NSEvent *)event qkbd_state_key_event(kbd, Q_KEY_CODE_CTRL_R, false); } if (!(modifiers & NSEventModifierFlagOption)) { - qkbd_state_key_event(kbd, Q_KEY_CODE_ALT, false); - qkbd_state_key_event(kbd, Q_KEY_CODE_ALT_R, false); + if (swap_command_option_keys) { + qkbd_state_key_event(kbd, Q_KEY_CODE_META_L, false); + qkbd_state_key_event(kbd, Q_KEY_CODE_META_R, false); + } else { + qkbd_state_key_event(kbd, Q_KEY_CODE_ALT, false); + qkbd_state_key_event(kbd, Q_KEY_CODE_ALT_R, false); + } } if (!(modifiers & NSEventModifierFlagCommand)) { - qkbd_state_key_event(kbd, Q_KEY_CODE_META_L, false); - qkbd_state_key_event(kbd, Q_KEY_CODE_META_R, false); + if (swap_command_option_keys) { + qkbd_state_key_event(kbd, Q_KEY_CODE_ALT, false); + qkbd_state_key_event(kbd, Q_KEY_CODE_ALT_R, false); + } else { + qkbd_state_key_event(kbd, Q_KEY_CODE_META_L, false); + qkbd_state_key_event(kbd, Q_KEY_CODE_META_R, false); + } } =20 switch ([event type]) { @@ -847,13 +858,22 @@ - (bool) handleEventLocked:(NSEvent *)event =20 case kVK_Option: if (!!(modifiers & NSEventModifierFlagOption)) { - [self toggleKey:Q_KEY_CODE_ALT]; + if (swap_command_option_keys) { + [self toggleKey:Q_KEY_CODE_META_L]; + } else { + [self toggleKey:Q_KEY_CODE_ALT]; + } + } break; =20 case kVK_RightOption: if (!!(modifiers & NSEventModifierFlagOption)) { - [self toggleKey:Q_KEY_CODE_ALT_R]; + if (swap_command_option_keys) { + [self toggleKey:Q_KEY_CODE_META_R]; + } else { + [self toggleKey:Q_KEY_CODE_ALT_R]; + } } break; =20 @@ -861,14 +881,22 @@ - (bool) handleEventLocked:(NSEvent *)event case kVK_Command: if (isMouseGrabbed && !!(modifiers & NSEventModifierFlagCommand)) { - [self toggleKey:Q_KEY_CODE_META_L]; + if (swap_command_option_keys) { + [self toggleKey:Q_KEY_CODE_ALT]; + } else { + [self toggleKey:Q_KEY_CODE_META_L]; + } } break; =20 case kVK_RightCommand: if (isMouseGrabbed && !!(modifiers & NSEventModifierFlagCommand)) { - [self toggleKey:Q_KEY_CODE_META_R]; + if (swap_command_option_keys) { + [self toggleKey:Q_KEY_CODE_ALT_R]; + } else { + [self toggleKey:Q_KEY_CODE_META_R]; + } } break; } @@ -1188,6 +1216,7 @@ - (IBAction) do_about_menu_item: (id) sender; - (void)make_about_window; - (void)adjustSpeed:(id)sender; - (IBAction)doFullGrab:(id)sender; +- (IBAction)doSwapCommandOptionKeys:(id)sender; @end =20 @implementation QemuCocoaAppController @@ -1669,6 +1698,22 @@ - (IBAction)doFullGrab:(id) sender } } =20 +// The action method to the "Options->Swap Command and Option Keys" menu i= tem +- (IBAction)doSwapCommandOptionKeys:(id)sender +{ + // If the menu item is not checked + if ([sender state] =3D=3D NSControlStateValueOff) { + swap_command_option_keys =3D true; + [sender setState: NSControlStateValueOn]; + } + + // If the menu item is checked + else { + swap_command_option_keys =3D false; + [sender setState: NSControlStateValueOff]; + } +} + @end =20 @interface QemuApplication : NSApplication @@ -1762,6 +1807,11 @@ static void create_initial_menus(void) @"Full Keyboard Grab" action:@selector(doFullGrab= :) keyEquivalent:@""] autorelease]]; =20 + [menu addItem: [[[NSMenuItem alloc] initWithTitle: + @"Swap Command and Option= Keys" + action:@selector(doSwapComm= andOptionKeys:) + keyEquivalent:@""] autorelease]]; + menuItem =3D [[[NSMenuItem alloc] initWithTitle:@"Options" action:nil keyEquivalent:@""] autorelease]; [menuItem setSubmenu:menu]; --=20 2.24.3 (Apple Git-128)