i3-blocks-go/blocks/workspace_apps/main.go
Simon Vieille c9665b33b3
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
add block ps
2022-08-30 13:33:58 +02:00

167 lines
3.4 KiB
Go

package main
import (
"encoding/json"
"fmt"
r "gitnet.fr/deblan/i3-blocks-go/rendering"
"os"
"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)
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 {
foreground = "#ffffff"
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)
}
}
}
}