File 2001-battery-applet.patch of Package powerdevil6
diff --git a/applets/batterymonitor/package/contents/ui/CompactRepresentation.qml b/applets/batterymonitor/package/contents/ui/CompactRepresentation.qml
index 3cbfba60a16f504ecf191b21f7376dc33289aaaf..a4f7317a583f6387cfc6e9ddca015cceaed98a3f 100644
--- a/applets/batterymonitor/package/contents/ui/CompactRepresentation.qml
+++ b/applets/batterymonitor/package/contents/ui/CompactRepresentation.qml
@@ -30,7 +30,7 @@ MouseArea {
required property bool isSomehowFullyCharged
required property bool isDischarging
- required property bool isManuallyInhibited
+ required property bool isInhibited
required property bool isInDefaultPowerProfile
required property bool isInPowersaveProfile
required property bool isInBalancedProfile
@@ -50,7 +50,7 @@ MouseArea {
: isInPerformanceProfile ? "battery-profile-performance-symbolic"
: Plasmoid.icon
- readonly property string powerModeIconSrc: isManuallyInhibited
+ readonly property string powerModeIconSrc: isInhibited
? "system-suspend-inhibited-symbolic"
: !isInDefaultPowerProfile
? activeProfileIconSrc
@@ -62,7 +62,7 @@ MouseArea {
anchors.fill: parent
- visible: root.isConstrained && (!root.hasInternalBatteries || (root.isManuallyInhibited && !root.isDischarging))
+ visible: root.isConstrained && (!root.hasInternalBatteries || (root.isInhibited && !root.isDischarging))
source: root.powerModeIconSrc
active: root.containsMouse
}
diff --git a/applets/batterymonitor/package/contents/ui/InhibitionHint.qml b/applets/batterymonitor/package/contents/ui/InhibitionHint.qml
index 80e198280fd1cb4021369104ec693bbce61ae094..0d39491a37c7e874bccbb582cc8c7441593a3970 100644
--- a/applets/batterymonitor/package/contents/ui/InhibitionHint.qml
+++ b/applets/batterymonitor/package/contents/ui/InhibitionHint.qml
@@ -11,25 +11,48 @@ import org.kde.plasma.components as PlasmaComponents3
import org.kde.kirigami as Kirigami
RowLayout {
+ property alias allowed: content.enabled
property alias iconSource: iconItem.source
property alias text: label.text
+ property alias description: descriptionLabel.text
spacing: Kirigami.Units.smallSpacing
- Kirigami.Icon {
- id: iconItem
- Layout.preferredWidth: Kirigami.Units.iconSizes.small
- Layout.preferredHeight: Kirigami.Units.iconSizes.small
- visible: valid
- }
+ GridLayout {
+ id: content
- PlasmaComponents3.Label {
- id: label
Layout.fillWidth: true
- font: Kirigami.Theme.smallFont
- textFormat: Text.PlainText
- wrapMode: Text.WordWrap
- elide: Text.ElideRight
- maximumLineCount: 4
+ columns: 2
+ columnSpacing: Kirigami.Units.smallSpacing
+ rowSpacing: 0
+
+ Kirigami.Icon {
+ id: iconItem
+ Layout.rowSpan: 2
+ Layout.preferredWidth: descriptionLabel.visible ? Kirigami.Units.iconSizes.smallMedium : Kirigami.Units.iconSizes.small
+ Layout.preferredHeight: Layout.preferredWidth
+ enabled: !parent.blocked
+ visible: valid
+ }
+
+ PlasmaComponents3.Label {
+ id: label
+ Layout.fillWidth: true
+ textFormat: Text.PlainText
+ wrapMode: Text.WordWrap
+ elide: Text.ElideRight
+ maximumLineCount: 4
+ }
+
+ PlasmaComponents3.Label {
+ id: descriptionLabel
+ Layout.fillWidth: true
+ font: Kirigami.Theme.smallFont
+ textFormat: Text.PlainText
+ wrapMode: Text.WordWrap
+ elide: Text.ElideRight
+ maximumLineCount: 4
+ visible: text.length > 0
+ }
}
}
diff --git a/applets/batterymonitor/package/contents/ui/PopupDialog.qml b/applets/batterymonitor/package/contents/ui/PopupDialog.qml
index 1f5efe26e1c40453562dd478ebc25c8ce3db97d8..ae9b85269121a989ac286d7107ab19245facec3e 100644
--- a/applets/batterymonitor/package/contents/ui/PopupDialog.qml
+++ b/applets/batterymonitor/package/contents/ui/PopupDialog.qml
@@ -19,7 +19,6 @@ PlasmaExtras.Representation {
property bool pluggedIn
property int chargeStopThreshold
property bool isManuallyInhibited
- property bool isManuallyInhibitedError
property int remainingTime
@@ -47,12 +46,11 @@ PlasmaExtras.Representation {
// type: [{ Name: string, Icon: string, Profile: string, Reason: string }]
required property var profileHolds
- signal inhibitionChangeRequested(bool inhibit)
signal activateProfileRequested(string profile)
collapseMarginsHint: true
- KeyNavigation.down: batteryRepeater.headerItem
+ KeyNavigation.down: powerProfileItem
contentItem: PlasmaComponents3.ScrollView {
id: scrollView
@@ -71,99 +69,99 @@ PlasmaExtras.Representation {
}
}
- ListView {
- id: batteryRepeater
-
+ Column {
spacing: Kirigami.Units.smallSpacing * 2
- // Note: this Column prevents ListView from throwing a cryptic warning and breaking CI:
- // > QQmlComponent: Cannot create new component instance before completing the previous
- // However, it also the source of a bug that the view is slightly scrollable for no reason.
- header: Column {
- width: scrollView.availableWidth
-
- PowerProfileItem {
- anchors.left: parent.left
- anchors.right: parent.right
+ PowerProfileItem {
+ id: powerProfileItem
- KeyNavigation.up: batteryRepeater.footerItem
- KeyNavigation.down: batteryRepeater.count > 0 ? batteryRepeater.itemAtIndex(0) : batteryRepeater.footerItem
- KeyNavigation.backtab: KeyNavigation.up
- KeyNavigation.tab: KeyNavigation.down
+ width: scrollView.availableWidth
- profilesInstalled: dialog.profilesInstalled
- profilesAvailable: dialog.profiles.length > 0
- activeProfile: dialog.activeProfile
- activeProfileError: dialog.activeProfileError
- inhibitionReason: dialog.inhibitionReason
- degradationReason: dialog.degradationReason
- profileHolds: dialog.profileHolds
+ KeyNavigation.up: dialog.KeyNavigation.up
+ KeyNavigation.down: batteryRepeater.count > 0 ? batteryRepeater.itemAt(0) : powerManagementItem
+ KeyNavigation.backtab: dialog.KeyNavigation.backtab
+ KeyNavigation.tab: KeyNavigation.down
- isTlpInstalled: dialog.isTlpInstalled
+ profilesInstalled: dialog.profilesInstalled
+ profilesAvailable: dialog.profiles.length > 0
+ activeProfile: dialog.activeProfile
+ activeProfileError: dialog.activeProfileError
+ inhibitionReason: dialog.inhibitionReason
+ degradationReason: dialog.degradationReason
+ profileHolds: dialog.profileHolds
+ isTlpInstalled: dialog.isTlpInstalled
+
+ onActivateProfileRequested: profile => {
+ dialog.activateProfileRequested(profile);
+ }
- onActivateProfileRequested: profile => {
- dialog.activateProfileRequested(profile);
+ onActiveFocusChanged: {
+ if (activeFocus) {
+ scrollView.positionViewAtItem(this);
}
-
- onActiveFocusChanged: if (activeFocus) scrollView.positionViewAtItem(this)
}
}
- delegate: BatteryItem {
- width: scrollView.availableWidth
-
- batteryPercent: Percent
- batteryCapacity: Capacity
- batteryEnergy: Energy
- batteryPluggedIn: PluggedIn
- batteryIsPowerSupply: IsPowerSupply
- batteryChargeState: ChargeState
- batteryPrettyName: PrettyName
- batteryType: Type
- remainingTime: dialog.remainingTime
-
- KeyNavigation.up: index === 0 ? (batteryRepeater.headerItem.visible ? batteryRepeater.headerItem : batteryRepeater.headerItem.KeyNavigation.up) : batteryRepeater.itemAtIndex(index - 1)
- KeyNavigation.down: index + 1 < batteryRepeater.count ? batteryRepeater.itemAtIndex(index + 1) : batteryRepeater.footerItem
-
- pluggedIn: dialog.pluggedIn
- chargeStopThreshold: dialog.chargeStopThreshold
+ Repeater {
+ id: batteryRepeater
+
+ BatteryItem {
+ width: scrollView.availableWidth
+
+ batteryPercent: Percent
+ batteryCapacity: Capacity
+ batteryEnergy: Energy
+ batteryPluggedIn: PluggedIn
+ batteryIsPowerSupply: IsPowerSupply
+ batteryChargeState: ChargeState
+ batteryPrettyName: PrettyName
+ batteryType: Type
+ remainingTime: dialog.remainingTime
+ pluggedIn: dialog.pluggedIn
+ chargeStopThreshold: dialog.chargeStopThreshold
+
+ KeyNavigation.up: index > 0 ? batteryRepeater.itemAt(index - 1) : powerProfileItem
+ KeyNavigation.down: index < batteryRepeater.count - 1 ? batteryRepeater.itemAt(index + 1) : powerManagementItem
+ KeyNavigation.backtab: KeyNavigation.up
+ KeyNavigation.tab: KeyNavigation.down
- KeyNavigation.backtab: KeyNavigation.up
- KeyNavigation.tab: KeyNavigation.down
+ Keys.onTabPressed: event => {
+ if (index === batteryRepeater.count - 1) {
+ // Workaround to leave applet's focus on desktop
+ nextItemInFocusChain(false).forceActiveFocus(Qt.TabFocusReason);
+ } else {
+ event.accepted = false;
+ }
+ }
- Keys.onTabPressed: event => {
- if (index === batteryRepeater.count - 1) {
- // Workaround to leave applet's focus on desktop
- nextItemInFocusChain(false).forceActiveFocus(Qt.TabFocusReason);
- } else {
- event.accepted = false;
+ onActiveFocusChanged: {
+ if (activeFocus) {
+ scrollView.positionViewAtItem(this);
+ }
}
}
-
- onActiveFocusChanged: if (activeFocus) scrollView.positionViewAtItem(this)
}
- footer: PowerManagementItem {
- readonly property var pmControl: dialog.pmControl
+ PowerManagementItem {
+ id: powerManagementItem
width: scrollView.availableWidth
-
- KeyNavigation.up: batteryRepeater.itemAtIndex(batteryRepeater.count - 1)
- KeyNavigation.down: null
- KeyNavigation.backtab:KeyNavigation.up
-
inhibitions: dialog.inhibitions
blockedInhibitions: dialog.blockedInhibitions
isManuallyInhibited: dialog.isManuallyInhibited
- isManuallyInhibitedError: dialog.isManuallyInhibitedError
inhibitsLidAction: dialog.inhibitsLidAction
- pluggedIn: dialog.pluggedIn
+
+ KeyNavigation.up: batteryRepeater.count > 0 ? batteryRepeater.itemAt(batteryRepeater.count - 1) : powerProfileItem
onInhibitionChangeRequested: inhibit => {
batterymonitor.inhibitionChangeRequested(inhibit);
}
- onActiveFocusChanged: if (activeFocus) scrollView.positionViewAtItem(this)
+ onActiveFocusChanged: {
+ if (activeFocus) {
+ scrollView.positionViewAtItem(this);
+ }
+ }
}
}
}
diff --git a/applets/batterymonitor/package/contents/ui/PowerManagementItem.qml b/applets/batterymonitor/package/contents/ui/PowerManagementItem.qml
index b6727376c9026c6148c36c325ad1100dfad4793c..866e6a465f1a92faa4c75f701ecfaf48d4c70d7e 100644
--- a/applets/batterymonitor/package/contents/ui/PowerManagementItem.qml
+++ b/applets/batterymonitor/package/contents/ui/PowerManagementItem.qml
@@ -8,10 +8,9 @@
import QtQuick
import QtQuick.Layouts
-import QtQuick.Controls
-import org.kde.notification
-import org.kde.kwindowsystem as KWindowSystem
+import org.kde.plasma.plasmoid
+import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components as PlasmaComponents3
import org.kde.plasma.extras as PlasmaExtras
import org.kde.ksvg as KSvg
@@ -20,12 +19,24 @@ import org.kde.kirigami as Kirigami
PlasmaComponents3.ItemDelegate {
id: root
- property bool pluggedIn
+ component InlineMessage: PlasmaComponents3.ItemDelegate {
+ hoverEnabled: false
+ padding: Kirigami.Units.largeSpacing
+ background: Rectangle {
+ border.color: transparentize(Kirigami.Theme.textColor, Kirigami.Theme.frameContrast)
+ border.width: 1
+ color: transparentize(Kirigami.Theme.textColor, Kirigami.Theme.lightFrameContrast)
+ radius: Kirigami.Units.cornerRadius
+
+ function transparentize(color, alpha) {
+ return Qt.rgba(color.r, color.g, color.b, alpha);
+ }
+ }
+ }
signal inhibitionChangeRequested(bool inhibit)
property bool isManuallyInhibited
- property bool isManuallyInhibitedError
// List of active power management inhibitions (applications that are
// blocking sleep and screen locking).
//
@@ -39,21 +50,13 @@ PlasmaComponents3.ItemDelegate {
property var blockedInhibitions: []
property bool inhibitsLidAction
- background.visible: highlighted
+ readonly property bool hasHeader: Plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentDrawsPlasmoidHeading
+
highlighted: activeFocus
hoverEnabled: false
text: i18nc("@title:group", "Sleep and Screen Locking after Inactivity")
- Notification {
- id: inhibitionError
- componentName: "plasma_workspace"
- eventId: "warning"
- iconName: "system-suspend-uninhibited"
- title: i18n("Power Management")
- }
-
Accessible.description: pmStatusLabel.text
- Accessible.role: Accessible.CheckBox
contentItem: RowLayout {
spacing: Kirigami.Units.gridUnit
@@ -66,6 +69,8 @@ PlasmaComponents3.ItemDelegate {
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
}
+ KeyNavigation.tab: inhibitionSwitch.visible ? inhibitionSwitch : inhibitionSwitch.KeyNavigation.tab
+
ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
@@ -73,6 +78,7 @@ PlasmaComponents3.ItemDelegate {
RowLayout {
Layout.fillWidth: true
+ Layout.bottomMargin: Kirigami.Units.smallSpacing
spacing: Kirigami.Units.largeSpacing
PlasmaComponents3.Label {
@@ -91,279 +97,161 @@ PlasmaComponents3.ItemDelegate {
}
}
- // list of inhibitions
- ColumnLayout {
- id: inhibitionReasonsLayout
-
- Layout.fillWidth: true
-
- InhibitionHint {
- readonly property var pmControl: root.pmControl
-
- Layout.fillWidth: true
- visible: root.inhibitsLidAction
- iconSource: "computer-laptop"
- text: i18nc("Minimize the length of this string as much as possible", "Your laptop is configured not to sleep when closing the lid while an external monitor is connected.")
+ RowLayout {
+ Layout.bottomMargin: Kirigami.Units.largeSpacing
+ spacing: Kirigami.Units.smallSpacing
+ visible: !root.hasHeader
+
+ PlasmaComponents3.Switch {
+ id: inhibitionSwitch
+ checked: root.isManuallyInhibited
+ text: i18nc("@action:button Block sleep and screen locking after inactivity", "Manually Block")
+
+ Accessible.onPressAction: toggled()
+
+ Keys.onPressed: event => {
+ switch (event.key) {
+ case Qt.Key_Enter:
+ case Qt.Key_Return:
+ case Qt.Key_Space:
+ toggle();
+ break;
+ default:
+ break;
+ }
+ }
+ onToggled: inhibitionChangeRequested(!root.isManuallyInhibited)
}
- // list of automatic inhibitions
- PlasmaComponents3.Label {
- id: inhibitionExplanation
+ Item {
Layout.fillWidth: true
- visible: root.inhibitions.length > 1
- font: Kirigami.Theme.smallFont
- wrapMode: Text.WordWrap
- elide: Text.ElideRight
- maximumLineCount: 3
- text: i18np("%1 application is currently blocking sleep and screen locking:",
- "%1 applications are currently blocking sleep and screen locking:",
- root.inhibitions.length)
- textFormat: Text.PlainText
}
+ }
- Repeater {
- model: root.inhibitions
-
- InhibitionHint {
- property string icon: modelData.Icon
- || (KWindowSystem.KWindowSystem.isPlatformWayland ? "wayland" : "xorg")
- property string app: modelData.Name
- property string name: modelData.PrettyName
- property string reason: modelData.Reason
- property bool permanentlyBlocked: {
- return root.blockedInhibitions.some(function (blockedInhibition) {
- return blockedInhibition.Name === app && blockedInhibition.Reason === reason && blockedInhibition.Permanently;
- });
- }
+ InlineMessage {
+ Layout.fillWidth: true
+ visible: root.isManuallyInhibited
+ contentItem: InhibitionHint {
+ iconSource: "user"
+ text: i18nc("Keep this text as short as possible", "You have manually blocked sleep and screen locking")
+ }
+ }
- Layout.fillWidth: true
- iconSource: icon
- text: {
- if (root.inhibitions.length === 1) {
- if (reason && name) {
- return i18n("%1 is currently blocking sleep and screen locking (%2)", name, reason)
- } else if (name) {
- return i18n("%1 is currently blocking sleep and screen locking (unknown reason)", name)
- } else if (reason) {
- return i18n("An application is currently blocking sleep and screen locking (%1)", reason)
- } else {
- return i18n("An application is currently blocking sleep and screen locking (unknown reason)")
- }
- } else {
- if (reason && name) {
- return i18nc("Application name: reason for preventing sleep and screen locking", "%1: %2", name, reason)
- } else if (name) {
- return i18nc("Application name: reason for preventing sleep and screen locking", "%1: unknown reason", name)
- } else if (reason) {
- return i18nc("Application name: reason for preventing sleep and screen locking", "Unknown application: %1", reason)
- } else {
- return i18nc("Application name: reason for preventing sleep and screen locking", "Unknown application: unknown reason")
- }
- }
- }
+ InlineMessage {
+ Layout.fillWidth: true
+ visible: root.inhibitsLidAction
+ contentItem: InhibitionHint {
+ iconSource: "computer-laptop"
+ text: i18nc("Keep this text as short as possible", "Your laptop is configured not to sleep when closing the lid while an external monitor is connected")
+ }
+ }
- Item {
- visible: !permanentlyBlocked
- width: blockMenuButton.width
- height: blockMenuButton.height
-
- PlasmaComponents3.Button {
- id: blockMenuButton
- text: i18nc("@action:button Prevent an app from blocking automatic sleep and screen locking after inactivity", "Unblock")
- icon.name: "edit-delete-remove"
- Accessible.role: Accessible.ButtonMenu
- onClicked: blockMenuButtonMenu.open()
- }
+ InlineMessage {
+ Layout.fillWidth: true
+ visible: repeater.model.length > 0
+ contentItem: ColumnLayout {
+ spacing: Kirigami.Units.smallSpacing
- PlasmaExtras.Menu {
- id: blockMenuButtonMenu
+ PlasmaComponents3.Label {
+ Layout.fillWidth: true
+ wrapMode: Text.WordWrap
+ elide: Text.ElideRight
+ maximumLineCount: 4
+ textFormat: Text.PlainText
+ text: i18nc("Keep this text as short as possible", "Applications blocking sleep and screen locking")
+ }
- PlasmaExtras.MenuItem {
- text: i18nc("@action:button Prevent an app from blocking automatic sleep and screen locking after inactivity", "Only this time")
- onClicked: pmControl.blockInhibition(app, reason, false)
- }
+ KSvg.SvgItem {
+ Layout.fillWidth: true
+ imagePath: "widgets/line"
+ elementId: "horizontal-line"
+ }
- PlasmaExtras.MenuItem {
- text: i18nc("@action:button Prevent an app from blocking automatic sleep and screen locking after inactivity", "Every time for this app and reason")
- onClicked: pmControl.blockInhibition(app, reason, true)
+ Repeater {
+ id: repeater
+
+ model: {
+ const inhibitions = [...root.inhibitions];
+ root.blockedInhibitions.forEach((blockedInhibition) => {
+ const allowedInhibition = inhibitions.find((inhibition) => {
+ return inhibition.Name === blockedInhibition.Name && inhibition.Reason === blockedInhibition.Reason;
+ });
+ if (allowedInhibition) {
+ allowedInhibition.Permanently = blockedInhibition.Permanently;
+ } else {
+ blockedInhibition.Blocked = true;
+ inhibitions.push(blockedInhibition);
}
- }
+ });
+ inhibitions.sort((inhibition1, inhibition2) => {
+ return inhibition1.Name.localeCompare(inhibition2.Name);
+ });
+ return inhibitions;
}
- Item {
- visible: permanentlyBlocked
- width: blockButton.width
- height: blockButton.height
-
- PlasmaComponents3.Button {
- id: blockButton
- text: i18nc("@action:button Prevent an app from blocking automatic sleep and screen locking after inactivity", "Unblock")
- icon.name: "edit-delete-remove"
- onClicked: pmControl.blockInhibition(app, reason, true)
- }
- }
- }
- }
+ InhibitionHint {
+ readonly property string app: modelData.Name
+ readonly property string reason: modelData.Reason
+ readonly property bool permanently: !!modelData.Permanently
- // UI to undo manually inhibit sleep and screen locking
- InhibitionHint {
- visible: root.isManuallyInhibited
+ Layout.fillWidth: true
+ allowed: !modelData.Blocked
+ iconSource: modelData.Icon || "application-x-executable"
+ text: modelData.PrettyName || i18n("Unknown application")
+ description: reason || i18n("Unknown reason")
- iconSource: "user"
- text: i18nc("Minimize the length of this string as much as possible", "You have manually blocked sleep and screen locking.")
+ PlasmaComponents3.ToolButton {
+ icon.name: "view-more-symbolic"
- PlasmaComponents3.Button {
- id: manualUninhibitionButton
- Layout.alignment: Qt.AlignRight
- text: i18nc("@action:button Undo blocking sleep and screen locking after inactivity", "Unblock")
- icon.name: "edit-delete-remove"
+ PlasmaExtras.Menu {
+ id: menu
- Keys.onPressed: (event) => {
- if (event.key == Qt.Key_Space || event.key == Qt.Key_Return || event.key == Qt.Key_Enter) {
- click();
- }
- }
+ placement: PlasmaExtras.Menu.BottomPosedLeftAlignedPopup
- onClicked: {
- inhibitionChangeRequested(!root.isManuallyInhibited);
- }
+ PlasmaExtras.MenuItem {
+ text: i18nc("@action:button Block this app", "Block only this time")
+ visible: allowed && !permanently
- Connections {
- target: root
- function onIsManuallyInhibitedErrorChanged() {
- if (root.isManuallyInhibitedError) {
- root.isManuallyInhibitedError = false;
- if (!root.isManuallyInhibited) {
- inhibitionError.text = i18n("Failed to unblock automatic sleep and screen locking");
- inhibitionError.sendEvent();
- } else {
- inhibitionError.text = i18n("Failed to block automatic sleep and screen locking");
- inhibitionError.sendEvent();
+ onClicked: pmControl.blockInhibition(app, reason, false)
}
- }
- }
- }
- }
- }
- // list of blocked inhibitions
- PlasmaComponents3.Label {
- id: blockedInhibitionExplanation
- Layout.fillWidth: true
- visible: root.blockedInhibitions.length > 1
- font: Kirigami.Theme.smallFont
- wrapMode: Text.WordWrap
- elide: Text.ElideRight
- maximumLineCount: 3
- text: i18np("%1 application has been prevented from blocking sleep and screen locking:",
- "%1 applications have been prevented from blocking sleep and screen locking:",
- root.blockedInhibitions.length)
- textFormat: Text.PlainText
- }
+ PlasmaExtras.MenuItem {
+ text: {
+ if (permanently) {
+ return i18nc("@action:button Block this app", "Block again");
+ }
+ return i18nc("@action:button Block this app", "Block every time for this app and reason");
+ }
+ visible: allowed
- Repeater {
- model: root.blockedInhibitions
-
- InhibitionHint {
- property string icon: modelData.Icon
- || (KWindowSystem.isPlatformWayland ? "wayland" : "xorg")
- property string app: modelData.Name
- property string name: modelData.PrettyName
- property string reason: modelData.Reason
- property bool permanently: modelData.Permanently
- property bool temporarilyUnblocked: {
- return root.inhibitions.some(function (inhibition) {
- return inhibition.Name === app && inhibition.Reason === reason;
- });
- }
- visible: !temporarilyUnblocked
+ onClicked: pmControl.blockInhibition(app, reason, true)
+ }
- Layout.fillWidth: true
- iconSource: icon
- text: {
- if (root.blockedInhibitions.length === 1) {
- return i18nc("Application name; reason", "%1 has been prevented from blocking sleep and screen locking for %2", name, reason)
- } else {
- return i18nc("Application name: reason for preventing sleep and screen locking", "%1: %2", name, reason)
- }
- }
+ PlasmaExtras.MenuItem {
+ text: i18nc("@action:button Allow this app", "Allow only this time")
+ visible: !allowed && permanently
- Item {
- visible: permanently
- width: unblockMenuButton.width
- height: unblockMenuButton.height
-
- PlasmaComponents3.Button {
- id: unblockMenuButton
- text: i18nc("@action:button Undo preventing an app from blocking automatic sleep and screen locking after inactivity", "Block Again")
- icon.name: "dialog-cancel"
- Accessible.role: Accessible.ButtonMenu
- onClicked: unblockButtonMenu.open()
- }
+ onClicked: pmControl.unblockInhibition(app, reason, false)
+ }
- PlasmaExtras.Menu {
- id: unblockButtonMenu
+ PlasmaExtras.MenuItem {
+ text: {
+ if (permanently) {
+ return i18nc("@action:button Allow this app", "Allow every time for this app and reason");
+ }
+ return i18nc("@action:button Allow this app", "Allow again");
+ }
+ visible: !allowed
- PlasmaExtras.MenuItem {
- text: i18nc("@action:button Prevent an app from blocking automatic sleep and screen locking after inactivity", "Only this time")
- onClicked: pmControl.unblockInhibition(app, reason, false)
+ onClicked: pmControl.unblockInhibition(app, reason, true)
+ }
}
- PlasmaExtras.MenuItem {
- text: i18nc("@action:button Prevent an app from blocking automatic sleep and screen locking after inactivity", "Every time for this app and reason")
- onClicked: pmControl.unblockInhibition(app, reason, true)
+ PlasmaComponents3.ToolTip {
+ text: i18nc("@action:button", "Actions")
}
- }
- }
-
- Item {
- visible: !permanently
- width: unblockButton.width
- height: unblockButton.height
- PlasmaComponents3.Button {
- id: unblockButton
- text: i18nc("@action:button Undo preventing an app from blocking automatic sleep and screen locking after inactivity", "Block Again")
- icon.name: "dialog-cancel"
- onClicked: pmControl.unblockInhibition(app, reason, false)
- }
- }
- }
- }
-
- // UI to manually inhibit sleep and screen locking
- InhibitionHint {
- visible: !root.isManuallyInhibited
-
- PlasmaComponents3.Button {
- id: manualInhibitionButton
- Layout.alignment: Qt.AlignRight
- text: i18nc("@action:button Block sleep and screen locking after inactivity", "Manually Block")
- icon.name: "dialog-cancel"
-
- Keys.onPressed: (event) => {
- if (event.key == Qt.Key_Space || event.key == Qt.Key_Return || event.key == Qt.Key_Enter) {
- click();
- }
- }
-
- onClicked: {
- inhibitionChangeRequested(!root.isManuallyInhibited);
- }
-
- Connections {
- target: root
- function onIsManuallyInhibitedErrorChanged() {
- if (root.isManuallyInhibitedError) {
- root.isManuallyInhibitedError = false;
- if (!root.isManuallyInhibited) {
- inhibitionError.text = i18n("Failed to unblock automatic sleep and screen locking");
- inhibitionError.sendEvent();
- } else {
- inhibitionError.text = i18n("Failed to block automatic sleep and screen locking");
- inhibitionError.sendEvent();
- }
- }
+ onClicked: menu.openRelative()
}
}
}
diff --git a/applets/batterymonitor/package/contents/ui/main.qml b/applets/batterymonitor/package/contents/ui/main.qml
index c7bfdc5c4ead3316f9e1021ab504487d6d651f54..385b26ec22936ffe028036b56778527e65068ae0 100644
--- a/applets/batterymonitor/package/contents/ui/main.qml
+++ b/applets/batterymonitor/package/contents/ui/main.qml
@@ -14,6 +14,7 @@ import QtQuick.Layouts
import org.kde.coreaddons as KCoreAddons
import org.kde.kcmutils as KCMUtils
import org.kde.config as KConfig
+import org.kde.notification
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.plasmoid
import org.kde.kirigami as Kirigami
@@ -45,6 +46,25 @@ PlasmoidItem {
PowerManagementControl {
id: powerManagementControl
+
+ onIsManuallyInhibitedErrorChanged: {
+ if (isManuallyInhibitedError) {
+ if (!isManuallyInhibited) {
+ inhibitionError.text = i18n("Failed to unblock automatic sleep and screen locking");
+ } else {
+ inhibitionError.text = i18n("Failed to block automatic sleep and screen locking");
+ }
+ inhibitionError.sendEvent();
+ }
+ }
+ }
+
+ Notification {
+ id: inhibitionError
+ componentName: "plasma_workspace"
+ eventId: "warning"
+ iconName: "system-suspend-uninhibited"
+ title: i18n("Power Management")
}
readonly property bool kcmAuthorized: KConfig.KAuthorized.authorizeControlModule("powerdevilprofilesconfig")
@@ -99,11 +119,19 @@ PlasmoidItem {
LayoutMirroring.childrenInherit: true
Plasmoid.status: {
- if (powerManagementControl.isManuallyInhibited || !powerProfilesControl.isInDefaultPowerProfile) {
+ if (powerProfilesControl.isPowerProfileDaemonInstalled && !powerProfilesControl.isInDefaultPowerProfile) {
return PlasmaCore.Types.ActiveStatus;
}
- if (batteryControl.hasCumulative && (batteryControl.state === BatteryControlModel.Discharging || batteryControl.state === BatteryControlModel.Charging)) {
+ if (powerManagementControl.isLidPresent && !powerManagementControl.triggersLidAction) {
+ return PlasmaCore.Types.ActiveStatus;
+ }
+
+ if (powerManagementControl.isManuallyInhibited || powerManagementControl.inhibitions.length > 0) {
+ return PlasmaCore.Types.ActiveStatus;
+ }
+
+ if (batteryControl.hasCumulative && ![BatteryControlModel.NoCharge, BatteryControlModel.FullyCharged].includes(batteryControl.state)) {
return PlasmaCore.Types.ActiveStatus;
}
@@ -117,11 +145,13 @@ PlasmoidItem {
if (!batteryControl.hasInternalBatteries) {
return Plasmoid.title
- } else if (batteryControl.isSomehowFullyCharged) {
- return i18n("Fully Charged");
}
const percent = batteryControl.percent;
+ if (batteryControl.isSomehowFullyCharged) {
+ return i18n("Battery at %1%, Fully Charged", batteryControl.percent);
+ }
+
if (batteryControl.pluggedIn) {
const state = batteryControl.state;
if (state === BatteryControlModel.NoCharge) {
@@ -206,7 +236,7 @@ PlasmoidItem {
compactRepresentation: CompactRepresentation {
batteryPercent: batteryControl.percent
- batteryPluggedIn: batteryControl.pluggedIn
+ batteryPluggedIn: batteryControl.state === BatteryControlModel.Charging
hasBatteries: batteryControl.hasBatteries
hasInternalBatteries: batteryControl.hasInternalBatteries
hasCumulative: batteryControl.hasCumulative
@@ -214,7 +244,17 @@ PlasmoidItem {
isSomehowFullyCharged: batteryControl.isSomehowFullyCharged
isDischarging: !batteryControl.pluggedIn
- isManuallyInhibited: powerManagementControl.isManuallyInhibited
+ isInhibited: {
+ if (powerManagementControl.inhibitions.length > 0) {
+ return true;
+ }
+
+ if (powerManagementControl.isLidPresent && !powerManagementControl.triggersLidAction) {
+ return true;
+ }
+
+ return powerManagementControl.isManuallyInhibited;
+ }
isInDefaultPowerProfile: powerProfilesControl.isInDefaultPowerProfile
isInPowersaveProfile: powerProfilesControl.isInPowersaveProfile
isInBalancedProfile: powerProfilesControl.isInBalancedProfile
@@ -271,7 +311,6 @@ PlasmoidItem {
model: batteryControl
isManuallyInhibited: powerManagementControl.isManuallyInhibited
- isManuallyInhibitedError: powerManagementControl.isManuallyInhibitedError
pluggedIn: batteryControl.pluggedIn
chargeStopThreshold: batteryControl.chargeStopThreshold
remainingTime: batteryControl.remainingTime
@@ -290,13 +329,22 @@ PlasmoidItem {
onActivateProfileRequested: profile => {
batterymonitor.activateProfileRequested(profile);
}
-
- onInhibitionChangeRequested: inhibit => {
- batterymonitor.inhibitionChangeRequested(inhibit);
- }
}
Plasmoid.contextualActions: [
+ PlasmaCore.Action {
+ text: i18n("Manually block sleep and screen locking after inactivity")
+ icon.name: "system-suspend-inhibited"
+ priority: PlasmaCore.Action.HighPriority
+ checkable: true
+ checked: powerManagementControl.isManuallyInhibited
+ onTriggered: checked => {
+ batterymonitor.inhibitionChangeRequested(checked);
+ }
+ },
+ PlasmaCore.Action {
+ isSeparator: true
+ },
PlasmaCore.Action {
text: i18n("&Show Energy Information…")
icon.name: "documentinfo"