Merge lp:~3v1n0/unity/dash-invalid-keys-filter-5.0 into lp:unity/5.0

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 2377
Proposed branch: lp:~3v1n0/unity/dash-invalid-keys-filter-5.0
Merge into: lp:unity/5.0
Diff against target: 394 lines (+189/-31)
5 files modified
plugins/unityshell/src/DashView.cpp (+19/-7)
plugins/unityshell/src/KeyboardUtil.cpp (+40/-12)
plugins/unityshell/src/KeyboardUtil.h (+13/-12)
tests/CMakeLists.txt (+2/-0)
tests/test_keyboard_util.cpp (+115/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/dash-invalid-keys-filter-5.0
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) Approve
Review via email: mp+112616@code.launchpad.net

Commit message

DashView: filter out the unprintable keys when focusing the search bar

The search bar can't be focused when invalid keys (such as shift, ctrl, F1...) are pressed.

Description of the change

To post a comment you must log in.
Revision history for this message
Andrea Azzarone (azzar1) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/DashView.cpp'
2--- plugins/unityshell/src/DashView.cpp 2012-04-24 08:20:00 +0000
3+++ plugins/unityshell/src/DashView.cpp 2012-06-28 17:26:31 +0000
4@@ -32,6 +32,7 @@
5 #include "DashStyle.h"
6 #include "DashSettings.h"
7 #include "UBusMessages.h"
8+#include "KeyboardUtil.h"
9
10 namespace unity
11 {
12@@ -804,15 +805,15 @@
13 }
14
15 Area* DashView::FindKeyFocusArea(unsigned int key_symbol,
16- unsigned long x11_key_code,
17- unsigned long special_keys_state)
18+ unsigned long x11_key_code,
19+ unsigned long special_keys_state)
20 {
21 // Do what nux::View does, but if the event isn't a key navigation,
22 // designate the text entry to process it.
23
24+ nux::KeyNavDirection direction = KEY_NAV_NONE;
25 bool ctrl = (special_keys_state & NUX_STATE_CTRL);
26
27- nux::KeyNavDirection direction = KEY_NAV_NONE;
28 switch (x11_key_code)
29 {
30 case NUX_VK_UP:
31@@ -850,7 +851,6 @@
32 break;
33 default:
34 direction = KEY_NAV_NONE;
35- break;
36 }
37
38 // We should not do it here, but I really don't want to make DashView
39@@ -858,7 +858,7 @@
40 // DashView::KeyNavIteration.
41 nux::InputArea* focus_area = nux::GetWindowCompositor().GetKeyFocusArea();
42
43- if (key_symbol == nux::NUX_KEYDOWN && !search_bar_->im_preedit)
44+ if (direction != KEY_NAV_NONE && key_symbol == nux::NUX_KEYDOWN && !search_bar_->im_preedit)
45 {
46 std::list<nux::Area*> tabs;
47 for (auto category : active_lens_view_->categories())
48@@ -933,7 +933,18 @@
49 }
50 }
51
52- if (direction == KEY_NAV_NONE || search_bar_->im_preedit)
53+ bool search_key = false;
54+
55+ if (direction == KEY_NAV_NONE)
56+ {
57+ if (ui::KeyboardUtil::IsPrintableKeySymbol(x11_key_code) ||
58+ ui::KeyboardUtil::IsMoveKeySymbol(x11_key_code))
59+ {
60+ search_key = true;
61+ }
62+ }
63+
64+ if (search_key || search_bar_->im_preedit)
65 {
66 // then send the event to the search entry
67 return search_bar_->text_entry();
68@@ -942,7 +953,8 @@
69 {
70 return next_object_to_key_focus_area_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state);
71 }
72- return NULL;
73+
74+ return nullptr;
75 }
76
77 }
78
79=== modified file 'plugins/unityshell/src/KeyboardUtil.cpp'
80--- plugins/unityshell/src/KeyboardUtil.cpp 2011-08-30 12:15:45 +0000
81+++ plugins/unityshell/src/KeyboardUtil.cpp 2012-06-28 17:26:31 +0000
82@@ -17,9 +17,8 @@
83 * Authored by: Jason Smith <jason.smith@canonical.com>
84 */
85
86+#include <gdk/gdk.h>
87 #include <string.h>
88-
89-#include <stdio.h>
90 #include <cmath>
91
92 #include "KeyboardUtil.h"
93@@ -31,7 +30,7 @@
94 : display_(display)
95 {
96 unsigned int fetch_mask = XkbGBN_KeyNamesMask | XkbGBN_ClientSymbolsMask | XkbGBN_GeometryMask;
97- keyboard_ = XkbGetKeyboard (display, fetch_mask, XkbUseCoreKbd);
98+ keyboard_ = XkbGetKeyboard (display, fetch_mask, XkbUseCoreKbd);
99 }
100
101 KeyboardUtil::~KeyboardUtil()
102@@ -39,7 +38,7 @@
103 XkbFreeKeyboard (keyboard_, 0, True);
104 }
105
106-bool KeyboardUtil::FindKeyInGeometry(XkbGeometryPtr geo, char *key_name, int& res_section, XkbBoundsRec& res_bounds)
107+bool KeyboardUtil::FindKeyInGeometry(XkbGeometryPtr geo, char *key_name, int& res_section, XkbBoundsRec& res_bounds) const
108 {
109 // seems that Xkb does not give null terminated strings... was painful
110 int name_length = XkbKeyNameLength;
111@@ -73,7 +72,7 @@
112 return false;
113 }
114
115-bool KeyboardUtil::CompareOffsets (int current_x, int current_y, int best_x, int best_y)
116+bool KeyboardUtil::CompareOffsets(int current_x, int current_y, int best_x, int best_y) const
117 {
118 // never EVER prefer something higher on the keyboard than what we have
119 if (current_y > best_y)
120@@ -85,7 +84,7 @@
121 return false;
122 }
123
124-guint KeyboardUtil::ConvertKeyToKeycode (XkbKeyPtr key)
125+guint KeyboardUtil::ConvertKeyToKeycode(XkbKeyPtr key) const
126 {
127 int min_code = keyboard_->min_key_code;
128 int max_code = keyboard_->max_key_code;
129@@ -98,7 +97,7 @@
130 return 0;
131 }
132
133-XkbBoundsRec KeyboardUtil::GetAbsoluteKeyBounds (XkbKeyPtr key, XkbRowPtr row, XkbSectionPtr section, XkbGeometryPtr geo)
134+XkbBoundsRec KeyboardUtil::GetAbsoluteKeyBounds(XkbKeyPtr key, XkbRowPtr row, XkbSectionPtr section, XkbGeometryPtr geo) const
135 {
136 XkbShapePtr shape = XkbKeyShape(geo, key);
137
138@@ -117,7 +116,7 @@
139 y_offset += local_shape->bounds.y2 - local_shape->bounds.y1;
140 else
141 x_offset += local_shape->bounds.x2 - local_shape->bounds.x1;
142-
143+
144 i++;
145 }
146
147@@ -129,7 +128,7 @@
148 return result;
149 }
150
151-bool KeyboardUtil::FindKeyInSectionAboveBounds (XkbGeometryPtr geo, int section_index, XkbBoundsRec const& target_bounds, guint &keycode)
152+bool KeyboardUtil::FindKeyInSectionAboveBounds(XkbGeometryPtr geo, int section_index, XkbBoundsRec const& target_bounds, guint &keycode) const
153 {
154 XkbKeyPtr best = NULL;
155 int best_x_offset = G_MAXINT;
156@@ -155,7 +154,7 @@
157 int center = (bounds.x1 + bounds.x2) / 2;
158 if (center < target_bounds.x1 || center > target_bounds.x2)
159 continue;
160-
161+
162 // make sure the key is actually above our target.
163 int current_y_offset = target_bounds.y1 - bounds.y2;
164 if (current_y_offset < 0)
165@@ -181,7 +180,7 @@
166 return false;
167 }
168
169-guint KeyboardUtil::GetKeycodeAboveKeySymbol(KeySym key_symbol)
170+guint KeyboardUtil::GetKeycodeAboveKeySymbol(KeySym key_symbol) const
171 {
172 guint result = 0;
173
174@@ -208,9 +207,38 @@
175 if (found_key)
176 result = maybe;
177 }
178-
179+
180 return result;
181 }
182
183+bool KeyboardUtil::IsPrintableKeySymbol(KeySym sym)
184+{
185+ bool printable_key = false;
186+
187+ if (sym == XK_Delete || sym == XK_BackSpace || sym == XK_Return)
188+ {
189+ printable_key = true;
190+ }
191+ else
192+ {
193+ unsigned int unicode = gdk_keyval_to_unicode(sym);
194+ printable_key = g_unichar_isprint(unicode);
195+ }
196+
197+ return printable_key;
198+}
199+
200+bool KeyboardUtil::IsMoveKeySymbol(KeySym sym)
201+{
202+ bool move_key = false;
203+
204+ if (sym >= XK_Home && sym <= XK_Begin)
205+ {
206+ move_key = true;
207+ }
208+
209+ return move_key;
210+}
211+
212 }
213 }
214\ No newline at end of file
215
216=== modified file 'plugins/unityshell/src/KeyboardUtil.h'
217--- plugins/unityshell/src/KeyboardUtil.h 2012-03-14 06:24:18 +0000
218+++ plugins/unityshell/src/KeyboardUtil.h 2012-06-28 17:26:31 +0000
219@@ -33,22 +33,23 @@
220
221 class KeyboardUtil
222 {
223-
224 public:
225-
226 KeyboardUtil(Display *display);
227- virtual ~KeyboardUtil();
228-
229- guint GetKeycodeAboveKeySymbol(KeySym key_symbol);
230+ ~KeyboardUtil();
231+
232+ guint GetKeycodeAboveKeySymbol(KeySym key_symbol) const;
233+
234+ static bool IsPrintableKeySymbol(KeySym key_symbol);
235+ static bool IsMoveKeySymbol(KeySym sym);
236
237 private:
238- bool CompareOffsets (int current_x, int current_y, int best_x, int best_y);
239- guint ConvertKeyToKeycode (XkbKeyPtr key);
240-
241- bool FindKeyInGeometry(XkbGeometryPtr geo, char *key_name, int& res_section, XkbBoundsRec& res_bounds);
242- bool FindKeyInSectionAboveBounds (XkbGeometryPtr geo, int section, XkbBoundsRec const& target_bounds, guint &keycode);
243-
244- XkbBoundsRec GetAbsoluteKeyBounds (XkbKeyPtr key, XkbRowPtr row, XkbSectionPtr section, XkbGeometryPtr geo);
245+ bool CompareOffsets (int current_x, int current_y, int best_x, int best_y) const;
246+ guint ConvertKeyToKeycode (XkbKeyPtr key) const;
247+
248+ bool FindKeyInGeometry(XkbGeometryPtr geo, char *key_name, int& res_section, XkbBoundsRec& res_bounds) const;
249+ bool FindKeyInSectionAboveBounds (XkbGeometryPtr geo, int section, XkbBoundsRec const& target_bounds, guint &keycode) const;
250+
251+ XkbBoundsRec GetAbsoluteKeyBounds (XkbKeyPtr key, XkbRowPtr row, XkbSectionPtr section, XkbGeometryPtr geo) const;
252
253 XkbDescPtr keyboard_;
254 Display *display_;
255
256=== modified file 'tests/CMakeLists.txt'
257--- tests/CMakeLists.txt 2012-06-19 17:04:29 +0000
258+++ tests/CMakeLists.txt 2012-06-28 17:26:31 +0000
259@@ -205,6 +205,7 @@
260 test_icon_loader.cpp
261 test_im_text_entry.cpp
262 test_hud_view.cpp
263+ test_keyboard_util.cpp
264 test_resultviewgrid.cpp
265 test_single_monitor_launcher_icon.cpp
266 test_switcher_controller.cpp
267@@ -242,6 +243,7 @@
268 ${UNITY_SRC}/LauncherHoverMachine.cpp
269 ${UNITY_SRC}/LauncherIcon.cpp
270 ${UNITY_SRC}/LauncherModel.cpp
271+ ${UNITY_SRC}/KeyboardUtil.cpp
272 ${UNITY_SRC}/OverlayRenderer.cpp
273 ${UNITY_SRC}/JSONParser.cpp
274 ${UNITY_SRC}/SearchBar.cpp
275
276=== added file 'tests/test_keyboard_util.cpp'
277--- tests/test_keyboard_util.cpp 1970-01-01 00:00:00 +0000
278+++ tests/test_keyboard_util.cpp 2012-06-28 17:26:31 +0000
279@@ -0,0 +1,115 @@
280+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
281+/*
282+ * Copyright (C) 2012 Canonical Ltd
283+ *
284+ * This program is free software: you can redistribute it and/or modify
285+ * it under the terms of the GNU General Public License version 3 as
286+ * published by the Free Software Foundation.
287+ *
288+ * This program is distributed in the hope that it will be useful,
289+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
290+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
291+ * GNU General Public License for more details.
292+ *
293+ * You should have received a copy of the GNU General Public License
294+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
295+ *
296+ * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
297+ */
298+
299+#include <gtest/gtest.h>
300+#include <algorithm>
301+
302+#include "KeyboardUtil.h"
303+
304+using namespace unity::ui;
305+
306+namespace
307+{
308+
309+void test_key(KeyboardUtil const& key_util, Display* x_display, const char* key)
310+{
311+ unsigned int above_keycode = key_util.GetKeycodeAboveKeySymbol(XStringToKeysym(key));
312+ KeySym above_keysym = XkbKeycodeToKeysym(x_display, above_keycode, 0, 1);
313+ EXPECT_NE(above_keysym, NoSymbol);
314+}
315+
316+TEST(TestKeyboardUtil, AboveKeySymbol)
317+{
318+ Display* x_display = XOpenDisplay(NULL);
319+
320+ KeyboardUtil key_util(x_display);
321+ test_key(key_util, x_display, "Tab");
322+ test_key(key_util, x_display, "Shift_R");
323+ test_key(key_util, x_display, "Control_L");
324+ test_key(key_util, x_display, "space");
325+ test_key(key_util, x_display, "comma");
326+ test_key(key_util, x_display, "a");
327+ test_key(key_util, x_display, "b");
328+ test_key(key_util, x_display, "c");
329+ test_key(key_util, x_display, "d");
330+ test_key(key_util, x_display, "e");
331+ test_key(key_util, x_display, "f");
332+ test_key(key_util, x_display, "g");
333+ test_key(key_util, x_display, "h");
334+ test_key(key_util, x_display, "i");
335+ test_key(key_util, x_display, "j");
336+ test_key(key_util, x_display, "k");
337+ test_key(key_util, x_display, "l");
338+ test_key(key_util, x_display, "m");
339+ test_key(key_util, x_display, "n");
340+ test_key(key_util, x_display, "o");
341+ test_key(key_util, x_display, "p");
342+ test_key(key_util, x_display, "k");
343+ test_key(key_util, x_display, "r");
344+ test_key(key_util, x_display, "s");
345+ test_key(key_util, x_display, "t");
346+ test_key(key_util, x_display, "u");
347+ test_key(key_util, x_display, "v");
348+ test_key(key_util, x_display, "w");
349+ test_key(key_util, x_display, "x");
350+ test_key(key_util, x_display, "y");
351+ test_key(key_util, x_display, "z");
352+}
353+
354+TEST(TestKeyboardUtil, PrintableKeySymbols)
355+{
356+ EXPECT_TRUE(KeyboardUtil::IsPrintableKeySymbol(XK_Delete));
357+ EXPECT_TRUE(KeyboardUtil::IsPrintableKeySymbol(XK_BackSpace));
358+ EXPECT_TRUE(KeyboardUtil::IsPrintableKeySymbol(XK_space));
359+ EXPECT_TRUE(KeyboardUtil::IsPrintableKeySymbol(XK_3));
360+ EXPECT_TRUE(KeyboardUtil::IsPrintableKeySymbol(XK_v));
361+ EXPECT_TRUE(KeyboardUtil::IsPrintableKeySymbol(XK_1));
362+ EXPECT_TRUE(KeyboardUtil::IsPrintableKeySymbol(XK_ntilde));
363+ EXPECT_TRUE(KeyboardUtil::IsPrintableKeySymbol(XK_0));
364+ EXPECT_TRUE(KeyboardUtil::IsPrintableKeySymbol(XK_exclam));
365+
366+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_F1));
367+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_Select));
368+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_Hyper_R));
369+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_Control_L));
370+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_Shift_L));
371+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_Super_L));
372+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_Print));
373+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_Insert));
374+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_Num_Lock));
375+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_Caps_Lock));
376+ EXPECT_FALSE(KeyboardUtil::IsPrintableKeySymbol(XK_ISO_Level3_Shift));
377+}
378+
379+TEST(TestKeyboardUtil, MoveKeySymbols)
380+{
381+ std::vector<KeySym> move_symbols { XK_Home, XK_Left, XK_Up, XK_Right, XK_Down,
382+ XK_Prior, XK_Page_Up, XK_Next, XK_Page_Down,
383+ XK_End, XK_Begin };
384+
385+ for (KeySym sym = 0; sym < XK_VoidSymbol; ++sym)
386+ {
387+ if (std::find(move_symbols.begin(), move_symbols.end(), sym) != move_symbols.end())
388+ EXPECT_TRUE(KeyboardUtil::IsMoveKeySymbol(sym));
389+ else
390+ EXPECT_FALSE(KeyboardUtil::IsMoveKeySymbol(sym));
391+ }
392+}
393+
394+} // Namespace

Subscribers

People subscribed via source and target branches