ui/cocoa: add option to swap Option and Command
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 <armbru@redhat.com> Signed-off-by: Gustavo Noronha Silva <gustavo@noronha.dev.br> Message-Id: <20210713213200.2547-3-gustavo@noronha.dev.br> Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com> Message-Id: <20220306121119.45631-3-akihiko.odaki@gmail.com> Reviewed-by: Will Cohen <wwcohen@gmail.com> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
This commit is contained in:
parent
f844cdb997
commit
4797adce5f
@ -1275,12 +1275,17 @@
|
||||
# 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': {
|
||||
'*left-command-key': 'bool',
|
||||
'*full-grab': 'bool'
|
||||
'*full-grab': 'bool',
|
||||
'*swap-opt-cmd': 'bool'
|
||||
} }
|
||||
|
||||
##
|
||||
|
@ -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"
|
||||
|
49
ui/cocoa.m
49
ui/cocoa.m
@ -96,6 +96,7 @@ static DisplayChangeListener dcl = {
|
||||
static int last_buttons;
|
||||
static int cursor_hide = 1;
|
||||
static int left_command_key_enabled = 1;
|
||||
static bool swap_opt_cmd;
|
||||
|
||||
static int gArgc;
|
||||
static char **gArgv;
|
||||
@ -854,12 +855,22 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
||||
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]) {
|
||||
@ -891,29 +902,44 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
||||
|
||||
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;
|
||||
|
||||
/* Don't pass command key changes to guest unless mouse is grabbed */
|
||||
case kVK_Command:
|
||||
if (isMouseGrabbed &&
|
||||
!!(modifiers & NSEventModifierFlagCommand) &&
|
||||
left_command_key_enabled) {
|
||||
[self toggleKey:Q_KEY_CODE_META_L];
|
||||
!!(modifiers & NSEventModifierFlagCommand)) {
|
||||
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;
|
||||
}
|
||||
@ -2068,6 +2094,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;
|
||||
}
|
||||
|
||||
if (opts->u.cocoa.has_left_command_key && !opts->u.cocoa.left_command_key) {
|
||||
left_command_key_enabled = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user