This commit is contained in:
pika 2025-06-10 15:34:15 +02:00
parent 32edcff102
commit 0296117901
110 changed files with 9713 additions and 5 deletions

View file

@ -0,0 +1,66 @@
import "root:/services"
import "root:/config"
import "root:/modules/osd" as Osd
import "root:/modules/notifications" as Notifications
import "root:/modules/session" as Session
import "root:/modules/launcher" as Launcher
import "root:/modules/dashboard" as Dashboard
import "root:/modules/bar/popouts" as BarPopouts
import QtQuick
import QtQuick.Shapes
Shape {
id: root
required property Panels panels
required property Item bar
anchors.fill: parent
anchors.margins: BorderConfig.thickness
anchors.leftMargin: bar.implicitWidth
preferredRendererType: Shape.CurveRenderer
opacity: Colours.transparency.enabled ? Colours.transparency.base : 1
Osd.Background {
wrapper: panels.osd
startX: root.width - panels.session.width
startY: (root.height - wrapper.height) / 2 - rounding
}
Notifications.Background {
wrapper: panels.notifications
startX: root.width
startY: 0
}
Session.Background {
wrapper: panels.session
startX: root.width
startY: (root.height - wrapper.height) / 2 - rounding
}
Launcher.Background {
wrapper: panels.launcher
startX: (root.width - wrapper.width) / 2 - rounding
startY: root.height
}
Dashboard.Background {
wrapper: panels.dashboard
startX: (root.width - wrapper.width) / 2 - rounding
startY: 0
}
BarPopouts.Background {
wrapper: panels.popouts
invertBottomRounding: wrapper.y + wrapper.height + 1 >= root.height
startX: 0
startY: wrapper.y - rounding
}
}

View file

@ -0,0 +1,47 @@
import "root:/widgets"
import "root:/services"
import "root:/config"
import Quickshell
import QtQuick
import QtQuick.Effects
Item {
id: root
required property Item bar
anchors.fill: parent
StyledRect {
id: rect
anchors.fill: parent
color: Colours.alpha(BorderConfig.colour, false)
visible: false
}
Item {
id: mask
anchors.fill: parent
layer.enabled: true
visible: false
Rectangle {
anchors.fill: parent
anchors.margins: BorderConfig.thickness
anchors.leftMargin: root.bar.implicitWidth
radius: BorderConfig.rounding
}
}
MultiEffect {
anchors.fill: parent
maskEnabled: true
maskInverted: true
maskSource: mask
source: rect
maskThresholdMin: 0.5
maskSpreadAtMin: 1
}
}

147
modules/drawers/Drawers.qml Normal file
View file

@ -0,0 +1,147 @@
pragma ComponentBehavior: Bound
import "root:/widgets"
import "root:/services"
import "root:/config"
import "root:/modules/bar"
import Quickshell
import Quickshell.Wayland
import Quickshell.Hyprland
import QtQuick
import QtQuick.Effects
Variants {
model: Quickshell.screens
Scope {
id: scope
required property ShellScreen modelData
Exclusions {
screen: scope.modelData
bar: bar
}
StyledWindow {
id: win
screen: scope.modelData
name: "drawers"
WlrLayershell.exclusionMode: ExclusionMode.Ignore
WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.session ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
mask: Region {
x: bar.implicitWidth
y: BorderConfig.thickness
width: win.width - bar.implicitWidth - BorderConfig.thickness
height: win.height - BorderConfig.thickness * 2
intersection: Intersection.Xor
regions: regions.instances
}
anchors.top: true
anchors.bottom: true
anchors.left: true
anchors.right: true
Variants {
id: regions
model: panels.children
Region {
required property Item modelData
x: modelData.x + bar.implicitWidth
y: modelData.y + BorderConfig.thickness
width: modelData.width
height: modelData.height
intersection: Intersection.Subtract
}
}
HyprlandFocusGrab {
active: visibilities.launcher || visibilities.session
windows: [win]
onCleared: {
visibilities.launcher = false;
visibilities.session = false;
}
}
StyledRect {
anchors.fill: parent
opacity: visibilities.session ? 0.5 : 0
color: Colours.palette.m3scrim
Behavior on opacity {
NumberAnimation {
duration: Appearance.anim.durations.normal
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard
}
}
}
Item {
id: background
anchors.fill: parent
visible: false
Border {
bar: bar
}
Backgrounds {
panels: panels
bar: bar
}
}
MultiEffect {
anchors.fill: source
source: background
shadowEnabled: true
blurMax: 15
shadowColor: Qt.alpha(Colours.palette.m3shadow, 0.7)
}
PersistentProperties {
id: visibilities
property bool osd
property bool session
property bool launcher
property bool dashboard
Component.onCompleted: Visibilities.screens[scope.modelData] = this
}
Interactions {
screen: scope.modelData
popouts: panels.popouts
visibilities: visibilities
panels: panels
bar: bar
Panels {
id: panels
screen: scope.modelData
visibilities: visibilities
bar: bar
}
}
Bar {
id: bar
screen: scope.modelData
popouts: panels.popouts
}
}
}
}

View file

@ -0,0 +1,36 @@
pragma ComponentBehavior: Bound
import "root:/widgets"
import "root:/config"
import Quickshell
import QtQuick
Scope {
id: root
required property ShellScreen screen
required property Item bar
ExclusionZone {
anchors.left: true
exclusiveZone: root.bar.implicitWidth
}
ExclusionZone {
anchors.top: true
}
ExclusionZone {
anchors.right: true
}
ExclusionZone {
anchors.bottom: true
}
component ExclusionZone: StyledWindow {
screen: root.screen
name: "border-exclusion"
exclusiveZone: BorderConfig.thickness
}
}

View file

@ -0,0 +1,83 @@
import "root:/services"
import "root:/config"
import "root:/modules/bar/popouts" as BarPopouts
import "root:/modules/osd" as Osd
import Quickshell
import QtQuick
MouseArea {
id: root
required property ShellScreen screen
required property BarPopouts.Wrapper popouts
required property PersistentProperties visibilities
required property Panels panels
required property Item bar
property bool osdHovered
property point dragStart
function withinPanelHeight(panel: Item, x: real, y: real): bool {
const panelY = BorderConfig.thickness + panel.y;
return y >= panelY - BorderConfig.rounding && y <= panelY + panel.height + BorderConfig.rounding;
}
function inRightPanel(panel: Item, x: real, y: real): bool {
return x > bar.implicitWidth + panel.x && withinPanelHeight(panel, x, y);
}
function inTopPanel(panel: Item, x: real, y: real): bool {
const panelX = bar.implicitWidth + panel.x;
return y < BorderConfig.thickness + panel.y + panel.height && x >= panelX - BorderConfig.rounding && x <= panelX + panel.width + BorderConfig.rounding;
}
anchors.fill: parent
hoverEnabled: true
onPressed: event => dragStart = Qt.point(event.x, event.y)
onContainsMouseChanged: {
if (!containsMouse) {
visibilities.osd = false;
osdHovered = false;
visibilities.dashboard = false;
popouts.hasCurrent = false;
}
}
onPositionChanged: ({x, y}) => {
// Show osd on hover
const showOsd = inRightPanel(panels.osd, x, y);
visibilities.osd = showOsd;
osdHovered = showOsd;
// Show/hide session on drag
if (pressed && withinPanelHeight(panels.session, x, y)) {
const dragX = x - dragStart.x;
if (dragX < -SessionConfig.dragThreshold)
visibilities.session = true;
else if (dragX > SessionConfig.dragThreshold)
visibilities.session = false;
}
// Show dashboard on hover
visibilities.dashboard = inTopPanel(panels.dashboard, x, y);
// Show popouts on hover
const popout = panels.popouts;
if (x < bar.implicitWidth + popout.width) {
if (x < bar.implicitWidth)
// Handle like part of bar
bar.checkPopout(y);
else
// Keep on hover
popouts.hasCurrent = withinPanelHeight(popout, x, y);
} else
popouts.hasCurrent = false;
}
Osd.Interactions {
screen: root.screen
visibilities: root.visibilities
hovered: root.osdHovered
}
}

View file

@ -0,0 +1,93 @@
import "root:/services"
import "root:/config"
import "root:/modules/osd" as Osd
import "root:/modules/notifications" as Notifications
import "root:/modules/session" as Session
import "root:/modules/launcher" as Launcher
import "root:/modules/dashboard" as Dashboard
import "root:/modules/bar/popouts" as BarPopouts
import Quickshell
import QtQuick
Item {
id: root
required property ShellScreen screen
required property PersistentProperties visibilities
required property Item bar
readonly property Osd.Wrapper osd: osd
readonly property Notifications.Wrapper notifications: notifications
readonly property Session.Wrapper session: session
readonly property Launcher.Wrapper launcher: launcher
readonly property Dashboard.Wrapper dashboard: dashboard
readonly property BarPopouts.Wrapper popouts: popouts
anchors.fill: parent
anchors.margins: BorderConfig.thickness
anchors.leftMargin: bar.implicitWidth
Component.onCompleted: Visibilities.panels[screen] = this
Osd.Wrapper {
id: osd
clip: root.visibilities.session
screen: root.screen
visibility: root.visibilities.osd
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: session.width
}
Notifications.Wrapper {
id: notifications
anchors.top: parent.top
anchors.right: parent.right
}
Session.Wrapper {
id: session
visibilities: root.visibilities
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
}
Launcher.Wrapper {
id: launcher
visibilities: root.visibilities
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
}
Dashboard.Wrapper {
id: dashboard
visibilities: root.visibilities
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
}
BarPopouts.Wrapper {
id: popouts
screen: root.screen
anchors.left: parent.left
anchors.verticalCenter: parent.top
anchors.verticalCenterOffset: {
const off = root.popouts.currentCenter - BorderConfig.thickness;
const diff = root.height - Math.floor(off + implicitHeight / 2);
if (diff < 0)
return off + diff;
return off;
}
}
}