From 58980959aa4e3604b992d90eaa25b218f7a1e288 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:45:38 +0100 Subject: [PATCH 01/12] init waffles --- .../ii/assets/icons/fluent/speaker-0.svg | 12 +++ .../ii/assets/icons/fluent/speaker-1.svg | 12 +++ .../ii/assets/icons/fluent/speaker.svg | 6 ++ .../quickshell/ii/modules/common/Config.qml | 8 ++ .../background/widgets/clock/ClockWidget.qml | 2 +- .../quickshell/ii/modules/ii/bar/Bar.qml | 18 ++-- .../ii/modules/ii/bar/ClockWidget.qml | 2 +- .../modules/ii/overlay/OverlayBackground.qml | 2 +- .../ii/modules/waffle/bar/BarButton.qml | 78 ++++++++++++++++ .../ii/modules/waffle/bar/SystemButton.qml | 25 ++++++ .../ii/modules/waffle/bar/TimeButton.qml | 30 +++++++ .../ii/modules/waffle/bar/WaffleBar.qml | 89 +++++++++++++++++++ .../modules/waffle/bar/WaffleBarContent.qml | 46 ++++++++++ .../ii/modules/waffle/looks/FluentIcon.qml | 17 ++++ .../ii/modules/waffle/looks/Looks.qml | 77 ++++++++++++++++ .../ii/modules/waffle/looks/WText.qml | 15 ++++ .../quickshell/ii/services/DateTime.qml | 3 +- dots/.config/quickshell/ii/shell.qml | 35 ++++++++ 18 files changed, 463 insertions(+), 14 deletions(-) create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/speaker-0.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/speaker-1.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/speaker.svg create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/looks/WText.qml diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/speaker-0.svg b/dots/.config/quickshell/ii/assets/icons/fluent/speaker-0.svg new file mode 100644 index 000000000..0ff116afd --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/speaker-0.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_speaker_0_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/speaker-1.svg b/dots/.config/quickshell/ii/assets/icons/fluent/speaker-1.svg new file mode 100644 index 000000000..eff9b6d0c --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/speaker-1.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_speaker_1_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/speaker.svg b/dots/.config/quickshell/ii/assets/icons/fluent/speaker.svg new file mode 100644 index 000000000..477b04792 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/speaker.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 1b13540ef..ffc67805a 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -80,6 +80,7 @@ Singleton { property list enabledPanels: [ "iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector" ] + property string panelFamily: "ii" // "ii", "w" property JsonObject policies: JsonObject { property int ai: 1 // 0: No | 1: Yes | 2: Local @@ -521,6 +522,7 @@ Singleton { // https://doc.qt.io/qt-6/qtime.html#toString property string format: "hh:mm" property string shortDateFormat: "dd/MM" + property string dateWithYearFormat: "dd/MM/yyyy" property string dateFormat: "ddd, dd/MM" property JsonObject pomodoro: JsonObject { property int breakTime: 300 @@ -555,6 +557,12 @@ Singleton { property list linkKeywords: ["hentai", "porn", "sukebei", "hitomi.la", "rule34", "gelbooru", "fanbox", "dlsite"] } } + + property JsonObject waffles: JsonObject { + property JsonObject bar: JsonObject { + property bool bottom: true + } + } } } } diff --git a/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockWidget.qml b/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockWidget.qml index cf8c739e0..c5803b6e2 100644 --- a/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockWidget.qml +++ b/dots/.config/quickshell/ii/modules/ii/background/widgets/clock/ClockWidget.qml @@ -70,7 +70,7 @@ AbstractBackgroundWidget { } ClockText { Layout.topMargin: -5 - text: DateTime.date + text: DateTime.longDate } StyledText { // Somehow gets fucked up if made a ClockText??? diff --git a/dots/.config/quickshell/ii/modules/ii/bar/Bar.qml b/dots/.config/quickshell/ii/modules/ii/bar/Bar.qml index 74f8b5f1b..71a64d76d 100644 --- a/dots/.config/quickshell/ii/modules/ii/bar/Bar.qml +++ b/dots/.config/quickshell/ii/modules/ii/bar/Bar.qml @@ -14,12 +14,14 @@ Scope { Variants { // For each monitor - model: { - const screens = Quickshell.screens; - const list = Config.options.bar.screenList; - if (!list || list.length === 0) - return screens; - return screens.filter(screen => list.includes(screen.name)); + model: ScriptModel { + values: { + const screens = Quickshell.screens; + const list = Config.options.bar.screenList; + if (!list || list.length === 0) + return screens; + return screens.filter(screen => list.includes(screen.name)); + } } LazyLoader { id: barLoader @@ -29,10 +31,6 @@ Scope { id: barRoot screen: barLoader.modelData - property var brightnessMonitor: Brightness.getMonitorForScreen(barLoader.modelData) - property real useShortenedForm: (Appearance.sizes.barHellaShortenScreenWidthThreshold >= screen.width) ? 2 : (Appearance.sizes.barShortenScreenWidthThreshold >= screen.width) ? 1 : 0 - readonly property int centerSideModuleWidth: (useShortenedForm == 2) ? Appearance.sizes.barCenterSideModuleWidthHellaShortened : (useShortenedForm == 1) ? Appearance.sizes.barCenterSideModuleWidthShortened : Appearance.sizes.barCenterSideModuleWidth - Timer { id: showBarTimer interval: (Config?.options.bar.autoHide.showWhenPressingSuper.delay ?? 100) diff --git a/dots/.config/quickshell/ii/modules/ii/bar/ClockWidget.qml b/dots/.config/quickshell/ii/modules/ii/bar/ClockWidget.qml index 895ad9be0..958695a86 100644 --- a/dots/.config/quickshell/ii/modules/ii/bar/ClockWidget.qml +++ b/dots/.config/quickshell/ii/modules/ii/bar/ClockWidget.qml @@ -33,7 +33,7 @@ Item { visible: root.showDate font.pixelSize: Appearance.font.pixelSize.small color: Appearance.colors.colOnLayer1 - text: DateTime.date + text: DateTime.longDate } } diff --git a/dots/.config/quickshell/ii/modules/ii/overlay/OverlayBackground.qml b/dots/.config/quickshell/ii/modules/ii/overlay/OverlayBackground.qml index 205307cab..d91e4cbba 100644 --- a/dots/.config/quickshell/ii/modules/ii/overlay/OverlayBackground.qml +++ b/dots/.config/quickshell/ii/modules/ii/overlay/OverlayBackground.qml @@ -4,5 +4,5 @@ import qs.modules.common Rectangle { id: contentItem anchors.fill: parent - color: Appearance.m3colors.m3surfaceContainer + color: Appearance.colors.colSurfaceContainer } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml new file mode 100644 index 000000000..1ea789fcb --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml @@ -0,0 +1,78 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import qs.modules.common +import qs.modules.common.functions +import qs.modules.waffle.looks + +Button { + id: root + + Layout.fillHeight: true + topInset: 4 + bottomInset: 4 + + property color borderColor: ColorUtils.transparentize(Looks.colors.bg1Border, (root.hovered && !root.down) ? Looks.fluentContentTransparency : 1) + Behavior on borderColor { + animation: Looks.transition.color.createObject(this) + } + onBorderColorChanged: { + borderCanvas.requestPaint(); + } + + background: Rectangle { + id: background + color: { + if (root.down) { + return Looks.colors.bg1Active + } else if (root.hovered) { + return Looks.colors.bg1Hover + } else { + return ColorUtils.transparentize(Looks.colors.bg1) + } + } + radius: Looks.radius.medium + Behavior on color { + animation: Looks.transition.color.createObject(this) + } + + // Top 1px border with color + Canvas { + id: borderCanvas + anchors.fill: parent + onPaint: { + var ctx = getContext("2d"); + ctx.clearRect(0, 0, width, height); + + var borderColor = root.borderColor; + + var r = background.radius; + var fadeLength = Math.max(1, r); + var fadeLengthPercent = fadeLength / width; + + // Compute normalized stops + var leftFadeStop = fadeLengthPercent; + var rightFadeStop = 1 - fadeLengthPercent; + + var grad = ctx.createLinearGradient(0, 0, width, 0); + grad.addColorStop(0, Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0)); + grad.addColorStop(leftFadeStop, borderColor); + grad.addColorStop(rightFadeStop, borderColor); + grad.addColorStop(1, Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0)); + + ctx.strokeStyle = grad; + ctx.lineWidth = 1; + + ctx.beginPath(); + ctx.moveTo(r, 0.5); + ctx.lineTo(width - r, 0.5); + // Top-right curve + ctx.arcTo(width, 0.5, width, r + 0.5, r); + // Top-left curve + ctx.moveTo(width - r, 0.5); + ctx.arcTo(0, 0.5, 0, r + 0.5, r); + ctx.stroke(); + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml new file mode 100644 index 000000000..107bb00f6 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml @@ -0,0 +1,25 @@ +import QtQuick +import QtQuick.Layouts +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +BarButton { + id: root + + // padding: 12 + + contentItem: Item { + anchors.centerIn: root.background + implicitHeight: column.implicitHeight + implicitWidth: column.implicitWidth + Row { + id: column + anchors.centerIn: parent + + FluentIcon { + icon: "speaker" // System icon + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml new file mode 100644 index 000000000..53177da12 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml @@ -0,0 +1,30 @@ +import QtQuick +import QtQuick.Layouts +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +BarButton { + id: root + + rightInset: 12 // For now this is the rightmost button. Desktop peek is useless. (for now) + padding: 12 + + contentItem: Item { + anchors.centerIn: root.background + implicitHeight: column.implicitHeight + implicitWidth: column.implicitWidth + Column { + id: column + anchors.centerIn: parent + WText { + anchors.right: parent.right + text: DateTime.time + } + WText { + anchors.right: parent.right + text: DateTime.date + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml new file mode 100644 index 000000000..241b5e66b --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml @@ -0,0 +1,89 @@ +import QtQuick +import Quickshell +import Quickshell.Io +import Quickshell.Wayland +import Quickshell.Hyprland +import qs +import qs.services +import qs.modules.common +import qs.modules.common.widgets + +Scope { + id: bar + property bool showBarBackground: Config.options.bar.showBackground + + LazyLoader { + id: barLoader + active: GlobalStates.barOpen && !GlobalStates.screenLocked + component: Variants { + model: Quickshell.screens + delegate: PanelWindow { // Bar window + id: barRoot + required property var modelData + screen: modelData + exclusionMode: ExclusionMode.Ignore + exclusiveZone: implicitHeight + WlrLayershell.namespace: "quickshell:wbar" + + anchors { + left: true + right: true + bottom: Config.options.waffles.bar.bottom + top: !Config.options.waffles.bar.bottom + } + + color: "transparent" + implicitHeight: content.implicitHeight + implicitWidth: content.implicitWidth + + WaffleBarContent { + id: content + anchors.fill: parent + } + } + } + } + + IpcHandler { + target: "bar" + + function toggle(): void { + GlobalStates.barOpen = !GlobalStates.barOpen + } + + function close(): void { + GlobalStates.barOpen = false + } + + function open(): void { + GlobalStates.barOpen = true + } + } + + GlobalShortcut { + name: "barToggle" + description: "Toggles bar on press" + + onPressed: { + GlobalStates.barOpen = !GlobalStates.barOpen; + } + } + + GlobalShortcut { + name: "barOpen" + description: "Opens bar on press" + + onPressed: { + GlobalStates.barOpen = true; + } + } + + GlobalShortcut { + name: "barClose" + description: "Closes bar on press" + + onPressed: { + GlobalStates.barOpen = false; + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml new file mode 100644 index 000000000..a2119ddde --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml @@ -0,0 +1,46 @@ +import QtQuick +import QtQuick.Layouts +import qs.modules.common +import qs.modules.waffle.looks + +Rectangle { + id: root + + color: Looks.colors.bg0 + implicitHeight: 48 + + Rectangle { + id: border + anchors { + left: parent.left + right: parent.right + top: Config.options.waffles.bar.bottom ? parent.top : undefined + bottom: Config.options.waffles.bar.bottom ? undefined : parent.bottom + } + color: Looks.colors.bg0Border + implicitHeight: 1 + } + + BarGroupRow { + id: bloatRow + anchors.left: parent.left + } + + BarGroupRow { + id: appsRow + anchors.horizontalCenter: parent.horizontalCenter + } + + BarGroupRow { + id: systemRow + anchors.right: parent.right + SystemButton {} + TimeButton {} + } + + component BarGroupRow: RowLayout { + anchors.top: parent.top + anchors.bottom: parent.bottom + spacing: 0 + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml b/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml new file mode 100644 index 000000000..892214cd7 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml @@ -0,0 +1,17 @@ +import QtQuick +import org.kde.kirigami as Kirigami +import qs.modules.common +import qs.modules.waffle.looks + +Kirigami.Icon { + id: root + required property string icon + property int implicitSize: 18 // Should be 16, but it appears the icons have some padding + implicitWidth: implicitSize + implicitHeight: implicitSize + + roundToIconSize: false + color: Looks.colors.fg + isMask: true + source: `${Looks.iconsPath}/${root.icon}.svg` +} diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml new file mode 100644 index 000000000..3b451935f --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml @@ -0,0 +1,77 @@ +pragma ComponentBehavior: Bound +pragma Singleton + +import QtQuick +import Quickshell +import qs.modules.common +import qs.modules.common.functions + +Singleton { + id: root + property QtObject colors + property QtObject radius + property QtObject font + property QtObject transition + property string iconsPath: `${Directories.assetsPath}/icons/fluent` + + property real fluentBackgroundTransparency: 0.17 + property real fluentContentTransparency: 0.3 + colors: QtObject { + id: colors + property color bg0: "#1C1C1C" + property color bg0Border: "#404040" + property color bg1: "#2E2E2E" + property color bg1Hover: "#292929" + property color bg1Active: "#252525" + property color bg1Border: "#333333" + property color fg: "#FFFFFF" + property color brand: Appearance.m3colors.m3primary + } + + radius: QtObject { + id: radius + property int none: 0 + property int small: 2 + property int medium: 4 + property int large: 8 + property int xLarge: 12 + } + + font: QtObject { + id: font + property QtObject family: QtObject { + property string ui: "Noto Sans" + } + property QtObject weight: QtObject { + property int regular: Font.Normal + property int strong: Font.DemiBold + property int stronger: Font.Bold + } + property QtObject variableAxes: QtObject { + + } + property QtObject pixelSize: QtObject { + property int small: 10 + property int normal: 11 + } + } + + transition: QtObject { + id: transition + property QtObject easing: QtObject { + property QtObject bezierCurve: QtObject { + readonly property list easeInOut: [0.42,0.00,0.58,1.00] + readonly property list easeIn: [0,1,1,1] + readonly property list easeOut: [1,0,1,1] + } + } + + property Component color: Component { + ColorAnimation { + duration: 80 + easing.type: Easing.BezierSpline + easing.bezierCurve: transition.easing.bezierCurve.easeInOut + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/WText.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WText.qml new file mode 100644 index 000000000..240fd63be --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/looks/WText.qml @@ -0,0 +1,15 @@ +import QtQuick + +Text { + id: root + + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + color: Looks.colors.fg + + font { + family: Looks.font.family.ui + pixelSize: Looks.font.pixelSize.normal + weight: Looks.font.weight.regular + } +} diff --git a/dots/.config/quickshell/ii/services/DateTime.qml b/dots/.config/quickshell/ii/services/DateTime.qml index 62d296dbc..514da212b 100644 --- a/dots/.config/quickshell/ii/services/DateTime.qml +++ b/dots/.config/quickshell/ii/services/DateTime.qml @@ -20,7 +20,8 @@ Singleton { } property string time: Qt.locale().toString(clock.date, Config.options?.time.format ?? "hh:mm") property string shortDate: Qt.locale().toString(clock.date, Config.options?.time.shortDateFormat ?? "dd/MM") - property string date: Qt.locale().toString(clock.date, Config.options?.time.dateFormat ?? "dddd, dd/MM") + property string date: Qt.locale().toString(clock.date, Config.options?.time.dateWithYearFormat ?? "dd/MM/yyyy") + property string longDate: Qt.locale().toString(clock.date, Config.options?.time.dateFormat ?? "dddd, dd/MM") property string collapsedCalendarFormat: Qt.locale().toString(clock.date, "dd MMMM yyyy") property string uptime: "0h, 0m" diff --git a/dots/.config/quickshell/ii/shell.qml b/dots/.config/quickshell/ii/shell.qml index ee2217bf7..a23c84cca 100644 --- a/dots/.config/quickshell/ii/shell.qml +++ b/dots/.config/quickshell/ii/shell.qml @@ -28,12 +28,18 @@ import qs.modules.ii.overlay import qs.modules.ii.verticalBar import qs.modules.ii.wallpaperSelector +import qs.modules.waffle.bar + import QtQuick import QtQuick.Window import Quickshell +import Quickshell.Io +import Quickshell.Hyprland import qs.services ShellRoot { + id: root + // Force initialization of some singletons Component.onCompleted: { MaterialThemeLoader.reapplyTheme() @@ -67,11 +73,40 @@ ShellRoot { PanelLoader { identifier: "iiSidebarRight"; component: SidebarRight {} } PanelLoader { identifier: "iiVerticalBar"; extraCondition: Config.options.bar.vertical; component: VerticalBar {} } PanelLoader { identifier: "iiWallpaperSelector"; component: WallpaperSelector {} } + PanelLoader { identifier: "wBar"; component: WaffleBar {} } component PanelLoader: LazyLoader { required property string identifier property bool extraCondition: true active: Config.ready && Config.options.enabledPanels.includes(identifier) && extraCondition } + + // Panel families + property list families: ["ii", "waffle"] + property var panelFamilies: ({ + "ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"], + "waffle": ["wBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiWallpaperSelector"], + }) + function cyclePanelFamily() { + const currentIndex = families.indexOf(Config.options.panelFamily) + const nextIndex = (currentIndex + 1) % families.length + Config.options.panelFamily = families[nextIndex] + Config.options.enabledPanels = panelFamilies[Config.options.panelFamily] + } + + IpcHandler { + target: "panelFamily" + + function cycle(): void { + root.cyclePanelFamily() + } + } + + GlobalShortcut { + name: "panelFamilyCycle" + description: "Cycles panel family" + + onPressed: root.cyclePanelFamily() + } } From 42919c59ec616012c7a5d755d7ee05abfa44daab Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:36:08 +0100 Subject: [PATCH 02/12] wbar: add volume and battery icons --- .../ii/assets/icons/fluent/battery-1.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-2.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-3.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-4.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-5.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-7.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-8.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-9.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-charge.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-full.svg | 12 +++++++ .../ii/assets/icons/fluent/battery-saver.svg | 12 +++++++ .../assets/icons/fluent/battery-warning.svg | 12 +++++++ .../icons/fluent/bluetooth-connected.svg | 12 +++++++ .../icons/fluent/bluetooth-searching.svg | 12 +++++++ .../ii/assets/icons/fluent/ethernet.svg | 12 +++++++ .../ii/assets/icons/fluent/mic-on.svg | 12 +++++++ .../ii/assets/icons/fluent/speaker-none.svg | 5 +++ .../ii/assets/icons/fluent/speaker-off.svg | 7 +++++ .../ii/assets/icons/fluent/wifi-1.svg | 12 +++++++ .../ii/assets/icons/fluent/wifi-2.svg | 12 +++++++ .../ii/assets/icons/fluent/wifi-3.svg | 12 +++++++ .../ii/assets/icons/fluent/wifi-4.svg | 12 +++++++ .../ii/assets/icons/fluent/wifi-off.svg | 1 + .../ii/assets/icons/fluent/wifi-warning.svg | 1 + .../ii/modules/waffle/bar/SystemButton.qml | 21 ++++++++++++- .../ii/modules/waffle/looks/FluentIcon.qml | 7 +++-- .../ii/modules/waffle/looks/Looks.qml | 10 ++---- .../ii/modules/waffle/looks/WIcons.qml | 31 +++++++++++++++++++ 28 files changed, 313 insertions(+), 10 deletions(-) create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-1.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-2.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-3.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-4.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-5.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-7.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-8.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-9.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-charge.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-full.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-saver.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-warning.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/bluetooth-connected.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/bluetooth-searching.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/ethernet.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/mic-on.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/speaker-none.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/speaker-off.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/wifi-1.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/wifi-2.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/wifi-3.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/wifi-4.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/wifi-off.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/wifi-warning.svg create mode 100644 dots/.config/quickshell/ii/modules/waffle/looks/WIcons.qml diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-1.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-1.svg new file mode 100644 index 000000000..caa369c58 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-1.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_1_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-2.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-2.svg new file mode 100644 index 000000000..b939043ea --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-2.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_2_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-3.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-3.svg new file mode 100644 index 000000000..a504a1ed5 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-3.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_3_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-4.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-4.svg new file mode 100644 index 000000000..6567ddf10 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-4.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_4_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-5.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-5.svg new file mode 100644 index 000000000..1bf4d914f --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-5.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_5_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-7.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-7.svg new file mode 100644 index 000000000..a5197ce94 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-7.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_7_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-8.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-8.svg new file mode 100644 index 000000000..c83bc5fb6 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-8.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_8_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-9.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-9.svg new file mode 100644 index 000000000..7f4937b99 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-9.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_9_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-charge.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-charge.svg new file mode 100644 index 000000000..512a78b1b --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-charge.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_charge_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-full.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-full.svg new file mode 100644 index 000000000..4749fc178 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-full.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_full_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-saver.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-saver.svg new file mode 100644 index 000000000..397061caf --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-saver.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_saver_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-warning.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-warning.svg new file mode 100644 index 000000000..7ccade277 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-warning.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_warning_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/bluetooth-connected.svg b/dots/.config/quickshell/ii/assets/icons/fluent/bluetooth-connected.svg new file mode 100644 index 000000000..b491276df --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/bluetooth-connected.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_bluetooth_connected_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/bluetooth-searching.svg b/dots/.config/quickshell/ii/assets/icons/fluent/bluetooth-searching.svg new file mode 100644 index 000000000..e0d9eab70 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/bluetooth-searching.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_bluetooth_searching_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/ethernet.svg b/dots/.config/quickshell/ii/assets/icons/fluent/ethernet.svg new file mode 100644 index 000000000..904d9720e --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/ethernet.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_cellular_data_1_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/mic-on.svg b/dots/.config/quickshell/ii/assets/icons/fluent/mic-on.svg new file mode 100644 index 000000000..3f680d2e3 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/mic-on.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_mic_on_48_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/speaker-none.svg b/dots/.config/quickshell/ii/assets/icons/fluent/speaker-none.svg new file mode 100644 index 000000000..364af84cb --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/speaker-none.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/speaker-off.svg b/dots/.config/quickshell/ii/assets/icons/fluent/speaker-off.svg new file mode 100644 index 000000000..5fa19e406 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/speaker-off.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/wifi-1.svg b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-1.svg new file mode 100644 index 000000000..47662e101 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-1.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_wifi_1_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/wifi-2.svg b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-2.svg new file mode 100644 index 000000000..9897c5d70 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-2.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_wifi_2_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/wifi-3.svg b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-3.svg new file mode 100644 index 000000000..8a4674bd4 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-3.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_wifi_3_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/wifi-4.svg b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-4.svg new file mode 100644 index 000000000..f14828bd8 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-4.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_wifi_4_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/wifi-off.svg b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-off.svg new file mode 100644 index 000000000..3c247ab12 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/wifi-warning.svg b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-warning.svg new file mode 100644 index 000000000..d573ddde0 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/wifi-warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml index 107bb00f6..dcb56c30b 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml @@ -16,9 +16,28 @@ BarButton { Row { id: column anchors.centerIn: parent + spacing: 4 FluentIcon { - icon: "speaker" // System icon + icon: WIcons.internetIcon + } + + FluentIcon { + icon: { + const muted = Audio.sink?.audio.muted ?? false; + const volume = Audio.sink?.audio.volume ?? 0; + if (muted) return volume > 0 ? "speaker-off" : "speaker-none"; + if (volume == 0) return "speaker-none"; + if (volume < 0.5) return "speaker-1"; + return "speaker"; + } + } + + FluentIcon { + icon: { + print(WIcons.batteryIcon) + return WIcons.batteryIcon + } } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml b/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml index 892214cd7..229df0458 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml @@ -6,12 +6,15 @@ import qs.modules.waffle.looks Kirigami.Icon { id: root required property string icon - property int implicitSize: 18 // Should be 16, but it appears the icons have some padding + // Should be 16, but it appears the icons have some padding, + // Unlike the Windows-only Segoe UI icons, the open source FluentUI ones are hella small + property int implicitSize: 20 implicitWidth: implicitSize implicitHeight: implicitSize + source: `${Looks.iconsPath}/${root.icon}.svg` roundToIconSize: false color: Looks.colors.fg isMask: true - source: `${Looks.iconsPath}/${root.icon}.svg` + animated: true } diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml index 3b451935f..9020b9d85 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml @@ -42,17 +42,13 @@ Singleton { property QtObject family: QtObject { property string ui: "Noto Sans" } - property QtObject weight: QtObject { - property int regular: Font.Normal + property QtObject weight: QtObject { // Noto is not Segoe, so we might use slightly different weights + property int regular: Font.Medium property int strong: Font.DemiBold property int stronger: Font.Bold - } - property QtObject variableAxes: QtObject { - } property QtObject pixelSize: QtObject { - property int small: 10 - property int normal: 11 + property real normal: 11 } } diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/WIcons.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WIcons.qml new file mode 100644 index 000000000..813b0a1ce --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/looks/WIcons.qml @@ -0,0 +1,31 @@ +pragma Singleton +import QtQuick +import Quickshell +import qs.services + +Singleton { + id: root + + property string internetIcon: { + if (Network.ethernet) return "ethernet"; + if (Network.wifiEnabled) { + const strength = Network.networkStrength; + if (strength > 75) return "wifi-1"; + if (strength > 50) return "wifi-2"; + if (strength > 25) return "wifi-3"; + return "wifi-4"; + } + if (Network.wifiStatus === "connecting") return "wifi-4"; + if (Network.wifiStatus === "disconnected") return "wifi-off"; + if (Network.wifiStatus === "disabled") return "wifi-off"; + return "wifi-warning"; + } + + property string batteryIcon: { + if (Battery.isCharging) return "battery-charge"; + if (Battery.isCriticalAndNotCharging) return "battery-warning"; + if (Battery.percentage >= 0.9) return "battery-full"; + return `battery-${Math.ceil(Battery.percentage * 10)}`; + } + +} From 694eaccfbfeee9118853716867ef92594393a8bd Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 10 Nov 2025 22:48:04 +0100 Subject: [PATCH 03/12] add start and search icons --- .../ii/assets/icons/fluent/battery-0.svg | 12 +++ .../ii/assets/icons/fluent/battery-6.svg | 12 +++ .../icons/fluent/system-search-dark.svg | 82 +++++++++++++++++++ .../icons/fluent/system-search-light.svg | 82 +++++++++++++++++++ .../quickshell/ii/modules/common/Config.qml | 1 + .../ii/modules/waffle/bar/AppButton.qml | 40 +++++++++ .../ii/modules/waffle/bar/SearchButton.qml | 12 +++ .../ii/modules/waffle/bar/StartButton.qml | 13 +++ .../ii/modules/waffle/bar/SystemButton.qml | 5 +- .../modules/waffle/bar/WaffleBarContent.qml | 24 ++++-- .../ii/modules/waffle/looks/FluentIcon.qml | 1 + .../ii/modules/waffle/looks/Looks.qml | 33 ++++++++ 12 files changed, 308 insertions(+), 9 deletions(-) create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-0.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/battery-6.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/system-search-dark.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/system-search-light.svg create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-0.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-0.svg new file mode 100644 index 000000000..7fe9d7a3d --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-0.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_0_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/battery-6.svg b/dots/.config/quickshell/ii/assets/icons/fluent/battery-6.svg new file mode 100644 index 000000000..145d9a7de --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/battery-6.svg @@ -0,0 +1,12 @@ + + + + ic_fluent_battery_6_24_regular + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/system-search-dark.svg b/dots/.config/quickshell/ii/assets/icons/fluent/system-search-dark.svg new file mode 100644 index 000000000..2d972a7b4 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/system-search-dark.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/system-search-light.svg b/dots/.config/quickshell/ii/assets/icons/fluent/system-search-light.svg new file mode 100644 index 000000000..b22f9c0ca --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/system-search-light.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index ffc67805a..2ac21aa40 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -561,6 +561,7 @@ Singleton { property JsonObject waffles: JsonObject { property JsonObject bar: JsonObject { property bool bottom: true + property bool leftAlignApps: true } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml new file mode 100644 index 000000000..808a8ba0a --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml @@ -0,0 +1,40 @@ +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +BarButton { + id: root + + required property string iconName + implicitWidth: height - topInset - bottomInset + leftInset + rightInset + + contentItem: Item { + id: contentItem + anchors.centerIn: root.background + + implicitHeight: iconWidget.implicitHeight + implicitWidth: iconWidget.implicitWidth + + scale: root.down ? 5/6 : 1 // If/When we do dragging, the scale is 1.25 + Behavior on scale { + NumberAnimation { + duration: 90 + easing.type: Easing.BezierSpline + easing.bezierCurve: root.down ? Looks.transition.easing.bezierCurve.easeIn : Looks.transition.easing.bezierCurve.easeOut + } + } + + Kirigami.Icon { + id: iconWidget + anchors.centerIn: parent + implicitWidth: 26 + implicitHeight: 26 + roundToIconSize: false + source: `${Looks.iconsPath}/${root.iconName}-${Looks.dark ? "dark" : "light"}.svg` + fallback: root.iconName + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml new file mode 100644 index 000000000..3bfd3a781 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml @@ -0,0 +1,12 @@ +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +AppButton { + id: root + + iconName: "system-search" +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml new file mode 100644 index 000000000..e3aea59d2 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml @@ -0,0 +1,13 @@ +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +AppButton { + id: root + + leftInset: 12 + iconName: "start-here" +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml index dcb56c30b..e1bb83684 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml @@ -34,10 +34,7 @@ BarButton { } FluentIcon { - icon: { - print(WIcons.batteryIcon) - return WIcons.batteryIcon - } + icon: WIcons.batteryIcon } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml index a2119ddde..f4881adf0 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml @@ -21,14 +21,28 @@ Rectangle { implicitHeight: 1 } - BarGroupRow { - id: bloatRow - anchors.left: parent.left - } - BarGroupRow { id: appsRow + spacing: 4 + anchors.left: undefined anchors.horizontalCenter: parent.horizontalCenter + + states: State { + name: "left" + when: Config.options.waffles.bar.leftAlignApps + AnchorChanges { + target: appsRow + anchors.left: parent.left + anchors.horizontalCenter: undefined + } + } + + transitions: Transition { + animations: Looks.transition.anchor.createObject(this) + } + + StartButton {} + SearchButton {} } BarGroupRow { diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml b/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml index 229df0458..81b6ebf08 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/FluentIcon.qml @@ -13,6 +13,7 @@ Kirigami.Icon { implicitHeight: implicitSize source: `${Looks.iconsPath}/${root.icon}.svg` + fallback: root.icon roundToIconSize: false color: Looks.colors.fg isMask: true diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml index 9020b9d85..95693a05d 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml @@ -13,6 +13,7 @@ Singleton { property QtObject font property QtObject transition property string iconsPath: `${Directories.assetsPath}/icons/fluent` + property bool dark: Appearance.m3colors.darkmode property real fluentBackgroundTransparency: 0.17 property real fluentContentTransparency: 0.3 @@ -66,6 +67,38 @@ Singleton { ColorAnimation { duration: 80 easing.type: Easing.BezierSpline + easing.bezierCurve: transition.easing.bezierCurve.easeIn + } + } + + property Component enter: Component { + NumberAnimation { + duration: 250 + easing.type: Easing.BezierSpline + easing.bezierCurve: transition.easing.bezierCurve.easeIn + } + } + + property Component exit: Component { + NumberAnimation { + duration: 250 + easing.type: Easing.BezierSpline + easing.bezierCurve: transition.easing.bezierCurve.easeOut + } + } + + property Component move: Component { + NumberAnimation { + duration: 100 + easing.type: Easing.BezierSpline + easing.bezierCurve: transition.easing.bezierCurve.easeInOut + } + } + + property Component anchor: Component { + AnchorAnimation { + duration: 250 + easing.type: Easing.BezierSpline easing.bezierCurve: transition.easing.bezierCurve.easeInOut } } From fdcb95b8a4b4fae45bd2e76b2544ebc033f1ad6c Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 10 Nov 2025 23:41:15 +0100 Subject: [PATCH 04/12] wbar: add widgets, taskview, light theme --- .../ii/assets/icons/fluent/task-view.svg | 79 ++++++++++++++++ .../ii/assets/icons/fluent/widgets.svg | 92 +++++++++++++++++++ .../ii/modules/waffle/bar/AppButton.qml | 9 +- .../ii/modules/waffle/bar/AppIcon.qml | 16 ++++ .../ii/modules/waffle/bar/SearchButton.qml | 1 + .../ii/modules/waffle/bar/StartButton.qml | 2 +- .../ii/modules/waffle/bar/TaskViewButton.qml | 12 +++ .../modules/waffle/bar/WaffleBarContent.qml | 19 ++++ .../ii/modules/waffle/bar/WidgetsButton.qml | 39 ++++++++ .../ii/modules/waffle/looks/Looks.qml | 26 ++++-- 10 files changed, 279 insertions(+), 16 deletions(-) create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/task-view.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/widgets.svg create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/task-view.svg b/dots/.config/quickshell/ii/assets/icons/fluent/task-view.svg new file mode 100644 index 000000000..4323e8421 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/task-view.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/widgets.svg b/dots/.config/quickshell/ii/assets/icons/fluent/widgets.svg new file mode 100644 index 000000000..0989033a7 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/widgets.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml index 808a8ba0a..017d8f931 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml @@ -9,6 +9,7 @@ BarButton { id: root required property string iconName + property bool separateLightDark: false implicitWidth: height - topInset - bottomInset + leftInset + rightInset contentItem: Item { @@ -27,14 +28,10 @@ BarButton { } } - Kirigami.Icon { + AppIcon { id: iconWidget anchors.centerIn: parent - implicitWidth: 26 - implicitHeight: 26 - roundToIconSize: false - source: `${Looks.iconsPath}/${root.iconName}-${Looks.dark ? "dark" : "light"}.svg` - fallback: root.iconName + iconName: root.iconName } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml b/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml new file mode 100644 index 000000000..02c1da144 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml @@ -0,0 +1,16 @@ +import QtQuick +import org.kde.kirigami as Kirigami +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +Kirigami.Icon { + id: iconWidget + required property string iconName + + implicitWidth: 26 + implicitHeight: 26 + roundToIconSize: false + source: `${Looks.iconsPath}/${root.iconName}${!root.separateLightDark ? "" : Looks.dark ? "-dark" : "-light"}.svg` + fallback: root.iconName +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml index 3bfd3a781..d1b59b85b 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml @@ -9,4 +9,5 @@ AppButton { id: root iconName: "system-search" + separateLightDark: true } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml index e3aea59d2..d5a4e0f97 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml @@ -8,6 +8,6 @@ import qs.modules.waffle.looks AppButton { id: root - leftInset: 12 + leftInset: Config.options.waffles.bar.leftAlignApps ? 12 : 0 iconName: "start-here" } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml new file mode 100644 index 000000000..3211217fa --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml @@ -0,0 +1,12 @@ +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +AppButton { + id: root + + iconName: "task-view" +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml index f4881adf0..989904e2f 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Layouts import qs.modules.common +import qs.modules.common.widgets import qs.modules.waffle.looks Rectangle { @@ -21,6 +22,18 @@ Rectangle { implicitHeight: 1 } + BarGroupRow { + id: bloatRow + anchors.left: parent.left + opacity: Config.options.waffles.bar.leftAlignApps ? 0 : 1 + visible: opacity > 0 + Behavior on opacity { + animation: Looks.transition.opacity.createObject(this) + } + + WidgetsButton {} + } + BarGroupRow { id: appsRow spacing: 4 @@ -43,11 +56,17 @@ Rectangle { StartButton {} SearchButton {} + TaskViewButton {} } BarGroupRow { id: systemRow anchors.right: parent.right + FadeLoader { + Layout.fillHeight: true + shown: Config.options.waffles.bar.leftAlignApps + sourceComponent: WidgetsButton {} + } SystemButton {} TimeButton {} } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml new file mode 100644 index 000000000..94c194686 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml @@ -0,0 +1,39 @@ +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +AppButton { + id: root + + readonly property bool expandedForm: Config.options.waffles.bar.leftAlignApps + leftInset: Config.options.waffles.bar.leftAlignApps ? 0 : 12 + implicitWidth: expandedForm ? 148 : (height - topInset - bottomInset + leftInset + rightInset) + iconName: "widgets" + + contentItem: Item { + anchors { + verticalCenter: parent.verticalCenter + left: root.expandedForm ? parent.left : undefined + horizontalCenter: root.expandedForm ? undefined : background.horizontalCenter + } + implicitHeight: row.implicitHeight + implicitWidth: row.implicitWidth + Row { + id: row + anchors { + verticalCenter: parent.verticalCenter + left: root.expandedForm ? parent.left : undefined + horizontalCenter: root.expandedForm ? undefined : parent.horizontalCenter + margins: 8 + } + + AppIcon { + id: iconWidget + iconName: root.iconName + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml index 95693a05d..ea225f093 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml @@ -19,13 +19,13 @@ Singleton { property real fluentContentTransparency: 0.3 colors: QtObject { id: colors - property color bg0: "#1C1C1C" - property color bg0Border: "#404040" - property color bg1: "#2E2E2E" - property color bg1Hover: "#292929" - property color bg1Active: "#252525" - property color bg1Border: "#333333" - property color fg: "#FFFFFF" + property color bg0: root.dark ? "#1C1C1C" : "#EEEEEE" + property color bg0Border: root.dark ? "#404040" : "#BEBEBE" + property color bg1: root.dark ? "#2E2E2E" : "#F7F7F7" + property color bg1Hover: root.dark ? "#292929" : "#F7F7F7" + property color bg1Active: root.dark ? "#252525" : "#F3F3F3" + property color bg1Border: root.dark ? "#333333" : "#E9E9E9" + property color fg: root.dark ? "#FFFFFF" : "#000000" property color brand: Appearance.m3colors.m3primary } @@ -71,6 +71,14 @@ Singleton { } } + property Component opacity: Component { + NumberAnimation{ + duration: 80 + easing.type: Easing.BezierSpline + easing.bezierCurve: transition.easing.bezierCurve.easeIn + } + } + property Component enter: Component { NumberAnimation { duration: 250 @@ -97,9 +105,9 @@ Singleton { property Component anchor: Component { AnchorAnimation { - duration: 250 + duration: 160 easing.type: Easing.BezierSpline - easing.bezierCurve: transition.easing.bezierCurve.easeInOut + easing.bezierCurve: transition.easing.bezierCurve.easeIn } } } From cbcb8cf8e13e6c8d03c769007e9f9c32e4f7eb22 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 11 Nov 2025 00:01:57 +0100 Subject: [PATCH 05/12] wbar: more interactions --- dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml | 4 ++-- .../quickshell/ii/modules/waffle/bar/TaskViewButton.qml | 6 ++++++ .../.config/quickshell/ii/modules/waffle/bar/TimeButton.qml | 6 ++++++ dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml index 1ea789fcb..20929b1e6 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml @@ -12,7 +12,7 @@ Button { topInset: 4 bottomInset: 4 - property color borderColor: ColorUtils.transparentize(Looks.colors.bg1Border, (root.hovered && !root.down) ? Looks.fluentContentTransparency : 1) + property color borderColor: ColorUtils.transparentize(Looks.colors.bg1Border, ((root.hovered && !root.down) || root.checked) ? Looks.fluentContentTransparency : 1) Behavior on borderColor { animation: Looks.transition.color.createObject(this) } @@ -25,7 +25,7 @@ Button { color: { if (root.down) { return Looks.colors.bg1Active - } else if (root.hovered) { + } else if ((root.hovered && !root.down) || root.checked) { return Looks.colors.bg1Hover } else { return ColorUtils.transparentize(Looks.colors.bg1) diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml index 3211217fa..1239fed6f 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Layouts import org.kde.kirigami as Kirigami +import qs import qs.services import qs.modules.common import qs.modules.waffle.looks @@ -9,4 +10,9 @@ AppButton { id: root iconName: "task-view" + + checked: GlobalStates.overviewOpen + onClicked: { + GlobalStates.overviewOpen = !GlobalStates.overviewOpen; + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml index 53177da12..f8e2f38cc 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml @@ -1,5 +1,6 @@ import QtQuick import QtQuick.Layouts +import qs import qs.services import qs.modules.common import qs.modules.waffle.looks @@ -10,6 +11,11 @@ BarButton { rightInset: 12 // For now this is the rightmost button. Desktop peek is useless. (for now) padding: 12 + checked: GlobalStates.sidebarRightOpen + onClicked: { + GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen; + } + contentItem: Item { anchors.centerIn: root.background implicitHeight: column.implicitHeight diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml index 241b5e66b..5c19c661f 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml @@ -23,7 +23,7 @@ Scope { screen: modelData exclusionMode: ExclusionMode.Ignore exclusiveZone: implicitHeight - WlrLayershell.namespace: "quickshell:wbar" + WlrLayershell.namespace: "quickshell:wBar" anchors { left: true From dec65aea17f8ac4a20e360f4be7ede94da7a6596 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 11 Nov 2025 00:03:19 +0100 Subject: [PATCH 06/12] update hyprland config --- dots/.config/hypr/hyprland/general.conf | 4 ++-- dots/.config/hypr/hyprland/keybinds.conf | 1 + dots/.config/hypr/hyprland/rules.conf | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dots/.config/hypr/hyprland/general.conf b/dots/.config/hypr/hyprland/general.conf index 2c79a857f..14074b345 100644 --- a/dots/.config/hypr/hyprland/general.conf +++ b/dots/.config/hypr/hyprland/general.conf @@ -6,8 +6,8 @@ monitor=,preferred,auto,1 # monitor=HDMI-A-1,1920x1080@60,1920x0,1,mirror,eDP-1 gesture = 3, swipe, move, +gesture = 3, pinch, float gesture = 4, horizontal, workspace -gesture = 4, pinch, float gesture = 4, up, dispatcher, global, quickshell:overviewToggle gesture = 4, down, dispatcher, global, quickshell:overviewClose gestures { @@ -62,7 +62,7 @@ decoration { brightness = 1 noise = 0.04 contrast = 1 - popups = true + popups = false popups_ignorealpha = 0.6 input_methods = true input_methods_ignorealpha = 0.8 diff --git a/dots/.config/hypr/hyprland/keybinds.conf b/dots/.config/hypr/hyprland/keybinds.conf index 294854d67..fdda9a714 100644 --- a/dots/.config/hypr/hyprland/keybinds.conf +++ b/dots/.config/hypr/hyprland/keybinds.conf @@ -53,6 +53,7 @@ bindd = Ctrl+Super, T, Toggle wallpaper selector, global, quickshell:wallpaperSe bindd = Ctrl+Super+Alt, T, Select random wallpaper, global, quickshell:wallpaperSelectorRandom # Random wallpaper bindd = Ctrl+Super, T, Change wallpaper, exec, qs -c $qsConfig ipc call TEST_ALIVE || ~/.config/quickshell/$qsConfig/scripts/colors/switchwall.sh # [hidden] Change wallpaper (fallback) bind = Ctrl+Super, R, exec, killall ags agsv1 gjs ydotool qs quickshell; qs -c $qsConfig & # Restart widgets +bind = Super+Alt, W, global, quickshell:panelFamilyCycle # Cycle panel family ##! Utilities # Screenshot, Record, OCR, Color picker, Clipboard history diff --git a/dots/.config/hypr/hyprland/rules.conf b/dots/.config/hypr/hyprland/rules.conf index 01ac1056d..dc34a4a6b 100644 --- a/dots/.config/hypr/hyprland/rules.conf +++ b/dots/.config/hypr/hyprland/rules.conf @@ -154,6 +154,8 @@ layerrule = animation slide right, quickshell:sidebarRight layerrule = animation slide left, quickshell:sidebarLeft layerrule = animation slide, quickshell:verticalBar layerrule = animation slide top, quickshell:wallpaperSelector +# Quickshell - Waffles +layerrule = animation slide, quickshell:wBar # Launchers need to be FAST layerrule = noanim, gtk4-layer-shell From a412688af299a4b6adf8214e9da4965549e88807 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 11 Nov 2025 20:23:09 +0100 Subject: [PATCH 07/12] add bg, taskbar items --- .../ii/assets/icons/fluent/README.md | 5 + .../ii/assets/icons/fluent/task-view-dark.svg | 128 ++++++++++++++++++ .../assets/icons/fluent/task-view-light.svg | 104 ++++++++++++++ .../ii/assets/icons/fluent/task-view.svg | 79 ----------- .../quickshell/ii/modules/common/Config.qml | 4 +- .../ii/modules/ii/dock/DockAppButton.qml | 4 +- .../ii/modules/ii/dock/DockApps.qml | 46 +------ .../waffle/background/WaffleBackground.qml | 46 +++++++ .../ii/modules/waffle/bar/TaskAppButton.qml | 17 +++ .../ii/modules/waffle/bar/TaskViewButton.qml | 1 + .../ii/modules/waffle/bar/Tasks.qml | 34 +++++ .../ii/modules/waffle/bar/WaffleBar.qml | 2 +- .../modules/waffle/bar/WaffleBarContent.qml | 1 + .../ii/modules/waffle/bar/WidgetsButton.qml | 15 ++ .../quickshell/ii/services/TaskbarApps.qml | 60 ++++++++ dots/.config/quickshell/ii/shell.qml | 4 +- 16 files changed, 424 insertions(+), 126 deletions(-) create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/README.md create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/task-view-dark.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/task-view-light.svg delete mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/task-view.svg create mode 100644 dots/.config/quickshell/ii/modules/waffle/background/WaffleBackground.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml create mode 100644 dots/.config/quickshell/ii/services/TaskbarApps.qml diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/README.md b/dots/.config/quickshell/ii/assets/icons/fluent/README.md new file mode 100644 index 000000000..5f4d3eaa2 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/README.md @@ -0,0 +1,5 @@ +The "search" and "task view" icons are from here, with modifications + +https://www.figma.com/community/file/1123040825921884189/windows-11 + +License: CC BY 4.0 diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/task-view-dark.svg b/dots/.config/quickshell/ii/assets/icons/fluent/task-view-dark.svg new file mode 100644 index 000000000..d38c927c8 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/task-view-dark.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/task-view-light.svg b/dots/.config/quickshell/ii/assets/icons/fluent/task-view-light.svg new file mode 100644 index 000000000..1f37c4aa4 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/task-view-light.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/task-view.svg b/dots/.config/quickshell/ii/assets/icons/fluent/task-view.svg deleted file mode 100644 index 4323e8421..000000000 --- a/dots/.config/quickshell/ii/assets/icons/fluent/task-view.svg +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 2ac21aa40..a724c043d 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -389,7 +389,7 @@ Singleton { property bool darkenScreen: true property real clickthroughOpacity: 0.8 property JsonObject floatingImage: JsonObject { - property string imageSource: "https://cdn.discordapp.com/attachments/961693710968557598/1369635662390759434/image.gif?ex=6911cb1c&is=6910799c&hm=4450244066c0a7a6e5d2bdd195f47388eb5e7f9dd53d3931e99ad9642c638a00&" + property string imageSource: "https://media.tenor.com/H5U5bJzj3oAAAAAi/kukuru.gif" property real scale: 0.5 } } @@ -561,7 +561,7 @@ Singleton { property JsonObject waffles: JsonObject { property JsonObject bar: JsonObject { property bool bottom: true - property bool leftAlignApps: true + property bool leftAlignApps: false } } } diff --git a/dots/.config/quickshell/ii/modules/ii/dock/DockAppButton.qml b/dots/.config/quickshell/ii/modules/ii/dock/DockAppButton.qml index 406eb3f57..41ed8cd07 100644 --- a/dots/.config/quickshell/ii/modules/ii/dock/DockAppButton.qml +++ b/dots/.config/quickshell/ii/modules/ii/dock/DockAppButton.qml @@ -17,8 +17,8 @@ DockButton { property real countDotHeight: 4 property bool appIsActive: appToplevel.toplevels.find(t => (t.activated == true)) !== undefined - property bool isSeparator: appToplevel.appId === "SEPARATOR" - property var desktopEntry: DesktopEntries.heuristicLookup(appToplevel.appId) + readonly property bool isSeparator: appToplevel.appId === "SEPARATOR" + readonly property var desktopEntry: DesktopEntries.heuristicLookup(appToplevel.appId) enabled: !isSeparator implicitWidth: isSeparator ? 1 : implicitHeight - topInset - bottomInset diff --git a/dots/.config/quickshell/ii/modules/ii/dock/DockApps.qml b/dots/.config/quickshell/ii/modules/ii/dock/DockApps.qml index 2bba6553a..d575b7dd4 100644 --- a/dots/.config/quickshell/ii/modules/ii/dock/DockApps.qml +++ b/dots/.config/quickshell/ii/modules/ii/dock/DockApps.qml @@ -1,6 +1,3 @@ -import qs.modules.common -import qs.modules.common.widgets -import qs.modules.common.functions import Qt5Compat.GraphicalEffects import QtQuick import QtQuick.Controls @@ -8,6 +5,10 @@ import QtQuick.Layouts import Quickshell import Quickshell.Widgets import Quickshell.Wayland +import qs.services +import qs.modules.common +import qs.modules.common.widgets +import qs.modules.common.functions Item { id: root @@ -40,44 +41,7 @@ Item { model: ScriptModel { objectProp: "appId" - values: { - var map = new Map(); - - // Pinned apps - const pinnedApps = Config.options?.dock.pinnedApps ?? []; - for (const appId of pinnedApps) { - if (!map.has(appId.toLowerCase())) map.set(appId.toLowerCase(), ({ - pinned: true, - toplevels: [] - })); - } - - // Separator - if (pinnedApps.length > 0) { - map.set("SEPARATOR", { pinned: false, toplevels: [] }); - } - - // Ignored apps - const ignoredRegexStrings = Config.options?.dock.ignoredAppRegexes ?? []; - const ignoredRegexes = ignoredRegexStrings.map(pattern => new RegExp(pattern, "i")); - // Open windows - for (const toplevel of ToplevelManager.toplevels.values) { - if (ignoredRegexes.some(re => re.test(toplevel.appId))) continue; - if (!map.has(toplevel.appId.toLowerCase())) map.set(toplevel.appId.toLowerCase(), ({ - pinned: false, - toplevels: [] - })); - map.get(toplevel.appId.toLowerCase()).toplevels.push(toplevel); - } - - var values = []; - - for (const [key, value] of map) { - values.push({ appId: key, toplevels: value.toplevels, pinned: value.pinned }); - } - - return values; - } + values: TaskbarApps.apps } delegate: DockAppButton { required property var modelData diff --git a/dots/.config/quickshell/ii/modules/waffle/background/WaffleBackground.qml b/dots/.config/quickshell/ii/modules/waffle/background/WaffleBackground.qml new file mode 100644 index 000000000..caaff1707 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/background/WaffleBackground.qml @@ -0,0 +1,46 @@ +pragma ComponentBehavior: Bound + +import qs +import qs.services +import qs.modules.common +import qs.modules.common.widgets +import qs.modules.common.widgets.widgetCanvas +import QtQuick +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import Quickshell +import Quickshell.Io +import Quickshell.Wayland +import Quickshell.Hyprland + +import qs.modules.ii.background.widgets +import qs.modules.ii.background.widgets.clock +import qs.modules.ii.background.widgets.weather + +Variants { + id: root + model: Quickshell.screens + + PanelWindow { + id: panelRoot + required property var modelData + + screen: modelData + exclusionMode: ExclusionMode.Ignore + WlrLayershell.layer: WlrLayer.Bottom + WlrLayershell.namespace: "quickshell:background" + anchors { + top: true + bottom: true + left: true + right: true + } + color: "transparent" + + StyledImage { + anchors.fill: parent + source: Config.options.background.wallpaperPath + fillMode: Image.PreserveAspectCrop + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml new file mode 100644 index 000000000..241796f0f --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml @@ -0,0 +1,17 @@ +import QtQuick +import QtQuick.Layouts +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +AppButton { + id: root + + required property var toplevel + readonly property bool isSeparator: toplevel.appId === "SEPARATOR" + readonly property var desktopEntry: DesktopEntries.heuristicLookup(toplevel.appId) + + Layout.fillHeight: true + + iconName: toplevel.appId +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml index 1239fed6f..c3a4853f0 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml @@ -10,6 +10,7 @@ AppButton { id: root iconName: "task-view" + separateLightDark: true checked: GlobalStates.overviewOpen onClicked: { diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml b/dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml new file mode 100644 index 000000000..ba8944999 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml @@ -0,0 +1,34 @@ +import QtQuick +import QtQuick.Layouts +import Quickshell +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +Item { + id: root + + Layout.fillHeight: true + implicitHeight: row.implicitHeight + implicitWidth: row.implicitWidth + + // Apps row + RowLayout { + id: row + anchors.fill: parent + spacing: 4 + + Repeater { + model: ScriptModel { + objectProp: "appId" + values: TaskbarApps.apps.filter(app => app.appId !== "SEPARATOR") + } + delegate: TaskAppButton { + required property var modelData + toplevel: modelData + } + } + } + + // TODO: Previews popup +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml index 5c19c661f..aa5f51f68 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBar.qml @@ -23,7 +23,7 @@ Scope { screen: modelData exclusionMode: ExclusionMode.Ignore exclusiveZone: implicitHeight - WlrLayershell.namespace: "quickshell:wBar" + WlrLayershell.namespace: "quickshell:bar" anchors { left: true diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml index 989904e2f..1a9763616 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml @@ -57,6 +57,7 @@ Rectangle { StartButton {} SearchButton {} TaskViewButton {} + Tasks {} } BarGroupRow { diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml index 94c194686..840f63c7a 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Layouts import org.kde.kirigami as Kirigami +import qs import qs.services import qs.modules.common import qs.modules.waffle.looks @@ -13,6 +14,11 @@ AppButton { implicitWidth: expandedForm ? 148 : (height - topInset - bottomInset + leftInset + rightInset) iconName: "widgets" + checked: GlobalStates.sidebarLeftOpen + onClicked: { + GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen + } + contentItem: Item { anchors { verticalCenter: parent.verticalCenter @@ -29,11 +35,20 @@ AppButton { horizontalCenter: root.expandedForm ? undefined : parent.horizontalCenter margins: 8 } + spacing: 6 AppIcon { id: iconWidget + anchors.verticalCenter: parent.verticalCenter iconName: root.iconName } + + Column { + anchors.verticalCenter: parent.verticalCenter + WText { + text: Translation.tr("Widgets") + } + } } } } diff --git a/dots/.config/quickshell/ii/services/TaskbarApps.qml b/dots/.config/quickshell/ii/services/TaskbarApps.qml new file mode 100644 index 000000000..0b5818b71 --- /dev/null +++ b/dots/.config/quickshell/ii/services/TaskbarApps.qml @@ -0,0 +1,60 @@ +pragma Singleton + +import qs.modules.common +import QtQuick +import Quickshell +import Quickshell.Wayland + +Singleton { + id: root + + property list apps: { + var map = new Map(); + + // Pinned apps + const pinnedApps = Config.options?.dock.pinnedApps ?? []; + for (const appId of pinnedApps) { + if (!map.has(appId.toLowerCase())) map.set(appId.toLowerCase(), ({ + pinned: true, + toplevels: [] + })); + } + + // Separator + if (pinnedApps.length > 0) { + map.set("SEPARATOR", { pinned: false, toplevels: [] }); + } + + // Ignored apps + const ignoredRegexStrings = Config.options?.dock.ignoredAppRegexes ?? []; + const ignoredRegexes = ignoredRegexStrings.map(pattern => new RegExp(pattern, "i")); + // Open windows + for (const toplevel of ToplevelManager.toplevels.values) { + if (ignoredRegexes.some(re => re.test(toplevel.appId))) continue; + if (!map.has(toplevel.appId.toLowerCase())) map.set(toplevel.appId.toLowerCase(), ({ + pinned: false, + toplevels: [] + })); + map.get(toplevel.appId.toLowerCase()).toplevels.push(toplevel); + } + + var values = []; + + for (const [key, value] of map) { + values.push(appEntryComp.createObject(null, { appId: key, toplevels: value.toplevels, pinned: value.pinned })); + } + + return values; + } + + component TaskbarAppEntry: QtObject { + id: wrapper + required property string appId + required property list toplevels + required property bool pinned + } + Component { + id: appEntryComp + TaskbarAppEntry {} + } +} diff --git a/dots/.config/quickshell/ii/shell.qml b/dots/.config/quickshell/ii/shell.qml index a23c84cca..dc0a9509f 100644 --- a/dots/.config/quickshell/ii/shell.qml +++ b/dots/.config/quickshell/ii/shell.qml @@ -28,6 +28,7 @@ import qs.modules.ii.overlay import qs.modules.ii.verticalBar import qs.modules.ii.wallpaperSelector +import qs.modules.waffle.background import qs.modules.waffle.bar import QtQuick @@ -74,6 +75,7 @@ ShellRoot { PanelLoader { identifier: "iiVerticalBar"; extraCondition: Config.options.bar.vertical; component: VerticalBar {} } PanelLoader { identifier: "iiWallpaperSelector"; component: WallpaperSelector {} } PanelLoader { identifier: "wBar"; component: WaffleBar {} } + PanelLoader { identifier: "wBackground"; component: WaffleBackground {} } component PanelLoader: LazyLoader { required property string identifier @@ -85,7 +87,7 @@ ShellRoot { property list families: ["ii", "waffle"] property var panelFamilies: ({ "ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"], - "waffle": ["wBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiWallpaperSelector"], + "waffle": ["wBar", "wBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiWallpaperSelector"], }) function cyclePanelFamily() { const currentIndex = families.indexOf(Config.options.panelFamily) From 20e1f0e0bb79cc796035e38558ea0aa09df7f93a Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Wed, 12 Nov 2025 00:09:22 +0100 Subject: [PATCH 08/12] taskbar: window previews --- .../ii/assets/icons/fluent/dismiss.svg | 1 + .../ii/modules/waffle/bar/AppButton.qml | 13 +- .../ii/modules/waffle/bar/AppIcon.qml | 8 +- .../ii/modules/waffle/bar/BarButton.qml | 55 +------ .../ii/modules/waffle/bar/TaskAppButton.qml | 18 ++- .../ii/modules/waffle/bar/TaskPreview.qml | 128 +++++++++++++++++ .../ii/modules/waffle/bar/Tasks.qml | 19 ++- .../modules/waffle/bar/WaffleBarContent.qml | 1 - .../ii/modules/waffle/bar/WindowPreview.qml | 135 ++++++++++++++++++ .../modules/waffle/looks/AcrylicRectangle.qml | 63 ++++++++ .../ii/modules/waffle/looks/Looks.qml | 25 ++-- .../quickshell/ii/services/AppSearch.qml | 2 +- 12 files changed, 390 insertions(+), 78 deletions(-) create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/dismiss.svg create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/TaskPreview.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/WindowPreview.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/looks/AcrylicRectangle.qml diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/dismiss.svg b/dots/.config/quickshell/ii/assets/icons/fluent/dismiss.svg new file mode 100644 index 000000000..3cb3656dc --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/dismiss.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml index 017d8f931..90d0cc007 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml @@ -10,8 +10,16 @@ BarButton { required property string iconName property bool separateLightDark: false + leftInset: 2 + rightInset: 2 implicitWidth: height - topInset - bottomInset + leftInset + rightInset + onDownChanged: { + scaleAnim.duration = root.down ? 150 : 200 + scaleAnim.easing.bezierCurve = root.down ? Looks.transition.easing.bezierCurve.easeIn : Looks.transition.easing.bezierCurve.easeOut + contentItem.scale = root.down ? 5/6 : 1 // If/When we do dragging, the scale is 1.25 + } + contentItem: Item { id: contentItem anchors.centerIn: root.background @@ -19,12 +27,10 @@ BarButton { implicitHeight: iconWidget.implicitHeight implicitWidth: iconWidget.implicitWidth - scale: root.down ? 5/6 : 1 // If/When we do dragging, the scale is 1.25 Behavior on scale { NumberAnimation { - duration: 90 + id: scaleAnim easing.type: Easing.BezierSpline - easing.bezierCurve: root.down ? Looks.transition.easing.bezierCurve.easeIn : Looks.transition.easing.bezierCurve.easeOut } } @@ -32,6 +38,7 @@ BarButton { id: iconWidget anchors.centerIn: parent iconName: root.iconName + separateLightDark: root.separateLightDark } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml b/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml index 02c1da144..fc5c75426 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml @@ -5,11 +5,13 @@ import qs.modules.common import qs.modules.waffle.looks Kirigami.Icon { - id: iconWidget + id: root required property string iconName + property bool separateLightDark: false - implicitWidth: 26 - implicitHeight: 26 + property real implicitSize: 26 + implicitWidth: implicitSize + implicitHeight: implicitSize roundToIconSize: false source: `${Looks.iconsPath}/${root.iconName}${!root.separateLightDark ? "" : Looks.dark ? "-dark" : "-light"}.svg` fallback: root.iconName diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml index 20929b1e6..52e5164aa 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml @@ -11,17 +11,9 @@ Button { Layout.fillHeight: true topInset: 4 bottomInset: 4 - - property color borderColor: ColorUtils.transparentize(Looks.colors.bg1Border, ((root.hovered && !root.down) || root.checked) ? Looks.fluentContentTransparency : 1) - Behavior on borderColor { - animation: Looks.transition.color.createObject(this) - } - onBorderColorChanged: { - borderCanvas.requestPaint(); - } - background: Rectangle { - id: background + background: AcrylicRectangle { + shiny: ((root.hovered && !root.down) || root.checked) color: { if (root.down) { return Looks.colors.bg1Active @@ -31,48 +23,5 @@ Button { return ColorUtils.transparentize(Looks.colors.bg1) } } - radius: Looks.radius.medium - Behavior on color { - animation: Looks.transition.color.createObject(this) - } - - // Top 1px border with color - Canvas { - id: borderCanvas - anchors.fill: parent - onPaint: { - var ctx = getContext("2d"); - ctx.clearRect(0, 0, width, height); - - var borderColor = root.borderColor; - - var r = background.radius; - var fadeLength = Math.max(1, r); - var fadeLengthPercent = fadeLength / width; - - // Compute normalized stops - var leftFadeStop = fadeLengthPercent; - var rightFadeStop = 1 - fadeLengthPercent; - - var grad = ctx.createLinearGradient(0, 0, width, 0); - grad.addColorStop(0, Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0)); - grad.addColorStop(leftFadeStop, borderColor); - grad.addColorStop(rightFadeStop, borderColor); - grad.addColorStop(1, Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0)); - - ctx.strokeStyle = grad; - ctx.lineWidth = 1; - - ctx.beginPath(); - ctx.moveTo(r, 0.5); - ctx.lineTo(width - r, 0.5); - // Top-right curve - ctx.arcTo(width, 0.5, width, r + 0.5, r); - // Top-left curve - ctx.moveTo(width - r, 0.5); - ctx.arcTo(0, 0.5, 0, r + 0.5, r); - ctx.stroke(); - } - } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml index 241796f0f..7363b0387 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml @@ -3,15 +3,23 @@ import QtQuick.Layouts import qs.services import qs.modules.common import qs.modules.waffle.looks +import Quickshell AppButton { id: root - required property var toplevel - readonly property bool isSeparator: toplevel.appId === "SEPARATOR" - readonly property var desktopEntry: DesktopEntries.heuristicLookup(toplevel.appId) + required property var appEntry + readonly property bool isSeparator: appEntry.appId === "SEPARATOR" + readonly property var desktopEntry: DesktopEntries.heuristicLookup(appEntry.appId) - Layout.fillHeight: true + signal hoverPreviewRequested() - iconName: toplevel.appId + iconName: AppSearch.guessIcon(appEntry.appId) + Timer { + running: root.hovered + interval: 250 + onTriggered: { + root.hoverPreviewRequested() + } + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TaskPreview.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TaskPreview.qml new file mode 100644 index 000000000..3c03563a3 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TaskPreview.qml @@ -0,0 +1,128 @@ +import QtQuick +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import qs.services +import qs.modules.common +import qs.modules.common.functions +import qs.modules.waffle.looks +import Quickshell + +PopupWindow { + id: root + + ///////////////////// Properties //////////////////// + required property bool tasksHovered + property var appEntry + property Item anchorItem + + //////////////////// Functions //////////////////// + function close() { + marginBehavior.enabled = false; + root.visible = false; + } + + function open() { + marginBehavior.enabled = true; + root.visible = true; + } + + function show(appEntry: var, button: Item) { + root.appEntry = appEntry; + root.anchorItem = button; + root.anchor.updateAnchor(); + root.open(); + } + + ///////////////////// Internals ///////////////////// + readonly property bool bottom: Config.options.waffles.bar.bottom + property real visualMargin: 12 + property alias ambientShadowWidth: ambientShadow.border.width + + visible: false + color: "transparent" + implicitWidth: contentItem.implicitWidth + ambientShadowWidth + (visualMargin * 2) + implicitHeight: contentItem.implicitHeight + ambientShadowWidth + (visualMargin * 2) + anchor { + adjustment: PopupAdjustment.Slide + item: root.anchorItem + gravity: bottom ? Edges.Top : Edges.Bottom + edges: bottom ? Edges.Top : Edges.Bottom + } + + Timer { + interval: 250 + running: root.visible && !hoverChecker.containsMouse && !root.tasksHovered + onTriggered: { + root.close(); + } + } + + // Content + MouseArea { + id: hoverChecker + anchors.fill: parent + hoverEnabled: true + + // Shadow + Rectangle { + id: ambientShadow + anchors { + fill: contentItem + margins: -border.width + } + border.color: ColorUtils.transparentize(Looks.colors.bg0Border, Looks.contentTransparency) + border.width: 1 + color: "transparent" + radius: Looks.radius.large + border.width + } + + Rectangle { + id: contentItem + property real sourceEdgeMargin: root.visible ? (root.ambientShadowWidth + root.visualMargin) : -root.implicitHeight + Behavior on sourceEdgeMargin { + id: marginBehavior + animation: Looks.transition.enter.createObject(this) + } + anchors { + left: parent.left + right: parent.right + top: root.bottom ? undefined : parent.top + bottom: root.bottom ? parent.bottom : undefined + margins: root.ambientShadowWidth + root.visualMargin + // Opening anim + bottomMargin: root.bottom ? sourceEdgeMargin : (root.ambientShadowWidth + root.visualMargin) + topMargin: root.bottom ? (root.ambientShadowWidth + root.visualMargin) : sourceEdgeMargin + } + color: Looks.colors.bg1 + radius: Looks.radius.large + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: contentItem.width + height: contentItem.height + radius: contentItem.radius + } + } + + // Testing + implicitHeight: Math.min(158, windowsRow.implicitHeight) + implicitWidth: windowsRow.implicitWidth + + RowLayout { + id: windowsRow + anchors.fill: parent + + Repeater { + model: ScriptModel { + values: root.appEntry?.toplevels ?? [] + } + delegate: WindowPreview { + required property var modelData + toplevel: modelData + } + } + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml b/dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml index ba8944999..eac963722 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml @@ -5,30 +5,41 @@ import qs.services import qs.modules.common import qs.modules.waffle.looks -Item { +MouseArea { id: root Layout.fillHeight: true implicitHeight: row.implicitHeight implicitWidth: row.implicitWidth + hoverEnabled: true // Apps row RowLayout { id: row anchors.fill: parent - spacing: 4 + spacing: 0 Repeater { + // TODO: Include only apps (and windows) in current workspace only model: ScriptModel { objectProp: "appId" values: TaskbarApps.apps.filter(app => app.appId !== "SEPARATOR") } delegate: TaskAppButton { required property var modelData - toplevel: modelData + appEntry: modelData + + onHoverPreviewRequested: { + previewPopup.show(appEntry, this) + } } } } - // TODO: Previews popup + // Previews popup + TaskPreview { + id: previewPopup + tasksHovered: root.containsMouse + anchor.window: root.QsWindow.window + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml index 1a9763616..5228abb5c 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml @@ -36,7 +36,6 @@ Rectangle { BarGroupRow { id: appsRow - spacing: 4 anchors.left: undefined anchors.horizontalCenter: parent.horizontalCenter diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WindowPreview.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WindowPreview.qml new file mode 100644 index 000000000..b1944c350 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WindowPreview.qml @@ -0,0 +1,135 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects +import qs.services +import qs.modules.common +import qs.modules.common.functions +import qs.modules.waffle.looks +import Quickshell +import Quickshell.Wayland + +Button { + id: root + + required property var toplevel + property real previewWidthConstraint: 200 + property real previewHeightConstraint: 110 + padding: 5 + Layout.fillHeight: true + + onClicked: { + root.toplevel.activate(); // TODO: make this work with those who disable focus on activate because telegram is abusive + } + + background: Rectangle { + id: background + radius: Looks.radius.medium + color: root.down ? Looks.colors.bg2Active : (root.hovered ? Looks.colors.bg2Hover : ColorUtils.transparentize(Looks.colors.bg2)) + Behavior on color { + animation: Looks.transition.color.createObject(this) + } + } + + contentItem: ColumnLayout { + id: contentItem + anchors.fill: parent + anchors.margins: root.padding + spacing: 5 + + RowLayout { + Layout.fillWidth: true + Layout.fillHeight: false + spacing: 8 + + AppIcon { + id: appIcon + Layout.leftMargin: Looks.radius.large - root.padding + 2 + Layout.alignment: Qt.AlignVCenter + iconName: AppSearch.guessIcon(root.toplevel.appId) + implicitSize: 16 + } + + Item { + id: appTitleContainer + Layout.fillWidth: true + Layout.fillHeight: true + implicitHeight: closeButton.implicitHeight // Enforce height, because closeButton doesn't contribute when it's invisible + WText { + id: appTitleText + anchors.fill: parent + text: root.toplevel.title + elide: Text.ElideRight + font.pixelSize: Looks.font.pixelSize.large + font.weight: Looks.font.weight.thin + color: Looks.colors.fg1 + } + } + + CloseButton { + id: closeButton + } + } + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: Looks.radius.large - root.padding + Layout.topMargin: 0 + implicitWidth: Math.max(screencopyView.implicitWidth, 80) + implicitHeight: screencopyView.implicitHeight + + ScreencopyView { + id: screencopyView + anchors.centerIn: parent + captureSource: root.toplevel + live: true + paintCursor: true + constraintSize: Qt.size(root.previewWidthConstraint, root.previewHeightConstraint) + } + } + } + + component CloseButton: Button { + id: reusableCloseButton + visible: root.hovered + Layout.leftMargin: 4 + implicitHeight: 30 + implicitWidth: 30 + onClicked: { + root.toplevel.close(); + } + + Rectangle { + z: 0 + color: "transparent" + anchors.fill: closeButtonBg + anchors.margins: -1 + opacity: closeButtonBg.opacity + border.width: 1 + radius: closeButtonBg.radius + 1 + border.color: Looks.colors.bg2Border + } + + background: Rectangle { + id: closeButtonBg + z: 1 + opacity: reusableCloseButton.hovered ? 1 : 0 + radius: Looks.radius.large - root.padding + color: reusableCloseButton.pressed ? Looks.colors.dangerActive : Looks.colors.danger + Behavior on opacity { + animation: Looks.transition.opacity.createObject(this) + } + Behavior on color { + animation: Looks.transition.color.createObject(this) + } + } + + contentItem: FluentIcon { + z: 2 + anchors.centerIn: parent + icon: "dismiss" + implicitSize: 10 + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/AcrylicRectangle.qml b/dots/.config/quickshell/ii/modules/waffle/looks/AcrylicRectangle.qml new file mode 100644 index 000000000..3720d6186 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/looks/AcrylicRectangle.qml @@ -0,0 +1,63 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import qs.modules.common +import qs.modules.common.functions +import qs.modules.waffle.looks + +Rectangle { + id: root + + property bool shiny: true // Top border + property color borderColor: ColorUtils.transparentize(Looks.colors.bg1Border, shiny ? Looks.contentTransparency : 1) + color: Looks.colors.bg1Hover + radius: Looks.radius.medium + Behavior on color { + animation: Looks.transition.color.createObject(this) + } + Behavior on borderColor { + animation: Looks.transition.color.createObject(this) + } + onBorderColorChanged: { + borderCanvas.requestPaint(); + } + + // Top 1px border with color + Canvas { + id: borderCanvas + anchors.fill: parent + onPaint: { + var ctx = getContext("2d"); + ctx.clearRect(0, 0, width, height); + + var borderColor = root.borderColor; + + var r = root.radius; + var fadeLength = Math.max(1, r); + var fadeLengthPercent = fadeLength / width; + + // Compute normalized stops + var leftFadeStop = fadeLengthPercent; + var rightFadeStop = 1 - fadeLengthPercent; + + var grad = ctx.createLinearGradient(0, 0, width, 0); + grad.addColorStop(0, Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0)); + grad.addColorStop(leftFadeStop, borderColor); + grad.addColorStop(rightFadeStop, borderColor); + grad.addColorStop(1, Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0)); + + ctx.strokeStyle = grad; + ctx.lineWidth = 1; + + ctx.beginPath(); + ctx.moveTo(r, 0.5); + ctx.lineTo(width - r, 0.5); + // Top-right curve + ctx.arcTo(width, 0.5, width, r + 0.5, r); + // Top-left curve + ctx.moveTo(width - r, 0.5); + ctx.arcTo(0, 0.5, 0, r + 0.5, r); + ctx.stroke(); + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml index ea225f093..df7df8187 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml @@ -15,17 +15,24 @@ Singleton { property string iconsPath: `${Directories.assetsPath}/icons/fluent` property bool dark: Appearance.m3colors.darkmode - property real fluentBackgroundTransparency: 0.17 - property real fluentContentTransparency: 0.3 + property real backgroundTransparency: 0.17 + property real contentTransparency: 0.25 colors: QtObject { id: colors property color bg0: root.dark ? "#1C1C1C" : "#EEEEEE" property color bg0Border: root.dark ? "#404040" : "#BEBEBE" - property color bg1: root.dark ? "#2E2E2E" : "#F7F7F7" + property color bg1: root.dark ? "#2C2C2C" : "#F7F7F7" property color bg1Hover: root.dark ? "#292929" : "#F7F7F7" property color bg1Active: root.dark ? "#252525" : "#F3F3F3" property color bg1Border: root.dark ? "#333333" : "#E9E9E9" + property color bg2: root.dark ? "#313131" : "#FBFBFB" + property color bg2Hover: root.dark ? "#383838" : "#FDFDFD" + property color bg2Active: root.dark ? "#333333" : "#FDFDFD" + property color bg2Border: root.dark ? "#464646" : "#EEEEEE" property color fg: root.dark ? "#FFFFFF" : "#000000" + property color fg1: root.dark ? "#D1D1D1" : "#626262" + property color danger: "#C42B1C" + property color dangerActive: "#B62D1F" property color brand: Appearance.m3colors.m3primary } @@ -44,12 +51,14 @@ Singleton { property string ui: "Noto Sans" } property QtObject weight: QtObject { // Noto is not Segoe, so we might use slightly different weights + property int thin: Font.Normal property int regular: Font.Medium property int strong: Font.DemiBold property int stronger: Font.Bold } property QtObject pixelSize: QtObject { property real normal: 11 + property real large: 15 } } @@ -57,15 +66,15 @@ Singleton { id: transition property QtObject easing: QtObject { property QtObject bezierCurve: QtObject { - readonly property list easeInOut: [0.42,0.00,0.58,1.00] - readonly property list easeIn: [0,1,1,1] - readonly property list easeOut: [1,0,1,1] + readonly property list easeInOut: [0.42,0.00,0.58,1.00,1,1] + readonly property list easeIn: [0,1,1,1,1,1] + readonly property list easeOut: [1,0,1,1,1,1] } } property Component color: Component { ColorAnimation { - duration: 80 + duration: 120 easing.type: Easing.BezierSpline easing.bezierCurve: transition.easing.bezierCurve.easeIn } @@ -73,7 +82,7 @@ Singleton { property Component opacity: Component { NumberAnimation{ - duration: 80 + duration: 120 easing.type: Easing.BezierSpline easing.bezierCurve: transition.easing.bezierCurve.easeIn } diff --git a/dots/.config/quickshell/ii/services/AppSearch.qml b/dots/.config/quickshell/ii/services/AppSearch.qml index 196e1bed3..7d8c375a6 100644 --- a/dots/.config/quickshell/ii/services/AppSearch.qml +++ b/dots/.config/quickshell/ii/services/AppSearch.qml @@ -151,6 +151,6 @@ Singleton { // Give up - return str; + return "application-x-executable"; } } From 20cae142d7e34fd36b8b4d8cfdfce078e4bf4602 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Wed, 12 Nov 2025 00:16:32 +0100 Subject: [PATCH 09/12] fix widget button when on the left --- dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml index 840f63c7a..7107cfafd 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml @@ -44,6 +44,7 @@ AppButton { } Column { + visible: root.expandedForm anchors.verticalCenter: parent.verticalCenter WText { text: Translation.tr("Widgets") From 945c6a07821c206b0d1bdb9dbecfce55de6e3130 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Wed, 12 Nov 2025 21:38:30 +0100 Subject: [PATCH 10/12] wbar: add tooltip and stuff --- .../modules/common/widgets/PopupToolTip.qml | 28 +++--- .../volumeMixer/VolumeDialogContent.qml | 2 +- .../ii/modules/waffle/bar/AppButton.qml | 44 ++++++++- .../ii/modules/waffle/bar/AppIcon.qml | 3 +- .../ii/modules/waffle/bar/BarButton.qml | 66 ++++++++++++-- .../ii/modules/waffle/bar/BarToolTip.qml | 8 ++ .../ii/modules/waffle/bar/SearchButton.qml | 11 +++ .../ii/modules/waffle/bar/StartButton.qml | 11 +++ .../ii/modules/waffle/bar/SystemButton.qml | 90 +++++++++++++++---- .../ii/modules/waffle/bar/TaskAppButton.qml | 25 ------ .../ii/modules/waffle/bar/TaskViewButton.qml | 5 ++ .../ii/modules/waffle/bar/TimeButton.qml | 6 ++ .../modules/waffle/bar/WaffleBarContent.qml | 1 + .../ii/modules/waffle/bar/WidgetsButton.qml | 5 ++ .../waffle/bar/tasks/TaskAppButton.qml | 71 +++++++++++++++ .../waffle/bar/{ => tasks}/TaskPreview.qml | 2 +- .../modules/waffle/bar/{ => tasks}/Tasks.qml | 8 +- .../waffle/bar/{ => tasks}/WindowPreview.qml | 1 + .../ii/modules/waffle/looks/Looks.qml | 7 +- .../ii/modules/waffle/looks/WPopupToolTip.qml | 51 +++++++++++ .../quickshell/ii/services/AppSearch.qml | 5 +- 21 files changed, 377 insertions(+), 73 deletions(-) create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/BarToolTip.qml delete mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskAppButton.qml rename dots/.config/quickshell/ii/modules/waffle/bar/{ => tasks}/TaskPreview.qml (99%) rename dots/.config/quickshell/ii/modules/waffle/bar/{ => tasks}/Tasks.qml (81%) rename dots/.config/quickshell/ii/modules/waffle/bar/{ => tasks}/WindowPreview.qml (99%) create mode 100644 dots/.config/quickshell/ii/modules/waffle/looks/WPopupToolTip.qml diff --git a/dots/.config/quickshell/ii/modules/common/widgets/PopupToolTip.qml b/dots/.config/quickshell/ii/modules/common/widgets/PopupToolTip.qml index 741b4556c..bc72ee416 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/PopupToolTip.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/PopupToolTip.qml @@ -1,3 +1,4 @@ +pragma ComponentBehavior: Bound import qs.modules.common import qs.modules.common.widgets import QtQuick @@ -13,15 +14,24 @@ Item { property real horizontalPadding: 10 property real verticalPadding: 5 + readonly property bool internalVisibleCondition: (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition property var anchorEdges: Edges.Top property var anchorGravity: anchorEdges - readonly property bool internalVisibleCondition: (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition + property Item contentItem: StyledToolTipContent { + id: contentItem + anchors.centerIn: parent + text: root.text + shown: false + Component.onCompleted: shown = true + horizontalPadding: root.horizontalPadding + verticalPadding: root.verticalPadding + } Loader { id: tooltipLoader anchors.fill: parent - active: internalVisibleCondition + active: root.internalVisibleCondition sourceComponent: PopupWindow { visible: true anchor { @@ -35,18 +45,10 @@ Item { } color: "transparent" - implicitWidth: contentItem.implicitWidth + root.horizontalPadding * 2 - implicitHeight: contentItem.implicitHeight + root.verticalPadding * 2 + implicitWidth: root.contentItem.implicitWidth + root.horizontalPadding * 2 + implicitHeight: root.contentItem.implicitHeight + root.verticalPadding * 2 - StyledToolTipContent { - id: contentItem - anchors.centerIn: parent - text: root.text - shown: false - Component.onCompleted: shown = true - horizontalPadding: root.horizontalPadding - verticalPadding: root.verticalPadding - } + data: [root.contentItem] } } } diff --git a/dots/.config/quickshell/ii/modules/ii/sidebarRight/volumeMixer/VolumeDialogContent.qml b/dots/.config/quickshell/ii/modules/ii/sidebarRight/volumeMixer/VolumeDialogContent.qml index 46d83f7de..5eb409ecb 100644 --- a/dots/.config/quickshell/ii/modules/ii/sidebarRight/volumeMixer/VolumeDialogContent.qml +++ b/dots/.config/quickshell/ii/modules/ii/sidebarRight/volumeMixer/VolumeDialogContent.qml @@ -44,7 +44,7 @@ ColumnLayout { Layout.fillHeight: false Layout.fillWidth: true Layout.bottomMargin: 6 - model: root.devices.map(node => node.description) + model: root.devices.map(node => (node.nickname || node.description || Translation.tr("Unknown"))) currentIndex: root.devices.findIndex(item => { if (root.isSink) { return item.id === Pipewire.preferredDefaultAudioSink?.id diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml index 90d0cc007..a35e12a2e 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/AppButton.qml @@ -1,5 +1,6 @@ import QtQuick import QtQuick.Layouts +import Qt5Compat.GraphicalEffects import org.kde.kirigami as Kirigami import qs.services import qs.modules.common @@ -9,7 +10,9 @@ BarButton { id: root required property string iconName + property bool multiple: false property bool separateLightDark: false + property alias tryCustomIcon: iconWidget.tryCustomIcon leftInset: 2 rightInset: 2 implicitWidth: height - topInset - bottomInset + leftInset + rightInset @@ -20,9 +23,37 @@ BarButton { contentItem.scale = root.down ? 5/6 : 1 // If/When we do dragging, the scale is 1.25 } + background: Item { + BackgroundAcrylicRectangle { + id: mainBgRect + anchors.fill: parent + layer.enabled: root.multiple + layer.effect: OpacityMask { + invert: true + maskSource: Item { + width: mainBgRect.width + height: mainBgRect.height + Rectangle { + anchors.fill: parent + anchors.rightMargin: 3 + radius: mainBgRect.radius + } + } + } + } + Loader { + anchors.fill: parent + anchors.rightMargin: 5 + active: root.multiple + sourceComponent: BackgroundAcrylicRectangle { + + } + } + } + contentItem: Item { id: contentItem - anchors.centerIn: root.background + anchors.centerIn: parent implicitHeight: iconWidget.implicitHeight implicitWidth: iconWidget.implicitWidth @@ -41,4 +72,15 @@ BarButton { separateLightDark: root.separateLightDark } } + + component BackgroundAcrylicRectangle: AcrylicRectangle { + shiny: ((root.hovered && !root.down) || root.checked) + color: root.colBackground + border.width: 1 + border.color: root.colBackgroundBorder + + Behavior on border.color { + animation: Looks.transition.color.createObject(this) + } + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml b/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml index fc5c75426..f70a80603 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/AppIcon.qml @@ -8,11 +8,12 @@ Kirigami.Icon { id: root required property string iconName property bool separateLightDark: false + property bool tryCustomIcon: true property real implicitSize: 26 implicitWidth: implicitSize implicitHeight: implicitSize roundToIconSize: false - source: `${Looks.iconsPath}/${root.iconName}${!root.separateLightDark ? "" : Looks.dark ? "-dark" : "-light"}.svg` fallback: root.iconName + source: tryCustomIcon ? `${Looks.iconsPath}/${root.iconName}${!root.separateLightDark ? "" : Looks.dark ? "-dark" : "-light"}.svg` : fallback } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml index 52e5164aa..ce1a4cdc7 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/BarButton.qml @@ -8,20 +8,70 @@ import qs.modules.waffle.looks Button { id: root + signal altAction() + signal middleClickAction() + + property color colBackground + property color colBackgroundBorder Layout.fillHeight: true topInset: 4 bottomInset: 4 + signal hoverTimedOut() + property bool shouldShowTooltip: false + property Timer hoverTimer: Timer { + id: hoverTimer + running: root.hovered + interval: 400 + onTriggered: { + root.hoverTimedOut() + } + } + onHoverTimedOut: { + root.shouldShowTooltip = true + } + onHoveredChanged: { + if (!root.hovered) { + root.shouldShowTooltip = false + root.hoverTimer.stop() + } + } + + colBackground: { + if (root.down) { + return Looks.colors.bg1Active + } else if ((root.hovered && !root.down) || root.checked) { + return Looks.colors.bg1Hover + } else { + return ColorUtils.transparentize(Looks.colors.bg1) + } + } + colBackgroundBorder: ColorUtils.transparentize(Looks.colors.bg1Border, root.checked ? Looks.contentTransparency : 1) + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton + onPressed: (event) => { + root.down = true; + } + onReleased: (event) => { + root.down = false; + } + onClicked: (event) => { + if (event.button === Qt.LeftButton) root.clicked(); + if (event.button === Qt.RightButton) root.altAction(); + if (event.button === Qt.MiddleButton) root.middleClickAction(); + } + } + background: AcrylicRectangle { shiny: ((root.hovered && !root.down) || root.checked) - color: { - if (root.down) { - return Looks.colors.bg1Active - } else if ((root.hovered && !root.down) || root.checked) { - return Looks.colors.bg1Hover - } else { - return ColorUtils.transparentize(Looks.colors.bg1) - } + color: root.colBackground + border.width: 1 + border.color: root.colBackgroundBorder + + Behavior on border.color { + animation: Looks.transition.color.createObject(this) } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/BarToolTip.qml b/dots/.config/quickshell/ii/modules/waffle/bar/BarToolTip.qml new file mode 100644 index 000000000..d38566fdd --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/BarToolTip.qml @@ -0,0 +1,8 @@ +import QtQuick +import Quickshell +import qs.modules.common +import qs.modules.waffle.looks + +WPopupToolTip { + anchorEdges: Config.options.waffles.bar.bottom ? Edges.Top : Edges.Bottom +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml index d1b59b85b..a86faaece 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/SearchButton.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Layouts import org.kde.kirigami as Kirigami +import qs import qs.services import qs.modules.common import qs.modules.waffle.looks @@ -10,4 +11,14 @@ AppButton { iconName: "system-search" separateLightDark: true + + onClicked: { + GlobalStates.overviewOpen = !GlobalStates.overviewOpen; // For now... + } + + BarToolTip { + id: tooltip + text: Translation.tr("Search") + extraVisibleCondition: root.shouldShowTooltip + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml index d5a4e0f97..4595802ee 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/StartButton.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Layouts import org.kde.kirigami as Kirigami +import qs import qs.services import qs.modules.common import qs.modules.waffle.looks @@ -10,4 +11,14 @@ AppButton { leftInset: Config.options.waffles.bar.leftAlignApps ? 12 : 0 iconName: "start-here" + + onClicked: { + GlobalStates.overviewOpen = !GlobalStates.overviewOpen; // For now... + } + + BarToolTip { + id: tooltip + text: Translation.tr("Start") + extraVisibleCondition: root.shouldShowTooltip + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml index e1bb83684..1de9654d5 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/SystemButton.qml @@ -1,5 +1,6 @@ import QtQuick import QtQuick.Layouts +import qs import qs.services import qs.modules.common import qs.modules.waffle.looks @@ -7,35 +8,88 @@ import qs.modules.waffle.looks BarButton { id: root - // padding: 12 + checked: GlobalStates.sidebarRightOpen + onClicked: { + GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen; // For now... + } contentItem: Item { - anchors.centerIn: root.background + anchors.fill: parent implicitHeight: column.implicitHeight implicitWidth: column.implicitWidth Row { id: column - anchors.centerIn: parent - spacing: 4 - - FluentIcon { - icon: WIcons.internetIcon + anchors { + top: parent.top + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter } - - FluentIcon { - icon: { - const muted = Audio.sink?.audio.muted ?? false; - const volume = Audio.sink?.audio.volume ?? 0; - if (muted) return volume > 0 ? "speaker-off" : "speaker-none"; - if (volume == 0) return "speaker-none"; - if (volume < 0.5) return "speaker-1"; - return "speaker"; + spacing: 4 + + IconHoverArea { + id: internetHoverArea + iconItem: FluentIcon { + anchors.verticalCenter: parent.verticalCenter + icon: WIcons.internetIcon } } - FluentIcon { - icon: WIcons.batteryIcon + IconHoverArea { + id: volumeHoverArea + iconItem: FluentIcon { + anchors.verticalCenter: parent.verticalCenter + icon: { + const muted = Audio.sink?.audio.muted ?? false; + const volume = Audio.sink?.audio.volume ?? 0; + if (muted) + return volume > 0 ? "speaker-off" : "speaker-none"; + if (volume == 0) + return "speaker-none"; + if (volume < 0.5) + return "speaker-1"; + return "speaker"; + } + } + } + + IconHoverArea { + id: batteryHoverArea + iconItem: FluentIcon { + anchors.verticalCenter: parent.verticalCenter + icon: WIcons.batteryIcon + } } } } + + component IconHoverArea: MouseArea { + id: hoverArea + required property var iconItem + anchors { + top: parent.top + bottom: parent.bottom + } + hoverEnabled: true + implicitHeight: hoverArea.iconItem.implicitHeight + implicitWidth: hoverArea.iconItem.implicitWidth + + onPressed: (event) => event.accepted = false; // Don't consume clicks + + children: [iconItem] + } + + BarToolTip { + extraVisibleCondition: root.shouldShowTooltip && internetHoverArea.containsMouse + text: Translation.tr("%1\nInternet access").arg(Network.ethernet ? Translation.tr("Network") : Network.networkName) + } + BarToolTip { + extraVisibleCondition: root.shouldShowTooltip && volumeHoverArea.containsMouse + text: Translation.tr("Speakers (%1): %2") // + .arg(Audio.sink?.nickname || Audio.sink?.description || Translation.tr("Unknown")) // + .arg(`${Math.round(Audio.sink?.audio.volume * 100) || 0}%`) // + } + BarToolTip { + extraVisibleCondition: root.shouldShowTooltip && batteryHoverArea.containsMouse + text: Translation.tr("Battery: %1").arg(`${Math.round(Battery.percentage * 100) || 0}%`) + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml deleted file mode 100644 index 7363b0387..000000000 --- a/dots/.config/quickshell/ii/modules/waffle/bar/TaskAppButton.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import qs.services -import qs.modules.common -import qs.modules.waffle.looks -import Quickshell - -AppButton { - id: root - - required property var appEntry - readonly property bool isSeparator: appEntry.appId === "SEPARATOR" - readonly property var desktopEntry: DesktopEntries.heuristicLookup(appEntry.appId) - - signal hoverPreviewRequested() - - iconName: AppSearch.guessIcon(appEntry.appId) - Timer { - running: root.hovered - interval: 250 - onTriggered: { - root.hoverPreviewRequested() - } - } -} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml index c3a4853f0..cc35c8b41 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TaskViewButton.qml @@ -16,4 +16,9 @@ AppButton { onClicked: { GlobalStates.overviewOpen = !GlobalStates.overviewOpen; } + + BarToolTip { + extraVisibleCondition: root.shouldShowTooltip + text: Translation.tr("Task View") // Should be a preview of workspaces, but we'll have this for now... + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml index f8e2f38cc..bb813c85c 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/TimeButton.qml @@ -33,4 +33,10 @@ BarButton { } } } + + BarToolTip { + id: tooltip + extraVisibleCondition: root.shouldShowTooltip + text: `${Qt.locale().toString(DateTime.clock.date, "dddd, MMMM d, yyyy")}\n\n${Qt.locale().toString(DateTime.clock.date, "ddd hh:mm AP")}` + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml index 5228abb5c..aa064118a 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WaffleBarContent.qml @@ -3,6 +3,7 @@ import QtQuick.Layouts import qs.modules.common import qs.modules.common.widgets import qs.modules.waffle.looks +import qs.modules.waffle.bar.tasks Rectangle { id: root diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml index 7107cfafd..1c6c11859 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/WidgetsButton.qml @@ -52,4 +52,9 @@ AppButton { } } } + + BarToolTip { + extraVisibleCondition: root.shouldShowTooltip + text: Translation.tr("Widgets") + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskAppButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskAppButton.qml new file mode 100644 index 000000000..10fdbdf38 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskAppButton.qml @@ -0,0 +1,71 @@ +import QtQuick +import QtQuick.Layouts +import qs.services +import qs.modules.common +import qs.modules.waffle.looks +import qs.modules.waffle.bar +import Quickshell + +AppButton { + id: root + + required property var appEntry + readonly property bool isSeparator: appEntry.appId === "SEPARATOR" + readonly property var desktopEntry: DesktopEntries.heuristicLookup(appEntry.appId) + property bool active: root.appEntry.toplevels.some(t => t.activated) + property bool hasWindows: appEntry.toplevels.length > 0 + + signal hoverPreviewRequested() + + multiple: appEntry.toplevels.length > 1 + checked: active + iconName: AppSearch.guessIcon(appEntry.appId) + tryCustomIcon: false + + onHoverTimedOut: { + root.hoverPreviewRequested() + } + + onClicked: { + root.hoverTimer.stop() // Prevents preview showing up when clicking to focus + if (root.multiple) { + root.hoverPreviewRequested() + } else if (root.appEntry.toplevels.length === 1) { + root.appEntry.toplevels[0].activate() + } else { + root.desktopEntry.execute() + } + } + + // Active indicator + Rectangle { + id: activeIndicator + opacity: root.hasWindows ? 1 : 0 + anchors { + horizontalCenter: root.background.horizontalCenter + bottom: root.background.bottom + bottomMargin: 1 + } + + implicitWidth: root.active ? 16 : 6 + implicitHeight: 3 + radius: height / 2 + + color: root.active ? Looks.colors.accent : Looks.colors.accentUnfocused + + Behavior on implicitWidth { + animation: Looks.transition.enter.createObject(this) + } + Behavior on color { + animation: Looks.transition.color.createObject(this) + } + Behavior on opacity { + animation: Looks.transition.opacity.createObject(this) + } + } + + BarToolTip { + extraVisibleCondition: root.shouldShowTooltip && !root.hasWindows + text: desktopEntry ? desktopEntry.name : appEntry.appId + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/TaskPreview.qml b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskPreview.qml similarity index 99% rename from dots/.config/quickshell/ii/modules/waffle/bar/TaskPreview.qml rename to dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskPreview.qml index 3c03563a3..6d8aeba1a 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/TaskPreview.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskPreview.qml @@ -70,7 +70,7 @@ PopupWindow { fill: contentItem margins: -border.width } - border.color: ColorUtils.transparentize(Looks.colors.bg0Border, Looks.contentTransparency) + border.color: ColorUtils.transparentize(Looks.colors.bg0Border, Looks.shadowTransparency) border.width: 1 color: "transparent" radius: Looks.radius.large + border.width diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/Tasks.qml similarity index 81% rename from dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml rename to dots/.config/quickshell/ii/modules/waffle/bar/tasks/Tasks.qml index eac963722..895b1353f 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/Tasks.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/Tasks.qml @@ -13,6 +13,10 @@ MouseArea { implicitWidth: row.implicitWidth hoverEnabled: true + function showPreviewPopup(appEntry, button) { + previewPopup.show(appEntry, button); + } + // Apps row RowLayout { id: row @@ -20,7 +24,7 @@ MouseArea { spacing: 0 Repeater { - // TODO: Include only apps (and windows) in current workspace only + // TODO: Include only apps (and windows) in current workspace only | wait, does that even make sense in a Hyprland workflow? model: ScriptModel { objectProp: "appId" values: TaskbarApps.apps.filter(app => app.appId !== "SEPARATOR") @@ -30,7 +34,7 @@ MouseArea { appEntry: modelData onHoverPreviewRequested: { - previewPopup.show(appEntry, this) + root.showPreviewPopup(appEntry, this) } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/WindowPreview.qml b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/WindowPreview.qml similarity index 99% rename from dots/.config/quickshell/ii/modules/waffle/bar/WindowPreview.qml rename to dots/.config/quickshell/ii/modules/waffle/bar/tasks/WindowPreview.qml index b1944c350..2839a6747 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/WindowPreview.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/WindowPreview.qml @@ -6,6 +6,7 @@ import qs.services import qs.modules.common import qs.modules.common.functions import qs.modules.waffle.looks +import qs.modules.waffle.bar import Quickshell import Quickshell.Wayland diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml index df7df8187..09176830f 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml @@ -17,6 +17,7 @@ Singleton { property real backgroundTransparency: 0.17 property real contentTransparency: 0.25 + property real shadowTransparency: 0.6 colors: QtObject { id: colors property color bg0: root.dark ? "#1C1C1C" : "#EEEEEE" @@ -33,7 +34,9 @@ Singleton { property color fg1: root.dark ? "#D1D1D1" : "#626262" property color danger: "#C42B1C" property color dangerActive: "#B62D1F" - property color brand: Appearance.m3colors.m3primary + // property color accent: root.dark ? "#A5C6D8" : "#5377A3" + property color accent: Appearance.m3colors.m3primary + property color accentUnfocused: root.dark ? "#989898" : "#848484" } radius: QtObject { @@ -106,7 +109,7 @@ Singleton { property Component move: Component { NumberAnimation { - duration: 100 + duration: 170 easing.type: Easing.BezierSpline easing.bezierCurve: transition.easing.bezierCurve.easeInOut } diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/WPopupToolTip.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WPopupToolTip.qml new file mode 100644 index 000000000..b35258204 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/looks/WPopupToolTip.qml @@ -0,0 +1,51 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import qs.modules.common +import qs.modules.common.functions +import qs.modules.common.widgets +import qs.modules.waffle.looks + +PopupToolTip { + id: root + + property real padding: 2 + verticalPadding: padding + horizontalPadding: padding + + contentItem: Item { + anchors.centerIn: parent + implicitWidth: realContent.implicitWidth + root.verticalPadding * 2 + implicitHeight: realContent.implicitHeight + root.horizontalPadding * 2 + + Rectangle { + id: ambientShadow + z: 0 + anchors { + fill: realContent + margins: -border.width + } + border.color: ColorUtils.transparentize(Looks.colors.bg0Border, Looks.shadowTransparency) + border.width: 1 + color: "transparent" + radius: realContent.radius + border.width + } + + Rectangle { + id: realContent + z: 1 + anchors.centerIn: parent + implicitWidth: tooltipText.implicitWidth + 10 * 2 + implicitHeight: tooltipText.implicitHeight + 8 * 2 + color: Looks.colors.bg1 + radius: Looks.radius.medium + + WText { + id: tooltipText + text: root.text + anchors.centerIn: parent + } + } + } +} diff --git a/dots/.config/quickshell/ii/services/AppSearch.qml b/dots/.config/quickshell/ii/services/AppSearch.qml index 7d8c375a6..d67919890 100644 --- a/dots/.config/quickshell/ii/services/AppSearch.qml +++ b/dots/.config/quickshell/ii/services/AppSearch.qml @@ -94,7 +94,7 @@ Singleton { if (!str || str.length == 0) return "image-missing"; // Quickshell's desktop entry lookup - const entry = DesktopEntries.heuristicLookup(str); + const entry = DesktopEntries.byId(str); if (entry) return entry.icon; // Normal substitutions @@ -149,6 +149,9 @@ Singleton { if (iconExists(guess)) return guess; } + // Quickshell's desktop entry lookup + const heuristicEntry = DesktopEntries.heuristicLookup(str); + if (heuristicEntry) return heuristicEntry.icon; // Give up return "application-x-executable"; From 7bfbf011d2d0b317f127093999d93a935340b9c1 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Wed, 12 Nov 2025 21:40:21 +0100 Subject: [PATCH 11/12] taskbar: middle click to launch new instance --- .../ii/modules/waffle/bar/tasks/TaskAppButton.qml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskAppButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskAppButton.qml index 10fdbdf38..53b68b82c 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskAppButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tasks/TaskAppButton.qml @@ -37,6 +37,12 @@ AppButton { } } + onMiddleClickAction: { + if (root.desktopEntry) { + desktopEntry.execute() + } + } + // Active indicator Rectangle { id: activeIndicator From df0c7bbbd68cad378d86aed0474e0d1b9a68b841 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Wed, 12 Nov 2025 21:49:12 +0100 Subject: [PATCH 12/12] Update rules.conf --- dots/.config/hypr/hyprland/rules.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/dots/.config/hypr/hyprland/rules.conf b/dots/.config/hypr/hyprland/rules.conf index dc34a4a6b..01ac1056d 100644 --- a/dots/.config/hypr/hyprland/rules.conf +++ b/dots/.config/hypr/hyprland/rules.conf @@ -154,8 +154,6 @@ layerrule = animation slide right, quickshell:sidebarRight layerrule = animation slide left, quickshell:sidebarLeft layerrule = animation slide, quickshell:verticalBar layerrule = animation slide top, quickshell:wallpaperSelector -# Quickshell - Waffles -layerrule = animation slide, quickshell:wBar # Launchers need to be FAST layerrule = noanim, gtk4-layer-shell