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 }