Merge lp:~3v1n0/unity/ups-special-keys into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Andrea Azzarone
Approved revision: no longer in the source branch.
Merged at revision: 3890
Proposed branch: lp:~3v1n0/unity/ups-special-keys
Merge into: lp:unity
Diff against target: 207 lines (+92/-26)
3 files modified
services/panel-main.c (+10/-14)
services/panel-service.c (+76/-8)
unity-shared/GnomeKeyGrabber.cpp (+6/-4)
To merge this branch: bzr merge lp:~3v1n0/unity/ups-special-keys
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+240630@code.launchpad.net

Commit message

PanelService: inject special key events back to the root window when a menu is opened

This will make the multimedia keys to work also if an indicator menu is opened.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andrea Azzarone (azzar1) wrote :

LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'services/panel-main.c'
2--- services/panel-main.c 2014-09-19 18:38:21 +0000
3+++ services/panel-main.c 2014-11-04 19:05:13 +0000
4@@ -19,6 +19,7 @@
5 */
6
7 #include <glib.h>
8+#include <glib-unix.h>
9 #include <gio/gio.h>
10 #include <gtk/gtk.h>
11 #include <libido/libido.h>
12@@ -422,19 +423,14 @@
13 gtk_main_quit ();
14 }
15
16-static void
17-on_indicators_cleared (PanelService *service)
18-{
19- gtk_main_quit ();
20-}
21-
22-static void
23-on_signal (int sig)
24-{
25- PanelService *service = panel_service_get_default ();
26+static gboolean
27+on_unix_signal (gpointer data)
28+{
29+ PanelService *service = PANEL_SERVICE (data);
30+ g_signal_connect (service, "indicators-cleared",
31+ G_CALLBACK (gtk_main_quit), NULL);
32 panel_service_clear_indicators (service);
33- g_signal_connect (service, "indicators-cleared",
34- G_CALLBACK (on_indicators_cleared), NULL);
35+ return FALSE;
36 }
37
38 static void
39@@ -497,8 +493,8 @@
40 service,
41 NULL);
42
43- signal (SIGINT, on_signal);
44- signal (SIGTERM, on_signal);
45+ g_unix_signal_add (SIGINT, on_unix_signal, service);
46+ g_unix_signal_add (SIGTERM, on_unix_signal, service);
47
48 gtk_main ();
49
50
51=== modified file 'services/panel-service.c'
52--- services/panel-service.c 2014-09-19 19:17:00 +0000
53+++ services/panel-service.c 2014-11-04 19:05:13 +0000
54@@ -31,6 +31,7 @@
55 #include <libindicator/indicator-ng.h>
56
57 #include <X11/XKBlib.h>
58+#include <X11/XF86keysym.h>
59 #include <X11/extensions/XInput2.h>
60
61 #include <upstart.h>
62@@ -474,6 +475,64 @@
63 return FALSE;
64 }
65
66+static gboolean
67+is_special_keysym (KeySym keysym)
68+{
69+ /* Multimedia keys, see X11/XF86keysym.h */
70+ if (keysym >= 0x1008FF00 && keysym <= 0x1008FFFF)
71+ return TRUE;
72+
73+ return FALSE;
74+}
75+
76+static gboolean
77+is_control_keysym (KeySym keysym)
78+{
79+ if (!is_special_keysym (keysym))
80+ return FALSE;
81+
82+ /* Display backlight controls */
83+ if (keysym >= 0x1008FF01 && keysym <= 0x1008FF0F)
84+ return TRUE;
85+
86+ switch (keysym)
87+ {
88+ case XF86XK_Battery:
89+ case XF86XK_Bluetooth:
90+ case XF86XK_WLAN:
91+ case XF86XK_UWB:
92+ return !lockscreen_mode;
93+ case XF86XK_Suspend:
94+ case XF86XK_Hibernate:
95+ case XF86XK_Sleep:
96+ case XF86XK_PowerOff:
97+ case XF86XK_ScreenSaver:
98+ return lockscreen_mode;
99+ }
100+
101+ const gchar *keystr = XKeysymToString (keysym);
102+
103+ if (g_str_has_prefix (keystr, "XF86Audio") ||
104+ g_str_has_prefix (keystr, "XF86Touchpad"))
105+ {
106+ return TRUE;
107+ }
108+
109+ return FALSE;
110+}
111+
112+static gboolean
113+is_allowed_keysym (KeySym keysym)
114+{
115+ if (keysym == XK_Print)
116+ return TRUE;
117+
118+ if (is_special_keysym (keysym))
119+ return TRUE;
120+
121+ return FALSE;
122+}
123+
124 static GdkFilterReturn
125 event_filter (GdkXEvent *ev, GdkEvent *gev, PanelService *self)
126 {
127@@ -503,10 +562,18 @@
128 {
129 case XI_KeyPress:
130 {
131+ KeySym keysym = XkbKeycodeToKeysym (event->display, event->detail, 0, 0);
132+
133 if (lockscreen_mode)
134- break;
135+ {
136+ if (is_control_keysym (keysym))
137+ {
138+ reinject_key_event_to_root_window (event);
139+ ret = GDK_FILTER_REMOVE;
140+ }
141
142- KeySym keysym = XkbKeycodeToKeysym (event->display, event->detail, 0, 0);
143+ break;
144+ }
145
146 if (event_matches_keybinding (event->mods.base, keysym, &priv->menu_toggle) ||
147 event_matches_keybinding (event->mods.base, keysym, &priv->show_dash) ||
148@@ -519,9 +586,9 @@
149 }
150 else if (event->mods.base != GDK_CONTROL_MASK)
151 {
152- if (!IsModifierKey (keysym) && (event->mods.base != 0 || keysym == XK_Print))
153+ if (!IsModifierKey (keysym) && (event->mods.base != 0 || is_allowed_keysym (keysym)))
154 {
155- if (GTK_IS_MENU (priv->last_menu))
156+ if (GTK_IS_MENU (priv->last_menu) && !is_control_keysym (keysym))
157 gtk_menu_popdown (GTK_MENU (priv->last_menu));
158
159 reinject_key_event_to_root_window (event);
160@@ -593,19 +660,20 @@
161 }
162 }
163 }
164- else if (entry && (event->detail == 2 || event->detail == 4 || event->detail == 5))
165+ else if (entry && (event->detail == 2 || event->detail >= 4 || event->detail <= 7))
166 {
167 /* If we're scrolling or middle-clicking over an indicator
168 * (which is not an appmenu entry) then we need to send the
169 * event to the indicator itself, and avoid it to close */
170 gchar *entry_id = get_indicator_entry_id_by_entry (entry);
171
172- if (event->detail == 4 || event->detail == 5)
173+ if (event->detail >= 4 || event->detail <= 7)
174 {
175- gint32 delta = (event->detail == 4) ? 120 : -120;
176+ gint32 delta = (event->detail >= 6) ? NUX_HORIZONTAL_SCROLL_DELTA : NUX_VERTICAL_SCROLL_DELTA;
177+ delta = (event->detail % 2 == 0) ? delta : delta * -1;
178 panel_service_scroll_entry (self, entry_id, delta);
179 }
180- else if (entry == priv->pressed_entry)
181+ else if (event->detail == 2 && entry == priv->pressed_entry)
182 {
183 panel_service_secondary_activate_entry (self, entry_id);
184 }
185
186=== modified file 'unity-shared/GnomeKeyGrabber.cpp'
187--- unity-shared/GnomeKeyGrabber.cpp 2014-10-03 16:53:29 +0000
188+++ unity-shared/GnomeKeyGrabber.cpp 2014-11-04 19:05:13 +0000
189@@ -202,12 +202,14 @@
190
191 if (action.key().toString().empty())
192 {
193- CompString prefixed = "XF86" + CompString(accelerator);
194- LOG_DEBUG(logger) << "Can't grab \"" << accelerator << "\", trying \"" << prefixed << "\"";
195- action.keyFromString(prefixed);
196+ CompString prefixed = "XF86" + CompString(accelerator);
197+ LOG_DEBUG(logger) << "Can't grab \"" << accelerator << "\", trying \"" << prefixed << "\"";
198+ action.keyFromString(prefixed);
199 }
200 else
201- LOG_DEBUG(logger) << "grabAccelerator \"" << accelerator << "\"";
202+ {
203+ LOG_DEBUG(logger) << "grabAccelerator \"" << accelerator << "\"";
204+ }
205
206 if (!isActionPostponed(action))
207 {