diff --git a/applets/batterymonitor/package/contents/ui/BatteryItem.qml b/applets/batterymonitor/package/contents/ui/BatteryItem.qml index b988b35cd..522f25c83 100644 --- a/applets/batterymonitor/package/contents/ui/BatteryItem.qml +++ b/applets/batterymonitor/package/contents/ui/BatteryItem.qml @@ -16,7 +16,7 @@ import org.kde.plasma.workspace.components 2.0 import "logic.js" as Logic -RowLayout { +PlasmaComponents3.ItemDelegate { id: root // We'd love to use `required` properties, especially since the model provides role names for them; @@ -54,148 +54,168 @@ RowLayout { property PlasmaComponents3.Slider matchHeightOfSlider: PlasmaComponents3.Slider {} readonly property real extraMargin: Math.max(0, Math.floor((matchHeightOfSlider.height - chargeBar.height) / 2)) - spacing: PlasmaCore.Units.gridUnit + background.visible: highlighted + highlighted: activeFocus + text: battery["Pretty Name"] - BatteryIcon { - id: batteryIcon + Accessible.description: `${isPowerSupplyLabel.text} ${percentLabel.text}; ${details.Accessible.description}` - Layout.alignment: Qt.AlignTop - Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium - Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium + contentItem: RowLayout { + spacing: PlasmaCore.Units.gridUnit - batteryType: root.battery.Type - percent: root.battery.Percent - hasBattery: root.isPresent - pluggedIn: root.battery.State === "Charging" && root.battery["Is Power Supply"] - } - - ColumnLayout { - Layout.fillWidth: true - Layout.alignment: root.isPresent ? Qt.AlignTop : Qt.AlignVCenter - spacing: 0 - - RowLayout { - spacing: PlasmaCore.Units.smallSpacing - - PlasmaComponents3.Label { - Layout.fillWidth: true - elide: Text.ElideRight - text: root.battery["Pretty Name"] - } + BatteryIcon { + id: batteryIcon - PlasmaComponents3.Label { - text: Logic.stringForBatteryState(root.battery) - visible: root.battery["Is Power Supply"] - enabled: false - } + Layout.alignment: Qt.AlignTop + Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium + Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium - PlasmaComponents3.Label { - horizontalAlignment: Text.AlignRight - visible: root.isPresent - text: i18nc("Placeholder is battery percentage", "%1%", root.battery.Percent) - } + batteryType: root.battery.Type + percent: root.battery.Percent + hasBattery: root.isPresent + pluggedIn: root.battery.State === "Charging" && root.battery["Is Power Supply"] } - PlasmaComponents3.ProgressBar { - id: chargeBar - - Layout.fillWidth: true - Layout.topMargin: root.extraMargin - Layout.bottomMargin: root.extraMargin - - from: 0 - to: 100 - visible: root.isPresent - value: Number(root.battery.Percent) - } - - // This gridLayout basically emulates an at-most-two-rows table with a - // single wide fillWidth/columnSpan header. Not really worth it trying - // to refactor it into some more clever fancy model-delegate stuff. - GridLayout { - id: details - + ColumnLayout { Layout.fillWidth: true - Layout.topMargin: PlasmaCore.Units.smallSpacing + Layout.alignment: root.isPresent ? Qt.AlignTop : Qt.AlignVCenter + spacing: 0 + + RowLayout { + spacing: PlasmaCore.Units.smallSpacing + + PlasmaComponents3.Label { + Layout.fillWidth: true + elide: Text.ElideRight + text: root.text + } + + PlasmaComponents3.Label { + id: isPowerSupplyLabel + text: Logic.stringForBatteryState(root.battery) + visible: root.battery["Is Power Supply"] + enabled: false + } + + PlasmaComponents3.Label { + id: percentLabel + horizontalAlignment: Text.AlignRight + visible: root.isPresent + text: i18nc("Placeholder is battery percentage", "%1%", root.battery.Percent) + } + } - columns: 2 - columnSpacing: PlasmaCore.Units.smallSpacing - rowSpacing: 0 + PlasmaComponents3.ProgressBar { + id: chargeBar - component LeftLabel : PlasmaComponents3.Label { - // fillWidth is true, so using internal alignment - horizontalAlignment: Text.AlignLeft Layout.fillWidth: true - font: PlasmaCore.Theme.smallestFont - wrapMode: Text.WordWrap - enabled: false - } - component RightLabel : PlasmaComponents3.Label { - // fillWidth is false, so using external (grid-cell-internal) alignment - Layout.alignment: Qt.AlignRight - Layout.fillWidth: false - font: PlasmaCore.Theme.smallestFont - enabled: false - } + Layout.topMargin: root.extraMargin + Layout.bottomMargin: root.extraMargin - PlasmaComponents3.Label { - Layout.fillWidth: true - Layout.columnSpan: 2 - - text: root.isBroken && typeof root.battery.Capacity !== "undefined" - ? i18n("This battery's health is at only %1% and it should be replaced. Contact the manufacturer.", root.battery.Capacity) - : "" - font: PlasmaCore.Theme.smallestFont - color: PlasmaCore.Theme.neutralTextColor - visible: root.isBroken - wrapMode: Text.WordWrap + from: 0 + to: 100 + visible: root.isPresent + value: Number(root.battery.Percent) } - readonly property bool remainingTimeRowVisible: root.battery !== null - && root.remainingTime > 0 - && root.battery["Is Power Supply"] - && ["Discharging", "Charging"].includes(root.battery.State) - - LeftLabel { - text: root.battery.State === "Charging" - ? i18n("Time To Full:") - : i18n("Remaining Time:") - visible: details.remainingTimeRowVisible - } + // This gridLayout basically emulates an at-most-two-rows table with a + // single wide fillWidth/columnSpan header. Not really worth it trying + // to refactor it into some more clever fancy model-delegate stuff. + GridLayout { + id: details - RightLabel { - text: KCoreAddons.Format.formatDuration(root.remainingTime, KCoreAddons.FormatTypes.HideSeconds) - visible: details.remainingTimeRowVisible + Layout.fillWidth: true + Layout.topMargin: PlasmaCore.Units.smallSpacing + + columns: 2 + columnSpacing: PlasmaCore.Units.smallSpacing + rowSpacing: 0 + + Accessible.description: { + let description = []; + for (let i = 0; i < children.length; i++) { + if (children[i].visible && children[i].hasOwnProperty("text")) { + description.push(children[i].text); + } + } + return description.join(" "); + } + + component LeftLabel : PlasmaComponents3.Label { + // fillWidth is true, so using internal alignment + horizontalAlignment: Text.AlignLeft + Layout.fillWidth: true + font: PlasmaCore.Theme.smallestFont + wrapMode: Text.WordWrap + enabled: false + } + component RightLabel : PlasmaComponents3.Label { + // fillWidth is false, so using external (grid-cell-internal) alignment + Layout.alignment: Qt.AlignRight + Layout.fillWidth: false + font: PlasmaCore.Theme.smallestFont + enabled: false + } + + PlasmaComponents3.Label { + Layout.fillWidth: true + Layout.columnSpan: 2 + + text: root.isBroken && typeof root.battery.Capacity !== "undefined" + ? i18n("This battery's health is at only %1% and it should be replaced. Contact the manufacturer.", root.battery.Capacity) + : "" + font: PlasmaCore.Theme.smallestFont + color: PlasmaCore.Theme.neutralTextColor + visible: root.isBroken + wrapMode: Text.WordWrap + } + + readonly property bool remainingTimeRowVisible: root.battery !== null + && root.remainingTime > 0 + && root.battery["Is Power Supply"] + && ["Discharging", "Charging"].includes(root.battery.State) + + LeftLabel { + text: root.battery.State === "Charging" + ? i18n("Time To Full:") + : i18n("Remaining Time:") + visible: details.remainingTimeRowVisible + } + + RightLabel { + text: KCoreAddons.Format.formatDuration(root.remainingTime, KCoreAddons.FormatTypes.HideSeconds) + visible: details.remainingTimeRowVisible + } + + readonly property bool healthRowVisible: root.battery !== null + && root.battery["Is Power Supply"] + && root.battery.Capacity !== "" + && typeof root.battery.Capacity === "number" + && !root.isBroken + + LeftLabel { + text: i18n("Battery Health:") + visible: details.healthRowVisible + } + + RightLabel { + text: details.healthRowVisible + ? i18nc("Placeholder is battery health percentage", "%1%", root.battery.Capacity) + : "" + visible: details.healthRowVisible + } } - readonly property bool healthRowVisible: root.battery !== null - && root.battery["Is Power Supply"] - && root.battery.Capacity !== "" - && typeof root.battery.Capacity === "number" - && !root.isBroken - - LeftLabel { - text: i18n("Battery Health:") - visible: details.healthRowVisible - } + InhibitionHint { + Layout.fillWidth: true + Layout.topMargin: PlasmaCore.Units.smallSpacing - RightLabel { - text: details.healthRowVisible - ? i18nc("Placeholder is battery health percentage", "%1%", root.battery.Capacity) - : "" - visible: details.healthRowVisible + readonly property var chargeStopThreshold: pmSource.data["Battery"] ? pmSource.data["Battery"]["Charge Stop Threshold"] : undefined + readonly property bool pluggedIn: pmSource.data["AC Adapter"] !== undefined && pmSource.data["AC Adapter"]["Plugged in"] + visible: pluggedIn && root.isPowerSupply && typeof chargeStopThreshold === "number" && chargeStopThreshold > 0 && chargeStopThreshold < 100 + iconSource: "kt-speed-limits" // FIXME good icon + text: i18n("Battery is configured to charge up to approximately %1%.", chargeStopThreshold || 0) } } - - InhibitionHint { - Layout.fillWidth: true - Layout.topMargin: PlasmaCore.Units.smallSpacing - - readonly property var chargeStopThreshold: pmSource.data["Battery"] ? pmSource.data["Battery"]["Charge Stop Threshold"] : undefined - readonly property bool pluggedIn: pmSource.data["AC Adapter"] !== undefined && pmSource.data["AC Adapter"]["Plugged in"] - visible: pluggedIn && root.isPowerSupply && typeof chargeStopThreshold === "number" && chargeStopThreshold > 0 && chargeStopThreshold < 100 - iconSource: "kt-speed-limits" // FIXME good icon - text: i18n("Battery is configured to charge up to approximately %1%.", chargeStopThreshold || 0) - } } } diff --git a/applets/batterymonitor/package/contents/ui/BrightnessItem.qml b/applets/batterymonitor/package/contents/ui/BrightnessItem.qml index 6a95bf0b2..d3f44745a 100644 --- a/applets/batterymonitor/package/contents/ui/BrightnessItem.qml +++ b/applets/batterymonitor/package/contents/ui/BrightnessItem.qml @@ -11,11 +11,9 @@ import QtQuick.Layouts 1.15 import org.kde.plasma.components 3.0 as PlasmaComponents3 import org.kde.plasma.core 2.1 as PlasmaCore -RowLayout { +PlasmaComponents3.ItemDelegate { id: root - property alias icon: image.source - property alias label: title.text property alias slider: control property alias value: control.value property alias maximumValue: control.to @@ -26,48 +24,62 @@ RowLayout { signal moved() - spacing: PlasmaCore.Units.gridUnit + background.visible: highlighted + highlighted: activeFocus + hoverEnabled: false - PlasmaCore.IconItem { - id: image - Layout.alignment: Qt.AlignTop - Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium - Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium - } + Accessible.description: percent.text + Accessible.role: Accessible.Slider + Keys.forwardTo: [slider] + + contentItem: RowLayout { + spacing: PlasmaCore.Units.gridUnit - ColumnLayout { - Layout.fillWidth: true - Layout.alignment: Qt.AlignTop - spacing: 0 + PlasmaCore.IconItem { + id: image + Layout.alignment: Qt.AlignTop + Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium + Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium + source: root.icon.name + } - RowLayout { + ColumnLayout { Layout.fillWidth: true - spacing: PlasmaCore.Units.smallSpacing + Layout.alignment: Qt.AlignTop + spacing: 0 - PlasmaComponents3.Label { - id: title + RowLayout { Layout.fillWidth: true + spacing: PlasmaCore.Units.smallSpacing + + PlasmaComponents3.Label { + id: title + Layout.fillWidth: true + text: root.text + } + + PlasmaComponents3.Label { + id: percent + Layout.alignment: Qt.AlignRight + text: i18nc("Placeholder is brightness percentage", "%1%", root.percentage) + } } - PlasmaComponents3.Label { - id: percent - Layout.alignment: Qt.AlignRight - text: i18nc("Placeholder is brightness percentage", "%1%", root.percentage) - } - } + PlasmaComponents3.Slider { + id: control + Layout.fillWidth: true - PlasmaComponents3.Slider { - id: control - Layout.fillWidth: true - // Don't allow the slider to turn off the screen - // Please see https://git.reviewboard.kde.org/r/122505/ for more information - from: to > 100 ? 1 : 0 - stepSize: 1 + activeFocusOnTab: false + // Don't allow the slider to turn off the screen + // Please see https://git.reviewboard.kde.org/r/122505/ for more information + from: to > 100 ? 1 : 0 + stepSize: 1 - Accessible.name: root.label - Accessible.description: percent.text + Accessible.name: root.text + Accessible.description: percent.text - onMoved: root.moved() + onMoved: root.moved() + } } } } diff --git a/applets/batterymonitor/package/contents/ui/PopupDialog.qml b/applets/batterymonitor/package/contents/ui/PopupDialog.qml index abf00b385..aeb18a707 100644 --- a/applets/batterymonitor/package/contents/ui/PopupDialog.qml +++ b/applets/batterymonitor/package/contents/ui/PopupDialog.qml @@ -16,7 +16,7 @@ import org.kde.plasma.extras 2.0 as PlasmaExtras PlasmaExtras.Representation { id: dialog - property alias model: batteryList.model + property alias model: batteryRepeater.model property bool pluggedIn property int remainingTime @@ -48,6 +48,8 @@ PlasmaExtras.Representation { collapseMarginsHint: true + KeyNavigation.down: pmSwitch.pmCheckBox + header: PlasmaExtras.PlasmoidHeading { leftPadding: PlasmaCore.Units.smallSpacing contentItem: PowerManagementItem { @@ -57,127 +59,134 @@ PlasmaExtras.Representation { inhibitsLidAction: dialog.inhibitsLidAction pluggedIn: dialog.pluggedIn onDisabledChanged: powerManagementChanged(disabled) - - KeyNavigation.tab: if (batteryList.headerItem) { - if (isBrightnessAvailable) { - return batteryList.headerItem.children[1]; - } else if (isKeyboardBrightnessAvailable) { - return batteryList.headerItem.children[2]; - } else if (dialog.profiles.length > 0) { - return batteryList.headerItem.children[3]; - } else { - return batteryList; - } - } } } - PlasmaComponents3.ScrollView { - focus: true - anchors.fill: parent + contentItem: PlasmaComponents3.ScrollView { + id: scrollView + + focus: false // HACK: workaround for https://bugreports.qt.io/browse/QTBUG-83890 PlasmaComponents3.ScrollBar.horizontal.policy: PlasmaComponents3.ScrollBar.AlwaysOff - contentItem: ListView { + Column { id: batteryList - keyNavigationEnabled: true - - leftMargin: PlasmaCore.Units.smallSpacing * 2 - rightMargin: PlasmaCore.Units.smallSpacing * 2 - topMargin: PlasmaCore.Units.smallSpacing * 2 - bottomMargin: PlasmaCore.Units.smallSpacing * 2 - spacing: PlasmaCore.Units.smallSpacing - - // header so that it scroll with the content of the ListView - header: ColumnLayout { - spacing: PlasmaCore.Units.smallSpacing * 2 - width: parent.width - - BrightnessItem { - id: brightnessSlider - - Layout.fillWidth: true - - icon: "video-display-brightness" - label: i18n("Display Brightness") - visible: isBrightnessAvailable - value: batterymonitor.screenBrightness - maximumValue: batterymonitor.maximumScreenBrightness - KeyNavigation.tab: if (isKeyboardBrightnessAvailable) { - return keyboardBrightnessSlider; - } else if (dialog.profiles.length > 0) { - return powerProfileItem - } else { - return batteryList - } - stepSize: batterymonitor.maximumScreenBrightness/100 - onMoved: batterymonitor.screenBrightness = value + spacing: PlasmaCore.Units.smallSpacing * 2 - // Manually dragging the slider around breaks the binding - Connections { - target: batterymonitor - function onScreenBrightnessChanged() { - brightnessSlider.value = batterymonitor.screenBrightness; - } - } + readonly property Item firstHeaderItem: { + if (brightnessSlider.visible) { + return brightnessSlider; + } else if (keyboardBrightnessSlider.visible) { + return keyboardBrightnessSlider; + } else if (powerProfileItem.visible) { + return powerProfileItem; + } + return null; + } + readonly property Item lastHeaderItem: { + if (powerProfileItem.visible) { + return powerProfileItem; + } else if (keyboardBrightnessSlider.visible) { + return keyboardBrightnessSlider; + } else if (brightnessSlider.visible) { + return brightnessSlider; } + return null; + } - BrightnessItem { - id: keyboardBrightnessSlider - - Layout.fillWidth: true - - icon: "input-keyboard-brightness" - label: i18n("Keyboard Brightness") - showPercentage: false - value: batterymonitor.keyboardBrightness - maximumValue: batterymonitor.maximumKeyboardBrightness - visible: isKeyboardBrightnessAvailable - KeyNavigation.tab: if (dialog.profiles.length > 0) { - return powerProfileItem - } else { - return batteryList - } + BrightnessItem { + id: brightnessSlider + + width: scrollView.availableWidth - onMoved: batterymonitor.keyboardBrightness = value + icon.name: "video-display-brightness" + text: i18n("Display Brightness") + visible: isBrightnessAvailable + value: batterymonitor.screenBrightness + maximumValue: batterymonitor.maximumScreenBrightness - // Manually dragging the slider around breaks the binding - Connections { - target: batterymonitor - function onKeyboardBrightnessChanged() { - keyboardBrightnessSlider.value = batterymonitor.keyboardBrightness; - } + KeyNavigation.up: pmSwitch.pmCheckBox + KeyNavigation.down: keyboardBrightnessSlider.visible ? keyboardBrightnessSlider : keyboardBrightnessSlider.KeyNavigation.down + KeyNavigation.backtab: KeyNavigation.up + KeyNavigation.tab: KeyNavigation.down + stepSize: batterymonitor.maximumScreenBrightness/100 + + onMoved: batterymonitor.screenBrightness = value + + // Manually dragging the slider around breaks the binding + Connections { + target: batterymonitor + function onScreenBrightnessChanged() { + brightnessSlider.value = batterymonitor.screenBrightness; } } + } - PowerProfileItem { - id: powerProfileItem - Layout.fillWidth: true - - KeyNavigation.tab: batteryList - activeProfile: dialog.activeProfile - inhibitionReason: dialog.inhibitionReason - visible: dialog.profiles.length > 0 - degradationReason: dialog.degradationReason - profileHolds: dialog.profileHolds - onActivateProfileRequested: dialog.activateProfileRequested(profile) - } - Item { - Layout.fillWidth: true - // additional margin, because the bottom of PowerProfileItem - // and the top of BatteryItem are more dense. + BrightnessItem { + id: keyboardBrightnessSlider + + width: scrollView.availableWidth + + icon.name: "input-keyboard-brightness" + text: i18n("Keyboard Brightness") + showPercentage: false + value: batterymonitor.keyboardBrightness + maximumValue: batterymonitor.maximumKeyboardBrightness + visible: isKeyboardBrightnessAvailable + + KeyNavigation.up: brightnessSlider.visible ? brightnessSlider : brightnessSlider.KeyNavigation.up + KeyNavigation.down: powerProfileItem.visible ? powerProfileItem : powerProfileItem.KeyNavigation.down + KeyNavigation.backtab: KeyNavigation.up + KeyNavigation.tab: KeyNavigation.down + + onMoved: batterymonitor.keyboardBrightness = value + + // Manually dragging the slider around breaks the binding + Connections { + target: batterymonitor + function onKeyboardBrightnessChanged() { + keyboardBrightnessSlider.value = batterymonitor.keyboardBrightness; + } } } - delegate: BatteryItem { - width: ListView.view.width - PlasmaCore.Units.smallSpacing * 4 + PowerProfileItem { + id: powerProfileItem + + width: scrollView.availableWidth + + KeyNavigation.up: keyboardBrightnessSlider.visible ? keyboardBrightnessSlider : keyboardBrightnessSlider.KeyNavigation.up + KeyNavigation.down: batteryRepeater.count > 0 ? batteryRepeater.itemAt(0) : null + KeyNavigation.backtab: KeyNavigation.up + KeyNavigation.tab: KeyNavigation.down - battery: model - remainingTime: dialog.remainingTime - matchHeightOfSlider: ListView.view.headerItem ? ListView.view.headerItem.children[1].slider : null + activeProfile: dialog.activeProfile + inhibitionReason: dialog.inhibitionReason + visible: dialog.profiles.length > 0 + degradationReason: dialog.degradationReason + profileHolds: dialog.profileHolds + onActivateProfileRequested: dialog.activateProfileRequested(profile) + } + + Repeater { + id: batteryRepeater + + delegate: BatteryItem { + width: scrollView.availableWidth + + battery: model + remainingTime: dialog.remainingTime + matchHeightOfSlider: batteryList.firstHeaderItem ? batteryList.firstHeaderItem.slider : null + + KeyNavigation.up: index === 0 ? batteryList.lastHeaderItem : batteryRepeater.itemAt(index - 1) + KeyNavigation.down: index + 1 < batteryRepeater.count ? batteryRepeater.itemAt(index + 1) : null + KeyNavigation.backtab: KeyNavigation.up + KeyNavigation.tab: KeyNavigation.down + } } } } } + diff --git a/applets/batterymonitor/package/contents/ui/PowerManagementItem.qml b/applets/batterymonitor/package/contents/ui/PowerManagementItem.qml index 18ae7cb60..0c9f2e858 100644 --- a/applets/batterymonitor/package/contents/ui/PowerManagementItem.qml +++ b/applets/batterymonitor/package/contents/ui/PowerManagementItem.qml @@ -15,6 +15,7 @@ import org.kde.plasma.core 2.1 as PlasmaCore ColumnLayout { id: root + property alias pmCheckBox: pmCheckBox property alias disabled: pmCheckBox.checked property bool pluggedIn @@ -35,6 +36,12 @@ ColumnLayout { Layout.fillWidth: true text: i18nc("Minimize the length of this string as much as possible", "Manually block sleep and screen locking") checked: false + focus: true + + KeyNavigation.up: dialog.KeyNavigation.up + KeyNavigation.down: batteryList.children[0] + KeyNavigation.backtab: dialog.KeyNavigation.backtab + KeyNavigation.tab: KeyNavigation.down } // Separator line diff --git a/applets/batterymonitor/package/contents/ui/PowerProfileItem.qml b/applets/batterymonitor/package/contents/ui/PowerProfileItem.qml index 9bab9c9a4..6a8d41842 100644 --- a/applets/batterymonitor/package/contents/ui/PowerProfileItem.qml +++ b/applets/batterymonitor/package/contents/ui/PowerProfileItem.qml @@ -11,9 +11,11 @@ import QtQuick.Layouts 1.15 import org.kde.plasma.components 3.0 as PlasmaComponents3 import org.kde.plasma.core 2.1 as PlasmaCore -RowLayout { +PlasmaComponents3.ItemDelegate { id: root + property alias slider: slider + property string activeProfile property string inhibitionReason @@ -51,190 +53,204 @@ RowLayout { signal activateProfileRequested(string profile) - spacing: PlasmaCore.Units.gridUnit + background.visible: highlighted + highlighted: activeFocus + hoverEnabled: false + text: i18n("Power Profile") - PlasmaCore.IconItem { - source: "speedometer" - Layout.alignment: Qt.AlignTop - Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium - Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium - } + Accessible.description: activeProfileLabel.text + Accessible.role: Accessible.Slider + Keys.forwardTo: [slider] - ColumnLayout { - Layout.fillWidth: true - Layout.alignment: Qt.AlignTop - spacing: 0 + contentItem: RowLayout { + spacing: PlasmaCore.Units.gridUnit + + PlasmaCore.IconItem { + source: "speedometer" + Layout.alignment: Qt.AlignTop + Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium + Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium + } - RowLayout { + ColumnLayout { Layout.fillWidth: true - spacing: PlasmaCore.Units.smallSpacing + Layout.alignment: Qt.AlignTop + spacing: 0 - PlasmaComponents3.Label { + RowLayout { Layout.fillWidth: true - elide: Text.ElideRight - text: i18n("Power Profile") - } + spacing: PlasmaCore.Units.smallSpacing - PlasmaComponents3.Label { - Layout.alignment: Qt.AlignRight - text: activeProfileData ? activeProfileData.label : "" + PlasmaComponents3.Label { + Layout.fillWidth: true + elide: Text.ElideRight + text: root.text + } + + PlasmaComponents3.Label { + id: activeProfileLabel + Layout.alignment: Qt.AlignRight + text: activeProfileData ? activeProfileData.label : "" + } } - } - PlasmaComponents3.Slider { - Layout.fillWidth: true + PlasmaComponents3.Slider { + id: slider + Layout.fillWidth: true - from: 0 - to: 2 - stepSize: 1 - value: root.activeProfileIndex - snapMode: PlasmaComponents3.Slider.SnapAlways - onMoved: { - const { canBeInhibited, profile } = root.profileData[value]; - if (!(canBeInhibited && root.inhibited)) { - activateProfileRequested(profile); - } else { - value = Qt.binding(() => root.activeProfileIndex); + activeFocusOnTab: false + from: 0 + to: 2 + stepSize: 1 + value: root.activeProfileIndex + snapMode: PlasmaComponents3.Slider.SnapAlways + onMoved: { + const { canBeInhibited, profile } = root.profileData[value]; + if (!(canBeInhibited && root.inhibited)) { + activateProfileRequested(profile); + } else { + value = Qt.binding(() => root.activeProfileIndex); + } } - } - // fake having a disabled second half - Rectangle { - z: -1 - visible: root.inhibited - color: PlasmaCore.Theme.backgroundColor - anchors { - top: parent.background.top - left: parent.horizontalCenter - leftMargin: 1 - right: parent.right - bottom: parent.background.bottom + // fake having a disabled second half + Rectangle { + z: -1 + visible: root.inhibited + color: PlasmaCore.Theme.backgroundColor + anchors { + top: parent.background.top + left: parent.horizontalCenter + leftMargin: 1 + right: parent.right + bottom: parent.background.bottom + } + opacity: 0.4 } - opacity: 0.4 } - } - RowLayout { - spacing: 0 - Layout.topMargin: PlasmaCore.Units.smallSpacing - Layout.bottomMargin: PlasmaCore.Units.smallSpacing - Layout.fillWidth: true + RowLayout { + spacing: 0 + Layout.topMargin: PlasmaCore.Units.smallSpacing + Layout.bottomMargin: PlasmaCore.Units.smallSpacing + Layout.fillWidth: true - PlasmaCore.Svg { - id: svg - imagePath: "icons/battery" - } + PlasmaCore.Svg { + id: svg + imagePath: "icons/battery" + } - PlasmaCore.SvgItem { - Layout.preferredHeight: PlasmaCore.Units.iconSizes.smallMedium - Layout.preferredWidth: PlasmaCore.Units.iconSizes.smallMedium - svg: svg - elementId: "profile-powersave" + PlasmaCore.SvgItem { + Layout.preferredHeight: PlasmaCore.Units.iconSizes.smallMedium + Layout.preferredWidth: PlasmaCore.Units.iconSizes.smallMedium + svg: svg + elementId: "profile-powersave" - HoverHandler { - id: powersaveIconHover - } + HoverHandler { + id: powersaveIconHover + } - PlasmaComponents3.ToolTip { - text: root.profileData.find(profile => profile.profile === "power-saver").label - visible: powersaveIconHover.hovered + PlasmaComponents3.ToolTip { + text: root.profileData.find(profile => profile.profile === "power-saver").label + visible: powersaveIconHover.hovered + } } - } - Item { - Layout.fillWidth: true - } + Item { + Layout.fillWidth: true + } - PlasmaCore.SvgItem { - Layout.preferredHeight: PlasmaCore.Units.iconSizes.smallMedium - Layout.preferredWidth: PlasmaCore.Units.iconSizes.smallMedium - svg: svg - elementId: "profile-performance" + PlasmaCore.SvgItem { + Layout.preferredHeight: PlasmaCore.Units.iconSizes.smallMedium + Layout.preferredWidth: PlasmaCore.Units.iconSizes.smallMedium + svg: svg + elementId: "profile-performance" - HoverHandler { - id: performanceIconHover - } + HoverHandler { + id: performanceIconHover + } - PlasmaComponents3.ToolTip { - text: root.profileData.find(profile => profile.profile === "performance").label - visible: performanceIconHover.hovered + PlasmaComponents3.ToolTip { + text: root.profileData.find(profile => profile.profile === "performance").label + visible: performanceIconHover.hovered + } } } - } - // NOTE Only one of these will be visible at a time since the daemon will only set one depending - // on its version - InhibitionHint { - id: inhibitionReasonHint + // NOTE Only one of these will be visible at a time since the daemon will only set one depending + // on its version + InhibitionHint { + id: inhibitionReasonHint - Layout.fillWidth: true + Layout.fillWidth: true - visible: root.inhibited - iconSource: "dialog-information" - text: switch(root.inhibitionReason) { - case "lap-detected": - return i18n("Performance mode has been disabled to reduce heat generation because the computer has detected that it may be sitting on your lap.") - case "high-operating-temperature": - return i18n("Performance mode is unavailable because the computer is running too hot.") - default: - return i18n("Performance mode is unavailable.") + visible: root.inhibited + iconSource: "dialog-information" + text: switch(root.inhibitionReason) { + case "lap-detected": + return i18n("Performance mode has been disabled to reduce heat generation because the computer has detected that it may be sitting on your lap.") + case "high-operating-temperature": + return i18n("Performance mode is unavailable because the computer is running too hot.") + default: + return i18n("Performance mode is unavailable.") + } } - } - InhibitionHint { - id: inhibitionPerformanceHint + InhibitionHint { + id: inhibitionPerformanceHint - Layout.fillWidth: true + Layout.fillWidth: true - visible: root.activeProfile === "performance" && root.degradationReason !== "" - iconSource: "dialog-information" - text: switch(root.degradationReason) { - case "lap-detected": - return i18n("Performance may be lowered to reduce heat generation because the computer has detected that it may be sitting on your lap.") - case "high-operating-temperature": - return i18n("Performance may be reduced because the computer is running too hot.") - default: - return i18n("Performance may be reduced.") + visible: root.activeProfile === "performance" && root.degradationReason !== "" + iconSource: "dialog-information" + text: switch(root.degradationReason) { + case "lap-detected": + return i18n("Performance may be lowered to reduce heat generation because the computer has detected that it may be sitting on your lap.") + case "high-operating-temperature": + return i18n("Performance may be reduced because the computer is running too hot.") + default: + return i18n("Performance may be reduced.") + } } - } - InhibitionHint { - id: inhibitionHoldersHint + InhibitionHint { + id: inhibitionHoldersHint - Layout.fillWidth: true + Layout.fillWidth: true - visible: root.activeHolds.length > 0 && root.activeProfileData !== undefined - text: root.activeProfileData !== undefined - ? i18np("One application has requested activating %2:", - "%1 applications have requested activating %2:", - root.activeHolds.length, - i18n(root.activeProfileData.label)) - : "" - } + visible: root.activeHolds.length > 0 && root.activeProfileData !== undefined + text: root.activeProfileData !== undefined + ? i18np("One application has requested activating %2:", + "%1 applications have requested activating %2:", + root.activeHolds.length, + i18n(root.activeProfileData.label)) + : "" + } - Repeater { - id: repeater + Repeater { + id: repeater - model: root.activeHolds + model: root.activeHolds - InhibitionHint { - Layout.fillWidth: true + InhibitionHint { + Layout.fillWidth: true - x: PlasmaCore.Units.smallSpacing - iconSource: modelData.Icon - text: i18nc("%1 is the name of the application, %2 is the reason provided by it for activating performance mode", - "%1: %2", modelData.Name, modelData.Reason) + x: PlasmaCore.Units.smallSpacing + iconSource: modelData.Icon + text: i18nc("%1 is the name of the application, %2 is the reason provided by it for activating performance mode", + "%1: %2", modelData.Name, modelData.Reason) + } } - } - Item { - Layout.fillWidth: true - Layout.preferredHeight: PlasmaCore.Units.smallSpacing + Item { + Layout.fillWidth: true + Layout.preferredHeight: PlasmaCore.Units.smallSpacing - visible: repeater.visibleChildren > 0 - || inhibitionReasonHint.visible - || inhibitionPerformanceHint.visible - || inhibitionHoldersHint.visible + visible: repeater.visibleChildren > 0 + || inhibitionReasonHint.visible + || inhibitionPerformanceHint.visible + || inhibitionHoldersHint.visible + } } } } diff --git a/applets/batterymonitor/package/contents/ui/main.qml b/applets/batterymonitor/package/contents/ui/main.qml index a7b5ad1cf..a83cb3d15 100644 --- a/applets/batterymonitor/package/contents/ui/main.qml +++ b/applets/batterymonitor/package/contents/ui/main.qml @@ -249,7 +249,6 @@ Item { id: dialogItem model: Plasmoid.expanded ? batteries : null - focus: true isBrightnessAvailable: batterymonitor.isBrightnessAvailable isKeyboardBrightnessAvailable: batterymonitor.isKeyboardBrightnessAvailable