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
|
||||
|
||||
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.bottom: parent.bottom
|
||||
|
||||
|
|
@ -21,6 +33,19 @@ StyledRect {
|
|||
|
||||
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 {
|
||||
id: child
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ Item {
|
|||
id: root
|
||||
|
||||
property color colour: Colours.palette.m3primary
|
||||
readonly property Item child: child
|
||||
|
||||
implicitWidth: child.implicitWidth
|
||||
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/launcher" as Launcher
|
||||
import "root:/modules/dashboard" as Dashboard
|
||||
import "root:/modules/bar/popouts" as BarPopouts
|
||||
import QtQuick.Shapes
|
||||
|
||||
Shape {
|
||||
|
|
@ -51,4 +52,11 @@ Shape {
|
|||
startX: (root.width - wrapper.width) / 2
|
||||
startY: 0
|
||||
}
|
||||
|
||||
BarPopouts.Background {
|
||||
wrapper: panels.popouts
|
||||
|
||||
startX: 0
|
||||
startY: wrapper.y
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ MouseArea {
|
|||
visibilities.osd = false;
|
||||
osdHovered = false;
|
||||
visibilities.dashboard = false;
|
||||
Popouts.hasCurrent = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +59,18 @@ MouseArea {
|
|||
// Show dashboard on hover
|
||||
const showDashboard = root.inTopPanel(panels.dashboard, x, y);
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ 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
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ Item {
|
|||
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
|
||||
|
|
@ -70,4 +72,14 @@ Item {
|
|||
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: 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