diff --git a/.config/quickshell/own/Bar.qml b/.config/quickshell/own/Bar.qml new file mode 100644 index 0000000..cf02bc1 --- /dev/null +++ b/.config/quickshell/own/Bar.qml @@ -0,0 +1,63 @@ +// Bar.qml - top panel +import Quickshell +import Quickshell.Wayland +import QtQuick +import QtQuick.Layouts +import "./modules" + +PanelWindow { + id: root + + WlrLayershell.namespace: "quickshell-bar" + WlrLayershell.layer: WlrLayer.Top + WlrLayershell.keyboardFocus: WlrKeyboardFocus.None + + anchors { + top: true + left: true + right: true + } + + margins { + left: 0 + right: 0 + bottom: 0 + top: 0 + } + + function setColorAlpha(color, alpha) { + return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha) + } + + implicitHeight: Theme.barHeight + Theme.barPadding * 2 + exclusiveZone: Theme.barHeight + Theme.barPadding * 2 + color: setColorAlpha(Theme.background, 0) + + RowLayout { + anchors.fill: parent + anchors.leftMargin: Theme.barPadding + anchors.topMargin: Theme.barPadding + anchors.bottomMargin: Theme.barPadding + anchors.rightMargin: Theme.barPadding + spacing: Theme.spacing + + // ─── LEFT ────────────────────────────────────────── + SysTrayWidget { parentWindow: root } + ClockWidget {} + WeatherWidget {} + WorkspacesWidget { screen: root.screen } + WindowTitleWidget { screen: root.screen } + + Item { Layout.fillWidth: true } + + // ─── RIGHT ───────────────────────────────────────── + MediaCavaWidget {} + MemoryWidget {} + CpuWidget {} + TemperatureWidget {} + BatteryWidget {} + //BluetoothWidget {} + PowerProfilesWidget {} + PowerMenuWidget {} + } +} diff --git a/.config/quickshell/own/Colors.qml b/.config/quickshell/own/Colors.qml new file mode 100644 index 0000000..510fb99 --- /dev/null +++ b/.config/quickshell/own/Colors.qml @@ -0,0 +1,27 @@ +// colors.qml - Generated by wallust +pragma Singleton +import Quickshell +import QtQuick + +Singleton { + readonly property color background: "#0E0E14" + readonly property color foreground: "#B6B6BC" + readonly property color cursor: "#769BBF" + + readonly property color color0: "#3A453E" + readonly property color color1: "#6A6C52" + readonly property color color2: "#42617B" + readonly property color color3: "#744246" + readonly property color color4: "#638D4F" + readonly property color color5: "#C26E26" + readonly property color color6: "#4380BA" + readonly property color color7: "#8E8E98" + readonly property color color8: "#64636A" + readonly property color color9: "#6A6C52" + readonly property color color10: "#42617B" + readonly property color color11: "#744246" + readonly property color color12: "#638D4F" + readonly property color color13: "#C26E26" + readonly property color color14: "#4380BA" + readonly property color color15: "#8E8E98" +} \ No newline at end of file diff --git a/.config/quickshell/own/Exec.qml b/.config/quickshell/own/Exec.qml new file mode 100644 index 0000000..c0644ce --- /dev/null +++ b/.config/quickshell/own/Exec.qml @@ -0,0 +1,23 @@ +// Exec.qml - process launcher +// Usage from any file: Exec.run(["kitty", "-e", "btop"]) +pragma Singleton +import Quickshell +import Quickshell.Io +import QtQuick + +Singleton { + id: root + + function run(cmd) { + const proc = procPool.createObject(root, { command: cmd }); + proc.running = true; + } + + Component { + id: procPool + Process { + running: false + onExited: destroy() + } + } +} diff --git a/.config/quickshell/own/GlobalStates.qml b/.config/quickshell/own/GlobalStates.qml new file mode 100644 index 0000000..026e773 --- /dev/null +++ b/.config/quickshell/own/GlobalStates.qml @@ -0,0 +1,23 @@ +// GlobalStates.qml - a place to store global state variables accessible from any QML file. +pragma Singleton +import Quickshell +import QtQuick + +Singleton { + id: root + + // Used by the merged overview module (own/modules/overview) — see own/modules/overview/CREDITS.md + property bool overviewOpen: false + + readonly property QtObject popups: QtObject { + property string active: "" + property real anchorX: 0 + + function open(name, ax) { popups.anchorX = ax ?? 0; popups.active = name } + function close() { popups.active = "" } + function toggle(name, ax) { + if (popups.active === name) { popups.active = "" } + else { popups.anchorX = ax ?? 0; popups.active = name } + } + } +} diff --git a/.config/quickshell/own/Pill.qml b/.config/quickshell/own/Pill.qml new file mode 100644 index 0000000..4432cf3 --- /dev/null +++ b/.config/quickshell/own/Pill.qml @@ -0,0 +1,39 @@ +// Pill.qml - styled module container +import QtQuick +import QtQuick.Layouts + +Rectangle { + id: root + + default property alias content: inner.data + + property bool hovered: mouseArea.containsMouse + signal clicked(var mouse) + signal scrolled(var wheel) + + property real leftPadding: Theme.pillPadH + property real rightPadding: Theme.pillPadH + implicitWidth: inner.implicitWidth + leftPadding + rightPadding + implicitHeight: Theme.barHeight + radius: Theme.radius + color: hovered ? Theme.pillHover : Theme.pill + + Behavior on color { ColorAnimation { duration: 150 } } + + RowLayout { + id: inner + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: root.leftPadding + spacing: 4 + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton + onClicked: (m) => root.clicked(m) + onWheel: (w) => root.scrolled(w) + } +} diff --git a/.config/quickshell/own/Popup.qml b/.config/quickshell/own/Popup.qml new file mode 100644 index 0000000..fe9cf08 --- /dev/null +++ b/.config/quickshell/own/Popup.qml @@ -0,0 +1,109 @@ +// Popup.qml - a reusable popup component for Quickshell. +import Quickshell +import Quickshell.Wayland +import QtQuick + +PanelWindow { + id: root + + required property var screen + required property string popupName + + property int rightMargin: 10 + property int topMargin: 1 + property int autoHideDelay: Theme.popupAutoHideDelay + + default property alias content: contentItem.data + + // ── Visibility ──────────────────────────────────────────── + property bool logicalOpen: GlobalStates.popups.active === popupName + property bool _keepVisible: false + + visible: logicalOpen || _keepVisible + + onLogicalOpenChanged: { + if (logicalOpen) { + closeTimer.stop() + _keepVisible = false + openY.start() + openOpacity.start() + } else { + hideTimer.stop() + _keepVisible = true + closeY.start() + closeOpacity.start() + closeTimer.restart() + } + } + + // Keeps the Overlay window alive for the duration of the close animation + Timer { + id: closeTimer + interval: 280 + onTriggered: root._keepVisible = false + } + + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.namespace: "quickshell-popup-" + popupName + WlrLayershell.keyboardFocus: WlrKeyboardFocus.None + + anchors { top: true; left: true; right: true; bottom: true } + color: Qt.rgba(0, 0, 0, 0) + + Timer { + id: hideTimer + interval: root.autoHideDelay + repeat: false + onTriggered: GlobalStates.popups.close() + } + + MouseArea { + anchors.fill: parent + onClicked: GlobalStates.popups.close() + } + + // ── Slide animations ────────────────────────────────────── + NumberAnimation { id: openY; target: box; property: "y"; to: root.topMargin; duration: 250; easing.type: Easing.OutCubic } + NumberAnimation { id: closeY; target: box; property: "y"; to: root.topMargin - 200; duration: 200; easing.type: Easing.InCubic } + NumberAnimation { id: openOpacity; target: box; property: "opacity"; to: Theme.popupOpacity; duration: 200 } + NumberAnimation { id: closeOpacity;target: box; property: "opacity"; to: 0.0; duration: 200 } + + // ── Popup box ───────────────────────────────────────────── + Rectangle { + id: box + + x: { + var ax = GlobalStates.popups.anchorX + var centered = ax > 0 ? ax - width / 2 : parent.width - width - root.rightMargin + return Math.max(4, Math.min(parent.width - width - 4, centered)) + } + + // Initial state: closed (above the bar, transparent) + y: root.topMargin - 40 + opacity: 0.0 + + width: contentItem.implicitWidth + 10 + height: contentItem.implicitHeight + 10 + + color: Theme.popupBackground + radius: Theme.radius * 2 + border.color: Theme.popupBorderColor + border.width: Theme.popupBorderWidth + + // Absorb clicks so the outer close-on-click doesn't fire inside the box + MouseArea { anchors.fill: parent } + + // HoverHandler doesn't lose hover when a child MouseArea grabs a press, + // so clicking buttons won't accidentally start the hide timer. + HoverHandler { + onHoveredChanged: hovered ? hideTimer.stop() : hideTimer.start() + } + + Item { + id: contentItem + x: 5; y: 5 + implicitWidth: childrenRect.width + implicitHeight: childrenRect.height + } + } +} diff --git a/.config/quickshell/own/README b/.config/quickshell/own/README new file mode 100644 index 0000000..78bc3d9 --- /dev/null +++ b/.config/quickshell/own/README @@ -0,0 +1,7 @@ +Wallpaper switcher: echo 1 > /tmp/qs-wallpaper-ipc +In Hyprland: ctrl t + +Workspace overview: qs ipc -c own call overview toggle +Merged from Shanu-Kumawat/quickshell-overview (originally extracted from +end-4/dots-hyprland). See modules/overview/CREDITS.md for details and +the untouched upstream clone at ../overview. \ No newline at end of file diff --git a/.config/quickshell/own/Theme.qml b/.config/quickshell/own/Theme.qml new file mode 100644 index 0000000..560fb94 --- /dev/null +++ b/.config/quickshell/own/Theme.qml @@ -0,0 +1,60 @@ +// Theme.qml - global palette & dimensions +// QuickShell auto-discovers this; access from any file as `Theme.colorN` etc. +pragma Singleton +import Quickshell +import QtQuick + +Singleton { + + function setColorAlpha(color, alpha) { + return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha) + } + + // ── Wallust palette ────────────────────────────────────── + readonly property color background: Colors.foreground + readonly property color foreground: Colors.background + readonly property color color0: Colors.color0 + readonly property color color1: Colors.color1 + readonly property color color2: Colors.color2 + readonly property color color3: Colors.color3 + readonly property color color4: Colors.color4 + readonly property color color5: Colors.color5 + readonly property color color6: Colors.color6 + readonly property color color7: Colors.color7 + + readonly property color color8: Colors.color8 + // ── Derived / semantic ──────────────────────────────────── + readonly property color pill: setColorAlpha(Colors.background, 0.8) + readonly property color pillText: setColorAlpha(Colors.foreground, 1) + readonly property color pillHover: color2 + readonly property color wsActive: color3 + readonly property color wsUrgent: color1 + + // ── Typography ──────────────────────────────────────────── + readonly property string fontSans: "Fira Sans Condensed" + readonly property string fontMono: "FiraCode Nerd Font" + readonly property int fontSize: 11 + readonly property int fontSizeSecondary: 10 + + // ── Bar geometry ───────────────────────────────────────── + readonly property int barHeight: 24 + readonly property int barPadding: 2 + readonly property int radius: 5 + readonly property int pillPadH: 10 + readonly property int spacing: 4 + + // ── Popup ─────────────────────────────────────────────── + readonly property color popupBackground: setColorAlpha(Colors.background, 0.75) + readonly property int popupBorderWidth: 0 + readonly property color popupBorderColor: setColorAlpha(Colors.foreground, 0.1) + readonly property int popupPadding: 10 + readonly property double popupOpacity: 0.7 + + // ── Animations ─────────────────────────────────────────── + readonly property int cavaDissapearTime: 500 + readonly property int workspaceSlideTime: 250 + readonly property int popupAutoHideDelay: 500 + + // ── Other constants ─────────────────────────────────────── + readonly property int titleLength: 75 +} diff --git a/.config/quickshell/own/modules/WallpaperPopup.qml b/.config/quickshell/own/modules/WallpaperPopup.qml index 17e239d..1a407ea 100644 --- a/.config/quickshell/own/modules/WallpaperPopup.qml +++ b/.config/quickshell/own/modules/WallpaperPopup.qml @@ -1,5 +1,6 @@ // WallpaperPopup.qml - A popup for browsing and setting wallpapers from /usr/share/wallpapers import QtQuick +import QtQuick.Controls import Quickshell import Quickshell.Io import Quickshell.Wayland @@ -116,9 +117,15 @@ PanelWindow { GridView { id: grid - anchors { fill: parent; margins: 8 } + anchors { + fill: parent + leftMargin: 8 + topMargin: 8 + rightMargin: 8 + bottomMargin: 8 + } clip: true - cellWidth: Math.floor(width / 2) + cellWidth: Math.floor((width - 12) / 2) cellHeight: 104 focus: true keyNavigationEnabled: true @@ -136,6 +143,30 @@ PanelWindow { model: wallpaperModel + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AsNeeded + width: 12 + anchors { + rightMargin: 0 + topMargin: 4 + bottomMargin: 4 + } + + background: Rectangle { + implicitWidth: 12 + radius: 6 + color: Theme.accent ?? Theme.pillText + opacity: 0.1 + } + + contentItem: Rectangle { + implicitWidth: 6 + radius: 3 + color: Theme.accent ?? Theme.pillText + opacity: parent.pressed ? 1.0 : 0.7 + } + } + highlight: Rectangle { z: 2 radius: Theme.radius + 1 diff --git a/.config/quickshell/own/shell.qml b/.config/quickshell/own/shell.qml new file mode 100644 index 0000000..56923a5 --- /dev/null +++ b/.config/quickshell/own/shell.qml @@ -0,0 +1,39 @@ +// shell.qml - entry point +//@ pragma UseQApplication +import Quickshell +import "./modules" +import "./modules/overview" + +ShellRoot { + Variants { + model: Quickshell.screens + Bar { + required property var modelData + screen: modelData + } + } + Variants { + model: Quickshell.screens + PowerMenuPopup { + required property var modelData + screen: modelData + } + } + + Variants { + model: Quickshell.screens + MediaPopup { + required property var modelData + screen: modelData + } + } + + WallpaperPopup { + screen: Quickshell.screens[0] + } + + // Workspace overview (SUPER+TAB-style popup) — merged from ./overview, + // see modules/overview/CREDITS.md for attribution. + Overview {} + +}