Merge lp:~3v1n0/unity/near-tab-key-support 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: 4040
Proposed branch: lp:~3v1n0/unity/near-tab-key-support
Merge into: lp:unity
Prerequisite: lp:~3v1n0/unity/switcher-dynamic-model
Diff against target: 647 lines (+352/-117)
9 files modified
launcher/SwitcherController.cpp (+19/-0)
launcher/SwitcherControllerImpl.h (+2/-0)
launcher/SwitcherModel.cpp (+1/-1)
launcher/SwitcherModel.h (+1/-1)
launcher/SwitcherView.cpp (+2/-2)
launcher/SwitcherView.h (+1/-0)
tests/test_keyboard_util.cpp (+138/-38)
unity-shared/XKeyboardUtil.cpp (+185/-75)
unity-shared/XKeyboardUtil.h (+3/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/near-tab-key-support
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+276438@code.launchpad.net

Commit message

XKeyboardUtil: add ability to get keycodes from any relative position

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

Nice.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/SwitcherController.cpp'
2--- launcher/SwitcherController.cpp 2015-11-09 23:58:16 +0000
3+++ launcher/SwitcherController.cpp 2015-11-09 23:58:16 +0000
4@@ -154,6 +154,24 @@
5 }
6 }
7
8+void Controller::Impl::CloseSelection()
9+{
10+ if (obj_->detail())
11+ {
12+ if (model_->detail_selection)
13+ {
14+ WindowManager::Default().Close(model_->DetailSelectionWindow());
15+ }
16+ }
17+ else
18+ {
19+ // Using model_->Selection()->Close() would be nicer, but it wouldn't take
20+ // in consideration the workspace related settings
21+ for (auto window : model_->DetailXids())
22+ WindowManager::Default().Close(window);
23+ }
24+}
25+
26 void Controller::Next()
27 {
28 impl_->Next();
29@@ -443,6 +461,7 @@
30 view_->switcher_prev.connect(sigc::mem_fun(this, &Impl::Prev));
31 view_->switcher_start_detail.connect(sigc::mem_fun(this, &Impl::StartDetailMode));
32 view_->switcher_stop_detail.connect(sigc::mem_fun(this, &Impl::StopDetailMode));
33+ view_->switcher_close_current.connect(sigc::mem_fun(this, &Impl::CloseSelection));
34
35 ConstructWindow();
36 main_layout_->AddView(view_.GetPointer(), 1);
37
38=== modified file 'launcher/SwitcherControllerImpl.h'
39--- launcher/SwitcherControllerImpl.h 2015-11-09 23:58:16 +0000
40+++ launcher/SwitcherControllerImpl.h 2015-11-09 23:58:16 +0000
41@@ -62,6 +62,8 @@
42 void NextDetail();
43 void PrevDetail();
44
45+ void CloseSelection();
46+
47 void NextDetailRow();
48 void PrevDetailRow();
49 bool HasNextDetailRow() const;
50
51=== modified file 'launcher/SwitcherModel.cpp'
52--- launcher/SwitcherModel.cpp 2015-11-09 23:58:16 +0000
53+++ launcher/SwitcherModel.cpp 2015-11-09 23:58:16 +0000
54@@ -51,7 +51,7 @@
55 }
56
57
58-SwitcherModel::SwitcherModel(std::vector<AbstractLauncherIcon::Ptr> const& icons, bool sort_by_priority)
59+SwitcherModel::SwitcherModel(Applications const& icons, bool sort_by_priority)
60 : detail_selection(false)
61 , detail_selection_index(0)
62 , only_apps_on_viewport(true)
63
64=== modified file 'launcher/SwitcherModel.h'
65--- launcher/SwitcherModel.h 2015-11-09 23:58:16 +0000
66+++ launcher/SwitcherModel.h 2015-11-09 23:58:16 +0000
67@@ -61,7 +61,7 @@
68 nux::Property<unsigned int> detail_selection_index;
69 nux::Property<bool> only_apps_on_viewport;
70
71- SwitcherModel(std::vector<launcher::AbstractLauncherIcon::Ptr> const& icons, bool sort_by_priority);
72+ SwitcherModel(Applications const&, bool sort_by_priority);
73 virtual ~SwitcherModel() = default;
74
75 iterator begin();
76
77=== modified file 'launcher/SwitcherView.cpp'
78--- launcher/SwitcherView.cpp 2015-11-09 23:58:16 +0000
79+++ launcher/SwitcherView.cpp 2015-11-09 23:58:16 +0000
80@@ -500,8 +500,8 @@
81 case NUX_VK_DOWN:
82 switcher_start_detail.emit();
83 break;
84- default:
85- return false;
86+ case NUX_VK_q:
87+ switcher_close_current.emit();
88 break;
89 }
90 }
91
92=== modified file 'launcher/SwitcherView.h'
93--- launcher/SwitcherView.h 2014-07-15 16:28:45 +0000
94+++ launcher/SwitcherView.h 2015-11-09 23:58:16 +0000
95@@ -85,6 +85,7 @@
96 sigc::signal<void> switcher_prev;
97 sigc::signal<void> switcher_start_detail;
98 sigc::signal<void> switcher_stop_detail;
99+ sigc::signal<void> switcher_close_current;
100
101 /* void; bool visible */
102 sigc::signal<void, bool> hide_request;
103
104=== modified file 'tests/test_keyboard_util.cpp'
105--- tests/test_keyboard_util.cpp 2012-10-11 01:44:15 +0000
106+++ tests/test_keyboard_util.cpp 2015-11-09 23:58:16 +0000
107@@ -30,48 +30,148 @@
108 namespace
109 {
110
111-void test_key(Display* x_display, const char* key)
112-{
113- KeySym keysym = XStringToKeysym(key);
114- KeySym above_keysym = keyboard::get_key_above_key_symbol(x_display, keysym);
115- EXPECT_NE(above_keysym, NoSymbol);
116-}
117-
118 TEST(TestKeyboardUtil, AboveKeySymbol)
119 {
120 Display* x_display = XOpenDisplay(NULL);
121
122- test_key(x_display, "Tab");
123- test_key(x_display, "Shift_R");
124- test_key(x_display, "Control_L");
125- test_key(x_display, "space");
126- test_key(x_display, "comma");
127- test_key(x_display, "a");
128- test_key(x_display, "b");
129- test_key(x_display, "c");
130- test_key(x_display, "d");
131- test_key(x_display, "e");
132- test_key(x_display, "f");
133- test_key(x_display, "g");
134- test_key(x_display, "h");
135- test_key(x_display, "i");
136- test_key(x_display, "j");
137- test_key(x_display, "k");
138- test_key(x_display, "l");
139- test_key(x_display, "m");
140- test_key(x_display, "n");
141- test_key(x_display, "o");
142- test_key(x_display, "p");
143- test_key(x_display, "k");
144- test_key(x_display, "r");
145- test_key(x_display, "s");
146- test_key(x_display, "t");
147- test_key(x_display, "u");
148- test_key(x_display, "v");
149- test_key(x_display, "w");
150- test_key(x_display, "x");
151- test_key(x_display, "y");
152- test_key(x_display, "z");
153+ ASSERT_EQ(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("escape")), NoSymbol);
154+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("Tab")), NoSymbol);
155+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("Shift_R")), NoSymbol);
156+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("Control_L")), NoSymbol);
157+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("space")), NoSymbol);
158+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("comma")), NoSymbol);
159+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("a")), NoSymbol);
160+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("b")), NoSymbol);
161+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("c")), NoSymbol);
162+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("d")), NoSymbol);
163+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("e")), NoSymbol);
164+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("f")), NoSymbol);
165+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("g")), NoSymbol);
166+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("h")), NoSymbol);
167+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("i")), NoSymbol);
168+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("j")), NoSymbol);
169+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("k")), NoSymbol);
170+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("l")), NoSymbol);
171+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("m")), NoSymbol);
172+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("n")), NoSymbol);
173+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("o")), NoSymbol);
174+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("p")), NoSymbol);
175+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("k")), NoSymbol);
176+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("r")), NoSymbol);
177+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("s")), NoSymbol);
178+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("t")), NoSymbol);
179+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("u")), NoSymbol);
180+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("v")), NoSymbol);
181+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("w")), NoSymbol);
182+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("x")), NoSymbol);
183+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("y")), NoSymbol);
184+ ASSERT_NE(keyboard::get_key_above_key_symbol(x_display, XStringToKeysym("z")), NoSymbol);
185+}
186+
187+TEST(TestKeyboardUtil, BelowKeySymbol)
188+{
189+ Display* x_display = XOpenDisplay(NULL);
190+
191+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("Tab")), NoSymbol);
192+ ASSERT_EQ(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("Control_L")), NoSymbol);
193+ ASSERT_EQ(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("space")), NoSymbol);
194+ ASSERT_EQ(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("comma")), NoSymbol);
195+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("a")), NoSymbol);
196+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("b")), NoSymbol);
197+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("d")), NoSymbol);
198+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("e")), NoSymbol);
199+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("f")), NoSymbol);
200+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("g")), NoSymbol);
201+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("h")), NoSymbol);
202+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("i")), NoSymbol);
203+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("j")), NoSymbol);
204+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("k")), NoSymbol);
205+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("l")), NoSymbol);
206+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("o")), NoSymbol);
207+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("p")), NoSymbol);
208+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("k")), NoSymbol);
209+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("r")), NoSymbol);
210+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("s")), NoSymbol);
211+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("t")), NoSymbol);
212+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("u")), NoSymbol);
213+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("w")), NoSymbol);
214+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("x")), NoSymbol);
215+ ASSERT_NE(keyboard::get_key_below_key_symbol(x_display, XStringToKeysym("y")), NoSymbol);
216+}
217+
218+TEST(TestKeyboardUtil, RightToKeySymbol)
219+{
220+ Display* x_display = XOpenDisplay(NULL);
221+
222+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("Tab")), NoSymbol);
223+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("Shift_R")), NoSymbol);
224+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("Control_L")), NoSymbol);
225+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("space")), NoSymbol);
226+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("comma")), NoSymbol);
227+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("a")), NoSymbol);
228+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("b")), NoSymbol);
229+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("c")), NoSymbol);
230+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("d")), NoSymbol);
231+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("e")), NoSymbol);
232+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("f")), NoSymbol);
233+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("g")), NoSymbol);
234+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("h")), NoSymbol);
235+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("i")), NoSymbol);
236+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("j")), NoSymbol);
237+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("k")), NoSymbol);
238+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("l")), NoSymbol);
239+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("m")), NoSymbol);
240+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("n")), NoSymbol);
241+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("o")), NoSymbol);
242+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("p")), NoSymbol);
243+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("k")), NoSymbol);
244+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("r")), NoSymbol);
245+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("s")), NoSymbol);
246+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("t")), NoSymbol);
247+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("u")), NoSymbol);
248+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("v")), NoSymbol);
249+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("w")), NoSymbol);
250+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("x")), NoSymbol);
251+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("y")), NoSymbol);
252+ ASSERT_NE(keyboard::get_key_right_to_key_symbol(x_display, XStringToKeysym("z")), NoSymbol);
253+}
254+
255+TEST(TestKeyboardUtil, LeftToKeySymbol)
256+{
257+ Display* x_display = XOpenDisplay(NULL);
258+
259+ ASSERT_EQ(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("Tab")), NoSymbol);
260+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("Shift_R")), NoSymbol);
261+ ASSERT_EQ(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("Control_L")), NoSymbol);
262+ ASSERT_EQ(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("escape")), NoSymbol);
263+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("space")), NoSymbol);
264+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("comma")), NoSymbol);
265+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("a")), NoSymbol);
266+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("b")), NoSymbol);
267+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("c")), NoSymbol);
268+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("d")), NoSymbol);
269+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("e")), NoSymbol);
270+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("f")), NoSymbol);
271+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("g")), NoSymbol);
272+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("h")), NoSymbol);
273+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("i")), NoSymbol);
274+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("j")), NoSymbol);
275+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("k")), NoSymbol);
276+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("l")), NoSymbol);
277+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("m")), NoSymbol);
278+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("n")), NoSymbol);
279+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("o")), NoSymbol);
280+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("p")), NoSymbol);
281+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("k")), NoSymbol);
282+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("r")), NoSymbol);
283+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("s")), NoSymbol);
284+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("t")), NoSymbol);
285+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("u")), NoSymbol);
286+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("v")), NoSymbol);
287+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("w")), NoSymbol);
288+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("x")), NoSymbol);
289+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("y")), NoSymbol);
290+ ASSERT_NE(keyboard::get_key_left_to_key_symbol(x_display, XStringToKeysym("z")), NoSymbol);
291 }
292
293 TEST(TestKeyboardUtil, PrintableKeySymbols)
294
295=== modified file 'unity-shared/XKeyboardUtil.cpp'
296--- unity-shared/XKeyboardUtil.cpp 2012-10-11 01:44:15 +0000
297+++ unity-shared/XKeyboardUtil.cpp 2015-11-09 23:58:16 +0000
298@@ -1,6 +1,6 @@
299 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
300 /*
301- * Copyright (C) 2011 Canonical Ltd
302+ * Copyright (C) 2011-2015 Canonical Ltd
303 *
304 * This program is free software: you can redistribute it and/or modify
305 * it under the terms of the GNU General Public License version 3 as
306@@ -15,12 +15,15 @@
307 * along with this program. If not, see <http://www.gnu.org/licenses/>.
308 *
309 * Authored by: Jason Smith <jason.smith@canonical.com>
310+ * Marco Trevisan <marco.trevisan@canonical.com>
311 */
312
313 #include <gdk/gdk.h>
314 #include <string.h>
315 #include <cmath>
316
317+#include <NuxCore/Logger.h>
318+
319 #include <X11/keysym.h>
320 #include <X11/XKBlib.h>
321 #include <X11/extensions/XKBgeom.h>
322@@ -34,6 +37,8 @@
323 {
324 namespace
325 {
326+DECLARE_LOGGER(logger, "unity.keyboard.xutil");
327+
328 const unsigned int FETCH_MASK = (XkbGBN_KeyNamesMask |
329 XkbGBN_ClientSymbolsMask |
330 XkbGBN_GeometryMask);
331@@ -44,16 +49,26 @@
332 KeyboardUtil(Display* display);
333 ~KeyboardUtil();
334
335- guint GetKeycodeAboveKeySymbol(KeySym key_symbol) const;
336+ enum class Position
337+ {
338+ LEFT,
339+ RIGHT,
340+ ABOVE,
341+ BELOW
342+ };
343+
344+ KeyCode GetKeyCodeNearKeySymbol(KeySym key_symbol, Position) const;
345+ KeySym GetNearKey(KeySym key_symbol, Position) const;
346
347 private:
348- bool CompareOffsets (int current_x, int current_y, int best_x, int best_y) const;
349- guint ConvertKeyToKeycode (XkbKeyPtr key) const;
350-
351- bool FindKeyInGeometry(XkbGeometryPtr geo, char *key_name, int& res_section, XkbBoundsRec& res_bounds) const;
352- bool FindKeyInSectionAboveBounds (XkbGeometryPtr geo, int section, XkbBoundsRec const& target_bounds, guint &keycode) const;
353-
354- XkbBoundsRec GetAbsoluteKeyBounds (XkbKeyPtr key, XkbRowPtr row, XkbSectionPtr section, XkbGeometryPtr geo) const;
355+ bool CompareOffsets(int current_x, int current_y, int best_x, int best_y) const;
356+ KeyCode ConvertKeyToKeycode(XkbKeyPtr key) const;
357+
358+ bool FindKeyInGeometry(XkbGeometryPtr, char *key_name, int& res_section, XkbBoundsRec&) const;
359+ bool FindKeyInVertical(Position, XkbGeometryPtr, int section, XkbBoundsRec const&, KeyCode&) const;
360+ bool FindKeyOnSides(Position, XkbGeometryPtr, int section_index, XkbBoundsRec const&, KeyCode &keycode) const;
361+
362+ XkbBoundsRec GetAbsoluteKeyBounds (XkbKeyPtr, XkbRowPtr, XkbSectionPtr, XkbGeometryPtr) const;
363
364 Display *display_;
365 XkbDescPtr keyboard_;
366@@ -116,7 +131,7 @@
367 return false;
368 }
369
370-guint KeyboardUtil::ConvertKeyToKeycode(XkbKeyPtr key) const
371+KeyCode KeyboardUtil::ConvertKeyToKeycode(XkbKeyPtr key) const
372 {
373 if (!keyboard_)
374 return 0;
375@@ -164,63 +179,124 @@
376 return result;
377 }
378
379-bool KeyboardUtil::FindKeyInSectionAboveBounds(XkbGeometryPtr geo, int section_index, XkbBoundsRec const& target_bounds, guint &keycode) const
380-{
381- XkbKeyPtr best = NULL;
382- int best_x_offset = G_MAXINT;
383- int best_y_offset = G_MAXINT;
384-
385- int sections_in_geometry = geo->num_sections;
386- for (int k = 0; k < sections_in_geometry; k++)
387- {
388-
389- XkbSectionPtr section = &geo->sections[section_index];
390- int rows_in_section = section->num_rows;
391- for (int i = 0; i < rows_in_section; i++)
392- {
393- XkbRowPtr row = &section->rows[i];
394-
395- int keys_in_row = row->num_keys;
396- for (int j = 0; j < keys_in_row; j++)
397- {
398- XkbKeyPtr key = &row->keys[j];
399- XkbBoundsRec bounds = GetAbsoluteKeyBounds (key, row, section, geo);
400-
401- // make sure we are actually over the target bounds
402- int center = (bounds.x1 + bounds.x2) / 2;
403- if (center < target_bounds.x1 || center > target_bounds.x2)
404- continue;
405-
406- // make sure the key is actually above our target.
407- int current_y_offset = target_bounds.y1 - bounds.y2;
408- if (current_y_offset < 0)
409- continue;
410-
411- int current_x_offset = std::abs(center - (target_bounds.x1 + target_bounds.x2) / 2);
412-
413- if (CompareOffsets(current_x_offset, current_y_offset, best_x_offset, best_y_offset))
414- {
415- best = key;
416- best_x_offset = current_x_offset;
417- best_y_offset = current_y_offset;
418- }
419- }
420- }
421- }
422-
423- if (best)
424- {
425- keycode = ConvertKeyToKeycode(best);
426- return true;
427- }
428- return false;
429-}
430-
431-guint KeyboardUtil::GetKeycodeAboveKeySymbol(KeySym key_symbol) const
432-{
433- guint result = 0;
434-
435- int code = XKeysymToKeycode(display_, key_symbol);
436+bool KeyboardUtil::FindKeyInVertical(Position pos, XkbGeometryPtr geo, int section_index, XkbBoundsRec const& target_bounds, KeyCode &keycode) const
437+{
438+ XkbKeyPtr best = nullptr;
439+ int best_x_offset = G_MAXINT;
440+ int best_y_offset = G_MAXINT;
441+
442+ int sections_in_geometry = geo->num_sections;
443+ for (int k = 0; k < sections_in_geometry; ++k)
444+ {
445+ XkbSectionPtr section = &geo->sections[section_index];
446+
447+ for (int i = 0; i < section->num_rows; ++i)
448+ {
449+ XkbRowPtr row = &section->rows[i];
450+
451+ int keys_in_row = row->num_keys;
452+ for (int j = 0; j < keys_in_row; ++j)
453+ {
454+ XkbKeyPtr key = &row->keys[j];
455+ XkbBoundsRec bounds = GetAbsoluteKeyBounds(key, row, section, geo);
456+
457+ // make sure we are actually over the target bounds
458+ int hcenter = (bounds.x1 + bounds.x2) / 2;
459+ if (hcenter < target_bounds.x1 || hcenter > target_bounds.x2)
460+ continue;
461+
462+ // make sure the key is actually above our target.
463+ int current_y_offset;
464+
465+ if (pos == Position::ABOVE)
466+ current_y_offset = target_bounds.y1 - bounds.y2;
467+ else // if (pos == Position::BELOW)
468+ current_y_offset = bounds.y1 - target_bounds.y2;
469+
470+ // make sure the key is actually above our target.
471+ if (current_y_offset < 0)
472+ continue;
473+
474+ int current_x_offset = std::abs(hcenter - (target_bounds.x1 + target_bounds.x2) / 2);
475+
476+ if (CompareOffsets(current_x_offset, current_y_offset, best_x_offset, best_y_offset))
477+ {
478+ best = key;
479+ best_x_offset = current_x_offset;
480+ best_y_offset = current_y_offset;
481+ }
482+ }
483+ }
484+ }
485+
486+ if (best)
487+ {
488+ keycode = ConvertKeyToKeycode(best);
489+ return true;
490+ }
491+ return false;
492+}
493+
494+bool KeyboardUtil::FindKeyOnSides(Position pos, XkbGeometryPtr geo, int section_index, XkbBoundsRec const& target_bounds, KeyCode &keycode) const
495+{
496+ XkbKeyPtr best = nullptr;
497+ int best_x_offset = G_MAXINT;
498+ int best_y_offset = G_MAXINT;
499+
500+ int sections_in_geometry = geo->num_sections;
501+ for (int k = 0; k < sections_in_geometry; ++k)
502+ {
503+ XkbSectionPtr section = &geo->sections[section_index];
504+ for (int i = 0; i < section->num_rows; ++i)
505+ {
506+ XkbRowPtr row = &section->rows[i];
507+
508+ int keys_in_row = row->num_keys;
509+ for (int j = 0; j < keys_in_row; ++j)
510+ {
511+ XkbKeyPtr key = &row->keys[j];
512+ XkbBoundsRec bounds = GetAbsoluteKeyBounds(key, row, section, geo);
513+
514+ // make sure we are actually over the target bounds
515+ int vcenter = (bounds.y1 + bounds.y2) / 2;
516+ if (vcenter < target_bounds.y1 || vcenter > target_bounds.y2)
517+ continue;
518+
519+ int current_x_offset;
520+
521+ if (pos == Position::LEFT)
522+ current_x_offset = target_bounds.x1 - bounds.x2;
523+ else // if (pos == Position::RIGHT)
524+ current_x_offset = target_bounds.x2 - bounds.x1;
525+
526+ // make sure the key is actually above our target.
527+ if (current_x_offset < 0)
528+ continue;
529+
530+ int current_y_offset = std::abs(vcenter - (target_bounds.y1 + target_bounds.y2) / 2);
531+
532+ if (CompareOffsets(current_x_offset, current_y_offset, best_x_offset, best_y_offset))
533+ {
534+ best = key;
535+ best_x_offset = current_x_offset;
536+ best_y_offset = current_y_offset;
537+ }
538+ }
539+ }
540+ }
541+
542+ if (best)
543+ {
544+ keycode = ConvertKeyToKeycode(best);
545+ return true;
546+ }
547+ return false;
548+}
549+
550+KeyCode KeyboardUtil::GetKeyCodeNearKeySymbol(KeySym key_symbol, Position pos) const
551+{
552+ KeyCode result = 0;
553+ KeyCode code = XKeysymToKeycode(display_, key_symbol);
554
555 if (!code || !keyboard_)
556 return result;
557@@ -230,15 +306,30 @@
558
559 char* key_str = keyboard_->names->keys[code].name;
560
561-
562 int key_section;
563 XkbBoundsRec key_bounds;
564 bool found_key = FindKeyInGeometry(keyboard_->geom, key_str, key_section, key_bounds);
565
566 if (found_key)
567 {
568- guint maybe;
569- found_key = FindKeyInSectionAboveBounds(keyboard_->geom, key_section, key_bounds, maybe);
570+ KeyCode maybe;
571+
572+ switch (pos)
573+ {
574+ case Position::LEFT:
575+ case Position::RIGHT:
576+ found_key = FindKeyOnSides(pos, keyboard_->geom, key_section, key_bounds, maybe);
577+ break;
578+ case Position::ABOVE:
579+ case Position::BELOW:
580+ found_key = FindKeyInVertical(pos, keyboard_->geom, key_section, key_bounds, maybe);
581+ break;
582+ default:
583+ LOG_ERROR(logger) << "Impossible to find key near to " << XKeysymToString(key_symbol)
584+ << " at position " << static_cast<unsigned>(pos); // Get actual type name.
585+ found_key = false;
586+ break;
587+ }
588
589 if (found_key)
590 result = maybe;
591@@ -247,6 +338,14 @@
592 return result;
593 }
594
595+KeySym KeyboardUtil::GetNearKey(KeySym key_symbol, Position pos) const
596+{
597+ KeyCode keycode = GetKeyCodeNearKeySymbol(key_symbol, pos);
598+ const unsigned int group_interest = 0;
599+ const unsigned int shift_interest = 0;
600+ return XkbKeycodeToKeysym(display_, keycode, group_interest, shift_interest);
601+}
602+
603
604 } // anon namespace
605
606@@ -277,11 +376,22 @@
607
608 KeySym get_key_above_key_symbol(Display* display, KeySym key_symbol)
609 {
610- KeyboardUtil util(display);
611- guint above_keycode = util.GetKeycodeAboveKeySymbol(key_symbol);
612- const unsigned int group_interest = 0;
613- const unsigned int shift_interest = 0;
614- return XkbKeycodeToKeysym(display, above_keycode, group_interest, shift_interest);
615+ return KeyboardUtil(display).GetNearKey(key_symbol, KeyboardUtil::Position::ABOVE);
616+}
617+
618+KeySym get_key_below_key_symbol(Display* display, KeySym key_symbol)
619+{
620+ return KeyboardUtil(display).GetNearKey(key_symbol, KeyboardUtil::Position::BELOW);
621+}
622+
623+KeySym get_key_right_to_key_symbol(Display* display, KeySym key_symbol)
624+{
625+ return KeyboardUtil(display).GetNearKey(key_symbol, KeyboardUtil::Position::RIGHT);
626+}
627+
628+KeySym get_key_left_to_key_symbol(Display* display, KeySym key_symbol)
629+{
630+ return KeyboardUtil(display).GetNearKey(key_symbol, KeyboardUtil::Position::LEFT);
631 }
632
633 } // namespace keyboard
634
635=== modified file 'unity-shared/XKeyboardUtil.h'
636--- unity-shared/XKeyboardUtil.h 2012-10-11 01:44:15 +0000
637+++ unity-shared/XKeyboardUtil.h 2015-11-09 23:58:16 +0000
638@@ -28,6 +28,9 @@
639 {
640
641 KeySym get_key_above_key_symbol(Display* display, KeySym key_symbol);
642+KeySym get_key_below_key_symbol(Display* display, KeySym key_symbol);
643+KeySym get_key_right_to_key_symbol(Display* display, KeySym key_symbol);
644+KeySym get_key_left_to_key_symbol(Display* display, KeySym key_symbol);
645
646
647 }