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] 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() + } }