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

View file

@ -55,16 +55,6 @@ 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;

View file

@ -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 = root.isConvergence ? 3 : 5; // more than 5 is just disorienting let maxRows = 5; // more than 5 is just disorienting
let targetRows = Math.floor(Window.height * (root.isConvergence ? 0.42 : 0.65) / rowHeight); let targetRows = Math.floor(Window.height * 0.65 / rowHeight);
return Math.max(1, Math.min(maxRows, Math.min(totalRows, targetRows))); return Math.min(maxRows, Math.min(totalRows, targetRows));
} }
readonly property int pageSize: rowCount * columnCount readonly property int pageSize: rowCount * columnCount
@ -63,10 +63,6 @@ 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
@ -140,72 +136,21 @@ Item {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
// Promoted desktop controls (convergence mode only) // Management status rows (convergence mode only)
GridLayout { ColumnLayout {
id: promotedGrid
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: root.promotedHorizontalMargin Layout.leftMargin: Kirigami.Units.smallSpacing
Layout.rightMargin: root.promotedHorizontalMargin Layout.rightMargin: Kirigami.Units.smallSpacing
Layout.bottomMargin: Kirigami.Units.smallSpacing Layout.bottomMargin: Kirigami.Units.smallSpacing
columns: root.promotedColumns spacing: Kirigami.Units.smallSpacing
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: isPromoted visible: root.isManagementTile(modelData.settingsCommand)
compact: true
text: modelData.text text: modelData.text
status: modelData.status status: modelData.status
icon: modelData.icon icon: modelData.icon
@ -341,9 +286,4 @@ 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
}
} }

View file

@ -9,7 +9,8 @@ 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
/** /**
* 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. * - 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.
*/ */
@ -21,11 +22,10 @@ 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 * (compact ? 3.1 : 3.6) implicitHeight: Kirigami.Units.gridUnit * 3.6
Kirigami.Theme.inherit: false Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Button 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 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)
@ -147,10 +146,8 @@ 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: Layout.preferredHeight height: Math.max(2, Math.round(Kirigami.Units.devicePixelRatio))
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
@ -165,14 +162,10 @@ Item {
id: toggleMouse id: toggleMouse
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: root.hasToggle ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: Qt.PointingHandCursor
onPressed: { onPressed: haptics.buttonVibrate()
if (root.hasToggle) {
haptics.buttonVibrate()
}
}
onClicked: { 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" 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
@ -94,15 +99,8 @@ 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
@ -149,7 +147,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.searchButtonWidth - root.trashButtonWidth - (pagerRightCount - i) * pagerButtonWidth let bx = root.width - navButtonWidth - 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]) : ""
@ -239,7 +237,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 }
searchButton.forceActiveFocus() overviewButton.forceActiveFocus()
} }
KeyboardHighlight { KeyboardHighlight {
@ -300,7 +298,11 @@ 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: {
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 { 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)) ---- // ---- Virtual desktop pager: left wing (desktops 1 .. ceil(N/2)) ----
Repeater { Repeater {
id: leftPagerRepeater id: leftPagerRepeater
@ -490,7 +421,7 @@ MouseArea {
return root.pagerButtonDesktopAt(cx) === desktopId 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 y: 0
width: root.pagerButtonWidth width: root.pagerButtonWidth
height: root.height height: root.height
@ -572,7 +503,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.searchButtonWidth - root.trashButtonWidth x: root.width - root.navButtonWidth - root.trashButtonWidth
y: 0 y: 0
width: root.trashButtonWidth width: root.trashButtonWidth
height: root.height height: root.height
@ -816,7 +747,7 @@ MouseArea {
if (firstTask) { if (firstTask) {
firstTask.forceActiveFocus(); firstTask.forceActiveFocus();
} else { } else {
searchButton.forceActiveFocus(); overviewButton.forceActiveFocus();
} }
event.accepted = true; event.accepted = true;
} }
@ -1390,7 +1321,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 }
searchButton.forceActiveFocus() overviewButton.forceActiveFocus()
} }
// Position after all favourites // 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.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 {
@ -23,10 +22,6 @@ 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")
@ -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 { 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.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: profileAvailable status: i18n("%1%", MobileShell.BatteryInfo.percent)
? i18n("%1% - %2", MobileShell.BatteryInfo.percent, profileLabel(GamingShell.PowerProfileControl.activeProfile)) icon: "battery-full" + (MobileShell.BatteryInfo.pluggedIn ? "-charging" : "")
: i18n("%1%", MobileShell.BatteryInfo.percent) enabled: false
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]
}
} }