90 lines
2.4 KiB
Go
90 lines
2.4 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"strings"
|
||
|
|
||
|
"git.milar.in/hyprland-tools/hypr"
|
||
|
"git.milar.in/milarin/slices"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
client, err := hypr.GetDefaultClient()
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
events, err := client.Subscribe(context.Background(), hypr.EventTypeMonitorAdded)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
for event := range events {
|
||
|
monitorName := event.Data[0]
|
||
|
log.Printf("monitor %s added", monitorName)
|
||
|
|
||
|
activeWorkspace, err := client.GetActiveWorkspace()
|
||
|
if err != nil {
|
||
|
log.Println(fmt.Errorf("active workspace: %w", err))
|
||
|
}
|
||
|
|
||
|
if err := client.DispatchExpectOK(fmt.Sprintf("focusmonitor %s", monitorName)); err != nil {
|
||
|
log.Println(fmt.Errorf("focus monitor '%s': %w", monitorName, err))
|
||
|
}
|
||
|
|
||
|
if err := FixAllSpecialWorkspacesOnMonitor(client, monitorName); err != nil {
|
||
|
log.Println(err)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if err := client.DispatchExpectOK(fmt.Sprintf("focusmonitor %s", activeWorkspace.Monitor)); err != nil {
|
||
|
log.Println(fmt.Errorf("focus monitor '%s': %w", monitorName, err))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func FixAllSpecialWorkspacesOnMonitor(client *hypr.Client, monitorName string) error {
|
||
|
workspaces, err := client.GetWorkspaces()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("retrieve workspaces from Hyprland: %w", err)
|
||
|
}
|
||
|
|
||
|
workspacesOnMonitor := slices.Filter(workspaces, WorkspaceIsOnMonitor(monitorName))
|
||
|
specialWorkspacesOnMonitor := slices.Filter(workspacesOnMonitor, WorkspaceIsSpecial)
|
||
|
|
||
|
for _, workspace := range specialWorkspacesOnMonitor {
|
||
|
if err := ToggleSpecialWorkspace(client, workspace.Name); err != nil {
|
||
|
return fmt.Errorf("toggle special workspace '%s': %w", workspace.Name, err)
|
||
|
}
|
||
|
|
||
|
if err := ToggleSpecialWorkspace(client, workspace.Name); err != nil {
|
||
|
return fmt.Errorf("toggle special workspace '%s': %w", workspace.Name, err)
|
||
|
}
|
||
|
|
||
|
log.Printf("special workspace '%s' fixed", workspace.Name)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func WorkspaceIsSpecial(w *hypr.Workspace) bool {
|
||
|
return w.ID < 0
|
||
|
}
|
||
|
|
||
|
func WorkspaceIsOnMonitor(monitorName string) func(w *hypr.Workspace) bool {
|
||
|
return func(w *hypr.Workspace) bool {
|
||
|
return w.Monitor == monitorName
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func ToggleSpecialWorkspace(client *hypr.Client, workspaceName string) error {
|
||
|
if workspaceName == "special" {
|
||
|
return client.DispatchExpectOK("togglespecialworkspace")
|
||
|
}
|
||
|
|
||
|
specialWorkspaceName := strings.TrimPrefix(workspaceName, "special:")
|
||
|
return client.DispatchExpectOK(fmt.Sprintf("togglespecialworkspace %s", specialWorkspaceName))
|
||
|
}
|