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}
This commit is contained in:
User8395 2025-03-13 20:11:41 +00:00 committed by Devin Lin
parent aab403b9f8
commit 3a2c3bc742
5 changed files with 200 additions and 0 deletions

View file

@ -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();
}

View file

@ -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);

View file

@ -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
}
}
}
}

View file

@ -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

View file

@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: 2025 User8395 <therealuser8395@proton.me>
// 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;
}
}
}