package main import ( "encoding/json" "fmt" "log" "os/exec" "strings" ) type tree struct { Id int `json:"id"` Name string `json:"name,omitempty"` AppId string `json:"app_id,omitempty"` Type string `json:"type,omitempty"` Nodes []tree `json:"nodes,omitempty"` FloatingNodes []tree `json:"floating_nodes,omitempty"` } type window struct { Id int AppIdAndName string } func flatten(in tree, windows *[]window) { if in.Name != "" && (in.Type == "con" || in.Type == "floating_con") { *windows = append(*windows, window{in.Id, in.AppId + " " + in.Name}) } for _, node := range append(in.Nodes, in.FloatingNodes...) { flatten(node, windows) } } func getWindowNames(windows []window) string { var windowNames []string for _, idAndName := range windows { windowNames = append(windowNames, idAndName.AppIdAndName) } return strings.Join(windowNames, "\n") } func selectWithWofi(windows string) string { cmd := exec.Command("wofi", "-i", "-d") cmd.Stdin = strings.NewReader(windows) stdout, err := cmd.Output() if err != nil { return "" } return strings.TrimSpace(string(stdout)) } func findWindowId(windowName string, windows []window) int { for _, window := range windows { if windowName == window.AppIdAndName { return window.Id } } log.Fatal("Invalid Window Name") return -1 } func switchToWindow(id int) { arg1 := fmt.Sprintf("[con_id=%d]", id) cmd := exec.Command("swaymsg", arg1, "focus") cmd.Start() } func main() { cmd := exec.Command("swaymsg", "-r", "-t", "get_tree") stdout, err := cmd.Output() if err != nil { log.Fatal(err) return } var swaymsg_output tree if err := json.Unmarshal(stdout, &swaymsg_output); err != nil { log.Fatal(err) } var windows []window flatten(swaymsg_output, &windows) if selected := selectWithWofi(getWindowNames(windows)); selected != "" { windowId := findWindowId(selected, windows) switchToWindow(windowId) } }