mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-06-11 00:47:22 +00:00
Track KWin Overview through the activeEffects DBus property and expose the state to Folio QML. Hide the workspace frame, dock overlay, and in-containment favourites scrim while Overview is active so the effect does not show Shift shell chrome in its desktop view. Set the state before invoking the Overview shortcut from Folio so the chrome is already gone when KWin starts composing the effect. The convergence dock invariant now guards both the hide rules and this ordering.
241 lines
7.3 KiB
C++
241 lines
7.3 KiB
C++
// SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
|
// SPDX-FileCopyrightText: 2022-2023 Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "homescreen.h"
|
|
|
|
#include <virtualdesktopinfo.h>
|
|
|
|
#include <KWindowSystem>
|
|
|
|
#include <QDBusConnection>
|
|
#include <QDBusInterface>
|
|
#include <QDBusMessage>
|
|
#include <QDBusReply>
|
|
#include <QDBusVariant>
|
|
#include <QDebug>
|
|
#include <QQmlEngine>
|
|
#include <QQmlExtensionPlugin>
|
|
#include <QQuickItem>
|
|
#include <QTimer>
|
|
|
|
K_PLUGIN_CLASS_WITH_JSON(HomeScreen, "metadata.json")
|
|
|
|
namespace
|
|
{
|
|
|
|
const QString s_kwinService = QStringLiteral("org.kde.KWin");
|
|
const QString s_kwinEffectsPath = QStringLiteral("/Effects");
|
|
const QString s_kwinEffectsInterface = QStringLiteral("org.kde.kwin.Effects");
|
|
const QString s_dbusPropertiesInterface = QStringLiteral("org.freedesktop.DBus.Properties");
|
|
|
|
QStringList effectListFromVariant(const QVariant &value)
|
|
{
|
|
QVariant effectValue = value;
|
|
if (effectValue.canConvert<QDBusVariant>()) {
|
|
effectValue = effectValue.value<QDBusVariant>().variant();
|
|
}
|
|
|
|
if (effectValue.canConvert<QStringList>()) {
|
|
return effectValue.toStringList();
|
|
}
|
|
|
|
QStringList effects;
|
|
const QVariantList effectList = effectValue.toList();
|
|
effects.reserve(effectList.size());
|
|
for (const QVariant &effect : effectList) {
|
|
effects.append(effect.toString());
|
|
}
|
|
return effects;
|
|
}
|
|
|
|
}
|
|
|
|
HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
|
|
: Plasma::Containment{parent, data, args}
|
|
, m_folioSettings{new FolioSettings{this}}
|
|
, m_homeScreenState{new HomeScreenState{this}}
|
|
, m_widgetsManager{new WidgetsManager{this}}
|
|
, m_applicationListModel{new ApplicationListModel{this}}
|
|
, m_applicationListSearchModel{new ApplicationListSearchModel{this, m_applicationListModel}}
|
|
, m_favouritesModel{new FavouritesModel{this}}
|
|
, m_pageListModel{new PageListModel{this}}
|
|
{
|
|
// HomeScreenState init() has dependencies on other objects
|
|
m_homeScreenState->init();
|
|
|
|
setHasConfigurationInterface(true);
|
|
|
|
connect(KWindowSystem::self(), &KWindowSystem::showingDesktopChanged, this, &HomeScreen::showingDesktopChanged);
|
|
|
|
updateOverviewActive();
|
|
QDBusConnection::sessionBus().connect(s_kwinService,
|
|
s_kwinEffectsPath,
|
|
s_dbusPropertiesInterface,
|
|
QStringLiteral("PropertiesChanged"),
|
|
this,
|
|
SLOT(onOverviewEffectsChanged(QString, QVariantMap, QStringList)));
|
|
|
|
auto overviewRefreshTimer = new QTimer(this);
|
|
overviewRefreshTimer->setInterval(250);
|
|
overviewRefreshTimer->setTimerType(Qt::CoarseTimer);
|
|
connect(overviewRefreshTimer, &QTimer::timeout, this, &HomeScreen::updateOverviewActive);
|
|
overviewRefreshTimer->start();
|
|
|
|
connect(this, &Plasma::Containment::appletAdded, this, &HomeScreen::onAppletAdded);
|
|
connect(this, &Plasma::Containment::appletAboutToBeRemoved, this, &HomeScreen::onAppletAboutToBeRemoved);
|
|
}
|
|
|
|
HomeScreen::~HomeScreen() = default;
|
|
|
|
void HomeScreen::configChanged()
|
|
{
|
|
Plasma::Containment::configChanged();
|
|
}
|
|
|
|
void HomeScreen::onAppletAdded(Plasma::Applet *applet, const QRectF &geometryHint)
|
|
{
|
|
Q_UNUSED(geometryHint)
|
|
widgetsManager()->addWidget(applet);
|
|
}
|
|
|
|
void HomeScreen::onAppletAboutToBeRemoved(Plasma::Applet *applet)
|
|
{
|
|
widgetsManager()->removeWidget(applet);
|
|
}
|
|
|
|
FolioSettings *HomeScreen::folioSettings()
|
|
{
|
|
return m_folioSettings;
|
|
}
|
|
|
|
HomeScreenState *HomeScreen::homeScreenState()
|
|
{
|
|
return m_homeScreenState;
|
|
}
|
|
|
|
WidgetsManager *HomeScreen::widgetsManager()
|
|
{
|
|
return m_widgetsManager;
|
|
}
|
|
|
|
ApplicationListModel *HomeScreen::applicationListModel()
|
|
{
|
|
return m_applicationListModel;
|
|
}
|
|
|
|
ApplicationListSearchModel *HomeScreen::applicationListSearchModel()
|
|
{
|
|
return m_applicationListSearchModel;
|
|
}
|
|
|
|
FavouritesModel *HomeScreen::favouritesModel()
|
|
{
|
|
return m_favouritesModel;
|
|
}
|
|
|
|
PageListModel *HomeScreen::pageListModel()
|
|
{
|
|
return m_pageListModel;
|
|
}
|
|
|
|
bool HomeScreen::overviewActive() const
|
|
{
|
|
return m_overviewActive;
|
|
}
|
|
|
|
void HomeScreen::setOverviewActive(bool overviewActive)
|
|
{
|
|
if (m_overviewActive == overviewActive) {
|
|
return;
|
|
}
|
|
|
|
m_overviewActive = overviewActive;
|
|
Q_EMIT overviewActiveChanged();
|
|
}
|
|
|
|
void HomeScreen::updateOverviewActive()
|
|
{
|
|
QDBusInterface propIface(s_kwinService, s_kwinEffectsPath, s_dbusPropertiesInterface, QDBusConnection::sessionBus());
|
|
if (!propIface.isValid()) {
|
|
setOverviewActive(false);
|
|
return;
|
|
}
|
|
|
|
QDBusReply<QDBusVariant> activeEffectsReply = propIface.call(QStringLiteral("Get"), s_kwinEffectsInterface, QStringLiteral("activeEffects"));
|
|
if (!activeEffectsReply.isValid()) {
|
|
setOverviewActive(false);
|
|
return;
|
|
}
|
|
|
|
setOverviewActive(effectListFromVariant(activeEffectsReply.value().variant()).contains(QStringLiteral("overview")));
|
|
}
|
|
|
|
void HomeScreen::onOverviewEffectsChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated)
|
|
{
|
|
if (interface != s_kwinEffectsInterface) {
|
|
return;
|
|
}
|
|
|
|
if (changed.contains(QStringLiteral("activeEffects"))) {
|
|
setOverviewActive(effectListFromVariant(changed.value(QStringLiteral("activeEffects"))).contains(QStringLiteral("overview")));
|
|
return;
|
|
}
|
|
|
|
if (invalidated.contains(QStringLiteral("activeEffects"))) {
|
|
updateOverviewActive();
|
|
}
|
|
}
|
|
|
|
void HomeScreen::triggerOverview()
|
|
{
|
|
setOverviewActive(true);
|
|
|
|
QDBusMessage message = QDBusMessage::createMethodCall("org.kde.kglobalaccel", "/component/kwin", "org.kde.kglobalaccel.Component", "invokeShortcut");
|
|
message.setArguments({QStringLiteral("Overview")});
|
|
QDBusConnection::sessionBus().send(message);
|
|
}
|
|
|
|
void HomeScreen::triggerMinimizeAll() const
|
|
{
|
|
QDBusMessage message = QDBusMessage::createMethodCall("org.kde.kglobalaccel", "/component/kwin", "org.kde.kglobalaccel.Component", "invokeShortcut");
|
|
message.setArguments({QStringLiteral("MinimizeAll")});
|
|
QDBusConnection::sessionBus().send(message);
|
|
}
|
|
|
|
void HomeScreen::activateVirtualDesktop(const QVariant &desktop) const
|
|
{
|
|
if (!desktop.isValid() || desktop.toString().isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
TaskManager::VirtualDesktopInfo virtualDesktopInfo;
|
|
virtualDesktopInfo.requestActivate(desktop);
|
|
}
|
|
|
|
void HomeScreen::createVirtualDesktop() const
|
|
{
|
|
TaskManager::VirtualDesktopInfo virtualDesktopInfo;
|
|
virtualDesktopInfo.requestCreateDesktop(virtualDesktopInfo.numberOfDesktops());
|
|
}
|
|
|
|
void HomeScreen::removeLastVirtualDesktop() const
|
|
{
|
|
TaskManager::VirtualDesktopInfo virtualDesktopInfo;
|
|
if (virtualDesktopInfo.numberOfDesktops() <= 1) {
|
|
return;
|
|
}
|
|
|
|
virtualDesktopInfo.requestRemoveDesktop(virtualDesktopInfo.numberOfDesktops() - 1);
|
|
}
|
|
|
|
void HomeScreen::emptyTrash() const
|
|
{
|
|
QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kio.trash"),
|
|
QStringLiteral("/trash"),
|
|
QStringLiteral("org.kde.KIO.Trash"),
|
|
QStringLiteral("emptyTrash"));
|
|
QDBusConnection::sessionBus().send(message);
|
|
}
|
|
|
|
#include "homescreen.moc"
|