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