On Sun, 6 Mar 2022, Akihiko Odaki wrote:
From: Gustavo Noronha Silva <gust...@noronha.dev.br>
On Mac OS X the Option key maps to Alt and Command to Super/Meta. This change
swaps them around so that Alt is the key closer to the space bar and Meta/Super
is between Control and Alt, like on non-Mac keyboards.
It is a cocoa display option, disabled by default.
Acked-by: Markus Armbruster <arm...@redhat.com>
Signed-off-by: Gustavo Noronha Silva <gust...@noronha.dev.br>
Message-Id: <20210713213200.2547-3-gust...@noronha.dev.br>
Signed-off-by: Akihiko Odaki <akihiko.od...@gmail.com>
---
qapi/ui.json | 7 ++++++-
qemu-options.hx | 2 +-
ui/cocoa.m | 46 ++++++++++++++++++++++++++++++++++++++--------
3 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/qapi/ui.json b/qapi/ui.json
index ff0a04da792..e28339887e0 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1270,10 +1270,15 @@
# a global grab on key events. (default: off)
# See https://support.apple.com/en-in/guide/mac-help/mh32356/mac
#
+# @swap-opt-cmd: Swap the Option and Command keys so that their key codes match
+# their position on non-Mac keyboards and you can use Meta/Super
+# and Alt where you expect them. (default: off)
+#
# Since: 7.0
##
{ 'struct' : 'DisplayCocoa',
- 'data' : { '*full-grab' : 'bool' } }
+ 'data' : { '*full-grab' : 'bool',
Indentation off now that next line became shorter.
Regards,
BALATON Zoltan
+ '*swap-opt-cmd' : 'bool' } }
##
# @DisplayType:
diff --git a/qemu-options.hx b/qemu-options.hx
index 4df9ccc3446..b57cbcb2c9e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1917,7 +1917,7 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
"-display curses[,charset=<encoding>]\n"
#endif
#if defined(CONFIG_COCOA)
- "-display cocoa[,full_grab=on|off]\n"
+ "-display cocoa[,full-grab=on|off][,swap-opt-cmd=on|off]\n"
#endif
#if defined(CONFIG_OPENGL)
"-display egl-headless[,rendernode=<file>]\n"
diff --git a/ui/cocoa.m b/ui/cocoa.m
index bfd602a96b9..ab9de404687 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -95,6 +95,7 @@ static void cocoa_switch(DisplayChangeListener *dcl,
};
static int last_buttons;
static int cursor_hide = 1;
+static bool swap_opt_cmd;
static int gArgc;
static char **gArgv;
@@ -853,12 +854,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_opt_cmd) {
+ 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_opt_cmd) {
+ 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);
+ }
}
switch ([event type]) {
@@ -890,13 +901,21 @@ - (bool) handleEventLocked:(NSEvent *)event
case kVK_Option:
if (!!(modifiers & NSEventModifierFlagOption)) {
- [self toggleKey:Q_KEY_CODE_ALT];
+ if (swap_opt_cmd) {
+ [self toggleKey:Q_KEY_CODE_META_L];
+ } else {
+ [self toggleKey:Q_KEY_CODE_ALT];
+ }
}
break;
case kVK_RightOption:
if (!!(modifiers & NSEventModifierFlagOption)) {
- [self toggleKey:Q_KEY_CODE_ALT_R];
+ if (swap_opt_cmd) {
+ [self toggleKey:Q_KEY_CODE_META_R];
+ } else {
+ [self toggleKey:Q_KEY_CODE_ALT_R];
+ }
}
break;
@@ -904,14 +923,22 @@ - (bool) handleEventLocked:(NSEvent *)event
case kVK_Command:
if (isMouseGrabbed &&
!!(modifiers & NSEventModifierFlagCommand)) {
- [self toggleKey:Q_KEY_CODE_META_L];
+ if (swap_opt_cmd) {
+ [self toggleKey:Q_KEY_CODE_ALT];
+ } else {
+ [self toggleKey:Q_KEY_CODE_META_L];
+ }
}
break;
case kVK_RightCommand:
if (isMouseGrabbed &&
!!(modifiers & NSEventModifierFlagCommand)) {
- [self toggleKey:Q_KEY_CODE_META_R];
+ if (swap_opt_cmd) {
+ [self toggleKey:Q_KEY_CODE_ALT_R];
+ } else {
+ [self toggleKey:Q_KEY_CODE_META_R];
+ }
}
break;
}
@@ -2130,6 +2157,9 @@ static void cocoa_display_init(DisplayState *ds,
DisplayOptions *opts)
if (opts->has_show_cursor && opts->show_cursor) {
cursor_hide = 0;
}
+ if (opts->u.cocoa.has_swap_opt_cmd) {
+ swap_opt_cmd = opts->u.cocoa.swap_opt_cmd;
+ }
// register vga output callbacks
register_displaychangelistener(&dcl);