i3-blocks-go/blocks/workspace_apps/main.go
Simon Vieille dc1ded5546
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
fix size calc (workspace_apps)
2022-08-30 22:45:33 +02:00

174 lines
3.5 KiB
Go

package main
import (
"encoding/json"
"fmt"
r "gitnet.fr/deblan/i3-blocks-go/rendering"
// "os"
"flag"
"os/exec"
"strconv"
"strings"
)
type WindowProperty struct {
Title string `json:"title"`
Instance int `json:"instance"`
}
const binI3Msg = "i3-msg"
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(binI3Msg, fmt.Sprintf("[id=%d] focus", window)).Run()
}
func GetTree() Tree {
output, _ := exec.Command(binI3Msg, "-t", "get_tree").Output()
tree := Tree{}
json.Unmarshal(output, &tree)
return tree
}
func GetVisibleWorkspaces() []Workspace {
output, _ := exec.Command(binI3Msg, "-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)
argX := flag.String("x", "", "")
flag.Parse()
x := 0
minX := 0
if *argX != "" {
x, _ = strconv.Atoi(*argX)
}
options := r.NewBlockOptions()
for _, app := range nodes {
foreground := "#9cb7d1"
background := "#222222"
title := strings.ToUpper(app.WindowProperties.Title)
if len(title) > 30 {
title = fmt.Sprintf("%s…", title[0:29])
}
size := (len(title) + 4) * 6
maxX := minX + size
isClicked := (x > minX && x < maxX)
if app.Urgent {
foreground = "#ffffff"
background = "#07c0d4"
} else if app.Focused || isClicked {
foreground = "#07c0d4"
background = "#333333"
} else if app.Output == "__i3" {
foreground = "#bababa"
}
if isClicked {
Focus(app.Window)
}
fb := r.FB{
Foreground: foreground,
Background: background,
}
options.FullText = fmt.Sprintf("%s%s", options.FullText, r.TextWithPadding(title, fb))
minX = maxX
}
block := r.Block("workspace_apps", options)
fmt.Println(block)
}