Hi,

There was some discussion on lyx-users a few years ago about patching Qt
to swap the Command and Control keys on the Mac for people who use Emacs
key bindings:
http://www.mail-archive.com/[EMAIL PROTECTED]/msg49883.html.

Since then, Jens Noeckel and I have occasionally compiled binaries with
the patch and posted links to them at
http://wiki.lyx.org/Mac/LyXmodifierKeys.  This is obviously not ideal.

I finally got around to making a better patch that configures the
swapping behavior at runtime based on a property in a preferences file.
The patch is appended below.  Details are posted on the LyXmodifierKeys
wiki page, along with a patched Universal binary of LyX 1.5.4 (built
with Qt/Mac 4.3.4) and scripts to create and apply the patch to a clean
Qt source distribution.  I also compiled and tested against the SVN
trunk (r24030), and it appears to work fine.

I believe the performance impact is negligible -- one or two extra "if"
tests on a static boolean each time a modifier key is pressed -- and
there is no change in Qt's behavior unless swapping is enabled.  Thanks
to Jens and Chris Menzel (on copy), it has now been tested on both PPC
and Intel Macs under both Tiger and Leopard.

Would the folks who maintain the Mac binaries (Bennett in particular)
consider incorporating this patch into future "official" Mac releases?

        -j

Jason Woodard
[EMAIL PROTECTED]



diff -Naur src/gui/kernel/qapplication_mac.cpp
src-patched/gui/kernel/qapplication_mac.cpp
--- src/gui/kernel/qapplication_mac.cpp 2008-03-23 22:25:23.000000000
+0800
+++ src-patched/gui/kernel/qapplication_mac.cpp 2008-03-23
22:26:56.000000000 +0800
@@ -157,6 +157,7 @@
 static bool qt_button_down_in_content; // whether the button_down was
in the content area.
 static bool qt_mac_previous_press_in_popup_mode = false;
 static bool qt_mac_no_click_through_mode = false;
+extern bool qt_mac_swap_modifiers;  // from qkeymapper_mac.cpp; keymap
hack
 static QPointer<QWidget> qt_mouseover;
 #if defined(QT_DEBUG)
 static bool        appNoGrab        = false;        // mouse/keyboard
grabbing
@@ -411,6 +412,12 @@
     if (appleValue.isValid())
         qt_antialiasing_threshold = appleValue.toInt();
 
+    // begin keymap hack
+    appleValue = appleSettings.value(QLatin1String("QtSwapModifiers"));
+    if (appleValue.isValid())
+        qt_mac_swap_modifiers = appleValue.toBool();
+    // end keymap hack
+
 #ifdef DEBUG_PLATFORM_SETTINGS
     qDebug("qt_mac_update_os_settings
*********************************************************************");
 #endif
diff -Naur src/gui/kernel/qkeymapper_mac.cpp
src-patched/gui/kernel/qkeymapper_mac.cpp
--- src/gui/kernel/qkeymapper_mac.cpp   2008-03-23 22:24:27.000000000
+0800
+++ src-patched/gui/kernel/qkeymapper_mac.cpp   2008-03-26
21:38:38.000000000 +0800
@@ -62,6 +62,7 @@
   Internal variables and functions
 
************************************************************************
*****/
 bool qt_mac_eat_unicode_key = false;
+bool qt_mac_swap_modifiers = false;  // keymap hack
 extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event);
//qapplication_mac.cpp
 
 Q_GUI_EXPORT void qt_mac_secure_keyboard(bool b)
@@ -144,20 +145,50 @@
     { kEventKeyModifierNumLockMask, QT_MAC_MAP_ENUM(Qt::KeypadModifier)
},
     { 0, QT_MAC_MAP_ENUM(0) }
 };
+
+// begin keymap hack
+static qt_mac_enum_mapper qt_mac_modifier_symbols_swapped[] = {
+    { shiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) },
+    { rightShiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) },
+    { controlKey, QT_MAC_MAP_ENUM(Qt::ControlModifier) },
+    { rightControlKey, QT_MAC_MAP_ENUM(Qt::ControlModifier) },
+    { cmdKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) },
+    { kEventKeyModifierNumLockMask, QT_MAC_MAP_ENUM(Qt::KeypadModifier)
},
+    { 0, QT_MAC_MAP_ENUM(0) }
+};
+// end keymap hack
+
 Qt::KeyboardModifiers qt_mac_get_modifiers(int keys)
 {
 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
     qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", keys,
keys);
 #endif
     Qt::KeyboardModifiers ret = Qt::NoModifier;
-    for(int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) {
-        if(keys & qt_mac_modifier_symbols[i].mac_code) {
+
+    // begin keymap hack
+    if(qt_mac_swap_modifiers) {
+        // same as below except use swapped array instead of original
one
+        for(int i = 0; qt_mac_modifier_symbols_swapped[i].qt_code; i++)
{
+            if(keys & qt_mac_modifier_symbols_swapped[i].mac_code) {
 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
-            qDebug("Qt: internal: got modifier: %s",
qt_mac_modifier_symbols[i].desc);
+                qDebug("Qt: internal: got swapped modifier: %s",
qt_mac_modifier_symbols_swapped[i].desc);
 #endif
-            ret |=
Qt::KeyboardModifier(qt_mac_modifier_symbols[i].qt_code);
+                ret |=
Qt::KeyboardModifier(qt_mac_modifier_symbols_swapped[i].qt_code);
+            }
+        }
+    } else {
+        // original code
+        for(int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) {
+            if(keys & qt_mac_modifier_symbols[i].mac_code) {
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+                qDebug("Qt: internal: got modifier: %s",
qt_mac_modifier_symbols[i].desc);
+#endif
+                ret |=
Qt::KeyboardModifier(qt_mac_modifier_symbols[i].qt_code);
+            }
         }
     }
+    // end keymap hack
+
     return ret;
 }
 static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys)
@@ -493,14 +524,29 @@
             static UInt32 tmp_state = 0L;
             if(*outModifiers & Qt::ShiftModifier)
                 tmp_mod |= shiftKey;
-            if(*outModifiers & Qt::MetaModifier)
-                tmp_mod |= controlKey;
-            if(*outModifiers & Qt::ControlModifier)
-                tmp_mod |= cmdKey;
+
+            // begin keymap hack
+            if(qt_mac_swap_modifiers) {
+                // same as below except swap cmd and control keys,
+                // and omit alt key to avoid interfering with
+                // accented characters
+                if(*outModifiers & Qt::MetaModifier)
+                    tmp_mod |= cmdKey;
+                if(*outModifiers & Qt::ControlModifier)
+                    tmp_mod |= controlKey;
+            } else {
+                // original code
+                if(*outModifiers & Qt::MetaModifier)
+                    tmp_mod |= controlKey;
+                if(*outModifiers & Qt::ControlModifier)
+                    tmp_mod |= cmdKey;
+                if(*outModifiers & Qt::AltModifier)
+                    tmp_mod |= optionKey;
+            } 
+            // end keymap hack
+
             if(GetCurrentEventKeyModifiers() & alphaLock) //no Qt
mapper
                 tmp_mod |= alphaLock;
-            if(*outModifiers & Qt::AltModifier)
-                tmp_mod |= optionKey;
             if(*outModifiers & Qt::KeypadModifier)
                 tmp_mod |= kEventKeyModifierNumLockMask;
             translatedChar = KeyTranslate(keyboard_layout, tmp_mod |
keyCode, &tmp_state);

Reply via email to