Merge lp:~dandrader/ubuntu/trusty/maliit-framework/orientationAngleMapping into lp:ubuntu/trusty/maliit-framework
- Trusty (14.04)
- orientationAngleMapping
- Merge into trusty
Proposed by
Daniel d'Andrada
Status: | Merged |
---|---|
Merge reported by: | Iain Lane |
Merged at revision: | not available |
Proposed branch: | lp:~dandrader/ubuntu/trusty/maliit-framework/orientationAngleMapping |
Merge into: | lp:ubuntu/trusty/maliit-framework |
Diff against target: |
908 lines (+843/-12) 6 files modified
.pc/0006-fix_orientation_to_angle_mapping.patch/input-context/minputcontext.cpp (+794/-0) .pc/applied-patches (+1/-0) debian/changelog (+6/-0) debian/patches/0006-fix_orientation_to_angle_mapping.patch (+38/-0) debian/patches/series (+1/-0) input-context/minputcontext.cpp (+3/-12) |
To merge this branch: | bzr merge lp:~dandrader/ubuntu/trusty/maliit-framework/orientationAngleMapping |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Bill Filler (community) | Approve | ||
Ubuntu branches | Pending | ||
Review via email: mp+204304@code.launchpad.net |
Commit message
Fix mapping between screen orientations and rotation angles.
Simply use the function that Qt provides for that.
Description of the change
To post a comment you must log in.
Revision history for this message
Bill Filler (bfiller) wrote : | # |
Are there any related MPs required for this MP to build/function as expected?
YES, https:/
Revision history for this message
Iain Lane (laney) wrote : | # |
I merged this manually because I didn't see this MP—thanks for the work.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory '.pc/0006-fix_orientation_to_angle_mapping.patch' | |||
2 | === added file '.pc/0006-fix_orientation_to_angle_mapping.patch/.timestamp' | |||
3 | === added directory '.pc/0006-fix_orientation_to_angle_mapping.patch/input-context' | |||
4 | === added file '.pc/0006-fix_orientation_to_angle_mapping.patch/input-context/minputcontext.cpp' | |||
5 | --- .pc/0006-fix_orientation_to_angle_mapping.patch/input-context/minputcontext.cpp 1970-01-01 00:00:00 +0000 | |||
6 | +++ .pc/0006-fix_orientation_to_angle_mapping.patch/input-context/minputcontext.cpp 2014-01-31 18:02:44 +0000 | |||
7 | @@ -0,0 +1,794 @@ | |||
8 | 1 | /* * This file is part of Maliit framework * | ||
9 | 2 | * | ||
10 | 3 | * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | ||
11 | 4 | * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). | ||
12 | 5 | * Copyright (C) 2013 Jolla Ltd. | ||
13 | 6 | * | ||
14 | 7 | * All rights reserved. | ||
15 | 8 | * | ||
16 | 9 | * Contact: maliit-discuss@lists.maliit.org | ||
17 | 10 | * | ||
18 | 11 | * This library is free software; you can redistribute it and/or | ||
19 | 12 | * modify it under the terms of the GNU Lesser General Public | ||
20 | 13 | * License version 2.1 as published by the Free Software Foundation | ||
21 | 14 | * and appearing in the file LICENSE.LGPL included in the packaging | ||
22 | 15 | * of this file. | ||
23 | 16 | */ | ||
24 | 17 | |||
25 | 18 | |||
26 | 19 | #include "minputcontext.h" | ||
27 | 20 | |||
28 | 21 | #include <QGuiApplication> | ||
29 | 22 | #include <QKeyEvent> | ||
30 | 23 | #include <QTextFormat> | ||
31 | 24 | #include <QDebug> | ||
32 | 25 | #include <QByteArray> | ||
33 | 26 | #include <QRectF> | ||
34 | 27 | #include <QLocale> | ||
35 | 28 | #include <QWindow> | ||
36 | 29 | #include <QSharedDataPointer> | ||
37 | 30 | #include <QQuickItem> | ||
38 | 31 | |||
39 | 32 | namespace | ||
40 | 33 | { | ||
41 | 34 | const int SoftwareInputPanelHideTimer = 100; | ||
42 | 35 | const char * const InputContextName = "MInputContext"; | ||
43 | 36 | |||
44 | 37 | int orientationAngle(Qt::ScreenOrientation orientation) | ||
45 | 38 | { | ||
46 | 39 | switch (orientation) { | ||
47 | 40 | case Qt::PrimaryOrientation: // Urgh. | ||
48 | 41 | case Qt::PortraitOrientation: | ||
49 | 42 | return MInputContext::Angle270; | ||
50 | 43 | case Qt::LandscapeOrientation: | ||
51 | 44 | return MInputContext::Angle0; | ||
52 | 45 | case Qt::InvertedPortraitOrientation: | ||
53 | 46 | return MInputContext::Angle90; | ||
54 | 47 | case Qt::InvertedLandscapeOrientation: | ||
55 | 48 | return MInputContext::Angle180; | ||
56 | 49 | } | ||
57 | 50 | return MInputContext::Angle0; | ||
58 | 51 | } | ||
59 | 52 | } | ||
60 | 53 | |||
61 | 54 | bool MInputContext::debug = false; | ||
62 | 55 | |||
63 | 56 | |||
64 | 57 | MInputContext::MInputContext() | ||
65 | 58 | : imServer(0), | ||
66 | 59 | active(false), | ||
67 | 60 | inputPanelState(InputPanelHidden), | ||
68 | 61 | preeditCursorPos(-1), | ||
69 | 62 | redirectKeys(false) | ||
70 | 63 | { | ||
71 | 64 | QByteArray debugEnvVar = qgetenv("MALIIT_DEBUG"); | ||
72 | 65 | if (!debugEnvVar.isEmpty() && debugEnvVar != "0") { | ||
73 | 66 | qDebug() << "Creating Maliit input context"; | ||
74 | 67 | debug = true; | ||
75 | 68 | } | ||
76 | 69 | |||
77 | 70 | QSharedPointer<Maliit::InputContext::DBus::Address> address(new Maliit::InputContext::DBus::DynamicAddress); | ||
78 | 71 | imServer = new DBusServerConnection(address); | ||
79 | 72 | |||
80 | 73 | sipHideTimer.setSingleShot(true); | ||
81 | 74 | sipHideTimer.setInterval(SoftwareInputPanelHideTimer); | ||
82 | 75 | connect(&sipHideTimer, SIGNAL(timeout()), SLOT(sendHideInputMethod())); | ||
83 | 76 | |||
84 | 77 | connectInputMethodServer(); | ||
85 | 78 | } | ||
86 | 79 | |||
87 | 80 | MInputContext::~MInputContext() | ||
88 | 81 | { | ||
89 | 82 | delete imServer; | ||
90 | 83 | } | ||
91 | 84 | |||
92 | 85 | void MInputContext::connectInputMethodServer() | ||
93 | 86 | { | ||
94 | 87 | connect(imServer, SIGNAL(connected()), this, SLOT(onDBusConnection())); | ||
95 | 88 | connect(imServer, SIGNAL(disconnected()), this, SLOT(onDBusDisconnection())); | ||
96 | 89 | |||
97 | 90 | // Hook up incoming communication from input method server | ||
98 | 91 | connect(imServer, SIGNAL(activationLostEvent()), this, SLOT(activationLostEvent())); | ||
99 | 92 | |||
100 | 93 | connect(imServer, SIGNAL(imInitiatedHide()), this, SLOT(imInitiatedHide())); | ||
101 | 94 | |||
102 | 95 | connect(imServer, SIGNAL(commitString(QString,int,int,int)), | ||
103 | 96 | this, SLOT(commitString(QString,int,int,int))); | ||
104 | 97 | |||
105 | 98 | connect(imServer, SIGNAL(updatePreedit(QString,QList<Maliit::PreeditTextFormat>,int,int,int)), | ||
106 | 99 | this, SLOT(updatePreedit(QString,QList<Maliit::PreeditTextFormat>,int,int,int))); | ||
107 | 100 | |||
108 | 101 | connect(imServer, SIGNAL(keyEvent(int,int,int,QString,bool,int,Maliit::EventRequestType)), | ||
109 | 102 | this, SLOT(keyEvent(int,int,int,QString,bool,int,Maliit::EventRequestType))); | ||
110 | 103 | |||
111 | 104 | connect(imServer, SIGNAL(updateInputMethodArea(QRect)), | ||
112 | 105 | this, SLOT(updateInputMethodArea(QRect))); | ||
113 | 106 | |||
114 | 107 | connect(imServer, SIGNAL(setGlobalCorrectionEnabled(bool)), | ||
115 | 108 | this, SLOT(setGlobalCorrectionEnabled(bool))); | ||
116 | 109 | |||
117 | 110 | connect(imServer, SIGNAL(getPreeditRectangle(QRect&,bool&)), | ||
118 | 111 | this, SLOT(getPreeditRectangle(QRect&,bool&))); | ||
119 | 112 | |||
120 | 113 | connect(imServer, SIGNAL(invokeAction(QString,QKeySequence)), this, SLOT(onInvokeAction(QString,QKeySequence))); | ||
121 | 114 | |||
122 | 115 | connect(imServer, SIGNAL(setRedirectKeys(bool)), this, SLOT(setRedirectKeys(bool))); | ||
123 | 116 | |||
124 | 117 | connect(imServer, SIGNAL(setDetectableAutoRepeat(bool)), | ||
125 | 118 | this, SLOT(setDetectableAutoRepeat(bool))); | ||
126 | 119 | |||
127 | 120 | connect(imServer, SIGNAL(setSelection(int,int)), | ||
128 | 121 | this, SLOT(setSelection(int,int))); | ||
129 | 122 | |||
130 | 123 | connect(imServer, SIGNAL(getSelection(QString&,bool&)), | ||
131 | 124 | this, SLOT(getSelection(QString&, bool&))); | ||
132 | 125 | |||
133 | 126 | connect(imServer, SIGNAL(setLanguage(QString)), | ||
134 | 127 | this, SLOT(setLanguage(QString))); | ||
135 | 128 | } | ||
136 | 129 | |||
137 | 130 | |||
138 | 131 | bool MInputContext::isValid() const | ||
139 | 132 | { | ||
140 | 133 | return true; | ||
141 | 134 | } | ||
142 | 135 | |||
143 | 136 | void MInputContext::setLanguage(const QString &language) | ||
144 | 137 | { | ||
145 | 138 | QLocale newLocale(language); | ||
146 | 139 | Qt::LayoutDirection oldDirection = inputDirection(); | ||
147 | 140 | |||
148 | 141 | if (newLocale != inputLocale) { | ||
149 | 142 | inputLocale = newLocale; | ||
150 | 143 | emitLocaleChanged(); | ||
151 | 144 | } | ||
152 | 145 | |||
153 | 146 | Qt::LayoutDirection newDirection = inputDirection(); | ||
154 | 147 | if (newDirection != oldDirection) { | ||
155 | 148 | emitInputDirectionChanged(newDirection); | ||
156 | 149 | } | ||
157 | 150 | } | ||
158 | 151 | |||
159 | 152 | void MInputContext::reset() | ||
160 | 153 | { | ||
161 | 154 | if (debug) qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__; | ||
162 | 155 | |||
163 | 156 | const bool hadPreedit = !preedit.isEmpty(); | ||
164 | 157 | |||
165 | 158 | // reset input method server, preedit requires synchronization. | ||
166 | 159 | // rationale: input method might be autocommitting existing preedit without | ||
167 | 160 | // user interaction. | ||
168 | 161 | imServer->reset(hadPreedit); | ||
169 | 162 | } | ||
170 | 163 | |||
171 | 164 | void MInputContext::commit() | ||
172 | 165 | { | ||
173 | 166 | if (debug) qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__; | ||
174 | 167 | |||
175 | 168 | const bool hadPreedit = !preedit.isEmpty(); | ||
176 | 169 | |||
177 | 170 | if (hadPreedit) { | ||
178 | 171 | QList<QInputMethodEvent::Attribute> attributes; | ||
179 | 172 | if (preeditCursorPos >= 0) { | ||
180 | 173 | bool valid = false; | ||
181 | 174 | int start = cursorStartPosition(&valid); | ||
182 | 175 | if (valid) { | ||
183 | 176 | attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, | ||
184 | 177 | start + preeditCursorPos, 0, QVariant()); | ||
185 | 178 | } | ||
186 | 179 | } | ||
187 | 180 | |||
188 | 181 | QInputMethodEvent event("", attributes); | ||
189 | 182 | event.setCommitString(preedit); | ||
190 | 183 | QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); | ||
191 | 184 | |||
192 | 185 | preedit.clear(); | ||
193 | 186 | preeditCursorPos = -1; | ||
194 | 187 | } | ||
195 | 188 | |||
196 | 189 | imServer->reset(hadPreedit); | ||
197 | 190 | } | ||
198 | 191 | |||
199 | 192 | void MInputContext::invokeAction(QInputMethod::Action action, int x) | ||
200 | 193 | { | ||
201 | 194 | if (debug) qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__; | ||
202 | 195 | |||
203 | 196 | if (!inputMethodAccepted()) | ||
204 | 197 | return; | ||
205 | 198 | |||
206 | 199 | if (action == QInputMethod::Click) { | ||
207 | 200 | if (x < 0 || x >= preedit.length()) { | ||
208 | 201 | reset(); | ||
209 | 202 | return; | ||
210 | 203 | } | ||
211 | 204 | |||
212 | 205 | // To preserve the wire protocol, the "x" argument gets | ||
213 | 206 | // transferred in widget state instead of being an extra | ||
214 | 207 | // argument to mouseClickedOnPreedit(). | ||
215 | 208 | QMap<QString, QVariant> stateInformation = getStateInformation(); | ||
216 | 209 | stateInformation["preeditClickPos"] = x; | ||
217 | 210 | imServer->updateWidgetInformation(stateInformation, false); | ||
218 | 211 | |||
219 | 212 | // FIXME: proper positions and preeditClickPos | ||
220 | 213 | QRect preeditRect; | ||
221 | 214 | QPoint globalPos; | ||
222 | 215 | imServer->mouseClickedOnPreedit(globalPos, preeditRect); | ||
223 | 216 | |||
224 | 217 | } else { | ||
225 | 218 | QPlatformInputContext::invokeAction(action, x); | ||
226 | 219 | } | ||
227 | 220 | } | ||
228 | 221 | |||
229 | 222 | void MInputContext::update(Qt::InputMethodQueries queries) | ||
230 | 223 | { | ||
231 | 224 | if (debug) qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__; | ||
232 | 225 | |||
233 | 226 | Q_UNUSED(queries) // fetching everything | ||
234 | 227 | |||
235 | 228 | if (queries & Qt::ImPlatformData) { | ||
236 | 229 | updateInputMethodExtensions(); | ||
237 | 230 | } | ||
238 | 231 | |||
239 | 232 | // get the state information of currently focused widget, and pass it to input method server | ||
240 | 233 | QMap<QString, QVariant> stateInformation = getStateInformation(); | ||
241 | 234 | imServer->updateWidgetInformation(stateInformation, false); | ||
242 | 235 | } | ||
243 | 236 | |||
244 | 237 | void MInputContext::updateServerOrientation(Qt::ScreenOrientation orientation) | ||
245 | 238 | { | ||
246 | 239 | if (active) { | ||
247 | 240 | imServer->appOrientationChanged(orientationAngle(orientation)); | ||
248 | 241 | } | ||
249 | 242 | } | ||
250 | 243 | |||
251 | 244 | |||
252 | 245 | void MInputContext::setFocusObject(QObject *focused) | ||
253 | 246 | { | ||
254 | 247 | if (debug) qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__ << focused; | ||
255 | 248 | |||
256 | 249 | updateInputMethodExtensions(); | ||
257 | 250 | |||
258 | 251 | QWindow *newFocusWindow = qGuiApp->focusWindow(); | ||
259 | 252 | if (newFocusWindow != window.data()) { | ||
260 | 253 | if (window) { | ||
261 | 254 | disconnect(window.data(), SIGNAL(contentOrientationChanged(Qt::ScreenOrientation)), | ||
262 | 255 | this, SLOT(updateServerOrientation(Qt::ScreenOrientation))); | ||
263 | 256 | } | ||
264 | 257 | |||
265 | 258 | window = newFocusWindow; | ||
266 | 259 | if (window) { | ||
267 | 260 | connect(window.data(), SIGNAL(contentOrientationChanged(Qt::ScreenOrientation)), | ||
268 | 261 | this, SLOT(updateServerOrientation(Qt::ScreenOrientation))); | ||
269 | 262 | } | ||
270 | 263 | } | ||
271 | 264 | |||
272 | 265 | if (focused && !active) { | ||
273 | 266 | imServer->activateContext(); | ||
274 | 267 | active = true; | ||
275 | 268 | updateServerOrientation(newFocusWindow->contentOrientation()); | ||
276 | 269 | } | ||
277 | 270 | |||
278 | 271 | const QMap<QString, QVariant> stateInformation = getStateInformation(); | ||
279 | 272 | imServer->updateWidgetInformation(stateInformation, true); | ||
280 | 273 | |||
281 | 274 | if (inputPanelState == InputPanelShowPending && focused) { | ||
282 | 275 | sipHideTimer.stop(); | ||
283 | 276 | imServer->showInputMethod(); | ||
284 | 277 | inputPanelState = InputPanelShown; | ||
285 | 278 | } | ||
286 | 279 | } | ||
287 | 280 | |||
288 | 281 | bool MInputContext::filterEvent(const QEvent *event) | ||
289 | 282 | { | ||
290 | 283 | bool eaten = false; | ||
291 | 284 | |||
292 | 285 | switch (event->type()) { | ||
293 | 286 | |||
294 | 287 | case QEvent::KeyPress: | ||
295 | 288 | case QEvent::KeyRelease: | ||
296 | 289 | if (!inputMethodAccepted()) { | ||
297 | 290 | break; | ||
298 | 291 | } | ||
299 | 292 | |||
300 | 293 | if (redirectKeys) { | ||
301 | 294 | const QKeyEvent *key = static_cast<const QKeyEvent *>(event); | ||
302 | 295 | imServer->processKeyEvent(key->type(), static_cast<Qt::Key>(key->key()), | ||
303 | 296 | key->modifiers(), key->text(), key->isAutoRepeat(), | ||
304 | 297 | key->count(), key->nativeScanCode(), | ||
305 | 298 | key->nativeModifiers(), 0 /* currentKeyEventTime */); | ||
306 | 299 | eaten = true; | ||
307 | 300 | } | ||
308 | 301 | break; | ||
309 | 302 | |||
310 | 303 | default: | ||
311 | 304 | break; | ||
312 | 305 | } | ||
313 | 306 | |||
314 | 307 | return eaten; | ||
315 | 308 | } | ||
316 | 309 | |||
317 | 310 | QRectF MInputContext::keyboardRect() const | ||
318 | 311 | { | ||
319 | 312 | return keyboardRectangle; | ||
320 | 313 | } | ||
321 | 314 | |||
322 | 315 | bool MInputContext::isAnimating() const | ||
323 | 316 | { | ||
324 | 317 | return false; // don't know here when input method server is actually doing transitions | ||
325 | 318 | } | ||
326 | 319 | |||
327 | 320 | void MInputContext::showInputPanel() | ||
328 | 321 | { | ||
329 | 322 | if (debug) qDebug() << __PRETTY_FUNCTION__; | ||
330 | 323 | |||
331 | 324 | if (inputMethodAccepted()) { | ||
332 | 325 | sipHideTimer.stop(); | ||
333 | 326 | } | ||
334 | 327 | |||
335 | 328 | if (!active || !inputMethodAccepted()) { | ||
336 | 329 | // in case SIP request comes without a properly focused widget, we | ||
337 | 330 | // don't ask input method server to be shown. It's done when the next widget | ||
338 | 331 | // is focused, so the widget state information can be set. | ||
339 | 332 | inputPanelState = InputPanelShowPending; | ||
340 | 333 | |||
341 | 334 | } else { | ||
342 | 335 | // note: could do this also if panel was hidden | ||
343 | 336 | |||
344 | 337 | imServer->showInputMethod(); | ||
345 | 338 | inputPanelState = InputPanelShown; | ||
346 | 339 | } | ||
347 | 340 | } | ||
348 | 341 | |||
349 | 342 | void MInputContext::hideInputPanel() | ||
350 | 343 | { | ||
351 | 344 | if (debug) qDebug() << __PRETTY_FUNCTION__; | ||
352 | 345 | sipHideTimer.start(); | ||
353 | 346 | } | ||
354 | 347 | |||
355 | 348 | bool MInputContext::isInputPanelVisible() const | ||
356 | 349 | { | ||
357 | 350 | return !keyboardRectangle.isEmpty(); | ||
358 | 351 | } | ||
359 | 352 | |||
360 | 353 | QLocale MInputContext::locale() const | ||
361 | 354 | { | ||
362 | 355 | return inputLocale; | ||
363 | 356 | } | ||
364 | 357 | |||
365 | 358 | Qt::LayoutDirection MInputContext::inputDirection() const | ||
366 | 359 | { | ||
367 | 360 | return inputLocale.textDirection(); | ||
368 | 361 | } | ||
369 | 362 | |||
370 | 363 | void MInputContext::sendHideInputMethod() | ||
371 | 364 | { | ||
372 | 365 | imServer->hideInputMethod(); | ||
373 | 366 | |||
374 | 367 | inputPanelState = InputPanelHidden; | ||
375 | 368 | } | ||
376 | 369 | |||
377 | 370 | void MInputContext::activationLostEvent() | ||
378 | 371 | { | ||
379 | 372 | if (debug) qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__; | ||
380 | 373 | |||
381 | 374 | // This method is called when activation was gracefully lost. | ||
382 | 375 | // There is similar cleaning up done in onDBusDisconnection. | ||
383 | 376 | active = false; | ||
384 | 377 | inputPanelState = InputPanelHidden; | ||
385 | 378 | |||
386 | 379 | updateInputMethodArea(QRect()); | ||
387 | 380 | } | ||
388 | 381 | |||
389 | 382 | |||
390 | 383 | void MInputContext::imInitiatedHide() | ||
391 | 384 | { | ||
392 | 385 | if (debug) qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__; | ||
393 | 386 | |||
394 | 387 | inputPanelState = InputPanelHidden; | ||
395 | 388 | |||
396 | 389 | // remove focus on QtQuick2 | ||
397 | 390 | QQuickItem *inputItem = qobject_cast<QQuickItem*>(QGuiApplication::focusObject()); | ||
398 | 391 | if (inputItem) { | ||
399 | 392 | inputItem->setFocus(false); | ||
400 | 393 | } | ||
401 | 394 | |||
402 | 395 | } | ||
403 | 396 | |||
404 | 397 | void MInputContext::commitString(const QString &string, int replacementStart, | ||
405 | 398 | int replacementLength, int cursorPos) | ||
406 | 399 | { | ||
407 | 400 | if (debug) qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__; | ||
408 | 401 | |||
409 | 402 | if (imServer->pendingResets()) { | ||
410 | 403 | return; | ||
411 | 404 | } | ||
412 | 405 | |||
413 | 406 | preedit.clear(); | ||
414 | 407 | preeditCursorPos = -1; | ||
415 | 408 | |||
416 | 409 | int start = -1; | ||
417 | 410 | if (cursorPos >= 0) { | ||
418 | 411 | bool valid = false; | ||
419 | 412 | int currentStart = cursorStartPosition(&valid); | ||
420 | 413 | if (valid) { | ||
421 | 414 | start = cursorPos + currentStart + replacementStart; | ||
422 | 415 | } | ||
423 | 416 | } | ||
424 | 417 | |||
425 | 418 | if (start >= 0) { | ||
426 | 419 | QList<QInputMethodEvent::Attribute> attributes; | ||
427 | 420 | attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, start, 0, QVariant()); | ||
428 | 421 | QInputMethodEvent event("", attributes); | ||
429 | 422 | event.setCommitString(string, replacementStart, replacementLength); | ||
430 | 423 | QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); | ||
431 | 424 | |||
432 | 425 | } else { | ||
433 | 426 | QInputMethodEvent event; | ||
434 | 427 | event.setCommitString(string, replacementStart, replacementLength); | ||
435 | 428 | QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); | ||
436 | 429 | } | ||
437 | 430 | } | ||
438 | 431 | |||
439 | 432 | |||
440 | 433 | void MInputContext::updatePreedit(const QString &string, | ||
441 | 434 | const QList<Maliit::PreeditTextFormat> &preeditFormats, | ||
442 | 435 | int replacementStart, int replacementLength, int cursorPos) | ||
443 | 436 | { | ||
444 | 437 | if (debug) { | ||
445 | 438 | qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__ << "preedit:" << string | ||
446 | 439 | << ", replacementStart:" << replacementStart | ||
447 | 440 | << ", replacementLength:" << replacementLength | ||
448 | 441 | << ", cursorPos:" << cursorPos; | ||
449 | 442 | } | ||
450 | 443 | |||
451 | 444 | if (imServer->pendingResets()) { | ||
452 | 445 | return; | ||
453 | 446 | } | ||
454 | 447 | |||
455 | 448 | updatePreeditInternally(string, preeditFormats, replacementStart, replacementLength, cursorPos); | ||
456 | 449 | } | ||
457 | 450 | |||
458 | 451 | void MInputContext::updatePreeditInternally(const QString &string, | ||
459 | 452 | const QList<Maliit::PreeditTextFormat> &preeditFormats, | ||
460 | 453 | int replacementStart, int replacementLength, int cursorPos) | ||
461 | 454 | { | ||
462 | 455 | preedit = string; | ||
463 | 456 | preeditCursorPos = cursorPos; | ||
464 | 457 | |||
465 | 458 | QList<QInputMethodEvent::Attribute> attributes; | ||
466 | 459 | Q_FOREACH (const Maliit::PreeditTextFormat &preeditFormat, preeditFormats) { | ||
467 | 460 | |||
468 | 461 | QTextCharFormat format; | ||
469 | 462 | |||
470 | 463 | // update style mode | ||
471 | 464 | switch (preeditFormat.preeditFace) { | ||
472 | 465 | case Maliit::PreeditNoCandidates: | ||
473 | 466 | format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); | ||
474 | 467 | format.setUnderlineColor(Qt::red); | ||
475 | 468 | break; | ||
476 | 469 | case Maliit::PreeditUnconvertible: | ||
477 | 470 | format.setForeground(QBrush(QColor(128, 128, 128))); | ||
478 | 471 | break; | ||
479 | 472 | case Maliit::PreeditActive: | ||
480 | 473 | format.setForeground(QBrush(QColor(153, 50, 204))); | ||
481 | 474 | format.setFontWeight(QFont::Bold); | ||
482 | 475 | break; | ||
483 | 476 | case Maliit::PreeditKeyPress: | ||
484 | 477 | case Maliit::PreeditDefault: | ||
485 | 478 | format.setUnderlineStyle(QTextCharFormat::SingleUnderline); | ||
486 | 479 | format.setUnderlineColor(QColor(0, 0, 0)); | ||
487 | 480 | break; | ||
488 | 481 | } | ||
489 | 482 | |||
490 | 483 | attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, | ||
491 | 484 | preeditFormat.start, | ||
492 | 485 | preeditFormat.length, format); | ||
493 | 486 | } | ||
494 | 487 | |||
495 | 488 | if (cursorPos >= 0) { | ||
496 | 489 | attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, 1, QVariant()); | ||
497 | 490 | } | ||
498 | 491 | |||
499 | 492 | QInputMethodEvent event(string, attributes); | ||
500 | 493 | if (replacementStart || replacementLength) { | ||
501 | 494 | event.setCommitString("", replacementStart, replacementLength); | ||
502 | 495 | } | ||
503 | 496 | |||
504 | 497 | QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); | ||
505 | 498 | } | ||
506 | 499 | |||
507 | 500 | void MInputContext::keyEvent(int type, int key, int modifiers, const QString &text, | ||
508 | 501 | bool autoRepeat, int count, | ||
509 | 502 | Maliit::EventRequestType requestType) | ||
510 | 503 | { | ||
511 | 504 | if (debug) qDebug() << InputContextName << "in" << __PRETTY_FUNCTION__; | ||
512 | 505 | |||
513 | 506 | if (qGuiApp->focusWindow() != 0 && requestType != Maliit::EventRequestSignalOnly) { | ||
514 | 507 | QEvent::Type eventType = static_cast<QEvent::Type>(type); | ||
515 | 508 | QKeyEvent event(eventType, key, static_cast<Qt::KeyboardModifiers>(modifiers), text, autoRepeat, count); | ||
516 | 509 | // need window instead of focus item so e.g. QQuickItem::keyPressEvent() gets properly called | ||
517 | 510 | QGuiApplication::sendEvent(qGuiApp->focusWindow(), &event); | ||
518 | 511 | } | ||
519 | 512 | } | ||
520 | 513 | |||
521 | 514 | |||
522 | 515 | void MInputContext::updateInputMethodArea(const QRect &rect) | ||
523 | 516 | { | ||
524 | 517 | bool wasVisible = isInputPanelVisible(); | ||
525 | 518 | |||
526 | 519 | if (rect != keyboardRectangle) { | ||
527 | 520 | keyboardRectangle = rect; | ||
528 | 521 | emitKeyboardRectChanged(); | ||
529 | 522 | |||
530 | 523 | if (wasVisible != isInputPanelVisible()) { | ||
531 | 524 | emitInputPanelVisibleChanged(); | ||
532 | 525 | } | ||
533 | 526 | } | ||
534 | 527 | } | ||
535 | 528 | |||
536 | 529 | |||
537 | 530 | void MInputContext::setGlobalCorrectionEnabled(bool enabled) | ||
538 | 531 | { | ||
539 | 532 | Q_UNUSED(enabled) | ||
540 | 533 | // not handling preedit injections, ignored | ||
541 | 534 | } | ||
542 | 535 | |||
543 | 536 | |||
544 | 537 | void MInputContext::getPreeditRectangle(QRect &rectangle, bool &valid) const | ||
545 | 538 | { | ||
546 | 539 | // not supported | ||
547 | 540 | rectangle = QRect(); | ||
548 | 541 | valid = false; | ||
549 | 542 | |||
550 | 543 | return; | ||
551 | 544 | } | ||
552 | 545 | |||
553 | 546 | void MInputContext::onInvokeAction(const QString &action, const QKeySequence &sequence) | ||
554 | 547 | { | ||
555 | 548 | if (debug) qDebug() << InputContextName << __PRETTY_FUNCTION__ << "action" << action; | ||
556 | 549 | |||
557 | 550 | // NOTE: currently not trying to trigger action directly | ||
558 | 551 | static const Qt::KeyboardModifiers AllModifiers = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | ||
559 | 552 | | Qt::MetaModifier | Qt::KeypadModifier; | ||
560 | 553 | |||
561 | 554 | for (int i = 0; i < sequence.count(); i++) { | ||
562 | 555 | const int key = sequence[i] & ~AllModifiers; | ||
563 | 556 | const int modifiers = sequence[i] & AllModifiers; | ||
564 | 557 | QString text(""); | ||
565 | 558 | if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { | ||
566 | 559 | text = QString(key); | ||
567 | 560 | } | ||
568 | 561 | keyEvent(QEvent::KeyPress, key, modifiers, text, false, 1); | ||
569 | 562 | keyEvent(QEvent::KeyRelease, key, modifiers, text, false, 1); | ||
570 | 563 | } | ||
571 | 564 | } | ||
572 | 565 | |||
573 | 566 | void MInputContext::onDBusDisconnection() | ||
574 | 567 | { | ||
575 | 568 | if (debug) qDebug() << __PRETTY_FUNCTION__; | ||
576 | 569 | |||
577 | 570 | active = false; | ||
578 | 571 | redirectKeys = false; | ||
579 | 572 | |||
580 | 573 | updateInputMethodArea(QRect()); | ||
581 | 574 | } | ||
582 | 575 | |||
583 | 576 | void MInputContext::onDBusConnection() | ||
584 | 577 | { | ||
585 | 578 | if (debug) qDebug() << __PRETTY_FUNCTION__; | ||
586 | 579 | |||
587 | 580 | // using one attribute extension for everything | ||
588 | 581 | imServer->registerAttributeExtension(0, QString()); | ||
589 | 582 | |||
590 | 583 | // Force activation, since setFocusWidget may have been called after | ||
591 | 584 | // onDBusDisconnection set active to false or before the dbus connection. | ||
592 | 585 | active = false; | ||
593 | 586 | |||
594 | 587 | if (inputMethodAccepted()) { | ||
595 | 588 | setFocusObject(QGuiApplication::focusObject()); | ||
596 | 589 | if (inputPanelState != InputPanelHidden) { | ||
597 | 590 | imServer->showInputMethod(); | ||
598 | 591 | inputPanelState = InputPanelShown; | ||
599 | 592 | } | ||
600 | 593 | } | ||
601 | 594 | } | ||
602 | 595 | |||
603 | 596 | void MInputContext::notifyOrientationAboutToChange(MInputContext::OrientationAngle angle) | ||
604 | 597 | { | ||
605 | 598 | // can get called from signal so cannot be sure we are really currently active | ||
606 | 599 | if (active) { | ||
607 | 600 | imServer->appOrientationAboutToChange(static_cast<int>(angle)); | ||
608 | 601 | } | ||
609 | 602 | } | ||
610 | 603 | |||
611 | 604 | void MInputContext::notifyOrientationChanged(MInputContext::OrientationAngle angle) | ||
612 | 605 | { | ||
613 | 606 | // can get called from signal so cannot be sure we are really currently active | ||
614 | 607 | if (active) { | ||
615 | 608 | imServer->appOrientationChanged(static_cast<int>(angle)); | ||
616 | 609 | } | ||
617 | 610 | } | ||
618 | 611 | |||
619 | 612 | Maliit::TextContentType MInputContext::contentType(Qt::InputMethodHints hints) const | ||
620 | 613 | { | ||
621 | 614 | Maliit::TextContentType type = Maliit::FreeTextContentType; | ||
622 | 615 | hints &= Qt::ImhExclusiveInputMask; | ||
623 | 616 | |||
624 | 617 | if (hints == Qt::ImhFormattedNumbersOnly || hints == Qt::ImhDigitsOnly) { | ||
625 | 618 | type = Maliit::NumberContentType; | ||
626 | 619 | } else if (hints == Qt::ImhDialableCharactersOnly) { | ||
627 | 620 | type = Maliit::PhoneNumberContentType; | ||
628 | 621 | } else if (hints == Qt::ImhEmailCharactersOnly) { | ||
629 | 622 | type = Maliit::EmailContentType; | ||
630 | 623 | } else if (hints == Qt::ImhUrlCharactersOnly) { | ||
631 | 624 | type = Maliit::UrlContentType; | ||
632 | 625 | } | ||
633 | 626 | |||
634 | 627 | return type; | ||
635 | 628 | } | ||
636 | 629 | |||
637 | 630 | void MInputContext::setRedirectKeys(bool enabled) | ||
638 | 631 | { | ||
639 | 632 | redirectKeys = enabled; | ||
640 | 633 | } | ||
641 | 634 | |||
642 | 635 | void MInputContext::setDetectableAutoRepeat(bool enabled) | ||
643 | 636 | { | ||
644 | 637 | Q_UNUSED(enabled); | ||
645 | 638 | qWarning() << "Detectable autorepeat not supported."; | ||
646 | 639 | } | ||
647 | 640 | |||
648 | 641 | QMap<QString, QVariant> MInputContext::getStateInformation() const | ||
649 | 642 | { | ||
650 | 643 | QMap<QString, QVariant> stateInformation; | ||
651 | 644 | |||
652 | 645 | stateInformation["focusState"] = inputMethodAccepted(); | ||
653 | 646 | |||
654 | 647 | if (!inputMethodAccepted()) { | ||
655 | 648 | return stateInformation; | ||
656 | 649 | } | ||
657 | 650 | |||
658 | 651 | QInputMethodQueryEvent query(Qt::ImQueryAll); | ||
659 | 652 | QGuiApplication::sendEvent(qGuiApp->focusObject(), &query); | ||
660 | 653 | |||
661 | 654 | QVariant queryResult; | ||
662 | 655 | |||
663 | 656 | queryResult = query.value(Qt::ImSurroundingText); | ||
664 | 657 | if (queryResult.isValid()) { | ||
665 | 658 | stateInformation["surroundingText"] = queryResult.toString(); | ||
666 | 659 | } | ||
667 | 660 | |||
668 | 661 | queryResult = query.value(Qt::ImCursorPosition); | ||
669 | 662 | if (queryResult.isValid()) { | ||
670 | 663 | stateInformation["cursorPosition"] = queryResult.toInt(); | ||
671 | 664 | } | ||
672 | 665 | |||
673 | 666 | queryResult = query.value(Qt::ImAnchorPosition); | ||
674 | 667 | if (queryResult.isValid()) { | ||
675 | 668 | stateInformation["anchorPosition"] = queryResult.toInt(); | ||
676 | 669 | } | ||
677 | 670 | |||
678 | 671 | queryResult = query.value(Qt::ImHints); | ||
679 | 672 | Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryResult.toUInt()); | ||
680 | 673 | |||
681 | 674 | // content type value | ||
682 | 675 | // Deprecated, replaced by just transmitting all hints (see below): | ||
683 | 676 | // FIXME: Remove once MAbstractInputMethod API for this got deprecated/removed. | ||
684 | 677 | stateInformation["contentType"] = contentType(hints); | ||
685 | 678 | |||
686 | 679 | stateInformation["autocapitalizationEnabled"] = !(hints & Qt::ImhNoAutoUppercase); | ||
687 | 680 | stateInformation["hiddenText"] = static_cast<bool>(hints & Qt::ImhHiddenText); | ||
688 | 681 | stateInformation["predictionEnabled"] = ! static_cast<bool>(hints & Qt::ImhNoPredictiveText); | ||
689 | 682 | |||
690 | 683 | stateInformation["maliit-inputmethod-hints"] = QVariant(static_cast<qint64>(hints)); | ||
691 | 684 | |||
692 | 685 | // is text selected | ||
693 | 686 | queryResult = query.value(Qt::ImCurrentSelection); | ||
694 | 687 | if (queryResult.isValid()) { | ||
695 | 688 | stateInformation["hasSelection"] = !(queryResult.toString().isEmpty()); | ||
696 | 689 | } | ||
697 | 690 | |||
698 | 691 | QWindow *window = qGuiApp->focusWindow(); | ||
699 | 692 | if (window) { | ||
700 | 693 | stateInformation["winId"] = static_cast<qulonglong>(window->winId()); | ||
701 | 694 | } | ||
702 | 695 | |||
703 | 696 | queryResult = query.value(Qt::ImCursorRectangle); | ||
704 | 697 | if (queryResult.isValid()) { | ||
705 | 698 | QRect rect = queryResult.toRect(); | ||
706 | 699 | rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(rect); | ||
707 | 700 | if (window) { | ||
708 | 701 | stateInformation["cursorRectangle"] = QRect(window->mapToGlobal(rect.topLeft()), rect.size()); | ||
709 | 702 | } | ||
710 | 703 | } | ||
711 | 704 | |||
712 | 705 | stateInformation["toolbarId"] = 0; // Global extension id. And bad state parameter name for it. | ||
713 | 706 | |||
714 | 707 | return stateInformation; | ||
715 | 708 | } | ||
716 | 709 | |||
717 | 710 | void MInputContext::setSelection(int start, int length) | ||
718 | 711 | { | ||
719 | 712 | if (!inputMethodAccepted()) | ||
720 | 713 | return; | ||
721 | 714 | |||
722 | 715 | QList<QInputMethodEvent::Attribute> attributes; | ||
723 | 716 | attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, start, | ||
724 | 717 | length, QVariant()); | ||
725 | 718 | QInputMethodEvent event("", attributes); | ||
726 | 719 | QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); | ||
727 | 720 | } | ||
728 | 721 | |||
729 | 722 | void MInputContext::getSelection(QString &selection, bool &valid) const | ||
730 | 723 | { | ||
731 | 724 | selection.clear(); | ||
732 | 725 | |||
733 | 726 | QString selectionText; | ||
734 | 727 | valid = false; | ||
735 | 728 | |||
736 | 729 | if (!inputMethodAccepted()) { | ||
737 | 730 | return; | ||
738 | 731 | } | ||
739 | 732 | |||
740 | 733 | QInputMethodQueryEvent query(Qt::ImCurrentSelection); | ||
741 | 734 | QGuiApplication::sendEvent(qGuiApp->focusObject(), &query); | ||
742 | 735 | |||
743 | 736 | QVariant queryResult = query.value(Qt::ImCurrentSelection); | ||
744 | 737 | valid = queryResult.isValid(); | ||
745 | 738 | selectionText = queryResult.toString(); | ||
746 | 739 | |||
747 | 740 | selection = selectionText; | ||
748 | 741 | } | ||
749 | 742 | |||
750 | 743 | int MInputContext::cursorStartPosition(bool *valid) | ||
751 | 744 | { | ||
752 | 745 | int start = -1; | ||
753 | 746 | if (valid) { | ||
754 | 747 | *valid = false; | ||
755 | 748 | } | ||
756 | 749 | |||
757 | 750 | if (!inputMethodAccepted()) { | ||
758 | 751 | return start; | ||
759 | 752 | } | ||
760 | 753 | |||
761 | 754 | QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition); | ||
762 | 755 | QGuiApplication::sendEvent(qGuiApp->focusObject(), &query); | ||
763 | 756 | |||
764 | 757 | // obtain the cursor absolute position | ||
765 | 758 | QVariant queryResult = query.value(Qt::ImCursorPosition); | ||
766 | 759 | if (queryResult.isValid()) { | ||
767 | 760 | int absCursorPos = queryResult.toInt(); | ||
768 | 761 | |||
769 | 762 | // Fetch anchor position too but don't require it. | ||
770 | 763 | queryResult = query.value(Qt::ImAnchorPosition); | ||
771 | 764 | int absAnchorPos = queryResult.isValid() ? queryResult.toInt() : absCursorPos; | ||
772 | 765 | |||
773 | 766 | // In case of selection, base cursorPos on start of it. | ||
774 | 767 | start = qMin<int>(absCursorPos, absAnchorPos); | ||
775 | 768 | *valid = true; | ||
776 | 769 | } | ||
777 | 770 | |||
778 | 771 | return start; | ||
779 | 772 | } | ||
780 | 773 | |||
781 | 774 | void MInputContext::updateInputMethodExtensions() | ||
782 | 775 | { | ||
783 | 776 | if (!inputMethodAccepted()) { | ||
784 | 777 | return; | ||
785 | 778 | } | ||
786 | 779 | if (debug) qDebug() << InputContextName << __PRETTY_FUNCTION__; | ||
787 | 780 | |||
788 | 781 | QVariantMap extensions = qGuiApp->focusObject()->property("__inputMethodExtensions").toMap(); | ||
789 | 782 | QVariant value; | ||
790 | 783 | value = extensions.value("enterKeyIconSource"); | ||
791 | 784 | imServer->setExtendedAttribute(0, "/keys", "actionKey", "icon", QVariant(value.toUrl().toString())); | ||
792 | 785 | |||
793 | 786 | value = extensions.value("enterKeyText"); | ||
794 | 787 | imServer->setExtendedAttribute(0, "/keys", "actionKey", "label", QVariant(value.toString())); | ||
795 | 788 | |||
796 | 789 | value = extensions.value("enterKeyEnabled"); | ||
797 | 790 | imServer->setExtendedAttribute(0, "/keys", "actionKey", "enabled", value.isValid() ? value.toBool() : true); | ||
798 | 791 | |||
799 | 792 | value = extensions.value("enterKeyHighlighted"); | ||
800 | 793 | imServer->setExtendedAttribute(0, "/keys", "actionKey", "highlighted", value.isValid() ? value.toBool() : false); | ||
801 | 794 | } | ||
802 | 0 | 795 | ||
803 | === modified file '.pc/applied-patches' | |||
804 | --- .pc/applied-patches 2013-07-23 19:47:04 +0000 | |||
805 | +++ .pc/applied-patches 2014-01-31 18:02:44 +0000 | |||
806 | @@ -3,3 +3,4 @@ | |||
807 | 3 | 0003-prediction.patch | 3 | 0003-prediction.patch |
808 | 4 | 0004-fix_activationlostevent.patch | 4 | 0004-fix_activationlostevent.patch |
809 | 5 | 0005-testability.patch | 5 | 0005-testability.patch |
810 | 6 | 0006-fix_orientation_to_angle_mapping.patch | ||
811 | 6 | 7 | ||
812 | === modified file 'debian/changelog' | |||
813 | --- debian/changelog 2014-01-24 13:49:59 +0000 | |||
814 | +++ debian/changelog 2014-01-31 18:02:44 +0000 | |||
815 | @@ -1,3 +1,9 @@ | |||
816 | 1 | maliit-framework (0.99.0+git20130615+97e8335-0ubuntu6) trusty; urgency=medium | ||
817 | 2 | |||
818 | 3 | * Fix mapping between screen orientations and rotation angles. (LP: #1251330) | ||
819 | 4 | |||
820 | 5 | -- Daniel d'Andrada <daniel.dandrada@canonical.com> Fri, 31 Jan 2014 15:59:27 -0200 | ||
821 | 6 | |||
822 | 1 | maliit-framework (0.99.0+git20130615+97e8335-0ubuntu5) trusty; urgency=medium | 7 | maliit-framework (0.99.0+git20130615+97e8335-0ubuntu5) trusty; urgency=medium |
823 | 2 | 8 | ||
824 | 3 | * Modify xvfb command to successfully pass tests (LP: #1272249) | 9 | * Modify xvfb command to successfully pass tests (LP: #1272249) |
825 | 4 | 10 | ||
826 | === added file 'debian/patches/0006-fix_orientation_to_angle_mapping.patch' | |||
827 | --- debian/patches/0006-fix_orientation_to_angle_mapping.patch 1970-01-01 00:00:00 +0000 | |||
828 | +++ debian/patches/0006-fix_orientation_to_angle_mapping.patch 2014-01-31 18:02:44 +0000 | |||
829 | @@ -0,0 +1,38 @@ | |||
830 | 1 | Author: Daniel d'Andrada <daniel.dandrada@canonical.com> | ||
831 | 2 | Bug: https://bugs.launchpad.net/ubuntu-keyboard/+bug/1251330 | ||
832 | 3 | Forwarded: no | ||
833 | 4 | Description: Fix mapping between screen orientations and rotation angles. | ||
834 | 5 | Simply use the function that Qt provides for that. | ||
835 | 6 | Index: orientationAngleMapping/input-context/minputcontext.cpp | ||
836 | 7 | =================================================================== | ||
837 | 8 | --- orientationAngleMapping.orig/input-context/minputcontext.cpp 2014-01-31 15:40:11.336846000 -0200 | ||
838 | 9 | +++ orientationAngleMapping/input-context/minputcontext.cpp 2014-01-31 15:41:15.171087065 -0200 | ||
839 | 10 | @@ -24,6 +24,7 @@ | ||
840 | 11 | #include <QDebug> | ||
841 | 12 | #include <QByteArray> | ||
842 | 13 | #include <QRectF> | ||
843 | 14 | +#include <QScreen> | ||
844 | 15 | #include <QLocale> | ||
845 | 16 | #include <QWindow> | ||
846 | 17 | #include <QSharedDataPointer> | ||
847 | 18 | @@ -36,18 +37,8 @@ | ||
848 | 19 | |||
849 | 20 | int orientationAngle(Qt::ScreenOrientation orientation) | ||
850 | 21 | { | ||
851 | 22 | - switch (orientation) { | ||
852 | 23 | - case Qt::PrimaryOrientation: // Urgh. | ||
853 | 24 | - case Qt::PortraitOrientation: | ||
854 | 25 | - return MInputContext::Angle270; | ||
855 | 26 | - case Qt::LandscapeOrientation: | ||
856 | 27 | - return MInputContext::Angle0; | ||
857 | 28 | - case Qt::InvertedPortraitOrientation: | ||
858 | 29 | - return MInputContext::Angle90; | ||
859 | 30 | - case Qt::InvertedLandscapeOrientation: | ||
860 | 31 | - return MInputContext::Angle180; | ||
861 | 32 | - } | ||
862 | 33 | - return MInputContext::Angle0; | ||
863 | 34 | + QScreen *screen = qGuiApp->primaryScreen(); | ||
864 | 35 | + return screen->angleBetween(screen->primaryOrientation(), orientation); | ||
865 | 36 | } | ||
866 | 37 | } | ||
867 | 38 | |||
868 | 0 | 39 | ||
869 | === modified file 'debian/patches/series' | |||
870 | --- debian/patches/series 2013-07-23 19:47:04 +0000 | |||
871 | +++ debian/patches/series 2014-01-31 18:02:44 +0000 | |||
872 | @@ -3,3 +3,4 @@ | |||
873 | 3 | 0003-prediction.patch | 3 | 0003-prediction.patch |
874 | 4 | 0004-fix_activationlostevent.patch | 4 | 0004-fix_activationlostevent.patch |
875 | 5 | 0005-testability.patch | 5 | 0005-testability.patch |
876 | 6 | 0006-fix_orientation_to_angle_mapping.patch | ||
877 | 6 | 7 | ||
878 | === modified file 'input-context/minputcontext.cpp' | |||
879 | --- input-context/minputcontext.cpp 2013-07-23 19:47:04 +0000 | |||
880 | +++ input-context/minputcontext.cpp 2014-01-31 18:02:44 +0000 | |||
881 | @@ -24,6 +24,7 @@ | |||
882 | 24 | #include <QDebug> | 24 | #include <QDebug> |
883 | 25 | #include <QByteArray> | 25 | #include <QByteArray> |
884 | 26 | #include <QRectF> | 26 | #include <QRectF> |
885 | 27 | #include <QScreen> | ||
886 | 27 | #include <QLocale> | 28 | #include <QLocale> |
887 | 28 | #include <QWindow> | 29 | #include <QWindow> |
888 | 29 | #include <QSharedDataPointer> | 30 | #include <QSharedDataPointer> |
889 | @@ -36,18 +37,8 @@ | |||
890 | 36 | 37 | ||
891 | 37 | int orientationAngle(Qt::ScreenOrientation orientation) | 38 | int orientationAngle(Qt::ScreenOrientation orientation) |
892 | 38 | { | 39 | { |
905 | 39 | switch (orientation) { | 40 | QScreen *screen = qGuiApp->primaryScreen(); |
906 | 40 | case Qt::PrimaryOrientation: // Urgh. | 41 | return screen->angleBetween(screen->primaryOrientation(), orientation); |
895 | 41 | case Qt::PortraitOrientation: | ||
896 | 42 | return MInputContext::Angle270; | ||
897 | 43 | case Qt::LandscapeOrientation: | ||
898 | 44 | return MInputContext::Angle0; | ||
899 | 45 | case Qt::InvertedPortraitOrientation: | ||
900 | 46 | return MInputContext::Angle90; | ||
901 | 47 | case Qt::InvertedLandscapeOrientation: | ||
902 | 48 | return MInputContext::Angle180; | ||
903 | 49 | } | ||
904 | 50 | return MInputContext::Angle0; | ||
907 | 51 | } | 42 | } |
908 | 52 | } | 43 | } |
909 | 53 | 44 |
tested with https:/ /code.launchpad .net/~dandrader /ubuntu- keyboard/ fixAngleToOrien tationMap/ +merge/ 204293 and worked as expected on tablet and N4
Did you perform an exploratory manual test run of the code change and any related functionality on device or emulator?
YES
Did you successfully run all tests found in your component's Test Plan /wiki.ubuntu. com/Process/ Merges/ TestPlan/<package-name>) on device or emulator?
(https:/
YES
Did CI run pass? If not, please explain why.
YES
Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?
YES