commit 6a2ec1a9579b9395500f507e6566780262a64517 Author: Milarin Date: Fri Apr 5 13:40:10 2024 +0200 initial commit diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0bc9c92 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module git.milar.in/milarin/hypr-fixwinbounds + +go 1.21.7 + +require ( + git.milar.in/milarin/hypr v0.1.3 + git.milar.in/milarin/slices v0.0.8 +) + +require git.milar.in/milarin/gmath v0.0.5 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..592c39b --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +git.milar.in/milarin/gmath v0.0.5 h1:qQQMUTbxEk5LriMMSRbElExDSouSJKYBo6zRcOYKVIU= +git.milar.in/milarin/gmath v0.0.5/go.mod h1:HDLftG5RLpiNGKiIWh+O2G1PYkNzyLDADO8Cd/1abiE= +git.milar.in/milarin/hypr v0.1.3 h1:v50AY21JyrqzmfpqVTPLdCNPeZ7crn32W78EkREdjzc= +git.milar.in/milarin/hypr v0.1.3/go.mod h1:lGdMbbjgh15oKbAsz7fxqflWHzX/Ud42aDk0erIUraw= +git.milar.in/milarin/slices v0.0.8 h1:qN9TE3tkArdTixMKSnwvNPcApwAjxpLVwA5a9k1rm2s= +git.milar.in/milarin/slices v0.0.8/go.mod h1:qMhdtMnfWswc1rHpwgNw33lB84aNEkdBn5BDiYA+G3k= diff --git a/main.go b/main.go new file mode 100644 index 0000000..9278729 --- /dev/null +++ b/main.go @@ -0,0 +1,104 @@ +package main + +import ( + "context" + "fmt" + "image" + "log" + + "git.milar.in/milarin/hypr" + "git.milar.in/milarin/slices" +) + +func main() { + client, err := hypr.GetDefaultClient() + if err != nil { + panic(err) + } + + events, err := client.Subscribe(context.Background(), hypr.EventTypeFullscreen) + if err != nil { + panic(err) + } + + if err := RestoreWindowPositions(client); err != nil { + panic(err) + } + + for event := range events { + if len(event.Data) != 1 || event.Data[0] != "0" { + continue + } + + if err := RestoreWindowPositions(client); err != nil { + panic(err) + } + } +} + +func RestoreWindowPositions(client *hypr.Client) error { + monitors, err := client.GetMonitors() + if err != nil { + return err + } + + monitorBoundsByID := slices.ToMap(monitors, func(m *hypr.Monitor) (int, image.Rectangle) { + return m.ID, image.Rect(m.X, m.Y, m.X+m.Width, m.Y+m.Height) + }) + + windows, err := client.GetWindows() + if err != nil { + return err + } + + for _, window := range windows { + if window.Workspace.ID < 0 { + continue + } + + //monitor := monitorByID[window.MonitorID] + + windowBounds := image.Rect( + window.At[0], + window.At[1], + window.At[0]+window.Size[0], + window.At[1]+window.Size[1]) + + shouldMonitorBounds := monitorBoundsByID[window.MonitorID] + + if windowBounds.In(shouldMonitorBounds) { + continue + } + + // fmt.Println("IMPOSSIBLE WINDOW POSITION DETECTED", window.Title, window.Address) + // fmt.Println("workspace:", window.Workspace.ID) + // fmt.Println("monitor:", shouldMonitorBounds) + // fmt.Println("window:", windowBounds) + + isMonitorBounds := image.Rect(-1, -1, -1, -1) + for _, monitorBounds := range monitorBoundsByID { + if windowBounds.In(monitorBounds) { + isMonitorBounds = monitorBounds + break + } + } + + diff := windowBounds.Min.Sub(isMonitorBounds.Min) + shouldPos := shouldMonitorBounds.Min.Add(diff) + + if isMonitorBounds == image.Rect(-1, -1, -1, -1) { + shouldPos = shouldMonitorBounds.Min + } + + client.DispatchExpectOK(fmt.Sprintf( + "movewindowpixel exact %d %d,address:%s", + shouldPos.X, + shouldPos.Y, + window.Address, + )) + + log.Printf("invalid position restored for window (class: '%s' | title: '%s')\n", window.Class, window.Title) + } + + return nil +}