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