mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-08-04 02:34:45 +00:00
when an application is already running bring window on front
all applications are single instance only
This commit is contained in:
parent
5881d6be92
commit
0d438d87d3
5 changed files with 105 additions and 14 deletions
|
|
@ -16,6 +16,7 @@ target_link_libraries(plasma_containment_phone_homescreen
|
||||||
KF5::Service
|
KF5::Service
|
||||||
KF5::KIOGui
|
KF5::KIOGui
|
||||||
KF5::Notifications
|
KF5::Notifications
|
||||||
|
KF5::WaylandClient
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,10 @@
|
||||||
#include <KSycoca>
|
#include <KSycoca>
|
||||||
#include <KSycocaEntry>
|
#include <KSycocaEntry>
|
||||||
|
|
||||||
|
#include <KWayland/Client/connection_thread.h>
|
||||||
|
#include <KWayland/Client/plasmawindowmanagement.h>
|
||||||
|
#include <KWayland/Client/registry.h>
|
||||||
|
|
||||||
constexpr int MAX_FAVOURITES = 5;
|
constexpr int MAX_FAVOURITES = 5;
|
||||||
|
|
||||||
ApplicationListModel::ApplicationListModel(HomeScreen *parent)
|
ApplicationListModel::ApplicationListModel(HomeScreen *parent)
|
||||||
|
|
@ -45,6 +49,7 @@ ApplicationListModel::ApplicationListModel(HomeScreen *parent)
|
||||||
this, &ApplicationListModel::sycocaDbChanged);
|
this, &ApplicationListModel::sycocaDbChanged);
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
initWayland();
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationListModel::~ApplicationListModel() = default;
|
ApplicationListModel::~ApplicationListModel() = default;
|
||||||
|
|
@ -79,7 +84,8 @@ QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
||||||
{ApplicationEntryPathRole, QByteArrayLiteral("applicationEntryPath")},
|
{ApplicationEntryPathRole, QByteArrayLiteral("applicationEntryPath")},
|
||||||
{ApplicationOriginalRowRole, QByteArrayLiteral("applicationOriginalRow")},
|
{ApplicationOriginalRowRole, QByteArrayLiteral("applicationOriginalRow")},
|
||||||
{ApplicationStartupNotifyRole, QByteArrayLiteral("applicationStartupNotify")},
|
{ApplicationStartupNotifyRole, QByteArrayLiteral("applicationStartupNotify")},
|
||||||
{ApplicationLocationRole, QByteArrayLiteral("applicationLocation")}
|
{ApplicationLocationRole, QByteArrayLiteral("applicationLocation")},
|
||||||
|
{ApplicationRunningRole, QByteArrayLiteral("applicationRunning")}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,6 +105,57 @@ bool appNameLessThan(const ApplicationListModel::ApplicationData &a1, const Appl
|
||||||
return a1.name.toLower() < a2.name.toLower();
|
return a1.name.toLower() < a2.name.toLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplicationListModel::initWayland()
|
||||||
|
{
|
||||||
|
if (!QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
using namespace KWayland::Client;
|
||||||
|
ConnectionThread *connection = ConnectionThread::fromApplication(this);
|
||||||
|
|
||||||
|
if (!connection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto *registry = new Registry(this);
|
||||||
|
registry->create(connection);
|
||||||
|
connect(registry, &Registry::plasmaWindowManagementAnnounced, this,
|
||||||
|
[this, registry] (quint32 name, quint32 version) {
|
||||||
|
m_windowManagement = registry->createPlasmaWindowManagement(name, version, this);
|
||||||
|
qRegisterMetaType<QVector<int> >("QVector<int>");
|
||||||
|
|
||||||
|
connect(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::windowCreated,
|
||||||
|
this, [this] (KWayland::Client::PlasmaWindow *window) {
|
||||||
|
if (window->appId() == QStringLiteral("org.kde.plasmashell")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int idx = 0;
|
||||||
|
for (auto i = m_applicationList.begin(); i != m_applicationList.end(); i++) {
|
||||||
|
if ((*i).storageId == window->appId() + QStringLiteral(".desktop")) {
|
||||||
|
(*i).window = window;
|
||||||
|
emit dataChanged(index(idx, 0), index(idx, 0));
|
||||||
|
connect(window, &KWayland::Client::PlasmaWindow::unmapped, this, [this, window] () {
|
||||||
|
int idx = 0;
|
||||||
|
for (auto i = m_applicationList.begin(); i != m_applicationList.end(); i++) {
|
||||||
|
if ((*i).storageId == window->appId() + QStringLiteral(".desktop")) {
|
||||||
|
(*i).window = nullptr;
|
||||||
|
emit dataChanged(index(idx, 0), index(idx, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
registry->setup();
|
||||||
|
connection->roundtrip();
|
||||||
|
}
|
||||||
|
|
||||||
void ApplicationListModel::loadApplications()
|
void ApplicationListModel::loadApplications()
|
||||||
{
|
{
|
||||||
auto cfg = KSharedConfig::openConfig(QStringLiteral("applications-blacklistrc"));
|
auto cfg = KSharedConfig::openConfig(QStringLiteral("applications-blacklistrc"));
|
||||||
|
|
@ -224,6 +281,8 @@ QVariant ApplicationListModel::data(const QModelIndex &index, int role) const
|
||||||
return m_applicationList.at(index.row()).startupNotify;
|
return m_applicationList.at(index.row()).startupNotify;
|
||||||
case ApplicationLocationRole:
|
case ApplicationLocationRole:
|
||||||
return m_applicationList.at(index.row()).location;
|
return m_applicationList.at(index.row()).location;
|
||||||
|
case ApplicationRunningRole:
|
||||||
|
return m_applicationList.at(index.row()).window != nullptr;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
@ -339,6 +398,13 @@ void ApplicationListModel::runApplication(const QString &storageId)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto i = m_applicationList.begin(); i != m_applicationList.end(); i++) {
|
||||||
|
if ((*i).window && (*i).storageId == storageId) {
|
||||||
|
(*i).window->requestActivate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KService::Ptr service = KService::serviceByStorageId(storageId);
|
KService::Ptr service = KService::serviceByStorageId(storageId);
|
||||||
KIO::ApplicationLauncherJob *job = new KIO::ApplicationLauncherJob(service);
|
KIO::ApplicationLauncherJob *job = new KIO::ApplicationLauncherJob(service);
|
||||||
job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled));
|
job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled));
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,15 @@
|
||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
|
|
||||||
|
namespace KWayland
|
||||||
|
{
|
||||||
|
namespace Client
|
||||||
|
{
|
||||||
|
class PlasmaWindowManagement;
|
||||||
|
class PlasmaWindow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ApplicationListModel;
|
class ApplicationListModel;
|
||||||
|
|
||||||
class ApplicationListModel : public QAbstractListModel {
|
class ApplicationListModel : public QAbstractListModel {
|
||||||
|
|
@ -54,6 +63,7 @@ public:
|
||||||
QString entryPath;
|
QString entryPath;
|
||||||
LauncherLocation location = LauncherLocation::Grid;
|
LauncherLocation location = LauncherLocation::Grid;
|
||||||
bool startupNotify = true;
|
bool startupNotify = true;
|
||||||
|
KWayland::Client::PlasmaWindow *window = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Roles {
|
enum Roles {
|
||||||
|
|
@ -63,7 +73,8 @@ public:
|
||||||
ApplicationEntryPathRole,
|
ApplicationEntryPathRole,
|
||||||
ApplicationOriginalRowRole,
|
ApplicationOriginalRowRole,
|
||||||
ApplicationStartupNotifyRole,
|
ApplicationStartupNotifyRole,
|
||||||
ApplicationLocationRole
|
ApplicationLocationRole,
|
||||||
|
ApplicationRunningRole
|
||||||
};
|
};
|
||||||
|
|
||||||
ApplicationListModel(HomeScreen *parent = nullptr);
|
ApplicationListModel(HomeScreen *parent = nullptr);
|
||||||
|
|
@ -104,8 +115,11 @@ Q_SIGNALS:
|
||||||
void maxFavoriteCountChanged();
|
void maxFavoriteCountChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void initWayland();
|
||||||
|
|
||||||
QList<ApplicationData> m_applicationList;
|
QList<ApplicationData> m_applicationList;
|
||||||
|
|
||||||
|
KWayland::Client::PlasmaWindowManagement *m_windowManagement = nullptr;
|
||||||
HomeScreen *m_homeScreen = nullptr;
|
HomeScreen *m_homeScreen = nullptr;
|
||||||
int m_maxFavoriteCount = 0;
|
int m_maxFavoriteCount = 0;
|
||||||
QStringList m_appOrder;
|
QStringList m_appOrder;
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,11 @@ ContainmentLayoutManager.ItemContainer {
|
||||||
|
|
||||||
contentItem: MouseArea {
|
contentItem: MouseArea {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
delegate.launch(delegate.x + (units.smallSpacing * 2), delegate.y + (units.smallSpacing * 2), icon.source, modelData.applicationName)
|
if (modelData.applicationRunning) {
|
||||||
|
delegate.launch(0, 0, "", modelData.applicationName);
|
||||||
|
} else {
|
||||||
|
delegate.launch(delegate.x + (units.smallSpacing * 2), delegate.y + (units.smallSpacing * 2), icon.source, modelData.applicationName);
|
||||||
|
}
|
||||||
|
|
||||||
plasmoid.nativeInterface.applicationListModel.runApplication(modelData.applicationStorageId);
|
plasmoid.nativeInterface.applicationListModel.runApplication(modelData.applicationStorageId);
|
||||||
}
|
}
|
||||||
|
|
@ -119,11 +123,17 @@ ContainmentLayoutManager.ItemContainer {
|
||||||
|
|
||||||
usesPlasmaTheme: false
|
usesPlasmaTheme: false
|
||||||
source: modelData ? modelData.applicationIcon : ""
|
source: modelData ? modelData.applicationIcon : ""
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
Rectangle {
|
||||||
duration: units.longDuration
|
anchors {
|
||||||
easing.type: Easing.InOutQuad
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottom: parent.bottom
|
||||||
}
|
}
|
||||||
|
visible: model.applicationRunning
|
||||||
|
radius: width
|
||||||
|
width: units.smallSpacing
|
||||||
|
height: width
|
||||||
|
color: theme.highlightColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,14 +68,14 @@ LauncherContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onLaunch: (x, y, icon, title) => {
|
onLaunch: (x, y, icon, title) => {
|
||||||
delegate.grabToImage((img) => {
|
if (icon !== "") {
|
||||||
NanoShell.StartupFeedback.open(
|
NanoShell.StartupFeedback.open(
|
||||||
icon,
|
icon,
|
||||||
title,
|
title,
|
||||||
delegate.iconItem.Kirigami.ScenePosition.x + delegate.iconItem.width/2,
|
delegate.iconItem.Kirigami.ScenePosition.x + delegate.iconItem.width/2,
|
||||||
delegate.iconItem.Kirigami.ScenePosition.y + delegate.iconItem.height/2,
|
delegate.iconItem.Kirigami.ScenePosition.y + delegate.iconItem.height/2,
|
||||||
Math.min(delegate.iconItem.width, delegate.iconItem.height)
|
Math.min(delegate.iconItem.width, delegate.iconItem.height));
|
||||||
)});
|
}
|
||||||
root.launched();
|
root.launched();
|
||||||
}
|
}
|
||||||
onParentFromLocationChanged: {
|
onParentFromLocationChanged: {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue