From eb4db2b91052f4301ca78f02c1f284b1454771e9 Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sat, 26 Jul 2025 16:50:29 +0700 Subject: [PATCH 01/12] feat: add environment variable support for settings and theme file paths --- Settings/Settings.qml | 3 ++- Settings/Theme.qml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Settings/Settings.qml b/Settings/Settings.qml index 95fe8b3..81701dc 100644 --- a/Settings/Settings.qml +++ b/Settings/Settings.qml @@ -8,7 +8,8 @@ Singleton { property string shellName: "Noctalia" property string settingsDir: (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env("HOME") + "/.config") + "/" + shellName + "/" - property string settingsFile: settingsDir + "Settings.json" + property string settingsFile: Quickshell.env("NOCTALIA_SETTINGS_FILE") || (settingsDir + "Settings.json") + property string themeFile: Quickshell.env("NOCTALIA_THEME_FILE") || (settingsDir + "Theme.json") property var settings: settingAdapter Item { diff --git a/Settings/Theme.qml b/Settings/Theme.qml index f825cef..cb8b5c1 100644 --- a/Settings/Theme.qml +++ b/Settings/Theme.qml @@ -15,7 +15,7 @@ Singleton { // FileView to load theme data from JSON file FileView { id: themeFile - path: Settings.settingsDir + "Theme.json" + path: Settings.themeFile watchChanges: true onFileChanged: reload() onAdapterUpdated: writeAdapter() From f1c2f9bea82334181083230346ab5dd8bf2de79f Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sat, 26 Jul 2025 18:22:06 +0700 Subject: [PATCH 02/12] feat: add font size scaling with configurable multiplier in settings --- Settings/Settings.qml | 3 ++- Settings/Theme.qml | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Settings/Settings.qml b/Settings/Settings.qml index 81701dc..9626986 100644 --- a/Settings/Settings.qml +++ b/Settings/Settings.qml @@ -7,7 +7,7 @@ import qs.Services Singleton { property string shellName: "Noctalia" - property string settingsDir: (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env("HOME") + "/.config") + "/" + shellName + "/" + property string settingsDir: Quickshell.env("NOCTALIA_SETTINGS_DIR") || (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env("HOME") + "/.config") + "/" + shellName + "/" property string settingsFile: Quickshell.env("NOCTALIA_SETTINGS_FILE") || (settingsDir + "Settings.json") property string themeFile: Quickshell.env("NOCTALIA_THEME_FILE") || (settingsDir + "Theme.json") property var settings: settingAdapter @@ -58,6 +58,7 @@ Singleton { property bool reverseDayMonth: false property bool use12HourClock: false property bool dimPanels: true + property real fontSizeMultiplier: 1.0 // Font size multiplier (1.0 = normal, 1.2 = 20% larger, 0.8 = 20% smaller) property var pinnedExecs: [] // Added for AppLauncher pinned apps } } diff --git a/Settings/Theme.qml b/Settings/Theme.qml index cb8b5c1..97e8d29 100644 --- a/Settings/Theme.qml +++ b/Settings/Theme.qml @@ -102,10 +102,14 @@ Singleton { // Font Properties property string fontFamily: "Roboto" // Family for all text - - property int fontSizeHeader: 32 // Headers and titles - property int fontSizeBody: 16 // Body text and general content - property int fontSizeSmall: 14 // Small text like clock, labels - property int fontSizeCaption: 12 // Captions and fine print + + // Font size multiplier - adjust this in Settings.json to scale all fonts + property real fontSizeMultiplier: Settings.settings.fontSizeMultiplier || 1.0 + + // Base font sizes (multiplied by fontSizeMultiplier) + property int fontSizeHeader: Math.round(32 * fontSizeMultiplier) // Headers and titles + property int fontSizeBody: Math.round(16 * fontSizeMultiplier) // Body text and general content + property int fontSizeSmall: Math.round(14 * fontSizeMultiplier) // Small text like clock, labels + property int fontSizeCaption: Math.round(12 * fontSizeMultiplier) // Captions and fine print } From 18bc65dff104c113e16054f9375deff5d4fd6bdd Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sat, 26 Jul 2025 21:52:08 +0700 Subject: [PATCH 03/12] feat: add taskbar module with configurable icon size and window management --- Bar/Bar.qml | 4 + Bar/Modules/Taskbar.qml | 186 ++++++++++++++++++++++++++++++++++++++++ Settings/Settings.qml | 1 + 3 files changed, 191 insertions(+) create mode 100644 Bar/Modules/Taskbar.qml diff --git a/Bar/Bar.qml b/Bar/Bar.qml index 83c3ae7..037d76c 100644 --- a/Bar/Bar.qml +++ b/Bar/Bar.qml @@ -63,6 +63,10 @@ Scope { Media { anchors.verticalCenter: parent.verticalCenter } + + Taskbar { + anchors.verticalCenter: parent.verticalCenter + } } ActiveWindow { diff --git a/Bar/Modules/Taskbar.qml b/Bar/Modules/Taskbar.qml new file mode 100644 index 0000000..afdb653 --- /dev/null +++ b/Bar/Modules/Taskbar.qml @@ -0,0 +1,186 @@ +import QtQuick +import QtQuick.Controls +import Quickshell +import Quickshell.Wayland +import Quickshell.Widgets +import qs.Settings +import qs.Components + +Item { + id: taskbar + width: runningAppsRow.width + height: Settings.settings.taskbarIconSize + + function getAppIcon(toplevel) { + if (!toplevel) + return ""; + + // Try different icon resolution strategies + var icon = Quickshell.iconPath(toplevel.appId?.toLowerCase(), true); + if (!icon) { + icon = Quickshell.iconPath(toplevel.appId, true); + } + if (!icon) { + icon = Quickshell.iconPath(toplevel.title?.toLowerCase(), true); + } + if (!icon) { + icon = Quickshell.iconPath(toplevel.title, true); + } + if (!icon) { + icon = Quickshell.iconPath("application-x-executable", true); + } + console.log(icon) + + return icon || ""; + } + + Row { + id: runningAppsRow + spacing: 8 + height: parent.height + + Repeater { + model: ToplevelManager ? ToplevelManager.toplevels : null + + delegate: Rectangle { + + id: appButton + width: Settings.settings.taskbarIconSize + height: Settings.settings.taskbarIconSize + radius: Math.max(4, Settings.settings.taskbarIconSize * 0.25) + color: isActive ? Theme.accentPrimary : (hovered ? Theme.surfaceVariant : "transparent") + border.color: isActive ? Qt.darker(Theme.accentPrimary, 1.2) : "transparent" + border.width: 1 + + + + property bool isActive: ToplevelManager.activeToplevel && ToplevelManager.activeToplevel === modelData + property bool hovered: mouseArea.containsMouse + property string appId: modelData ? modelData.appId : "" + property string appTitle: modelData ? modelData.title : "" + + Behavior on color { + ColorAnimation { + duration: 150 + } + } + + Behavior on border.color { + ColorAnimation { + duration: 150 + } + } + + // App icon + IconImage { + id: appIcon + width: Math.max(12, Settings.settings.taskbarIconSize * 0.625) // 62.5% of button size (20/32 = 0.625) + height: Math.max(12, Settings.settings.taskbarIconSize * 0.625) + anchors.centerIn: parent + source: getAppIcon(modelData) + smooth: true + + // Fallback to first letter if no icon + visible: source.toString() !== "" + } + + // Fallback text if no icon available + Text { + anchors.centerIn: parent + visible: !appIcon.visible + text: appButton.appId ? appButton.appId.charAt(0).toUpperCase() : "?" + font.family: Theme.fontFamily + font.pixelSize: Math.max(10, Settings.settings.taskbarIconSize * 0.4375) // 43.75% of button size (14/32 = 0.4375) + font.bold: true + color: appButton.isActive ? Theme.onAccent : Theme.textPrimary + } + + // Tooltip + ToolTip { + id: tooltip + visible: mouseArea.containsMouse && !mouseArea.pressed + delay: 800 + text: appTitle || appId + + background: Rectangle { + color: Theme.backgroundPrimary + border.color: Theme.outline + border.width: 1 + radius: 8 + } + + contentItem: Text { + text: tooltip.text + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSizeCaption + color: Theme.textPrimary + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + + onClicked: function(mouse) { + console.log("[Taskbar] Clicked on", appButton.appId, "- Active:", appButton.isActive); + + if (mouse.button === Qt.MiddleButton) { + console.log("[Taskbar] Middle-clicked on", appButton.appId); + + // Example: Close the window with middle click + if (modelData && modelData.close) { + modelData.close(); + } else { + console.log("[Taskbar] No close method available for:", modelData); + } + } + + if (mouse.button === Qt.LeftButton) { + // Left click: Focus/activate the window + if (modelData && modelData.activate) { + modelData.activate(); + } else { + console.log("[Taskbar] No activate method available for:", modelData); + } + } + } + + // Right-click for additional actions + onPressed: mouse => { + if (mouse.button === Qt.RightButton) { + console.log("[Taskbar] Right-clicked on", appButton.appId); + + // Example actions you can add: + // 1. Close window + // if (modelData && modelData.close) { + // modelData.close(); + // } + + // 2. Minimize window + // if (modelData && modelData.minimize) { + // modelData.minimize(); + // } + + // 3. Show context menu (needs Menu component) + // contextMenu.popup(); + } + } + } + + // Active indicator dot + Rectangle { + visible: isActive + width: 4 + height: 4 + radius: 2 + color: Theme.onAccent + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: -6 + } + } + } + } +} diff --git a/Settings/Settings.qml b/Settings/Settings.qml index 9626986..17941bc 100644 --- a/Settings/Settings.qml +++ b/Settings/Settings.qml @@ -59,6 +59,7 @@ Singleton { property bool use12HourClock: false property bool dimPanels: true property real fontSizeMultiplier: 1.0 // Font size multiplier (1.0 = normal, 1.2 = 20% larger, 0.8 = 20% smaller) + property int taskbarIconSize: 24 // Taskbar icon button size in pixels (default: 32, smaller: 24, larger: 40) property var pinnedExecs: [] // Added for AppLauncher pinned apps } } From 899a592c27a11a711c86ce45392501821b188948 Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sat, 26 Jul 2025 21:52:28 +0700 Subject: [PATCH 04/12] feat: add IPC handler for toggling window fullscreen state --- Helpers/IPCHandlers.qml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Helpers/IPCHandlers.qml b/Helpers/IPCHandlers.qml index 9e72395..4752b1d 100644 --- a/Helpers/IPCHandlers.qml +++ b/Helpers/IPCHandlers.qml @@ -1,4 +1,5 @@ import Quickshell.Io +import Quickshell.Wayland IpcHandler { property var appLauncherPanel @@ -6,6 +7,22 @@ IpcHandler { target: "globalIPC" + // Toggle Fullscreen + function toggleFullscreen(): void { + console.log("[IPC] toggleFullscreen() called") + if (ToplevelManager.activeToplevel) { + if (ToplevelManager.activeToplevel.fullscreen) { + // Exit fullscreen + ToplevelManager.activeToplevel.fullscreen = false; + } else { + // Enter fullscreen + ToplevelManager.activeToplevel.fullscreen = true; + } + } else { + console.warn("[IPC] No active toplevel window to toggle fullscreen"); + } + } + // Toggle Applauncher visibility function toggleLauncher(): void { if (!appLauncherPanel) { From ef2bacc4c40dcf8b2afe3b737e1f7c28aca477e0 Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sat, 26 Jul 2025 22:15:03 +0700 Subject: [PATCH 05/12] fix: update battery tooltip to reference correct widget properties --- Bar/Modules/Battery.qml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Bar/Modules/Battery.qml b/Bar/Modules/Battery.qml index fe66910..6ca0848 100644 --- a/Bar/Modules/Battery.qml +++ b/Bar/Modules/Battery.qml @@ -61,17 +61,17 @@ Item { id: batteryTooltip text: { let lines = []; - if (isReady) { - lines.push(charging ? "Charging" : "Discharging"); - lines.push(Math.round(percent) + "%"); - if (battery.changeRate !== undefined) - lines.push("Rate: " + battery.changeRate.toFixed(2) + " W"); - if (battery.timeToEmpty > 0) - lines.push("Time left: " + Math.floor(battery.timeToEmpty / 60) + " min"); - if (battery.timeToFull > 0) - lines.push("Time to full: " + Math.floor(battery.timeToFull / 60) + " min"); - if (battery.healthPercentage !== undefined) - lines.push("Health: " + Math.round(battery.healthPercentage) + "%"); + if (batteryWidget.isReady) { + lines.push(batteryWidget.charging ? "Charging" : "Discharging"); + lines.push(Math.round(batteryWidget.percent) + "%"); + if (batteryWidget.battery.changeRate !== undefined) + lines.push("Rate: " + batteryWidget.battery.changeRate.toFixed(2) + " W"); + if (batteryWidget.battery.timeToEmpty > 0) + lines.push("Time left: " + Math.floor(batteryWidget.battery.timeToEmpty / 60) + " min"); + if (batteryWidget.battery.timeToFull > 0) + lines.push("Time to full: " + Math.floor(batteryWidget.battery.timeToFull / 60) + " min"); + if (batteryWidget.battery.healthPercentage !== undefined) + lines.push("Health: " + Math.round(batteryWidget.battery.healthPercentage) + "%"); } return lines.join("\n"); } From f3652e7c82b6870ae5fd49b0d4d2c25e87edb71c Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sat, 26 Jul 2025 22:53:42 +0700 Subject: [PATCH 06/12] feat: add TypeScript types to getAppIcon and document fullscreen toggle command --- Bar/Modules/Taskbar.qml | 5 ++--- README.md | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Bar/Modules/Taskbar.qml b/Bar/Modules/Taskbar.qml index afdb653..ec87073 100644 --- a/Bar/Modules/Taskbar.qml +++ b/Bar/Modules/Taskbar.qml @@ -11,12 +11,12 @@ Item { width: runningAppsRow.width height: Settings.settings.taskbarIconSize - function getAppIcon(toplevel) { + function getAppIcon(toplevel: Toplevel): string { if (!toplevel) return ""; // Try different icon resolution strategies - var icon = Quickshell.iconPath(toplevel.appId?.toLowerCase(), true); + let icon = Quickshell.iconPath(toplevel.appId?.toLowerCase(), true); if (!icon) { icon = Quickshell.iconPath(toplevel.appId, true); } @@ -29,7 +29,6 @@ Item { if (!icon) { icon = Quickshell.iconPath("application-x-executable", true); } - console.log(icon) return icon || ""; } diff --git a/README.md b/README.md index d9adbf3..1c2aed4 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,12 @@ qs ipc call globalIPC toggleLock You can keybind it however you want in your niri setup. + +### Toggle Fullscreen: + +``` +qs ipc call globalIPC toggleFullscreen +``` --- From ef1274d42b8a70083605c7381535ab8e661a8b4f Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sun, 27 Jul 2025 17:47:59 +0700 Subject: [PATCH 07/12] del: remove fullscrren, move responsibilty to hyprland or niri --- Helpers/IPCHandlers.qml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/Helpers/IPCHandlers.qml b/Helpers/IPCHandlers.qml index 4752b1d..9e72395 100644 --- a/Helpers/IPCHandlers.qml +++ b/Helpers/IPCHandlers.qml @@ -1,5 +1,4 @@ import Quickshell.Io -import Quickshell.Wayland IpcHandler { property var appLauncherPanel @@ -7,22 +6,6 @@ IpcHandler { target: "globalIPC" - // Toggle Fullscreen - function toggleFullscreen(): void { - console.log("[IPC] toggleFullscreen() called") - if (ToplevelManager.activeToplevel) { - if (ToplevelManager.activeToplevel.fullscreen) { - // Exit fullscreen - ToplevelManager.activeToplevel.fullscreen = false; - } else { - // Enter fullscreen - ToplevelManager.activeToplevel.fullscreen = true; - } - } else { - console.warn("[IPC] No active toplevel window to toggle fullscreen"); - } - } - // Toggle Applauncher visibility function toggleLauncher(): void { if (!appLauncherPanel) { From c74a248e1dc3d727acdae4176bd1bbc8edafcf28 Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sun, 27 Jul 2025 18:11:48 +0700 Subject: [PATCH 08/12] feat: add idle inhibitor for ipc --- Helpers/IPCHandlers.qml | 7 +++++++ Helpers/IdleInhibitor.qml | 43 +++++++++++++++++++++++++++++++++++++++ shell.qml | 8 ++++++++ 3 files changed, 58 insertions(+) create mode 100644 Helpers/IdleInhibitor.qml diff --git a/Helpers/IPCHandlers.qml b/Helpers/IPCHandlers.qml index 9e72395..f0659cd 100644 --- a/Helpers/IPCHandlers.qml +++ b/Helpers/IPCHandlers.qml @@ -1,11 +1,18 @@ import Quickshell.Io +import "./IdleInhibitor.qml" + IpcHandler { property var appLauncherPanel property var lockScreen + property IdleInhibitor idleInhibitor target: "globalIPC" + function toggleIdleInhibitor(): void { + idleInhibitor.toggle() + } + // Toggle Applauncher visibility function toggleLauncher(): void { if (!appLauncherPanel) { diff --git a/Helpers/IdleInhibitor.qml b/Helpers/IdleInhibitor.qml new file mode 100644 index 0000000..de78a99 --- /dev/null +++ b/Helpers/IdleInhibitor.qml @@ -0,0 +1,43 @@ +import Quickshell.Io + +Process { + id: idleRoot + + // Example: systemd-inhibit to prevent idle/sleep + command: ["systemd-inhibit", "--what=idle:sleep", "--who=noctalia", "--why=User requested", "sleep", "infinity"] + + // Keep process running in background + property bool isRunning: running + + onStarted: { + console.log("[IdleInhibitor] Process started - idle inhibited") + } + + onExited: function(exitCode, exitStatus) { + console.log("[IdleInhibitor] Process finished:", exitCode) + } + + // Control functions + function start() { + if (!running) { + console.log("[IdleInhibitor] Starting idle inhibitor...") + running = true + } + } + + function stop() { + if (running) { + // Force stop the process by setting running to false + running = false + console.log("[IdleInhibitor] Stopping idle inhibitor...") + } + } + + function toggle() { + if (running) { + stop() + } else { + start() + } + } +} diff --git a/shell.qml b/shell.qml index a78bae5..74e41ca 100644 --- a/shell.qml +++ b/shell.qml @@ -11,6 +11,9 @@ import qs.Widgets.Notification import qs.Settings import qs.Helpers +import "./Helpers/IdleInhibitor.qml" +import "./Helpers/IPCHandlers.qml" + Scope { id: root @@ -50,6 +53,10 @@ Scope { } } + IdleInhibitor { + id: idleInhibitor + } + NotificationServer { id: notificationServer onNotification: function (notification) { @@ -88,6 +95,7 @@ Scope { IPCHandlers { appLauncherPanel: appLauncherPanel lockScreen: lockScreen + idleInhibitor: idleInhibitor } Connections { From ca48eef61231583a758e3ab6686a0e02b0a99918 Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sun, 27 Jul 2025 18:12:12 +0700 Subject: [PATCH 09/12] fix: convert to string first before using includes --- Settings/Theme.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Settings/Theme.qml b/Settings/Theme.qml index 97e8d29..ab61f04 100644 --- a/Settings/Theme.qml +++ b/Settings/Theme.qml @@ -20,8 +20,8 @@ Singleton { onFileChanged: reload() onAdapterUpdated: writeAdapter() onLoadFailed: function(error) { - if (error.includes("No such file")) { - themeData = {} + if (error.toString().includes("No such file") || error === 2) { + // File doesn't exist, create it with default values writeAdapter() } } From f8db6ba9df2149e1e52a6fa7b9c7a43850716d12 Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sun, 27 Jul 2025 18:55:13 +0700 Subject: [PATCH 10/12] feat: add ability to toggle notification popup visibility via IPC --- Helpers/IPCHandlers.qml | 7 +++++++ Widgets/Notification/NotificationPopup.qml | 9 ++++++++- shell.qml | 5 ++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Helpers/IPCHandlers.qml b/Helpers/IPCHandlers.qml index f0659cd..6cc0aea 100644 --- a/Helpers/IPCHandlers.qml +++ b/Helpers/IPCHandlers.qml @@ -6,6 +6,7 @@ IpcHandler { property var appLauncherPanel property var lockScreen property IdleInhibitor idleInhibitor + property var notificationPopup target: "globalIPC" @@ -13,6 +14,12 @@ IpcHandler { idleInhibitor.toggle() } + + function toggleNotificationPopup(): void { + console.log("[IPC] NotificationPopup toggle() called") + notificationPopup.togglePopup(); + } + // Toggle Applauncher visibility function toggleLauncher(): void { if (!appLauncherPanel) { diff --git a/Widgets/Notification/NotificationPopup.qml b/Widgets/Notification/NotificationPopup.qml index b80018f..10324c0 100644 --- a/Widgets/Notification/NotificationPopup.qml +++ b/Widgets/Notification/NotificationPopup.qml @@ -8,11 +8,12 @@ PanelWindow { implicitWidth: 350 implicitHeight: notificationColumn.implicitHeight color: "transparent" - visible: notificationModel.count > 0 + visible: notificationsVisible && notificationModel.count > 0 screen: Quickshell.primaryScreen !== undefined ? Quickshell.primaryScreen : null focusable: false property bool barVisible: true + property bool notificationsVisible: true anchors.top: true anchors.right: true @@ -26,6 +27,12 @@ PanelWindow { property int maxVisible: 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) { notificationModel.insert(0, { id: notification.id, diff --git a/shell.qml b/shell.qml index 74e41ca..6be575b 100644 --- a/shell.qml +++ b/shell.qml @@ -62,7 +62,9 @@ Scope { onNotification: function (notification) { console.log("Notification received:", notification.appName); notification.tracked = true; - notificationPopup.addNotification(notification); + if (notificationPopup.notificationsVisible) { + notificationPopup.addNotification(notification); + } if (notificationHistoryWin) { notificationHistoryWin.addToHistory({ id: notification.id, @@ -96,6 +98,7 @@ Scope { appLauncherPanel: appLauncherPanel lockScreen: lockScreen idleInhibitor: idleInhibitor + notificationPopup: notificationPopup } Connections { From a9b89e771ee8bd149c431543626ab929ab93eda2 Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sun, 27 Jul 2025 22:09:39 +0700 Subject: [PATCH 11/12] feat: add right-click toggle for notification silence mode with icon state --- Widgets/Notification/NotificationIcon.qml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Widgets/Notification/NotificationIcon.qml b/Widgets/Notification/NotificationIcon.qml index 6af48c6..988483a 100644 --- a/Widgets/Notification/NotificationIcon.qml +++ b/Widgets/Notification/NotificationIcon.qml @@ -7,12 +7,20 @@ import qs.Components Item { id: root width: 22; height: 22 + property bool isSilence: false + + // Process for executing CLI commands + Process { + id: rightClickProcess + command: ["qs","ipc", "call", "globalIPC", "toggleNotificationPopup"] + } // Bell icon/button Item { id: bell width: 22; height: 22 Text { + id: bellText anchors.centerIn: parent text: notificationHistoryWin.hasUnread ? "notifications_unread" : "notifications" font.family: mouseAreaBell.containsMouse ? "Material Symbols Rounded" : "Material Symbols Outlined" @@ -25,7 +33,20 @@ Item { anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor - onClicked: notificationHistoryWin.visible = !notificationHistoryWin.visible + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: function(mouse): void { + if (mouse.button === Qt.RightButton) { + root.isSilence = !root.isSilence; + rightClickProcess.running = true; + bellText.text = root.isSilence ? "notifications_off" : "notifications" + } + + if (mouse.button === Qt.LeftButton){ + notificationHistoryWin.visible = !notificationHistoryWin.visible + return; + } + + } onEntered: notificationTooltip.tooltipVisible = true onExited: notificationTooltip.tooltipVisible = false } From 226e562c543f3ddc0b96e23b36703053b55f3f89 Mon Sep 17 00:00:00 2001 From: JPratama7 Date: Sun, 27 Jul 2025 22:22:07 +0700 Subject: [PATCH 12/12] docs: update IPC commands with notification popup and idle inhibitor toggles --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 841ec27..473994d 100644 --- a/README.md +++ b/README.md @@ -153,14 +153,17 @@ To make the weather widget, wallpaper manager and record button work you will ha qs ipc call globalIPC toggleLauncher ``` -### Toggle Lockscreen: +### Toggle Notification Popup: ``` -qs ipc call globalIPC toggleLock +qs ipc call globalIPC toggleNotificationPopup ``` -You can keybind it however you want in your niri setup. +### Toggle Idle Inhibitor: +``` +qs ipc call globalIPC toggleIdleInhibitor +``` ### Toggle Fullscreen: