mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-05 14:59:27 -05:00
waffles: overview: more proper anims and dragging functionality
ITS FUCKING WORKING AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
This commit is contained in:
@@ -16,29 +16,43 @@ Rectangle {
|
||||
id: root
|
||||
|
||||
color: ColorUtils.transparentize(Looks.colors.bg1Base, 0.5)
|
||||
property bool draggingWindow: false
|
||||
property real openProgress: 0
|
||||
property Item hoveredWorkspace: null
|
||||
signal closed
|
||||
|
||||
Component.onCompleted: {
|
||||
openAnim.start();
|
||||
}
|
||||
function close() {
|
||||
closeAnim.start();
|
||||
}
|
||||
|
||||
PropertyAnimation {
|
||||
id: openAnim
|
||||
target: root
|
||||
property: "openProgress"
|
||||
to: 1
|
||||
duration: 200
|
||||
duration: 250
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||
}
|
||||
PropertyAnimation {
|
||||
SequentialAnimation {
|
||||
id: closeAnim
|
||||
target: root
|
||||
property: "openProgress"
|
||||
to: 0
|
||||
duration: 200
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||
|
||||
PropertyAnimation {
|
||||
target: root
|
||||
property: "openProgress"
|
||||
to: 0
|
||||
duration: 200
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||
}
|
||||
ScriptAction {
|
||||
script: {
|
||||
root.closed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Windows
|
||||
@@ -81,8 +95,18 @@ Rectangle {
|
||||
return resultLayout;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
z: 0
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
GlobalStates.overviewOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Windows
|
||||
WListView {
|
||||
id: windowListView
|
||||
z: root.openProgress == 1 ? 2 : 1
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
@@ -96,9 +120,8 @@ Rectangle {
|
||||
rightMargin: root.padding
|
||||
height: Math.min(contentHeight + topMargin + bottomMargin, root.height - (wsBorder.height + 16))
|
||||
|
||||
interactive: height < contentHeight
|
||||
|
||||
clip: true
|
||||
interactive: (height < contentHeight) && !root.draggingWindow
|
||||
clip: root.openProgress > 0.99 && !root.draggingWindow
|
||||
|
||||
model: ScriptModel {
|
||||
values: root.arrangedToplevels
|
||||
@@ -107,7 +130,7 @@ Rectangle {
|
||||
id: clientRow
|
||||
required property var modelData
|
||||
spacing: root.spacing
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.horizontalCenter: parent?.horizontalCenter ?? undefined
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
@@ -117,24 +140,61 @@ Rectangle {
|
||||
id: clientGridArea
|
||||
required property int index
|
||||
required property var modelData
|
||||
implicitWidth: windowItem.implicitWidth
|
||||
implicitHeight: windowItem.implicitHeight
|
||||
implicitWidth: windowItem.openedSize.width
|
||||
implicitHeight: windowItem.openedSize.height + windowItem.titleBarImplicitHeight
|
||||
|
||||
TaskViewWindow {
|
||||
id: windowItem
|
||||
z: 9999
|
||||
drag {
|
||||
target: this
|
||||
z: Drag.active ? 2 : 1
|
||||
opacity: openAnim.running ? root.openProgress : 1
|
||||
|
||||
property int mappedX: {
|
||||
// print("AAAWAWAAWAWWA: ", -(clientRow.x + clientGridArea.x + root.padding));
|
||||
var rootPosToThis = -(clientRow.x + clientGridArea.x + root.padding);
|
||||
return rootPosToThis + hyprlandClient.at[0];
|
||||
}
|
||||
property int mappedY: {
|
||||
// print("AAAWAWAAWAWWA YYYY YUIUSDFOIU: ", clientRow.y + windowListView.y + root.padding + windowItem.titleBarImplicitHeight)
|
||||
var rootPosToThis = -(clientRow.y + windowListView.y + root.padding + windowItem.titleBarImplicitHeight);
|
||||
return rootPosToThis + hyprlandClient.at[1];
|
||||
}
|
||||
property int openedX: 0
|
||||
property int openedY: 0
|
||||
// property int openedX: Drag.active ? (dragHandler.xAxis.activeValue) : 0
|
||||
// property int openedY: Drag.active ? (dragHandler.yAxis.activeValue) : 0
|
||||
scaleSize: (root.openProgress > 0 && !closeAnim.running)
|
||||
x: mappedX + (openedX - mappedX) * root.openProgress
|
||||
y: mappedY + (openedY - mappedY) * root.openProgress
|
||||
|
||||
droppable: root.hoveredWorkspace !== null
|
||||
Drag.active: dragHandler.active
|
||||
Drag.hotSpot.x: mouseX
|
||||
Drag.hotSpot.y: mouseY
|
||||
|
||||
DragHandler {
|
||||
id: dragHandler
|
||||
target: null
|
||||
xAxis.onActiveValueChanged: {
|
||||
windowItem.openedX = dragHandler.xAxis.activeValue;
|
||||
}
|
||||
yAxis.onActiveValueChanged: {
|
||||
windowItem.openedY = dragHandler.yAxis.activeValue;
|
||||
}
|
||||
onActiveChanged: {
|
||||
if (drag.active) {
|
||||
parent = root;
|
||||
if (active) {
|
||||
root.draggingWindow = true;
|
||||
} else {
|
||||
parent = clientGridArea;
|
||||
x = 0;
|
||||
y = 0;
|
||||
root.draggingWindow = false;
|
||||
if (root.hoveredWorkspace !== null && root.hoveredWorkspace.workspace !== windowItem.hyprlandClient.workspace.id) {
|
||||
Hyprland.dispatch(`movetoworkspacesilent ${root.hoveredWorkspace.workspace}, address:${windowItem.hyprlandClient.address}`);
|
||||
} else {
|
||||
windowItem.openedX = 0;
|
||||
windowItem.openedY = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Layout.alignment: Qt.AlignTop
|
||||
maxHeight: root.maxWindowHeight
|
||||
maxWidth: root.maxWindowWidth
|
||||
@@ -148,6 +208,7 @@ Rectangle {
|
||||
// Workspaces
|
||||
Rectangle {
|
||||
id: wsBorder
|
||||
z: root.openProgress == 1 ? 1 : 2
|
||||
property real sourceEdgeMargin: -(height + 8) + root.openProgress * (height + 16)
|
||||
anchors {
|
||||
left: parent.left
|
||||
@@ -210,9 +271,29 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
delegate: TaskViewWorkspace {
|
||||
id: workspaceItem
|
||||
required property int index
|
||||
workspace: index + 1
|
||||
newWorkspace: index == workspaceIndexModel.count - 1
|
||||
|
||||
droppable: root.hoveredWorkspace === workspaceItem
|
||||
DropArea {
|
||||
anchors.fill: parent
|
||||
onEntered: drag => {
|
||||
root.hoveredWorkspace = workspaceItem;
|
||||
}
|
||||
onExited: {
|
||||
if (root.hoveredWorkspace === workspaceItem) {
|
||||
root.hoveredWorkspace = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
GlobalStates.overviewOpen = false;
|
||||
root.closed(); // Close immediately to avoid weird animations
|
||||
Hyprland.dispatch(`workspace ${workspaceItem.workspace}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,47 +25,60 @@ WMouseAreaButton {
|
||||
|
||||
property string iconName: AppSearch.guessIcon(hyprlandClient?.class)
|
||||
|
||||
color: containsMouse ? Looks.colors.bg1Base : Looks.colors.bgPanelFooterBase
|
||||
borderColor: Looks.colors.bg2Border
|
||||
color: drag.active ? ColorUtils.transparentize(Looks.colors.bg1Base) : (containsMouse ? Looks.colors.bg1Base : Looks.colors.bgPanelFooterBase)
|
||||
borderColor: ColorUtils.transparentize(Looks.colors.bg2Border, drag.active ? 1 : 0)
|
||||
radius: Looks.radius.xLarge
|
||||
|
||||
property size size: WindowLayout.scaleWindow(hyprlandClient, maxWidth, maxHeight)
|
||||
property real titleBarImplicitHeight: titleBar.implicitHeight
|
||||
property bool scaleSize: true
|
||||
property size openedSize: WindowLayout.scaleWindow(hyprlandClient, maxWidth, maxHeight);
|
||||
property size fullSize: Qt.size(hyprlandClient?.size[0] ?? maxWidth, hyprlandClient?.size[1] ?? maxHeight)
|
||||
property size size: scaleSize ? openedSize : fullSize
|
||||
implicitWidth: Math.max(Math.round(contentItem.implicitWidth), 138)
|
||||
implicitHeight: Math.round(contentItem.implicitHeight)
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Rectangle {
|
||||
maskSource: Item {
|
||||
width: root.background.width
|
||||
height: root.background.height
|
||||
radius: root.background.radius
|
||||
Rectangle {
|
||||
radius: root.background.radius
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: root.drag.active ? root.titleBarImplicitHeight : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scale: (root.pressedButtons & Qt.LeftButton) ? 0.95 : 1
|
||||
property bool droppable: false
|
||||
scale: (root.pressedButtons & Qt.LeftButton || root.Drag.active) ? (droppable ? 0.4 : 0.95) : 1
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
id: scaleAnim
|
||||
duration: 300
|
||||
duration: 200
|
||||
easing.type: Easing.OutExpo
|
||||
}
|
||||
}
|
||||
|
||||
function closeWindow() {
|
||||
Hyprland.dispatch(`closewindow address:${root.hyprlandClient?.address}`)
|
||||
Hyprland.dispatch(`closewindow address:${root.hyprlandClient?.address}`);
|
||||
}
|
||||
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
||||
onClicked: (event) => {
|
||||
onClicked: event => {
|
||||
if (event.button === Qt.LeftButton) {
|
||||
GlobalStates.overviewOpen = false
|
||||
Hyprland.dispatch(`focuswindow address:${root.hyprlandClient?.address}`)
|
||||
GlobalStates.overviewOpen = false;
|
||||
Hyprland.dispatch(`focuswindow address:${root.hyprlandClient?.address}`);
|
||||
GlobalStates.overviewOpen = false;
|
||||
} else if (event.button === Qt.MiddleButton) {
|
||||
root.closeWindow();
|
||||
event.accepted = true;
|
||||
} else if (event.button === Qt.RightButton) {
|
||||
if (!windowMenu.visible) windowMenu.popup();
|
||||
else windowMenu.close();
|
||||
if (!windowMenu.visible)
|
||||
windowMenu.popup();
|
||||
else
|
||||
windowMenu.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +90,8 @@ WMouseAreaButton {
|
||||
spacing: 0
|
||||
|
||||
RowLayout {
|
||||
id: titleBar
|
||||
opacity: root.drag.active ? 0 : 1
|
||||
spacing: 8
|
||||
WAppIcon {
|
||||
Layout.leftMargin: 10
|
||||
@@ -104,6 +119,14 @@ WMouseAreaButton {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: Math.round(root.size.width)
|
||||
implicitHeight: Math.round(root.size.height)
|
||||
constraintSize: Qt.size(Math.round(root.size.width), Math.round(root.size.height))
|
||||
|
||||
Behavior on implicitWidth {
|
||||
animation: Looks.transition.enter.createObject(this)
|
||||
}
|
||||
Behavior on implicitHeight {
|
||||
animation: Looks.transition.enter.createObject(this)
|
||||
}
|
||||
|
||||
captureSource: root.toplevel ?? null
|
||||
live: true
|
||||
@@ -120,7 +143,7 @@ WMouseAreaButton {
|
||||
icon.name: isPinned ? "checkmark" : "empty"
|
||||
text: Translation.tr("Show this window on all desktops")
|
||||
onTriggered: {
|
||||
Hyprland.dispatch(`pin address:${root.hyprlandClient?.address}`)
|
||||
Hyprland.dispatch(`pin address:${root.hyprlandClient?.address}`);
|
||||
}
|
||||
}
|
||||
Action {
|
||||
|
||||
@@ -16,6 +16,7 @@ WMouseAreaButton {
|
||||
|
||||
required property int workspace
|
||||
property bool newWorkspace: false
|
||||
property bool droppable: false
|
||||
|
||||
readonly property bool isActiveWorkspace: HyprlandData.activeWorkspace?.id === root.workspace
|
||||
readonly property real screenWidth: QsWindow.window?.width ?? 0
|
||||
@@ -28,12 +29,7 @@ WMouseAreaButton {
|
||||
height: ListView.view?.height ?? 100
|
||||
implicitWidth: 244 // for now
|
||||
|
||||
onClicked: {
|
||||
GlobalStates.overviewOpen = false;
|
||||
Hyprland.dispatch(`workspace ${root.workspace}`);
|
||||
}
|
||||
|
||||
colBackground: ColorUtils.transparentize(Looks.colors.bg2, isActiveWorkspace ? 0 : 1)
|
||||
colBackground: ColorUtils.transparentize(Looks.colors.bg2, (isActiveWorkspace || droppable) ? 0 : 1)
|
||||
Behavior on color {
|
||||
animation: Looks.transition.color.createObject(this)
|
||||
}
|
||||
@@ -119,6 +115,14 @@ WMouseAreaButton {
|
||||
icon: "add"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
z: 2
|
||||
visible: root.droppable && !root.newWorkspace
|
||||
anchors.fill: parent
|
||||
color: Looks.colors.accent
|
||||
opacity: 0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,14 @@ Scope {
|
||||
Loader {
|
||||
id: panelLoader
|
||||
required property var modelData
|
||||
active: GlobalStates.overviewOpen
|
||||
active: false
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
function onOverviewOpenChanged() {
|
||||
if (GlobalStates.overviewOpen)
|
||||
panelLoader.active = true;
|
||||
}
|
||||
}
|
||||
sourceComponent: PanelWindow {
|
||||
id: root
|
||||
property string searchingText: ""
|
||||
@@ -44,7 +51,16 @@ Scope {
|
||||
}
|
||||
|
||||
TaskViewContent {
|
||||
id: taskViewContent
|
||||
anchors.fill: parent
|
||||
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
function onOverviewOpenChanged() {
|
||||
if (!GlobalStates.overviewOpen) taskViewContent.close();
|
||||
}
|
||||
}
|
||||
onClosed: panelLoader.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ Singleton {
|
||||
|
||||
function onRawEvent(event) {
|
||||
// console.log("Hyprland raw event:", event.name);
|
||||
if (["openlayer", "closelayer", "screencast"].includes(event.name)) return;
|
||||
updateAll()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user