Compare commits

..

No commits in common. "c23d756596efa3ccab9f5e2d387b730b2f277d34" and "e5ec88a12b93be9268f1a5636cc161f9d17b47c6" have entirely different histories.

8 changed files with 35 additions and 601 deletions

View file

@ -141,7 +141,6 @@ ecm_target_qml_sources(mobileshellplugin SOURCES
qml/actiondrawer/private/QuickSettingsPanel.qml
qml/actiondrawer/private/ContentContainer.qml
qml/actiondrawer/private/DetailPopup.qml
qml/actiondrawer/private/SystemTrayPopup.qml
qml/actiondrawer/private/LandscapeContentContainer.qml
qml/actiondrawer/private/NotificationDrawer.qml
qml/actiondrawer/private/PortraitContentContainer.qml

View file

@ -55,16 +55,6 @@ QQC2.Popup {
popup.open();
}
Connections {
target: MobileShell.AppletHost
function onAppletReady(pluginId) {
if (pluginId === popup.currentPluginId && !popup.opened) {
popup.show(pluginId);
}
}
}
onClosed: {
if (__currentItem) {
__currentItem.visible = false;

View file

@ -46,9 +46,9 @@ Item {
readonly property int columnCount: Math.floor(width/columnWidth)
readonly property int rowCount: {
let totalRows = Math.ceil(quickSettingsCount / columnCount);
let maxRows = root.isConvergence ? 3 : 5; // more than 5 is just disorienting
let targetRows = Math.floor(Window.height * (root.isConvergence ? 0.42 : 0.65) / rowHeight);
return Math.max(1, Math.min(maxRows, Math.min(totalRows, targetRows)));
let maxRows = 5; // more than 5 is just disorienting
let targetRows = Math.floor(Window.height * 0.65 / rowHeight);
return Math.min(maxRows, Math.min(totalRows, targetRows));
}
readonly property int pageSize: rowCount * columnCount
@ -63,10 +63,6 @@ Item {
})
readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled
function isManagementTile(cmd) { return cmd in __managementCommands; }
readonly property int promotedColumns: isConvergence && width >= Kirigami.Units.gridUnit * 18 ? 2 : 1
readonly property real promotedSpacing: Kirigami.Units.smallSpacing
readonly property real promotedHorizontalMargin: Kirigami.Units.smallSpacing
readonly property real promotedCellWidth: Math.floor((width - 2 * promotedHorizontalMargin - (promotedColumns - 1) * promotedSpacing) / promotedColumns)
readonly property alias brightnessPressedValue: brightnessItem.brightnessPressedValue
@ -140,72 +136,21 @@ Item {
anchors.left: parent.left
anchors.right: parent.right
// Promoted desktop controls (convergence mode only)
GridLayout {
id: promotedGrid
// Management status rows (convergence mode only)
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: root.promotedHorizontalMargin
Layout.rightMargin: root.promotedHorizontalMargin
Layout.leftMargin: Kirigami.Units.smallSpacing
Layout.rightMargin: Kirigami.Units.smallSpacing
Layout.bottomMargin: Kirigami.Units.smallSpacing
columns: root.promotedColumns
rowSpacing: root.promotedSpacing
columnSpacing: root.promotedSpacing
spacing: Kirigami.Units.smallSpacing
visible: root.isConvergence
Repeater {
model: [
{
text: i18n("Clipboard"),
status: i18n("History"),
icon: "klipper-symbolic",
pluginId: "org.kde.plasma.clipboard"
},
{
text: i18n("Disks & Devices"),
status: i18n("Removable media"),
icon: "device-notifier-symbolic",
pluginId: "org.kde.plasma.devicenotifier"
},
{
text: i18n("System Tray"),
status: systemTrayPopup.trayItemCount > 0 ? i18np("%1 status item", "%1 status items", systemTrayPopup.trayItemCount) : i18n("No status items"),
icon: "preferences-desktop-notification-symbolic",
trayPopup: true
}
]
delegate: QuickSettingsStatusRow {
required property var modelData
Layout.preferredWidth: root.promotedCellWidth
Layout.fillWidth: true
compact: true
text: modelData.text
status: modelData.status
icon: modelData.icon
enabled: false
toggleFunction: null
onDetailClicked: {
if (modelData.trayPopup) {
systemTrayPopup.show();
} else {
detailPopup.show(modelData.pluginId);
}
}
}
}
Repeater {
model: root.quickSettingsModel
delegate: QuickSettingsStatusRow {
required property var modelData
readonly property bool isPromoted: root.isManagementTile(modelData.settingsCommand)
Layout.preferredWidth: isPromoted ? root.promotedCellWidth : 0
Layout.preferredHeight: isPromoted ? implicitHeight : 0
Layout.maximumWidth: isPromoted ? root.promotedCellWidth : 0
Layout.maximumHeight: isPromoted ? implicitHeight : 0
Layout.fillWidth: true
visible: isPromoted
compact: true
visible: root.isManagementTile(modelData.settingsCommand)
text: modelData.text
status: modelData.status
icon: modelData.icon
@ -341,9 +286,4 @@ Item {
parent: root.Window.window ? root.Window.window.contentItem : root
}
SystemTrayPopup {
id: systemTrayPopup
parent: root.Window.window ? root.Window.window.contentItem : root
}
}

View file

@ -9,7 +9,8 @@ import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
/**
* Management/detail row shown in convergence mode. Two interaction zones:
* Full-width management row (Wi-Fi, Bluetooth, Audio, Battery) shown in
* convergence mode. Two interaction zones:
* - Left toggle pill: icon + indicator dot, tap toggles the service.
* - Right detail area: name + status + chevron, tap opens detail popup.
*/
@ -21,11 +22,10 @@ Item {
required property string icon
required property bool enabled
required property var toggleFunction
property bool compact: false
signal detailClicked()
implicitHeight: Kirigami.Units.gridUnit * (compact ? 3.1 : 3.6)
implicitHeight: Kirigami.Units.gridUnit * 3.6
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Button
@ -35,7 +35,6 @@ Item {
readonly property color enabledBgHover: mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.32)
readonly property color enabledBgPressed: mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.12)
readonly property color enabledBorder: Qt.darker(Kirigami.Theme.highlightColor, 1.25)
readonly property bool hasToggle: toggleFunction !== null && toggleFunction !== undefined
readonly property color disabledBg: Kirigami.Theme.alternateBackgroundColor
readonly property color disabledBgHover: mixColor(Kirigami.Theme.alternateBackgroundColor, Kirigami.Theme.textColor, 0.06)
@ -147,10 +146,8 @@ Item {
// Indicator bar
Rectangle {
Layout.alignment: Qt.AlignHCenter
visible: root.hasToggle
Layout.preferredHeight: visible ? Math.max(2, Math.round(Kirigami.Units.devicePixelRatio)) : 0
width: root.enabled ? Kirigami.Units.smallSpacing * 3 : Kirigami.Units.smallSpacing * 1.5
height: Layout.preferredHeight
height: Math.max(2, Math.round(Kirigami.Units.devicePixelRatio))
radius: height / 2
color: root.enabled ? Kirigami.Theme.highlightColor : Kirigami.Theme.disabledTextColor
opacity: root.enabled ? 1.0 : 0.4
@ -165,14 +162,10 @@ Item {
id: toggleMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: root.hasToggle ? Qt.PointingHandCursor : Qt.ArrowCursor
onPressed: {
if (root.hasToggle) {
haptics.buttonVibrate()
}
}
cursorShape: Qt.PointingHandCursor
onPressed: haptics.buttonVibrate()
onClicked: {
if (root.hasToggle) root.toggleFunction();
if (root.toggleFunction) root.toggleFunction();
}
}
}

View file

@ -1,238 +0,0 @@
// SPDX-FileCopyrightText: 2026 Marco Allegretti
// SPDX-License-Identifier: EUPL-1.2
import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.1
import org.kde.kirigami as Kirigami
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.systemtray as SystemTray
QQC2.Popup {
id: popup
modal: true
dim: true
closePolicy: QQC2.Popup.CloseOnEscape | QQC2.Popup.CloseOnPressOutside
x: parent ? Math.round((parent.width - width) / 2) : 0
y: parent ? Math.round((parent.height - height) / 2) : 0
width: Math.min(Kirigami.Units.gridUnit * 22,
parent ? parent.width - Kirigami.Units.gridUnit * 4 : 420)
height: Math.min(Kirigami.Units.gridUnit * 24,
parent ? parent.height - Kirigami.Units.gridUnit * 4 : 480)
padding: Kirigami.Units.smallSpacing
readonly property int trayItemCount: trayList.count
function show() {
popup.open();
}
SystemTray.StatusNotifierModel {
id: trayModel
}
background: Kirigami.ShadowedRectangle {
color: Kirigami.Theme.backgroundColor
radius: Kirigami.Units.cornerRadius
border.color: Kirigami.ColorUtils.linearInterpolation(
Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.2)
border.width: 1
shadow.size: Kirigami.Units.gridUnit
shadow.color: Qt.rgba(0, 0, 0, 0.45)
shadow.yOffset: 2
}
contentItem: ColumnLayout {
spacing: Kirigami.Units.smallSpacing
RowLayout {
Layout.fillWidth: true
Layout.leftMargin: Kirigami.Units.smallSpacing
Layout.rightMargin: Kirigami.Units.smallSpacing
Layout.topMargin: Kirigami.Units.smallSpacing
spacing: Kirigami.Units.smallSpacing
Kirigami.Icon {
Layout.alignment: Qt.AlignVCenter
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: implicitWidth
source: "preferences-desktop-notification-symbolic"
}
ColumnLayout {
Layout.fillWidth: true
spacing: 0
QQC2.Label {
Layout.fillWidth: true
text: i18n("System Tray")
font.weight: Font.Bold
elide: Text.ElideRight
}
QQC2.Label {
Layout.fillWidth: true
text: trayList.count > 0 ? i18np("%1 status item", "%1 status items", trayList.count) : i18n("No status items")
opacity: 0.65
elide: Text.ElideRight
}
}
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 1
color: Kirigami.ColorUtils.linearInterpolation(
Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.12)
}
ListView {
id: trayList
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
spacing: Kirigami.Units.smallSpacing
boundsBehavior: Flickable.StopAtBounds
model: trayModel
delegate: Item {
id: trayItem
width: ListView.view.width
height: Kirigami.Units.gridUnit * 3
readonly property string itemTitle: model.toolTipTitle ? model.toolTipTitle : (model.title ? model.title : i18n("Status Item"))
readonly property string itemStatus: {
if (model.status === "Passive") {
return i18n("Hidden");
}
if (model.category === "ApplicationStatus") {
return i18n("Application status");
}
return model.status ? model.status : i18n("Active");
}
readonly property bool itemActive: model.category !== "ApplicationStatus" && model.status !== "Passive"
function triggerOperation(operationName) {
if (!model.service) {
return;
}
let operation = model.service.operationDescription(operationName);
if (!operation) {
return;
}
let operationPoint = trayItem.mapToGlobal(trayItem.width, trayItem.height / 2);
operation.x = operationPoint.x;
operation.y = operationPoint.y;
model.service.startOperationCall(operation);
}
Rectangle {
id: rowBackground
anchors.fill: parent
anchors.leftMargin: Kirigami.Units.smallSpacing
anchors.rightMargin: Kirigami.Units.smallSpacing
radius: Kirigami.Units.cornerRadius
color: trayMouse.pressed ? Qt.rgba(Kirigami.Theme.textColor.r,
Kirigami.Theme.textColor.g,
Kirigami.Theme.textColor.b, 0.08)
: trayMouse.containsMouse ? Qt.rgba(Kirigami.Theme.textColor.r,
Kirigami.Theme.textColor.g,
Kirigami.Theme.textColor.b, 0.04)
: Kirigami.Theme.alternateBackgroundColor
border.width: 1
border.color: Kirigami.ColorUtils.linearInterpolation(
Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, trayItem.itemActive ? 0.16 : 0.08)
opacity: trayItem.itemActive ? 1 : 0.72
}
RowLayout {
anchors.fill: rowBackground
anchors.leftMargin: Kirigami.Units.smallSpacing * 2
anchors.rightMargin: Kirigami.Units.smallSpacing * 2
spacing: Kirigami.Units.smallSpacing
Kirigami.Icon {
Layout.alignment: Qt.AlignVCenter
implicitWidth: Kirigami.Units.iconSizes.smallMedium
implicitHeight: implicitWidth
source: model.iconName ? model.iconName : (model.icon ? model.icon : "")
}
ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
spacing: 2
MobileShell.MarqueeLabel {
Layout.fillWidth: true
inputText: trayItem.itemTitle
font.weight: Font.Bold
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.9
}
MobileShell.MarqueeLabel {
Layout.fillWidth: true
inputText: trayItem.itemStatus
opacity: 0.6
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 0.8
}
}
Kirigami.Icon {
Layout.alignment: Qt.AlignVCenter
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: implicitWidth
source: "go-next-symbolic"
opacity: 0.45
}
}
QQC2.ToolTip.text: trayItem.itemTitle
QQC2.ToolTip.visible: trayMouse.containsMouse && trayItem.itemTitle !== ""
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
MouseArea {
id: trayMouse
anchors.fill: rowBackground
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: (mouse) => {
trayItem.triggerOperation(mouse.button === Qt.RightButton ? "ContextMenu" : "Activate");
}
}
}
QQC2.Label {
anchors.centerIn: parent
visible: trayList.count === 0
text: i18n("No status items")
opacity: 0.65
}
}
}
enter: Transition {
NumberAnimation { property: "opacity"; from: 0; to: 1; duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
NumberAnimation { property: "scale"; from: 0.9; to: 1; duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
}
exit: Transition {
NumberAnimation { property: "opacity"; from: 1; to: 0; duration: Kirigami.Units.shortDuration; easing.type: Easing.InCubic }
}
QQC2.Overlay.modal: Rectangle {
color: Qt.rgba(0, 0, 0, 0.5)
}
}

View file

@ -62,6 +62,11 @@ MouseArea {
return "transparent"
}
// Center x for dock items (offset between nav buttons in convergence mode)
readonly property real dockCenterX: convergenceMode
? navButtonWidth + (root.width - 2 * navButtonWidth) / 2
: root.width / 2
// Visible spacer between pinned favourites and running tasks
readonly property bool showSpacer: showRunningTasks && repeater.count > 0 && taskRepeater.count > 0
property real spacerWidth: showSpacer ? Kirigami.Units.largeSpacing * 2 : 0
@ -94,15 +99,8 @@ MouseArea {
readonly property int pagerLeftCount: showPager ? Math.ceil(virtualDesktopInfo.numberOfDesktops / 2) : 0
readonly property int pagerRightCount: showPager ? virtualDesktopInfo.numberOfDesktops - pagerLeftCount : 0
property real trashButtonWidth: convergenceMode ? root.height : 0
property real searchButtonWidth: convergenceMode ? root.height : 0
readonly property real leftControlsWidth: convergenceMode ? navButtonWidth + pagerLeftCount * pagerButtonWidth : 0
readonly property real rightControlsWidth: convergenceMode ? navButtonWidth + searchButtonWidth + trashButtonWidth + pagerRightCount * pagerButtonWidth : 0
readonly property real dockCenterX: convergenceMode
? leftControlsWidth + (root.width - leftControlsWidth - rightControlsWidth) / 2
: root.width / 2
Behavior on pagerButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
Behavior on trashButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
Behavior on searchButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
function pagerDesktopName(index) {
let names = virtualDesktopInfo.desktopNames
@ -149,7 +147,7 @@ MouseArea {
return (ids && i < ids.length) ? String(ids[i]) : ""
}
for (let i = 0; i < pagerRightCount; ++i) {
let bx = root.width - navButtonWidth - root.searchButtonWidth - root.trashButtonWidth - (pagerRightCount - i) * pagerButtonWidth
let bx = root.width - navButtonWidth - root.trashButtonWidth - (pagerRightCount - i) * pagerButtonWidth
if (x >= bx && x < bx + pagerButtonWidth) {
let di = pagerLeftCount + i
return (ids && di < ids.length) ? String(ids[di]) : ""
@ -239,7 +237,7 @@ MouseArea {
if (first) { first.keyboardFocus(); return }
let firstTask = taskRepeater.itemAt(0)
if (firstTask) { firstTask.forceActiveFocus(); return }
searchButton.forceActiveFocus()
overviewButton.forceActiveFocus()
}
KeyboardHighlight {
@ -300,7 +298,11 @@ MouseArea {
Keys.onEnterPressed: root.folio.triggerOverview()
Keys.onSpacePressed: root.folio.triggerOverview()
Keys.onLeftPressed: {
searchButton.forceActiveFocus()
let lastTask = taskRepeater.itemAt(taskRepeater.count - 1)
if (lastTask) { lastTask.forceActiveFocus(); return }
let lastFav = repeater.itemAt(repeater.count - 1)
if (lastFav) { lastFav.keyboardFocus(); return }
homeButton.forceActiveFocus()
}
KeyboardHighlight {
@ -336,77 +338,6 @@ MouseArea {
}
}
// Search button (convergence mode, immediately left of Overview)
Rectangle {
id: searchButton
visible: root.convergenceMode || opacity > 0
enabled: root.convergenceMode
opacity: root.convergenceMode ? 1 : 0
activeFocusOnTab: root.convergenceMode
x: root.width - root.navButtonWidth - root.searchButtonWidth
y: 0
width: root.searchButtonWidth
height: root.height
color: "transparent"
Behavior on opacity {
NumberAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.InOutQuad }
}
Accessible.role: Accessible.Button
Accessible.name: i18n("Search")
Accessible.onPressAction: root.folio.HomeScreenState.openSearchWidget()
Keys.onReturnPressed: root.folio.HomeScreenState.openSearchWidget()
Keys.onEnterPressed: root.folio.HomeScreenState.openSearchWidget()
Keys.onSpacePressed: root.folio.HomeScreenState.openSearchWidget()
Keys.onLeftPressed: {
let lastTask = taskRepeater.itemAt(taskRepeater.count - 1)
if (lastTask) { lastTask.forceActiveFocus(); return }
let lastFav = repeater.itemAt(repeater.count - 1)
if (lastFav) { lastFav.keyboardFocus(); return }
homeButton.forceActiveFocus()
}
Keys.onRightPressed: overviewButton.forceActiveFocus()
KeyboardHighlight {
anchors.fill: parent
visible: searchButton.activeFocus
}
Rectangle {
anchors.fill: parent
anchors.margins: root.dockItemInset
radius: Kirigami.Units.cornerRadius
color: root.dockItemColor(searchMouseArea.containsPress, searchMouseArea.containsMouse, false)
Behavior on color {
ColorAnimation { duration: Kirigami.Units.shortDuration; easing.type: Easing.OutCubic }
}
}
Kirigami.Icon {
anchors.centerIn: parent
width: root.dockIconSize
height: width
source: "search"
active: searchMouseArea.containsMouse
}
PC3.ToolTip {
visible: searchMouseArea.containsMouse
text: i18n("Search")
}
MouseArea {
id: searchMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: root.convergenceMode ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: root.folio.HomeScreenState.openSearchWidget()
}
}
// ---- Virtual desktop pager: left wing (desktops 1 .. ceil(N/2)) ----
Repeater {
id: leftPagerRepeater
@ -490,7 +421,7 @@ MouseArea {
return root.pagerButtonDesktopAt(cx) === desktopId
}
x: root.width - root.navButtonWidth - root.searchButtonWidth - root.trashButtonWidth - (root.pagerRightCount - index) * root.pagerButtonWidth
x: root.width - root.navButtonWidth - root.trashButtonWidth - (root.pagerRightCount - index) * root.pagerButtonWidth
y: 0
width: root.pagerButtonWidth
height: root.height
@ -572,7 +503,7 @@ MouseArea {
enabled: root.convergenceMode
opacity: root.convergenceMode ? 1 : 0
activeFocusOnTab: root.convergenceMode
x: root.width - root.navButtonWidth - root.searchButtonWidth - root.trashButtonWidth
x: root.width - root.navButtonWidth - root.trashButtonWidth
y: 0
width: root.trashButtonWidth
height: root.height
@ -816,7 +747,7 @@ MouseArea {
if (firstTask) {
firstTask.forceActiveFocus();
} else {
searchButton.forceActiveFocus();
overviewButton.forceActiveFocus();
}
event.accepted = true;
}
@ -1390,7 +1321,7 @@ MouseArea {
Keys.onRightPressed: {
let next = taskRepeater.itemAt(taskDelegate.index + 1)
if (next) { next.forceActiveFocus(); return }
searchButton.forceActiveFocus()
overviewButton.forceActiveFocus()
}
// Position after all favourites

View file

@ -10,7 +10,6 @@ import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami as Kirigami
import org.kde.kcmutils as KCM
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
KCM.SimpleKCM {
@ -23,10 +22,6 @@ KCM.SimpleKCM {
leftPadding: 0
rightPadding: 0
function openSettingsModule(moduleName) {
MobileShell.ShellUtil.executeCommand("plasma-open-settings " + moduleName);
}
ColumnLayout {
FormCard.FormHeader {
title: i18n("General")
@ -130,136 +125,6 @@ KCM.SimpleKCM {
}
}
}
FormCard.FormDelegateSeparator { above: autoHidePanels; below: displayConfigurationButton }
FormCard.FormButtonDelegate {
id: displayConfigurationButton
icon.name: "preferences-desktop-display-randr"
text: i18n("Display Configuration")
onClicked: root.openSettingsModule("kcm_kscreen")
}
FormCard.FormDelegateSeparator { above: displayConfigurationButton; below: networkingButton }
FormCard.FormButtonDelegate {
id: networkingButton
icon.name: "preferences-system-network"
text: i18n("Wi-Fi & Networking")
onClicked: root.openSettingsModule("kcm_networkmanagement")
}
FormCard.FormDelegateSeparator { above: networkingButton; below: soundButton }
FormCard.FormButtonDelegate {
id: soundButton
icon.name: "preferences-desktop-sound"
text: i18n("Sound")
onClicked: root.openSettingsModule("kcm_pulseaudio")
}
FormCard.FormDelegateSeparator { above: soundButton; below: shortcutsButton }
FormCard.FormButtonDelegate {
id: shortcutsButton
icon.name: "preferences-desktop-keyboard-shortcut"
text: i18n("Shortcuts")
onClicked: root.openSettingsModule("kcm_keys")
}
FormCard.FormDelegateSeparator { above: shortcutsButton; below: accessibilityButton }
FormCard.FormButtonDelegate {
id: accessibilityButton
icon.name: "preferences-desktop-accessibility"
text: i18n("Accessibility")
onClicked: root.openSettingsModule("kcm_access")
}
FormCard.FormDelegateSeparator { above: accessibilityButton; below: notificationsButton }
FormCard.FormButtonDelegate {
id: notificationsButton
icon.name: "preferences-desktop-notification-bell"
text: i18n("Notifications")
onClicked: root.openSettingsModule("kcm_notifications")
}
FormCard.FormDelegateSeparator { above: notificationsButton; below: screenLockingButton }
FormCard.FormButtonDelegate {
id: screenLockingButton
icon.name: "preferences-desktop-user-password"
text: i18n("Screen Locking")
onClicked: root.openSettingsModule("kcm_screenlocker")
}
FormCard.FormDelegateSeparator { above: screenLockingButton; below: virtualKeyboardButton }
FormCard.FormButtonDelegate {
id: virtualKeyboardButton
icon.name: "input-keyboard-virtual"
text: i18n("Virtual Keyboard")
onClicked: root.openSettingsModule("kcm_virtualkeyboard")
}
}
FormCard.FormHeader {
title: i18n("Desktop Workspace")
}
FormCard.FormCard {
FormCard.FormButtonDelegate {
id: virtualDesktopsButton
icon.name: "preferences-desktop-virtual"
text: i18n("Virtual Desktops")
onClicked: root.openSettingsModule("kcm_kwin_virtualdesktops")
}
FormCard.FormDelegateSeparator { above: virtualDesktopsButton; below: windowBehaviorButton }
FormCard.FormButtonDelegate {
id: windowBehaviorButton
icon.name: "preferences-system-windows-actions"
text: i18n("Window Behavior")
onClicked: root.openSettingsModule("kcm_kwinoptions")
}
FormCard.FormDelegateSeparator { above: windowBehaviorButton; below: windowRulesButton }
FormCard.FormButtonDelegate {
id: windowRulesButton
icon.name: "preferences-system-windows-actions"
text: i18n("Window Rules")
onClicked: root.openSettingsModule("kcm_kwinrules")
}
FormCard.FormDelegateSeparator { above: windowRulesButton; below: taskSwitcherButton }
FormCard.FormButtonDelegate {
id: taskSwitcherButton
icon.name: "preferences-system-tabbox"
text: i18n("Task Switcher")
onClicked: root.openSettingsModule("kcm_kwintabbox")
}
FormCard.FormDelegateSeparator { above: taskSwitcherButton; below: desktopEffectsButton }
FormCard.FormButtonDelegate {
id: desktopEffectsButton
icon.name: "preferences-desktop-effects"
text: i18n("Desktop Effects")
onClicked: root.openSettingsModule("kcm_kwin_effects")
}
FormCard.FormDelegateSeparator { above: desktopEffectsButton; below: windowDecorationsButton }
FormCard.FormButtonDelegate {
id: windowDecorationsButton
icon.name: "preferences-desktop-theme-windowdecorations"
text: i18n("Window Decorations")
onClicked: root.openSettingsModule("kcm_kwindecoration")
}
}
FormCard.FormHeader {

View file

@ -5,57 +5,11 @@ import QtQuick 2.15
import org.kde.plasma.private.mobileshell.quicksettingsplugin as QS
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.gamingshellplugin as GamingShell
QS.QuickSetting {
id: root
readonly property var profileOrder: ["power-saver", "balanced", "performance"]
readonly property bool profileAvailable: GamingShell.PowerProfileControl.available
&& GamingShell.PowerProfileControl.profiles.length > 0
property var toggle: profileAvailable ? root.cycleProfile : undefined
text: i18n("Battery")
status: profileAvailable
? i18n("%1% - %2", MobileShell.BatteryInfo.percent, profileLabel(GamingShell.PowerProfileControl.activeProfile))
: i18n("%1%", MobileShell.BatteryInfo.percent)
icon: profileAvailable ? profileIcon(GamingShell.PowerProfileControl.activeProfile)
: "battery-full" + (MobileShell.BatteryInfo.pluggedIn ? "-charging" : "")
enabled: profileAvailable && GamingShell.PowerProfileControl.activeProfile !== "balanced"
status: i18n("%1%", MobileShell.BatteryInfo.percent)
icon: "battery-full" + (MobileShell.BatteryInfo.pluggedIn ? "-charging" : "")
enabled: false
settingsCommand: "plasma-open-settings kcm_mobile_power"
function profileLabel(profile) {
switch (profile) {
case "performance": return i18n("Performance")
case "balanced": return i18n("Balanced")
case "power-saver": return i18n("Power Saver")
default: return profile
}
}
function profileIcon(profile) {
switch (profile) {
case "performance": return "speedometer"
case "power-saver": return "battery-profile-powersave"
default: return "battery-full" + (MobileShell.BatteryInfo.pluggedIn ? "-charging" : "")
}
}
function cycleProfile() {
let availableProfiles = []
for (let i = 0; i < profileOrder.length; ++i) {
let profile = profileOrder[i]
if (GamingShell.PowerProfileControl.profiles.indexOf(profile) >= 0) {
availableProfiles.push(profile)
}
}
if (availableProfiles.length === 0) {
return
}
let currentIndex = availableProfiles.indexOf(GamingShell.PowerProfileControl.activeProfile)
let nextIndex = currentIndex < 0 ? 0 : (currentIndex + 1) % availableProfiles.length
GamingShell.PowerProfileControl.activeProfile = availableProfiles[nextIndex]
}
}