swaysw/main.go

90 lines
1.9 KiB
Go

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)
}
}