Merge lp:~osomon/webbrowser-app/qquickshortcuts into lp:webbrowser-app
- qquickshortcuts
- Merge into trunk
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Olivier Tilloy | ||||||||||||
Approved revision: | 1391 | ||||||||||||
Merged at revision: | 1407 | ||||||||||||
Proposed branch: | lp:~osomon/webbrowser-app/qquickshortcuts | ||||||||||||
Merge into: | lp:webbrowser-app | ||||||||||||
Diff against target: |
1198 lines (+666/-337) 12 files modified
src/app/CMakeLists.txt (+3/-1) src/app/FilteredKeyboardModel.qml (+33/-0) src/app/browserapplication.cpp (+2/-0) src/app/qquickshortcut.cpp (+283/-0) src/app/qquickshortcut_p.h (+109/-0) src/app/webbrowser/Browser.qml (+200/-258) src/app/webbrowser/KeyboardShortcut.qml (+0/-25) src/app/webbrowser/KeyboardShortcuts.qml (+0/-41) src/app/webbrowser/ListViewHighlight.qml (+2/-3) src/app/webbrowser/NavigationBar.qml (+10/-7) tests/autopilot/webbrowser_app/tests/test_keyboard.py (+22/-1) tests/autopilot/webbrowser_app/tests/test_private.py (+2/-1) |
||||||||||||
To merge this branch: | bzr merge lp:~osomon/webbrowser-app/qquickshortcuts | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
system-apps-ci-bot | continuous-integration | Needs Fixing | |
PS Jenkins bot | continuous-integration | Needs Fixing | |
Review via email: mp+290299@code.launchpad.net |
Commit message
Import QQuickShortcut from Qt 5.5 to properly handle window-level keyboard shortcuts.
We cannot bump the dependency on Qt to 5.5 as the stable overlay PPA for devices currently has Qt 5.4.1.
Description of the change
- 1389. By Olivier Tilloy
-
Remove an incorrect condition now that the QInputInfo API is available.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1390. By Olivier Tilloy
-
Fix failing autopilot test.
- 1391. By Olivier Tilloy
-
Filter out autopilot-emulated keyboards.
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:1391
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 1392. By Olivier Tilloy
-
Do not change focus unnecessarily when switching tabs: clear the address bar instead if needed.
Preview Diff
1 | === modified file 'src/app/CMakeLists.txt' |
2 | --- src/app/CMakeLists.txt 2016-02-09 21:19:41 +0000 |
3 | +++ src/app/CMakeLists.txt 2016-04-08 16:47:47 +0000 |
4 | @@ -27,13 +27,15 @@ |
5 | session-storage.cpp |
6 | single-instance-manager.cpp |
7 | webbrowser-window.cpp |
8 | + qquickshortcut.cpp |
9 | ) |
10 | |
11 | add_library(${COMMONLIB} STATIC ${COMMONLIB_SRC}) |
12 | |
13 | include_directories(${unity8_SOURCE_DIR}/libs/UbuntuGestures |
14 | ${unity8_SOURCE_DIR}/plugins |
15 | - ${LIBAPPARMOR_INCLUDE_DIRS}) |
16 | + ${LIBAPPARMOR_INCLUDE_DIRS} |
17 | + ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) |
18 | target_link_libraries(${COMMONLIB} |
19 | Qt5::Core |
20 | Qt5::Gui |
21 | |
22 | === added file 'src/app/FilteredKeyboardModel.qml' |
23 | --- src/app/FilteredKeyboardModel.qml 1970-01-01 00:00:00 +0000 |
24 | +++ src/app/FilteredKeyboardModel.qml 2016-04-08 16:47:47 +0000 |
25 | @@ -0,0 +1,33 @@ |
26 | +/* |
27 | + * Copyright 2016 Canonical Ltd. |
28 | + * |
29 | + * This file is part of webbrowser-app. |
30 | + * |
31 | + * webbrowser-app is free software; you can redistribute it and/or modify |
32 | + * it under the terms of the GNU General Public License as published by |
33 | + * the Free Software Foundation; version 3. |
34 | + * |
35 | + * webbrowser-app is distributed in the hope that it will be useful, |
36 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
37 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
38 | + * GNU General Public License for more details. |
39 | + * |
40 | + * You should have received a copy of the GNU General Public License |
41 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
42 | + */ |
43 | + |
44 | +import QtQuick 2.4 |
45 | +import Ubuntu.Components 1.3 |
46 | +import Unity.InputInfo 0.1 |
47 | + |
48 | +SortFilterModel { |
49 | + model: InputDeviceModel { |
50 | + deviceFilter: InputInfo.Keyboard |
51 | + } |
52 | + filter { |
53 | + // Filter out autopilot-emulated keyboards |
54 | + // (see https://launchpad.net/bugs/1542224). |
55 | + property: "name" |
56 | + pattern: /^(?!py-evdev-uinput).*$/ |
57 | + } |
58 | +} |
59 | |
60 | === modified file 'src/app/browserapplication.cpp' |
61 | --- src/app/browserapplication.cpp 2016-02-09 22:03:25 +0000 |
62 | +++ src/app/browserapplication.cpp 2016-04-08 16:47:47 +0000 |
63 | @@ -38,6 +38,7 @@ |
64 | #include "favicon-fetcher.h" |
65 | #include "meminfo.h" |
66 | #include "mime-database.h" |
67 | +#include "qquickshortcut_p.h" |
68 | #include "session-storage.h" |
69 | #include "webbrowser-window.h" |
70 | |
71 | @@ -179,6 +180,7 @@ |
72 | qmlRegisterSingletonType<MemInfo>(uri, 0, 1, "MemInfo", MemInfo_singleton_factory); |
73 | qmlRegisterSingletonType<MimeDatabase>(uri, 0, 1, "MimeDatabase", MimeDatabase_singleton_factory); |
74 | qmlRegisterType<SessionStorage>(uri, 0, 1, "SessionStorage"); |
75 | + qmlRegisterType<QQuickShortcut>(uri, 0, 1, "Shortcut"); |
76 | |
77 | const char* gesturesUri = "Ubuntu.Gestures"; |
78 | qmlRegisterSingletonType<Direction>(gesturesUri, 0, 1, "Direction", Direction_singleton_factory); |
79 | |
80 | === added file 'src/app/qquickshortcut.cpp' |
81 | --- src/app/qquickshortcut.cpp 1970-01-01 00:00:00 +0000 |
82 | +++ src/app/qquickshortcut.cpp 2016-04-08 16:47:47 +0000 |
83 | @@ -0,0 +1,283 @@ |
84 | +/**************************************************************************** |
85 | +** |
86 | +** Copyright (C) 2015 The Qt Company Ltd. |
87 | +** Contact: http://www.qt.io/licensing/ |
88 | +** |
89 | +** This file is part of the QtQuick module of the Qt Toolkit. |
90 | +** |
91 | +** $QT_BEGIN_LICENSE:LGPL21$ |
92 | +** Commercial License Usage |
93 | +** Licensees holding valid commercial Qt licenses may use this file in |
94 | +** accordance with the commercial license agreement provided with the |
95 | +** Software or, alternatively, in accordance with the terms contained in |
96 | +** a written agreement between you and The Qt Company. For licensing terms |
97 | +** and conditions see http://www.qt.io/terms-conditions. For further |
98 | +** information use the contact form at http://www.qt.io/contact-us. |
99 | +** |
100 | +** GNU Lesser General Public License Usage |
101 | +** Alternatively, this file may be used under the terms of the GNU Lesser |
102 | +** General Public License version 2.1 or version 3 as published by the Free |
103 | +** Software Foundation and appearing in the file LICENSE.LGPLv21 and |
104 | +** LICENSE.LGPLv3 included in the packaging of this file. Please review the |
105 | +** following information to ensure the GNU Lesser General Public License |
106 | +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and |
107 | +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
108 | +** |
109 | +** As a special exception, The Qt Company gives you certain additional |
110 | +** rights. These rights are described in The Qt Company LGPL Exception |
111 | +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
112 | +** |
113 | +** $QT_END_LICENSE$ |
114 | +** |
115 | +****************************************************************************/ |
116 | + |
117 | +#include "qquickshortcut_p.h" |
118 | + |
119 | +#include <QtQuick/qquickitem.h> |
120 | +#include <QtQuick/qquickwindow.h> |
121 | +#include <QtGui/private/qguiapplication_p.h> |
122 | + |
123 | +QT_BEGIN_NAMESPACE |
124 | + |
125 | +/*! |
126 | + \qmltype Shortcut |
127 | + \instantiates QQuickShortcut |
128 | + \inqmlmodule QtQuick |
129 | + \since 5.5 |
130 | + \ingroup qtquick-input |
131 | + \brief Provides keyboard shortcuts |
132 | + |
133 | + The Shortcut type provides a way of handling keyboard shortcuts. The shortcut can |
134 | + be set to one of the \l{QKeySequence::StandardKey}{standard keyboard shortcuts}, |
135 | + or it can be described with a string containing a sequence of up to four key |
136 | + presses that are needed to \l{Shortcut::activated}{activate} the shortcut. |
137 | + |
138 | + \qml |
139 | + Item { |
140 | + id: view |
141 | + |
142 | + property int currentIndex |
143 | + |
144 | + Shortcut { |
145 | + sequence: StandardKey.NextChild |
146 | + onActivated: view.currentIndex++ |
147 | + } |
148 | + } |
149 | + \endqml |
150 | + |
151 | + \sa Keys |
152 | +*/ |
153 | + |
154 | +/*! \qmlsignal QtQuick::Shortcut::activated() |
155 | + |
156 | + This signal is emitted when the shortcut is activated. |
157 | + |
158 | + The corresponding handler is \c onActivated. |
159 | +*/ |
160 | + |
161 | +/*! \qmlsignal QtQuick::Shortcut::activatedAmbiguously() |
162 | + |
163 | + This signal is emitted when the shortcut is activated ambigously, |
164 | + meaning that it matches the start of more than one shortcut. |
165 | + |
166 | + The corresponding handler is \c onActivatedAmbiguously. |
167 | +*/ |
168 | + |
169 | +QQuickShortcut::QQuickShortcut(QObject *parent) : QObject(parent), m_id(0), |
170 | + m_enabled(true), m_completed(false), m_autorepeat(true), m_context(Qt::WindowShortcut) |
171 | +{ |
172 | +} |
173 | + |
174 | +QQuickShortcut::~QQuickShortcut() |
175 | +{ |
176 | + ungrabShortcut(); |
177 | +} |
178 | + |
179 | +/*! |
180 | + \qmlproperty keysequence QtQuick::Shortcut::sequence |
181 | + |
182 | + This property holds the shortcut's key sequence. The key sequence can be set |
183 | + to one of the \l{QKeySequence::StandardKey}{standard keyboard shortcuts}, or |
184 | + it can be described with a string containing a sequence of up to four key |
185 | + presses that are needed to \l{Shortcut::activated}{activate} the shortcut. |
186 | + |
187 | + The default value is an empty key sequence. |
188 | + |
189 | + \qml |
190 | + Shortcut { |
191 | + sequence: "Ctrl+E,Ctrl+W" |
192 | + onActivated: edit.wrapMode = TextEdit.Wrap |
193 | + } |
194 | + \endqml |
195 | +*/ |
196 | +QVariant QQuickShortcut::sequence() const |
197 | +{ |
198 | + return m_sequence; |
199 | +} |
200 | + |
201 | +void QQuickShortcut::setSequence(const QVariant &sequence) |
202 | +{ |
203 | + if (sequence == m_sequence) |
204 | + return; |
205 | + |
206 | + QKeySequence shortcut; |
207 | + if (sequence.type() == QVariant::Int) |
208 | + shortcut = QKeySequence(static_cast<QKeySequence::StandardKey>(sequence.toInt())); |
209 | + else |
210 | + shortcut = QKeySequence::fromString(sequence.toString()); |
211 | + |
212 | + grabShortcut(shortcut, m_context); |
213 | + |
214 | + m_sequence = sequence; |
215 | + m_shortcut = shortcut; |
216 | + emit sequenceChanged(); |
217 | +} |
218 | + |
219 | +/*! |
220 | + \qmlproperty bool QtQuick::Shortcut::enabled |
221 | + |
222 | + This property holds whether the shortcut is enabled. |
223 | + |
224 | + The default value is \c true. |
225 | +*/ |
226 | +bool QQuickShortcut::isEnabled() const |
227 | +{ |
228 | + return m_enabled; |
229 | +} |
230 | + |
231 | +void QQuickShortcut::setEnabled(bool enabled) |
232 | +{ |
233 | + if (enabled == m_enabled) |
234 | + return; |
235 | + |
236 | + if (m_id) |
237 | + QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enabled, m_id, this); |
238 | + |
239 | + m_enabled = enabled; |
240 | + emit enabledChanged(); |
241 | +} |
242 | + |
243 | +/*! |
244 | + \qmlproperty bool QtQuick::Shortcut::autoRepeat |
245 | + |
246 | + This property holds whether the shortcut can auto repeat. |
247 | + |
248 | + The default value is \c true. |
249 | +*/ |
250 | +bool QQuickShortcut::autoRepeat() const |
251 | +{ |
252 | + return m_autorepeat; |
253 | +} |
254 | + |
255 | +void QQuickShortcut::setAutoRepeat(bool repeat) |
256 | +{ |
257 | + if (repeat == m_autorepeat) |
258 | + return; |
259 | + |
260 | + if (m_id) |
261 | + QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(repeat, m_id, this); |
262 | + |
263 | + m_autorepeat = repeat; |
264 | + emit autoRepeatChanged(); |
265 | +} |
266 | + |
267 | +/*! |
268 | + \qmlproperty enumeration QtQuick::Shortcut::context |
269 | + |
270 | + This property holds the \l{Qt::ShortcutContext}{shortcut context}. |
271 | + |
272 | + Supported values are: |
273 | + \list |
274 | + \li \c Qt.WindowShortcut (default) - The shortcut is active when its parent item is in an active top-level window. |
275 | + \li \c Qt.ApplicationShortcut - The shortcut is active when one of the application's windows are active. |
276 | + \endlist |
277 | + |
278 | + \qml |
279 | + Shortcut { |
280 | + sequence: StandardKey.Quit |
281 | + context: Qt.ApplicationShortcut |
282 | + onActivated: Qt.quit() |
283 | + } |
284 | + \endqml |
285 | +*/ |
286 | +Qt::ShortcutContext QQuickShortcut::context() const |
287 | +{ |
288 | + return m_context; |
289 | +} |
290 | + |
291 | +void QQuickShortcut::setContext(Qt::ShortcutContext context) |
292 | +{ |
293 | + if (context == m_context) |
294 | + return; |
295 | + |
296 | + grabShortcut(m_shortcut, context); |
297 | + |
298 | + m_context = context; |
299 | + emit contextChanged(); |
300 | +} |
301 | + |
302 | +void QQuickShortcut::classBegin() |
303 | +{ |
304 | +} |
305 | + |
306 | +void QQuickShortcut::componentComplete() |
307 | +{ |
308 | + m_completed = true; |
309 | + grabShortcut(m_shortcut, m_context); |
310 | +} |
311 | + |
312 | +bool QQuickShortcut::event(QEvent *event) |
313 | +{ |
314 | + if (m_enabled && event->type() == QEvent::Shortcut) { |
315 | + QShortcutEvent *se = static_cast<QShortcutEvent *>(event); |
316 | + if (se->shortcutId() == m_id && se->key() == m_shortcut){ |
317 | + if (se->isAmbiguous()) |
318 | + emit activatedAmbiguously(); |
319 | + else |
320 | + emit activated(); |
321 | + return true; |
322 | + } |
323 | + } |
324 | + return false; |
325 | +} |
326 | + |
327 | +static bool qQuickShortcutContextMatcher(QObject *obj, Qt::ShortcutContext context) |
328 | +{ |
329 | + switch (context) { |
330 | + case Qt::ApplicationShortcut: |
331 | + return true; |
332 | + case Qt::WindowShortcut: |
333 | + while (obj && !obj->isWindowType()) { |
334 | + obj = obj->parent(); |
335 | + if (QQuickItem *item = qobject_cast<QQuickItem *>(obj)) |
336 | + obj = item->window(); |
337 | + } |
338 | + return obj && obj == QGuiApplication::focusWindow(); |
339 | + default: |
340 | + return false; |
341 | + } |
342 | +} |
343 | + |
344 | +void QQuickShortcut::grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context) |
345 | +{ |
346 | + ungrabShortcut(); |
347 | + |
348 | + if (m_completed && !sequence.isEmpty()) { |
349 | + QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance(); |
350 | + m_id = pApp->shortcutMap.addShortcut(this, sequence, context, qQuickShortcutContextMatcher); |
351 | + if (!m_enabled) |
352 | + pApp->shortcutMap.setShortcutEnabled(false, m_id, this); |
353 | + if (!m_autorepeat) |
354 | + pApp->shortcutMap.setShortcutAutoRepeat(false, m_id, this); |
355 | + } |
356 | +} |
357 | + |
358 | +void QQuickShortcut::ungrabShortcut() |
359 | +{ |
360 | + if (m_id) { |
361 | + QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_id, this); |
362 | + m_id = 0; |
363 | + } |
364 | +} |
365 | + |
366 | +QT_END_NAMESPACE |
367 | |
368 | === added file 'src/app/qquickshortcut_p.h' |
369 | --- src/app/qquickshortcut_p.h 1970-01-01 00:00:00 +0000 |
370 | +++ src/app/qquickshortcut_p.h 2016-04-08 16:47:47 +0000 |
371 | @@ -0,0 +1,109 @@ |
372 | +/**************************************************************************** |
373 | +** |
374 | +** Copyright (C) 2015 The Qt Company Ltd. |
375 | +** Contact: http://www.qt.io/licensing/ |
376 | +** |
377 | +** This file is part of the QtQuick module of the Qt Toolkit. |
378 | +** |
379 | +** $QT_BEGIN_LICENSE:LGPL21$ |
380 | +** Commercial License Usage |
381 | +** Licensees holding valid commercial Qt licenses may use this file in |
382 | +** accordance with the commercial license agreement provided with the |
383 | +** Software or, alternatively, in accordance with the terms contained in |
384 | +** a written agreement between you and The Qt Company. For licensing terms |
385 | +** and conditions see http://www.qt.io/terms-conditions. For further |
386 | +** information use the contact form at http://www.qt.io/contact-us. |
387 | +** |
388 | +** GNU Lesser General Public License Usage |
389 | +** Alternatively, this file may be used under the terms of the GNU Lesser |
390 | +** General Public License version 2.1 or version 3 as published by the Free |
391 | +** Software Foundation and appearing in the file LICENSE.LGPLv21 and |
392 | +** LICENSE.LGPLv3 included in the packaging of this file. Please review the |
393 | +** following information to ensure the GNU Lesser General Public License |
394 | +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and |
395 | +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
396 | +** |
397 | +** As a special exception, The Qt Company gives you certain additional |
398 | +** rights. These rights are described in The Qt Company LGPL Exception |
399 | +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
400 | +** |
401 | +** $QT_END_LICENSE$ |
402 | +** |
403 | +****************************************************************************/ |
404 | + |
405 | +#ifndef QQUICKSHORTCUT_P_H |
406 | +#define QQUICKSHORTCUT_P_H |
407 | + |
408 | +// |
409 | +// W A R N I N G |
410 | +// ------------- |
411 | +// |
412 | +// This file is not part of the Qt API. It exists purely as an |
413 | +// implementation detail. This header file may change from version to |
414 | +// version without notice, or even be removed. |
415 | +// |
416 | +// We mean it. |
417 | +// |
418 | + |
419 | +#include <QtCore/qobject.h> |
420 | +#include <QtCore/qvariant.h> |
421 | +#include <QtGui/qkeysequence.h> |
422 | +#include <QtQml/qqmlparserstatus.h> |
423 | + |
424 | +QT_BEGIN_NAMESPACE |
425 | + |
426 | +class QQuickShortcut : public QObject, public QQmlParserStatus |
427 | +{ |
428 | + Q_OBJECT |
429 | + Q_INTERFACES(QQmlParserStatus) |
430 | + Q_PROPERTY(QVariant sequence READ sequence WRITE setSequence NOTIFY sequenceChanged FINAL) |
431 | + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL) |
432 | + Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL) |
433 | + Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext NOTIFY contextChanged FINAL) |
434 | + |
435 | +public: |
436 | + explicit QQuickShortcut(QObject *parent = Q_NULLPTR); |
437 | + ~QQuickShortcut(); |
438 | + |
439 | + QVariant sequence() const; |
440 | + void setSequence(const QVariant &sequence); |
441 | + |
442 | + bool isEnabled() const; |
443 | + void setEnabled(bool enabled); |
444 | + |
445 | + bool autoRepeat() const; |
446 | + void setAutoRepeat(bool repeat); |
447 | + |
448 | + Qt::ShortcutContext context() const; |
449 | + void setContext(Qt::ShortcutContext context); |
450 | + |
451 | +Q_SIGNALS: |
452 | + void sequenceChanged(); |
453 | + void enabledChanged(); |
454 | + void autoRepeatChanged(); |
455 | + void contextChanged(); |
456 | + |
457 | + void activated(); |
458 | + void activatedAmbiguously(); |
459 | + |
460 | +protected: |
461 | + void classBegin() Q_DECL_OVERRIDE; |
462 | + void componentComplete() Q_DECL_OVERRIDE; |
463 | + bool event(QEvent *event) Q_DECL_OVERRIDE; |
464 | + |
465 | + void grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context); |
466 | + void ungrabShortcut(); |
467 | + |
468 | +private: |
469 | + int m_id; |
470 | + bool m_enabled; |
471 | + bool m_completed; |
472 | + bool m_autorepeat; |
473 | + QKeySequence m_shortcut; |
474 | + Qt::ShortcutContext m_context; |
475 | + QVariant m_sequence; |
476 | +}; |
477 | + |
478 | +QT_END_NAMESPACE |
479 | + |
480 | +#endif // QQUICKSHORTCUT_P_H |
481 | |
482 | === modified file 'src/app/webbrowser/Browser.qml' |
483 | --- src/app/webbrowser/Browser.qml 2016-03-07 18:44:34 +0000 |
484 | +++ src/app/webbrowser/Browser.qml 2016-04-08 16:47:47 +0000 |
485 | @@ -63,21 +63,6 @@ |
486 | } |
487 | |
488 | Connections { |
489 | - target: tabsModel |
490 | - onCurrentIndexChanged: { |
491 | - // Remove focus from the address bar when the current tab |
492 | - // changes to ensure that its contents are updated. |
493 | - contentsContainer.forceActiveFocus() |
494 | - |
495 | - // In narrow mode, the tabslist is a stack: |
496 | - // the current tab is always at the top. |
497 | - if (!browser.wide) { |
498 | - tabsModel.move(tabsModel.currentIndex, 0) |
499 | - } |
500 | - } |
501 | - } |
502 | - |
503 | - Connections { |
504 | target: currentWebview |
505 | |
506 | /* Note that we are connecting the mediaAccessPermissionRequested signal |
507 | @@ -111,6 +96,10 @@ |
508 | deviceFilter: InputInfo.TouchScreen |
509 | } |
510 | |
511 | + FilteredKeyboardModel { |
512 | + id: keyboardModel |
513 | + } |
514 | + |
515 | Component { |
516 | id: mediaAccessDialogComponent |
517 | MediaAccessDialog { } |
518 | @@ -1425,21 +1414,12 @@ |
519 | Component { |
520 | id: bookmarkOptionsComponent |
521 | BookmarkOptions { |
522 | - id: bookmarkOptions |
523 | folderModel: BookmarksFolderListModel { |
524 | sourceModel: BookmarksModel |
525 | } |
526 | |
527 | - Component.onCompleted: { |
528 | - forceActiveFocus() |
529 | - } |
530 | + Component.onCompleted: forceActiveFocus() |
531 | |
532 | - // Fragile workaround for https://launchpad.net/bugs/1546677. |
533 | - // By destroying the popover, its visibility isn’t changed to |
534 | - // false, and thus the bookmark is not removed. |
535 | - function closeAndConfirm() { |
536 | - destroy() |
537 | - } |
538 | onVisibleChanged: { |
539 | if (!visible) { |
540 | BookmarksModel.remove(bookmarkUrl) |
541 | @@ -1452,28 +1432,11 @@ |
542 | } |
543 | } |
544 | |
545 | - Keys.onPressed: { |
546 | - if (bookmarkOptionsShortcuts.processKey(event.key, event.modifiers)) { |
547 | - event.accepted = true |
548 | - } |
549 | - } |
550 | - |
551 | - KeyboardShortcuts { |
552 | - id: bookmarkOptionsShortcuts |
553 | - KeyboardShortcut { |
554 | - key: Qt.Key_Return |
555 | - onTriggered: closeAndConfirm() |
556 | - } |
557 | - |
558 | - KeyboardShortcut { |
559 | - modifiers: Qt.ControlModifier |
560 | - key: Qt.Key_D |
561 | - onTriggered: { |
562 | - BookmarksModel.remove(bookmarkUrl) |
563 | - closeAndConfirm() |
564 | - } |
565 | - } |
566 | - } |
567 | + // Fragile workaround for https://launchpad.net/bugs/1546677. |
568 | + // By destroying the popover, its visibility isn’t changed to |
569 | + // false, and thus the bookmark is not removed. |
570 | + Keys.onEnterPressed: destroy() |
571 | + Keys.onReturnPressed: destroy() |
572 | } |
573 | } |
574 | |
575 | @@ -1627,16 +1590,7 @@ |
576 | } |
577 | |
578 | function maybeFocusAddressBar() { |
579 | - // XXX: this is not the right condition, but it is better than |
580 | - // inferring a "desktop" form factor from various heuristics. |
581 | - // The real fix is to detect whether there is a physical keyboard |
582 | - // connected, for which there is currently no API yet (there will |
583 | - // be a QInputInfo API in a future version of Qt). |
584 | - // Wide mode might be in use on a device without a physical |
585 | - // keyboard (e.g. a 10" tablet), and conversely the browser window |
586 | - // might be shrinked to a narrow layout on a desktop setup with a |
587 | - // physical keyboard and no OSK. |
588 | - if (browser.wide) { |
589 | + if (keyboardModel.count > 0) { |
590 | focusAddressBar() |
591 | } else { |
592 | contentsContainer.forceActiveFocus() |
593 | @@ -1682,14 +1636,14 @@ |
594 | } |
595 | } |
596 | |
597 | + property var currentBookmarkOptionsDialog: null |
598 | function addBookmark(url, title, icon, location) { |
599 | if (title == "") title = UrlUtils.removeScheme(url) |
600 | BookmarksModel.add(url, title, icon, "") |
601 | if (location === undefined) location = chrome.bookmarkTogglePlaceHolder |
602 | - PopupUtils.open(bookmarkOptionsComponent, |
603 | - location, |
604 | - {"bookmarkUrl": url, |
605 | - "bookmarkTitle": title}) |
606 | + var properties = {"bookmarkUrl": url, "bookmarkTitle": title} |
607 | + currentBookmarkOptionsDialog = PopupUtils.open(bookmarkOptionsComponent, |
608 | + location, properties) |
609 | } |
610 | } |
611 | |
612 | @@ -1926,6 +1880,13 @@ |
613 | |
614 | Connections { |
615 | target: tabsModel |
616 | + onCurrentIndexChanged: { |
617 | + // In narrow mode, the tabslist is a stack: |
618 | + // the current tab is always at the top. |
619 | + if (!browser.wide) { |
620 | + tabsModel.move(tabsModel.currentIndex, 0) |
621 | + } |
622 | + } |
623 | onCurrentTabChanged: { |
624 | chrome.findInPageMode = false |
625 | var tab = tabsModel.currentTab |
626 | @@ -1972,206 +1933,187 @@ |
627 | } |
628 | } |
629 | |
630 | - Keys.onPressed: if (shortcuts.processKey(event.key, event.modifiers)) event.accepted = true |
631 | - KeyboardShortcuts { |
632 | - id: shortcuts |
633 | - |
634 | - // Ctrl+Tab or Ctrl+PageDown: cycle through open tabs |
635 | - KeyboardShortcut { |
636 | - modifiers: Qt.ControlModifier |
637 | - key: Qt.Key_Tab |
638 | - enabled: tabContainer.visible || recentView.visible |
639 | - onTriggered: internal.switchToNextTab() |
640 | - } |
641 | - KeyboardShortcut { |
642 | - modifiers: Qt.ControlModifier |
643 | - key: Qt.Key_PageDown |
644 | - enabled: tabContainer.visible || recentView.visible |
645 | - onTriggered: internal.switchToNextTab() |
646 | - } |
647 | - |
648 | - // Ctrl+Shift+Tab or Ctrl+PageUp: cycle through open tabs in reverse order |
649 | - KeyboardShortcut { |
650 | - modifiers: Qt.ControlModifier |
651 | - key: Qt.Key_Backtab |
652 | - enabled: tabContainer.visible || recentView.visible |
653 | - onTriggered: internal.switchToPreviousTab() |
654 | - } |
655 | - KeyboardShortcut { |
656 | - modifiers: Qt.ControlModifier |
657 | - key: Qt.Key_PageUp |
658 | - enabled: tabContainer.visible || recentView.visible |
659 | - onTriggered: internal.switchToPreviousTab() |
660 | - } |
661 | - |
662 | - // Ctrl+Shift+W or Ctrl+Shift+T: Undo close tab |
663 | - KeyboardShortcut { |
664 | - modifiers: Qt.ControlModifier | Qt.ShiftModifier |
665 | - key: Qt.Key_W |
666 | - enabled: tabContainer.visible || recentView.visible |
667 | - onTriggered: internal.undoCloseTab() |
668 | - } |
669 | - |
670 | - KeyboardShortcut { |
671 | - modifiers: Qt.ControlModifier | Qt.ShiftModifier |
672 | - key: Qt.Key_T |
673 | - enabled: tabContainer.visible || recentView.visible |
674 | - onTriggered: internal.undoCloseTab() |
675 | - } |
676 | - |
677 | - // Ctrl+W or Ctrl+F4: Close the current tab |
678 | - KeyboardShortcut { |
679 | - modifiers: Qt.ControlModifier |
680 | - key: Qt.Key_W |
681 | - enabled: tabContainer.visible || recentView.visible |
682 | - onTriggered: internal.closeCurrentTab() |
683 | - } |
684 | - KeyboardShortcut { |
685 | - modifiers: Qt.ControlModifier |
686 | - key: Qt.Key_F4 |
687 | - enabled: tabContainer.visible || recentView.visible |
688 | - onTriggered: internal.closeCurrentTab() |
689 | - } |
690 | - |
691 | - // Ctrl+T: Open a new Tab |
692 | - KeyboardShortcut { |
693 | - modifiers: Qt.ControlModifier |
694 | - key: Qt.Key_T |
695 | - enabled: tabContainer.visible || recentView.visible || |
696 | - bookmarksViewLoader.active || historyViewLoader.active |
697 | - onTriggered: { |
698 | - openUrlInNewTab("", true) |
699 | - if (recentView.visible) recentView.reset() |
700 | - bookmarksViewLoader.active = false |
701 | - historyViewLoader.active = false |
702 | - } |
703 | - } |
704 | - |
705 | - // F6 or Ctrl+L or Alt+D: Select the content in the address bar |
706 | - KeyboardShortcut { |
707 | - modifiers: Qt.ControlModifier |
708 | - key: Qt.Key_L |
709 | - enabled: tabContainer.visible |
710 | - onTriggered: internal.focusAddressBar(true) |
711 | - } |
712 | - KeyboardShortcut { |
713 | - modifiers: Qt.AltModifier |
714 | - key: Qt.Key_D |
715 | - enabled: tabContainer.visible |
716 | - onTriggered: internal.focusAddressBar(true) |
717 | - } |
718 | - KeyboardShortcut { |
719 | - key: Qt.Key_F6 |
720 | - enabled: tabContainer.visible |
721 | - onTriggered: internal.focusAddressBar(true) |
722 | - } |
723 | - |
724 | - // Ctrl+D: Toggle bookmarked state on current Tab |
725 | - KeyboardShortcut { |
726 | - modifiers: Qt.ControlModifier |
727 | - key: Qt.Key_D |
728 | - enabled: tabContainer.visible |
729 | - onTriggered: { |
730 | - if (currentWebview) { |
731 | - if (BookmarksModel.contains(currentWebview.url)) { |
732 | - BookmarksModel.remove(currentWebview.url) |
733 | - } else { |
734 | - internal.addBookmark(currentWebview.url, currentWebview.title, currentWebview.icon) |
735 | - } |
736 | + // TODO: internationalize non-standard key sequences? |
737 | + |
738 | + // Ctrl+Tab or Ctrl+PageDown: cycle through open tabs |
739 | + Shortcut { |
740 | + sequence: StandardKey.NextChild |
741 | + enabled: tabContainer.visible || recentView.visible |
742 | + onActivated: internal.switchToNextTab() |
743 | + } |
744 | + Shortcut { |
745 | + sequence: "Ctrl+PgDown" |
746 | + enabled: tabContainer.visible || recentView.visible |
747 | + onActivated: internal.switchToNextTab() |
748 | + } |
749 | + |
750 | + // Ctrl+Shift+Tab or Ctrl+PageUp: cycle through open tabs in reverse order |
751 | + Shortcut { |
752 | + sequence: StandardKey.PreviousChild |
753 | + enabled: tabContainer.visible || recentView.visible |
754 | + onActivated: internal.switchToPreviousTab() |
755 | + } |
756 | + Shortcut { |
757 | + sequence: "Ctrl+Shift+Tab" |
758 | + enabled: tabContainer.visible || recentView.visible |
759 | + onActivated: internal.switchToPreviousTab() |
760 | + } |
761 | + Shortcut { |
762 | + sequence: "Ctrl+PgUp" |
763 | + enabled: tabContainer.visible || recentView.visible |
764 | + onActivated: internal.switchToPreviousTab() |
765 | + } |
766 | + |
767 | + // Ctrl+W or Ctrl+F4: Close the current tab |
768 | + Shortcut { |
769 | + sequence: StandardKey.Close |
770 | + enabled: tabContainer.visible || recentView.visible |
771 | + onActivated: internal.closeCurrentTab() |
772 | + } |
773 | + Shortcut { |
774 | + sequence: "Ctrl+F4" |
775 | + enabled: tabContainer.visible || recentView.visible |
776 | + onActivated: internal.closeCurrentTab() |
777 | + } |
778 | + |
779 | + // Ctrl+Shift+W or Ctrl+Shift+T: Undo close tab |
780 | + Shortcut { |
781 | + sequence: "Ctrl+Shift+W" |
782 | + enabled: tabContainer.visible || recentView.visible |
783 | + onActivated: internal.undoCloseTab() |
784 | + } |
785 | + Shortcut { |
786 | + sequence: "Ctrl+Shift+T" |
787 | + enabled: tabContainer.visible || recentView.visible |
788 | + onActivated: internal.undoCloseTab() |
789 | + } |
790 | + |
791 | + // Ctrl+T: Open a new Tab |
792 | + Shortcut { |
793 | + sequence: StandardKey.AddTab |
794 | + enabled: tabContainer.visible || recentView.visible || |
795 | + bookmarksViewLoader.active || historyViewLoader.active |
796 | + onActivated: { |
797 | + openUrlInNewTab("", true) |
798 | + if (recentView.visible) recentView.reset() |
799 | + bookmarksViewLoader.active = false |
800 | + historyViewLoader.active = false |
801 | + } |
802 | + } |
803 | + |
804 | + // F6 or Ctrl+L or Alt+D: Select the content in the address bar |
805 | + Shortcut { |
806 | + sequence: "F6" |
807 | + enabled: tabContainer.visible |
808 | + onActivated: internal.focusAddressBar(true) |
809 | + } |
810 | + Shortcut { |
811 | + sequence: "Ctrl+L" |
812 | + enabled: tabContainer.visible |
813 | + onActivated: internal.focusAddressBar(true) |
814 | + } |
815 | + Shortcut { |
816 | + sequence: "Alt+D" |
817 | + enabled: tabContainer.visible |
818 | + onActivated: internal.focusAddressBar(true) |
819 | + } |
820 | + |
821 | + // Ctrl+D: Toggle bookmarked state on current Tab |
822 | + Shortcut { |
823 | + sequence: "Ctrl+D" |
824 | + enabled: tabContainer.visible |
825 | + onActivated: { |
826 | + if (internal.currentBookmarkOptionsDialog) { |
827 | + internal.currentBookmarkOptionsDialog.hide() |
828 | + } else if (currentWebview) { |
829 | + if (BookmarksModel.contains(currentWebview.url)) { |
830 | + BookmarksModel.remove(currentWebview.url) |
831 | + } else { |
832 | + internal.addBookmark(currentWebview.url, currentWebview.title, currentWebview.icon) |
833 | } |
834 | } |
835 | } |
836 | - |
837 | - // Ctrl+H: Show History |
838 | - KeyboardShortcut { |
839 | - modifiers: Qt.ControlModifier |
840 | - key: Qt.Key_H |
841 | - enabled: tabContainer.visible |
842 | - onTriggered: historyViewLoader.active = true |
843 | - } |
844 | - |
845 | - // Ctrl+Shift+O: Show Bookmarks |
846 | - KeyboardShortcut { |
847 | - modifiers: Qt.ControlModifier | Qt.ShiftModifier |
848 | - key: Qt.Key_O |
849 | - enabled: tabContainer.visible |
850 | - onTriggered: bookmarksViewLoader.active = true |
851 | - } |
852 | - |
853 | - // Alt+← or Backspace: Goes to the previous page in history |
854 | - KeyboardShortcut { |
855 | - modifiers: Qt.AltModifier |
856 | - key: Qt.Key_Left |
857 | - enabled: tabContainer.visible |
858 | - onTriggered: internal.historyGoBack() |
859 | - } |
860 | - KeyboardShortcut { |
861 | - key: Qt.Key_Backspace |
862 | - enabled: tabContainer.visible |
863 | - onTriggered: internal.historyGoBack() |
864 | - } |
865 | - |
866 | - // Alt+→ or Shift+Backspace: Goes to the next page in history |
867 | - KeyboardShortcut { |
868 | - modifiers: Qt.AltModifier |
869 | - key: Qt.Key_Right |
870 | - enabled: tabContainer.visible |
871 | - onTriggered: internal.historyGoForward() |
872 | - } |
873 | - KeyboardShortcut { |
874 | - modifiers: Qt.ShiftModifier |
875 | - key: Qt.Key_Backspace |
876 | - enabled: tabContainer.visible |
877 | - onTriggered: internal.historyGoForward() |
878 | - } |
879 | - |
880 | - // F5 or Ctrl+R: Reload current Tab |
881 | - KeyboardShortcut { |
882 | - key: Qt.Key_F5 |
883 | - enabled: tabContainer.visible |
884 | - onTriggered: if (currentWebview) currentWebview.reload() |
885 | - } |
886 | - KeyboardShortcut { |
887 | - modifiers: Qt.ControlModifier |
888 | - key: Qt.Key_R |
889 | - enabled: tabContainer.visible |
890 | - onTriggered: if (currentWebview) currentWebview.reload() |
891 | - } |
892 | - |
893 | - // Ctrl+F: Find in Page |
894 | - KeyboardShortcut { |
895 | - modifiers: Qt.ControlModifier |
896 | - key: Qt.Key_F |
897 | - enabled: tabContainer.visible && !newTabViewLoader.active |
898 | - onTriggered: chrome.findInPageMode = true |
899 | - } |
900 | - |
901 | - // Ctrl+J: Show downloads page |
902 | - KeyboardShortcut { |
903 | - modifiers: Qt.ControlModifier |
904 | - key: Qt.Key_J |
905 | - enabled: chrome.visible && |
906 | - downloadHandlerLoader.status == Loader.Ready && |
907 | - contentHandlerLoader.status == Loader.Ready && |
908 | - !downloadsViewLoader.active |
909 | - onTriggered: downloadsViewLoader.active = true |
910 | - } |
911 | - |
912 | - // Ctrl+Shift+G: Find previous |
913 | - KeyboardShortcut { |
914 | - modifiers: Qt.ControlModifier | Qt.ShiftModifier |
915 | - key: Qt.Key_G |
916 | - enabled: currentWebview && chrome.findInPageMode |
917 | - onTriggered: currentWebview.findController.previous() |
918 | - } |
919 | - |
920 | - // Ctrl+G: Find next |
921 | - KeyboardShortcut { |
922 | - modifiers: Qt.ControlModifier |
923 | - key: Qt.Key_G |
924 | - enabled: currentWebview && chrome.findInPageMode |
925 | - onTriggered: currentWebview.findController.next() |
926 | - } |
927 | + } |
928 | + |
929 | + // Ctrl+H: Show History |
930 | + Shortcut { |
931 | + sequence: "Ctrl+H" |
932 | + enabled: tabContainer.visible |
933 | + onActivated: historyViewLoader.active = true |
934 | + } |
935 | + |
936 | + // Ctrl+Shift+O: Show Bookmarks |
937 | + Shortcut { |
938 | + sequence: "Ctrl+Shift+O" |
939 | + enabled: tabContainer.visible |
940 | + onActivated: bookmarksViewLoader.active = true |
941 | + } |
942 | + |
943 | + // Alt+← or Backspace: Goes to the previous page in history |
944 | + Shortcut { |
945 | + sequence: StandardKey.Back |
946 | + enabled: tabContainer.visible |
947 | + onActivated: internal.historyGoBack() |
948 | + } |
949 | + Shortcut { |
950 | + sequence: "Backspace" |
951 | + enabled: tabContainer.visible |
952 | + onActivated: internal.historyGoBack() |
953 | + } |
954 | + |
955 | + // Alt+→ or Shift+Backspace: Goes to the next page in history |
956 | + Shortcut { |
957 | + sequence: StandardKey.Forward |
958 | + enabled: tabContainer.visible |
959 | + onActivated: internal.historyGoForward() |
960 | + } |
961 | + Shortcut { |
962 | + sequence: "Shift+Backspace" |
963 | + enabled: tabContainer.visible |
964 | + onActivated: internal.historyGoForward() |
965 | + } |
966 | + |
967 | + // F5 or Ctrl+R: Reload current Tab |
968 | + Shortcut { |
969 | + sequence: StandardKey.Refresh |
970 | + enabled: tabContainer.visible |
971 | + onActivated: if (currentWebview) currentWebview.reload() |
972 | + } |
973 | + Shortcut { |
974 | + sequence: "F5" |
975 | + enabled: tabContainer.visible |
976 | + onActivated: if (currentWebview) currentWebview.reload() |
977 | + } |
978 | + |
979 | + // Ctrl+F: Find in Page |
980 | + Shortcut { |
981 | + sequence: StandardKey.Find |
982 | + enabled: tabContainer.visible && !newTabViewLoader.active |
983 | + onActivated: chrome.findInPageMode = true |
984 | + } |
985 | + |
986 | + // Ctrl+J: Show downloads page |
987 | + Shortcut { |
988 | + sequence: "Ctrl+J" |
989 | + enabled: chrome.visible && |
990 | + downloadHandlerLoader.status == Loader.Ready && |
991 | + contentHandlerLoader.status == Loader.Ready && |
992 | + !downloadsViewLoader.active |
993 | + onActivated: downloadsViewLoader.active = true |
994 | + } |
995 | + |
996 | + // Ctrl+G: Find next |
997 | + Shortcut { |
998 | + sequence: StandardKey.FindNext |
999 | + enabled: currentWebview && chrome.findInPageMode |
1000 | + onActivated: currentWebview.findController.next() |
1001 | + } |
1002 | + |
1003 | + // Ctrl+Shift+G: Find previous |
1004 | + Shortcut { |
1005 | + sequence: StandardKey.FindPrevious |
1006 | + enabled: currentWebview && chrome.findInPageMode |
1007 | + onActivated: currentWebview.findController.previous() |
1008 | } |
1009 | |
1010 | Loader { |
1011 | |
1012 | === removed file 'src/app/webbrowser/KeyboardShortcut.qml' |
1013 | --- src/app/webbrowser/KeyboardShortcut.qml 2015-08-10 15:22:00 +0000 |
1014 | +++ src/app/webbrowser/KeyboardShortcut.qml 1970-01-01 00:00:00 +0000 |
1015 | @@ -1,25 +0,0 @@ |
1016 | -/* |
1017 | - * Copyright 2015 Canonical Ltd. |
1018 | - * |
1019 | - * This file is part of webbrowser-app. |
1020 | - * |
1021 | - * webbrowser-app is free software; you can redistribute it and/or modify |
1022 | - * it under the terms of the GNU General Public License as published by |
1023 | - * the Free Software Foundation; version 3. |
1024 | - * |
1025 | - * webbrowser-app is distributed in the hope that it will be useful, |
1026 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1027 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1028 | - * GNU General Public License for more details. |
1029 | - * |
1030 | - * You should have received a copy of the GNU General Public License |
1031 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1032 | - */ |
1033 | - |
1034 | -import QtQuick 2.4 |
1035 | -import Ubuntu.Components 1.3 |
1036 | - |
1037 | -Action { |
1038 | - property int key |
1039 | - property int modifiers: Qt.NoModifier |
1040 | -} |
1041 | |
1042 | === removed file 'src/app/webbrowser/KeyboardShortcuts.qml' |
1043 | --- src/app/webbrowser/KeyboardShortcuts.qml 2015-08-10 15:22:00 +0000 |
1044 | +++ src/app/webbrowser/KeyboardShortcuts.qml 1970-01-01 00:00:00 +0000 |
1045 | @@ -1,41 +0,0 @@ |
1046 | -/* |
1047 | - * Copyright 2015 Canonical Ltd. |
1048 | - * |
1049 | - * This file is part of webbrowser-app. |
1050 | - * |
1051 | - * webbrowser-app is free software; you can redistribute it and/or modify |
1052 | - * it under the terms of the GNU General Public License as published by |
1053 | - * the Free Software Foundation; version 3. |
1054 | - * |
1055 | - * webbrowser-app is distributed in the hope that it will be useful, |
1056 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1057 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1058 | - * GNU General Public License for more details. |
1059 | - * |
1060 | - * You should have received a copy of the GNU General Public License |
1061 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1062 | - */ |
1063 | - |
1064 | -import QtQuick 2.4 |
1065 | - |
1066 | -Item { |
1067 | - function processKey(key, modifiers) { |
1068 | - for (var i = 0; i < data.length; i++) { |
1069 | - var shortcut = data[i]; |
1070 | - |
1071 | - if (!shortcut.enabled) continue |
1072 | - if (key !== shortcut.key) continue |
1073 | - |
1074 | - if (shortcut.modifiers === Qt.NoModifier) { |
1075 | - if (modifiers === Qt.NoModifier) { |
1076 | - shortcut.trigger() |
1077 | - return true |
1078 | - } |
1079 | - } else if ((modifiers & shortcut.modifiers) === shortcut.modifiers) { |
1080 | - shortcut.trigger() |
1081 | - return true |
1082 | - } |
1083 | - } |
1084 | - return false |
1085 | - } |
1086 | -} |
1087 | |
1088 | === modified file 'src/app/webbrowser/ListViewHighlight.qml' |
1089 | --- src/app/webbrowser/ListViewHighlight.qml 2016-02-10 17:20:47 +0000 |
1090 | +++ src/app/webbrowser/ListViewHighlight.qml 2016-04-08 16:47:47 +0000 |
1091 | @@ -18,7 +18,7 @@ |
1092 | |
1093 | import QtQuick 2.4 |
1094 | import Ubuntu.Components 1.3 |
1095 | -import Unity.InputInfo 0.1 |
1096 | +import ".." |
1097 | |
1098 | Rectangle { |
1099 | color: "transparent" |
1100 | @@ -33,8 +33,7 @@ |
1101 | |
1102 | readonly property bool hasKeyboard: keyboardModel.count > 0 |
1103 | |
1104 | - InputDeviceModel { |
1105 | + FilteredKeyboardModel { |
1106 | id: keyboardModel |
1107 | - deviceFilter: InputInfo.Keyboard |
1108 | } |
1109 | } |
1110 | |
1111 | === modified file 'src/app/webbrowser/NavigationBar.qml' |
1112 | --- src/app/webbrowser/NavigationBar.qml 2016-03-01 09:20:32 +0000 |
1113 | +++ src/app/webbrowser/NavigationBar.qml 2016-04-08 16:47:47 +0000 |
1114 | @@ -220,15 +220,18 @@ |
1115 | id: internal |
1116 | property var openDrawer: null |
1117 | readonly property var webview: tab ? tab.webview : null |
1118 | + } |
1119 | |
1120 | - onWebviewChanged: { |
1121 | - if (webview) { |
1122 | - addressbar.actualUrl = webview.url |
1123 | - addressbar.securityStatus = webview.securityStatus |
1124 | - } else { |
1125 | - addressbar.actualUrl = "" |
1126 | - addressbar.securityStatus = null |
1127 | + onTabChanged: { |
1128 | + if (tab) { |
1129 | + addressbar.actualUrl = tab.url |
1130 | + addressbar.securityStatus = (tab.webview ? tab.webview.securityStatus : null) |
1131 | + if (!tab.url.toString() && editing) { |
1132 | + addressbar.text = "" |
1133 | } |
1134 | + } else { |
1135 | + addressbar.actualUrl = "" |
1136 | + addressbar.securityStatus = null |
1137 | } |
1138 | } |
1139 | |
1140 | |
1141 | === modified file 'tests/autopilot/webbrowser_app/tests/test_keyboard.py' |
1142 | --- tests/autopilot/webbrowser_app/tests/test_keyboard.py 2016-01-21 10:29:17 +0000 |
1143 | +++ tests/autopilot/webbrowser_app/tests/test_keyboard.py 2016-04-08 16:47:47 +0000 |
1144 | @@ -103,7 +103,7 @@ |
1145 | self.check_tab_number(2) |
1146 | self.main_window.press_key('Ctrl+Page_Down') |
1147 | self.check_tab_number(0) |
1148 | - self.main_window.press_key('Shift+Ctrl+Tab') |
1149 | + self.main_window.press_key('Ctrl+Shift+Tab') |
1150 | if self.main_window.wide: |
1151 | self.check_tab_number(2) |
1152 | else: |
1153 | @@ -493,3 +493,24 @@ |
1154 | |
1155 | self.main_window.press_key('Ctrl+w') |
1156 | self.assert_number_webviews_eventually(1) |
1157 | + |
1158 | + def test_addressbar_cleared_when_opening_new_tab(self): |
1159 | + # Verify that when opening a new tab while the address bar was focused, |
1160 | + # the address bar is cleared. |
1161 | + self.main_window.press_key('Ctrl+l') |
1162 | + self.address_bar.activeFocus.wait_for(True) |
1163 | + self.assertThat(self.address_bar.text, Eventually(Equals(self.url))) |
1164 | + self.main_window.press_key('Ctrl+t') |
1165 | + self.address_bar.activeFocus.wait_for(True) |
1166 | + self.assertThat(self.address_bar.text, Eventually(Equals(""))) |
1167 | + |
1168 | + def test_addressbar_cleared_when_switching_between_new_tabs(self): |
1169 | + # Verify that when opening a new tab while a new tab was already open |
1170 | + # with text input in the address bar, the address bar is cleared. |
1171 | + self.main_window.press_key('Ctrl+t') |
1172 | + self.address_bar.activeFocus.wait_for(True) |
1173 | + self.assertThat(self.address_bar.text, Eventually(Equals(""))) |
1174 | + self.address_bar.write("abc") |
1175 | + self.main_window.press_key('Ctrl+t') |
1176 | + self.address_bar.activeFocus.wait_for(True) |
1177 | + self.assertThat(self.address_bar.text, Eventually(Equals(""))) |
1178 | |
1179 | === modified file 'tests/autopilot/webbrowser_app/tests/test_private.py' |
1180 | --- tests/autopilot/webbrowser_app/tests/test_private.py 2016-01-21 10:29:17 +0000 |
1181 | +++ tests/autopilot/webbrowser_app/tests/test_private.py 2016-04-08 16:47:47 +0000 |
1182 | @@ -16,6 +16,7 @@ |
1183 | |
1184 | from testtools.matchers import Equals, NotEquals |
1185 | from autopilot.matchers import Eventually |
1186 | +from autopilot.platform import model |
1187 | |
1188 | from webbrowser_app.tests import StartOpenRemotePageTestCaseBase |
1189 | |
1190 | @@ -30,7 +31,7 @@ |
1191 | self.assert_number_incognito_webviews_eventually(1) |
1192 | self.assertTrue(self.main_window.is_new_private_tab_view_visible()) |
1193 | self.assertThat(address_bar.activeFocus, |
1194 | - Eventually(Equals(self.main_window.wide))) |
1195 | + Eventually(Equals(model() == 'Desktop'))) |
1196 | self.assertThat(address_bar.text, Eventually(Equals(""))) |
1197 | |
1198 | self.main_window.leave_private_mode() |
FAILED: Continuous integration, rev:1389 jenkins. qa.ubuntu. com/job/ webbrowser- app-ci/ 2677/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 6789/console jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- amd64-ci/ 1430/console jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 1430/console jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- i386-ci/ 1430/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 6800/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/webbrowser- app-ci/ 2677/rebuild
http://