startupfeedback: Add support for multiple screens

Addresses https://invent.kde.org/plasma/plasma-mobile/-/issues/175
This commit is contained in:
Devin Lin 2024-03-09 22:50:55 -05:00
parent af58923a1e
commit e2e6590222
13 changed files with 125 additions and 56 deletions

View file

@ -64,12 +64,10 @@ MobileShell.BaseItem {
root.toggleFunction();
} else if (root.settingsCommand && !root.restrictedPermissions) {
closeRequested();
MobileShellState.ShellDBusClient.openAppLaunchAnimation(
root.icon,
root.text,
iconItem.Kirigami.ScenePosition.x + iconItem.width/2,
iconItem.Kirigami.ScenePosition.y + iconItem.height/2,
Math.min(iconItem.width, iconItem.height))
__getCurrentScreenNumber(),
root.icon);
MobileShell.ShellUtil.executeCommand(root.settingsCommand);
}
}
@ -78,14 +76,22 @@ MobileShell.BaseItem {
if (root.settingsCommand && !root.restrictedPermissions) {
closeRequested();
MobileShellState.ShellDBusClient.openAppLaunchAnimation(
root.icon,
root.text,
iconItem.Kirigami.ScenePosition.x + iconItem.width/2,
iconItem.Kirigami.ScenePosition.y + iconItem.height/2,
Math.min(iconItem.width, iconItem.height))
__getCurrentScreenNumber(),
root.icon);
MobileShell.ShellUtil.executeCommand(root.settingsCommand);
} else if (root.toggleFunction) {
root.toggleFunction();
}
}
function __getCurrentScreenNumber() {
const screens = Qt.application.screens;
for (let i = 0; i < screens.length; i++) {
if (screens[i].name === Screen.name) {
return i;
}
}
return 0;
}
}

View file

@ -12,6 +12,7 @@ import org.kde.kirigami as Kirigami
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
import org.kde.plasma.plasmoid
/**
* Component that animates an app opening from a location.
@ -25,8 +26,17 @@ MouseArea { // use mousearea to ensure clicks don't go behind
property alias icon: icon.source
property bool __openRequested: false
function open(splashIcon) {
iconParent.scale = 0.5;
background.scale = 0.5;
backgroundParent.x = 0;
backgroundParent.y = 0;
__openRequested = true;
updateIconSource(splashIcon);
}
function open(splashIcon, title, x, y, sourceIconSize) {
function openWithPosition(splashIcon, x, y, sourceIconSize) {
iconParent.scale = sourceIconSize/iconParent.width;
background.scale = 0;
backgroundParent.x = -root.width/2 + x
@ -61,19 +71,31 @@ MouseArea { // use mousearea to ensure clicks don't go behind
root.close();
}
}
// open startupfeedback when notifier gives an app
Connections {
target: WindowPlugin.WindowUtil
function onAppActivationStarted(appId, iconName) {
if (!openAnimComplex.running && !root.__openRequested) {
iconParent.scale = 0.5;
background.scale = 0.5;
backgroundParent.x = 0
backgroundParent.y = 0
root.__openRequested = true;
root.updateIconSource(iconName);
// Open StartupFeedback when the notifier gives an app (ex. from Milou search)
// TODO: This is problematic with multiple screens, because we don't have any info given
// on which screen the app is opening on. Thus StartupFeedback would just open on
// every single screen...
// -> We have it disabled for now until some solution is found. We manually open StartupFeedback
// from launches in the homescreen (call open()).
//
// function onAppActivationStarted(appId, iconName) {
// if (!openAnimComplex.running && !root.__openRequested) {
// // TODO: this doesn't work because it gets triggered on screen 0 even if the app is opening on screen 1
// // HACK: We have no way of knowing which screen this app is going to open on
// // -> Assume the first screen for now
// if (Plasmoid.screen === 0) {
// root.open(iconName);
// }
// }
// }
function onAppActivationFinished(appId, iconName) {
if (iconName === root.icon.name) {
root.close();
}
}
}

View file

@ -102,8 +102,20 @@ Item {
root.resetHomeScreenPosition();
}
function onOpenAppLaunchAnimationRequested(splashIcon, title, x, y, sourceIconSize) {
startupFeedback.open(splashIcon, title, x, y, sourceIconSize);
function onOpenAppLaunchAnimationRequested(screen, splashIcon) {
if (screen !== Plasmoid.screen) {
return;
}
startupFeedback.open(splashIcon);
}
function onOpenAppLaunchAnimationWithPositionRequested(screen, splashIcon, title, x, y, sourceIconSize) {
if (screen !== Plasmoid.screen) {
return;
}
startupFeedback.openWithPosition(splashIcon, x, y, sourceIconSize);
}
function onCloseAppLaunchAnimationRequested() {

View file

@ -168,7 +168,6 @@ NanoShell.FullScreenOverlay {
onClicked: {
let coords = mapToItem(flickable, 0, 0);
MobileShellState.ShellDBusClient.openAppLaunchAnimation("audio-volume-high", i18n("Audio Settings"), coords.x, coords.y, Kirigami.Units.iconSizes.medium);
MobileShell.ShellUtil.executeCommand("plasma-open-settings kcm_pulseaudio");
}
}

View file

@ -35,6 +35,10 @@ void ShellDBusClient::connectSignals()
connect(m_interface, &OrgKdePlasmashellInterface::openActionDrawerRequested, this, &ShellDBusClient::openActionDrawerRequested);
connect(m_interface, &OrgKdePlasmashellInterface::closeActionDrawerRequested, this, &ShellDBusClient::closeActionDrawerRequested);
connect(m_interface, &OrgKdePlasmashellInterface::openAppLaunchAnimationRequested, this, &ShellDBusClient::openAppLaunchAnimationRequested);
connect(m_interface,
&OrgKdePlasmashellInterface::openAppLaunchAnimationWithPositionRequested,
this,
&ShellDBusClient::openAppLaunchAnimationWithPositionRequested);
connect(m_interface, &OrgKdePlasmashellInterface::closeAppLaunchAnimationRequested, this, &ShellDBusClient::closeAppLaunchAnimationRequested);
connect(m_interface, &OrgKdePlasmashellInterface::openHomeScreenRequested, this, &ShellDBusClient::openHomeScreenRequested);
connect(m_interface, &OrgKdePlasmashellInterface::resetHomeScreenPositionRequested, this, &ShellDBusClient::resetHomeScreenPositionRequested);
@ -80,9 +84,14 @@ bool ShellDBusClient::isTaskSwitcherVisible() const
return m_isTaskSwitcherVisible;
}
void ShellDBusClient::openAppLaunchAnimation(QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize)
void ShellDBusClient::openAppLaunchAnimation(int screen, QString splashIcon)
{
m_interface->openAppLaunchAnimation(splashIcon, title, x, y, sourceIconSize);
m_interface->openAppLaunchAnimation(screen, splashIcon);
}
void ShellDBusClient::openAppLaunchAnimationWithPosition(int screen, QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize)
{
m_interface->openAppLaunchAnimationWithPosition(screen, splashIcon, title, x, y, sourceIconSize);
}
void ShellDBusClient::closeAppLaunchAnimation()

View file

@ -34,7 +34,8 @@ public:
Q_INVOKABLE void openActionDrawer();
Q_INVOKABLE void closeActionDrawer();
Q_INVOKABLE void openAppLaunchAnimation(QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize);
Q_INVOKABLE void openAppLaunchAnimation(int screen, QString splashIcon);
Q_INVOKABLE void openAppLaunchAnimationWithPosition(int screen, QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize);
Q_INVOKABLE void closeAppLaunchAnimation();
Q_INVOKABLE void openHomeScreen();
@ -47,7 +48,8 @@ Q_SIGNALS:
void isTaskSwitcherVisibleChanged();
void openActionDrawerRequested();
void closeActionDrawerRequested();
void openAppLaunchAnimationRequested(QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize);
void openAppLaunchAnimationRequested(int screen, QString splashIcon);
void openAppLaunchAnimationWithPositionRequested(int screen, QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize);
void closeAppLaunchAnimationRequested();
void openHomeScreenRequested();
void resetHomeScreenPositionRequested();

View file

@ -69,9 +69,14 @@ void ShellDBusObject::closeActionDrawer()
Q_EMIT closeActionDrawerRequested();
}
void ShellDBusObject::openAppLaunchAnimation(QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize)
void ShellDBusObject::openAppLaunchAnimation(int screen, QString splashIcon)
{
Q_EMIT openAppLaunchAnimationRequested(splashIcon, title, x, y, sourceIconSize);
Q_EMIT openAppLaunchAnimationRequested(screen, splashIcon);
}
void ShellDBusObject::openAppLaunchAnimationWithPosition(int screen, QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize)
{
Q_EMIT openAppLaunchAnimationWithPositionRequested(screen, splashIcon, title, x, y, sourceIconSize);
}
void ShellDBusObject::closeAppLaunchAnimation()

View file

@ -26,7 +26,8 @@ Q_SIGNALS:
Q_SCRIPTABLE void isTaskSwitcherVisibleChanged();
Q_SCRIPTABLE void openActionDrawerRequested();
Q_SCRIPTABLE void closeActionDrawerRequested();
Q_SCRIPTABLE void openAppLaunchAnimationRequested(QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize);
Q_SCRIPTABLE void openAppLaunchAnimationRequested(int screen, QString splashIcon);
Q_SCRIPTABLE void openAppLaunchAnimationWithPositionRequested(int screen, QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize);
Q_SCRIPTABLE void closeAppLaunchAnimationRequested();
Q_SCRIPTABLE void openHomeScreenRequested();
Q_SCRIPTABLE void resetHomeScreenPositionRequested();
@ -46,7 +47,8 @@ public Q_SLOTS:
Q_SCRIPTABLE void openActionDrawer();
Q_SCRIPTABLE void closeActionDrawer();
Q_SCRIPTABLE void openAppLaunchAnimation(QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize);
Q_SCRIPTABLE void openAppLaunchAnimation(int screen, QString splashIcon);
Q_SCRIPTABLE void openAppLaunchAnimationWithPosition(int screen, QString splashIcon, QString title, qreal x, qreal y, qreal sourceIconSize);
Q_SCRIPTABLE void closeAppLaunchAnimation();
Q_SCRIPTABLE void openHomeScreen();

View file

@ -73,7 +73,7 @@ void WindowUtil::initWayland()
auto iface = registry->createPlasmaActivationFeedback(name, version, this);
connect(iface, &PlasmaActivationFeedback::activation, this, [this](PlasmaActivation *activation) {
connect(activation, &PlasmaActivation::applicationId, this, [this](const QString &appId) {
connect(activation, &PlasmaActivation::applicationId, this, [this, activation](const QString &appId) {
// do not show activation screen for the plasmashell process
if (appId == "org.kde.plasmashell") {
return;
@ -98,13 +98,19 @@ void WindowUtil::initWayland()
});
if (!servicesFound.isEmpty()) {
Q_EMIT appActivationStarted(appId, servicesFound.constFirst()->icon());
QString iconName = servicesFound.constFirst()->icon();
// Connect signal to when activation is complete to trigger event
connect(activation, &PlasmaActivation::finished, this, [this, appId, iconName]() {
Q_EMIT appActivationFinished(appId, iconName);
});
// Trigger app activation event
Q_EMIT appActivationStarted(appId, iconName);
} else {
qDebug() << "WindowUtil: Could not find service" << appId;
}
});
connect(activation, &PlasmaActivation::finished, this, &WindowUtil::appActivationFinished);
});
});

View file

@ -107,8 +107,8 @@ Q_SIGNALS:
// Emitted when an application is launched
void appActivationStarted(const QString &appId, const QString &iconName);
// Emitted the application has finished launching
void appActivationFinished();
// Emitted when an application has finished launching
void appActivationFinished(const QString &appId, const QString &iconName);
private Q_SLOTS:
void updateActiveWindowIsShell();

View file

@ -11,6 +11,7 @@ import org.kde.kirigami 2.20 as Kirigami
import org.kde.private.mobile.homescreen.folio 1.0 as Folio
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.plasmoid
AbstractDelegate {
id: root
@ -27,12 +28,13 @@ AbstractDelegate {
function launchApp() {
if (application.icon !== "") {
MobileShellState.ShellDBusClient.openAppLaunchAnimation(
application.icon,
application.name,
root.iconItem.Kirigami.ScenePosition.x + root.iconItem.width/2,
root.iconItem.Kirigami.ScenePosition.y + root.iconItem.height/2,
Math.min(root.iconItem.width, root.iconItem.height));
MobileShellState.ShellDBusClient.openAppLaunchAnimationWithPosition(
Plasmoid.screen,
application.icon,
application.name,
root.iconItem.Kirigami.ScenePosition.x + root.iconItem.width/2,
root.iconItem.Kirigami.ScenePosition.y + root.iconItem.height/2,
Math.min(root.iconItem.width, root.iconItem.height));
}
application.setMinimizedDelegate(root);

View file

@ -14,6 +14,7 @@ import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutM
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.plasma.plasmoid
import org.kde.kirigami 2.19 as Kirigami
@ -77,12 +78,13 @@ Item {
function launchAppWithAnim(x: int, y: int, source, title: string, storageId: string) {
if (source !== "") {
MobileShellState.ShellDBusClient.openAppLaunchAnimation(
source,
title,
iconLoader.Kirigami.ScenePosition.x + iconLoader.width/2,
iconLoader.Kirigami.ScenePosition.y + iconLoader.height/2,
Math.min(iconLoader.width, iconLoader.height));
MobileShellState.ShellDBusClient.openAppLaunchAnimationWithPosition(
Plasmoid.screen,
source,
title,
iconLoader.Kirigami.ScenePosition.x + iconLoader.width/2,
iconLoader.Kirigami.ScenePosition.y + iconLoader.height/2,
Math.min(iconLoader.width, iconLoader.height));
}
application.setMinimizedDelegate(delegate);

View file

@ -13,6 +13,7 @@ import org.kde.kirigami 2.10 as Kirigami
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.private.mobile.homescreen.halcyon 1.0 as Halcyon
import org.kde.plasma.plasmoid
MobileShell.GridView {
id: gridView
@ -88,12 +89,13 @@ MobileShell.GridView {
onLaunch: (x, y, icon, title, storageId) => {
if (icon !== "") {
MobileShellState.ShellDBusClient.openAppLaunchAnimation(
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));
MobileShellState.ShellDBusClient.openAppLaunchAnimationWithPosition(
Plasmoid.screen,
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));
}
application.setMinimizedDelegate(delegate);