waffles: add action center window

This commit is contained in:
end-4
2025-11-16 23:52:07 +01:00
parent 71e0538cf5
commit 2d65af70ad
14 changed files with 321 additions and 43 deletions
+2
View File
@@ -133,12 +133,14 @@ layerrule = blurpopups, quickshell:.*
layerrule = blur, quickshell:.*
layerrule = ignorealpha 0.79, quickshell:.*
layerrule = animation slide, quickshell:bar
layerrule = noanim, quickshell:actionCenter
layerrule = animation slide bottom, quickshell:cheatsheet
layerrule = animation slide bottom, quickshell:dock
layerrule = animation popin 120%, quickshell:screenCorners
layerrule = noanim, quickshell:lockWindowPusher
layerrule = animation fade, quickshell:notificationPopup
layerrule = noanim, quickshell:overlay
layerrule = ignorealpha 1, quickshell:overlay
layerrule = noanim, quickshell:overview
layerrule = animation slide bottom, quickshell:osk
layerrule = noanim, quickshell:polkit
@@ -0,0 +1 @@
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12.012 2.25c.734.008 1.465.093 2.182.253a.75.75 0 0 1 .582.649l.17 1.527a1.384 1.384 0 0 0 1.927 1.116l1.401-.615a.75.75 0 0 1 .85.174 9.792 9.792 0 0 1 2.204 3.792.75.75 0 0 1-.271.825l-1.242.916a1.381 1.381 0 0 0 0 2.226l1.243.915a.75.75 0 0 1 .272.826 9.797 9.797 0 0 1-2.204 3.792.75.75 0 0 1-.848.175l-1.407-.617a1.38 1.38 0 0 0-1.926 1.114l-.169 1.526a.75.75 0 0 1-.572.647 9.518 9.518 0 0 1-4.406 0 .75.75 0 0 1-.572-.647l-.168-1.524a1.382 1.382 0 0 0-1.926-1.11l-1.406.616a.75.75 0 0 1-.849-.175 9.798 9.798 0 0 1-2.204-3.796.75.75 0 0 1 .272-.826l1.243-.916a1.38 1.38 0 0 0 0-2.226l-1.243-.914a.75.75 0 0 1-.271-.826 9.793 9.793 0 0 1 2.204-3.792.75.75 0 0 1 .85-.174l1.4.615a1.387 1.387 0 0 0 1.93-1.118l.17-1.526a.75.75 0 0 1 .583-.65c.717-.159 1.45-.243 2.201-.252Zm0 1.5a9.135 9.135 0 0 0-1.354.117l-.109.977A2.886 2.886 0 0 1 6.525 7.17l-.898-.394a8.293 8.293 0 0 0-1.348 2.317l.798.587a2.881 2.881 0 0 1 0 4.643l-.799.588c.32.842.776 1.626 1.348 2.322l.905-.397a2.882 2.882 0 0 1 4.017 2.318l.11.984c.889.15 1.798.15 2.687 0l.11-.984a2.881 2.881 0 0 1 4.018-2.322l.905.396a8.296 8.296 0 0 0 1.347-2.318l-.798-.588a2.881 2.881 0 0 1 0-4.643l.796-.587a8.293 8.293 0 0 0-1.348-2.317l-.896.393a2.884 2.884 0 0 1-4.023-2.324l-.11-.976a8.988 8.988 0 0 0-1.333-.117ZM12 8.25a3.75 3.75 0 1 1 0 7.5 3.75 3.75 0 0 1 0-7.5Zm0 1.5a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Z" fill="#212121"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -0,0 +1,77 @@
import QtQuick
import QtQuick.Layouts
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.waffle.looks
WBarAttachedPanelContent {
id: root
contentItem: ColumnLayout {
anchors.centerIn: parent
spacing: 0
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
topLeftRadius: root.border.radius - root.border.border.width
topRightRadius: topLeftRadius
color: Looks.colors.bgPanelBody
implicitWidth: 360
implicitHeight: 380
}
Rectangle {
Layout.fillHeight: false
Layout.fillWidth: true
color: Looks.colors.bgPanelSeparator
implicitHeight: 1
}
Rectangle {
Layout.fillHeight: false
Layout.fillWidth: true
bottomLeftRadius: root.border.radius - root.border.border.width
bottomRightRadius: bottomLeftRadius
color: Looks.colors.bgPanelFooter
implicitWidth: 360
implicitHeight: 47
// Battery button
WPanelFooterButton {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 12
contentItem: Row {
spacing: 4
FluentIcon {
anchors.verticalCenter: parent.verticalCenter
icon: WIcons.batteryIcon
}
WText {
anchors.verticalCenter: parent.verticalCenter
text: `${Math.round(Battery.percentage * 100) || 0}%`
}
}
}
// Settings button
WPanelFooterButton {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 12
contentItem: FluentIcon {
icon: "settings"
}
}
}
}
}
@@ -0,0 +1,85 @@
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: root
Connections {
target: GlobalStates
function onSidebarLeftOpenChanged() {
if (GlobalStates.sidebarLeftOpen) barLoader.active = true;
}
}
Loader {
id: barLoader
active: GlobalStates.sidebarLeftOpen
sourceComponent: PanelWindow {
id: panelWindow
exclusiveZone: 0
WlrLayershell.namespace: "quickshell:actionCenter"
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
color: "transparent"
anchors {
bottom: Config.options.waffles.bar.bottom
top: !Config.options.waffles.bar.bottom
right: true
}
implicitWidth: content.implicitWidth + content.visualMargin * 2
implicitHeight: content.implicitHeight + content.visualMargin * 2
HyprlandFocusGrab {
id: focusGrab
active: true
windows: [panelWindow]
onCleared: content.close();
}
Connections {
target: GlobalStates
function onSidebarLeftOpenChanged() {
if (!GlobalStates.sidebarLeftOpen) content.close();
}
}
ActionCenterContent {
id: content
anchors.centerIn: parent
onClosed: {
barLoader.active = false;
GlobalStates.sidebarLeftOpen = false;
}
}
}
}
function toggleOpen() {
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen;
}
IpcHandler {
target: "sidebarLeft"
function toggle() {
root.toggleOpen();
}
}
GlobalShortcut {
name: "sidebarLeftToggle"
description: "Toggles left sidebar on press"
onPressed: root.toggleOpen();
}
}
@@ -70,8 +70,8 @@ Loader {
focusGrab.active = true; // Doesn't work
}
implicitWidth: realContent.implicitWidth + (ambientShadow.border.width * 2) + (root.visualMargin * 2)
implicitHeight: realContent.implicitHeight + (ambientShadow.border.width * 2) + (root.visualMargin * 2)
implicitWidth: realContent.implicitWidth + (root.ambientShadowWidth * 2) + (root.visualMargin * 2)
implicitHeight: realContent.implicitHeight + (root.ambientShadowWidth * 2) + (root.visualMargin * 2)
property real sourceEdgeMargin: -implicitHeight
PropertyAnimation {
@@ -101,17 +101,8 @@ Loader {
}
color: "transparent"
Rectangle {
id: ambientShadow
z: 0
anchors {
fill: realContent
margins: -border.width
}
border.color: ColorUtils.transparentize(Looks.colors.ambientShadow, Looks.shadowTransparency)
border.width: root.ambientShadowWidth
color: "transparent"
radius: realContent.radius + border.width
WAmbientShadow {
target: realContent
}
Rectangle {
@@ -8,9 +8,9 @@ import qs.modules.waffle.looks
BarButton {
id: root
checked: GlobalStates.sidebarRightOpen
checked: GlobalStates.sidebarLeftOpen
onClicked: {
GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen; // For now...
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen;
}
contentItem: Item {
@@ -9,9 +9,8 @@ import qs.modules.common
import qs.modules.common.widgets
Scope {
id: bar
property bool showBarBackground: Config.options.bar.showBackground
id: root
LazyLoader {
id: barLoader
active: GlobalStates.barOpen && !GlobalStates.screenLocked
@@ -36,7 +36,7 @@ PopupWindow {
///////////////////// Internals /////////////////////
readonly property bool bottom: Config.options.waffles.bar.bottom
property real visualMargin: 12
property alias ambientShadowWidth: ambientShadow.border.width
property real ambientShadowWidth: 1
visible: false
color: "transparent"
@@ -64,16 +64,8 @@ PopupWindow {
hoverEnabled: true
// Shadow
Rectangle {
id: ambientShadow
anchors {
fill: contentItem
margins: -border.width
}
border.color: ColorUtils.transparentize(Looks.colors.ambientShadow, Looks.shadowTransparency)
border.width: 1
color: "transparent"
radius: Looks.radius.large + border.width
WAmbientShadow {
target: contentItem
}
Rectangle {
@@ -17,10 +17,12 @@ Singleton {
property real backgroundTransparency: 0.17
property real contentTransparency: 0.25
property real shadowTransparency: 0.6
colors: QtObject {
id: colors
property color ambientShadow: ColorUtils.transparentize("#000000", 0.4)
property color ambientShadow: ColorUtils.transparentize("#000000", 0.75)
property color bgPanelFooter: root.dark ? "#1C1C1C" : "#EEEEEE"
property color bgPanelBody: root.dark ? "#242424" : "#F2F2F2"
property color bgPanelSeparator: root.dark ? "#191919" : "#E0E0E0"
property color bg0: root.dark ? "#1C1C1C" : "#EEEEEE"
property color bg0Border: root.dark ? "#404040" : "#BEBEBE"
property color bg1: root.dark ? "#2C2C2C" : "#F7F7F7"
@@ -0,0 +1,25 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Hyprland
import qs.modules.common
import qs.modules.common.functions
import qs.modules.waffle.looks
Rectangle {
id: root
required property var target
z: 0
anchors {
fill: target
margins: -border.width
}
border.color: Looks.colors.ambientShadow
border.width: 1
color: "transparent"
radius: target.radius + border.width
}
@@ -0,0 +1,79 @@
import QtQuick
import QtQuick.Layouts
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.waffle.looks
Item {
id: root
signal closed()
property alias border: borderRect
required default property Item contentItem
property real visualMargin: 12
function close() {
closeAnim.start();
}
readonly property bool barAtBottom: Config.options.waffles.bar.bottom
implicitHeight: borderRect.implicitHeight
implicitWidth: borderRect.implicitWidth
Rectangle {
id: borderRect
color: "transparent"
radius: Looks.radius.large
border.color: Looks.colors.bg2Border
border.width: 1
implicitWidth: contentItem.implicitWidth + border.width * 2
implicitHeight: contentItem.implicitHeight + border.width * 2
children: [root.contentItem]
anchors {
left: parent.left
right: parent.right
top: root.barAtBottom ? undefined : parent.top
bottom: root.barAtBottom ? parent.bottom : undefined
// Opening anim
bottomMargin: root.barAtBottom ? sourceEdgeMargin : 0
topMargin: root.barAtBottom ? 0 : sourceEdgeMargin
}
Component.onCompleted: {
openAnim.start();
}
property real sourceEdgeMargin: -(implicitHeight + root.visualMargin)
PropertyAnimation {
id: openAnim
target: borderRect
property: "sourceEdgeMargin"
to: 0
duration: 200
easing.type: Easing.BezierSpline
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
}
SequentialAnimation {
id: closeAnim
PropertyAnimation {
target: borderRect
property: "sourceEdgeMargin"
to: -(implicitHeight + root.visualMargin)
duration: 150
easing.type: Easing.BezierSpline
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut
}
ScriptAction {
script: {
root.closed();
}
}
}
}
}
@@ -0,0 +1,32 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import qs.modules.common
import qs.modules.common.functions
import qs.modules.waffle.looks
Button {
id: root
implicitHeight: 36
property color colBackground: ColorUtils.transparentize(Looks.colors.bg1)
property color colBackgroundHover: Looks.colors.bg1Hover
property color colBackgroundActive: Looks.colors.bg1Active
property color color
property color colForeground: Looks.colors.fg
color: {
if (root.down) {
return root.colBackgroundActive
} else if ((root.hovered && !root.down) || root.checked) {
return root.colBackgroundHover
} else {
return root.colBackground
}
}
background: Rectangle {
radius: Looks.radius.medium
color: root.color
}
}
@@ -27,17 +27,8 @@ PopupToolTip {
implicitWidth: realContent.implicitWidth + 2 * 2
implicitHeight: realContent.implicitHeight + 2 * 2
Rectangle {
id: ambientShadow
z: 0
anchors {
fill: realContent
margins: -border.width
}
border.color: ColorUtils.transparentize(Looks.colors.ambientShadow, Looks.shadowTransparency)
border.width: 1
color: "transparent"
radius: realContent.radius + border.width
WAmbientShadow {
target: realContent
}
Rectangle {
+3 -1
View File
@@ -28,6 +28,7 @@ import qs.modules.ii.overlay
import qs.modules.ii.verticalBar
import qs.modules.ii.wallpaperSelector
import qs.modules.waffle.actionCenter
import qs.modules.waffle.background
import qs.modules.waffle.bar
@@ -75,6 +76,7 @@ ShellRoot {
PanelLoader { identifier: "iiSidebarRight"; component: SidebarRight {} }
PanelLoader { identifier: "iiVerticalBar"; extraCondition: Config.options.bar.vertical; component: VerticalBar {} }
PanelLoader { identifier: "iiWallpaperSelector"; component: WallpaperSelector {} }
PanelLoader { identifier: "wActionCenter"; component: WaffleActionCenter {} }
PanelLoader { identifier: "wBar"; component: WaffleBar {} }
PanelLoader { identifier: "wBackground"; component: WaffleBackground {} }
@@ -88,7 +90,7 @@ ShellRoot {
property list<string> 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", "wBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiWallpaperSelector"],
"waffle": ["wBar", "wBackground", "wActionCenter", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiSessionScreen", "iiSidebarRight", "iiWallpaperSelector"],
})
function cyclePanelFamily() {
const currentIndex = families.indexOf(Config.options.panelFamily)