Fix notification and other small fixes

This commit is contained in:
Ly-sec 2025-08-05 20:15:11 +02:00
parent fb68300746
commit 69d84752f3
10 changed files with 366 additions and 338 deletions

View file

@ -6,7 +6,7 @@ IpcHandler {
property var appLauncherPanel property var appLauncherPanel
property var lockScreen property var lockScreen
property IdleInhibitor idleInhibitor property IdleInhibitor idleInhibitor
property var notificationPopupVariants property var notificationPopup
target: "globalIPC" target: "globalIPC"
@ -17,18 +17,11 @@ IpcHandler {
function toggleNotificationPopup(): void { function toggleNotificationPopup(): void {
console.log("[IPC] NotificationPopup toggle() called") console.log("[IPC] NotificationPopup toggle() called")
// Use the global toggle function from the notification manager
if (notificationPopupVariants) { notificationPopup.togglePopup();
for (let i = 0; i < notificationPopupVariants.count; i++) {
let popup = notificationPopupVariants.objectAt(i);
if (popup) {
popup.togglePopup();
}
}
}
} }
// Toggle Applauncher visibility
function toggleLauncher(): void { function toggleLauncher(): void {
if (!appLauncherPanel) { if (!appLauncherPanel) {
console.warn("AppLauncherIpcHandler: appLauncherPanel not set!"); console.warn("AppLauncherIpcHandler: appLauncherPanel not set!");
@ -42,7 +35,7 @@ IpcHandler {
} }
} }
// Toggle LockScreen
function toggleLock(): void { function toggleLock(): void {
if (!lockScreen) { if (!lockScreen) {
console.warn("LockScreenIpcHandler: lockScreen not set!"); console.warn("LockScreenIpcHandler: lockScreen not set!");

View file

@ -81,7 +81,7 @@ Singleton {
// Monitor/Display Settings // Monitor/Display Settings
property var barMonitors: [] // Array of monitor names to show the bar on property var barMonitors: [] // Array of monitor names to show the bar on
property var dockMonitors: [] // Array of monitor names to show the dock on property var dockMonitors: [] // Array of monitor names to show the dock on
property var notificationMonitors: [] // Array of monitor names to show notifications on property var notificationMonitors: [] // Array of monitor names to show notifications on, "*" means all monitors
} }
} }
@ -90,5 +90,7 @@ Singleton {
function onRandomWallpaperChanged() { WallpaperManager.toggleRandomWallpaper() } function onRandomWallpaperChanged() { WallpaperManager.toggleRandomWallpaper() }
function onWallpaperIntervalChanged() { WallpaperManager.restartRandomWallpaperTimer() } function onWallpaperIntervalChanged() { WallpaperManager.restartRandomWallpaperTimer() }
function onWallpaperFolderChanged() { WallpaperManager.loadWallpapers() } function onWallpaperFolderChanged() { WallpaperManager.loadWallpapers() }
function onNotificationMonitorsChanged() {
}
} }
} }

View file

@ -4,17 +4,63 @@ import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import qs.Settings import qs.Settings
PanelWindow { // Main container that manages multiple notification popups for different monitors
id: window Item {
id: notificationManager
anchors.fill: parent
// Get list of available monitors/screens
property var monitors: Quickshell.screens || []
// Global visibility state for all notification popups
property bool notificationsVisible: true
function togglePopup(): void {
console.log("[NotificationManager] Current state: " + notificationsVisible);
notificationsVisible = !notificationsVisible;
console.log("[NotificationManager] New state: " + notificationsVisible);
}
// Create a notification popup for each monitor
Repeater {
model: notificationManager.monitors
delegate: Item {
id: delegateItem
// Make addNotification accessible from the Item level
function addNotification(notification) {
if (panelWindow) {
panelWindow.addNotification(notification);
}
}
PanelWindow {
id: panelWindow
implicitWidth: 350 implicitWidth: 350
implicitHeight: notificationColumn.implicitHeight implicitHeight: Math.max(notificationColumn.height, 0)
color: "transparent" color: "transparent"
visible: notificationsVisible && notificationModel.count > 0 visible: notificationManager.notificationsVisible && notificationModel.count > 0 && shouldShowOnThisMonitor
screen: (typeof modelData !== 'undefined' ? modelData : Quickshell.primaryScreen) screen: modelData
focusable: false focusable: false
property bool barVisible: true property bool barVisible: true
property bool notificationsVisible: true property bool notificationsVisible: notificationManager.notificationsVisible
// Check if this monitor should show notifications - make it reactive to settings changes
property bool shouldShowOnThisMonitor: {
let notificationMonitors = Settings.settings.notificationMonitors || [];
let currentScreenName = modelData ? modelData.name : "";
return notificationMonitors.includes("*") ||
notificationMonitors.includes(currentScreenName);
}
// Watch for changes in notification monitors setting
Connections {
target: Settings.settings
function onNotificationMonitorsChanged() {
// Settings changed, visibility will update automatically
}
}
anchors.top: true anchors.top: true
anchors.right: true anchors.right: true
@ -28,12 +74,6 @@ PanelWindow {
property int maxVisible: 5 property int maxVisible: 5
property int spacing: 5 property int spacing: 5
function togglePopup(): void {
console.log("[NotificationPopup] Current state: " + notificationsVisible);
notificationsVisible = !notificationsVisible;
console.log("[NotificationPopup] New state: " + notificationsVisible);
}
function addNotification(notification) { function addNotification(notification) {
notificationModel.insert(0, { notificationModel.insert(0, {
id: notification.id, id: notification.id,
@ -308,8 +348,11 @@ PanelWindow {
Connections { Connections {
target: Quickshell target: Quickshell
function onScreensChanged() { function onScreensChanged() {
if (window.screen) { if (panelWindow.screen) {
x = window.screen.width - width - 20; x = panelWindow.screen.width - panelWindow.width - 20;
}
}
}
} }
} }
} }

View file

@ -255,7 +255,7 @@ Item {
font.pixelSize: 14 font.pixelSize: 14
color: Theme.textSecondary color: Theme.textSecondary
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
Layout.topMargin: 16 Layout.topMargin: 24
} }

View file

@ -14,6 +14,17 @@ ColumnLayout {
// Get list of available monitors/screens // Get list of available monitors/screens
property var monitors: Quickshell.screens || [] property var monitors: Quickshell.screens || []
// Sorted monitors by name
property var sortedMonitors: {
let sorted = [...monitors];
sorted.sort((a, b) => {
let nameA = a.name || "Unknown";
let nameB = b.name || "Unknown";
return nameA.localeCompare(nameB);
});
return sorted;
}
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 0 Layout.preferredHeight: 0
@ -68,7 +79,7 @@ ColumnLayout {
spacing: 8 spacing: 8
Repeater { Repeater {
model: root.monitors model: root.sortedMonitors
delegate: Rectangle { delegate: Rectangle {
id: barCheckbox id: barCheckbox
property bool isChecked: false property bool isChecked: false
@ -171,7 +182,7 @@ ColumnLayout {
spacing: 8 spacing: 8
Repeater { Repeater {
model: root.monitors model: root.sortedMonitors
delegate: Rectangle { delegate: Rectangle {
id: dockCheckbox id: dockCheckbox
property bool isChecked: false property bool isChecked: false
@ -277,7 +288,7 @@ ColumnLayout {
spacing: 8 spacing: 8
Repeater { Repeater {
model: root.monitors model: root.sortedMonitors
delegate: Rectangle { delegate: Rectangle {
id: notificationCheckbox id: notificationCheckbox
property bool isChecked: false property bool isChecked: false

View file

@ -107,15 +107,11 @@ ColumnLayout {
} }
} }
Item {
Layout.fillWidth: true
Layout.preferredHeight: 16
}
ColumnLayout { ColumnLayout {
spacing: 4 spacing: 4
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 58
Text { Text {
text: "User Interface" text: "User Interface"

View file

@ -101,7 +101,7 @@ ColumnLayout {
ColumnLayout { ColumnLayout {
spacing: 16 spacing: 16
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 58
Text { Text {
text: "Bluetooth" text: "Bluetooth"

View file

@ -172,7 +172,7 @@ ColumnLayout {
ColumnLayout { ColumnLayout {
spacing: 4 spacing: 4
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 58
Text { Text {
text: "Weather" text: "Weather"

View file

@ -22,17 +22,18 @@ Scope {
property var notificationHistoryWin: notificationHistoryWin property var notificationHistoryWin: notificationHistoryWin
property bool pendingReload: false property bool pendingReload: false
// Round volume to nearest 5% increment for consistent control // Helper function to round value to nearest step
function roundToStep(value, step) { function roundToStep(value, step) {
return Math.round(value / step) * step; return Math.round(value / step) * step;
} }
// Current audio volume (0-100), synced with system // Volume property reflecting current audio volume in 0-100
// Will be kept in sync dynamically below
property int volume: (defaultAudioSink && defaultAudioSink.audio && !defaultAudioSink.audio.muted) property int volume: (defaultAudioSink && defaultAudioSink.audio && !defaultAudioSink.audio.muted)
? Math.round(defaultAudioSink.audio.volume * 100) ? Math.round(defaultAudioSink.audio.volume * 100)
: 0 : 0
// Update volume with 5-step increments and apply to audio sink // Function to update volume with clamping, stepping, and applying to audio sink
function updateVolume(vol) { function updateVolume(vol) {
var clamped = Math.max(0, Math.min(100, vol)); var clamped = Math.max(0, Math.min(100, vol));
var stepped = roundToStep(clamped, 5); var stepped = roundToStep(clamped, 5);
@ -52,13 +53,8 @@ Scope {
property var notificationHistoryWin: notificationHistoryWin property var notificationHistoryWin: notificationHistoryWin
} }
// Create dock for each monitor (respects dockMonitors setting)
Variants {
model: Quickshell.screens
Dock { Dock {
property var modelData id: dock
}
} }
Applauncher { Applauncher {
@ -83,17 +79,16 @@ Scope {
NotificationServer { NotificationServer {
id: notificationServer id: notificationServer
onNotification: function (notification) { onNotification: function (notification) {
console.log("Notification received:", notification.appName);
notification.tracked = true; notification.tracked = true;
if (notificationPopup.notificationsVisible) {
// Distribute notification to all visible notification popups // Add notification to all popup instances
for (let i = 0; i < notificationPopupVariants.count; i++) { for (let i = 0; i < notificationPopup.children.length; i++) {
let popup = notificationPopupVariants.objectAt(i); let child = notificationPopup.children[i];
if (popup && popup.notificationsVisible) { if (child.addNotification) {
popup.addNotification(notification); child.addNotification(notification);
}
} }
} }
if (notificationHistoryWin) { if (notificationHistoryWin) {
notificationHistoryWin.addToHistory({ notificationHistoryWin.addToHistory({
id: notification.id, id: notification.id,
@ -107,19 +102,8 @@ Scope {
} }
} }
// Create notification popups for each selected monitor
Variants {
id: notificationPopupVariants
model: Quickshell.screens
NotificationPopup { NotificationPopup {
property var modelData id: notificationPopup
barVisible: bar.visible
screen: modelData
visible: notificationsVisible && notificationModel.count > 0 &&
(Settings.settings.notificationMonitors.includes(modelData.name) ||
(Settings.settings.notificationMonitors.length === 0)) // Show on all if none selected
}
} }
NotificationHistory { NotificationHistory {
@ -137,7 +121,7 @@ Scope {
appLauncherPanel: appLauncherPanel appLauncherPanel: appLauncherPanel
lockScreen: lockScreen lockScreen: lockScreen
idleInhibitor: idleInhibitor idleInhibitor: idleInhibitor
notificationPopupVariants: notificationPopupVariants notificationPopup: notificationPopup
} }
Connections { Connections {
@ -154,12 +138,11 @@ Scope {
Timer { Timer {
id: reloadTimer id: reloadTimer
interval: 500 interval: 500 // ms
repeat: false repeat: false
onTriggered: Quickshell.reload(true) onTriggered: Quickshell.reload(true)
} }
// Handle screen configuration changes (delay reload if locked)
Connections { Connections {
target: Quickshell target: Quickshell
function onScreensChanged() { function onScreensChanged() {