Merge lp:~mitya57/kubuntu-packaging/qtbase-fix-keymap-update-handling into lp:~kubuntu-packagers/kubuntu-packaging/qtbase-opensource-src
- qtbase-fix-keymap-update-handling
- Merge into qtbase-opensource-src
Status: | Rejected |
---|---|
Rejected by: | Dmitry Shachnev |
Proposed branch: | lp:~mitya57/kubuntu-packaging/qtbase-fix-keymap-update-handling |
Merge into: | lp:~kubuntu-packagers/kubuntu-packaging/qtbase-opensource-src |
Prerequisite: | lp:~timo-jyrinki/kubuntu-packaging/qtbase_cherrypick_lp1299712 |
Diff against target: |
694 lines (+674/-0) 3 files modified
debian/changelog (+8/-0) debian/patches/Add_better_support_for_keymap_update_handling.patch (+665/-0) debian/patches/series (+1/-0) |
To merge this branch: | bzr merge lp:~mitya57/kubuntu-packaging/qtbase-fix-keymap-update-handling |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Timo Jyrinki | Needs Fixing | ||
Review via email: mp+213687@code.launchpad.net |
Commit message
Backport upstream patch to fix issues with keymap update handling
(Add_better_
Debian and rebased).
Description of the change
qtbase-
* Backport upstream patch to fix issues with keymap update handling
(Add_
Debian and rebased).
-- Dmitry Shachnev <email address hidden> Tue, 01 Apr 2014 20:22:12 +0400
Timo Jyrinki (timo-jyrinki) wrote : | # |
Timo Jyrinki (timo-jyrinki) wrote : | # |
This seems to fail to build, because it'd apparently require libxkbcommon 0.4.0 while Ubuntu only has 0.3.2. https:/
0.4.0 will probably be available in the u series in ~3 weeks since it should be autosynced as soon as Debian sync is enabled.
Dmitry Shachnev (mitya57) wrote : | # |
Sorry, I should have given it more testing :)
FYI, I added the missing build-dep in Debian Git: <http://
Unmerged revisions
- 166. By Dmitry Shachnev
-
Backport upstream patch to fix issues with keymap update handling
(Add_better_support_ for_keymap_ update_ handling. patch, copied from
Debian and rebased).
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2014-04-01 16:39:26 +0000 |
3 | +++ debian/changelog 2014-04-01 16:39:26 +0000 |
4 | @@ -1,3 +1,11 @@ |
5 | +qtbase-opensource-src (5.2.1+dfsg-1ubuntu12) UNRELEASED; urgency=medium |
6 | + |
7 | + * Backport upstream patch to fix issues with keymap update handling |
8 | + (Add_better_support_for_keymap_update_handling.patch, copied from |
9 | + Debian and rebased). |
10 | + |
11 | + -- Dmitry Shachnev <mitya57@ubuntu.com> Tue, 01 Apr 2014 20:22:12 +0400 |
12 | + |
13 | qtbase-opensource-src (5.2.1+dfsg-1ubuntu11) trusty; urgency=medium |
14 | |
15 | * debian/patches/When-looking-up-the-window-hierarchy-stop-at-foreign.patch |
16 | |
17 | === added file 'debian/patches/Add_better_support_for_keymap_update_handling.patch' |
18 | --- debian/patches/Add_better_support_for_keymap_update_handling.patch 1970-01-01 00:00:00 +0000 |
19 | +++ debian/patches/Add_better_support_for_keymap_update_handling.patch 2014-04-01 16:39:26 +0000 |
20 | @@ -0,0 +1,665 @@ |
21 | +From 18e162e8640d96f2d7f2a85ef35d00350360903d Mon Sep 17 00:00:00 2001 |
22 | +From: Gatis Paeglis <gatis.paeglis@digia.com> |
23 | +Date: Thu, 27 Feb 2014 18:05:14 +0100 |
24 | +Subject: [PATCH] Add better support for keymap update handling |
25 | + |
26 | +Use the new X11 support API xkb_x11_* released in libxkbcommon version 0.4.0. |
27 | + |
28 | +From the commit message where this API was introduced: |
29 | + |
30 | +"These are function to create an xkb_keymap directly from XKB requests |
31 | +to the X server. This opens up the possibility for X clients to use |
32 | +xcb + xcb-xkb + xkbcommon as a proper replacement for Xlib + xkbfile for |
33 | +keyboard support. |
34 | + |
35 | +Why not just use the RMLVO that the server puts in the _XKB_RULES_NAMES |
36 | +property? This does not account for custom keymaps, on-the-fly keymap |
37 | +modifications, remote clients, etc., so is not a proper solution in |
38 | +practice. Also, some servers don't even set it. Now, the client just |
39 | +needs to recreate the keymap in response to a change in the server's |
40 | +keymap (as Xlib clients do with XRefreshKeyboardMapping() and friends)." |
41 | + |
42 | +This patch moves XKEYBOARD presence decision from compile time to runtime |
43 | +for a proper remote X client support. |
44 | + |
45 | +Task-number: QTBUG-31527 |
46 | +Task-number: QTBUG-32760 |
47 | +Change-Id: I4d402668cda2126ef180b27022154f96b1874b1d |
48 | +--- |
49 | + src/plugins/platforms/xcb/qxcbconnection.cpp | 61 ++++---- |
50 | + src/plugins/platforms/xcb/qxcbconnection.h | 2 +- |
51 | + src/plugins/platforms/xcb/qxcbkeyboard.cpp | 220 +++++++++++---------------- |
52 | + src/plugins/platforms/xcb/qxcbkeyboard.h | 35 ++--- |
53 | + src/plugins/platforms/xcb/xcb-plugin.pro | 8 +- |
54 | + 5 files changed, 136 insertions(+), 190 deletions(-) |
55 | + |
56 | +--- a/src/plugins/platforms/xcb/qxcbconnection.cpp |
57 | ++++ b/src/plugins/platforms/xcb/qxcbconnection.cpp |
58 | +@@ -782,6 +782,7 @@ |
59 | + xcb_timestamp_t time; |
60 | + uint8_t deviceID; |
61 | + } any; |
62 | ++ xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify; |
63 | + xcb_xkb_map_notify_event_t map_notify; |
64 | + xcb_xkb_state_notify_event_t state_notify; |
65 | + } _xkb_event; |
66 | +@@ -812,15 +813,11 @@ |
67 | + case XCB_EXPOSE: |
68 | + HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent); |
69 | + case XCB_BUTTON_PRESS: |
70 | +-#ifdef QT_NO_XKB |
71 | + m_keyboard->updateXKBStateFromCore(((xcb_button_press_event_t *)event)->state); |
72 | +-#endif |
73 | + handleButtonPress(event); |
74 | + HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); |
75 | + case XCB_BUTTON_RELEASE: |
76 | +-#ifdef QT_NO_XKB |
77 | + m_keyboard->updateXKBStateFromCore(((xcb_button_release_event_t *)event)->state); |
78 | +-#endif |
79 | + handleButtonRelease(event); |
80 | + HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); |
81 | + case XCB_MOTION_NOTIFY: |
82 | +@@ -828,9 +825,7 @@ |
83 | + xcb_motion_notify_event_t *mev = (xcb_motion_notify_event_t *)event; |
84 | + qDebug("xcb: moved mouse to %4d, %4d; button state %X", mev->event_x, mev->event_y, static_cast<unsigned int>(m_buttons)); |
85 | + } |
86 | +-#ifdef QT_NO_XKB |
87 | + m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state); |
88 | +-#endif |
89 | + HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); |
90 | + case XCB_CONFIGURE_NOTIFY: |
91 | + HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent); |
92 | +@@ -846,29 +841,21 @@ |
93 | + case XCB_ENTER_NOTIFY: |
94 | + HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent); |
95 | + case XCB_LEAVE_NOTIFY: |
96 | +-#ifdef QT_NO_XKB |
97 | + m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state); |
98 | +-#endif |
99 | + HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent); |
100 | + case XCB_FOCUS_IN: |
101 | + HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent); |
102 | + case XCB_FOCUS_OUT: |
103 | + HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent); |
104 | + case XCB_KEY_PRESS: |
105 | +-#ifdef QT_NO_XKB |
106 | + m_keyboard->updateXKBStateFromCore(((xcb_key_press_event_t *)event)->state); |
107 | +-#endif |
108 | + HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent); |
109 | + case XCB_KEY_RELEASE: |
110 | +-#ifdef QT_NO_XKB |
111 | + m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state); |
112 | +-#endif |
113 | + HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent); |
114 | +-#ifdef QT_NO_XKB |
115 | + case XCB_MAPPING_NOTIFY: |
116 | + m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event); |
117 | + break; |
118 | +-#endif |
119 | + case XCB_SELECTION_REQUEST: |
120 | + { |
121 | + xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event; |
122 | +@@ -936,6 +923,8 @@ |
123 | + _xkb_event *xkb_event = reinterpret_cast<_xkb_event *>(event); |
124 | + if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) { |
125 | + switch (xkb_event->any.xkbType) { |
126 | ++ // XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap |
127 | ++ // updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundent recompilations. |
128 | + case XCB_XKB_STATE_NOTIFY: |
129 | + m_keyboard->updateXKBState(&xkb_event->state_notify); |
130 | + handled = true; |
131 | +@@ -944,6 +933,12 @@ |
132 | + m_keyboard->handleMappingNotifyEvent(&xkb_event->map_notify); |
133 | + handled = true; |
134 | + break; |
135 | ++ case XCB_XKB_NEW_KEYBOARD_NOTIFY: { |
136 | ++ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify; |
137 | ++ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES) |
138 | ++ m_keyboard->updateKeymap(); |
139 | ++ break; |
140 | ++ } |
141 | + default: |
142 | + break; |
143 | + } |
144 | +@@ -1667,6 +1662,7 @@ |
145 | + #ifndef QT_NO_XKB |
146 | + const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xkb_id); |
147 | + if (!reply || !reply->present) { |
148 | ++ qWarning() << "Qt: XKEYBOARD extension not present on the X server."; |
149 | + xkb_first_event = 0; |
150 | + return; |
151 | + } |
152 | +@@ -1676,14 +1672,14 @@ |
153 | + xcb_xkb_use_extension_cookie_t xkb_query_cookie; |
154 | + xcb_xkb_use_extension_reply_t *xkb_query; |
155 | + |
156 | +- xkb_query_cookie = xcb_xkb_use_extension(c, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); |
157 | ++ xkb_query_cookie = xcb_xkb_use_extension(c, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION); |
158 | + xkb_query = xcb_xkb_use_extension_reply(c, xkb_query_cookie, 0); |
159 | + |
160 | + if (!xkb_query) { |
161 | + qWarning("Qt: Failed to initialize XKB extension"); |
162 | + return; |
163 | + } else if (!xkb_query->supported) { |
164 | +- qWarning("Qt: Unsupported XKB version (want %d %d, has %d %d)", |
165 | ++ qWarning("Qt: Unsupported XKB version (We want %d %d, but X server has %d %d)", |
166 | + XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION, |
167 | + xkb_query->serverMajor, xkb_query->serverMinor); |
168 | + free(xkb_query); |
169 | +@@ -1693,25 +1689,28 @@ |
170 | + has_xkb = true; |
171 | + free(xkb_query); |
172 | + |
173 | +- uint affectMap, map; |
174 | +- affectMap = map = XCB_XKB_MAP_PART_KEY_TYPES | |
175 | +- XCB_XKB_MAP_PART_KEY_SYMS | |
176 | +- XCB_XKB_MAP_PART_MODIFIER_MAP | |
177 | +- XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | |
178 | +- XCB_XKB_MAP_PART_KEY_ACTIONS | |
179 | +- XCB_XKB_MAP_PART_KEY_BEHAVIORS | |
180 | +- XCB_XKB_MAP_PART_VIRTUAL_MODS | |
181 | +- XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP; |
182 | ++ const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES | |
183 | ++ XCB_XKB_MAP_PART_KEY_SYMS | |
184 | ++ XCB_XKB_MAP_PART_MODIFIER_MAP | |
185 | ++ XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | |
186 | ++ XCB_XKB_MAP_PART_KEY_ACTIONS | |
187 | ++ XCB_XKB_MAP_PART_KEY_BEHAVIORS | |
188 | ++ XCB_XKB_MAP_PART_VIRTUAL_MODS | |
189 | ++ XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP); |
190 | ++ |
191 | ++ const uint16_t required_events = (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | |
192 | ++ XCB_XKB_EVENT_TYPE_MAP_NOTIFY | |
193 | ++ XCB_XKB_EVENT_TYPE_STATE_NOTIFY); |
194 | + |
195 | +- // Xkb events are reported to all interested clients without regard |
196 | ++ // XKB events are reported to all interested clients without regard |
197 | + // to the current keyboard input focus or grab state |
198 | + xcb_void_cookie_t select = xcb_xkb_select_events_checked(c, |
199 | + XCB_XKB_ID_USE_CORE_KBD, |
200 | +- XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY, |
201 | ++ required_events, |
202 | + 0, |
203 | +- XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY, |
204 | +- affectMap, |
205 | +- map, |
206 | ++ required_events, |
207 | ++ required_map_parts, |
208 | ++ required_map_parts, |
209 | + 0); |
210 | + |
211 | + xcb_generic_error_t *error = xcb_request_check(c, select); |
212 | +--- a/src/plugins/platforms/xcb/qxcbconnection.h |
213 | ++++ b/src/plugins/platforms/xcb/qxcbconnection.h |
214 | +@@ -54,7 +54,7 @@ |
215 | + #include <qpa/qwindowsysteminterface.h> |
216 | + |
217 | + // This is needed to make Qt compile together with XKB. xkb.h is using a variable |
218 | +-// which is called 'explicit', this is a reserved keyword in c++ */ |
219 | ++// which is called 'explicit', this is a reserved keyword in c++ |
220 | + #ifndef QT_NO_XKB |
221 | + #define explicit dont_use_cxx_explicit |
222 | + #include <xcb/xkb.h> |
223 | +--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp |
224 | ++++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp |
225 | +@@ -662,6 +662,7 @@ |
226 | + void QXcbKeyboard::updateKeymap() |
227 | + { |
228 | + m_config = true; |
229 | ++ // set xkb context object |
230 | + if (!xkb_context) { |
231 | + xkb_context = xkb_context_new((xkb_context_flags)0); |
232 | + if (!xkb_context) { |
233 | +@@ -670,67 +671,50 @@ |
234 | + return; |
235 | + } |
236 | + } |
237 | +- readXKBConfig(); |
238 | +- // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names |
239 | +- if (xkb_keymap) |
240 | +- xkb_keymap_unref(xkb_keymap); |
241 | ++ // update xkb keymap object |
242 | ++ xkb_keymap_unref(xkb_keymap); |
243 | ++ xkb_keymap = 0; |
244 | + |
245 | +- xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0); |
246 | ++ struct xkb_state *new_state = 0; |
247 | ++#ifndef QT_NO_XKB |
248 | ++ if (connection()->hasXKB()) { |
249 | ++ xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, xcb_connection(), core_device_id, (xkb_keymap_compile_flags)0); |
250 | ++ if (xkb_keymap) { |
251 | ++ // Create a new keyboard state object for a keymap |
252 | ++ new_state = xkb_x11_state_new_from_device(xkb_keymap, xcb_connection(), core_device_id); |
253 | ++ } |
254 | ++ } |
255 | ++#endif |
256 | ++ if (!xkb_keymap) { |
257 | ++ // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names |
258 | ++ readXKBConfig(); |
259 | ++ xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0); |
260 | ++ if (xkb_keymap) |
261 | ++ new_state = xkb_state_new(xkb_keymap); |
262 | ++ } |
263 | + |
264 | + if (!xkb_keymap) { |
265 | + qWarning("Qt: Failed to compile a keymap"); |
266 | + m_config = false; |
267 | +- return; |
268 | + } |
269 | +- // Create a new keyboard state object for a keymap |
270 | +- struct xkb_state *new_state = xkb_state_new(xkb_keymap); |
271 | + if (!new_state) { |
272 | +- qWarning("Qt: Failed to create a new keyboard state"); |
273 | ++ qWarning("Qt: Failed to create xkb state"); |
274 | + m_config = false; |
275 | +- return; |
276 | + } |
277 | ++ if (!m_config) |
278 | ++ return; |
279 | + |
280 | +- if (xkb_state) { |
281 | +- xkb_state_unref(xkb_state); |
282 | +- xkb_state = new_state; |
283 | +- } else { |
284 | +- xkb_state = new_state; |
285 | +-#ifndef QT_NO_XKB |
286 | +- // get initial state from the X server (and keep it up-to-date at all times) |
287 | +- xcb_xkb_get_state_cookie_t state; |
288 | +- xcb_xkb_get_state_reply_t *init_state; |
289 | +- |
290 | +- xcb_connection_t *c = xcb_connection(); |
291 | +- state = xcb_xkb_get_state(c, XCB_XKB_ID_USE_CORE_KBD); |
292 | +- init_state = xcb_xkb_get_state_reply(c, state, 0); |
293 | +- if (!init_state) { |
294 | +- qWarning("Qt: couldn't retrieve an initial keyboard state"); |
295 | +- return; |
296 | +- } |
297 | +- /* The xkb keyboard state is comprised of the state of all keyboard modifiers, |
298 | +- the keyboard group, and the state of the pointer buttons */ |
299 | +- xkb_state_update_mask(xkb_state, |
300 | +- init_state->baseMods, |
301 | +- init_state->latchedMods, |
302 | +- init_state->lockedMods, |
303 | +- init_state->baseGroup, |
304 | +- init_state->latchedGroup, |
305 | +- init_state->lockedGroup); |
306 | +- free(init_state); |
307 | +-#else |
308 | ++ // update xkb state object |
309 | ++ xkb_state_unref(xkb_state); |
310 | ++ xkb_state = new_state; |
311 | ++ if (!connection()->hasXKB()) |
312 | + updateXKBMods(); |
313 | +-#endif |
314 | +- } |
315 | + } |
316 | + |
317 | + #ifndef QT_NO_XKB |
318 | + void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state) |
319 | + { |
320 | +- if (!m_config) |
321 | +- return; |
322 | +- |
323 | +- if (connection()->hasXKB()) { |
324 | +- |
325 | ++ if (m_config && connection()->hasXKB()) { |
326 | + const xkb_state_component newState |
327 | + = xkb_state_update_mask(xkb_state, |
328 | + state->baseMods, |
329 | +@@ -745,35 +729,34 @@ |
330 | + } |
331 | + } |
332 | + } |
333 | ++#endif |
334 | + |
335 | +-#else |
336 | + void QXcbKeyboard::updateXKBStateFromCore(quint16 state) |
337 | + { |
338 | +- if (!m_config) |
339 | +- return; |
340 | ++ if (m_config && !connection()->hasXKB()) { |
341 | ++ const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED); |
342 | ++ const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); |
343 | ++ const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); |
344 | ++ const quint32 xkbMask = xkbModMask(state); |
345 | ++ |
346 | ++ const quint32 latched = modsLatched & xkbMask; |
347 | ++ const quint32 locked = modsLocked & xkbMask; |
348 | ++ quint32 depressed = modsDepressed & xkbMask; |
349 | ++ // set modifiers in depressed if they don't appear in any of the final masks |
350 | ++ depressed |= ~(depressed | latched | locked) & xkbMask; |
351 | + |
352 | +- const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED); |
353 | +- const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); |
354 | +- const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); |
355 | +- const quint32 xkbMask = xkbModMask(state); |
356 | +- |
357 | +- const quint32 latched = modsLatched & xkbMask; |
358 | +- const quint32 locked = modsLocked & xkbMask; |
359 | +- quint32 depressed = modsDepressed & xkbMask; |
360 | +- // set modifiers in depressed if they don't appear in any of the final masks |
361 | +- depressed |= ~(depressed | latched | locked) & xkbMask; |
362 | +- |
363 | +- const xkb_state_component newState |
364 | +- = xkb_state_update_mask(xkb_state, |
365 | +- depressed, |
366 | +- latched, |
367 | +- locked, |
368 | +- 0, |
369 | +- 0, |
370 | +- (state >> 13) & 3); // bits 13 and 14 report the state keyboard group |
371 | ++ const xkb_state_component newState |
372 | ++ = xkb_state_update_mask(xkb_state, |
373 | ++ depressed, |
374 | ++ latched, |
375 | ++ locked, |
376 | ++ 0, |
377 | ++ 0, |
378 | ++ (state >> 13) & 3); // bits 13 and 14 report the state keyboard group |
379 | + |
380 | +- if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { |
381 | +- //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); |
382 | ++ if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { |
383 | ++ //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); |
384 | ++ } |
385 | + } |
386 | + } |
387 | + |
388 | +@@ -803,16 +786,15 @@ |
389 | + |
390 | + void QXcbKeyboard::updateXKBMods() |
391 | + { |
392 | +- xkb_mods.shift = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_SHIFT); |
393 | +- xkb_mods.lock = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_CAPS); |
394 | +- xkb_mods.control = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_CTRL); |
395 | +- xkb_mods.mod1 = xkb_map_mod_get_index(xkb_keymap, "Mod1"); |
396 | +- xkb_mods.mod2 = xkb_map_mod_get_index(xkb_keymap, "Mod2"); |
397 | +- xkb_mods.mod3 = xkb_map_mod_get_index(xkb_keymap, "Mod3"); |
398 | +- xkb_mods.mod4 = xkb_map_mod_get_index(xkb_keymap, "Mod4"); |
399 | +- xkb_mods.mod5 = xkb_map_mod_get_index(xkb_keymap, "Mod5"); |
400 | ++ xkb_mods.shift = xkb_keymap_mod_get_index(xkb_keymap, XKB_MOD_NAME_SHIFT); |
401 | ++ xkb_mods.lock = xkb_keymap_mod_get_index(xkb_keymap, XKB_MOD_NAME_CAPS); |
402 | ++ xkb_mods.control = xkb_keymap_mod_get_index(xkb_keymap, XKB_MOD_NAME_CTRL); |
403 | ++ xkb_mods.mod1 = xkb_keymap_mod_get_index(xkb_keymap, "Mod1"); |
404 | ++ xkb_mods.mod2 = xkb_keymap_mod_get_index(xkb_keymap, "Mod2"); |
405 | ++ xkb_mods.mod3 = xkb_keymap_mod_get_index(xkb_keymap, "Mod3"); |
406 | ++ xkb_mods.mod4 = xkb_keymap_mod_get_index(xkb_keymap, "Mod4"); |
407 | ++ xkb_mods.mod5 = xkb_keymap_mod_get_index(xkb_keymap, "Mod5"); |
408 | + } |
409 | +-#endif |
410 | + |
411 | + QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const |
412 | + { |
413 | +@@ -897,10 +879,8 @@ |
414 | + result += (qtKey + mods); |
415 | + } |
416 | + } |
417 | +- if (kb_state) |
418 | +- xkb_state_unref(kb_state); |
419 | +- if (fallback_keymap) |
420 | +- xkb_keymap_unref(fallback_keymap); |
421 | ++ xkb_state_unref(kb_state); |
422 | ++ xkb_keymap_unref(fallback_keymap); |
423 | + |
424 | + return result; |
425 | + } |
426 | +@@ -967,58 +947,41 @@ |
427 | + , xkb_context(0) |
428 | + , xkb_keymap(0) |
429 | + , xkb_state(0) |
430 | +-#ifndef QT_NO_XKB |
431 | + , core_device_id(0) |
432 | +-#endif |
433 | + { |
434 | + memset(&xkb_names, 0, sizeof(xkb_names)); |
435 | +- updateKeymap(); |
436 | + #ifndef QT_NO_XKB |
437 | + if (connection->hasXKB()) { |
438 | +- |
439 | + updateVModMapping(); |
440 | + updateVModToRModMapping(); |
441 | +- |
442 | +- // get the core keyboard id |
443 | +- xcb_xkb_get_device_info_cookie_t device_id_cookie; |
444 | +- xcb_xkb_get_device_info_reply_t *device_id; |
445 | +- |
446 | +- device_id_cookie = xcb_xkb_get_device_info(xcb_connection(), |
447 | +- XCB_XKB_ID_USE_CORE_KBD, |
448 | +- 0, 0, 0, 0, 0, 0); |
449 | +- |
450 | +- device_id = xcb_xkb_get_device_info_reply(xcb_connection(), device_id_cookie, 0); |
451 | +- if (!device_id) { |
452 | ++ core_device_id = xkb_x11_get_core_keyboard_device_id(xcb_connection()); |
453 | ++ if (core_device_id == -1) { |
454 | + qWarning("Qt: couldn't get core keyboard device info"); |
455 | + return; |
456 | + } |
457 | +- |
458 | +- core_device_id = device_id->deviceID; |
459 | +- free(device_id); |
460 | ++ } else { |
461 | ++#endif |
462 | ++ m_key_symbols = xcb_key_symbols_alloc(xcb_connection()); |
463 | ++ updateModifiers(); |
464 | ++#ifndef QT_NO_XKB |
465 | + } |
466 | +-#else |
467 | +- m_key_symbols = xcb_key_symbols_alloc(xcb_connection()); |
468 | +- updateModifiers(); |
469 | + #endif |
470 | ++ updateKeymap(); |
471 | + } |
472 | + |
473 | + QXcbKeyboard::~QXcbKeyboard() |
474 | + { |
475 | +- if (xkb_state) |
476 | +- xkb_state_unref(xkb_state); |
477 | +- if (xkb_keymap) |
478 | +- xkb_keymap_unref(xkb_keymap); |
479 | +- if (xkb_context) |
480 | +- xkb_context_unref(xkb_context); |
481 | +-#ifdef QT_NO_XKB |
482 | +- xcb_key_symbols_free(m_key_symbols); |
483 | +-#endif |
484 | ++ xkb_state_unref(xkb_state); |
485 | ++ xkb_keymap_unref(xkb_keymap); |
486 | ++ xkb_context_unref(xkb_context); |
487 | ++ if (!connection()->hasXKB()) |
488 | ++ xcb_key_symbols_free(m_key_symbols); |
489 | + clearXKBConfig(); |
490 | + } |
491 | + |
492 | +-#ifndef QT_NO_XKB |
493 | + void QXcbKeyboard::updateVModMapping() |
494 | + { |
495 | ++#ifndef QT_NO_XKB |
496 | + xcb_xkb_get_names_cookie_t names_cookie; |
497 | + xcb_xkb_get_names_reply_t *name_reply; |
498 | + xcb_xkb_get_names_value_list_t names_list; |
499 | +@@ -1082,10 +1045,12 @@ |
500 | + } |
501 | + |
502 | + free(name_reply); |
503 | ++#endif |
504 | + } |
505 | + |
506 | + void QXcbKeyboard::updateVModToRModMapping() |
507 | + { |
508 | ++#ifndef QT_NO_XKB |
509 | + xcb_xkb_get_map_cookie_t map_cookie; |
510 | + xcb_xkb_get_map_reply_t *map_reply; |
511 | + xcb_xkb_get_map_map_t map; |
512 | +@@ -1148,8 +1113,9 @@ |
513 | + |
514 | + free(map_reply); |
515 | + resolveMaskConflicts(); |
516 | ++#endif |
517 | + } |
518 | +-#else |
519 | ++ |
520 | + void QXcbKeyboard::updateModifiers() |
521 | + { |
522 | + // The core protocol does not provide a convenient way to determine the mapping |
523 | +@@ -1213,7 +1179,6 @@ |
524 | + free(modMapReply); |
525 | + resolveMaskConflicts(); |
526 | + } |
527 | +-#endif |
528 | + |
529 | + void QXcbKeyboard::resolveMaskConflicts() |
530 | + { |
531 | +@@ -1296,17 +1261,9 @@ |
532 | + |
533 | + if (!m_config) |
534 | + return; |
535 | +- // It is crucial the order of xkb_state_key_get_one_sym & |
536 | +- // xkb_state_update_key operations is not reversed! |
537 | ++ |
538 | ++ // It is crucial the order of xkb_state_key_get_one_sym & xkb_state_update_key operations is not reversed! |
539 | + xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code); |
540 | +-#ifdef QT_NO_XKB |
541 | +- enum xkb_key_direction direction; |
542 | +- if (type == QEvent::KeyPress) |
543 | +- direction = XKB_KEY_DOWN; |
544 | +- else |
545 | +- direction = XKB_KEY_UP; |
546 | +- xkb_state_update_key(xkb_state, code, direction); |
547 | +-#endif |
548 | + |
549 | + QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext(); |
550 | + QMetaMethod method; |
551 | +@@ -1442,17 +1399,14 @@ |
552 | + void QXcbKeyboard::handleMappingNotifyEvent(const void *event) |
553 | + { |
554 | + updateKeymap(); |
555 | +-#ifdef QT_NO_XKB |
556 | +- void *ev = const_cast<void *>(event); |
557 | +- xcb_refresh_keyboard_mapping(m_key_symbols, static_cast<xcb_mapping_notify_event_t *>(ev)); |
558 | +- updateModifiers(); |
559 | +-#else |
560 | +- Q_UNUSED(event) |
561 | + if (connection()->hasXKB()) { |
562 | + updateVModMapping(); |
563 | + updateVModToRModMapping(); |
564 | ++ } else { |
565 | ++ void *ev = const_cast<void *>(event); |
566 | ++ xcb_refresh_keyboard_mapping(m_key_symbols, static_cast<xcb_mapping_notify_event_t *>(ev)); |
567 | ++ updateModifiers(); |
568 | + } |
569 | +-#endif |
570 | + } |
571 | + |
572 | + QT_END_NAMESPACE |
573 | +--- a/src/plugins/platforms/xcb/qxcbkeyboard.h |
574 | ++++ b/src/plugins/platforms/xcb/qxcbkeyboard.h |
575 | +@@ -44,11 +44,15 @@ |
576 | + |
577 | + #include "qxcbobject.h" |
578 | + |
579 | +-#ifdef QT_NO_XKB |
580 | + #include <xcb/xcb_keysyms.h> |
581 | +-#endif |
582 | + |
583 | + #include <xkbcommon/xkbcommon.h> |
584 | ++#ifndef QT_NO_XKB |
585 | ++// note: extern won't be needed from libxkbcommon 0.4.1 and above |
586 | ++extern "C" { |
587 | ++#include <xkbcommon/xkbcommon-x11.h> |
588 | ++} |
589 | ++#endif |
590 | + |
591 | + #include <QEvent> |
592 | + |
593 | +@@ -65,41 +69,37 @@ |
594 | + |
595 | + void handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event); |
596 | + void handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event); |
597 | +- |
598 | + void handleMappingNotifyEvent(const void *event); |
599 | + |
600 | + Qt::KeyboardModifiers translateModifiers(int s) const; |
601 | +- |
602 | + void updateKeymap(); |
603 | + QList<int> possibleKeys(const QKeyEvent *e) const; |
604 | + |
605 | +-#ifdef QT_NO_XKB |
606 | +- void updateXKBStateFromCore(quint16 state); |
607 | ++ // when XKEYBOARD not present on the X server |
608 | + void updateXKBMods(); |
609 | + quint32 xkbModMask(quint16 state); |
610 | +-#else |
611 | +- int coreDeviceId() { return core_device_id; } |
612 | ++ void updateXKBStateFromCore(quint16 state); |
613 | ++ // when XKEYBOARD is present on the X server |
614 | ++ int coreDeviceId() const { return core_device_id; } |
615 | ++#ifndef QT_NO_XKB |
616 | + void updateXKBState(xcb_xkb_state_notify_event_t *state); |
617 | + #endif |
618 | + |
619 | + protected: |
620 | + void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time); |
621 | +- void resolveMaskConflicts(); |
622 | + |
623 | ++ void resolveMaskConflicts(); |
624 | + QString keysymToUnicode(xcb_keysym_t sym) const; |
625 | +- |
626 | + int keysymToQtKey(xcb_keysym_t keysym) const; |
627 | + int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const; |
628 | + |
629 | + void readXKBConfig(); |
630 | + void clearXKBConfig(); |
631 | +- |
632 | +-#ifdef QT_NO_XKB |
633 | ++ // when XKEYBOARD not present on the X server |
634 | + void updateModifiers(); |
635 | +-#else |
636 | ++ // when XKEYBOARD is present on the X server |
637 | + void updateVModMapping(); |
638 | + void updateVModToRModMapping(); |
639 | +-#endif |
640 | + |
641 | + private: |
642 | + bool m_config; |
643 | +@@ -120,9 +120,8 @@ |
644 | + |
645 | + _mod_masks rmod_masks; |
646 | + |
647 | +-#ifdef QT_NO_XKB |
648 | ++ // when XKEYBOARD not present on the X server |
649 | + xcb_key_symbols_t *m_key_symbols; |
650 | +- |
651 | + struct _xkb_mods { |
652 | + xkb_mod_index_t shift; |
653 | + xkb_mod_index_t lock; |
654 | +@@ -133,12 +132,10 @@ |
655 | + xkb_mod_index_t mod4; |
656 | + xkb_mod_index_t mod5; |
657 | + }; |
658 | +- |
659 | + _xkb_mods xkb_mods; |
660 | +-#else |
661 | ++ // when XKEYBOARD is present on the X server |
662 | + _mod_masks vmod_masks; |
663 | + int core_device_id; |
664 | +-#endif |
665 | + }; |
666 | + |
667 | + QT_END_NAMESPACE |
668 | +--- a/src/plugins/platforms/xcb/xcb-plugin.pro |
669 | ++++ b/src/plugins/platforms/xcb/xcb-plugin.pro |
670 | +@@ -121,13 +121,9 @@ |
671 | + INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude |
672 | + LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static |
673 | + } else { |
674 | +- LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr |
675 | ++ LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-keysyms |
676 | + !contains(DEFINES, QT_NO_SHAPE):LIBS += -lxcb-shape |
677 | +- contains(DEFINES, QT_NO_XKB) { |
678 | +- LIBS += -lxcb-keysyms |
679 | +- } else { |
680 | +- LIBS += -lxcb-xkb |
681 | +- } |
682 | ++ !contains(DEFINES, QT_NO_XKB):LIBS += -lxcb-xkb |
683 | + } |
684 | + |
685 | + # libxkbcommon |
686 | |
687 | === modified file 'debian/patches/series' |
688 | --- debian/patches/series 2014-04-01 16:39:26 +0000 |
689 | +++ debian/patches/series 2014-04-01 16:39:26 +0000 |
690 | @@ -29,3 +29,4 @@ |
691 | Minor-optimization-for-QTextEngine-shapeText.patch |
692 | HarfBuzz-NG-Hide-characters-that-should-normally-be-.patch |
693 | When-looking-up-the-window-hierarchy-stop-at-foreign.patch |
694 | +Add_better_support_for_keymap_update_handling.patch |
Building and to be tested via https:/ /launchpad. net/~ci- train-ppa- service/ +archive/ landing- 017
The earlier ubuntu11 was tested and is now in UNAPPROVED queue and needs to be passed to the archives first.