Implemented workspace fixing after reducing number of outputs
This commit is contained in:
parent
f816d60138
commit
c3a504fcbf
39
main.go
39
main.go
@ -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()
|
||||
}
|
||||
}
|
||||
|
71
session.go
71
session.go
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user