From f8c34d7f45068de57c9729b090b89355b39b7a46 Mon Sep 17 00:00:00 2001 From: corazon <99136079+corazon008@users.noreply.github.com> Date: Wed, 24 Jun 2026 01:04:30 +0200 Subject: [PATCH 1/5] Reformat file --- .../quickshell/SidebarApp/SidebarWindow.qml | 380 ++++++++++++------ 1 file changed, 257 insertions(+), 123 deletions(-) diff --git a/dotfiles/.config/quickshell/SidebarApp/SidebarWindow.qml b/dotfiles/.config/quickshell/SidebarApp/SidebarWindow.qml index 718b74d3b..04e9aa100 100644 --- a/dotfiles/.config/quickshell/SidebarApp/SidebarWindow.qml +++ b/dotfiles/.config/quickshell/SidebarApp/SidebarWindow.qml @@ -38,7 +38,7 @@ PanelWindow { active: root.isOpen onCleared: { if (root.isOpen) { - root.isOpen = false + root.isOpen = false; } } } @@ -48,7 +48,7 @@ PanelWindow { sequence: "Escape" onActivated: { if (root.isOpen) { - root.isOpen = false + root.isOpen = false; } } } @@ -57,7 +57,9 @@ PanelWindow { property bool isOpen: false visible: isOpen || slideAnim.running - margins { right: root.currentMargin } + margins { + right: root.currentMargin + } property real currentMargin: isOpen ? 0 : -470 Behavior on currentMargin { @@ -70,9 +72,15 @@ PanelWindow { IpcHandler { target: "sidebar" - function toggle(): void { root.isOpen = !root.isOpen } - function open(): void { root.isOpen = true } - function close(): void { root.isOpen = false } + function toggle(): void { + root.isOpen = !root.isOpen; + } + function open(): void { + root.isOpen = true; + } + function close(): void { + root.isOpen = false; + } } Process { @@ -81,8 +89,8 @@ PanelWindow { stdout: StdioCollector { onStreamFinished: { - console.log(this.text.trim()) - root.isHyprlandSettingsInstalled = (this.text.trim() === "0") + console.log(this.text.trim()); + root.isHyprlandSettingsInstalled = (this.text.trim() === "0"); } } } @@ -142,7 +150,11 @@ PanelWindow { implicitHeight: 22 radius: 11 color: parent.parent.checked ? Theme.background : Theme.on_primary - Behavior on x { NumberAnimation { duration: 150 } } + Behavior on x { + NumberAnimation { + duration: 150 + } + } } } } @@ -150,7 +162,9 @@ PanelWindow { component SettingsWheel: Button { implicitWidth: 28 implicitHeight: 28 - background: Rectangle { color: "transparent" } + background: Rectangle { + color: "transparent" + } contentItem: Item { Image { anchors.centerIn: parent @@ -175,7 +189,9 @@ PanelWindow { property string iconSrc: "" implicitWidth: 28 implicitHeight: 28 - background: Rectangle { color: "transparent" } + background: Rectangle { + color: "transparent" + } contentItem: Item { Text { anchors.centerIn: parent @@ -243,30 +259,37 @@ PanelWindow { ActionIcon { iconSrc: "../shared/icons/darklight.svg" onClicked: { - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/scripts/ml4w-toggle-theme"]) + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/scripts/ml4w-toggle-theme"]); } } ActionIcon { iconSrc: "../shared/icons/picker.svg" onClicked: { - root.isOpen = false - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/settings/hyprpicker.sh"]) + root.isOpen = false; + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/settings/hyprpicker.sh"]); } } ActionIcon { iconSrc: "../shared/icons/screenshot.svg" onClicked: { - root.isOpen = false - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/hypr/scripts/screenshot.sh"]) + root.isOpen = false; + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/hypr/scripts/screenshot.sh"]); } } - Item { Layout.fillWidth: true } + Item { + Layout.fillWidth: true + } } - Rectangle { Layout.fillWidth: true; implicitHeight: 1; color: Theme.primary; opacity: 0.3 } + Rectangle { + Layout.fillWidth: true + implicitHeight: 1 + color: Theme.primary + opacity: 0.3 + } // --- THREE BUTTONS ROW --- RowLayout { @@ -276,29 +299,34 @@ PanelWindow { ML4WButton { text: "Welcome" onClicked: { - root.isOpen = false - Quickshell.execDetached(["bash", "-c", "qs ipc call welcome toggle"]) + root.isOpen = false; + Quickshell.execDetached(["bash", "-c", "qs ipc call welcome toggle"]); } } ML4WButton { text: "Settings" onClicked: { - root.isOpen = false + root.isOpen = false; // Quickshell.execDetached(["kitty", "--class", "dotfiles-floating", "-e", "ml4w-dotfiles-settings", "com.ml4w.dotfiles"]) - Quickshell.execDetached(["bash", "-c", "qs -p " + Quickshell.env("HOME") + "/.local/share/ml4w-dotfiles-settings/quickshell ipc call settings toggle"]) + Quickshell.execDetached(["bash", "-c", "qs -p " + Quickshell.env("HOME") + "/.local/share/ml4w-dotfiles-settings/quickshell ipc call settings toggle"]); } } ML4WButton { text: "HyprMod" visible: root.isHyprlandSettingsInstalled onClicked: { - root.isOpen = false - Quickshell.execDetached(["hyprmod"]) + root.isOpen = false; + Quickshell.execDetached(["hyprmod"]); } } } - Rectangle { Layout.fillWidth: true; implicitHeight: 1; color: Theme.primary; opacity: 0.3 } + Rectangle { + Layout.fillWidth: true + implicitHeight: 1 + color: Theme.primary + opacity: 0.3 + } // --- SCROLLABLE CONTENT --- ScrollView { @@ -312,7 +340,9 @@ PanelWindow { policy: ScrollBar.AsNeeded interactive: true contentItem: Rectangle { - implicitWidth: 6; radius: 3; color: Theme.primary + implicitWidth: 6 + radius: 3 + color: Theme.primary opacity: parent.pressed ? 1.0 : (parent.active ? 0.8 : 0.4) } } @@ -352,14 +382,15 @@ PanelWindow { running: root.isOpen stdout: StdioCollector { onStreamFinished: { - let val = parseInt(this.text.trim()) - if (!isNaN(val)) volumeSlider.value = val; + let val = parseInt(this.text.trim()); + if (!isNaN(val)) + volumeSlider.value = val; } } } onMoved: { - Quickshell.execDetached(["bash", "-c", "wpctl set-volume @DEFAULT_AUDIO_SINK@ " + Math.round(value) + "%"]) + Quickshell.execDetached(["bash", "-c", "wpctl set-volume @DEFAULT_AUDIO_SINK@ " + Math.round(value) + "%"]); } background: Rectangle { @@ -420,14 +451,15 @@ PanelWindow { running: root.isOpen stdout: StdioCollector { onStreamFinished: { - let val = parseInt(this.text.trim()) - if (!isNaN(val)) brightnessSlider.value = Math.max(10, val); + let val = parseInt(this.text.trim()); + if (!isNaN(val)) + brightnessSlider.value = Math.max(10, val); } } } onMoved: { - Quickshell.execDetached(["bash", "-c", "brightnessctl set " + Math.round(value) + "%"]) + Quickshell.execDetached(["bash", "-c", "brightnessctl set " + Math.round(value) + "%"]); } background: Rectangle { @@ -464,7 +496,14 @@ PanelWindow { } } - Rectangle { Layout.fillWidth: true; implicitHeight: 1; color: Theme.primary; opacity: 0.3; Layout.topMargin: 5; Layout.bottomMargin: 5 } + Rectangle { + Layout.fillWidth: true + implicitHeight: 1 + color: Theme.primary + opacity: 0.3 + Layout.topMargin: 5 + Layout.bottomMargin: 5 + } // --- MPRIS PLAYERS (Scrollable ListView) --- ListView { @@ -489,7 +528,9 @@ PanelWindow { policy: mprisListView.count > 2 ? ScrollBar.AsNeeded : ScrollBar.AlwaysOff interactive: true contentItem: Rectangle { - implicitWidth: 6; radius: 3; color: Theme.primary + implicitWidth: 6 + radius: 3 + color: Theme.primary opacity: parent.pressed ? 1.0 : (parent.active ? 0.8 : 0.4) } } @@ -557,8 +598,10 @@ PanelWindow { Text { Layout.fillWidth: true text: { - if (player.trackArtist) return player.trackArtist; - if (player.trackArtists && player.trackArtists.length > 0) return player.trackArtists[0]; + if (player.trackArtist) + return player.trackArtist; + if (player.trackArtists && player.trackArtists.length > 0) + return player.trackArtists[0]; return "Unknown Artist"; } color: Theme.on_background @@ -568,13 +611,17 @@ PanelWindow { opacity: 0.8 } - Item { Layout.fillHeight: true } + Item { + Layout.fillHeight: true + } RowLayout { Layout.fillWidth: true spacing: 15 - Item { Layout.fillWidth: true } + Item { + Layout.fillWidth: true + } ActionIcon { iconTxt: "󰒮" @@ -597,7 +644,9 @@ PanelWindow { onClicked: player.next() } - Item { Layout.fillWidth: true } + Item { + Layout.fillWidth: true + } } } } @@ -605,20 +654,27 @@ PanelWindow { } Rectangle { - Layout.fillWidth: true; - implicitHeight: 1; - color: Theme.primary; - opacity: 0.3; - Layout.topMargin: 5; - Layout.bottomMargin: 5; + Layout.fillWidth: true + implicitHeight: 1 + color: Theme.primary + opacity: 0.3 + Layout.topMargin: 5 + Layout.bottomMargin: 5 visible: Mpris.players.values.length > 0 } // --- WAYBAR --- RowLayout { Layout.fillWidth: true - Text { text: "Waybar"; color: Theme.on_background; font.family: Theme.fontFamily; font.pixelSize: 16 } - Item { Layout.fillWidth: true } + Text { + text: "Waybar" + color: Theme.on_background + font.family: Theme.fontFamily + font.pixelSize: 16 + } + Item { + Layout.fillWidth: true + } ML4WSwitch { id: waybarSwitch property bool ready: false @@ -627,19 +683,18 @@ PanelWindow { running: root.isOpen stdout: StdioCollector { onStreamFinished: { - console.log("Test for Waybar: " + this.text.trim()) - waybarSwitch.checked = (this.text.trim() === "1") - waybarSwitch.ready = true + console.log("Test for Waybar: " + this.text.trim()); + waybarSwitch.checked = (this.text.trim() === "1"); + waybarSwitch.ready = true; } } } onClicked: { - if (!ready) return; - let fileCmd = checked - ? "rm -f ~/.config/ml4w/settings/waybar-disabled" - : "touch ~/.config/ml4w/settings/waybar-disabled" - console.log("Waybar cmd: " + fileCmd) - Quickshell.execDetached(["bash", "-c", fileCmd + ";" + Quickshell.env("HOME") + "/.config/waybar/launch.sh"]) + if (!ready) + return; + let fileCmd = checked ? "rm -f ~/.config/ml4w/settings/waybar-disabled" : "touch ~/.config/ml4w/settings/waybar-disabled"; + console.log("Waybar cmd: " + fileCmd); + Quickshell.execDetached(["bash", "-c", fileCmd + ";" + Quickshell.env("HOME") + "/.config/waybar/launch.sh"]); } } @@ -651,18 +706,29 @@ PanelWindow { implicitWidth: 220 padding: 8 - background: Rectangle { color: Theme.background; border.color: Theme.primary; border.width: 1; radius: 8 } - ML4WMenuItem { text: "Select Waybar Theme"; onClicked: { - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/waybar/themeswitcher.sh"]) + background: Rectangle { + color: Theme.background + border.color: Theme.primary + border.width: 1 + radius: 8 + } + ML4WMenuItem { + text: "Select Waybar Theme" + onClicked: { + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/waybar/themeswitcher.sh"]); } } - ML4WMenuItem { text: "Edit Quicklinks"; onClicked: { - root.isOpen = false - Quickshell.execDetached(["gnome-text-editor", Quickshell.env("HOME") + "/.config/ml4w/settings/waybar-quicklinks.json"]) + ML4WMenuItem { + text: "Edit Quicklinks" + onClicked: { + root.isOpen = false; + Quickshell.execDetached(["gnome-text-editor", Quickshell.env("HOME") + "/.config/ml4w/settings/waybar-quicklinks.json"]); } } - ML4WMenuItem { text: "Reload Waybar"; onClicked: { - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/waybar/launch.sh"]) + ML4WMenuItem { + text: "Reload Waybar" + onClicked: { + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/waybar/launch.sh"]); } } } @@ -672,8 +738,15 @@ PanelWindow { // --- DOCK --- RowLayout { Layout.fillWidth: true - Text { text: "Dock"; color: Theme.on_background; font.family: Theme.fontFamily; font.pixelSize: 16 } - Item { Layout.fillWidth: true } + Text { + text: "Dock" + color: Theme.on_background + font.family: Theme.fontFamily + font.pixelSize: 16 + } + Item { + Layout.fillWidth: true + } ML4WSwitch { id: dockSwitch property bool ready: false @@ -682,29 +755,37 @@ PanelWindow { running: root.isOpen stdout: StdioCollector { onStreamFinished: { - console.log("Test for Dock: " + this.text.trim()) - dockSwitch.checked = (this.text.trim() === "1") - dockSwitch.ready = true + console.log("Test for Dock: " + this.text.trim()); + dockSwitch.checked = (this.text.trim() === "1"); + dockSwitch.ready = true; } } } onClicked: { - if (!ready) return; - let fileCmd = checked - ? "rm -f ~/.config/ml4w/settings/dock-disabled" - : "touch ~/.config/ml4w/settings/dock-disabled" - console.log("Dock cmd: " + fileCmd) - Quickshell.execDetached(["bash", "-c", fileCmd + "; " + Quickshell.env("HOME") + "/.config/nwg-dock-hyprland/launch.sh"]) + if (!ready) + return; + let fileCmd = checked ? "rm -f ~/.config/ml4w/settings/dock-disabled" : "touch ~/.config/ml4w/settings/dock-disabled"; + console.log("Dock cmd: " + fileCmd); + Quickshell.execDetached(["bash", "-c", fileCmd + "; " + Quickshell.env("HOME") + "/.config/nwg-dock-hyprland/launch.sh"]); } } - Item { implicitWidth: 28 } + Item { + implicitWidth: 28 + } } // --- DOCK AUTOHIDE --- RowLayout { Layout.fillWidth: true - Text { text: "Dock Autohide"; color: Theme.on_background; font.family: Theme.fontFamily; font.pixelSize: 16 } - Item { Layout.fillWidth: true } + Text { + text: "Dock Autohide" + color: Theme.on_background + font.family: Theme.fontFamily + font.pixelSize: 16 + } + Item { + Layout.fillWidth: true + } ML4WSwitch { id: dockAutohideSwitch property bool ready: false @@ -713,29 +794,37 @@ PanelWindow { running: root.isOpen stdout: StdioCollector { onStreamFinished: { - console.log("Test for Dock Autohide: " + this.text.trim()) - dockAutohideSwitch.checked = (this.text.trim() === "1") - dockAutohideSwitch.ready = true + console.log("Test for Dock Autohide: " + this.text.trim()); + dockAutohideSwitch.checked = (this.text.trim() === "1"); + dockAutohideSwitch.ready = true; } } } onClicked: { - if (!ready) return; - let fileCmd = checked - ? "mkdir -p ~/.config/ml4w/settings && touch ~/.config/ml4w/settings/dock-autohide" - : "rm -f ~/.config/ml4w/settings/dock-autohide" - console.log("Dock Autohide cmd: " + fileCmd) - Quickshell.execDetached(["bash", "-c", fileCmd + "; " + Quickshell.env("HOME") + "/.config/nwg-dock-hyprland/launch.sh"]) + if (!ready) + return; + let fileCmd = checked ? "mkdir -p ~/.config/ml4w/settings && touch ~/.config/ml4w/settings/dock-autohide" : "rm -f ~/.config/ml4w/settings/dock-autohide"; + console.log("Dock Autohide cmd: " + fileCmd); + Quickshell.execDetached(["bash", "-c", fileCmd + "; " + Quickshell.env("HOME") + "/.config/nwg-dock-hyprland/launch.sh"]); } } - Item { implicitWidth: 28 } + Item { + implicitWidth: 28 + } } // --- GAMEMODE --- RowLayout { Layout.fillWidth: true - Text { text: "Gamemode"; color: Theme.on_background; font.family: Theme.fontFamily; font.pixelSize: 16 } - Item { Layout.fillWidth: true } + Text { + text: "Gamemode" + color: Theme.on_background + font.family: Theme.fontFamily + font.pixelSize: 16 + } + Item { + Layout.fillWidth: true + } ML4WSwitch { id: gamemodeSwitch property bool ready: false @@ -744,25 +833,35 @@ PanelWindow { running: root.isOpen stdout: StdioCollector { onStreamFinished: { - console.log("Test for Gamemode: " + this.text.trim()) - gamemodeSwitch.checked = (this.text.trim() === "0") - gamemodeSwitch.ready = true + console.log("Test for Gamemode: " + this.text.trim()); + gamemodeSwitch.checked = (this.text.trim() === "0"); + gamemodeSwitch.ready = true; } } } onClicked: { - if (!ready) return; - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/hypr/scripts/gamemode.sh"]) + if (!ready) + return; + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/hypr/scripts/gamemode.sh"]); } } - Item { implicitWidth: 28 } + Item { + implicitWidth: 28 + } } // --- FASTFETCH --- RowLayout { Layout.fillWidth: true - Text { text: "Fastfetch"; color: Theme.on_background; font.family: Theme.fontFamily; font.pixelSize: 16 } - Item { Layout.fillWidth: true } + Text { + text: "Fastfetch" + color: Theme.on_background + font.family: Theme.fontFamily + font.pixelSize: 16 + } + Item { + Layout.fillWidth: true + } ML4WSwitch { id: fastfetchSwitch property bool ready: false @@ -771,32 +870,49 @@ PanelWindow { running: root.isOpen stdout: StdioCollector { onStreamFinished: { - console.log("Test for Fastfetch: " + this.text.trim()) - fastfetchSwitch.checked = (this.text.trim() === "0") - fastfetchSwitch.ready = true + console.log("Test for Fastfetch: " + this.text.trim()); + fastfetchSwitch.checked = (this.text.trim() === "0"); + fastfetchSwitch.ready = true; } } } onClicked: { - if (!ready) return; - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/scripts/ml4w-toggle-fastfetch"]) + if (!ready) + return; + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/scripts/ml4w-toggle-fastfetch"]); } } - Item { implicitWidth: 28 } + Item { + implicitWidth: 28 + } } - Rectangle { Layout.fillWidth: true; implicitHeight: 1; color: Theme.primary; opacity: 0.3; Layout.topMargin: 5; Layout.bottomMargin: 5 } + Rectangle { + Layout.fillWidth: true + implicitHeight: 1 + color: Theme.primary + opacity: 0.3 + Layout.topMargin: 5 + Layout.bottomMargin: 5 + } // --- WALLPAPER --- RowLayout { Layout.fillWidth: true - Text { text: "Wallpaper"; color: Theme.on_background; font.family: Theme.fontFamily; font.pixelSize: 16 } - Item { Layout.fillWidth: true } + Text { + text: "Wallpaper" + color: Theme.on_background + font.family: Theme.fontFamily + font.pixelSize: 16 + } + Item { + Layout.fillWidth: true + } ActionIcon { iconSrc: "../shared/icons/wallpaper.svg" onClicked: { - root.isOpen = false - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/scripts/ml4w-wallpaper-app"]) + root.isOpen = false; + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/scripts/ml4w-wallpaper-app"]); } } } @@ -804,13 +920,20 @@ PanelWindow { // --- THEME --- RowLayout { Layout.fillWidth: true - Text { text: "Theme"; color: Theme.on_background; font.family: Theme.fontFamily; font.pixelSize: 16 } - Item { Layout.fillWidth: true } + Text { + text: "Theme" + color: Theme.on_background + font.family: Theme.fontFamily + font.pixelSize: 16 + } + Item { + Layout.fillWidth: true + } ActionIcon { iconSrc: "../shared/icons/theme.svg" onClicked: { - root.isOpen = false - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/themes/themes.sh"]) + root.isOpen = false; + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/ml4w/themes/themes.sh"]); } } SettingsWheel { @@ -822,20 +945,31 @@ PanelWindow { implicitWidth: 220 padding: 8 - background: Rectangle { color: Theme.background; border.color: Theme.primary; border.width: 1; radius: 8 } - ML4WMenuItem { text: "Set GTK Theme"; onClicked: { - root.isOpen = false - Quickshell.execDetached(["nwg-look"]) + background: Rectangle { + color: Theme.background + border.color: Theme.primary + border.width: 1 + radius: 8 + } + ML4WMenuItem { + text: "Set GTK Theme" + onClicked: { + root.isOpen = false; + Quickshell.execDetached(["nwg-look"]); } } - ML4WMenuItem { text: "Set QT Theme"; onClicked: { - root.isOpen = false - Quickshell.execDetached(["qt6ct"]) + ML4WMenuItem { + text: "Set QT Theme" + onClicked: { + root.isOpen = false; + Quickshell.execDetached(["qt6ct"]); } } - ML4WMenuItem { text: "Refresh GTK Theme"; onClicked: { - root.isOpen = false - Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/hypr/scripts/gtk.sh"]) + ML4WMenuItem { + text: "Refresh GTK Theme" + onClicked: { + root.isOpen = false; + Quickshell.execDetached(["bash", "-c", Quickshell.env("HOME") + "/.config/hypr/scripts/gtk.sh"]); } } } From 93da5643beb7f6870919e59bdaca53e31a42e0ce Mon Sep 17 00:00:00 2001 From: corazon <99136079+corazon008@users.noreply.github.com> Date: Wed, 24 Jun 2026 01:06:21 +0200 Subject: [PATCH 2/5] Add support for several sound and brightness device --- .../SidebarApp/BrightnessControls.qml | 108 ++++++++++++++ .../quickshell/SidebarApp/SidebarWindow.qml | 140 +----------------- .../quickshell/SidebarApp/SoundControls.qml | 114 ++++++++++++++ 3 files changed, 228 insertions(+), 134 deletions(-) create mode 100644 dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml create mode 100644 dotfiles/.config/quickshell/SidebarApp/SoundControls.qml diff --git a/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml b/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml new file mode 100644 index 000000000..12adf474a --- /dev/null +++ b/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml @@ -0,0 +1,108 @@ +import Quickshell +import Quickshell.Io +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import qs.CustomTheme + +ColumnLayout { + id: root + Layout.fillWidth: true + spacing: 20 + + property bool isOpen: false + property int screenCount: 1 + + Process { + id: brightnessDisplays + command: ["bash", "-c", "~/.config/hypr/scripts/brightness.sh displays"] + + running: root.isOpen + + stdout: StdioCollector { + onStreamFinished: { + root.screenCount = parseInt(this.text.trim()); + } + } + } + + Text { + text: "Brightness" // Sun/Brightness icon + color: Theme.primary + font.family: "monospace" + font.pixelSize: 18 + Layout.alignment: Qt.AlignVCenter + } + + Repeater { + model: root.screenCount + + delegate: RowLayout { + Layout.fillWidth: true + spacing: 15 + + Text { + text: "☀ " + (index + 1) + color: Theme.primary + font.family: "monospace" + font.pixelSize: 18 + Layout.alignment: Qt.AlignVCenter + } + + Slider { + id: brightnessSlider + Layout.fillWidth: true + from: 0 + to: 100 + value: 50 // Default + + Process { + command: ["bash", "-c", "~/.config/hypr/scripts/brightness.sh get-display " + (index + 1)] + running: root.isOpen + stdout: StdioCollector { + onStreamFinished: { + let v = parseInt(this.text.trim()); + if (!isNaN(v)) + brightnessSlider.value = v; + } + } + } + + onMoved: { + Quickshell.execDetached(["bash", "-c", "~/.config/hypr/scripts/brightness.sh set-display " + (index + 1) + " " + Math.round(value)]); + } + + background: Rectangle { + x: brightnessSlider.leftPadding + y: brightnessSlider.topPadding + brightnessSlider.availableHeight / 2 - height / 2 + implicitWidth: 200 + implicitHeight: 6 + width: brightnessSlider.availableWidth + height: implicitHeight + radius: 3 + color: Theme.background + border.color: Theme.primary + border.width: 1 + + Rectangle { + width: brightnessSlider.visualPosition * parent.width + height: parent.height + color: Theme.primary + radius: 3 + } + } + + handle: Rectangle { + x: brightnessSlider.leftPadding + brightnessSlider.visualPosition * (brightnessSlider.availableWidth - width) + y: brightnessSlider.topPadding + brightnessSlider.availableHeight / 2 - height / 2 + implicitWidth: 16 + implicitHeight: 16 + radius: 8 + color: brightnessSlider.pressed ? Theme.background : Theme.primary + border.color: Theme.primary + border.width: 1 + } + } + } + } +} diff --git a/dotfiles/.config/quickshell/SidebarApp/SidebarWindow.qml b/dotfiles/.config/quickshell/SidebarApp/SidebarWindow.qml index 04e9aa100..5eb1ad6c3 100644 --- a/dotfiles/.config/quickshell/SidebarApp/SidebarWindow.qml +++ b/dotfiles/.config/quickshell/SidebarApp/SidebarWindow.qml @@ -357,142 +357,14 @@ PanelWindow { Layout.fillWidth: true spacing: 20 - // LOUDNESS SLIDER - RowLayout { - Layout.fillWidth: true - spacing: 15 - - Text { - text: "" // Speaker icon - color: Theme.primary - font.family: "monospace" - font.pixelSize: 18 - Layout.alignment: Qt.AlignVCenter - } - - Slider { - id: volumeSlider - Layout.fillWidth: true - from: 0 - to: 100 - value: 50 // Default - - Process { - command: ["bash", "-c", "wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{print int($2 * 100)}'"] - running: root.isOpen - stdout: StdioCollector { - onStreamFinished: { - let val = parseInt(this.text.trim()); - if (!isNaN(val)) - volumeSlider.value = val; - } - } - } - - onMoved: { - Quickshell.execDetached(["bash", "-c", "wpctl set-volume @DEFAULT_AUDIO_SINK@ " + Math.round(value) + "%"]); - } - - background: Rectangle { - x: volumeSlider.leftPadding - y: volumeSlider.topPadding + volumeSlider.availableHeight / 2 - height / 2 - implicitWidth: 200 - implicitHeight: 6 - width: volumeSlider.availableWidth - height: implicitHeight - radius: 3 - color: Theme.background - border.color: Theme.primary - border.width: 1 - - Rectangle { - width: volumeSlider.visualPosition * parent.width - height: parent.height - color: Theme.primary - radius: 3 - } - } - - handle: Rectangle { - x: volumeSlider.leftPadding + volumeSlider.visualPosition * (volumeSlider.availableWidth - width) - y: volumeSlider.topPadding + volumeSlider.availableHeight / 2 - height / 2 - implicitWidth: 16 - implicitHeight: 16 - radius: 8 - color: volumeSlider.pressed ? Theme.background : Theme.primary - border.color: Theme.primary - border.width: 1 - } - } + SoundControls { + id: soundControls + isOpen: root.isOpen } - // BRIGHTNESS SLIDER - RowLayout { - Layout.fillWidth: true - spacing: 15 - - Text { - text: "" // Sun/Brightness icon - color: Theme.primary - font.family: "monospace" - font.pixelSize: 18 - Layout.alignment: Qt.AlignVCenter - } - - Slider { - id: brightnessSlider - Layout.fillWidth: true - from: 10 // Guaranteed Minimum 10% - to: 100 - value: 100 - - Process { - command: ["bash", "-c", "brightnessctl -m | awk -F, '{gsub(\"%\",\"\",$4); print $4}'"] - running: root.isOpen - stdout: StdioCollector { - onStreamFinished: { - let val = parseInt(this.text.trim()); - if (!isNaN(val)) - brightnessSlider.value = Math.max(10, val); - } - } - } - - onMoved: { - Quickshell.execDetached(["bash", "-c", "brightnessctl set " + Math.round(value) + "%"]); - } - - background: Rectangle { - x: brightnessSlider.leftPadding - y: brightnessSlider.topPadding + brightnessSlider.availableHeight / 2 - height / 2 - implicitWidth: 200 - implicitHeight: 6 - width: brightnessSlider.availableWidth - height: implicitHeight - radius: 3 - color: Theme.background - border.color: Theme.primary - border.width: 1 - - Rectangle { - width: brightnessSlider.visualPosition * parent.width - height: parent.height - color: Theme.primary - radius: 3 - } - } - - handle: Rectangle { - x: brightnessSlider.leftPadding + brightnessSlider.visualPosition * (brightnessSlider.availableWidth - width) - y: brightnessSlider.topPadding + brightnessSlider.availableHeight / 2 - height / 2 - implicitWidth: 16 - implicitHeight: 16 - radius: 8 - color: brightnessSlider.pressed ? Theme.background : Theme.primary - border.color: Theme.primary - border.width: 1 - } - } + BrightnessControls { + id: brightnessControls + isOpen: root.isOpen } } diff --git a/dotfiles/.config/quickshell/SidebarApp/SoundControls.qml b/dotfiles/.config/quickshell/SidebarApp/SoundControls.qml new file mode 100644 index 000000000..86a2c43e6 --- /dev/null +++ b/dotfiles/.config/quickshell/SidebarApp/SoundControls.qml @@ -0,0 +1,114 @@ +import Quickshell +import Quickshell.Io +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import qs.CustomTheme + +ColumnLayout { + id: root + Layout.fillWidth: true + spacing: 20 + + property bool isOpen: false + property var soundIds: [] + + Process { + id: soundOutputs + command: ["bash", "-c", "pactl list sinks short | awk '{print $1}'"] + + running: root.isOpen + + stdout: StdioCollector { + onStreamFinished: { + root.soundIds = this.text.trim().split("\n").map(id => parseInt(id)).filter(id => !isNaN(id)); + console.log("Sinks:", root.soundIds); + } + } + } + + ColumnLayout { + Layout.fillWidth: true + spacing: 20 + + Text { + text: "Sound" + color: Theme.primary + font.family: "monospace" + font.pixelSize: 18 + } + + Repeater { + model: root.soundIds + + delegate: RowLayout { + Layout.fillWidth: true + spacing: 15 + + property int sinkId: modelData + + Text { + text: " " //+ sinkId + color: Theme.primary + font.family: "monospace" + font.pixelSize: 18 + } + + Slider { + id: soundSlider + Layout.fillWidth: true + from: 0 + to: 100 + value: 50 + + Process { + command: ["bash", "-c", "pactl get-sink-volume " + sinkId + " | grep -o '[0-9]*%' | head -1 | sed 's/%//'"] + running: root.isOpen + stdout: StdioCollector { + onStreamFinished: { + let v = parseInt(this.text.trim()); + if (!isNaN(v)) + soundSlider.value = v; + } + } + } + + onMoved: { + Quickshell.execDetached(["bash", "-c", "pactl set-sink-volume " + sinkId + " " + Math.round(value) + "%"]); + } + + background: Rectangle { + x: soundSlider.leftPadding + y: soundSlider.topPadding + soundSlider.availableHeight / 2 - height / 2 + implicitWidth: 200 + implicitHeight: 6 + width: soundSlider.availableWidth + height: implicitHeight + radius: 3 + color: Theme.background + border.color: Theme.primary + border.width: 1 + + Rectangle { + width: soundSlider.visualPosition * parent.width + height: parent.height + color: Theme.primary + radius: 3 + } + } + + handle: Rectangle { + x: soundSlider.leftPadding + soundSlider.visualPosition * (soundSlider.availableWidth - width) + y: soundSlider.topPadding + soundSlider.availableHeight / 2 - height / 2 + implicitWidth: 16 + implicitHeight: 16 + radius: 8 + color: soundSlider.pressed ? Theme.background : Theme.primary + border.color: Theme.primary + border.width: 1 + } + } + } + } + } +} From 352c63689c3f8a1c1ec3fb56537e0388b61ccf71 Mon Sep 17 00:00:00 2001 From: corazon <99136079+corazon008@users.noreply.github.com> Date: Wed, 24 Jun 2026 01:26:44 +0200 Subject: [PATCH 3/5] Remove versions --- .../.config/quickshell/SidebarApp/BrightnessControls.qml | 8 ++++---- dotfiles/.config/quickshell/SidebarApp/SoundControls.qml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml b/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml index 12adf474a..9143c7ae3 100644 --- a/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml +++ b/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml @@ -1,8 +1,8 @@ import Quickshell import Quickshell.Io -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import qs.CustomTheme ColumnLayout { @@ -42,7 +42,7 @@ ColumnLayout { spacing: 15 Text { - text: "☀ " + (index + 1) + text: "☀ " color: Theme.primary font.family: "monospace" font.pixelSize: 18 diff --git a/dotfiles/.config/quickshell/SidebarApp/SoundControls.qml b/dotfiles/.config/quickshell/SidebarApp/SoundControls.qml index 86a2c43e6..7ae17d65d 100644 --- a/dotfiles/.config/quickshell/SidebarApp/SoundControls.qml +++ b/dotfiles/.config/quickshell/SidebarApp/SoundControls.qml @@ -1,8 +1,8 @@ import Quickshell import Quickshell.Io -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import qs.CustomTheme ColumnLayout { From 70289b3100958b424f556e60720f2753725185ab Mon Sep 17 00:00:00 2001 From: corazon <99136079+corazon008@users.noreply.github.com> Date: Wed, 24 Jun 2026 01:31:39 +0200 Subject: [PATCH 4/5] Add timer to avoid filling ddc queue --- .../quickshell/SidebarApp/BrightnessControls.qml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml b/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml index 9143c7ae3..c30a761ff 100644 --- a/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml +++ b/dotfiles/.config/quickshell/SidebarApp/BrightnessControls.qml @@ -68,8 +68,18 @@ ColumnLayout { } } + Timer { + id: brightnessTimer + interval: 50 // play with the delay if you want to make it more or less responsive, keep in mind that DDC/CI commands can be slow and you don't want to spam them too much + repeat: false + + onTriggered: { + Quickshell.execDetached(["bash", "-c", "~/.config/hypr/scripts/brightness.sh set-display " + (index + 1) + " " + Math.round(brightnessSlider.value)]); + } + } + onMoved: { - Quickshell.execDetached(["bash", "-c", "~/.config/hypr/scripts/brightness.sh set-display " + (index + 1) + " " + Math.round(value)]); + brightnessTimer.restart(); } background: Rectangle { From 821cc8fddf0e92505b39012152fcc0e21f1a6f43 Mon Sep 17 00:00:00 2001 From: corazon <99136079+corazon008@users.noreply.github.com> Date: Wed, 24 Jun 2026 01:39:30 +0200 Subject: [PATCH 5/5] Create brightness.sh --- dotfiles/.config/hypr/scripts/brightness.sh | 87 +++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 dotfiles/.config/hypr/scripts/brightness.sh diff --git a/dotfiles/.config/hypr/scripts/brightness.sh b/dotfiles/.config/hypr/scripts/brightness.sh new file mode 100644 index 000000000..2ba5354cd --- /dev/null +++ b/dotfiles/.config/hypr/scripts/brightness.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash + +get_mode() { + if ls /sys/class/backlight/* >/dev/null 2>&1; then + echo "backlight" + else + echo "ddc" + fi +} + +MODE=$(get_mode) + +case "$1" in + +displays) + if [ "$MODE" = "backlight" ]; then + echo 1 + else + ddcutil detect | grep "Display" | wc -l + fi +;; + +get) + if [ "$MODE" = "backlight" ]; then + brightnessctl -m | awk -F, '{gsub("%","",$4); print $4}' + else + ddcutil getvcp 10 | grep -oP 'current value =\s*\K\d+' | head -1 + fi +;; + +get-display) + if [ "$MODE" = "backlight" ]; then + brightnessctl -m | awk -F, '{gsub("%","",$4); print $4}' + else + ddcutil --display "$2" getvcp 10 | grep -oP 'current value =\s*\K\d+' + fi +;; + +set) + if [ "$MODE" = "backlight" ]; then + brightnessctl set "$2%" + else + for d in $(seq 1 $(ddcutil detect | grep Display | wc -l)); do + ddcutil --display "$d" setvcp 10 "$2" + done + fi +;; + +set-percentage) + if [ "$MODE" = "backlight" ]; then + brightnessctl set "$2%" + else + for d in $(seq 1 $(ddcutil detect | grep Display | wc -l)); do + current=$(ddcutil --display "$d" getvcp 10 | grep -oP 'current value =\s*\K\d+') + new=$((current + $2)) + + [ "$new" -gt 100 ] && new=100 + [ "$new" -lt 0 ] && new=0 + + ddcutil --display "$d" setvcp 10 "$new" + done + fi +;; + +set-display) + if [ "$MODE" = "backlight" ]; then + brightnessctl set "$3%" + else + ddcutil --display "$2" setvcp 10 "$3" + fi +;; + +set-display-percentage) + if [ "$MODE" = "backlight" ]; then + brightnessctl set "$3%" + else + delta="$3" + current=$(ddcutil --display "$2" getvcp 10 | grep -oP 'current value =\s*\K\d+') + new=$((current + delta)) + + [ "$new" -gt 100 ] && new=100 + [ "$new" -lt 0 ] && new=0 + + ddcutil --display "$2" setvcp 10 "$new" + fi + +esac