package main import ( "encoding/json" "fmt" r "gitnet.fr/deblan/i3-blocks-go/rendering" "os" "os/exec" "strconv" "strings" "time" ) type WindowProperty struct { Title string `json:"title"` Instance int `json:"instance"` } type Tree struct { Num int `json:"num"` Output string `json:"output"` FloatingNodes []Tree `json:"floating_nodes"` Nodes []Tree `json:"nodes"` Window int `json:"window"` Name string `json:"name"` Focused bool `json:"focused"` Urgent bool `json:"urgent"` WindowProperties WindowProperty `json:"window_properties"` } type Workspace struct { Num int `json:"num"` Visible bool `json:"visible"` } func Focus(window int) { exec.Command("i3-msg", fmt.Sprintf("[id=%d] focus", window)).Run() } func GetTree() Tree { output, _ := exec.Command("i3-msg", "-t", "get_tree").Output() tree := Tree{} json.Unmarshal(output, &tree) return tree } func GetVisibleWorkspaces() []Workspace { output, _ := exec.Command("i3-msg", "-t", "get_workspaces").Output() workspaces := []Workspace{} datas := []Workspace{} json.Unmarshal(output, &datas) for _, workspace := range datas { if workspace.Visible { workspaces = append(workspaces, workspace) } } return workspaces } func GetVisibleNodes(tree Tree, workspaces []Workspace) []Tree { var nodes []Tree var visibleNodes []Tree for _, workspace := range workspaces { if tree.Num == workspace.Num { for _, node := range tree.Nodes { nodes = append(nodes, node) } for _, node := range tree.FloatingNodes { nodes = append(nodes, node) } } else if tree.Output == "__i3" && tree.Window > 0 { nodes = []Tree{tree} } } for _, node := range tree.Nodes { nNodes := GetVisibleNodes(node, workspaces) for _, n := range nNodes { nodes = append(nodes, n) } } for _, node := range tree.FloatingNodes { nNodes := GetVisibleNodes(node, workspaces) for _, n := range nNodes { nodes = append(nodes, n) } } for _, node := range nodes { if node.Window > 0 { visibleNodes = append(visibleNodes, node) } else { for _, sNode := range node.Nodes { visibleNodes = append(visibleNodes, sNode) } for _, sNode := range node.FloatingNodes { visibleNodes = append(visibleNodes, sNode) } } } return visibleNodes } func main() { workspaces := GetVisibleWorkspaces() tree := GetTree() nodes := GetVisibleNodes(tree, workspaces) appNumber, _ := strconv.Atoi(os.Args[1]) blockButton := "" for k, v := range os.Args { if k == 2 { blockButton = v } } for key, app := range nodes { if key == appNumber { foreground := "#9cb7d1" background := "#222222" if app.Urgent { s := time.Now().Format("%S") second, _ := strconv.Atoi(s) foreground = "#ffffff" if second%2 == 1 { background = "#87af15" } else { background = "#07c0d4" } } else if app.Focused { foreground = "#07c0d4" background = "#333333" } else if app.Output == "__i3" { foreground = "#bababa" } fb := r.FB{ Foreground: foreground, Background: background, } title := strings.ToUpper(app.WindowProperties.Title) if len(title) > 25 { title = fmt.Sprintf("%s…", title[0:22]) } options := r.NewBlockOptions() options.FullText = r.TextWithPadding(title, fb) block := r.Block(fmt.Sprintf("workspace_apps_%d", appNumber), options) fmt.Println(block) if blockButton == "1" { Focus(app.Window) } } } }