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