summaryrefslogtreecommitdiff
path: root/services/Hyprland.qml
blob: 7a2538e9961d2e1cc7f6eb2d35a8faf8901829c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
pragma Singleton

import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import QtQuick

Singleton {
    id: root

    readonly property list<Client> clients: []
    readonly property var workspaces: Hyprland.workspaces
    readonly property var monitors: Hyprland.monitors
    property Client activeClient: null
    readonly property HyprlandWorkspace activeWorkspace: focusedMonitor?.activeWorkspace ?? null
    readonly property HyprlandMonitor focusedMonitor: Hyprland.focusedMonitor
    readonly property int activeWsId: activeWorkspace?.id ?? 1
    property point cursorPos

    function reload() {
        Hyprland.refreshWorkspaces();
        Hyprland.refreshMonitors();
        getClients.running = true;
        getActiveClient.running = true;
    }

    function dispatch(request: string): void {
        Hyprland.dispatch(request);
    }

    Component.onCompleted: reload()

    Connections {
        target: Hyprland

        function onRawEvent(event: HyprlandEvent): void {
            if (!event.name.endsWith("v2"))
                root.reload();
        }
    }

    FrameAnimation {
        running: true
        onTriggered: getCursorPos.running = true
    }

    Process {
        id: getCursorPos
        command: ["hyprctl", "cursorpos"]
        stdout: SplitParser {
            onRead: data => root.cursorPos = data
        }
    }

    Process {
        id: getClients
        command: ["sh", "-c", "hyprctl -j clients | jq -c"]
        stdout: SplitParser {
            onRead: data => {
                const clients = JSON.parse(data);
                const rClients = root.clients;

                const destroyed = rClients.filter(rc => !clients.find(c => c.address === rc.address));
                for (const client of destroyed)
                    rClients.splice(rClients.indexOf(client), 1).forEach(c => c.destroy());

                for (const client of clients) {
                    const match = rClients.find(c => c.address === client.address);
                    if (match) {
                        match.lastIpcObject = client;
                    } else {
                        rClients.push(clientComp.createObject(root, {
                            lastIpcObject: client
                        }));
                    }
                }
            }
        }
    }

    Process {
        id: getActiveClient
        command: ["hyprctl", "-j", "activewindow"]
        stdout: SplitParser {
            splitMarker: ""
            onRead: data => {
                const client = JSON.parse(data);
                const rClient = root.activeClient;
                if (client.address) {
                    if (rClient)
                        rClient.lastIpcObject = client;
                    else
                        root.activeClient = clientComp.createObject(root, {
                            lastIpcObject: client
                        });
                } else {
                    rClient.destroy();
                    root.activeClient = null;
                }
            }
        }
    }

    component Client: QtObject {
        required property var lastIpcObject
        readonly property string address: lastIpcObject.address
        readonly property string wmClass: lastIpcObject.class
        readonly property string title: lastIpcObject.title
        readonly property string initialClass: lastIpcObject.initialClass
        readonly property string initialTitle: lastIpcObject.initialTitle
        readonly property int x: lastIpcObject.at[0]
        readonly property int y: lastIpcObject.at[1]
        readonly property int width: lastIpcObject.size[0]
        readonly property int height: lastIpcObject.size[1]
        readonly property HyprlandWorkspace workspace: Hyprland.workspaces.values.find(w => w.id === lastIpcObject.workspace.id) ?? null
        readonly property bool floating: lastIpcObject.floating
        readonly property bool fullscreen: lastIpcObject.fullscreen
        readonly property int pid: lastIpcObject.pid
        readonly property int focusHistoryId: lastIpcObject.focusHistoryID
    }

    Component {
        id: clientComp

        Client {}
    }
}