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 qs.Config import qs.Helpers import qs.Drawers 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 - fsTransitionProg) property color surfaceColor: DynamicColors.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 ? 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 } } 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(DynamicColors.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: Appearance.rounding.normal 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 ? 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: Appearance.rounding.smallest + 5 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: Appearance.rounding.normal } 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 ?? Appearance.rounding.normal 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: Appearance.rounding.large 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: Appearance.rounding.large + Appearance.padding.normal } PanelBg { id: dockBg deformAmount: 0.08 panel: panels.dock radius: Appearance.rounding.normal } PanelBg { id: drawingBg deformAmount: 0.08 panel: panels.drawing radius: Appearance.rounding.normal } 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: Appearance.rounding.smallest x: panel.x + geometry.insetLeft(root.borderThickness) y: panel.y + geometry.insetTop(root.borderThickness) } }