--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: kde-runtime: kglobalaccel_x11 ungrabs wrong X11 keycodes leading to non-functional delete key
- From: Edgar Fuß <ef@math.uni-bonn.de>
- Date: Thu, 7 Aug 2014 15:28:10 +0200
- Message-id: <20140807132805.GA31787@math.uni-bonn.de>
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;
};
--- End Message ---