[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#757364: kde-runtime: kglobalaccel_x11 ungrabs wrong X11 keycodes leading to non-functional delete key



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 to: