From e2e6590222737a0403c31678bfb2d23a125c8c94 Mon Sep 17 00:00:00 2001 From: Devin Lin Date: Sat, 9 Mar 2024 22:50:55 -0500 Subject: [PATCH] startupfeedback: Add support for multiple screens Addresses https://invent.kde.org/plasma/plasma-mobile/-/issues/175 --- .../quicksettings/QuickSettingsDelegate.qml | 26 ++++++----- .../qml/components/StartupFeedback.qml | 44 ++++++++++++++----- .../mobileshell/qml/homescreen/HomeScreen.qml | 16 ++++++- .../mobileshell/qml/volumeosd/VolumeOSD.qml | 1 - .../mobileshellstate/shelldbusclient.cpp | 13 +++++- components/mobileshellstate/shelldbusclient.h | 6 ++- .../mobileshellstate/shelldbusobject.cpp | 9 +++- components/mobileshellstate/shelldbusobject.h | 6 ++- components/windowplugin/windowutil.cpp | 14 ++++-- components/windowplugin/windowutil.h | 4 +- .../contents/ui/delegate/AppDelegate.qml | 14 +++--- .../contents/ui/FavoritesAppDelegate.qml | 14 +++--- .../package/contents/ui/GridAppList.qml | 14 +++--- 13 files changed, 125 insertions(+), 56 deletions(-) diff --git a/components/mobileshell/qml/actiondrawer/quicksettings/QuickSettingsDelegate.qml b/components/mobileshell/qml/actiondrawer/quicksettings/QuickSettingsDelegate.qml index 79b7e5ac..4b932023 100644 --- a/components/mobileshell/qml/actiondrawer/quicksettings/QuickSettingsDelegate.qml +++ b/components/mobileshell/qml/actiondrawer/quicksettings/QuickSettingsDelegate.qml @@ -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; + } } diff --git a/components/mobileshell/qml/components/StartupFeedback.qml b/components/mobileshell/qml/components/StartupFeedback.qml index 4f172e92..a10cdadd 100644 --- a/components/mobileshell/qml/components/StartupFeedback.qml +++ b/components/mobileshell/qml/components/StartupFeedback.qml @@ -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(); } } } diff --git a/components/mobileshell/qml/homescreen/HomeScreen.qml b/components/mobileshell/qml/homescreen/HomeScreen.qml index cd569be6..0afa7cc2 100644 --- a/components/mobileshell/qml/homescreen/HomeScreen.qml +++ b/components/mobileshell/qml/homescreen/HomeScreen.qml @@ -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() { diff --git a/components/mobileshell/qml/volumeosd/VolumeOSD.qml b/components/mobileshell/qml/volumeosd/VolumeOSD.qml index 476bf87c..cceeb46b 100644 --- a/components/mobileshell/qml/volumeosd/VolumeOSD.qml +++ b/components/mobileshell/qml/volumeosd/VolumeOSD.qml @@ -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"); } } diff --git a/components/mobileshellstate/shelldbusclient.cpp b/components/mobileshellstate/shelldbusclient.cpp index 8b17edc0..701ceab5 100644 --- a/components/mobileshellstate/shelldbusclient.cpp +++ b/components/mobileshellstate/shelldbusclient.cpp @@ -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() diff --git a/components/mobileshellstate/shelldbusclient.h b/components/mobileshellstate/shelldbusclient.h index 29a43afd..f2f620d7 100644 --- a/components/mobileshellstate/shelldbusclient.h +++ b/components/mobileshellstate/shelldbusclient.h @@ -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(); diff --git a/components/mobileshellstate/shelldbusobject.cpp b/components/mobileshellstate/shelldbusobject.cpp index d8897d17..2af26c70 100644 --- a/components/mobileshellstate/shelldbusobject.cpp +++ b/components/mobileshellstate/shelldbusobject.cpp @@ -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() diff --git a/components/mobileshellstate/shelldbusobject.h b/components/mobileshellstate/shelldbusobject.h index b1dbca14..7121428c 100644 --- a/components/mobileshellstate/shelldbusobject.h +++ b/components/mobileshellstate/shelldbusobject.h @@ -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(); diff --git a/components/windowplugin/windowutil.cpp b/components/windowplugin/windowutil.cpp index 27458836..51427e4d 100644 --- a/components/windowplugin/windowutil.cpp +++ b/components/windowplugin/windowutil.cpp @@ -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); }); }); diff --git a/components/windowplugin/windowutil.h b/components/windowplugin/windowutil.h index 13ff7228..b13fdad7 100644 --- a/components/windowplugin/windowutil.h +++ b/components/windowplugin/windowutil.h @@ -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(); diff --git a/containments/homescreens/folio/package/contents/ui/delegate/AppDelegate.qml b/containments/homescreens/folio/package/contents/ui/delegate/AppDelegate.qml index b16c34ce..9af8b7fb 100644 --- a/containments/homescreens/folio/package/contents/ui/delegate/AppDelegate.qml +++ b/containments/homescreens/folio/package/contents/ui/delegate/AppDelegate.qml @@ -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); diff --git a/containments/homescreens/halcyon/package/contents/ui/FavoritesAppDelegate.qml b/containments/homescreens/halcyon/package/contents/ui/FavoritesAppDelegate.qml index b3433344..93afa924 100644 --- a/containments/homescreens/halcyon/package/contents/ui/FavoritesAppDelegate.qml +++ b/containments/homescreens/halcyon/package/contents/ui/FavoritesAppDelegate.qml @@ -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); diff --git a/containments/homescreens/halcyon/package/contents/ui/GridAppList.qml b/containments/homescreens/halcyon/package/contents/ui/GridAppList.qml index 70dd2cd2..795ba26f 100644 --- a/containments/homescreens/halcyon/package/contents/ui/GridAppList.qml +++ b/containments/homescreens/halcyon/package/contents/ui/GridAppList.qml @@ -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);