2022-06-17 04:48:53 +00:00
|
|
|
// SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
2023-10-22 03:59:27 +00:00
|
|
|
// SPDX-FileCopyrightText: 2022-2023 Devin Lin <devin@kde.org>
|
2022-06-17 04:48:53 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2015-05-14 16:05:01 +00:00
|
|
|
|
|
|
|
|
#include "homescreen.h"
|
|
|
|
|
|
2026-04-29 10:10:31 +00:00
|
|
|
#include <virtualdesktopinfo.h>
|
|
|
|
|
|
2021-10-16 03:17:32 +00:00
|
|
|
#include <KWindowSystem>
|
2022-06-17 04:48:53 +00:00
|
|
|
|
2026-04-09 08:15:14 +00:00
|
|
|
#include <QDBusConnection>
|
2026-05-23 13:33:23 +00:00
|
|
|
#include <QDBusInterface>
|
2026-04-09 08:15:14 +00:00
|
|
|
#include <QDBusMessage>
|
2026-05-23 13:33:23 +00:00
|
|
|
#include <QDBusReply>
|
|
|
|
|
#include <QDBusVariant>
|
2015-05-14 16:05:01 +00:00
|
|
|
#include <QDebug>
|
2023-10-22 03:59:27 +00:00
|
|
|
#include <QQmlEngine>
|
|
|
|
|
#include <QQmlExtensionPlugin>
|
2019-09-04 16:39:31 +00:00
|
|
|
#include <QQuickItem>
|
2026-05-23 13:33:23 +00:00
|
|
|
#include <QTimer>
|
2015-05-14 16:05:01 +00:00
|
|
|
|
2025-07-16 17:02:18 +00:00
|
|
|
K_PLUGIN_CLASS_WITH_JSON(HomeScreen, "metadata.json")
|
|
|
|
|
|
2026-05-23 13:33:23 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-24 11:44:41 +00:00
|
|
|
HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
|
2022-06-17 04:48:53 +00:00
|
|
|
: Plasma::Containment{parent, data, args}
|
2024-06-21 04:42:14 +00:00
|
|
|
, m_folioSettings{new FolioSettings{this}}
|
|
|
|
|
, m_homeScreenState{new HomeScreenState{this}}
|
|
|
|
|
, m_widgetsManager{new WidgetsManager{this}}
|
|
|
|
|
, m_applicationListModel{new ApplicationListModel{this}}
|
2024-07-01 16:04:32 +00:00
|
|
|
, m_applicationListSearchModel{new ApplicationListSearchModel{this, m_applicationListModel}}
|
2024-06-21 04:42:14 +00:00
|
|
|
, m_favouritesModel{new FavouritesModel{this}}
|
|
|
|
|
, m_pageListModel{new PageListModel{this}}
|
2015-05-14 16:05:01 +00:00
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
// HomeScreenState init() has dependencies on other objects
|
|
|
|
|
m_homeScreenState->init();
|
2023-10-22 03:59:27 +00:00
|
|
|
|
2024-06-21 04:42:14 +00:00
|
|
|
setHasConfigurationInterface(true);
|
|
|
|
|
|
2021-10-16 03:17:32 +00:00
|
|
|
connect(KWindowSystem::self(), &KWindowSystem::showingDesktopChanged, this, &HomeScreen::showingDesktopChanged);
|
2023-11-05 05:14:39 +00:00
|
|
|
|
2026-05-23 13:33:23 +00:00
|
|
|
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();
|
|
|
|
|
|
2023-11-05 05:14:39 +00:00
|
|
|
connect(this, &Plasma::Containment::appletAdded, this, &HomeScreen::onAppletAdded);
|
|
|
|
|
connect(this, &Plasma::Containment::appletAboutToBeRemoved, this, &HomeScreen::onAppletAboutToBeRemoved);
|
2015-05-14 16:05:01 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-20 00:08:59 +00:00
|
|
|
HomeScreen::~HomeScreen() = default;
|
2015-05-14 16:05:01 +00:00
|
|
|
|
2019-09-16 17:13:52 +00:00
|
|
|
void HomeScreen::configChanged()
|
|
|
|
|
{
|
|
|
|
|
Plasma::Containment::configChanged();
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-05 05:14:39 +00:00
|
|
|
void HomeScreen::onAppletAdded(Plasma::Applet *applet, const QRectF &geometryHint)
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
Q_UNUSED(geometryHint)
|
|
|
|
|
widgetsManager()->addWidget(applet);
|
2023-11-05 05:14:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HomeScreen::onAppletAboutToBeRemoved(Plasma::Applet *applet)
|
|
|
|
|
{
|
2024-06-21 04:42:14 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-01 16:04:32 +00:00
|
|
|
ApplicationListSearchModel *HomeScreen::applicationListSearchModel()
|
|
|
|
|
{
|
|
|
|
|
return m_applicationListSearchModel;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-21 04:42:14 +00:00
|
|
|
FavouritesModel *HomeScreen::favouritesModel()
|
|
|
|
|
{
|
|
|
|
|
return m_favouritesModel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PageListModel *HomeScreen::pageListModel()
|
|
|
|
|
{
|
|
|
|
|
return m_pageListModel;
|
2023-11-05 05:14:39 +00:00
|
|
|
}
|
|
|
|
|
|
2026-05-23 13:33:23 +00:00
|
|
|
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)
|
2026-04-09 08:15:14 +00:00
|
|
|
{
|
2026-05-23 13:33:23 +00:00
|
|
|
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);
|
|
|
|
|
|
2026-04-09 08:15:14 +00:00
|
|
|
QDBusMessage message = QDBusMessage::createMethodCall("org.kde.kglobalaccel", "/component/kwin", "org.kde.kglobalaccel.Component", "invokeShortcut");
|
|
|
|
|
message.setArguments({QStringLiteral("Overview")});
|
|
|
|
|
QDBusConnection::sessionBus().send(message);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-09 08:47:41 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-29 10:10:31 +00:00
|
|
|
void HomeScreen::activateVirtualDesktop(const QVariant &desktop) const
|
|
|
|
|
{
|
|
|
|
|
if (!desktop.isValid() || desktop.toString().isEmpty()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskManager::VirtualDesktopInfo virtualDesktopInfo;
|
|
|
|
|
virtualDesktopInfo.requestActivate(desktop);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-09 08:48:52 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-01 10:48:49 +00:00
|
|
|
void HomeScreen::emptyTrash() const
|
|
|
|
|
{
|
|
|
|
|
QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kio.trash"),
|
2026-05-09 11:55:19 +00:00
|
|
|
QStringLiteral("/trash"),
|
2026-05-01 10:48:49 +00:00
|
|
|
QStringLiteral("org.kde.KIO.Trash"),
|
|
|
|
|
QStringLiteral("emptyTrash"));
|
|
|
|
|
QDBusConnection::sessionBus().send(message);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-14 16:05:01 +00:00
|
|
|
#include "homescreen.moc"
|