Bug 102742 - KGlobalAccel conflicts with Mode_switch handling on SunRay
Summary: KGlobalAccel conflicts with Mode_switch handling on SunRay
Status: RESOLVED FIXED
Alias: None
Product: kdelibs
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: unspecified
Platform: Debian testing Linux
: NOR normal
Target Milestone: ---
Assignee: Stephan Kulow
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-03-29 14:24 UTC by Nikita V. Youshchenko
Modified: 2005-03-29 16:26 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nikita V. Youshchenko 2005-03-29 14:24:46 UTC
Version:            (using KDE KDE 3.3.2)
Installed from:    Debian testing/unstable Packages
OS:                Linux

Kde global accelerators (like Ctrl+Fn to switch desktops, Alt_F2 for Run Command, etc) don't work on SunRay terminals, served from a Debian Linux server, if keyboard is in Russian mode. Accelerators work OK when keyboard is in English mode.

This is caused by the way how SunRay's handle keyboard mode switch. The X server used (Xnewt) does not support XKB. The only way to implement two-language keyboard is to write a xmodmap file, that defines 4-keysym mappings, and maps Mode_switch to mod3 (note that only mapping to mod3 works, mapping to any other X modifier does not).

This makes most things work correctly, but not KGlobalAccel, which becomes confused by mod3 bit set in state of incoming X KeyPress/KeyRelease events.

This may be fixed by applying the following patch to libkdecore (patch done for KDE 3.3, but almost same applies to KDE 3.4).

diff -urN kdecore.orig/kglobalaccel_x11.cpp kdecore/kglobalaccel_x11.cpp
--- kdecore.orig/kglobalaccel_x11.cpp   2004-10-03 11:40:15.000000000 +0400
+++ kdecore/kglobalaccel_x11.cpp        2005-03-29 15:21:45.461660064 +0400
@@ -49,7 +49,8 @@
        g_keyModMaskXOnOrOff =
                        KKeyServer::modXLock() |
                        KKeyServer::modXNumLock() |
-                       KKeyServer::modXScrollLock();
+                       KKeyServer::modXScrollLock() |
+                       KKeyServer::modXModeSwitch();
        //kdDebug() << "g_keyModMaskXAccel = " << g_keyModMaskXAccel
        //      << "g_keyModMaskXOnOrOff = " << g_keyModMaskXOnOrOff << endl;
 }
diff -urN kdecore.orig/kkeynative.h kdecore/kkeynative.h
--- kdecore.orig/kkeynative.h   2003-08-18 12:45:04.000000000 +0400
+++ kdecore/kkeynative.h        2005-03-29 15:18:46.000000000 +0400
@@ -235,6 +235,13 @@
         */
        static uint modXScrollLock();

+       /**
+        * Returns the X11 Mode_switch modifier mask/flag.
+        * @return the X11 Mode_switch modifier mask/flag.
+        * @see accelModMaskX()
+        */
+       static uint modXModeSwitch();
+
  private:
        uint m_code, m_mod, m_sym;
        KKeyNativePrivate* d;
diff -urN kdecore.orig/kkeyserver_x11.cpp kdecore/kkeyserver_x11.cpp
--- kdecore.orig/kkeyserver_x11.cpp     2004-05-23 00:55:09.000000000 +0400
+++ kdecore/kkeyserver_x11.cpp  2005-03-29 15:21:03.000000000 +0400
@@ -283,13 +283,13 @@
 //---------------------------------------------------------------------
 static bool g_bInitializedMods, g_bInitializedVariations, g_bInitializedKKeyLabels;
 static bool g_bMacLabels;
-static uint g_modXNumLock, g_modXScrollLock;
+static uint g_modXNumLock, g_modXScrollLock, g_modXModeSwitch;

 bool initializeMods()
 {
        XModifierKeymap* xmk = XGetModifierMapping( qt_xdisplay() );

-       g_rgModInfo[3].modX = g_modXNumLock = g_modXScrollLock = 0;
+       g_rgModInfo[3].modX = g_modXNumLock = g_modXScrollLock = g_modXModeSwitch = 0;

         int min_keycode, max_keycode;
         int keysyms_per_keycode = 0;
@@ -313,6 +313,7 @@
                        case XK_Meta_L:
                        case XK_Meta_R:      if( !g_rgModInfo[3].modX ) g_rgModInfo[3].modX = mask; break; // Win alternate
                        case XK_Scroll_Lock: g_modXScrollLock = mask; break;  // Normally Mod5Mask
+                       case XK_Mode_switch: g_modXModeSwitch = mask; break;
                }
        }

@@ -533,6 +534,7 @@
 uint modXNumLock()    { if( !g_bInitializedMods ) { initializeMods(); } return g_modXNumLock; }
 uint modXWin()        { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX; }
 uint modXScrollLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXScrollLock; }
+uint modXModeSwitch() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXModeSwitch; }

 uint accelModMaskX()
 {
Comment 1 Lubos Lunak 2005-03-29 16:25:05 UTC
Please use attachments for patches next time, I had to redo the patch manually.
Comment 2 Lubos Lunak 2005-03-29 16:26:07 UTC
CVS commit by lunakl: 

Ignore also Mode Switch modifier.
BUG: 102742


  M +2 -1      kglobalaccel_x11.cpp   1.34
  M +8 -0      kkeynative.h   1.14
  M +1 -0      kkeynative_x11.cpp   1.24
  M +4 -2      kkeyserver_x11.cpp   1.35
  M +8 -0      kkeyserver_x11.h   1.17


--- kdelibs/kdecore/kglobalaccel_x11.cpp  #1.33:1.34
@@ -69,5 +69,6 @@ static void calculateGrabMasks()
                         KKeyServer::modXLock() |
                         KKeyServer::modXNumLock() |
-                        KKeyServer::modXScrollLock();
+                        KKeyServer::modXScrollLock() | 
+                        KKeyServer::modXModeSwitch(); 
         //kdDebug() << "g_keyModMaskXAccel = " << g_keyModMaskXAccel
         //      << "g_keyModMaskXOnOrOff = " << g_keyModMaskXOnOrOff << endl;

--- kdelibs/kdecore/kkeynative.h  #1.13:1.14
@@ -241,4 +241,12 @@ class KDECORE_EXPORT KKeyNative
          */
         static uint modXScrollLock();
+
+        /** 
+         * Returns the X11 Mode_switch modifier mask/flag. 
+         * @return the X11 Mode_switch modifier mask/flag. 
+         * @see accelModMaskX() 
+         * @since 3.5
+         */ 
+        static uint modXModeSwitch(); 
 #endif
 

--- kdelibs/kdecore/kkeynative_x11.cpp  #1.23:1.24
@@ -193,4 +193,5 @@ uint KKeyNative::modXNumLock()          
 uint KKeyNative::modXLock()                    { return KKeyServer::modXLock(); }
 uint KKeyNative::modXScrollLock()              { return KKeyServer::modXScrollLock(); }
+uint KKeyNative::modXModeSwitch()              { return KKeyServer::modXModeSwitch(); }
 #endif
 

--- kdelibs/kdecore/kkeyserver_x11.cpp  #1.34:1.35
@@ -325,5 +325,5 @@ static bool g_bInitializedMods, g_bIniti
 static bool g_bMacLabels;
 #ifdef Q_WS_X11
-static uint g_modXNumLock, g_modXScrollLock;
+static uint g_modXNumLock, g_modXScrollLock, g_modXModeSwitch; 
 
 bool initializeMods()
@@ -331,5 +331,5 @@ bool initializeMods()
         XModifierKeymap* xmk = XGetModifierMapping( qt_xdisplay() );
 
-        g_rgModInfo[3].modX = g_modXNumLock = g_modXScrollLock = 0;
+        g_rgModInfo[3].modX = g_modXNumLock = g_modXScrollLock = g_modXModeSwitch = 0; 
 
         int min_keycode, max_keycode;
@@ -355,4 +355,5 @@ bool initializeMods()
                         case XK_Meta_R:      if( !g_rgModInfo[3].modX ) g_rgModInfo[3].modX = mask; break; // Win alternate
                         case XK_Scroll_Lock: g_modXScrollLock = mask; break;  // Normally Mod5Mask
+                        case XK_Mode_switch: g_modXModeSwitch = mask; break; 
                 }
         }
@@ -610,4 +611,5 @@ uint modXNumLock()    { if( !g_bInitiali
 uint modXWin()        { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX; }
 uint modXScrollLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXScrollLock; }
+uint modXModeSwitch() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXModeSwitch; } 
 
 uint accelModMaskX()

--- kdelibs/kdecore/kkeyserver_x11.h  #1.16:1.17
@@ -326,4 +326,12 @@ namespace KKeyServer
 
         /**
+         * Returns the X11 Mode_switch modifier mask/flag. 
+         * @return the X11 Mode_switch modifier mask/flag. 
+         * @see accelModMaskX()
+         * @since 3.5
+         */
+        KDECORE_EXPORT uint modXModeSwitch();
+
+        /**
          * Returns bitwise OR'ed mask containing Shift, Ctrl, Alt, and
          * Win (if available).