Skip to content

Commit

Permalink
Fix #7
Browse files Browse the repository at this point in the history
  • Loading branch information
diogox committed Feb 22, 2021
1 parent e869658 commit d502143
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 3 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/diogox/bspm
go 1.15

require (
github.com/diogox/bspc-go v0.0.0-20210222214855-663c9dbacfbf
github.com/diogox/bspc-go v0.0.0-20210222233335-ddbb8522bfa6
github.com/fatih/color v1.10.0
github.com/golang/mock v1.4.4
github.com/stretchr/testify v1.7.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ github.com/diogox/bspc-go v0.0.0-20210214194434-b9726aa9e65e h1:dHdbwD+GAx8zCRLa
github.com/diogox/bspc-go v0.0.0-20210214194434-b9726aa9e65e/go.mod h1:0WUzLLyXqCBHXV4dk5O9H2O3PcUxlLtYv/MRNR1Dkcs=
github.com/diogox/bspc-go v0.0.0-20210222214855-663c9dbacfbf h1:wMFi0PgssldUrJ5hLAY+J7Hs2H+CLX25UHkz1xRGeq4=
github.com/diogox/bspc-go v0.0.0-20210222214855-663c9dbacfbf/go.mod h1:0WUzLLyXqCBHXV4dk5O9H2O3PcUxlLtYv/MRNR1Dkcs=
github.com/diogox/bspc-go v0.0.0-20210222225301-092068f0bcc2 h1:VY8qz3N3LHXpslchCNOkowwh/qxamFtjaBeex1Nwp8Q=
github.com/diogox/bspc-go v0.0.0-20210222225301-092068f0bcc2/go.mod h1:0WUzLLyXqCBHXV4dk5O9H2O3PcUxlLtYv/MRNR1Dkcs=
github.com/diogox/bspc-go v0.0.0-20210222233335-ddbb8522bfa6 h1:W52pb9PI5QNZPUdPh8RfIOB7Hw7Pw1Rq6HvjVrXwvmE=
github.com/diogox/bspc-go v0.0.0-20210222233335-ddbb8522bfa6/go.mod h1:d4jYBJhdGS8dxKhiT6+AMbjjUE3jIr3+SfG190UUMKk=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
Expand Down
23 changes: 23 additions & 0 deletions internal/bspwm/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,68 @@
package bspwm

import (
"fmt"

"github.com/diogox/bspc-go"

bspwmdesktop "github.com/diogox/bspm/internal/bspwm/desktop"
bspwmevent "github.com/diogox/bspm/internal/bspwm/event"
bspwmnode "github.com/diogox/bspm/internal/bspwm/node"
)

type (
Service interface {
State() (bspc.State, error)
Desktops() bspwmdesktop.Service
Nodes() bspwmnode.Service
Events() bspwmevent.Manager
}
)

type service struct {
client bspc.Client
desktopService bspwmdesktop.Service
nodeService bspwmnode.Service
eventManager bspwmevent.Manager
}

func NewService(
client bspc.Client,
desktopService bspwmdesktop.Service,
nodeService bspwmnode.Service,
eventManager bspwmevent.Manager,
) Service {
return service{
client: client,
desktopService: desktopService,
nodeService: nodeService,
eventManager: eventManager,
}
}

// State returns bspwm's current state.
func (s service) State() (bspc.State, error) {
const cmd = "wm --dump-state"

var state bspc.State
if err := s.client.Query(cmd, bspc.ToStruct(&state)); err != nil {
return bspc.State{}, fmt.Errorf("failed to retrieve bspwm state: %w", err)
}

return state, nil
}

// Desktops returns the service for dealing with bspwm desktops.
func (s service) Desktops() bspwmdesktop.Service {
return s.desktopService
}

// Nodes returns the service for dealing with bspwm nodes.
func (s service) Nodes() bspwmnode.Service {
return s.nodeService
}

// Events returns the service for dealing with bspwm events.
func (s service) Events() bspwmevent.Manager {
return s.eventManager
}
16 changes: 16 additions & 0 deletions internal/bspwm/service_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions internal/cli/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func runDaemon(logger *log.Logger) error {
logger,
state.NewTransparentMonocle(),
bspwm.NewService(
bspwmClient,
bspwmdesktop.NewService(bspwmClient),
bspwmnode.NewService(bspwmClient),
bspwmevent.NewManager(logger, bspwmClient),
Expand Down
47 changes: 45 additions & 2 deletions internal/feature/transparent_monocle.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,12 @@ func StartTransparentMonocle(
}
}

// TODO: we can't know what node was focused atm. So the newly focused node (the one called last below) is
// going to be random for now. Refactor this when I add an internal representation of bspwm's state.
st, err := service.State()
if err != nil {
logger.Error("failed to retrieve bspwm's current state",
append(loggerOpts, zap.Error(err))...,
)
}

for _, n := range sourceNodes {
if err := handleNodeRemoved(logger, service, desktops, payload.SourceDesktopID, n.ID); err != nil {
Expand All @@ -225,6 +229,28 @@ func StartTransparentMonocle(
}
}

if len(sourceNodes) == 1 {
focusedIndex, ok := findMostRecentlyFocusedNode(st.OrderedFocusHistory(), payload.SourceDesktopID, sourceNodes)
if ok {
focusedNode := sourceNodes[focusedIndex]

// Move node to focus to the end of the slice so it gets called last. (giving it focus)
sourceNodes = append(sourceNodes[:focusedIndex], sourceNodes[focusedIndex+1:]...)
sourceNodes = append(sourceNodes, focusedNode)
}
}

if len(destinationNodes) == 1 {
focusedIndex, ok := findMostRecentlyFocusedNode(st.OrderedFocusHistory(), payload.DestinationDesktopID, destinationNodes)
if ok {
focusedNode := destinationNodes[focusedIndex]

// Move node to focus to the end of the slice so it gets called last. (giving it focus)
destinationNodes = append(destinationNodes[:focusedIndex], destinationNodes[focusedIndex+1:]...)
destinationNodes = append(destinationNodes, focusedNode)
}
}

for _, n := range sourceNodes {
if err := handleNodeAdded(logger, service, desktops, payload.DestinationDesktopID, n.ID); err != nil {
logger.Error("failed to handle node swap (across desktops) source node added at destination desktop",
Expand Down Expand Up @@ -548,3 +574,20 @@ func removeFromSlice(slice []bspc.ID, toRemove bspc.ID) []bspc.ID {

return ss
}

// findMostRecentlyFocusedNode returns the node from the provided slice that shows up first in the focused node history.
func findMostRecentlyFocusedNode(focusHistory []bspc.StateFocusHistoryEntry, relevantDesktopID bspc.ID, nodes []bspc.Node) (int, bool) {
for _, prevFocusedNode := range focusHistory {
if prevFocusedNode.DesktopID != relevantDesktopID {
continue
}

for index, n := range nodes {
if prevFocusedNode.NodeID == n.ID {
return index, true
}
}
}

return -1, false
}

0 comments on commit d502143

Please sign in to comment.