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; };