Merge lp:~timo-jyrinki/kubuntu-packaging/qtbase-fix-keymap-update-handling2 into lp:~kubuntu-packagers/kubuntu-packaging/qtbase-opensource-src

Proposed by Timo Jyrinki
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
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_better_support_for_keymap_update_handling.patch, copied from
  Debian and rebased).
* Build-depend on libxkbcommon-x11-dev, as the new patch includes
  <xkbcommon/xkbcommon-x11.h>.

Description of the change

For U-series when it opens, via a landing silo

To post a comment you must log in.
Revision history for this message
Dmitry Shachnev (mitya57) wrote :

> 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).

Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote :

There was a last minute 0.4.1 upload to trusty:
http://packages.ubuntu.com/search?keywords=libxkbcommon-x11-dev

So it's ok already now.

Revision history for this message
Dmitry Shachnev (mitya57) wrote :

Indeed, I missed that. Looks good to me then.

review: Approve
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: Needs Fixing (continuous-integration)
Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote :
review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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

Subscribers

People subscribed via source and target branches