Commit 0d438d87 authored by Marco Martin's avatar Marco Martin

when an application is already running bring window on front

all applications are single instance only
parent 5881d6be
......@@ -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: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment