Implemented workspace fixing after reducing number of outputs

This commit is contained in:
Magnus Åhall 2021-12-21 22:03:50 +01:00
parent f816d60138
commit c3a504fcbf
2 changed files with 83 additions and 27 deletions

39
main.go
View File

@ -5,7 +5,6 @@ import (
"fmt"
"net"
"os"
"regexp"
"strings"
)
@ -62,48 +61,34 @@ func main() {
}
// Find outputs and assign an index to them
outputs, err := session.Outputs()
err = session.UpdateOutputIndices()
if err != nil {
fmt.Printf("Output error: %s\n", err)
os.Exit(1)
}
idx := 0
for _, output := range outputs {
if output.Active {
outputIndices[output.Name] = idx
idx++
}
}
// XXX: still needed? Find the configured workspaces
if false {
var configData string
var configLines []string
configData, err = session.Config()
configLines = strings.Split(configData, "\n")
r := regexp.MustCompile(`(?i)^\s*workspace\s+["']?([^"']+?)["']?\s+output\s+["']?([^"']+?)["']?\s*$`)
for _, line := range configLines {
matches := r.FindAllStringSubmatch(line, -1)
if len(matches) > 0 && len(matches[0]) == 3 {
fmt.Printf("%#v\n", matches[0][1:])
}
}
}
// Listen for external commands
var conn net.Conn
var n int
for {
conn, err = listener.Accept()
if err != nil {
fmt.Printf("Connection accept: %s\n", err)
}
buf := make([]byte, 1024)
_, err = conn.Read(buf)
n, err = conn.Read(buf)
if err != nil {
fmt.Printf("Connection read: %s\n", err)
} else {
fmt.Printf("%s\n", buf)
}
cmd := strings.TrimSpace(string(buf[:n]))
if cmd == "fix workspaces" {
err = session.FixWorkspaces()
if err != nil {
fmt.Printf("Fix workspaces: %s\n", err)
}
}
conn.Close()
}
}

View File

@ -39,6 +39,28 @@ func (sess I3Session) Outputs() (outputs []I3Output, err error) {
return
}
// UpdateOutputIndices counts the outputs and assign incdices to them.
// The indices are used to calculate workspace IDs.
func (sess I3Session) UpdateOutputIndices() error {
outputIndices = make(map[string]int)
fmt.Printf("Update output indices:\n")
defer fmt.Printf("\n")
outputs, err := sess.Outputs()
if err != nil {
return err
}
idx := 0
for _, output := range outputs {
if output.Active {
fmt.Printf(" %2d %s\n", idx, output.Name)
outputIndices[output.Name] = idx
idx++
}
}
return nil
}
// Marks query I3 for mark data.
func (sess I3Session) Marks() (marks []string, err error) {
var outputJson []byte
@ -368,4 +390,53 @@ func (sess I3Session) MarkMove() error {
return nil
}
// FixWorkspaces moves windows from workspaces on the wrong monitor to
// to workspaces on the correct monitor. For fixing when going to less
// outputs.
func (sess I3Session) FixWorkspaces() error {
// Outputs could be completely different, and could need to be updated.
err := sess.UpdateOutputIndices()
if err != nil {
return err
}
// Identify workspaces on the wrong output
wss, err := sess.Workspaces()
if err != nil {
return err
}
var outputIdx int
var found bool
for _, ws := range wss {
outputIdx, found = outputIndices[ws.Output]
outputIdx *= 10
if !found {
return fmt.Errorf("Output %s not found", ws.Output)
}
// Is workspace on the wrong output?
wsOutputIdx := ws.Num - (ws.Num % 10)
if wsOutputIdx != outputIdx {
if (ws.Num % 10) >= len(workspaces) {
return fmt.Errorf(
"Workspace index doesn't exist",
)
}
cmd := fmt.Sprintf(
"[workspace=\"%s\"] move window to workspace \"%d:%s\"",
ws.Name,
(outputIdx*10)+(ws.Num % 10),
workspaces[(ws.Num % 10)].Name,
)
_, err := sess.Socket.Request(RUN_COMMAND, cmd)
if err != nil {
return err
}
}
}
return nil
}
// vim: foldmethod=marker