feat: bar popouts
Create active window popout
This commit is contained in:
parent
e52c3d82a0
commit
24a3da8138
10 changed files with 263 additions and 0 deletions
|
|
@ -12,6 +12,18 @@ StyledRect {
|
||||||
|
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
|
|
||||||
|
function checkPopout(y: real): var {
|
||||||
|
const aw = activeWindow.child
|
||||||
|
const awy = activeWindow.y + aw.y
|
||||||
|
if (y >= awy && y <= awy + aw.implicitHeight) {
|
||||||
|
Popouts.currentName = "activewindow"
|
||||||
|
Popouts.currentCenter = Qt.binding(() => activeWindow.y + aw.y + aw.implicitHeight / 2);
|
||||||
|
Popouts.hasCurrent = true;
|
||||||
|
} else {
|
||||||
|
Popouts.hasCurrent = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
|
@ -21,6 +33,19 @@ StyledRect {
|
||||||
|
|
||||||
Component.onCompleted: Visibilities.bars[screen] = this
|
Component.onCompleted: Visibilities.bars[screen] = this
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onPositionChanged: event => root.checkPopout(event.y)
|
||||||
|
|
||||||
|
onContainsMouseChanged: {
|
||||||
|
if (!containsMouse)
|
||||||
|
Popouts.hasCurrent = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: child
|
id: child
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property color colour: Colours.palette.m3primary
|
property color colour: Colours.palette.m3primary
|
||||||
|
readonly property Item child: child
|
||||||
|
|
||||||
implicitWidth: child.implicitWidth
|
implicitWidth: child.implicitWidth
|
||||||
implicitHeight: child.implicitHeight
|
implicitHeight: child.implicitHeight
|
||||||
|
|
|
||||||
33
modules/bar/popouts/ActiveWindow.qml
Normal file
33
modules/bar/popouts/ActiveWindow.qml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
|
||||||
|
import "root:/widgets"
|
||||||
|
import "root:/services"
|
||||||
|
import "root:/utils"
|
||||||
|
import "root:/config"
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
implicitWidth: child.implicitWidth
|
||||||
|
implicitHeight: child.implicitHeight
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: child
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: Hyprland.activeClient?.title ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: Hyprland.activeClient?.wmClass ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreencopyView {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
63
modules/bar/popouts/Background.qml
Normal file
63
modules/bar/popouts/Background.qml
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
import "root:/services"
|
||||||
|
import "root:/config"
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Shapes
|
||||||
|
|
||||||
|
ShapePath {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property Wrapper wrapper
|
||||||
|
readonly property real rounding: BorderConfig.rounding
|
||||||
|
readonly property bool flatten: wrapper.width < rounding * 2
|
||||||
|
readonly property real roundingX: flatten ? wrapper.width / 2 : rounding
|
||||||
|
|
||||||
|
strokeWidth: -1
|
||||||
|
fillColor: BorderConfig.colour
|
||||||
|
|
||||||
|
PathArc {
|
||||||
|
relativeX: root.roundingX
|
||||||
|
relativeY: root.rounding
|
||||||
|
radiusX: Math.min(root.rounding, root.wrapper.width)
|
||||||
|
radiusY: root.rounding
|
||||||
|
direction: PathArc.Counterclockwise
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
relativeX: root.wrapper.width - root.roundingX * 2
|
||||||
|
relativeY: 0
|
||||||
|
}
|
||||||
|
PathArc {
|
||||||
|
relativeX: root.roundingX
|
||||||
|
relativeY: root.rounding
|
||||||
|
radiusX: Math.min(root.rounding, root.wrapper.width)
|
||||||
|
radiusY: root.rounding
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
relativeX: 0
|
||||||
|
relativeY: root.wrapper.height - root.rounding * 4
|
||||||
|
}
|
||||||
|
PathArc {
|
||||||
|
relativeX: -root.roundingX
|
||||||
|
relativeY: root.rounding
|
||||||
|
radiusX: Math.min(root.rounding, root.wrapper.width)
|
||||||
|
radiusY: root.rounding
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
relativeX: -(root.wrapper.width - root.roundingX * 2)
|
||||||
|
relativeY: 0
|
||||||
|
}
|
||||||
|
PathArc {
|
||||||
|
relativeX: -root.roundingX
|
||||||
|
relativeY: root.rounding
|
||||||
|
radiusX: Math.min(root.rounding, root.wrapper.width)
|
||||||
|
radiusY: root.rounding
|
||||||
|
direction: PathArc.Counterclockwise
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on fillColor {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Appearance.anim.durations.normal
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
79
modules/bar/popouts/Content.qml
Normal file
79
modules/bar/popouts/Content.qml
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
import "root:/services"
|
||||||
|
import "root:/config"
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property ShellScreen screen
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
implicitWidth: Popouts.hasCurrent ? content.children.find(c => c.shouldBeActive).implicitWidth + Appearance.padding.large * 2 : 0
|
||||||
|
implicitHeight: Popouts.hasCurrent ? content.children.find(c => c.shouldBeActive).implicitHeight + Appearance.padding.large * 2 : 0
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Appearance.padding.large
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Popout {
|
||||||
|
name: "activewindow"
|
||||||
|
sourceComponent: ActiveWindow {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
Anim {
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.emphasized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
Anim {
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.emphasized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Popout: Loader {
|
||||||
|
id: popout
|
||||||
|
|
||||||
|
required property string name
|
||||||
|
property bool shouldBeActive: Popouts.currentName === name
|
||||||
|
|
||||||
|
active: shouldBeActive
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
Behavior on active {
|
||||||
|
SequentialAnimation {
|
||||||
|
Anim {
|
||||||
|
target: popout
|
||||||
|
property: "opacity"
|
||||||
|
from: popout.shouldBeActive ? 1 : 0
|
||||||
|
to: popout.shouldBeActive ? 0 : 1
|
||||||
|
duration: popout.shouldBeActive ? 0 : Appearance.anim.durations.normal
|
||||||
|
}
|
||||||
|
PropertyAction {}
|
||||||
|
Anim {
|
||||||
|
target: popout
|
||||||
|
property: "opacity"
|
||||||
|
from: popout.shouldBeActive ? 0 : 1
|
||||||
|
to: popout.shouldBeActive ? 1 : 0
|
||||||
|
duration: popout.shouldBeActive ? Appearance.anim.durations.normal : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Anim: NumberAnimation {
|
||||||
|
duration: Appearance.anim.durations.normal
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
}
|
||||||
19
modules/bar/popouts/Wrapper.qml
Normal file
19
modules/bar/popouts/Wrapper.qml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import "root:/services"
|
||||||
|
import "root:/config"
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property ShellScreen screen
|
||||||
|
|
||||||
|
implicitWidth: content.implicitWidth
|
||||||
|
implicitHeight: content.implicitHeight + BorderConfig.rounding * 2
|
||||||
|
|
||||||
|
Content {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
screen: root.screen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import "root:/modules/notifications" as Notifications
|
||||||
import "root:/modules/session" as Session
|
import "root:/modules/session" as Session
|
||||||
import "root:/modules/launcher" as Launcher
|
import "root:/modules/launcher" as Launcher
|
||||||
import "root:/modules/dashboard" as Dashboard
|
import "root:/modules/dashboard" as Dashboard
|
||||||
|
import "root:/modules/bar/popouts" as BarPopouts
|
||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
|
|
||||||
Shape {
|
Shape {
|
||||||
|
|
@ -51,4 +52,11 @@ Shape {
|
||||||
startX: (root.width - wrapper.width) / 2
|
startX: (root.width - wrapper.width) / 2
|
||||||
startY: 0
|
startY: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BarPopouts.Background {
|
||||||
|
wrapper: panels.popouts
|
||||||
|
|
||||||
|
startX: 0
|
||||||
|
startY: wrapper.y
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ MouseArea {
|
||||||
visibilities.osd = false;
|
visibilities.osd = false;
|
||||||
osdHovered = false;
|
osdHovered = false;
|
||||||
visibilities.dashboard = false;
|
visibilities.dashboard = false;
|
||||||
|
Popouts.hasCurrent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,6 +59,18 @@ MouseArea {
|
||||||
// Show dashboard on hover
|
// Show dashboard on hover
|
||||||
const showDashboard = root.inTopPanel(panels.dashboard, x, y);
|
const showDashboard = root.inTopPanel(panels.dashboard, x, y);
|
||||||
visibilities.dashboard = showDashboard;
|
visibilities.dashboard = showDashboard;
|
||||||
|
|
||||||
|
// Show popouts on hover
|
||||||
|
const popout = panels.popouts;
|
||||||
|
if (x < BorderConfig.thickness + popout.width) {
|
||||||
|
if (x < BorderConfig.thickness)
|
||||||
|
// Handle like part of bar
|
||||||
|
Visibilities.bars[screen].checkPopout(y);
|
||||||
|
else
|
||||||
|
// Keep on hover
|
||||||
|
Popouts.hasCurrent = withinPanelHeight(popout, x, y);
|
||||||
|
} else
|
||||||
|
Popouts.hasCurrent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Osd.Interactions {
|
Osd.Interactions {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import "root:/modules/notifications" as Notifications
|
||||||
import "root:/modules/session" as Session
|
import "root:/modules/session" as Session
|
||||||
import "root:/modules/launcher" as Launcher
|
import "root:/modules/launcher" as Launcher
|
||||||
import "root:/modules/dashboard" as Dashboard
|
import "root:/modules/dashboard" as Dashboard
|
||||||
|
import "root:/modules/bar/popouts" as BarPopouts
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
|
|
@ -19,6 +20,7 @@ Item {
|
||||||
readonly property Session.Wrapper session: session
|
readonly property Session.Wrapper session: session
|
||||||
readonly property Launcher.Wrapper launcher: launcher
|
readonly property Launcher.Wrapper launcher: launcher
|
||||||
readonly property Dashboard.Wrapper dashboard: dashboard
|
readonly property Dashboard.Wrapper dashboard: dashboard
|
||||||
|
readonly property BarPopouts.Wrapper popouts: popouts
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: BorderConfig.thickness
|
anchors.margins: BorderConfig.thickness
|
||||||
|
|
@ -70,4 +72,14 @@ Item {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BarPopouts.Wrapper {
|
||||||
|
id: popouts
|
||||||
|
|
||||||
|
screen: root.screen
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.top
|
||||||
|
anchors.verticalCenterOffset: Popouts.currentCenter - BorderConfig.thickness
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
services/Popouts.qml
Normal file
10
services/Popouts.qml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
property string currentName
|
||||||
|
property real currentCenter
|
||||||
|
property bool hasCurrent
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue