mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +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::KIOGui
|
||||
KF5::Notifications
|
||||
KF5::WaylandClient
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@
|
|||
#include <KSycoca>
|
||||
#include <KSycocaEntry>
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/plasmawindowmanagement.h>
|
||||
#include <KWayland/Client/registry.h>
|
||||
|
||||
constexpr int MAX_FAVOURITES = 5;
|
||||
|
||||
ApplicationListModel::ApplicationListModel(HomeScreen *parent)
|
||||
|
|
@ -45,6 +49,7 @@ ApplicationListModel::ApplicationListModel(HomeScreen *parent)
|
|||
this, &ApplicationListModel::sycocaDbChanged);
|
||||
|
||||
loadSettings();
|
||||
initWayland();
|
||||
}
|
||||
|
||||
ApplicationListModel::~ApplicationListModel() = default;
|
||||
|
|
@ -79,7 +84,8 @@ QHash<int, QByteArray> ApplicationListModel::roleNames() const
|
|||
{ApplicationEntryPathRole, QByteArrayLiteral("applicationEntryPath")},
|
||||
{ApplicationOriginalRowRole, QByteArrayLiteral("applicationOriginalRow")},
|
||||
{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();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
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;
|
||||
case ApplicationLocationRole:
|
||||
return m_applicationList.at(index.row()).location;
|
||||
case ApplicationRunningRole:
|
||||
return m_applicationList.at(index.row()).window != nullptr;
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
|
|
@ -339,6 +398,13 @@ void ApplicationListModel::runApplication(const QString &storageId)
|
|||
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);
|
||||
KIO::ApplicationLauncherJob *job = new KIO::ApplicationLauncherJob(service);
|
||||
job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled));
|
||||
|
|
|
|||
|
|
@ -30,6 +30,15 @@
|
|||
|
||||
class QString;
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Client
|
||||
{
|
||||
class PlasmaWindowManagement;
|
||||
class PlasmaWindow;
|
||||
}
|
||||
}
|
||||
|
||||
class ApplicationListModel;
|
||||
|
||||
class ApplicationListModel : public QAbstractListModel {
|
||||
|
|
@ -54,6 +63,7 @@ public:
|
|||
QString entryPath;
|
||||
LauncherLocation location = LauncherLocation::Grid;
|
||||
bool startupNotify = true;
|
||||
KWayland::Client::PlasmaWindow *window = nullptr;
|
||||
};
|
||||
|
||||
enum Roles {
|
||||
|
|
@ -63,7 +73,8 @@ public:
|
|||
ApplicationEntryPathRole,
|
||||
ApplicationOriginalRowRole,
|
||||
ApplicationStartupNotifyRole,
|
||||
ApplicationLocationRole
|
||||
ApplicationLocationRole,
|
||||
ApplicationRunningRole
|
||||
};
|
||||
|
||||
ApplicationListModel(HomeScreen *parent = nullptr);
|
||||
|
|
@ -104,8 +115,11 @@ Q_SIGNALS:
|
|||
void maxFavoriteCountChanged();
|
||||
|
||||
private:
|
||||
void initWayland();
|
||||
|
||||
QList<ApplicationData> m_applicationList;
|
||||
|
||||
KWayland::Client::PlasmaWindowManagement *m_windowManagement = nullptr;
|
||||
HomeScreen *m_homeScreen = nullptr;
|
||||
int m_maxFavoriteCount = 0;
|
||||
QStringList m_appOrder;
|
||||
|
|
|
|||
|
|
@ -93,7 +93,11 @@ ContainmentLayoutManager.ItemContainer {
|
|||
|
||||
contentItem: MouseArea {
|
||||
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);
|
||||
}
|
||||
|
|
@ -119,11 +123,17 @@ ContainmentLayoutManager.ItemContainer {
|
|||
|
||||
usesPlasmaTheme: false
|
||||
source: modelData ? modelData.applicationIcon : ""
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: units.longDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
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) => {
|
||||
delegate.grabToImage((img) => {
|
||||
if (icon !== "") {
|
||||
NanoShell.StartupFeedback.open(
|
||||
icon,
|
||||
title,
|
||||
delegate.iconItem.Kirigami.ScenePosition.x + delegate.iconItem.width/2,
|
||||
delegate.iconItem.Kirigami.ScenePosition.y + delegate.iconItem.height/2,
|
||||
Math.min(delegate.iconItem.width, delegate.iconItem.height)
|
||||
)});
|
||||
icon,
|
||||
title,
|
||||
delegate.iconItem.Kirigami.ScenePosition.x + delegate.iconItem.width/2,
|
||||
delegate.iconItem.Kirigami.ScenePosition.y + delegate.iconItem.height/2,
|
||||
Math.min(delegate.iconItem.width, delegate.iconItem.height));
|
||||
}
|
||||
root.launched();
|
||||
}
|
||||
onParentFromLocationChanged: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue