[PATCH v2] winemac: Allow Command to be mapped to Ctrl.

Ricky Zhou ricky at rzhou.org
Wed Sep 12 04:35:30 CDT 2018


Adds the following registry options, which configure the Mac driver to
map Command to Ctrl:

HKEY_CURRENT_USER\Software\Wine\Mac Driver\LeftCommandIsCtrl
HKEY_CURRENT_USER\Software\Wine\Mac Driver\RightCommandIsCtrl

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=35351
Signed-off-by: Ricky Zhou <ricky at rzhou.org>
---
v2: Fix comment, add warning about making it impossible to send Alt.
---
 dlls/winemac.drv/cocoa_window.m | 37 +++++++++++++++++++--------------
 dlls/winemac.drv/macdrv_cocoa.h |  2 ++
 dlls/winemac.drv/macdrv_main.c  | 12 +++++++++++
 3 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m
index 4143d147df..e405cda2d2 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -140,22 +140,27 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         *modifiers &= ~NX_ALTERNATEMASK;
 }
 
-static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modifiers)
+static inline NSUInteger adjusted_modifiers_for_settings(NSUInteger modifiers)
 {
     fix_device_modifiers_by_generic(&modifiers);
-    if (left_option_is_alt && (modifiers & NX_DEVICELALTKEYMASK))
-    {
-        modifiers |= NX_DEVICELCMDKEYMASK;
-        modifiers &= ~NX_DEVICELALTKEYMASK;
-    }
-    if (right_option_is_alt && (modifiers & NX_DEVICERALTKEYMASK))
-    {
-        modifiers |= NX_DEVICERCMDKEYMASK;
-        modifiers &= ~NX_DEVICERALTKEYMASK;
-    }
-    fix_generic_modifiers_by_device(&modifiers);
-
-    return modifiers;
+    NSUInteger new_modifiers = modifiers & ~(NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK |
+                                             NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK);
+
+    // The MACDRV keyboard driver translates Command keys to Alt. If the
+    // Option key (NX_DEVICE[LR]ALTKEYMASK) should behave like Alt in
+    // Windows, rewrite it to Command (NX_DEVICE[LR]CMDKEYMASK).
+    if (modifiers & NX_DEVICELALTKEYMASK)
+        new_modifiers |= left_option_is_alt ? NX_DEVICELCMDKEYMASK : NX_DEVICELALTKEYMASK;
+    if (modifiers & NX_DEVICERALTKEYMASK)
+        new_modifiers |= right_option_is_alt ? NX_DEVICERCMDKEYMASK : NX_DEVICERALTKEYMASK;
+
+    if (modifiers & NX_DEVICELCMDKEYMASK)
+        new_modifiers |= left_command_is_ctrl ? NX_DEVICELCTLKEYMASK : NX_DEVICELCMDKEYMASK;
+    if (modifiers & NX_DEVICERCMDKEYMASK)
+        new_modifiers |= right_command_is_ctrl ? NX_DEVICERCTLKEYMASK : NX_DEVICERCMDKEYMASK;
+
+    fix_generic_modifiers_by_device(&new_modifiers);
+    return new_modifiers;
 }
 
 
@@ -2059,7 +2064,7 @@ - (void) postKeyEvent:(NSEvent *)theEvent
         [self flagsChanged:theEvent];
         [self postKey:[theEvent keyCode]
               pressed:[theEvent type] == NSKeyDown
-            modifiers:adjusted_modifiers_for_option_behavior([theEvent modifierFlags])
+            modifiers:adjusted_modifiers_for_settings([theEvent modifierFlags])
                 event:theEvent];
     }
 
@@ -2679,7 +2684,7 @@ - (void) flagsChanged:(NSEvent *)theEvent
             { NX_DEVICERCMDKEYMASK,     kVK_RightCommand },
         };
 
-        NSUInteger modifierFlags = adjusted_modifiers_for_option_behavior([theEvent modifierFlags]);
+        NSUInteger modifierFlags = adjusted_modifiers_for_settings([theEvent modifierFlags]);
         NSUInteger changed;
         int i, last_changed;
 
diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h
index 6bad7903f6..011b1ffd37 100644
--- a/dlls/winemac.drv/macdrv_cocoa.h
+++ b/dlls/winemac.drv/macdrv_cocoa.h
@@ -159,6 +159,8 @@
 extern int capture_displays_for_fullscreen DECLSPEC_HIDDEN;
 extern int left_option_is_alt DECLSPEC_HIDDEN;
 extern int right_option_is_alt DECLSPEC_HIDDEN;
+extern int left_command_is_ctrl DECLSPEC_HIDDEN;
+extern int right_command_is_ctrl DECLSPEC_HIDDEN;
 extern int allow_immovable_windows DECLSPEC_HIDDEN;
 extern int cursor_clipping_locks_windows DECLSPEC_HIDDEN;
 extern int use_precise_scrolling DECLSPEC_HIDDEN;
diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c
index 7abeea9db8..544d448f9f 100644
--- a/dlls/winemac.drv/macdrv_main.c
+++ b/dlls/winemac.drv/macdrv_main.c
@@ -52,6 +52,8 @@ BOOL allow_vsync = TRUE;
 BOOL allow_set_gamma = TRUE;
 int left_option_is_alt = 0;
 int right_option_is_alt = 0;
+int left_command_is_ctrl = 0;
+int right_command_is_ctrl = 0;
 BOOL allow_software_rendering = FALSE;
 BOOL disable_window_decorations = FALSE;
 int allow_immovable_windows = TRUE;
@@ -172,6 +174,16 @@ static void setup_options(void)
     if (!get_config_key(hkey, appkey, "RightOptionIsAlt", buffer, sizeof(buffer)))
         right_option_is_alt = IS_OPTION_TRUE(buffer[0]);
 
+    if (!get_config_key(hkey, appkey, "LeftCommandIsCtrl", buffer, sizeof(buffer)))
+        left_command_is_ctrl = IS_OPTION_TRUE(buffer[0]);
+    if (!get_config_key(hkey, appkey, "RightCommandIsCtrl", buffer, sizeof(buffer)))
+        right_command_is_ctrl = IS_OPTION_TRUE(buffer[0]);
+
+    if (left_command_is_ctrl && right_command_is_ctrl && !left_option_is_alt && !right_option_is_alt)
+        WARN("Both Command keys have been mapped to Control. There is no way to "
+             "send an Alt key to Windows applications. Consider enabling "
+             "LeftOptionIsAlt or RightOptionIsAlt.\n");
+
     if (!get_config_key(hkey, appkey, "AllowSoftwareRendering", buffer, sizeof(buffer)))
         allow_software_rendering = IS_OPTION_TRUE(buffer[0]);
 
-- 
2.18.0




More information about the wine-devel mailing list