Better handling of store/restore workspaces

This commit is contained in:
Magnus Åhall 2021-12-28 10:57:18 +01:00
parent 08e84947ef
commit f9e815b4e3
2 changed files with 82 additions and 9 deletions

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os/exec"
"regexp"
"sort"
"strconv"
"strings"
)
@ -299,14 +300,29 @@ func (sess I3Session) MarkMove() error {
func (sess *I3Session) StoreWorkspaces() (err error) {
var workspaces []I3Workspace
sess.workspaces = make(map[int]string)
sess.workspaces = make(map[string]string)
sess.workspacesActive = make(map[string]string)
workspaces, err = sess.Workspaces()
if err != nil {
return
}
for _, ws := range workspaces {
sess.workspaces[ws.Id] = ws.Output
fmt.Printf("Store workspace: %s - %s\n", ws.Name, ws.Output)
sess.workspaces[ws.Name] = ws.Output
// Visible workspaces are stored to visit them at a restore,
// to make sure they still are visible afterwards.
if ws.Visible {
sess.workspacesActive[ws.Name] = ws.Output
}
// Focused workspace is switched to last, to ensure it is still
// the focused workspace.
if ws.Focused {
sess.activeWorkspace = ws.Name
}
}
return
}
@ -318,18 +334,71 @@ func (sess *I3Session) RestoreWorkspaces() (err error) {
return err
}
for wsId, output := range sess.workspaces {
var list [][]string
var wsNum int
for wsName, output := range sess.workspaces {
//fmt.Printf("Restore workspace: %s to %s\n", wsName, output)
components := strings.Split(wsName, ":")
wsNum, err = strconv.Atoi(components[0])
if err != nil {
return err
}
cmd := fmt.Sprintf(
"[workspace=%d] move workspace to output %s",
wsId,
"[workspace=\"%s\"] move workspace to output \"%s\"",
wsName,
output,
)
res, err := sess.Socket.Request(RUN_COMMAND, cmd)
list = append(list, []string{
fmt.Sprintf("%03d", wsNum),
cmd,
})
if false {
}
}
sort.SliceStable(list, func(i, j int) bool {
return list[i][0] < list[j][0]
})
for _, cmd := range list {
fmt.Printf("%s: ", cmd)
res, err := sess.Socket.Request(RUN_COMMAND, cmd[1])
if err != nil {
return err
}
fmt.Printf("%s\n", res)
}
// Visible workspaces are switched to to make sure they still are
// visible afterwards.
for wsName := range sess.workspacesActive {
cmd := fmt.Sprintf(
"workspace \"%s\"",
wsName,
)
_, err = sess.Socket.Request(RUN_COMMAND, cmd)
if err != nil {
return err
}
}
// i3 will often leave user on workspace "1", going to last workspace
// when stored makes for a better user experience.
if sess.activeWorkspace != "" {
cmd := fmt.Sprintf(
"workspace \"%s\"",
sess.activeWorkspace,
)
_, err = sess.Socket.Request(RUN_COMMAND, cmd)
if err != nil {
return err
}
}
return
}
@ -361,6 +430,7 @@ func (sess I3Session) FixWorkspaces() error {
// Is workspace on the wrong output?
wsOutputIdx := ws.Num - (ws.Num % 10)
if wsOutputIdx != outputIdx {
fmt.Printf("%s is on wrong output\n", ws.Name)
if (ws.Num % 10) >= len(workspaces) {
return fmt.Errorf(
"Workspace index doesn't exist",
@ -368,9 +438,10 @@ func (sess I3Session) FixWorkspaces() error {
}
cmd := fmt.Sprintf(
"[workspace=\"%s\"] move window to workspace \"%d:%s\"",
"[workspace=\"%s\"] move window to workspace "+
"\"%d:%s\"",
ws.Name,
(outputIdx*10)+(ws.Num % 10),
outputIdx+(ws.Num % 10),
workspaces[(ws.Num % 10)].Name,
)
_, err := sess.Socket.Request(RUN_COMMAND, cmd)

View File

@ -10,7 +10,9 @@ type I3Session struct {
filename string
// workspace ID → output name
workspaces map[int]string
workspaces map[string]string
workspacesActive map[string]string
activeWorkspace string
}
type I3Socket struct {