on xenial help sign in
Further clean up and refactor focus handling in DesktopStage
966b9e6Daniel d'Andrada
plugins/Utils/CMakeLists.txt+1
@@ -9,6 +9,7 @@ include_directories(
9)
9)
10
10
11set(QMLPLUGIN_SRC
11set(QMLPLUGIN_SRC
12+ activefocuslogger.cpp
12 constants.cpp
13 constants.cpp
13 HomeKeyWatcher.cpp
14 HomeKeyWatcher.cpp
14 inputwatcher.cpp
15 inputwatcher.cpp
plugins/Utils/plugin.cpp+2
@@ -23,6 +23,7 @@
23#include "plugin.h"
23#include "plugin.h"
24
24
25// local
25// local
26+#include "activefocuslogger.h"
26#include "easingcurve.h"
27#include "easingcurve.h"
27#include "HomeKeyWatcher.h"
28#include "HomeKeyWatcher.h"
28#include "inputwatcher.h"
29#include "inputwatcher.h"
@@ -66,6 +67,7 @@ void UtilsPlugin::registerTypes(const char *uri)
66 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
67 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
67 qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
68 qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
68 qmlRegisterSingletonType<Constants>(uri, 0, 1, "Constants", createConstants);
69 qmlRegisterSingletonType<Constants>(uri, 0, 1, "Constants", createConstants);
70+ qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger");
69}
71}
70
72
71void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
73void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
qml/Stages/DesktopStage.qml+8−15
@@ -77,7 +77,6 @@ Rectangle {
77 var appIndex = priv.indexOf(appId);
77 var appIndex = priv.indexOf(appId);
78 var appDelegate = appRepeater.itemAt(appIndex);
78 var appDelegate = appRepeater.itemAt(appIndex);
79 appDelegate.minimized = false;
79 appDelegate.minimized = false;
80− appDelegate.focus = true;
81 ApplicationManager.focusApplication(appId);
80 ApplicationManager.focusApplication(appId);
82 }
81 }
83 }
82 }
@@ -91,12 +90,6 @@ Rectangle {
91 return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null
90 return index >= 0 && index < appRepeater.count ? appRepeater.itemAt(index) : null
92 }
91 }
93
92
94− onFocusedAppDelegateChanged: {
95− if (focusedAppDelegate) {
96− focusedAppDelegate.focus = true;
97− }
98− }
99−
100 function indexOf(appId) {
93 function indexOf(appId) {
101 for (var i = 0; i < ApplicationManager.count; i++) {
94 for (var i = 0; i < ApplicationManager.count; i++) {
102 if (ApplicationManager.get(i).appId == appId) {
95 if (ApplicationManager.get(i).appId == appId) {
@@ -140,17 +133,21 @@ Rectangle {
140 case Qt.Key_Left:
133 case Qt.Key_Left:
141 case Qt.Key_Backtab:
134 case Qt.Key_Backtab:
142 selectPrevious(event.isAutoRepeat)
135 selectPrevious(event.isAutoRepeat)
136+ event.accepted = true;
143 break;
137 break;
144 case Qt.Key_Right:
138 case Qt.Key_Right:
145 case Qt.Key_Tab:
139 case Qt.Key_Tab:
146 selectNext(event.isAutoRepeat)
140 selectNext(event.isAutoRepeat)
141+ event.accepted = true;
147 break;
142 break;
148 case Qt.Key_Escape:
143 case Qt.Key_Escape:
149 appRepeater.highlightedIndex = -1
144 appRepeater.highlightedIndex = -1
145+ event.accepted = true;
150 case Qt.Key_Enter:
146 case Qt.Key_Enter:
151 case Qt.Key_Return:
147 case Qt.Key_Return:
152 case Qt.Key_Space:
148 case Qt.Key_Space:
153 root.state = ""
149 root.state = ""
150+ event.accepted = true;
154 }
151 }
155 }
152 }
156
153
@@ -181,7 +178,8 @@ Rectangle {
181
178
182 function focusSelected() {
179 function focusSelected() {
183 if (appRepeater.highlightedIndex != -1) {
180 if (appRepeater.highlightedIndex != -1) {
184− appRepeater.itemAt(appRepeater.highlightedIndex).focus = true;
181+ var application = ApplicationManager.get(appRepeater.highlightedIndex);
182+ ApplicationManager.focusApplication(application.appId);
185 }
183 }
186 }
184 }
187
185
@@ -206,11 +204,7 @@ Rectangle {
206 property bool maximized: false
204 property bool maximized: false
207 property bool minimized: false
205 property bool minimized: false
208
206
209− onFocusChanged: {
207+ focus: priv.focusedAppId === model.appId && root.state !== "altTab"
210− if (focus && ApplicationManager.focusedApplicationId !== model.appId) {
211− ApplicationManager.requestFocusApplication(model.appId);
212− }
213− }
214
208
215 Binding {
209 Binding {
216 target: ApplicationManager.get(index)
210 target: ApplicationManager.get(index)
@@ -321,7 +315,7 @@ Rectangle {
321 resizeHandleWidth: units.gu(2)
315 resizeHandleWidth: units.gu(2)
322 windowId: model.appId // FIXME: Change this to point to windowId once we have such a thing
316 windowId: model.appId // FIXME: Change this to point to windowId once we have such a thing
323
317
324− onPressed: appDelegate.focus = true;
318+ onPressed: ApplicationManager.focusApplication(model.appId);
325 }
319 }
326
320
327 DecoratedWindow {
321 DecoratedWindow {
@@ -577,7 +571,6 @@ Rectangle {
577 PropertyChanges { target: spreadFlickable; enabled: true }
571 PropertyChanges { target: spreadFlickable; enabled: true }
578 PropertyChanges { target: currentSelectedLabel; visible: true }
572 PropertyChanges { target: currentSelectedLabel; visible: true }
579 PropertyChanges { target: spreadBackground; visible: true }
573 PropertyChanges { target: spreadBackground; visible: true }
580− PropertyChanges { target: appContainer; focus: true }
581 }
574 }
582 ]
575 ]
583 signal updateWorkspaces();
576 signal updateWorkspaces();
tests/mocks/Utils/CMakeLists.txt+1
@@ -10,6 +10,7 @@ include_directories(
10)
10)
11
11
12set(QMLPLUGIN_SRC
12set(QMLPLUGIN_SRC
13+ ${CMAKE_SOURCE_DIR}/plugins/Utils/activefocuslogger.cpp
13 ${CMAKE_SOURCE_DIR}/plugins/Utils/qlimitproxymodelqml.cpp
14 ${CMAKE_SOURCE_DIR}/plugins/Utils/qlimitproxymodelqml.cpp
14 ${CMAKE_SOURCE_DIR}/plugins/Utils/unitysortfilterproxymodelqml.cpp
15 ${CMAKE_SOURCE_DIR}/plugins/Utils/unitysortfilterproxymodelqml.cpp
15 ${CMAKE_SOURCE_DIR}/plugins/Utils/relativetimeformatter.cpp
16 ${CMAKE_SOURCE_DIR}/plugins/Utils/relativetimeformatter.cpp
tests/mocks/Utils/plugin.cpp+2
@@ -35,6 +35,7 @@
35#include "constants.h"
35#include "constants.h"
36
36
37// plugin
37// plugin
38+#include <activefocuslogger.h>
38#include <inputwatcher.h>
39#include <inputwatcher.h>
39#include <qlimitproxymodelqml.h>
40#include <qlimitproxymodelqml.h>
40#include <unitysortfilterproxymodelqml.h>
41#include <unitysortfilterproxymodelqml.h>
@@ -74,6 +75,7 @@ void FakeUtilsPlugin::registerTypes(const char *uri)
74 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
75 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
75 qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
76 qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
76 qmlRegisterSingletonType<Constants>(uri, 0, 1, "Constants", createConstants);
77 qmlRegisterSingletonType<Constants>(uri, 0, 1, "Constants", createConstants);
78+ qmlRegisterType<ActiveFocusLogger>(uri, 0, 1, "ActiveFocusLogger");
77}
79}
78
80
79void FakeUtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
81void FakeUtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
tests/uqmlscene/ActiveFocusLogger.cppdeleted−48
@@ -1,48 +0,0 @@
1−/*
2− * Copyright (C) 2015 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#include "ActiveFocusLogger.h"
18−
19−#include <QDebug>
20−#include <QQuickItem>
21−
22−void ActiveFocusLogger::setWindow(QQuickWindow *window)
23−{
24− m_window = window;
25− QObject::connect(window, &QQuickWindow::activeFocusItemChanged,
26− this, &ActiveFocusLogger::printActiveFocusInfo);
27−}
28−
29−void ActiveFocusLogger::printActiveFocusInfo()
30−{
31− if (!m_window) {
32− return;
33− }
34−
35− qDebug() << "============== Active focus info START ================";
36− if (m_window->activeFocusItem()) {
37− qDebug() << m_window->activeFocusItem();
38− qDebug() << "Ancestry:";
39− QQuickItem *item = m_window->activeFocusItem()->parentItem();
40− while (item != nullptr) {
41− qDebug() << item << ", isFocusScope =" << item->isFocusScope();
42− item = item->parentItem();
43− }
44− } else {
45− qDebug() << "NULL";
46− }
47− qDebug() << "============== Active focus info END ================";
48−}
tests/uqmlscene/ActiveFocusLogger.hdeleted−37
@@ -1,37 +0,0 @@
1−/*
2− * Copyright (C) 2015 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#ifndef ACTIVE_FOCUS_LOGGER_H
18−#define ACTIVE_FOCUS_LOGGER_H
19−
20−#include <QObject>
21−#include <QQuickWindow>
22−#include <QPointer>
23−
24−class ActiveFocusLogger : public QObject {
25− Q_OBJECT
26−
27−public:
28− void setWindow(QQuickWindow *window);
29−
30−private Q_SLOTS:
31− void printActiveFocusInfo();
32−
33−private:
34− QPointer<QQuickWindow> m_window;
35−};
36−
37−#endif // ACTIVE_FOCUS_LOGGER_H
tests/uqmlscene/CMakeLists.txt−1
@@ -1,6 +1,5 @@
1add_executable(uqmlscene
1add_executable(uqmlscene
2 ${shellapplication_MOC_SRCS}
2 ${shellapplication_MOC_SRCS}
3− ActiveFocusLogger.cpp
4 main.cpp
3 main.cpp
5 )
4 )
6
5
tests/uqmlscene/main.cpp−13
@@ -63,12 +63,6 @@
63#include <QtCore/QTranslator>
63#include <QtCore/QTranslator>
64#include <QtCore/QLibraryInfo>
64#include <QtCore/QLibraryInfo>
65
65
66−#define UQMLSCENE_DEBUG_ACTIVE_FOCUS 0
67−
68−#if UQMLSCENE_DEBUG_ACTIVE_FOCUS
69− #include "ActiveFocusLogger.h"
70−#endif
71−
72#ifdef QML_RUNTIME_TESTING
66#ifdef QML_RUNTIME_TESTING
73class RenderStatistics
67class RenderStatistics
74{
68{
@@ -393,10 +387,6 @@ int main(int argc, char ** argv)
393{
387{
394 Options options;
388 Options options;
395
389
396− #if UQMLSCENE_DEBUG_ACTIVE_FOCUS
397− ActiveFocusLogger activeFocusLogger;
398− #endif
399−
400 QStringList imports;
390 QStringList imports;
401 QList<QPair<QString, QString> > bundles;
391 QList<QPair<QString, QString> > bundles;
402 for (int i = 1; i < argc; ++i) {
392 for (int i = 1; i < argc; ++i) {
@@ -515,9 +505,6 @@ int main(int argc, char ** argv)
515 QQuickItem *contentItem = qobject_cast<QQuickItem *>(topLevel);
505 QQuickItem *contentItem = qobject_cast<QQuickItem *>(topLevel);
516 if (contentItem) {
506 if (contentItem) {
517 qxView = new QQuickView(&engine, nullptr);
507 qxView = new QQuickView(&engine, nullptr);
518− #if UQMLSCENE_DEBUG_ACTIVE_FOCUS
519− activeFocusLogger.setWindow(qxView);
520− #endif
521 window = qxView;
508 window = qxView;
522 // Set window default properties; the qml can still override them
509 // Set window default properties; the qml can still override them
523 QString oname = contentItem->objectName();
510 QString oname = contentItem->objectName();