pragma ComponentBehavior: Bound import QtQuick import QtQuick.Controls import QtQuick.Effects import Quickshell import Quickshell.Io import Quickshell.Wayland import Quickshell.Hyprland import ZShell.Blobs import qs.Daemons import qs.Components import qs.Modules.Bar import ZShell.Config import qs.Helpers import qs.Drawers import qs.Services CustomWindow { id: root readonly property alias bar: bar readonly property real borderLayoutThickness: hasFullscreen ? 0 : Config.bar.border readonly property real borderRounding: Config.bar.rounding * (1 - fsTransitionProg) readonly property real borderThickness: Config.bar.border * (1 - fsTransitionProg) readonly property int dragMaskPadding: { if (focusGrab.active) return 0; if (monitor?.lastIpcObject.specialWorkspace?.name || monitor?.activeWorkspace?.lastIpcObject.windows > 0) return 0; return 100; } property real fsTransitionProg: hasFullscreen ? 1 : 0 readonly property alias geometry: geometry readonly property bool hasFullscreen: { if (hasSpecialWorkspace) { const specialName = monitor?.lastIpcObject.specialWorkspace?.name; if (!specialName) return false; const specialWs = Hypr.workspaces.values.find(ws => ws.name === specialName); return specialWs?.toplevels.values.some(t => t.lastIpcObject.fullscreen > 1) ?? false; } return hasFullscreenOnNormalWs; } readonly property bool hasFullscreenOnNormalWs: monitor?.activeWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen > 1) ?? false readonly property bool hasSpecialWorkspace: (monitor?.lastIpcObject.specialWorkspace?.name.length ?? 0) > 0 readonly property alias interactionWrapper: interactions readonly property alias menuRegion: regions.menuPopoutRegion readonly property HyprlandMonitor monitor: Hypr.monitorFor(screen) property var root: Quickshell.shellDir readonly property real sdfBorderOffset: 2 * fsTransitionProg readonly property real shadowOpacity: 0.7 * (1 - (bar.isHovered ? 0 : fsTransitionProg)) property color surfaceColor: Colors.tPalette.m3surface WlrLayershell.exclusionMode: ExclusionMode.Ignore WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.settings ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None WlrLayershell.layer: (fsTransitionProg > 0 && Config.general.showOverFullscreen) || (hasSpecialWorkspace && hasFullscreenOnNormalWs) ? WlrLayer.Overlay : WlrLayer.Top color: "transparent" contentItem.focus: true mask: visibilities.isDrawing ? null : (hasFullscreen && !bar.isHovered ? emptyRegion : regions) name: "Bar" Behavior on fsTransitionProg { Anim { } } Behavior on surfaceColor { CAnim { } } contentItem.Keys.onEscapePressed: { if (Config.bar.autoHide) visibilities.bar = false; visibilities.launcher = false; visibilities.sidebar = false; visibilities.dashboard = false; visibilities.osd = false; visibilities.settings = false; visibilities.resources = false; visibilities.dock = false; visibilities.clipboard = false; panels.popouts.hasCurrent = false; } onHasFullscreenChanged: { visibilities.launcher = false; visibilities.sidebar = false; visibilities.dashboard = false; visibilities.osd = false; visibilities.settings = false; visibilities.resources = false; visibilities.clipboard = false; visibilities.dock = false; panels.popouts.hasCurrent = false; } EdgeGeometry { id: geometry bar: bar configPosition: Config.bar.position win: root } Region { id: emptyRegion height: panels.notifications.height width: panels.notifications.width x: panels.notifications.x + geometry.insetLeft(root.borderThickness) y: panels.notifications.y + geometry.insetTop(root.borderThickness) Region { height: panels.osd.height width: panels.osdWrapper.width * (1 - panels.osd.offsetScale) + root.borderThickness x: root.width - width y: panels.osdWrapper.y + bar.implicitHeight } Region { height: geometry.horizontal ? 1 : root.screen.height width: geometry.horizontal ? root.screen.width : 1 y: geometry.position === "bottom" ? root.screen.height - 1 : 0 } } Regions { id: regions geometry: geometry panels: panels win: root } anchors { bottom: true left: true right: true top: true } HyprlandFocusGrab { id: focusGrab active: visibilities.dock || visibilities.resources || visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || visibilities.clipboard || (panels.popouts.hasCurrent && panels.popouts.currentName.startsWith("traymenu") && (!Config.bar.tray.showOnHover || (panels.popouts.current as StackView)?.depth > 1)) windows: [root] onCleared: { visibilities.launcher = false; visibilities.sidebar = false; visibilities.dashboard = false; visibilities.osd = false; visibilities.settings = false; visibilities.resources = false; visibilities.clipboard = false; visibilities.dock = false; panels.popouts.hasCurrent = false; } } PersistentProperties { id: visibilities property bool bar property bool clipboard property bool dashboard property bool dock property bool isDrawing property bool launcher property bool notif: NotifServer.popups.length > 0 property bool osd property bool resources property bool settings property bool sidebar Component.onCompleted: Visibilities.load(root.screen, this) } Binding { property: "bar" target: visibilities value: visibilities.sidebar || visibilities.dashboard || visibilities.osd || (!Config.bar.hideWhenNotif && visibilities.notif) || visibilities.resources || visibilities.settings || bar.isHovered when: Config.bar.autoHide } Item { id: surface anchors.fill: parent layer.enabled: true opacity: root.surfaceColor.a layer.effect: MultiEffect { blurMax: 32 shadowColor: Qt.alpha(Colors.palette.m3shadow, Math.max(0, root.shadowOpacity)) shadowEnabled: true } BlobGroup { id: blobGroup color: root.surfaceColor smoothing: Config.bar.smoothing } BlobInvertedRect { anchors.fill: parent anchors.margins: -50 borderBottom: geometry.insetBottom(root.borderThickness) - anchors.margins - root.sdfBorderOffset borderLeft: geometry.insetLeft(root.borderThickness) - anchors.margins - root.sdfBorderOffset borderRight: root.borderThickness - anchors.margins - root.sdfBorderOffset borderTop: geometry.insetTop(root.borderThickness) - anchors.margins - root.sdfBorderOffset group: blobGroup radius: root.borderRounding } PanelBg { id: dashBg property real extraExtent: 0.2 deformAmount: 0.06 implicitHeight: panels.dashboard.height * (geometry.horizontal ? 1 + extraExtent : 1) implicitWidth: panels.dashboard.width * (geometry.horizontal ? 1 : 1 + extraExtent) panel: panels.dashboardWrapper radius: Tokens.rounding.extraLarge x: panels.dashboardWrapper.x + panels.dashboard.x + geometry.insetLeft(root.borderThickness) - (geometry.horizontal ? 0 : panels.dashboard.width * extraExtent) y: panels.dashboardWrapper.y + panels.dashboard.y + geometry.insetTop(root.borderThickness) - (geometry.horizontal && geometry.position !== "bottom" ? panels.dashboard.height * extraExtent : 0) } PanelBg { id: launcherBg property real extraHeight: 0.2 deformAmount: 0.06 implicitHeight: panels.launcher.height * (1 + extraHeight) panel: panels.launcher radius: Tokens.rounding.medium + (Tokens.padding.largeIncreased / 4) y: panels.launcher.y + geometry.insetTop(root.borderThickness) } PanelBg { id: sidebarBg bottomLeftRadius: 0 deformAmount: 0.04 exclude: panels.sidebar.offsetScale > 0.08 ? [] : [utilsBg] implicitHeight: panel.height * (1 / rawDeformMatrix.m22) + 2 panel: panels.sidebar } PanelBg { id: osdBg deformAmount: 0.1 implicitHeight: panels.osd.height implicitWidth: panels.osd.width panel: panels.osdWrapper radius: 20 x: panels.osdWrapper.x + panels.osd.x + geometry.insetLeft(root.borderThickness) } PanelBg { id: notifsBg panel: panels.notifications radius: Tokens.rounding.large } PanelBg { id: utilsBg deformAmount: 0.1 exclude: panels.sidebar.offsetScale > 0.08 ? [] : [sidebarBg] panel: panels.utilities topLeftRadius: 0 } PanelBg { id: popoutBg property real extraExtent: 0.2 deformAmount: panels.popouts.currentName.startsWith("traymenu") ? 0.15 : 0.08 implicitHeight: panels.popouts.height * (geometry.horizontal ? 1 + extraExtent : 1) implicitWidth: panels.popouts.width * (geometry.horizontal ? 1 : 1 + extraExtent) panel: panels.popoutsWrapper radius: panels.popouts.current?.panelRadius ?? Tokens.rounding.large x: panels.popoutsWrapper.x + panels.popouts.x + geometry.insetLeft(root.borderThickness) - (geometry.horizontal ? 0 : panels.popouts.width * extraExtent) y: panels.popoutsWrapper.y + panels.popouts.y + geometry.insetTop(root.borderThickness) - (geometry.barOnTop ? panels.popouts.height * extraExtent : 0) Behavior on extraExtent { Anim { } } } PanelBg { id: resourcesBg deformAmount: 0.05 implicitHeight: panels.resources.height implicitWidth: panels.resources.width panel: panels.resourcesWrapper radius: Tokens.rounding.largeIncreased + Tokens.padding.small x: panels.resourcesWrapper.x + panels.resources.x + geometry.insetLeft(root.borderThickness) y: panels.resourcesWrapper.y + panels.resources.y + geometry.insetTop(root.borderThickness) } PanelBg { id: settingsBg deformAmount: 0.03 panel: panels.settings radius: Tokens.rounding.largeIncreased + Tokens.padding.small } PanelBg { id: dockBg deformAmount: 0.08 panel: panels.dock radius: Tokens.rounding.medium } PanelBg { id: drawingBg deformAmount: 0.08 panel: panels.drawing radius: Tokens.rounding.medium } PanelBg { id: clipboardBg deformAmount: 0.03 panel: panels.clipboard radius: 29 } } Drawing { id: drawing anchors.fill: parent layer.enabled: true visibilities: visibilities z: 2 layer.effect: MultiEffect { maskEnabled: true maskInverted: true maskSource: maskSource } } Item { id: maskSource anchors.fill: parent layer.enabled: true visible: false CustomRect { readonly property int extraWidth: radius color: "white" implicitHeight: panels.drawing.height implicitWidth: panels.drawing.width + extraWidth radius: drawingBg.radius x: -extraWidth + root.borderThickness + panels.drawing.x y: panels.drawing.y + bar.implicitHeight } } Interactions { id: interactions anchors.fill: parent bar: bar borderThickness: root.borderLayoutThickness drawing: drawing enabled: true geometry: geometry panels: panels popouts: panels.popouts screen: root.screen visibilities: visibilities Panels { id: panels bar: bar borderThickness: root.borderThickness drawingItem: drawing geometry: geometry screen: root.screen visibilities: visibilities clipboard.transform: Matrix4x4 { matrix: clipboardBg.deformMatrix } dashboard.transform: Matrix4x4 { matrix: dashBg.deformMatrix } dock.transform: Matrix4x4 { matrix: dockBg.deformMatrix } launcher.transform: Matrix4x4 { matrix: launcherBg.deformMatrix } notifications.transform: Matrix4x4 { matrix: notifsBg.deformMatrix } osd.transform: Matrix4x4 { matrix: osdBg.deformMatrix } popouts.transform: Matrix4x4 { matrix: popoutBg.deformMatrix } resources.transform: Matrix4x4 { matrix: resourcesBg.deformMatrix } settings.transform: Matrix4x4 { matrix: settingsBg.deformMatrix } sidebar.transform: Matrix4x4 { matrix: sidebarBg.deformMatrix } utilities.transform: Matrix4x4 { matrix: utilsBg.deformMatrix } } BarLoader { id: bar anchors.bottom: geometry.barOnBottom ? parent.bottom : undefined anchors.left: parent.left anchors.top: geometry.barOnBottom ? undefined : parent.top enabled: !visibilities.isDrawing fullscreen: root.hasFullscreen height: geometry.horizontal ? implicitHeight : parent.height popouts: panels.popouts popoutsWrapper: panels.popoutsWrapper position: geometry.position screen: root.screen visibilities: visibilities width: geometry.horizontal ? parent.width : implicitWidth } } component PanelBg: BlobRect { property real deformAmount: 0.15 required property Item panel deformScale: (deformAmount * Config.appearance.deform.scale) / 10000 group: blobGroup implicitHeight: panel.height implicitWidth: panel.width radius: Tokens.rounding.small x: panel.x + geometry.insetLeft(root.borderThickness) y: panel.y + geometry.insetTop(root.borderThickness) } }