diff --git a/containments/taskpanel/CMakeLists.txt b/containments/taskpanel/CMakeLists.txt index 0cf2b309..499ce34a 100644 --- a/containments/taskpanel/CMakeLists.txt +++ b/containments/taskpanel/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries(plasma_containment_phone_taskpanel Qt5::DBus KF5::Plasma Qt5::Qml + Qt5::Quick KF5::I18n KF5::Service KF5::WaylandClient diff --git a/containments/taskpanel/package/contents/ui/Task.qml b/containments/taskpanel/package/contents/ui/Task.qml index dd62a86f..3f8b844a 100644 --- a/containments/taskpanel/package/contents/ui/Task.qml +++ b/containments/taskpanel/package/contents/ui/Task.qml @@ -28,6 +28,23 @@ Item { id: delegate width: window.width/2 height: window.height/2 + + //Workaround + property bool active: model.IsActive + onActiveChanged: { + if (model.IsActive) { + window.currentTaskIndex = index + } + } + + Connections { + target: tasksView + onContentYChanged: { + var pos = delegate.mapToItem(tasksView, 0, 0); + plasmoid.nativeInterface.setTaskGeometry(filteredWindowModel.mapRowToSource(model.index), pos.x, pos.y, delegate.width, delegate.height); + } + } + Item { anchors { fill: parent diff --git a/containments/taskpanel/package/contents/ui/TaskSwitcher.qml b/containments/taskpanel/package/contents/ui/TaskSwitcher.qml index 5b41dc16..07c4f3f2 100644 --- a/containments/taskpanel/package/contents/ui/TaskSwitcher.qml +++ b/containments/taskpanel/package/contents/ui/TaskSwitcher.qml @@ -33,6 +33,7 @@ FullScreenPanel { property int offset: 0 property int overShoot: units.gridUnit * 2 property int tasksCount: filteredWindowModel.count + property int currentTaskIndex: -1 color: Qt.rgba(0, 0, 0, 0.6 * Math.min( (Math.min(tasksView.contentY + tasksView.height, tasksView.height) / tasksView.height), @@ -49,6 +50,7 @@ FullScreenPanel { scrollAnim.from = tasksView.contentY; scrollAnim.to = 0; scrollAnim.running = true; + setSingleActiveWindow(-1); } function hide() { scrollAnim.from = tasksView.contentY; @@ -60,6 +62,24 @@ FullScreenPanel { scrollAnim.running = true; } + function setSingleActiveWindow(id) { + var task; + for (var i = 0; i < filteredWindowModel.count; ++i) { + task = filteredWindowModel.get(i); + + if (i == id && task.IsMinimized) { + plasmoid.nativeInterface.windowModel.requestToggleMinimized(filteredWindowModel.mapRowToSource(i)); + } else if (i != id && !task.IsMinimized) { + plasmoid.nativeInterface.windowModel.requestToggleMinimized(filteredWindowModel.mapRowToSource(i)); + } + } + return; + if (id >= 0) { + plasmoid.nativeInterface.windowModel.requestActivate(filteredWindowModel.mapRowToSource(id)); + } + currentTaskIndex = id; + } + onOffsetChanged: tasksView.contentY = offset SequentialAnimation { @@ -84,6 +104,7 @@ FullScreenPanel { } } } + GridView { id: tasksView width: window.width @@ -163,4 +184,27 @@ FullScreenPanel { } } } + + Rectangle { + color: theme.textColor + anchors { + fill: showDesktopButton + margins: -showDesktopButton.width/4 + } + radius: width + } + Button { + id: showDesktopButton + height: units.iconSizes.medium + width: height + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + } + iconSource: "go-home" + onClicked: { + window.hide(); + } + } + Component.onCompleted: plasmoid.nativeInterface.panel = window; } diff --git a/containments/taskpanel/package/contents/ui/main.qml b/containments/taskpanel/package/contents/ui/main.qml index d0330ac8..a8c0568c 100644 --- a/containments/taskpanel/package/contents/ui/main.qml +++ b/containments/taskpanel/package/contents/ui/main.qml @@ -58,6 +58,7 @@ PlasmaCore.ColorScope { if (taskSwitcher.visibility == Window.Hidden && taskSwitcher.offset > -taskSwitcher.height + units.gridUnit && taskSwitcher.tasksCount) { taskSwitcher.visible = true; } + taskSwitcher.setSingleActiveWindow(-1); } onReleased: { if (taskSwitcher.visibility == Window.Hidden) { @@ -67,6 +68,7 @@ PlasmaCore.ColorScope { taskSwitcher.show(); } else { taskSwitcher.hide(); + taskSwitcher.setSingleActiveWindow(taskSwitcher.currentTaskIndex); } } @@ -95,13 +97,17 @@ PlasmaCore.ColorScope { anchors.horizontalCenter: parent.horizontalCenter iconSource: "go-home" checkable: true - onCheckedChanged: {print (checked) - plasmoid.nativeInterface.showDesktop = checked; + onCheckedChanged: { + if (checked) { + root.taskSwitcher.setSingleActiveWindow(-1); + } else { + root.taskSwitcher.setSingleActiveWindow(Math.max(0, root.taskSwitcher.currentTaskIndex)); + } } Connections { - target: plasmoid.nativeInterface - onShowingDesktopChanged: { - showDesktopButton.checked = plasmoid.nativeInterface.showDesktop; + target: root.taskSwitcher + onCurrentTaskIndexChanged: { + showDesktopButton.checked = root.taskSwitcher.currentTaskIndex >= 0 } } } diff --git a/containments/taskpanel/taskpanel.cpp b/containments/taskpanel/taskpanel.cpp index 9ffd3da7..21a0de09 100644 --- a/containments/taskpanel/taskpanel.cpp +++ b/containments/taskpanel/taskpanel.cpp @@ -21,13 +21,17 @@ #include #include +#include +#include #include #include #include #include +#include #include +#include static const QString s_kwinService = QStringLiteral("org.kde.KWin"); @@ -88,6 +92,21 @@ void TaskPanel::initWayland() }); } ); + connect(registry, &Registry::plasmaShellAnnounced, this, + [this, registry] (quint32 name, quint32 version) { + + m_shellInterface = registry->createPlasmaShell(name, version, this); + + if (!m_panel) { + return; + } + Surface *s = Surface::fromWindow(m_panel); + if (!s) { + return; + } + m_shellSurface = m_shellInterface->createSurface(s, this); + } + ); registry->setup(); } @@ -96,6 +115,32 @@ QAbstractItemModel *TaskPanel::windowModel() const return m_windowModel; } +QWindow *TaskPanel::panel() +{ + return m_panel; +} + +void TaskPanel::setPanel(QWindow *panel) +{ + using namespace KWayland::Client; + if (panel == m_panel) { + return; + } + + m_panel = panel; + emit panelChanged(); + + if (!m_shellSurface) { + return; + } + Surface *s = Surface::fromWindow(panel); + if (!s) { + return; + } + + m_shellSurface = m_shellInterface->createSurface(s, this); +} + void TaskPanel::updateActiveWindow() { if (!m_windowManagement) { @@ -118,6 +163,23 @@ void TaskPanel::closeActiveWindow() } } +void TaskPanel::setTaskGeometry(int row, int x, int y, int width, int height) +{ + using namespace KWayland::Client; + if (!m_shellSurface) { + if (!m_shellInterface || !m_panel || !m_panel->isVisible()) { + return; + } + m_surface = Surface::fromWindow(m_panel); + if (!m_surface) { + return; + } + m_shellSurface = m_shellInterface->createSurface(m_surface, this); + } + + m_windowModel->setMinimizedGeometry(row, m_surface, QRect(x, y, width, height)); +} + K_EXPORT_PLASMA_APPLET_WITH_JSON(taskpanel, TaskPanel, "metadata.json") #include "taskpanel.moc" diff --git a/containments/taskpanel/taskpanel.h b/containments/taskpanel/taskpanel.h index 8a701a05..ff3548a5 100644 --- a/containments/taskpanel/taskpanel.h +++ b/containments/taskpanel/taskpanel.h @@ -32,6 +32,9 @@ namespace Client class PlasmaWindowManagement; class PlasmaWindow; class PlasmaWindowModel; +class PlasmaShell; +class PlasmaShellSurface; +class Surface; } } @@ -41,6 +44,7 @@ class TaskPanel : public Plasma::Containment Q_PROPERTY(QAbstractItemModel* windowModel READ windowModel NOTIFY windowModelChanged) Q_PROPERTY(bool showDesktop READ isShowingDesktop WRITE requestShowingDesktop NOTIFY showingDesktopChanged) Q_PROPERTY(bool hasCloseableActiveWindow READ hasCloseableActiveWindow NOTIFY hasCloseableActiveWindowChanged) + Q_PROPERTY(QWindow *panel READ panel WRITE setPanel NOTIFY panelChanged) public: TaskPanel( QObject *parent, const QVariantList &args ); @@ -48,6 +52,9 @@ public: QAbstractItemModel *windowModel() const; + QWindow *panel(); + void setPanel(QWindow *panel); + Q_INVOKABLE void closeActiveWindow(); bool isShowingDesktop() const { @@ -57,16 +64,23 @@ public: bool hasCloseableActiveWindow() const; + Q_INVOKABLE void setTaskGeometry(int row, int x, int y, int width, int height); + Q_SIGNALS: void windowModelChanged(); void showingDesktopChanged(bool); void hasCloseableActiveWindowChanged(); + void panelChanged(); private: void initWayland(); void updateActiveWindow(); bool m_showingDesktop; - KWayland::Client::PlasmaWindowManagement *m_windowManagement; + QWindow *m_panel = nullptr; + KWayland::Client::PlasmaShellSurface *m_shellSurface = nullptr; + KWayland::Client::Surface *m_surface = nullptr; + KWayland::Client::PlasmaShell *m_shellInterface = nullptr; + KWayland::Client::PlasmaWindowManagement *m_windowManagement = nullptr; KWayland::Client::PlasmaWindowModel *m_windowModel = nullptr; KWayland::Client::PlasmaWindow *m_activeWindow = nullptr; };