Package: kde-runtime
Version: 4:4.8.4-2
Severity: normal
Tags: upstream patch

Kglobalaccel wants to register the Print key.
The X11 implementation (kglobalaccel_x11) looks up the X11 keycode for that Qt 
key, result is 107. It XGrabKey()s 107.
Later, the mapping changes. Kglobalaccel now unregisters all keys in order 
re-register them later.
Kglobalaccel unregisters the Print Key.
The X11 implementation looks up the X11 keycode, now being 111. It 
XUngrabKey()s 111.
This leaves 107 (which now is the Delete/,,Entfernen'' Key) still grabbed and 
thus non-functional.

Since this is a race condition between shortcut registration and keyboard 
mapping, it seems to appear randomly.

The bug has been filed (in 2011, including my original patch) as 
https://bugs.kde.org/269403, but no-one seems to pick it up.
We keep patching kdebase-runtime/kde-runtime since then.

I Include an updated patch for 4.8.3.

-- System Information:
Debian Release: 7.6
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.10.42.wap (SMP w/2 CPU cores)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages kde-runtime depends on:
ii  kde-runtime-data                4:4.8.4-2
ii  kdelibs5-plugins                4:4.8.4-4
ii  libasound2                      1.0.25-4
ii  libattica0                      0.2.0-1
ii  libc6                           2.13-38+deb7u3
ii  libcanberra0                    0.28-6
ii  libexiv2-12                     0.23-1
ii  libgcc1                         1:4.7.2-5
ii  libjpeg8                        8d-1+deb7u1
ii  libkcmutils4                    4:4.8.4-4
ii  libkdeclarative5                4:4.8.4-4
ii  libkdecore5                     4:4.8.4-4
ii  libkdesu5                       4:4.8.4-4
ii  libkdeui5                       4:4.8.4-4
ii  libkdewebkit5                   4:4.8.4-4
ii  libkdnssd4                      4:4.8.4-4
ii  libkemoticons4                  4:4.8.4-4
ii  libkfile4                       4:4.8.4-4
ii  libkhtml5                       4:4.8.4-4
ii  libkidletime4                   4:4.8.4-4
ii  libkio5                         4:4.8.4-4
ii  libkmediaplayer4                4:4.8.4-4
ii  libknewstuff3-4                 4:4.8.4-4
ii  libknotifyconfig4               4:4.8.4-4
ii  libkparts4                      4:4.8.4-4
ii  libkpty4                        4:4.8.4-4
ii  libnepomuk4                     4:4.8.4-4
ii  libnepomukquery4a               4:4.8.4-4
ii  libntrack-qt4-1                 016-1.1
ii  libopenexr6                     1.6.1-6
ii  libphonon4                      4:4.6.0.0-3
ii  libplasma3                      4:4.8.4-4
ii  libpulse-mainloop-glib0         2.0-6.1
ii  libpulse0                       2.0-6.1
ii  libqt4-dbus                     4:4.8.2+dfsg-11
ii  libqt4-declarative              4:4.8.2+dfsg-11
ii  libqt4-network                  4:4.8.2+dfsg-11
ii  libqt4-script                   4:4.8.2+dfsg-11
ii  libqt4-svg                      4:4.8.2+dfsg-11
ii  libqt4-xml                      4:4.8.2+dfsg-11
ii  libqtcore4                      4:4.8.2+dfsg-11
ii  libqtgui4                       4:4.8.2+dfsg-11
ii  libqtwebkit4                    2.2.1-5
ii  libsmbclient                    2:3.6.6-6+deb7u4
ii  libsolid4                       4:4.8.4-4
ii  libsoprano4                     2.7.6+dfsg.1-2wheezy1
ii  libssh-4                        0.5.4-1+deb7u1
ii  libstdc++6                      4.7.2-5
ii  libstreamanalyzer0              0.7.7-3
ii  libstreams0                     0.7.7-3
ii  libx11-6                        2:1.5.0-1+deb7u1
ii  libxcursor1                     1:1.1.13-1+deb7u1
ii  oxygen-icon-theme               4:4.8.4-1
ii  perl                            5.14.2-21+deb7u1
ii  phonon                          4:4.6.0.0-3
ii  plasma-scriptengine-javascript  4:4.8.4-2
ii  shared-desktop-ontologies       0.10.0-1

Versions of packages kde-runtime recommends:
ii  virtuoso-minimal  6.1.4+dfsg1-7

Versions of packages kde-runtime suggests:
ii  djvulibre-bin  3.5.25.3-1
pn  finger         <none>
pn  icoutils       <none>

-- no debconf information
Index: 4.8.4-2-mib/kglobalaccel/kglobalaccel_x11.cpp
===================================================================
--- 4.8.4-2-mib/kglobalaccel/kglobalaccel_x11.cpp       (revision 3582)
+++ 4.8.4-2-mib/kglobalaccel/kglobalaccel_x11.cpp       (revision 3583)
@@ -90,6 +90,8 @@
        uint keyModX;
        uint keySymX;
 
+       if (grab) {
+       /* not indented to keep the diff smaller */
        // Resolve the modifier
        if( !KKeyServer::keyQtToModX(keyQt, &keyModX) ) {
                kDebug() << "keyQt (0x" << hex << keyQt << ") failed to resolve 
to x11 modifier";
@@ -121,6 +123,27 @@
                kDebug() << "keyQt (0x" << hex << keyQt << ") was resolved to 
x11 keycode 0";
                return false;
        }
+       /* end of non-indented section */
+       } else {
+               // Make sure to use the same X11 keycode/modifier for ungrab
+               // that was used for grab. The mapping may have changed.
+               GrabbedKey *taken = 0;
+               for (int i = 0; i < m_grabbedKeys.size(); ++i) {
+                       if (m_grabbedKeys.at(i)->keyQt == keyQt) {
+                               taken = m_grabbedKeys.takeAt(i);
+                               break;
+                       }
+               }
+               if (taken) {
+                       keyCodeX = taken->keyCodeX;
+                       keyModX = taken->keyModX;
+                       // kDebug() << "found X11 keycode" << keyCodeX << 
"modifier" << hex << keyModX;
+                       delete taken;
+               } else {
+                       kDebug() << "keyQt (0x" << hex << keyQt << ") not in 
list of grabbed keys";
+                       return false;
+               }
+       }
 
        KXErrorHandler handler( XGrabErrorHandler );
 
@@ -155,6 +178,15 @@
                                if(( m & keyModMaskX ) == 0 )
                                        XUngrabKey( QX11Info::display(), 
keyCodeX, keyModX | m, QX11Info::appRootWindow() );
                        }
+               } else {
+                       // Remember the X11 keycode/modifier so as to be able
+                       // to ungrab the same combination later.
+                       // kDebug() << "remembering X11 keycode" << keyCodeX << 
"modifier" << hex << keyModX;
+                       GrabbedKey *grabbedKey = new GrabbedKey;
+                       grabbedKey->keyQt = keyQt;
+                       grabbedKey->keyCodeX = keyCodeX;
+                       grabbedKey->keyModX = keyModX;
+                       m_grabbedKeys << grabbedKey;
                }
        }
 
Index: 4.8.4-2-mib/kglobalaccel/kglobalaccel_x11.h
===================================================================
--- 4.8.4-2-mib/kglobalaccel/kglobalaccel_x11.h (revision 3582)
+++ 4.8.4-2-mib/kglobalaccel/kglobalaccel_x11.h (revision 3583)
@@ -20,6 +20,7 @@
 #ifndef _KGLOBALACCEL_X11_H
 #define _KGLOBALACCEL_X11_H
 
+#include <QtCore/QList>
 #include <QWidget>
 
 class GlobalShortcutsRegistry;
@@ -65,6 +66,19 @@
        virtual bool x11Event( XEvent* );
        void x11MappingNotify();
        bool x11KeyPress( const XEvent *pEvent );
+
+       /**
+        * List of Qt keycodes we grabbed and X11 keycode/modifiers
+        * we grabbed them under so we un-grab the same X11
+        * keycodes as we grabbed in case the mapping has changed
+        * in the meantime.
+        */
+       struct GrabbedKey {
+               int keyQt;
+               int keyCodeX;
+               uint keyModX;
+       };
+       QList<GrabbedKey *> m_grabbedKeys;
        
     GlobalShortcutsRegistry *m_owner;
 };

Reply via email to