Commit c8c734fa authored by David Edmundson's avatar David Edmundson
Browse files

Port minimize all applet from it's own plugin to org.kde.TaskManager

Summary:
This reduces the code we have and implicitly fixes it under wayland.

Tracking of which windows are minimised by us is now done in JS, and
through use of model indexes instead of X window IDs, which wouldn't
really have worked under wayland.

Potentially we may have some minor behavioural differences on X with
regards to which windows are managed, as the old code did not skip those
with skip_taskmanager.

Requires a tiny patch in libtaskmanager to export persistentmodelindexes to
QML.

Test Plan:
Under wayland:
Had 3 windows, one minimised already
Clicked button. All minimised.
Clicked again, two restored

Reviewers: #plasma, anthonyfieroni

Reviewed By: anthonyfieroni

Subscribers: ngraham, anthonyfieroni, sebas, broulik, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D10019
parent 093241bf
add_definitions(-DTRANSLATION_DOMAIN="plasma_applet_org.kde.plasma.minimizeall")
set(minimizeall_SRCS
plugin/minimizeall.cpp
plugin/minimizeallplugin.cpp
)
add_library(minimizeallplugin SHARED ${minimizeall_SRCS})
target_link_libraries(minimizeallplugin
Qt5::Core
Qt5::Qml
Qt5::Quick
KF5::WindowSystem
)
install(TARGETS minimizeallplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/minimizeall)
install(FILES plugin/qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/minimizeall)
plasma_install_package(package org.kde.plasma.minimizeall)
/*
* Copyright 2015 Sebastian Kügler <sebas@kde.org>
* Copyright 2016 Anthony Fieroni <bvbfan@abv.bg>
* Copyright 2018 David Edmundson <davidedmundson@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -23,8 +24,7 @@ import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.private.minimizeall 1.0
import org.kde.taskmanager 0.1 as TaskManager
Item {
id: root
......@@ -42,18 +42,68 @@ Item {
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
Plasmoid.onActivated: toggleActive()
property bool active: false
property var minimizedClients: [] //list of persistentmodelindexes from task manager model of clients minimised by us
function activate() {
if (!minimizeall.active) {
minimizeall.minimizeAllWindows();
var clients = []
for (var i = 0 ; i < tasksModel.count; i++) {
var idx = tasksModel.makeModelIndex(i);
if (!tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) {
tasksModel.requestToggleMinimized(idx);
clients.push(tasksModel.makePersistentModelIndex(i));
}
}
root.minimizedClients = clients;
root.active = true;
}
function deactivate() {
root.active = false;
for (var i = 0 ; i < root.minimizedClients.length; i++) {
var idx = root.minimizedClients[i]
//client deleted, do nothing
if (!idx.valid) {
continue;
}
//if the user has restored it already, do nothing
if (!tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) {
continue;
}
tasksModel.requestToggleMinimized(idx);
}
root.minimizedClients = [];
}
function toggleActive() {
if (root.active) {
deactivate();
} else {
minimizeall.unminimizeAllWindows();
activate();
}
}
Plasmoid.onActivated: activate()
TaskManager.TasksModel {
id: tasksModel
sortMode: TaskManager.TasksModel.SortDisabled
groupMode: TaskManager.TasksModel.GroupDisabled
}
MinimizeAll {
id: minimizeall
Connections {
target: tasksModel
enabled: root.active
onDataChanged: {
for (var i = topLeft.row; i <= bottomRight.row ; i++) {
var idx = tasksModel.makeModelIndex(i);
if (!tasksModel.data(idx, TaskManager.AbstractTasksModel.IsMinimized)) {
deactivate();
}
}
}
onVirtualDesktopChanged: deactivate()
onActivityChanged: deactivate()
}
PlasmaCore.FrameSvgItem {
......@@ -80,7 +130,7 @@ Item {
}
return prefix;
}
opacity: minimizeall.active ? 1 : 0
opacity: root.active ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: units.shortDuration
......@@ -106,7 +156,7 @@ Item {
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: activate()
onClicked: root.toggleActive()
}
//also activate when dragging an item over the plasmoid so a user can easily drag data to the desktop
DropArea {
......@@ -116,7 +166,7 @@ Item {
Timer {
id: activateTimer
interval: 250 //to match TaskManager
onTriggered: activate()
onTriggered: toggleActive()
}
}
}
......
/*
* Copyright 2015 Sebastian Kügler <sebas@kde.org>
* Copyright 2016 Anthony Fieroni <bvbfan@abv.bg>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "minimizeall.h"
#include <KWindowSystem>
#include <QDebug>
#include <QTimer>
MinimizeAll::MinimizeAll()
{
m_active = false;
}
MinimizeAll::~MinimizeAll()
{
}
bool MinimizeAll::active() const
{
return m_active;
}
void MinimizeAll::minimizeAllWindows()
{
m_minimizedWindows.clear();
Q_FOREACH (auto wid, KWindowSystem::self()->stackingOrder()) {
if (match(wid, false)) {
m_minimizedWindows << wid;
KWindowSystem::self()->minimizeWindow(wid);
}
}
if (m_minimizedWindows.isEmpty()) {
return;
}
if (!m_active) {
m_active = true;
Q_EMIT activeChanged();
}
const auto connectionType = Qt::ConnectionType(Qt::UniqueConnection | Qt::QueuedConnection);
connect(KWindowSystem::self(), static_cast<void (KWindowSystem::*)(WId)>(&KWindowSystem::windowChanged),
this, [this](WId wid) { if (match(wid, false)) deactivate(false); }, connectionType);
connect(KWindowSystem::self(), &KWindowSystem::currentDesktopChanged,
this, [this]() { deactivate(false); }, connectionType);
connect(KWindowSystem::self(), &KWindowSystem::stackingOrderChanged,
this, [this]() { deactivate(false); }, connectionType);
}
void MinimizeAll::unminimizeAllWindows()
{
deactivate(true);
}
bool MinimizeAll::match(const WId& wid, bool includehidden) const
{
bool match = true;
KWindowInfo info(wid, NET::WMState | NET::WMWindowType | NET::WMDesktop);
if (!includehidden && info.hasState(NET::Hidden)) {
match = false;
} else if (info.windowType(NET::DesktopMask) == NET::Desktop) {
match = false;
} else if (info.windowType(NET::DockMask) == NET::Dock) {
match = false;
} else if (!info.isOnCurrentDesktop()) {
match = false;
}
return match;
}
void MinimizeAll::deactivate(bool unminimize)
{
if (m_active) {
disconnect(KWindowSystem::self(), nullptr, this, nullptr);
if (unminimize) {
Q_FOREACH (auto wid, m_minimizedWindows) {
if (match(wid)) {
KWindowSystem::self()->unminimizeWindow(wid);
}
}
}
m_active = false;
Q_EMIT activeChanged();
}
}
/*
* Copyright 2015 Sebastian Kügler <sebas@kde.org>
* Copyright 2016 Anthony Fieroni <bvbfan@abv.bg>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MINIMIZEALL_HEADER
#define MINIMIZEALL_HEADER
#include <QObject>
#include <KWindowSystem>
class MinimizeAll : public QObject
{
Q_OBJECT
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
public:
MinimizeAll();
~MinimizeAll() override;
Q_INVOKABLE void minimizeAllWindows();
Q_INVOKABLE void unminimizeAllWindows();
bool active() const;
public Q_SLOTS:
void deactivate(bool unminimize);
Q_SIGNALS:
void activeChanged();
private:
bool match(const WId &wid, bool includehidden = true) const;
QList<WId> m_minimizedWindows;
bool m_active;
};
#endif //MINIMIZEALL_HEADER
/*
* Copyright 2015 Sebastian Kügler <sebas@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "minimizeallplugin.h"
#include "minimizeall.h"
// Qt
#include <QQmlEngine>
void MinimizeAllPlugin::registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.plasma.private.minimizeall"));
qmlRegisterType<MinimizeAll>(uri, 1, 0, "MinimizeAll");
}
/*
* Copyright 2015 Sebastian Kügler <sebas@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MINIMIZEALLPLUGIN_H
#define MINIMIZEALLPLUGIN_H
#include <QObject>
#include <QQmlEngine>
#include <QQmlExtensionPlugin>
class MinimizeAllPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
void registerTypes(const char *uri) override;
};
#endif // MINIMIZEALLPLUGIN_H
module org.kde.plasma.private.minimizeall
plugin minimizeallplugin
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment