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 ScreenState screenState: ShellState.forScreen(screen) readonly property real sdfBorderOffset: 2 * fsTransitionProg readonly property real shadowOpacity: 0.5 * (1 - (bar.isHovered ? 0 : fsTransitionProg)) property color surfaceColor: Colors.tPalette.m3surface WlrLayershell.exclusionMode: ExclusionMode.Ignore WlrLayershell.keyboardFocus: screenState.screenshot ? WlrKeyboardFocus.Exclusive : screenState.launcher || screenState.settings || screenState.sidebar ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None WlrLayershell.layer: (fsTransitionProg > 0 && Config.general.showOverFullscreen) || (hasSpecialWorkspace && hasFullscreenOnNormalWs) ? WlrLayer.Overlay : WlrLayer.Top color: "transparent" mask: screenState.isDrawing || screenState.screenshot ? null : (hasFullscreen && !bar.isHovered ? emptyRegion : regions) name: "Bar" Behavior on fsTransitionProg { Anim { } } Behavior on surfaceColor { CAnim { } } contentItem.Keys.onEscapePressed: { if (Config.bar.autoHide) screenState.bar = false; screenState.launcher = false; screenState.sidebar = false; screenState.dashboard = false; screenState.osd = false; screenState.settings = false; screenState.resources = false; screenState.dock = false; screenState.clipboard = false; panels.popouts.hasCurrent = false; } onHasFullscreenChanged: { screenState.launcher = false; screenState.sidebar = false; screenState.dashboard = false; screenState.osd = false; screenState.settings = false; screenState.resources = false; screenState.clipboard = false; screenState.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: { const s = root.screenState; const c = Config; if ((s.launcher && c.launcher.enabled) || (s.sidebar && c.sidebar.enabled) || (s.resources && c.dashboard.performance.enabled) || (s.clipboard && c.clipboard.enabled)) return true; if (s.dashboard && !c.dashboard.showOnHover && c.dashboard.enabled) return true; if (!c.dock.hoverToReveal && s.dock && c.dock.enable) return true; if (panels.popouts.currentName.startsWith("traymenu") && (panels.popouts.current as StackView)?.depth > 1) return true; if (s.settings) return true; return false; } windows: [root] onCleared: { root.screenState.launcher = false; root.screenState.sidebar = false; root.screenState.dashboard = false; root.screenState.osd = false; root.screenState.settings = false; root.screenState.resources = false; root.screenState.clipboard = false; root.screenState.dock = false; panels.popouts.hasCurrent = false; } } Binding { property: "bar" target: root.screenState value: root.screenState.sidebar || root.screenState.dashboard || root.screenState.osd || (!Config.bar.hideWhenNotif && NotifServer.popups.length > 0) || root.screenState.resources || root.screenState.settings || bar.isHovered when: Config.bar.autoHide } Item { id: surface anchors.fill: parent opacity: root.surfaceColor.a BlobGroup2 { id: blobGroup anchors.fill: parent color: root.surfaceColor shadowColor: Qt.alpha(Colors.palette.m3shadow, Math.max(0, root.shadowOpacity)) shadowRadius: 18 smoothing: Config.bar.smoothing } BlobInvertedRect2 { 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 atRestOverride: panels.osd.offsetScale < 0.99 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 atRestOverride: panel.implicitHeight > 0 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 property real extraExtent: 0.2 atRestOverride: panels.resources.offsetScale < 0.99 deformAmount: 0.05 implicitHeight: panels.resources.height * (1 + extraExtent) implicitWidth: panels.resources.width * (1 + extraExtent) panel: panels.resourcesWrapper radius: Tokens.rounding.largeIncreased + Tokens.padding.small x: panels.resourcesWrapper.x + panels.resources.x + geometry.insetLeft(root.borderThickness) - panels.resources.width * extraExtent y: panels.resourcesWrapper.y + panels.resources.y + geometry.insetTop(root.borderThickness) - panels.resources.height * extraExtent } 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 property real extraExtent: 0.2 deformAmount: 0.03 implicitHeight: panels.clipboard.height * (1 + extraExtent) implicitWidth: panels.clipboard.width * (1 + extraExtent) panel: panels.clipboard radius: 29 x: panels.clipboard.x + geometry.insetLeft(root.borderThickness) - panels.clipboard.width * extraExtent y: panels.clipboard.y + geometry.insetTop(root.borderThickness) } } Drawing { id: drawing anchors.fill: parent screenState: root.screenState z: 2 } Interactions2 { id: interactions anchors.fill: parent bar: bar borderThickness: root.borderLayoutThickness drawing: drawing enabled: true geometry: geometry panels: panels popouts: panels.popouts screen: root.screen screenState: root.screenState Panels { id: panels bar: bar borderThickness: root.borderThickness drawingItem: drawing geometry: geometry screen: root.screen screenState: root.screenState 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: !screenState.isDrawing fullscreen: root.hasFullscreen height: geometry.horizontal ? implicitHeight : parent.height popouts: panels.popouts popoutsWrapper: panels.popoutsWrapper position: geometry.position screen: root.screen screenState: root.screenState width: geometry.horizontal ? parent.width : implicitWidth } } LazyLoader { id: loader property bool closing: !root.screenState.screenshot onClosingChanged: if (!closing) activeAsync = true Picker { loader: loader parent: root.contentItem screen: root.screen screenState: root.screenState } } component PanelBg: BlobRect2 { property real deformAmount: 0.15 required property Item panel atRestOverride: panel?.offsetScale < 0.99 ?? false damping: 28.3 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) } }