waffles: task view: workspaces

This commit is contained in:
end-4
2025-12-11 23:29:42 +01:00
parent 70c0adb8e5
commit 044221be93
8 changed files with 333 additions and 7 deletions
@@ -0,0 +1,96 @@
import QtQuick
import Quickshell
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
import qs.modules.waffle.looks
Rectangle {
id: root
color: ColorUtils.transparentize(Looks.colors.bg1Base, 0.5)
property real openProgress: 0
Component.onCompleted: {
openAnim.start();
}
PropertyAnimation {
id: openAnim
target: root
property: "openProgress"
to: 1
duration: 200
easing.type: Easing.BezierSpline
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
}
PropertyAnimation {
id: closeAnim
target: root
property: "openProgress"
to: 0
duration: 200
easing.type: Easing.BezierSpline
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
}
// Workspaces
Rectangle {
id: wsBorder
property real sourceEdgeMargin: -(height + 8) + root.openProgress * (height + 16)
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
leftMargin: 8
rightMargin: 8
topMargin: sourceEdgeMargin
bottomMargin: sourceEdgeMargin
}
border.color: Looks.colors.bg2Border
border.width: 1
radius: Looks.radius.large
color: "transparent"
implicitHeight: wsBg.implicitHeight + border.width * 2
Rectangle {
id: wsBg
anchors.fill: parent
anchors.margins: wsBorder.border.width
radius: wsBorder.radius - wsBorder.border.width
color: Looks.colors.bgPanelFooterBase
implicitHeight: 174
ListView {
anchors {
top: parent.top
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
topMargin: 5
bottomMargin: 5
}
width: Math.min(contentWidth + leftMargin + rightMargin, parent.width)
leftMargin: 5
rightMargin: 5
clip: true
orientation: ListView.Horizontal
spacing: 4
model: ScriptModel {
values: {
const maxWorkspaceId = Math.max.apply(null, HyprlandData.workspaces.map(ws => ws.id))
return Array(maxWorkspaceId)
}
}
delegate: TaskViewWorkspace {
required property int index
workspace: index + 1
}
}
}
}
}
@@ -0,0 +1,97 @@
import QtQuick
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import Quickshell
import Quickshell.Wayland
import Quickshell.Hyprland
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.common.widgets
import qs.modules.waffle.looks
WMouseAreaButton {
id: root
required property int workspace
readonly property real screenWidth: QsWindow.window.width
readonly property real screenHeight: QsWindow.window.height
readonly property real screenAspectRatio: screenWidth / screenHeight
readonly property real screenScale: QsWindow.window.devicePixelRatio
readonly property real scale: 0.1148148148
height: ListView.view.height
implicitWidth: 244 // for now
onClicked: {
GlobalStates.overviewOpen = false;
Hyprland.dispatch(`workspace ${root.workspace}`);
}
ColumnLayout {
anchors {
fill: parent
leftMargin: 12
rightMargin: 12
topMargin: 9
bottomMargin: 8
}
spacing: 8
WText {
Layout.fillWidth: true
Layout.fillHeight: false
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
text: Translation.tr("Desktop %1").arg(root.workspace)
}
Rectangle {
id: wsBg
height: 124
Layout.fillHeight: true
Layout.fillWidth: true
color: Looks.colors.bg1Base
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
width: wsBg.width
height: wsBg.height
radius: Looks.radius.medium
}
}
StyledImage {
anchors.fill: parent
cache: true
sourceSize: Qt.size(root.screenAspectRatio * 124, 124)
source: Config.options.background.wallpaperPath
fillMode: Image.PreserveAspectCrop
Repeater {
model: ScriptModel {
values: ToplevelManager.toplevels.values.filter(toplevel => {
const address = `0x${toplevel.HyprlandToplevel?.address}`;
var win = HyprlandData.windowByAddress[address];
const inWorkspace = win?.workspace?.id === root.workspace;
return inWorkspace;
})
}
delegate: ScreencopyView {
required property var modelData
readonly property var hyprlandWindowData: HyprlandData.windowByAddress[`0x${modelData.HyprlandToplevel?.address}`]
captureSource: modelData
live: true
width: hyprlandWindowData?.size[0] * root.scale
height: hyprlandWindowData?.size[1] * root.scale
x: hyprlandWindowData?.at[0] * root.scale
y: hyprlandWindowData?.at[1] * root.scale
}
}
}
}
}
}
@@ -0,0 +1,84 @@
pragma ComponentBehavior: Bound
import qs
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import Qt.labs.synchronizer
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import Quickshell.Hyprland
Scope {
id: overviewScope
property bool dontAutoCancelSearch: false
Variants {
id: overviewVariants
model: Quickshell.screens
Loader {
id: panelLoader
required property var modelData
active: GlobalStates.overviewOpen
sourceComponent: PanelWindow {
id: root
property string searchingText: ""
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen)
property bool monitorIsFocused: (Hyprland.focusedMonitor?.id == monitor?.id)
screen: panelLoader.modelData
WlrLayershell.namespace: "quickshell:wTaskView"
WlrLayershell.layer: WlrLayer.Overlay
// WlrLayershell.keyboardFocus: GlobalStates.overviewOpen ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
color: "transparent"
anchors {
top: true
bottom: true
left: true
right: true
}
TaskViewContent {
anchors.fill: parent
}
}
}
}
IpcHandler {
target: "search"
function toggle() {
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
}
function workspacesToggle() {
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
}
function close() {
GlobalStates.overviewOpen = false;
}
function open() {
GlobalStates.overviewOpen = true;
}
function toggleReleaseInterrupt() {
GlobalStates.superReleaseMightTrigger = false;
}
function clipboardToggle() {
overviewScope.toggleClipboard();
}
}
GlobalShortcut {
name: "overviewWorkspacesToggle"
description: "Toggles overview on press"
onPressed: {
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
}
}
}