From 879d9ec879f8091658581985b10c9aeda5b3e939 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Mon, 22 Sep 2025 14:09:23 +0200 Subject: [PATCH] Notification: add location option Autoformat --- Commons/Settings.qml | 3 +- Modules/Notification/Notification.qml | 71 ++++++++++++------- .../SettingsPanel/Tabs/NotificationsTab.qml | 33 +++++++++ 3 files changed, 78 insertions(+), 29 deletions(-) diff --git a/Commons/Settings.qml b/Commons/Settings.qml index f4c463bb..8dd0ff05 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -245,9 +245,8 @@ Singleton { property JsonObject notifications: JsonObject { property bool doNotDisturb: false property list monitors: [] - // Last time the user opened the notification history (ms since e899999999999998poch) + property string location: "top_right" property real lastSeenTs: 0 - // Duration settings for different urgency levels (in seconds) property int lowUrgencyDuration: 3 property int normalUrgencyDuration: 8 property int criticalUrgencyDuration: 15 diff --git a/Modules/Notification/Notification.qml b/Modules/Notification/Notification.qml index 76874196..48bfe37a 100644 --- a/Modules/Notification/Notification.qml +++ b/Modules/Notification/Notification.qml @@ -39,48 +39,62 @@ Variants { screen: modelData color: Color.transparent - // Position based on bar location - always at top - anchors.top: true - anchors.right: Settings.data.bar.position === "right" || Settings.data.bar.position === "top" || Settings.data.bar.position === "bottom" - anchors.left: Settings.data.bar.position === "left" + readonly property string location: (Settings.isLoaded && Settings.data && Settings.data.notifications && Settings.data.notifications.location) ? Settings.data.notifications.location : "top_right" + readonly property bool isTop: (location === "top") || (location.length >= 3 && location.substring(0, 3) === "top") + readonly property bool isBottom: (location === "bottom") || (location.length >= 6 && location.substring(0, 6) === "bottom") + readonly property bool isLeft: location.indexOf("_left") >= 0 + readonly property bool isRight: location.indexOf("_right") >= 0 + readonly property bool isCentered: (location === "top" || location === "bottom") + // Anchor selection based on location (window edges) + anchors.top: isTop + anchors.bottom: isBottom + anchors.left: isLeft + anchors.right: isRight + + // Margins depending on bar position and chosen location margins.top: { - switch (Settings.data.bar.position) { - case "top": - return (Style.barHeight + Style.marginM) * scaling + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0) - default: - return Style.marginM * scaling + if (!(anchors.top)) + return 0 + var base = Style.marginM * scaling + if (Settings.data.bar.position === "top") { + var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0 + return (Style.barHeight * scaling) + base + floatExtraV } + return base } margins.bottom: { - switch (Settings.data.bar.position) { - case "bottom": - return (Style.barHeight + Style.marginM) * scaling + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0) - default: + if (!(anchors.bottom)) return 0 + var base = Style.marginM * scaling + if (Settings.data.bar.position === "bottom") { + var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0 + return (Style.barHeight * scaling) + base + floatExtraV } + return base } margins.left: { - switch (Settings.data.bar.position) { - case "left": - return (Style.barHeight + Style.marginM) * scaling + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0) - default: + if (!(anchors.left)) return 0 + var base = Style.marginM * scaling + if (Settings.data.bar.position === "left") { + var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0 + return (Style.barHeight * scaling) + base + floatExtraH } + return base } margins.right: { - switch (Settings.data.bar.position) { - case "right": - return (Style.barHeight + Style.marginM) * scaling + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0) - case "top": - case "bottom": - return Style.marginM * scaling - default: + if (!(anchors.right)) return 0 + var base = Style.marginM * scaling + if (Settings.data.bar.position === "right") { + var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0 + return (Style.barHeight * scaling) + base + floatExtraH } + return base } implicitWidth: 360 * scaling @@ -119,9 +133,12 @@ Variants { // Main notification container ColumnLayout { id: notificationStack - anchors.top: parent.top - anchors.right: (Settings.data.bar.position === "right" || Settings.data.bar.position === "top" || Settings.data.bar.position === "bottom") ? parent.right : undefined - anchors.left: Settings.data.bar.position === "left" ? parent.left : undefined + // Anchor the stack inside the window based on chosen location + anchors.top: parent.isTop ? parent.top : undefined + anchors.bottom: parent.isBottom ? parent.bottom : undefined + anchors.left: parent.isLeft ? parent.left : undefined + anchors.right: parent.isRight ? parent.right : undefined + anchors.horizontalCenter: parent.isCentered ? parent.horizontalCenter : undefined spacing: Style.marginS * scaling width: 360 * scaling visible: true diff --git a/Modules/SettingsPanel/Tabs/NotificationsTab.qml b/Modules/SettingsPanel/Tabs/NotificationsTab.qml index 68a56a61..64093d49 100644 --- a/Modules/SettingsPanel/Tabs/NotificationsTab.qml +++ b/Modules/SettingsPanel/Tabs/NotificationsTab.qml @@ -38,6 +38,39 @@ ColumnLayout { checked: Settings.data.notifications.doNotDisturb onToggled: checked => Settings.data.notifications.doNotDisturb = checked } + + NComboBox { + label: "Location" + description: "Where notifications appear on screen." + model: ListModel { + ListElement { + key: "top" + name: "Top" + } + ListElement { + key: "top_left" + name: "Top left" + } + ListElement { + key: "top_right" + name: "Top right" + } + ListElement { + key: "bottom" + name: "Bottom" + } + ListElement { + key: "bottom_left" + name: "Bottom left" + } + ListElement { + key: "bottom_right" + name: "Bottom right" + } + } + currentKey: Settings.data.notifications.location || "top_right" + onSelected: key => Settings.data.notifications.location = key + } } NDivider {