summaryrefslogtreecommitdiff
path: root/community/gnome-panel/18_fix_force_quit_applet.patch
blob: 8a72c9262e97016ceb31967d1be7d783d5a62e3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
Description: Fix Force-Quit panel applet
 This patch implements handling of XInput2 extension events in the applet.
 Without this patch, the applet fails to recognize such events (either mouse
 click for killing application, or escape key for exiting), hence freezing the
 desktop.
 .
 Also fix the event mask in call of gdk_device_grab() for keyboard.
Author: Sébastien Villemot <sebastien@debian.org>
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698740
Forwarded: no
Last-Update: 2013-01-28
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/gnome-panel/panel-force-quit.c
+++ b/gnome-panel/panel-force-quit.c
@@ -32,6 +32,8 @@
 #include <X11/Xlib.h>
 #include <X11/keysym.h>
 
+#include <X11/extensions/XInput2.h>
+
 #include "panel-icon-names.h"
 #include "panel-stock-icons.h"
 
@@ -246,22 +248,23 @@
 
 static void 
 handle_button_press_event (GtkWidget *popup,
-			   XKeyEvent *event)
+			   Display *display,
+			   Window subwindow)
 {
 	Window window;
 
 	remove_popup (popup);
 
-	if (event->subwindow == None)
+	if (subwindow == None)
 		return;
 
 	if (wm_state_atom == None)
-		wm_state_atom = XInternAtom (event->display, "WM_STATE", FALSE);
+		wm_state_atom = XInternAtom (display, "WM_STATE", FALSE);
 
-	window = find_managed_window (event->display, event->subwindow);
+	window = find_managed_window (display, subwindow);
 
 	if (window != None) {
-		if (!gdk_x11_window_lookup_for_display (gdk_x11_lookup_xdisplay (event->display), window))
+		if (!gdk_x11_window_lookup_for_display (gdk_x11_lookup_xdisplay (display), window))
 			kill_window_question ((gpointer) window);
 	}
 }
@@ -272,10 +275,12 @@
 	      GtkWidget *popup)
 {
 	XEvent *xevent = (XEvent *) gdk_xevent;
+	XIEvent *xiev;
+	XIDeviceEvent *xidev;
 
 	switch (xevent->type) {
 	case ButtonPress:
-		handle_button_press_event (popup, &xevent->xkey);
+		handle_button_press_event (popup, xevent->xbutton.display, xevent->xbutton.subwindow);
 		return GDK_FILTER_REMOVE;
 	case KeyPress:
 		if (xevent->xkey.keycode == XKeysymToKeycode (xevent->xany.display, XK_Escape)) {
@@ -283,6 +288,21 @@
 			return GDK_FILTER_REMOVE;
 		}
 		break;
+	case GenericEvent:
+		xiev = (XIEvent *) xevent->xcookie.data;
+		xidev = (XIDeviceEvent *) xiev;
+		switch (xiev->evtype) {
+		case XI_KeyPress:
+			if (xidev->detail == XKeysymToKeycode (xevent->xany.display, XK_Escape)) {
+				remove_popup (popup);
+				return GDK_FILTER_REMOVE;
+			}
+			break;
+		case XI_ButtonPress:
+			handle_button_press_event (popup, xidev->display, xidev->child);
+			return GDK_FILTER_REMOVE;
+		}
+		break;
 	default:
 		break;
 	}
@@ -331,7 +351,7 @@
 
 	status = gdk_device_grab (keyboard, root,
 				  GDK_OWNERSHIP_NONE, FALSE,
-				  GDK_KEY_PRESS | GDK_KEY_RELEASE,
+				  GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
 				  NULL, time);
 	if (status != GDK_GRAB_SUCCESS) {
 		g_warning ("Keyboard grab failed\n");