on xenial help sign in
added workspaces
commit14f1570da3b43e11ab6c577622a0ca46a50a2e91 authorNick Dedekind <nick.dedekind@canonical.com> dateFri 17 Feb 2017, 17:29 (10 years ago) parent94c2a09
14 files changed+410−7
plugins/WindowManager/CMakeLists.txt+3 plugins/WindowManager/Screen.cpp+7 plugins/WindowManager/Screen.h+6 plugins/WindowManager/WindowManagerPlugin.cpp+14−2 plugins/WindowManager/Workspace.cpp+63 plugins/WindowManager/Workspace.h+44 plugins/WindowManager/WorkspaceManager.cpp+47 plugins/WindowManager/WorkspaceManager.h+41 plugins/WindowManager/WorkspaceModel.cpp+90 plugins/WindowManager/WorkspaceModel.h+63 tests/mocks/WindowManager/CMakeLists.txt+3 tests/mocks/WindowManager/Screen.cpp+6 tests/mocks/WindowManager/Screen.h+9−3 tests/mocks/WindowManager/WindowManagerPlugin.cpp+14−2
plugins/WindowManager/CMakeLists.txt+3
@@ -10,6 +10,9 @@ set(WINDOWMANAGER_SRC
1010 Screens.cpp
1111 Screen.cpp
1212 ScreenWindow.cpp
13+ Workspace.cpp
14+ WorkspaceManager.cpp
15+ WorkspaceModel.cpp
1316 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
1417 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h
1518 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
plugins/WindowManager/Screen.cpp+7
@@ -15,9 +15,13 @@
1515 */
1616
1717#include "Screen.h"
18+#include "WorkspaceModel.h"
19+#include "WorkspaceManager.h"
20+#include "Workspace.h"
1821
1922Screen::Screen(qtmir::Screen* screen)
2023 : m_wrapped(screen)
24+ , m_workspaces(new WorkspaceModel)
2125{
2226 connect(m_wrapped, &qtmir::Screen::usedChanged, this, &Screen::usedChanged);
2327 connect(m_wrapped, &qtmir::Screen::nameChanged, this, &Screen::nameChanged);
@@ -29,6 +33,9 @@ Screen::Screen(qtmir::Screen* screen)
2933 connect(m_wrapped, &qtmir::Screen::activeChanged, this, &Screen::activeChanged);
3034 connect(m_wrapped, &qtmir::Screen::currentModeIndexChanged, this, &Screen::currentModeIndexChanged);
3135 connect(m_wrapped, &qtmir::Screen::availableModesChanged, this, &Screen::availableModesChanged);
36+
37+ WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
38+ WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
3239}
3340
3441qtmir::OutputId Screen::outputId() const
plugins/WindowManager/Screen.h+6
@@ -4,9 +4,12 @@
44#include <qtmir/screen.h>
55#include <QScopedPointer>
66
7+class WorkspaceModel;
8+
79class Screen : public qtmir::Screen
810{
911 Q_OBJECT
12+ Q_PROPERTY(WorkspaceModel* workspaces READ workspaces CONSTANT)
1013
1114public:
1215 explicit Screen(qtmir::Screen*const wrapped);
@@ -33,8 +36,11 @@ public:
3336
3437 qtmir::Screen* wrapped() const { return m_wrapped; }
3538
39+ WorkspaceModel* workspaces() const { return m_workspaces.data(); }
40+
3641private:
3742 qtmir::Screen*const m_wrapped;
43+ const QScopedPointer<WorkspaceModel> m_workspaces;
3844};
3945
4046#endif // SCREEN_H
plugins/WindowManager/WindowManagerPlugin.cpp+14−2
@@ -16,14 +16,23 @@
1616
1717#include "WindowManagerPlugin.h"
1818
19−#include "TopLevelWindowModel.h"
20−#include "Window.h"
2119#include "Screens.h"
2220#include "Screen.h"
2321#include "ScreenWindow.h"
22+#include "TopLevelWindowModel.h"
23+#include "Window.h"
24+#include "WorkspaceManager.h"
25+#include "Workspace.h"
26+#include "WorkspaceModel.h"
2427
2528#include <QtQml>
2629
30+static QObject *workspace_manager(QQmlEngine *engine, QJSEngine *scriptEngine)
31+{
32+ Q_UNUSED(engine)
33+ Q_UNUSED(scriptEngine)
34+ return WorkspaceManager::instance();
35+}
2736QObject* screensSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
2837 Q_UNUSED(engine);
2938 Q_UNUSED(scriptEngine);
@@ -33,10 +42,13 @@ QObject* screensSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3342void WindowManagerPlugin::registerTypes(const char *uri)
3443{
3544 qmlRegisterType<TopLevelWindowModel>(uri, 1, 0, "TopLevelWindowModel");
45+ qmlRegisterSingletonType<WorkspaceManager>(uri, 1, 0, "WorkspaceManager", workspace_manager);
46+ qmlRegisterUncreatableType<WorkspaceModel>(uri, 1, 0, "WorkspaceModel", "Not a creatable type");
3647 qmlRegisterSingletonType<Screens>(uri, 1, 0, "Screens", screensSingleton);
3748 qmlRegisterUncreatableType<qtmir::ScreenMode>(uri, 1, 0, "ScreenMode", "ScreenMode is not creatable.");
3849
3950 qRegisterMetaType<Window*>("Window*");
51+ qRegisterMetaType<Workspace*>("Workspace*");
4052
4153 qRegisterMetaType<QAbstractListModel*>("QAbstractListModel*");
4254 qRegisterMetaType<Screen*>("Screen*");
plugins/WindowManager/Workspace.cppnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2017 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 "Workspace.h"
18+#include "WorkspaceModel.h"
19+
20+Workspace::Workspace(QObject *parent)
21+ : QObject(parent)
22+ , m_model(nullptr)
23+{
24+
25+}
26+
27+Workspace::~Workspace()
28+{
29+ unassign();
30+}
31+
32+void Workspace::assign(WorkspaceModel *model)
33+{
34+ bool wasAssinged = false;
35+ if (m_model) {
36+ disconnect(model);
37+ m_model->remove(this);
38+ wasAssinged = true;
39+ }
40+
41+ m_model = model;
42+ if (model) {
43+ model->append(this);
44+
45+ connect(model, &QObject::destroyed, this, [this]() {
46+ m_model = nullptr;
47+ Q_EMIT unassigned();
48+ });
49+ Q_EMIT assigned();
50+ } else if (wasAssinged) {
51+ Q_EMIT unassigned();
52+ }
53+}
54+
55+void Workspace::unassign()
56+{
57+ if (m_model) {
58+ m_model->remove(this);
59+ m_model = nullptr;
60+
61+ Q_EMIT unassigned();
62+ }
63+}
plugins/WindowManager/Workspace.hnew file+44
@@ -0,0 +1,44 @@
1+/*
2+ * Copyright (C) 2017 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 WORKSPACE_H
18+#define WORKSPACE_H
19+
20+#include <QObject>
21+
22+class WorkspaceModel;
23+
24+class Workspace : public QObject
25+{
26+ Q_OBJECT
27+public:
28+ explicit Workspace(QObject *parent = 0);
29+ ~Workspace();
30+
31+ Q_INVOKABLE void assign(WorkspaceModel* model);
32+
33+public Q_SLOT:
34+ void unassign();
35+
36+Q_SIGNALS:
37+ void assigned();
38+ void unassigned();
39+
40+private:
41+ WorkspaceModel* m_model;
42+};
43+
44+#endif // WORKSPACE_H
plugins/WindowManager/WorkspaceManager.cppnew file+47
@@ -0,0 +1,47 @@
1+/*
2+ * Copyright (C) 2017 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 "WorkspaceManager.h"
18+#include "Workspace.h"
19+
20+// Qt
21+#include <QGuiApplication>
22+#include <QScreen>
23+#include <QQmlEngine>
24+
25+WorkspaceManager *WorkspaceManager::instance()
26+{
27+ static WorkspaceManager* workspaceManager(new WorkspaceManager());
28+ return workspaceManager;
29+}
30+
31+WorkspaceManager::WorkspaceManager()
32+{
33+}
34+Workspace *WorkspaceManager::createWorkspace()
35+{
36+ auto workspace = new Workspace(this);
37+ QQmlEngine::setObjectOwnership(workspace, QQmlEngine::CppOwnership);
38+ m_allWorkspaces.append(workspace);
39+ workspace->assign(this);
40+ return workspace;
41+}
42+
43+void WorkspaceManager::destroyWorkspace(Workspace *workspace)
44+{
45+ workspace->deleteLater();
46+}
47+
plugins/WindowManager/WorkspaceManager.hnew file+41
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright (C) 2017 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 WORKSPACEMANAGER_H
18+#define WORKSPACEMANAGER_H
19+
20+#include "WorkspaceModel.h"
21+
22+class Workspace;
23+
24+class WorkspaceManager : public WorkspaceModel
25+{
26+ Q_OBJECT
27+public:
28+ static WorkspaceManager* instance();
29+
30+private:
31+ WorkspaceManager();
32+
33+public Q_SLOTS:
34+ Workspace* createWorkspace();
35+ void destroyWorkspace(Workspace* workspace);
36+
37+private:
38+ QVector<Workspace*> m_allWorkspaces;
39+};
40+
41+#endif // WORKSPACEMANAGER_H
plugins/WindowManager/WorkspaceModel.cppnew file+90
@@ -0,0 +1,90 @@
1+/*
2+ * Copyright (C) 2017 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 "WorkspaceModel.h"
18+#include "Workspace.h"
19+
20+Q_LOGGING_CATEGORY(WORKSPACES, "Workspaces", QtInfoMsg)
21+
22+#define DEBUG_MSG qCDebug(WORKSPACES).nospace().noquote() << __func__
23+#define INFO_MSG qCInfo(WORKSPACES).nospace().noquote() << __func__
24+
25+WorkspaceModel::WorkspaceModel(QObject *parent)
26+ : QAbstractListModel(parent)
27+{
28+}
29+
30+void WorkspaceModel::append(Workspace *workspace)
31+{
32+ insert(m_workspaces.count(), workspace);
33+}
34+
35+void WorkspaceModel::insert(int index, Workspace *workspace)
36+{
37+ beginInsertRows(QModelIndex(), index, index);
38+ m_workspaces.append(workspace);
39+ endInsertRows();
40+ Q_EMIT countChanged();
41+}
42+
43+void WorkspaceModel::remove(Workspace *workspace)
44+{
45+ int index = m_workspaces.indexOf(workspace);
46+ if (index < 0) return;
47+
48+ beginRemoveRows(QModelIndex(), index, index);
49+ m_workspaces.removeAt(index);
50+ endRemoveRows();
51+ Q_EMIT countChanged();
52+}
53+
54+void WorkspaceModel::move(int from, int to)
55+{
56+ if (from == to) return;
57+ DEBUG_MSG << " from=" << from << " to=" << to;
58+
59+ if (from >= 0 && from < m_workspaces.size() && to >= 0 && to < m_workspaces.size()) {
60+ QModelIndex parent;
61+
62+ beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
63+#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
64+ const auto &window = m_windowModel.takeAt(from);
65+ m_workspaces.insert(to, window);
66+#else
67+ m_workspaces.move(from, to);
68+#endif
69+ endMoveRows();
70+ Q_EMIT countChanged();
71+ }
72+}
73+
74+int WorkspaceModel::rowCount(const QModelIndex &) const
75+{
76+ return m_workspaces.count();
77+}
78+
79+QVariant WorkspaceModel::data(const QModelIndex &index, int role) const
80+{
81+ if (index.row() < 0 || index.row() >= m_workspaces.size())
82+ return QVariant();
83+
84+ if (role == WorkspaceRole) {
85+ Workspace *workspace = m_workspaces.at(index.row());
86+ return QVariant::fromValue(workspace);
87+ } else {
88+ return QVariant();
89+ }
90+}
plugins/WindowManager/WorkspaceModel.hnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2017 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 WORKSPACEMODEL_H
18+#define WORKSPACEMODEL_H
19+
20+#include <QAbstractListModel>
21+#include <QLoggingCategory>
22+
23+Q_DECLARE_LOGGING_CATEGORY(WORKSPACES)
24+
25+class Workspace;
26+
27+class WorkspaceModel : public QAbstractListModel
28+{
29+ Q_OBJECT
30+ Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
31+public:
32+ /**
33+ * @brief The Roles supported by the model
34+ *
35+ * WorkspaceRole - A workspace.
36+ */
37+ enum Roles {
38+ WorkspaceRole = Qt::UserRole
39+ };
40+
41+ explicit WorkspaceModel(QObject *parent = 0);
42+
43+ void append(Workspace* workspace);
44+ void insert(int index, Workspace* workspace);
45+ void remove(Workspace* workspace);
46+ void move(int from, int to);
47+
48+ // From QAbstractItemModel
49+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
50+ QVariant data(const QModelIndex& index, int role) const override;
51+ QHash<int, QByteArray> roleNames() const override {
52+ QHash<int, QByteArray> roleNames { {WorkspaceRole, "workspace"} };
53+ return roleNames;
54+ }
55+
56+Q_SIGNALS:
57+ void countChanged();
58+
59+protected:
60+ QVector<Workspace*> m_workspaces;
61+};
62+
63+#endif // WORKSPACEMODEL_H
tests/mocks/WindowManager/CMakeLists.txt+3
@@ -10,6 +10,9 @@ include_directories(
1010set(WINDOWMANAGER_SRC
1111 ${CMAKE_SOURCE_DIR}/plugins/WindowManager/TopLevelWindowModel.cpp
1212 ${CMAKE_SOURCE_DIR}/plugins/WindowManager/Window.cpp
13+ ${CMAKE_SOURCE_DIR}/plugins/WindowManager/Workspace.cpp
14+ ${CMAKE_SOURCE_DIR}/plugins/WindowManager/WorkspaceManager.cpp
15+ ${CMAKE_SOURCE_DIR}/plugins/WindowManager/WorkspaceModel.cpp
1316 WindowManagerPlugin.cpp
1417 Screens.cpp
1518 Screen.cpp
tests/mocks/WindowManager/Screen.cpp+6
@@ -15,9 +15,15 @@
1515 */
1616
1717#include "Screen.h"
18+#include "WorkspaceModel.h"
19+#include "WorkspaceManager.h"
20+#include "Workspace.h"
1821
1922Screen::Screen()
23+ : m_workspaces(new WorkspaceModel)
2024{
25+ WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
26+ WorkspaceManager::instance()->createWorkspace()->assign(m_workspaces.data());
2127}
2228
2329QQmlListProperty<qtmir::ScreenMode> Screen::availableModes()
tests/mocks/WindowManager/Screen.h+9−3
@@ -1,12 +1,15 @@
1−#ifndef SCREEN_H
2−#define SCREEN_H
1+#ifndef MOCK_SCREEN_H
2+#define MOCK_SCREEN_H
33
44#include <qtmir/screen.h>
55#include <QScopedPointer>
66
7+class WorkspaceModel;
8+
79class Screen : public qtmir::Screen
810{
911 Q_OBJECT
12+ Q_PROPERTY(WorkspaceModel* workspaces READ workspaces CONSTANT)
1013
1114public:
1215 Screen();
@@ -31,6 +34,8 @@ public:
3134 qtmir::ScreenConfiguration *beginConfiguration() const override;
3235 bool applyConfiguration(qtmir::ScreenConfiguration *configuration) override;
3336
37+ WorkspaceModel* workspaces() const { return m_workspaces.data(); }
38+
3439public:
3540 qtmir::OutputId m_id{0};
3641 bool m_active{false};
@@ -45,6 +50,7 @@ public:
4550 uint m_currentModeIndex{0};
4651 QList<qtmir::ScreenMode*> m_sizes;
4752 QSizeF m_physicalSize;
53+ const QScopedPointer<WorkspaceModel> m_workspaces;
4854};
4955
50−#endif // SCREEN_H
56+#endif // MOCK_SCREEN_H
tests/mocks/WindowManager/WindowManagerPlugin.cpp+14−2
@@ -16,14 +16,23 @@
1616
1717#include "WindowManagerPlugin.h"
1818
19−#include "TopLevelWindowModel.h"
20−#include "Window.h"
2119#include "Screens.h"
2220#include "Screen.h"
2321#include "ScreenWindow.h"
22+#include "TopLevelWindowModel.h"
23+#include "Window.h"
24+#include "WorkspaceManager.h"
25+#include "Workspace.h"
26+#include "WorkspaceModel.h"
2427
2528#include <QtQml>
2629
30+static QObject *workspace_manager(QQmlEngine *engine, QJSEngine *scriptEngine)
31+{
32+ Q_UNUSED(engine)
33+ Q_UNUSED(scriptEngine)
34+ return WorkspaceManager::instance();
35+}
2736QObject* screensSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
2837 Q_UNUSED(engine);
2938 Q_UNUSED(scriptEngine);
@@ -33,10 +42,13 @@ QObject* screensSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3342void WindowManagerPlugin::registerTypes(const char *uri)
3443{
3544 qmlRegisterType<TopLevelWindowModel>(uri, 1, 0, "TopLevelWindowModel");
45+ qmlRegisterSingletonType<WorkspaceManager>(uri, 1, 0, "WorkspaceManager", workspace_manager);
46+ qmlRegisterUncreatableType<WorkspaceModel>(uri, 1, 0, "WorkspaceModel", "Not a creatable type");
3647 qmlRegisterSingletonType<Screens>(uri, 1, 0, "Screens", screensSingleton);
3748 qmlRegisterUncreatableType<qtmir::ScreenMode>(uri, 1, 0, "ScreenMode", "ScreenMode is not creatable.");
3849
3950 qRegisterMetaType<Window*>("Window*");
51+ qRegisterMetaType<Workspace*>("Workspace*");
4052
4153 qRegisterMetaType<QAbstractListModel*>("QAbstractListModel*");
4254 qRegisterMetaType<Screen*>("Screen*");