mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
homescreens/halcyon: Port to new model
This commit is contained in:
parent
b41e1f2b8a
commit
ef45546127
20 changed files with 854 additions and 74 deletions
|
|
@ -1,14 +1,9 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
||||
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
// SPDX-FileCopyrightText: 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
||||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Self
|
||||
#include "applicationlistmodel.h"
|
||||
|
||||
// Qt
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include <QModelIndex>
|
||||
|
|
@ -16,7 +11,6 @@
|
|||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
|
||||
// KDE
|
||||
#include <KApplicationTrader>
|
||||
#include <KConfigGroup>
|
||||
#include <KIO/ApplicationLauncherJob>
|
||||
|
|
@ -25,11 +19,6 @@
|
|||
#include <KSharedConfig>
|
||||
#include <KSycoca>
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/plasmawindowmanagement.h>
|
||||
#include <KWayland/Client/registry.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
ApplicationListModel::ApplicationListModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
|
|
@ -72,12 +61,6 @@ QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
|||
{ApplicationLocationRole, QByteArrayLiteral("applicationLocation")}};
|
||||
}
|
||||
|
||||
ApplicationListModel *ApplicationListModel::instance()
|
||||
{
|
||||
static ApplicationListModel *model = new ApplicationListModel;
|
||||
return model;
|
||||
}
|
||||
|
||||
void ApplicationListModel::sycocaDbChanged()
|
||||
{
|
||||
m_applicationList.clear();
|
||||
|
|
@ -232,19 +215,16 @@ void ApplicationListModel::setMinimizedDelegate(int row, QQuickItem *delegate)
|
|||
}
|
||||
|
||||
QWindow *delegateWindow = delegate->window();
|
||||
|
||||
if (!delegateWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace KWayland::Client;
|
||||
KWayland::Client::PlasmaWindow *window = m_applicationList[row].window;
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
Surface *surface = Surface::fromWindow(delegateWindow);
|
||||
|
||||
KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(delegateWindow);
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -261,19 +241,16 @@ void ApplicationListModel::unsetMinimizedDelegate(int row, QQuickItem *delegate)
|
|||
}
|
||||
|
||||
QWindow *delegateWindow = delegate->window();
|
||||
|
||||
if (!delegateWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace KWayland::Client;
|
||||
KWayland::Client::PlasmaWindow *window = m_applicationList[row].window;
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
Surface *surface = Surface::fromWindow(delegateWindow);
|
||||
|
||||
KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(delegateWindow);
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,19 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
||||
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
// SPDX-FileCopyrightText: 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
||||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
// Qt
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QQuickItem>
|
||||
#include <QSet>
|
||||
|
||||
class QString;
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Client
|
||||
{
|
||||
class PlasmaWindowManagement;
|
||||
class PlasmaWindow;
|
||||
}
|
||||
}
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/plasmawindowmanagement.h>
|
||||
#include <KWayland/Client/registry.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
/**
|
||||
* @short The base application list, used directly by the app drawer.
|
||||
|
|
@ -64,8 +54,6 @@ public:
|
|||
ApplicationListModel(QObject *parent = nullptr);
|
||||
~ApplicationListModel() override;
|
||||
|
||||
static ApplicationListModel *instance();
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
set(homescreen_SRCS
|
||||
homescreen.cpp
|
||||
application.cpp
|
||||
applicationfolder.cpp
|
||||
applicationlistmodel.cpp
|
||||
pinnedmodel.cpp
|
||||
windowlistener.cpp
|
||||
)
|
||||
|
||||
add_library(plasma_containment_phone_homescreen_halcyon MODULE ${homescreen_SRCS})
|
||||
|
|
|
|||
153
containments/homescreens/halcyon/application.cpp
Normal file
153
containments/homescreens/halcyon/application.cpp
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "application.h"
|
||||
#include "windowlistener.h"
|
||||
|
||||
#include <QQuickWindow>
|
||||
|
||||
#include <KIO/ApplicationLauncherJob>
|
||||
#include <KNotificationJobUiDelegate>
|
||||
#include <KService>
|
||||
|
||||
Application::Application(QObject *parent, KService::Ptr service)
|
||||
: QObject{parent}
|
||||
, m_running{false}
|
||||
, m_name{service->name()}
|
||||
, m_icon{service->icon()}
|
||||
, m_storageId{service->storageId()}
|
||||
{
|
||||
auto windows = WindowListener::instance()->windowsFromStorageId(m_storageId);
|
||||
if (windows.empty()) {
|
||||
m_window = nullptr;
|
||||
} else {
|
||||
m_window = windows[0];
|
||||
}
|
||||
|
||||
connect(WindowListener::instance(), &WindowListener::windowChanged, this, [this](QString storageId) {
|
||||
if (storageId == m_storageId) {
|
||||
auto windows = WindowListener::instance()->windowsFromStorageId(m_storageId);
|
||||
if (windows.empty()) {
|
||||
setWindow(nullptr);
|
||||
} else {
|
||||
setWindow(windows[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Application *Application::fromJson(QJsonObject &obj, QObject *parent)
|
||||
{
|
||||
QString storageId = obj[QStringLiteral("storageId")].toString();
|
||||
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
|
||||
return new Application(parent, service);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QJsonObject Application::toJson()
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj[QStringLiteral("type")] = "application";
|
||||
obj[QStringLiteral("storageId")] = m_storageId;
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool Application::running() const
|
||||
{
|
||||
return m_window != nullptr;
|
||||
}
|
||||
|
||||
QString Application::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
QString Application::icon() const
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
QString Application::storageId() const
|
||||
{
|
||||
return m_storageId;
|
||||
}
|
||||
|
||||
KWayland::Client::PlasmaWindow *Application::window() const
|
||||
{
|
||||
return m_window;
|
||||
}
|
||||
|
||||
void Application::setName(QString &name)
|
||||
{
|
||||
m_name = name;
|
||||
Q_EMIT nameChanged();
|
||||
}
|
||||
|
||||
void Application::setIcon(QString &icon)
|
||||
{
|
||||
m_icon = icon;
|
||||
Q_EMIT iconChanged();
|
||||
}
|
||||
|
||||
void Application::setStorageId(QString &storageId)
|
||||
{
|
||||
m_storageId = storageId;
|
||||
Q_EMIT storageIdChanged();
|
||||
}
|
||||
|
||||
void Application::setWindow(KWayland::Client::PlasmaWindow *window)
|
||||
{
|
||||
m_window = window;
|
||||
Q_EMIT windowChanged();
|
||||
}
|
||||
|
||||
void Application::runApplication()
|
||||
{
|
||||
if (m_window) {
|
||||
m_window->requestActivate();
|
||||
return;
|
||||
}
|
||||
|
||||
KService::Ptr service = KService::serviceByStorageId(m_storageId);
|
||||
KIO::ApplicationLauncherJob *job = new KIO::ApplicationLauncherJob(service);
|
||||
job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled));
|
||||
job->start();
|
||||
}
|
||||
|
||||
void Application::setMinimizedDelegate(QQuickItem *delegate)
|
||||
{
|
||||
QWindow *delegateWindow = delegate->window();
|
||||
if (!delegateWindow) {
|
||||
return;
|
||||
}
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
|
||||
KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(delegateWindow);
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
QRect rect = delegate->mapRectToScene(QRectF(0, 0, delegate->width(), delegate->height())).toRect();
|
||||
m_window->setMinimizedGeometry(surface, rect);
|
||||
}
|
||||
|
||||
void Application::unsetMinimizedDelegate(QQuickItem *delegate)
|
||||
{
|
||||
QWindow *delegateWindow = delegate->window();
|
||||
if (!delegateWindow) {
|
||||
return;
|
||||
}
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
|
||||
KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(delegateWindow);
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_window->unsetMinimizedGeometry(surface);
|
||||
}
|
||||
59
containments/homescreens/halcyon/application.h
Normal file
59
containments/homescreens/halcyon/application.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
#include <QQuickItem>
|
||||
#include <QString>
|
||||
|
||||
#include <KService>
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/plasmawindowmanagement.h>
|
||||
#include <KWayland/Client/registry.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
class Application : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool running READ running NOTIFY windowChanged)
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString icon READ icon NOTIFY iconChanged)
|
||||
Q_PROPERTY(QString storageId READ storageId NOTIFY storageIdChanged)
|
||||
|
||||
public:
|
||||
Application(QObject *parent = nullptr, KService::Ptr service = QExplicitlySharedDataPointer<KService>{nullptr});
|
||||
|
||||
static Application *fromJson(QJsonObject &obj, QObject *parent); // may return nullptr
|
||||
QJsonObject toJson();
|
||||
|
||||
bool running() const;
|
||||
QString name() const;
|
||||
QString icon() const;
|
||||
QString storageId() const;
|
||||
KWayland::Client::PlasmaWindow *window() const;
|
||||
|
||||
void setName(QString &name);
|
||||
void setIcon(QString &icon);
|
||||
void setStorageId(QString &storageId);
|
||||
void setWindow(KWayland::Client::PlasmaWindow *window);
|
||||
|
||||
Q_INVOKABLE void runApplication();
|
||||
Q_INVOKABLE void setMinimizedDelegate(QQuickItem *delegate);
|
||||
Q_INVOKABLE void unsetMinimizedDelegate(QQuickItem *delegate);
|
||||
|
||||
Q_SIGNALS:
|
||||
void nameChanged();
|
||||
void iconChanged();
|
||||
void storageIdChanged();
|
||||
void windowChanged();
|
||||
|
||||
private:
|
||||
bool m_running;
|
||||
QString m_name;
|
||||
QString m_icon;
|
||||
QString m_storageId;
|
||||
KWayland::Client::PlasmaWindow *m_window = nullptr;
|
||||
};
|
||||
64
containments/homescreens/halcyon/applicationfolder.cpp
Normal file
64
containments/homescreens/halcyon/applicationfolder.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "applicationfolder.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
ApplicationFolder::ApplicationFolder(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
ApplicationFolder *ApplicationFolder::fromJson(QJsonObject &obj, QObject *parent)
|
||||
{
|
||||
QString name = obj[QStringLiteral("name")].toString();
|
||||
QList<Application *> apps;
|
||||
for (auto storageId : obj[QStringLiteral("apps")].toArray()) {
|
||||
if (KService::Ptr service = KService::serviceByStorageId(storageId.toString())) {
|
||||
apps.append(new Application(parent, service));
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationFolder *folder = new ApplicationFolder(parent);
|
||||
folder->setName(name);
|
||||
folder->setApplications(apps);
|
||||
return folder;
|
||||
}
|
||||
|
||||
QJsonObject ApplicationFolder::toJson()
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj[QStringLiteral("type")] = "folder";
|
||||
obj[QStringLiteral("name")] = m_name;
|
||||
|
||||
QJsonArray arr;
|
||||
for (auto *application : m_applications) {
|
||||
arr.append(QJsonValue::fromVariant(application->storageId()));
|
||||
}
|
||||
|
||||
obj[QStringLiteral("apps")] = arr;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
QString ApplicationFolder::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void ApplicationFolder::setName(QString &name)
|
||||
{
|
||||
m_name = name;
|
||||
Q_EMIT nameChanged();
|
||||
}
|
||||
|
||||
QList<Application *> ApplicationFolder::applications()
|
||||
{
|
||||
return m_applications;
|
||||
}
|
||||
|
||||
void ApplicationFolder::setApplications(QList<Application *> applications)
|
||||
{
|
||||
m_applications = applications;
|
||||
Q_EMIT applicationsChanged();
|
||||
}
|
||||
43
containments/homescreens/halcyon/applicationfolder.h
Normal file
43
containments/homescreens/halcyon/applicationfolder.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "application.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#include <KService>
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/plasmawindowmanagement.h>
|
||||
#include <KWayland/Client/registry.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
class ApplicationFolder : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
Q_PROPERTY(QList<Application *> applications READ applications NOTIFY applicationsChanged)
|
||||
|
||||
public:
|
||||
ApplicationFolder(QObject *parent = nullptr);
|
||||
|
||||
static ApplicationFolder *fromJson(QJsonObject &obj, QObject *parent);
|
||||
QJsonObject toJson();
|
||||
|
||||
QString name() const;
|
||||
void setName(QString &name);
|
||||
|
||||
QList<Application *> applications();
|
||||
void setApplications(QList<Application *> applications);
|
||||
|
||||
Q_SIGNALS:
|
||||
void nameChanged();
|
||||
void applicationsChanged();
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QList<Application *> m_applications;
|
||||
};
|
||||
106
containments/homescreens/halcyon/applicationlistmodel.cpp
Normal file
106
containments/homescreens/halcyon/applicationlistmodel.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// SPDX-FileCopyrightText: 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
||||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "applicationlistmodel.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include <QModelIndex>
|
||||
#include <QProcess>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
|
||||
#include <KApplicationTrader>
|
||||
#include <KConfigGroup>
|
||||
#include <KIO/ApplicationLauncherJob>
|
||||
#include <KNotificationJobUiDelegate>
|
||||
#include <KService>
|
||||
#include <KSharedConfig>
|
||||
#include <KSycoca>
|
||||
|
||||
ApplicationListModel::ApplicationListModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
connect(KSycoca::self(), qOverload<const QStringList &>(&KSycoca::databaseChanged), this, &ApplicationListModel::sycocaDbChanged);
|
||||
#else
|
||||
connect(KSycoca::self(), &KSycoca::databaseChanged, this, &ApplicationListModel::sycocaDbChanged);
|
||||
#endif
|
||||
}
|
||||
|
||||
ApplicationListModel::~ApplicationListModel() = default;
|
||||
|
||||
QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
||||
{
|
||||
return {{ApplicationRole, QByteArrayLiteral("application")}};
|
||||
}
|
||||
|
||||
void ApplicationListModel::sycocaDbChanged()
|
||||
{
|
||||
m_applicationList.clear();
|
||||
loadApplications();
|
||||
}
|
||||
|
||||
void ApplicationListModel::loadApplications()
|
||||
{
|
||||
auto cfg = KSharedConfig::openConfig(QStringLiteral("applications-blacklistrc"));
|
||||
auto blgroup = KConfigGroup(cfg, QStringLiteral("Applications"));
|
||||
|
||||
const QStringList blacklist = blgroup.readEntry("blacklist", QStringList());
|
||||
|
||||
beginResetModel();
|
||||
|
||||
m_applicationList.clear();
|
||||
|
||||
QList<Application *> unorderedList;
|
||||
|
||||
auto filter = [blacklist](const KService::Ptr &service) -> bool {
|
||||
if (service->noDisplay()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!service->showOnCurrentPlatform()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blacklist.contains(service->desktopEntryName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const KService::List apps = KApplicationTrader::query(filter);
|
||||
|
||||
for (const KService::Ptr &service : apps) {
|
||||
Application *application = new Application{this, service};
|
||||
unorderedList.append(application);
|
||||
}
|
||||
|
||||
std::sort(unorderedList.begin(), unorderedList.end(), [](const Application *a1, const Application *a2) {
|
||||
return a1->name().compare(a2->name(), Qt::CaseInsensitive) < 0;
|
||||
});
|
||||
|
||||
m_applicationList << unorderedList;
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
return QVariant::fromValue(m_applicationList.at(index.row()));
|
||||
}
|
||||
|
||||
int ApplicationListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_applicationList.count();
|
||||
}
|
||||
42
containments/homescreens/halcyon/applicationlistmodel.h
Normal file
42
containments/homescreens/halcyon/applicationlistmodel.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// SPDX-FileCopyrightText: 2014 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
|
||||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "application.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QQuickItem>
|
||||
#include <QSet>
|
||||
|
||||
/**
|
||||
* @short The base application list, used directly by the app drawer.
|
||||
*/
|
||||
class ApplicationListModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles { ApplicationRole = Qt::UserRole + 1 };
|
||||
|
||||
ApplicationListModel(QObject *parent = nullptr);
|
||||
~ApplicationListModel() override;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Q_INVOKABLE void loadApplications();
|
||||
|
||||
public Q_SLOTS:
|
||||
void sycocaDbChanged();
|
||||
|
||||
Q_SIGNALS:
|
||||
void launchError(const QString &msg);
|
||||
|
||||
protected:
|
||||
QList<Application *> m_applicationList;
|
||||
};
|
||||
|
|
@ -1,2 +1,45 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "homescreen.h"
|
||||
#include "application.h"
|
||||
#include "applicationfolder.h"
|
||||
#include "pinnedmodel.h"
|
||||
#include "windowlistener.h"
|
||||
|
||||
#include <KWindowSystem>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QQuickItem>
|
||||
#include <QtQml>
|
||||
|
||||
HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
|
||||
: Plasma::Containment{parent, data, args}
|
||||
{
|
||||
setHasConfigurationInterface(true);
|
||||
|
||||
WindowListener::instance(); // ensure it is created
|
||||
|
||||
ApplicationListModel *applicationListModel = new ApplicationListModel{this};
|
||||
qmlRegisterSingletonType<ApplicationListModel>("org.kde.phone.homescreen.halcyon",
|
||||
1,
|
||||
0,
|
||||
"ApplicationListModel",
|
||||
[applicationListModel](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||
return applicationListModel;
|
||||
});
|
||||
|
||||
PinnedModel *pinnedModel = new PinnedModel{this, this};
|
||||
qmlRegisterSingletonType<PinnedModel>("org.kde.phone.homescreen.halcyon", 1, 0, "PinnedModel", [pinnedModel](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||
return pinnedModel;
|
||||
});
|
||||
|
||||
qmlRegisterType<Application>("org.kde.phone.homescreen.halcyon", 1, 0, "Application");
|
||||
qmlRegisterType<ApplicationFolder>("org.kde.phone.homescreen.halcyon", 1, 0, "ApplicationFolder");
|
||||
}
|
||||
|
||||
HomeScreen::~HomeScreen() = default;
|
||||
|
||||
K_PLUGIN_CLASS_WITH_JSON(HomeScreen, "metadata.json")
|
||||
|
||||
#include "homescreen.moc"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,17 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plasma/Containment>
|
||||
|
||||
#include <applicationlistmodel.h>
|
||||
|
||||
class HomeScreen : public Plasma::Containment
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HomeScreen(QObject *parent, const KPluginMetaData &data, const QVariantList &args);
|
||||
~HomeScreen() override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,12 +13,19 @@ import org.kde.kquickcontrolsaddons 2.0
|
|||
|
||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.halcyon 1.0 as Halcyon
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
MouseArea {
|
||||
id: delegate
|
||||
|
||||
property alias iconItem: icon
|
||||
property Halcyon.Application application: model.application
|
||||
|
||||
readonly property string applicationName: application ? application.name : ""
|
||||
readonly property string applicationStorageId: application ? application.storageId : ""
|
||||
readonly property string applicationIcon: application ? application.icon : ""
|
||||
|
||||
signal launch(int x, int y, var source, string title, string storageId)
|
||||
signal dragStarted(string imageSource, int x, int y, string mimeData)
|
||||
|
|
@ -33,8 +40,8 @@ MouseArea {
|
|||
Math.min(delegate.iconItem.width, delegate.iconItem.height));
|
||||
}
|
||||
|
||||
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||
MobileShell.ApplicationListModel.runApplication(storageId);
|
||||
application.setMinimizedDelegate(delegate);
|
||||
application.runApplication();
|
||||
}
|
||||
|
||||
onPressAndHold: {
|
||||
|
|
@ -44,10 +51,10 @@ MouseArea {
|
|||
|
||||
onClicked: {
|
||||
// launch app
|
||||
if (model.applicationRunning) {
|
||||
delegate.launch(0, 0, "", model.applicationName, model.applicationStorageId);
|
||||
if (application.running) {
|
||||
delegate.launch(0, 0, "", applicationName, applicationStorageId);
|
||||
} else {
|
||||
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, model.applicationName, model.applicationStorageId);
|
||||
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, applicationName, applicationStorageId);
|
||||
}
|
||||
}
|
||||
hoverEnabled: true
|
||||
|
|
@ -63,7 +70,7 @@ MouseArea {
|
|||
icon.name: "emblem-favorite"
|
||||
text: i18n("Remove from favourites")
|
||||
onClicked: {
|
||||
MobileShell.FavoritesModel.removeFavorite(model.index);
|
||||
Halcyon.PinnedModel.removeApp(model.index);
|
||||
}
|
||||
}
|
||||
onClosed: dialogLoader.active = false
|
||||
|
|
@ -98,14 +105,14 @@ MouseArea {
|
|||
Layout.preferredHeight: Layout.minimumHeight
|
||||
|
||||
usesPlasmaTheme: false
|
||||
source: model.applicationIcon
|
||||
source: applicationIcon
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
}
|
||||
visible: model.applicationRunning
|
||||
visible: application.running
|
||||
radius: width
|
||||
width: PlasmaCore.Units.smallSpacing
|
||||
height: width
|
||||
|
|
@ -132,7 +139,7 @@ MouseArea {
|
|||
maximumLineCount: 1
|
||||
elide: Text.ElideRight
|
||||
|
||||
text: model.applicationName
|
||||
text: applicationName
|
||||
|
||||
font.pointSize: PlasmaCore.Theme.defaultFont.pointSize
|
||||
font.weight: Font.Bold
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import org.kde.kquickcontrolsaddons 2.0
|
|||
|
||||
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.halcyon 1.0 as Halcyon
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
|
|
@ -24,6 +25,8 @@ MouseArea {
|
|||
width: GridView.view.cellWidth
|
||||
height: GridView.view.cellHeight
|
||||
|
||||
property Halcyon.Application application: model.application
|
||||
|
||||
property int reservedSpaceForLabel
|
||||
property alias iconItem: icon
|
||||
|
||||
|
|
@ -38,10 +41,10 @@ MouseArea {
|
|||
|
||||
function launchApp() {
|
||||
// launch app
|
||||
if (model.applicationRunning) {
|
||||
delegate.launch(0, 0, "", model.applicationName, model.applicationStorageId);
|
||||
if (application.running) {
|
||||
delegate.launch(0, 0, "", application.name, application.storageId);
|
||||
} else {
|
||||
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, model.applicationName, model.applicationStorageId);
|
||||
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, application.name, application.storageId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +59,7 @@ MouseArea {
|
|||
icon.name: "emblem-favorite"
|
||||
text: i18n("Add to favourites")
|
||||
onClicked: {
|
||||
MobileShell.FavoritesModel.addFavorite(model.applicationStorageId, 0, MobileShell.ApplicationListModel.Favorites);
|
||||
Halcyon.PinnedModel.addApp(application.storageId, 0);
|
||||
}
|
||||
}
|
||||
onClosed: dialogLoader.active = false
|
||||
|
|
@ -131,14 +134,14 @@ MouseArea {
|
|||
Layout.preferredHeight: Layout.minimumHeight
|
||||
|
||||
usesPlasmaTheme: false
|
||||
source: model.applicationIcon
|
||||
source: application.icon
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
}
|
||||
visible: model.applicationRunning
|
||||
visible: application.running
|
||||
radius: width
|
||||
width: PlasmaCore.Units.smallSpacing
|
||||
height: width
|
||||
|
|
@ -161,7 +164,7 @@ MouseArea {
|
|||
verticalAlignment: Text.AlignTop
|
||||
elide: Text.ElideRight
|
||||
|
||||
text: model.applicationName
|
||||
text: application.name
|
||||
|
||||
font.pointSize: theme.defaultFont.pointSize * 0.85
|
||||
font.weight: Font.Bold
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import org.kde.kirigami 2.10 as Kirigami
|
|||
|
||||
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.halcyon 1.0 as Halcyon
|
||||
|
||||
GridView {
|
||||
id: gridView
|
||||
|
|
@ -32,7 +33,7 @@ GridView {
|
|||
|
||||
cacheBuffer: Math.max(0, rows * cellHeight)
|
||||
|
||||
model: MobileShell.ApplicationListModel
|
||||
model: Halcyon.ApplicationListModel
|
||||
|
||||
header: Controls.Control {
|
||||
implicitWidth: gridView.width
|
||||
|
|
@ -59,6 +60,8 @@ GridView {
|
|||
delegate: GridAppDelegate {
|
||||
id: delegate
|
||||
|
||||
property Halcyon.Application application: model.application
|
||||
|
||||
width: gridView.cellWidth
|
||||
height: gridView.cellHeight
|
||||
reservedSpaceForLabel: gridView.reservedSpaceForLabel
|
||||
|
|
@ -73,8 +76,8 @@ GridView {
|
|||
Math.min(delegate.iconItem.width, delegate.iconItem.height));
|
||||
}
|
||||
|
||||
MobileShell.ApplicationListModel.setMinimizedDelegate(index, delegate);
|
||||
MobileShell.ApplicationListModel.runApplication(storageId);
|
||||
application.setMinimizedDelegate(delegate);
|
||||
application.runApplication();
|
||||
gridView.launched();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import org.kde.draganddrop 2.0 as DragDrop
|
|||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.halcyon 1.0 as Halcyon
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
|
@ -60,7 +61,7 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
model: MobileShell.FavoritesModel
|
||||
model: Halcyon.PinnedModel
|
||||
header: MobileShell.BaseItem {
|
||||
topPadding: Math.round(swipeView.height * 0.2)
|
||||
bottomPadding: PlasmaCore.Units.largeSpacing
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import org.kde.plasma.core 2.0 as PlasmaCore
|
|||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
|
||||
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||
import org.kde.phone.homescreen.halcyon 1.0 as Halcyon
|
||||
|
||||
MobileShell.HomeScreen {
|
||||
id: root
|
||||
|
|
@ -23,10 +24,7 @@ MobileShell.HomeScreen {
|
|||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
MobileShell.ApplicationListModel.loadApplications();
|
||||
MobileShell.FavoritesModel.applet = plasmoid;
|
||||
MobileShell.FavoritesModel.loadApplications();
|
||||
|
||||
Halcyon.ApplicationListModel.loadApplications();
|
||||
forceActiveFocus();
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +59,7 @@ MobileShell.HomeScreen {
|
|||
Connections {
|
||||
target: MobileShell.HomeScreenControls.taskSwitcher
|
||||
function onVisibleChanged() {
|
||||
searchWidget.close();
|
||||
search.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
130
containments/homescreens/halcyon/pinnedmodel.cpp
Normal file
130
containments/homescreens/halcyon/pinnedmodel.cpp
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "pinnedmodel.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
PinnedModel::PinnedModel(QObject *parent, Plasma::Applet *applet)
|
||||
: QAbstractListModel{parent}
|
||||
, m_applet{applet}
|
||||
{
|
||||
}
|
||||
|
||||
PinnedModel::~PinnedModel() = default;
|
||||
|
||||
int PinnedModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return m_applications.count();
|
||||
}
|
||||
|
||||
QVariant PinnedModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case IsFolderRole:
|
||||
return m_folders.at(index.row()) != nullptr;
|
||||
case ApplicationRole:
|
||||
return QVariant::fromValue(m_applications.at(index.row()));
|
||||
case FolderRole:
|
||||
return QVariant::fromValue(m_folders.at(index.row()));
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> PinnedModel::roleNames() const
|
||||
{
|
||||
return {{IsFolderRole, "isFolder"}, {ApplicationRole, "application"}, {FolderRole, "folder"}};
|
||||
}
|
||||
|
||||
void PinnedModel::addApp(const QString &storageId, int row)
|
||||
{
|
||||
if (row < 0 && row > m_applications.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (KService::Ptr service = KService::serviceByStorageId(storageId)) {
|
||||
Application *app = new Application(this, service);
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
m_applications.insert(row, app);
|
||||
m_folders.insert(0, nullptr); // maintain indicies
|
||||
endInsertRows();
|
||||
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedModel::removeApp(int row)
|
||||
{
|
||||
if (row < 0 && row >= m_applications.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
m_applications[row]->deleteLater();
|
||||
m_applications.removeAt(row);
|
||||
m_folders.removeAt(row); // maintain indicies
|
||||
endRemoveRows();
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
void PinnedModel::load()
|
||||
{
|
||||
if (!m_applet) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(m_applet->config().readEntry("Pinned", "{}").toUtf8());
|
||||
|
||||
beginResetModel();
|
||||
|
||||
for (QJsonValueRef r : doc.array()) {
|
||||
QJsonObject obj = r.toObject();
|
||||
|
||||
if (obj[QStringLiteral("type")].toString() == "application") {
|
||||
// read application
|
||||
Application *app = Application::fromJson(obj, this);
|
||||
if (app) {
|
||||
m_applications.append(app);
|
||||
m_folders.append(nullptr);
|
||||
}
|
||||
|
||||
} else if (obj[QStringLiteral("type")].toString() == "folder") {
|
||||
// read folder
|
||||
ApplicationFolder *folder = ApplicationFolder::fromJson(obj, this);
|
||||
if (folder) {
|
||||
m_applications.append(nullptr);
|
||||
m_folders.append(folder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void PinnedModel::save()
|
||||
{
|
||||
if (!m_applet) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonArray arr;
|
||||
for (int i = 0; i < m_applications.size() && i < m_folders.size(); i++) {
|
||||
if (m_applications[i]) {
|
||||
arr.push_back(m_applications[i]->toJson());
|
||||
} else if (m_folders[i]) {
|
||||
arr.push_back(m_folders[i]->toJson());
|
||||
}
|
||||
}
|
||||
QByteArray data = QJsonDocument(arr).toJson(QJsonDocument::Compact);
|
||||
|
||||
m_applet->config().writeEntry("Pinned", QString::fromStdString(data.toStdString()));
|
||||
Q_EMIT m_applet->configNeedsSaving();
|
||||
}
|
||||
47
containments/homescreens/halcyon/pinnedmodel.h
Normal file
47
containments/homescreens/halcyon/pinnedmodel.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "application.h"
|
||||
#include "applicationfolder.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QQuickItem>
|
||||
#include <QSet>
|
||||
|
||||
#include <Plasma/Applet>
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/plasmawindowmanagement.h>
|
||||
#include <KWayland/Client/registry.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
class PinnedModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles { IsFolderRole = Qt::UserRole + 1, ApplicationRole, FolderRole };
|
||||
|
||||
PinnedModel(QObject *parent = nullptr, Plasma::Applet *applet = nullptr);
|
||||
~PinnedModel() override;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Q_INVOKABLE void addApp(const QString &storageId, int row);
|
||||
Q_INVOKABLE void removeApp(int row);
|
||||
|
||||
Q_INVOKABLE void load();
|
||||
void save();
|
||||
|
||||
private:
|
||||
QList<Application *> m_applications;
|
||||
QList<ApplicationFolder *> m_folders;
|
||||
|
||||
Plasma::Applet *m_applet;
|
||||
};
|
||||
62
containments/homescreens/halcyon/windowlistener.cpp
Normal file
62
containments/homescreens/halcyon/windowlistener.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "windowlistener.h"
|
||||
|
||||
WindowListener::WindowListener(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
// initialize wayland window checking
|
||||
KWayland::Client::ConnectionThread *connection = KWayland::Client::ConnectionThread::fromApplication(this);
|
||||
if (!connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto *registry = new KWayland::Client::Registry(this);
|
||||
registry->create(connection);
|
||||
|
||||
connect(registry, &KWayland::Client::Registry::plasmaWindowManagementAnnounced, this, [this, registry](quint32 name, quint32 version) {
|
||||
m_windowManagement = registry->createPlasmaWindowManagement(name, version, this);
|
||||
connect(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::windowCreated, this, &WindowListener::windowCreated);
|
||||
});
|
||||
|
||||
registry->setup();
|
||||
connection->roundtrip();
|
||||
}
|
||||
|
||||
WindowListener *WindowListener::instance()
|
||||
{
|
||||
static WindowListener *listener = new WindowListener();
|
||||
return listener;
|
||||
}
|
||||
|
||||
QList<KWayland::Client::PlasmaWindow *> WindowListener::windowsFromStorageId(QString &storageId) const
|
||||
{
|
||||
if (!m_windows.contains(storageId)) {
|
||||
return {};
|
||||
}
|
||||
return m_windows[storageId];
|
||||
}
|
||||
|
||||
void WindowListener::windowCreated(KWayland::Client::PlasmaWindow *window)
|
||||
{
|
||||
QString storageId = window->appId() + QStringLiteral(".desktop");
|
||||
|
||||
// ignore empty windows
|
||||
if (storageId == ".desktop" || storageId == "org.kde.plasmashell.desktop") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_windows.contains(storageId)) {
|
||||
m_windows[storageId] = {};
|
||||
}
|
||||
m_windows[storageId].push_back(window);
|
||||
|
||||
// listen for window close
|
||||
connect(window, &KWayland::Client::PlasmaWindow::unmapped, this, [this, storageId]() {
|
||||
m_windows.remove(storageId);
|
||||
Q_EMIT windowChanged(storageId);
|
||||
});
|
||||
|
||||
Q_EMIT windowChanged(storageId);
|
||||
}
|
||||
34
containments/homescreens/halcyon/windowlistener.h
Normal file
34
containments/homescreens/halcyon/windowlistener.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/plasmawindowmanagement.h>
|
||||
#include <KWayland/Client/registry.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
class WindowListener : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowListener(QObject *parent = nullptr);
|
||||
|
||||
static WindowListener *instance();
|
||||
|
||||
QList<KWayland::Client::PlasmaWindow *> windowsFromStorageId(QString &storageId) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void windowCreated(KWayland::Client::PlasmaWindow *window);
|
||||
|
||||
Q_SIGNALS:
|
||||
void windowChanged(QString storageId);
|
||||
|
||||
private:
|
||||
KWayland::Client::PlasmaWindowManagement *m_windowManagement = nullptr;
|
||||
QHash<QString, QList<KWayland::Client::PlasmaWindow *>> m_windows; // <storageId, window>
|
||||
};
|
||||
Loading…
Reference in a new issue