From 3a2c3bc742c119a00f6aec385e45d90bee9c967b Mon Sep 17 00:00:00 2001 From: User8395 Date: Thu, 13 Mar 2025 20:11:41 +0000 Subject: [PATCH] lockscreen: add quick action buttons Closes: #441 Notes: - Camera cannot be selected as an action due to #377 ![image](/uploads/a97cad90219897b730d88b8aa43d49f3/image.png){width=461 height=288} --- .../mobileshellsettings.cpp | 31 ++++++++++ .../shellsettingsplugin/mobileshellsettings.h | 40 +++++++++++++ kcms/mobileshell/ui/main.qml | 57 +++++++++++++++++++ shell/contents/lockscreen/LockScreen.qml | 25 ++++++++ .../contents/lockscreen/QuickActionButton.qml | 47 +++++++++++++++ 5 files changed, 200 insertions(+) create mode 100644 shell/contents/lockscreen/QuickActionButton.qml diff --git a/components/shellsettingsplugin/mobileshellsettings.cpp b/components/shellsettingsplugin/mobileshellsettings.cpp index b9e3fc8d..b637e7a7 100644 --- a/components/shellsettingsplugin/mobileshellsettings.cpp +++ b/components/shellsettingsplugin/mobileshellsettings.cpp @@ -18,6 +18,7 @@ const QString CONFIG_FILE = QStringLiteral("plasmamobilerc"); const QString GENERAL_CONFIG_GROUP = QStringLiteral("General"); +const QString LOCKSCREEN_CONFIG_GROUP = QStringLiteral("Lockscreen"); MobileShellSettings::MobileShellSettings(QObject *parent) : QObject{parent} @@ -41,6 +42,10 @@ MobileShellSettings::MobileShellSettings(QObject *parent) Q_EMIT convergenceModeEnabledChanged(); Q_EMIT allowLogoutChanged(); } + if (group.name() == LOCKSCREEN_CONFIG_GROUP) { + Q_EMIT lockscreenLeftButtonActionChanged(); + Q_EMIT lockscreenRightButtonActionChanged(); + } }); } @@ -224,3 +229,29 @@ bool MobileShellSettings::allowLogout() const auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP}; return group.readEntry("allowLogout", true); } + +MobileShellSettings::LockscreenButtonAction MobileShellSettings::lockscreenLeftButtonAction() const +{ + auto group = KConfigGroup{m_config, LOCKSCREEN_CONFIG_GROUP}; + return (LockscreenButtonAction)group.readEntry("lockscreenLeftButtonAction", (int)LockscreenButtonAction::None); +} + +void MobileShellSettings::setLockscreenLeftButtonAction(const LockscreenButtonAction action) +{ + auto group = KConfigGroup{m_config, LOCKSCREEN_CONFIG_GROUP}; + group.writeEntry("lockscreenLeftButtonAction", (int)action, KConfigGroup::Notify); + m_config->sync(); +} + +MobileShellSettings::LockscreenButtonAction MobileShellSettings::lockscreenRightButtonAction() const +{ + auto group = KConfigGroup{m_config, LOCKSCREEN_CONFIG_GROUP}; + return (LockscreenButtonAction)group.readEntry("lockscreenRightButtonAction", (int)LockscreenButtonAction::None); +} + +void MobileShellSettings::setLockscreenRightButtonAction(const LockscreenButtonAction action) +{ + auto group = KConfigGroup{m_config, LOCKSCREEN_CONFIG_GROUP}; + group.writeEntry("lockscreenRightButtonAction", (int)action, KConfigGroup::Notify); + m_config->sync(); +} \ No newline at end of file diff --git a/components/shellsettingsplugin/mobileshellsettings.h b/components/shellsettingsplugin/mobileshellsettings.h index 86194ece..1d8fe06e 100644 --- a/components/shellsettingsplugin/mobileshellsettings.h +++ b/components/shellsettingsplugin/mobileshellsettings.h @@ -48,6 +48,12 @@ class MobileShellSettings : public QObject // logout dialog Q_PROPERTY(bool allowLogout READ allowLogout READ allowLogout NOTIFY allowLogoutChanged) + // locksreen shortcut icons + Q_PROPERTY(LockscreenButtonAction lockscreenLeftButtonAction READ lockscreenLeftButtonAction WRITE setLockscreenLeftButtonAction NOTIFY + lockscreenLeftButtonActionChanged) + Q_PROPERTY(LockscreenButtonAction lockscreenRightButtonAction READ lockscreenRightButtonAction WRITE setLockscreenRightButtonAction NOTIFY + lockscreenRightButtonActionChanged) + public: MobileShellSettings(QObject *parent = nullptr); @@ -57,6 +63,14 @@ public: }; Q_ENUM(ActionDrawerMode) + enum LockscreenButtonAction { + None, // hide the button + Flashlight, // toggle flashlight/torch + Camera, // camera + OpenApp // cant be selected, no support yet + }; + Q_ENUM(LockscreenButtonAction) + /** * Get whether shell vibrations are enabled. */ @@ -198,6 +212,30 @@ public: */ bool allowLogout() const; + /** + * The action of the left lock screen shortcut + */ + LockscreenButtonAction lockscreenLeftButtonAction() const; + + /** + * Set the action of the left lock screen shortcut + * + * @param action + */ + void setLockscreenLeftButtonAction(LockscreenButtonAction action); + + /** + * The action of the right lock screen shortcut + */ + LockscreenButtonAction lockscreenRightButtonAction() const; + + /** + * Set the action of the right lock screen shortcut + * + * @param action + */ + void setLockscreenRightButtonAction(LockscreenButtonAction action); + Q_SIGNALS: void vibrationsEnabledChanged(); void vibrationDurationChanged(); @@ -212,6 +250,8 @@ Q_SIGNALS: void actionDrawerTopRightModeChanged(); void convergenceModeEnabledChanged(); void allowLogoutChanged(); + void lockscreenLeftButtonActionChanged(); + void lockscreenRightButtonActionChanged(); private: void updateNavigationBarsInPlasma(bool navigationPanelEnabled); diff --git a/kcms/mobileshell/ui/main.qml b/kcms/mobileshell/ui/main.qml index ed030b28..27eeb1c8 100644 --- a/kcms/mobileshell/ui/main.qml +++ b/kcms/mobileshell/ui/main.qml @@ -207,5 +207,62 @@ KCM.SimpleKCM { onCurrentValueChanged: ShellSettings.Settings.actionDrawerTopRightMode = currentValue } } + + FormCard.FormHeader { + title: i18nc("@title:group", "Lock Screen Shortcuts") + } + + FormCard.FormCard { + id: quickActionButtons + property string noneString: i18nc("@item:inlistbox", "None") + property string flashlightString: i18nc("@item:inlistbox", "Flashlight") + property string cameraString: i18nc("@item:inlistbox", "Camera") + + FormCard.FormComboBoxDelegate { + id: lockscreenLeftButtonDelegate + text: i18nc("@label:listbox", "Left button") + + model: ListModel { + Component.onCompleted: { + append({"name": quickActionButtons.noneString, "value": ShellSettings.Settings.None}); + append({"name": quickActionButtons.flashlightString, "value": ShellSettings.Settings.Flashlight}); + // append({"name": quickActionButtons.cameraString, "value": ShellSettings.Settings.Camera}); + lockscreenLeftButtonDelegate.currentIndex = lockscreenLeftButtonDelegate.indexOfValue(ShellSettings.Settings.lockscreenLeftButtonAction) + } + } + + textRole: "name" + valueRole: "value" + + Component.onCompleted: { + dialog.parent = root + } + onCurrentValueChanged: ShellSettings.Settings.lockscreenLeftButtonAction = currentValue + } + + FormCard.FormDelegateSeparator { above: lockscreenRightButtonDelegate; below: lockscreenLeftButtonDelegate } + + FormCard.FormComboBoxDelegate { + id: lockscreenRightButtonDelegate + text: i18nc("@label:listbox", "Right button") + + model: ListModel { + Component.onCompleted: { + append({"name": quickActionButtons.noneString, "value": ShellSettings.Settings.None}); + append({"name": quickActionButtons.flashlightString, "value": ShellSettings.Settings.Flashlight}); + // append({"name": quickActionButtons.cameraString, "value": ShellSettings.Settings.Camera}); + lockscreenRightButtonDelegate.currentIndex = lockscreenRightButtonDelegate.indexOfValue(ShellSettings.Settings.lockscreenRightButtonAction) + } + } + + textRole: "name" + valueRole: "value" + + Component.onCompleted: { + dialog.parent = root + } + onCurrentValueChanged: ShellSettings.Settings.lockscreenRightButtonAction = currentValue + } + } } } diff --git a/shell/contents/lockscreen/LockScreen.qml b/shell/contents/lockscreen/LockScreen.qml index 6ac8c989..94346d5e 100644 --- a/shell/contents/lockscreen/LockScreen.qml +++ b/shell/contents/lockscreen/LockScreen.qml @@ -9,6 +9,7 @@ import QtQuick.Layouts import org.kde.plasma.core as PlasmaCore import org.kde.notificationmanager as Notifications import org.kde.plasma.private.mobileshell as MobileShell +import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings import org.kde.plasma.private.mobileshell.dpmsplugin as DPMS import org.kde.plasma.components 3.0 as PC3 @@ -212,6 +213,18 @@ Item { anchors.right: parent.right } + QuickActionButton { + id: leftButton + buttonAction: ShellSettings.Settings.lockscreenLeftButtonAction + opacity: Math.max(0, 1 - flickable.openFactor * 2) + anchors { + bottom: parent.bottom + left: parent.left + bottomMargin: Kirigami.Units.largeSpacing * 3 + leftMargin: Kirigami.Units.largeSpacing * 3 + } + } + // scroll up icon BottomIconIndicator { id: scrollUpIconLoader @@ -223,6 +236,18 @@ Item { anchors.horizontalCenter: parent.horizontalCenter } + QuickActionButton { + id: rightButton + buttonAction: ShellSettings.Settings.lockscreenRightButtonAction + opacity: Math.max(0, 1 - flickable.openFactor * 2) + anchors { + bottom: parent.bottom + right: parent.right + bottomMargin: Kirigami.Units.largeSpacing * 3 + rightMargin: Kirigami.Units.largeSpacing * 3 + } + } + Rectangle { id: keypadScrim anchors.fill: parent diff --git a/shell/contents/lockscreen/QuickActionButton.qml b/shell/contents/lockscreen/QuickActionButton.qml new file mode 100644 index 00000000..bdfbf278 --- /dev/null +++ b/shell/contents/lockscreen/QuickActionButton.qml @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2025 User8395 +// SPDX-License-Identifier: GPL-2.0-or-later + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import org.kde.plasma.quicksetting.flashlight 1.0 +import org.kde.plasma.private.mobileshell as MobileShell +import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings +import org.kde.kirigami as Kirigami + +Button { + id: root + property int buttonAction + + visible: buttonAction !== ShellSettings.Settings.None + highlighted: buttonAction === ShellSettings.Settings.Flashlight ? FlashlightUtil.torchEnabled() : false + display: Button.IconOnly + icon.name: { + switch (buttonAction) { + case ShellSettings.Settings.Flashlight: + return "flashlight-on-symbolic" + case ShellSettings.Settings.Camera: + return "camera-photo-symbolic" + } + } + text: { + switch (buttonAction) { + case ShellSettings.Settings.Flashlight: + return i18nc("@action:button", "Turn flashlight on"); + case ShellSettings.Settings.Camera: + return i18nc("@action:button", "Open camera"); + } + } + onClicked: { + switch (buttonAction) { + case ShellSettings.Settings.Flashlight: + FlashlightUtil.toggleTorch(); + return; + case ShellSettings.Settings.Camera: + MobileShell.ShellUtil.launchApp("org.kde.plasma.camera"); + flickable.goToOpenPosition(); + return; + } + } +} \ No newline at end of file