aboutsummaryrefslogtreecommitdiffstats
path: root/config/quickshell/qs-hyprview-trixie/layouts/SatelliteLayout.qml
blob: 2efb703b52847558eac641b00fb61b6d763eaa53 (plain) (blame)
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
pragma Singleton
import Quickshell
import Quickshell.Hyprland

Singleton {
    id: root

    function doLayout(windowList, outerWidth, outerHeight) {
        var N = windowList.length
        if (N === 0) return []

        // Move active window to the start of the list (Center Item)
        var activeAddr = Hyprland.activeToplevel?.lastIpcObject?.address
        if (activeAddr) {
            var activeIdx = windowList.findIndex(it => it.lastIpcObject.address === activeAddr)
            if (activeIdx !== -1) {
                windowList = [windowList[activeIdx], ...windowList.filter(it => it !== windowList[activeIdx])]
            }
        }

        // Safe Area definition (90%)
        var useW = outerWidth * 0.90
        var useH = outerHeight * 0.90
        var offX = (outerWidth - useW) / 2
        var offY = (outerHeight - useH) / 2

        var result = []

        // Center item (hero)
        var centerItem = windowList[0]

        // The center item takes up roughly 35% of the screen dimensions
        var centerW = useW * 0.35
        var centerH = useH * 0.35

        // Aspect Fit for the center item
        var w0 = (centerItem.width > 0) ? centerItem.width : 100
        var h0 = (centerItem.height > 0) ? centerItem.height : 100
        var sc0 = Math.min(centerW / w0, centerH / h0)
        var finalCenterW = w0 * sc0
        var finalCenterH = h0 * sc0

        result.push({
            win: centerItem.win,
            x: offX + (useW - finalCenterW) / 2,
            y: offY + (useH - finalCenterH) / 2,
            width: finalCenterW,
            height: finalCenterH,
            isSatellite: false
        })

        // Orbit items (satellites)
        var satellites = windowList.slice(1)
        var numSat = satellites.length

        if (numSat > 0) {
            // Orbit Radius (distance from center)
            var radiusX = useW * 0.4
            var radiusY = useH * 0.4

            // Max size for satellites.
            // As the number of satellites increases, we shrink them to avoid overlap.
            var maxSatW = (useW * 0.25) / Math.max(1, (numSat / 6))
            var maxSatH = (useH * 0.25) / Math.max(1, (numSat / 6))

            // Start angle (-90 degrees = Top)
            var startAngle = -Math.PI / 2
            var stepAngle = (2 * Math.PI) / numSat

            for (var i = 0; i < numSat; i++) {
                var item = satellites[i]
                var angle = startAngle + (i * stepAngle)

                // Calculate satellite center coordinates
                var cx = (useW / 2) + radiusX * Math.cos(angle)
                var cy = (useH / 2) + radiusY * Math.sin(angle)

                // Aspect Fit satellite
                var ws = (item.width > 0) ? item.width : 100
                var hs = (item.height > 0) ? item.height : 100
                var scS = Math.min(maxSatW / ws, maxSatH / hs)
                var finalSatW = ws * scS
                var finalSatH = hs * scS

                result.push({
                    win: item.win,
                    x: offX + cx - (finalSatW / 2),
                    y: offY + cy - (finalSatH / 2),
                    width: finalSatW,
                    height: finalSatH,
                    isSatellite: true
                })
            }
        }

        return result
    }
}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage