mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-06-25 07:37:42 +00:00
Compare commits
4 commits
e5ec88a12b
...
c23d756596
| Author | SHA1 | Date | |
|---|---|---|---|
| c23d756596 | |||
| c5582393bc | |||
| 85b5aec742 | |||
| 0ec1794929 |
8 changed files with 601 additions and 35 deletions
|
|
@ -141,6 +141,7 @@ ecm_target_qml_sources(mobileshellplugin SOURCES
|
||||||
qml/actiondrawer/private/QuickSettingsPanel.qml
|
qml/actiondrawer/private/QuickSettingsPanel.qml
|
||||||
qml/actiondrawer/private/ContentContainer.qml
|
qml/actiondrawer/private/ContentContainer.qml
|
||||||
qml/actiondrawer/private/DetailPopup.qml
|
qml/actiondrawer/private/DetailPopup.qml
|
||||||
|
qml/actiondrawer/private/SystemTrayPopup.qml
|
||||||
qml/actiondrawer/private/LandscapeContentContainer.qml
|
qml/actiondrawer/private/LandscapeContentContainer.qml
|
||||||
qml/actiondrawer/private/NotificationDrawer.qml
|
qml/actiondrawer/private/NotificationDrawer.qml
|
||||||
qml/actiondrawer/private/PortraitContentContainer.qml
|
qml/actiondrawer/private/PortraitContentContainer.qml
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,16 @@ QQC2.Popup {
|
||||||
popup.open();
|
popup.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: MobileShell.AppletHost
|
||||||
|
|
||||||
|
function onAppletReady(pluginId) {
|
||||||
|
if (pluginId === popup.currentPluginId && !popup.opened) {
|
||||||
|
popup.show(pluginId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onClosed: {
|
onClosed: {
|
||||||
if (__currentItem) {
|
if (__currentItem) {
|
||||||
__currentItem.visible = false;
|
__currentItem.visible = false;
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@ Item {
|
||||||
readonly property int columnCount: Math.floor(width/columnWidth)
|
readonly property int columnCount: Math.floor(width/columnWidth)
|
||||||
readonly property int rowCount: {
|
readonly property int rowCount: {
|
||||||
let totalRows = Math.ceil(quickSettingsCount / columnCount);
|
let totalRows = Math.ceil(quickSettingsCount / columnCount);
|
||||||
let maxRows = 5; // more than 5 is just disorienting
|
let maxRows = root.isConvergence ? 3 : 5; // more than 5 is just disorienting
|
||||||
let targetRows = Math.floor(Window.height * 0.65 / rowHeight);
|
let targetRows = Math.floor(Window.height * (root.isConvergence ? 0.42 : 0.65) / rowHeight);
|
||||||
return Math.min(maxRows, Math.min(totalRows, targetRows));
|
return Math.max(1, Math.min(maxRows, Math.min(totalRows, targetRows)));
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property int pageSize: rowCount * columnCount
|
readonly property int pageSize: rowCount * columnCount
|
||||||
|
|
@ -63,6 +63,10 @@ Item {
|
||||||
})
|
})
|
||||||
readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled
|
readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled
|
||||||
function isManagementTile(cmd) { return cmd in __managementCommands; }
|
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
|
readonly property alias brightnessPressedValue: brightnessItem.brightnessPressedValue
|
||||||
|
|
||||||
|
|
@ -136,21 +140,72 @@ Item {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
// Management status rows (convergence mode only)
|
// Promoted desktop controls (convergence mode only)
|
||||||
ColumnLayout {
|
GridLayout {
|
||||||
|
id: promotedGrid
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
Layout.leftMargin: root.promotedHorizontalMargin
|
||||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
Layout.rightMargin: root.promotedHorizontalMargin
|
||||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||||
spacing: Kirigami.Units.smallSpacing
|
columns: root.promotedColumns
|
||||||
|
rowSpacing: root.promotedSpacing
|
||||||
|
columnSpacing: root.promotedSpacing
|
||||||
visible: root.isConvergence
|
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 {
|
Repeater {
|
||||||
model: root.quickSettingsModel
|
model: root.quickSettingsModel
|
||||||
delegate: QuickSettingsStatusRow {
|
delegate: QuickSettingsStatusRow {
|
||||||
required property var modelData
|
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
|
Layout.fillWidth: true
|
||||||
visible: root.isManagementTile(modelData.settingsCommand)
|
visible: isPromoted
|
||||||
|
compact: true
|
||||||
text: modelData.text
|
text: modelData.text
|
||||||
status: modelData.status
|
status: modelData.status
|
||||||
icon: modelData.icon
|
icon: modelData.icon
|
||||||
|
|
@ -286,4 +341,9 @@ Item {
|
||||||
parent: root.Window.window ? root.Window.window.contentItem : root
|
parent: root.Window.window ? root.Window.window.contentItem : root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemTrayPopup {
|
||||||
|
id: systemTrayPopup
|
||||||
|
parent: root.Window.window ? root.Window.window.contentItem : root
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@ import org.kde.plasma.private.mobileshell as MobileShell
|
||||||
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
|
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Full-width management row (Wi-Fi, Bluetooth, Audio, Battery) shown in
|
* Management/detail row shown in convergence mode. Two interaction zones:
|
||||||
* convergence mode. Two interaction zones:
|
|
||||||
* - Left toggle pill: icon + indicator dot, tap toggles the service.
|
* - Left toggle pill: icon + indicator dot, tap toggles the service.
|
||||||
* - Right detail area: name + status + chevron, tap opens detail popup.
|
* - Right detail area: name + status + chevron, tap opens detail popup.
|
||||||
*/
|
*/
|
||||||
|
|
@ -22,10 +21,11 @@ Item {
|
||||||
required property string icon
|
required property string icon
|
||||||
required property bool enabled
|
required property bool enabled
|
||||||
required property var toggleFunction
|
required property var toggleFunction
|
||||||
|
property bool compact: false
|
||||||
|
|
||||||
signal detailClicked()
|
signal detailClicked()
|
||||||
|
|
||||||
implicitHeight: Kirigami.Units.gridUnit * 3.6
|
implicitHeight: Kirigami.Units.gridUnit * (compact ? 3.1 : 3.6)
|
||||||
|
|
||||||
Kirigami.Theme.inherit: false
|
Kirigami.Theme.inherit: false
|
||||||
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
||||||
|
|
@ -35,6 +35,7 @@ Item {
|
||||||
readonly property color enabledBgHover: mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.32)
|
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 enabledBgPressed: mixColor(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.12)
|
||||||
readonly property color enabledBorder: Qt.darker(Kirigami.Theme.highlightColor, 1.25)
|
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 disabledBg: Kirigami.Theme.alternateBackgroundColor
|
||||||
readonly property color disabledBgHover: mixColor(Kirigami.Theme.alternateBackgroundColor, Kirigami.Theme.textColor, 0.06)
|
readonly property color disabledBgHover: mixColor(Kirigami.Theme.alternateBackgroundColor, Kirigami.Theme.textColor, 0.06)
|
||||||
|
|
@ -146,8 +147,10 @@ Item {
|
||||||
// Indicator bar
|
// Indicator bar
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
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
|
width: root.enabled ? Kirigami.Units.smallSpacing * 3 : Kirigami.Units.smallSpacing * 1.5
|
||||||
height: Math.max(2, Math.round(Kirigami.Units.devicePixelRatio))
|
height: Layout.preferredHeight
|
||||||
radius: height / 2
|
radius: height / 2
|
||||||
color: root.enabled ? Kirigami.Theme.highlightColor : Kirigami.Theme.disabledTextColor
|
color: root.enabled ? Kirigami.Theme.highlightColor : Kirigami.Theme.disabledTextColor
|
||||||
opacity: root.enabled ? 1.0 : 0.4
|
opacity: root.enabled ? 1.0 : 0.4
|
||||||
|
|
@ -162,10 +165,14 @@ Item {
|
||||||
id: toggleMouse
|
id: toggleMouse
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: root.hasToggle ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
onPressed: haptics.buttonVibrate()
|
onPressed: {
|
||||||
|
if (root.hasToggle) {
|
||||||
|
haptics.buttonVibrate()
|
||||||
|
}
|
||||||
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (root.toggleFunction) root.toggleFunction();
|
if (root.hasToggle) root.toggleFunction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,238 @@
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -62,11 +62,6 @@ MouseArea {
|
||||||
return "transparent"
|
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
|
// Visible spacer between pinned favourites and running tasks
|
||||||
readonly property bool showSpacer: showRunningTasks && repeater.count > 0 && taskRepeater.count > 0
|
readonly property bool showSpacer: showRunningTasks && repeater.count > 0 && taskRepeater.count > 0
|
||||||
property real spacerWidth: showSpacer ? Kirigami.Units.largeSpacing * 2 : 0
|
property real spacerWidth: showSpacer ? Kirigami.Units.largeSpacing * 2 : 0
|
||||||
|
|
@ -99,8 +94,15 @@ MouseArea {
|
||||||
readonly property int pagerLeftCount: showPager ? Math.ceil(virtualDesktopInfo.numberOfDesktops / 2) : 0
|
readonly property int pagerLeftCount: showPager ? Math.ceil(virtualDesktopInfo.numberOfDesktops / 2) : 0
|
||||||
readonly property int pagerRightCount: showPager ? virtualDesktopInfo.numberOfDesktops - pagerLeftCount : 0
|
readonly property int pagerRightCount: showPager ? virtualDesktopInfo.numberOfDesktops - pagerLeftCount : 0
|
||||||
property real trashButtonWidth: convergenceMode ? root.height : 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 pagerButtonWidth { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic } }
|
||||||
Behavior on trashButtonWidth { 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) {
|
function pagerDesktopName(index) {
|
||||||
let names = virtualDesktopInfo.desktopNames
|
let names = virtualDesktopInfo.desktopNames
|
||||||
|
|
@ -147,7 +149,7 @@ MouseArea {
|
||||||
return (ids && i < ids.length) ? String(ids[i]) : ""
|
return (ids && i < ids.length) ? String(ids[i]) : ""
|
||||||
}
|
}
|
||||||
for (let i = 0; i < pagerRightCount; ++i) {
|
for (let i = 0; i < pagerRightCount; ++i) {
|
||||||
let bx = root.width - navButtonWidth - root.trashButtonWidth - (pagerRightCount - i) * pagerButtonWidth
|
let bx = root.width - navButtonWidth - root.searchButtonWidth - root.trashButtonWidth - (pagerRightCount - i) * pagerButtonWidth
|
||||||
if (x >= bx && x < bx + pagerButtonWidth) {
|
if (x >= bx && x < bx + pagerButtonWidth) {
|
||||||
let di = pagerLeftCount + i
|
let di = pagerLeftCount + i
|
||||||
return (ids && di < ids.length) ? String(ids[di]) : ""
|
return (ids && di < ids.length) ? String(ids[di]) : ""
|
||||||
|
|
@ -237,7 +239,7 @@ MouseArea {
|
||||||
if (first) { first.keyboardFocus(); return }
|
if (first) { first.keyboardFocus(); return }
|
||||||
let firstTask = taskRepeater.itemAt(0)
|
let firstTask = taskRepeater.itemAt(0)
|
||||||
if (firstTask) { firstTask.forceActiveFocus(); return }
|
if (firstTask) { firstTask.forceActiveFocus(); return }
|
||||||
overviewButton.forceActiveFocus()
|
searchButton.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardHighlight {
|
KeyboardHighlight {
|
||||||
|
|
@ -298,11 +300,7 @@ MouseArea {
|
||||||
Keys.onEnterPressed: root.folio.triggerOverview()
|
Keys.onEnterPressed: root.folio.triggerOverview()
|
||||||
Keys.onSpacePressed: root.folio.triggerOverview()
|
Keys.onSpacePressed: root.folio.triggerOverview()
|
||||||
Keys.onLeftPressed: {
|
Keys.onLeftPressed: {
|
||||||
let lastTask = taskRepeater.itemAt(taskRepeater.count - 1)
|
searchButton.forceActiveFocus()
|
||||||
if (lastTask) { lastTask.forceActiveFocus(); return }
|
|
||||||
let lastFav = repeater.itemAt(repeater.count - 1)
|
|
||||||
if (lastFav) { lastFav.keyboardFocus(); return }
|
|
||||||
homeButton.forceActiveFocus()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardHighlight {
|
KeyboardHighlight {
|
||||||
|
|
@ -338,6 +336,77 @@ 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)) ----
|
// ---- Virtual desktop pager: left wing (desktops 1 .. ceil(N/2)) ----
|
||||||
Repeater {
|
Repeater {
|
||||||
id: leftPagerRepeater
|
id: leftPagerRepeater
|
||||||
|
|
@ -421,7 +490,7 @@ MouseArea {
|
||||||
return root.pagerButtonDesktopAt(cx) === desktopId
|
return root.pagerButtonDesktopAt(cx) === desktopId
|
||||||
}
|
}
|
||||||
|
|
||||||
x: root.width - root.navButtonWidth - root.trashButtonWidth - (root.pagerRightCount - index) * root.pagerButtonWidth
|
x: root.width - root.navButtonWidth - root.searchButtonWidth - root.trashButtonWidth - (root.pagerRightCount - index) * root.pagerButtonWidth
|
||||||
y: 0
|
y: 0
|
||||||
width: root.pagerButtonWidth
|
width: root.pagerButtonWidth
|
||||||
height: root.height
|
height: root.height
|
||||||
|
|
@ -503,7 +572,7 @@ MouseArea {
|
||||||
enabled: root.convergenceMode
|
enabled: root.convergenceMode
|
||||||
opacity: root.convergenceMode ? 1 : 0
|
opacity: root.convergenceMode ? 1 : 0
|
||||||
activeFocusOnTab: root.convergenceMode
|
activeFocusOnTab: root.convergenceMode
|
||||||
x: root.width - root.navButtonWidth - root.trashButtonWidth
|
x: root.width - root.navButtonWidth - root.searchButtonWidth - root.trashButtonWidth
|
||||||
y: 0
|
y: 0
|
||||||
width: root.trashButtonWidth
|
width: root.trashButtonWidth
|
||||||
height: root.height
|
height: root.height
|
||||||
|
|
@ -747,7 +816,7 @@ MouseArea {
|
||||||
if (firstTask) {
|
if (firstTask) {
|
||||||
firstTask.forceActiveFocus();
|
firstTask.forceActiveFocus();
|
||||||
} else {
|
} else {
|
||||||
overviewButton.forceActiveFocus();
|
searchButton.forceActiveFocus();
|
||||||
}
|
}
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1321,7 +1390,7 @@ MouseArea {
|
||||||
Keys.onRightPressed: {
|
Keys.onRightPressed: {
|
||||||
let next = taskRepeater.itemAt(taskDelegate.index + 1)
|
let next = taskRepeater.itemAt(taskDelegate.index + 1)
|
||||||
if (next) { next.forceActiveFocus(); return }
|
if (next) { next.forceActiveFocus(); return }
|
||||||
overviewButton.forceActiveFocus()
|
searchButton.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position after all favourites
|
// Position after all favourites
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import QtQuick.Controls 2.15 as QQC2
|
||||||
import org.kde.kirigami as Kirigami
|
import org.kde.kirigami as Kirigami
|
||||||
import org.kde.kcmutils as KCM
|
import org.kde.kcmutils as KCM
|
||||||
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
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
|
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
|
||||||
|
|
||||||
KCM.SimpleKCM {
|
KCM.SimpleKCM {
|
||||||
|
|
@ -22,6 +23,10 @@ KCM.SimpleKCM {
|
||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
rightPadding: 0
|
rightPadding: 0
|
||||||
|
|
||||||
|
function openSettingsModule(moduleName) {
|
||||||
|
MobileShell.ShellUtil.executeCommand("plasma-open-settings " + moduleName);
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
FormCard.FormHeader {
|
FormCard.FormHeader {
|
||||||
title: i18n("General")
|
title: i18n("General")
|
||||||
|
|
@ -125,6 +130,136 @@ 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 {
|
FormCard.FormHeader {
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,57 @@ import QtQuick 2.15
|
||||||
|
|
||||||
import org.kde.plasma.private.mobileshell.quicksettingsplugin as QS
|
import org.kde.plasma.private.mobileshell.quicksettingsplugin as QS
|
||||||
import org.kde.plasma.private.mobileshell as MobileShell
|
import org.kde.plasma.private.mobileshell as MobileShell
|
||||||
|
import org.kde.plasma.private.mobileshell.gamingshellplugin as GamingShell
|
||||||
|
|
||||||
QS.QuickSetting {
|
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")
|
text: i18n("Battery")
|
||||||
status: i18n("%1%", MobileShell.BatteryInfo.percent)
|
status: profileAvailable
|
||||||
icon: "battery-full" + (MobileShell.BatteryInfo.pluggedIn ? "-charging" : "")
|
? i18n("%1% - %2", MobileShell.BatteryInfo.percent, profileLabel(GamingShell.PowerProfileControl.activeProfile))
|
||||||
enabled: false
|
: i18n("%1%", MobileShell.BatteryInfo.percent)
|
||||||
|
icon: profileAvailable ? profileIcon(GamingShell.PowerProfileControl.activeProfile)
|
||||||
|
: "battery-full" + (MobileShell.BatteryInfo.pluggedIn ? "-charging" : "")
|
||||||
|
enabled: profileAvailable && GamingShell.PowerProfileControl.activeProfile !== "balanced"
|
||||||
settingsCommand: "plasma-open-settings kcm_mobile_power"
|
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]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue