Skip to content

Commit

Permalink
Add support for creating single view
Browse files Browse the repository at this point in the history
  • Loading branch information
mikkeloscar committed Feb 13, 2017
1 parent a74e646 commit 20595a6
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 21 deletions.
15 changes: 14 additions & 1 deletion compositor/compositor.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,22 @@ func (c *Compositor) OutputCreated(o wlc.Output) bool {
return true
}

// OutputResolution is the callback triggered when output resolution changes.
func (c *Compositor) OutputResolution(o wlc.Output, from *wlc.Size, to *wlc.Size) {
c.layout.Arrange(c.layout.OutputByBackend(o))
}

// ViewRequestGeometry is the callback triggered when a new view geometry is
// requested. Note this callback must allways be be set (even if it's stubbed)
// otherwise wlc won't accept your geometry requests.
func (c *Compositor) ViewRequestGeometry(view wlc.View, geometry *wlc.Geometry) {
// stub intentionally to ignore geometry requests.
}

// ViewCreated is the callback triggered when a view is added by the backend.
func (c *Compositor) ViewCreated(v wlc.View) bool {
c.layout.NewView(c.ctx, v)
view := c.layout.NewView(c.ctx, v)
c.layout.Arrange(view.Parent())

// TODO: return false on failure
return true
Expand Down
13 changes: 13 additions & 0 deletions layout/i3/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,26 @@ func New() *Layout {
func (l *Layout) Arrange(start layout.Container) {
// TODO: implement with more than one view
switch c := start.(type) {
case *layout.Root:
l.Arrange(c.Focused())
case *layout.Output:
log.Debugf("OUTPUT VISIBILITY MASK %d", c.GetMask())
l.Arrange(c.Focused())
case *layout.Workspace:
l.Arrange(c.Focused())
case *layout.View:
c.SetMask(1) // TODO: don't set it here
pG := c.Parent().Geometry()
g := c.Geometry()
g.Origin = pG.Origin
g.Size = pG.Size
log.Debugf("Arranging view %s %dx%d (%d,%d)", c.Title(),
g.Size.W, g.Size.H, g.Origin.X, g.Origin.Y)
c.SetGeometry(0, *g)

// if c.Focused() == c {
c.Focus()
// }
}
}

Expand Down
10 changes: 10 additions & 0 deletions layout/i3/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ func (l *Layout) NewOutput(ctx context.Context, output backend.Output) {
l.NewWorkspace(ctx, o, name, num)
}

// OutputByBackend gets output container from backend output interface.
func (l *Layout) OutputByBackend(output backend.Output) layout.Container {
for _, child := range l.root.Children() {
if o, ok := child.(*layout.Output); ok && o.Output == output {
return child
}
}
return nil
}

// findNextWorkspace finds next available workspace name & number.
func findNextWorkspace(ws []*layout.Workspace, confWs map[uint]string) (string, uint) {
num := findAvailableWorkspaceNum(ws)
Expand Down
94 changes: 77 additions & 17 deletions layout/i3/output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package i3

import (
"context"
"fmt"
"testing"

"github.com/mikkeloscar/flis/backend"
"github.com/mikkeloscar/flis/config"
"github.com/mikkeloscar/flis/layout"
wlc "github.com/mikkeloscar/go-wlc"
Expand All @@ -21,14 +23,76 @@ func TestNewOutput(t *testing.T) {
},
)

output := wlc.Output(0)
output := mockOutput(0)
layout := New()
layout.NewOutput(ctx, output)
}

type mockOutput int

func (o mockOutput) Focus() {}
func (o mockOutput) GetMask() uint32 { return 0 }
func (o mockOutput) GetMutableViews() []wlc.View { return nil }
func (o mockOutput) Name() string { return fmt.Sprintf("%d", o) }
func (o mockOutput) GetRenderer() wlc.Renderer { return wlc.NoRenderer }
func (o mockOutput) GetResolution() *wlc.Size { return nil }
func (o mockOutput) GetVirtualResolution() *wlc.Size { return nil }
func (o mockOutput) SetResolution(resolution wlc.Size, scale uint32) {}
func (o mockOutput) GetScale() uint32 { return 0 }
func (o mockOutput) GetSleep() bool { return false }
func (o mockOutput) GetViews() []wlc.View { return nil }
func (o mockOutput) ScheduleRender() {}
func (o mockOutput) SetMask(mask uint32) {}
func (o mockOutput) SetSleep(sleep bool) {}
func (o mockOutput) SetViews(views []wlc.View) bool { return false }

// TestOutputByBackend tests getting an output container from a backend output
// interface.
func TestOutputByBackend(t *testing.T) {
ctx := context.WithValue(
context.Background(),
"config",
&config.Config{
Workspaces: map[uint]string{
1: "one",
},
},
)

layout := New()

for i := 0; i < 5; i++ {
output := mockOutput(i)
layout.NewOutput(ctx, output)
}

for _, ti := range []struct {
output backend.Output
exists bool
}{
{
output: mockOutput(2),
exists: true,
},
{
output: mockOutput(10),
exists: false,
},
} {
c := layout.OutputByBackend(ti.output)
if c == nil && ti.exists {
t.Errorf("expected to find an output")
}

if c != nil && !ti.exists {
t.Errorf("did not expect to find an output")
}
}
}

// TestFindNextWorkspace tests finding the next available workspace.
func TestFindNextWorkspace(t *testing.T) {
tests := []struct {
for _, ti := range []struct {
current []*layout.Workspace
names map[uint]string
name string
Expand Down Expand Up @@ -64,23 +128,21 @@ func TestFindNextWorkspace(t *testing.T) {
"2",
2,
},
}

for _, test := range tests {
name, num := findNextWorkspace(test.current, test.names)
if name != test.name {
t.Errorf("expected to get workspace name '%s', got '%s'", test.name, name)
} {
name, num := findNextWorkspace(ti.current, ti.names)
if name != ti.name {
t.Errorf("expected to get workspace name '%s', got '%s'", ti.name, name)
}

if num != test.num {
t.Errorf("expected to get workspace num '%d', got '%d'", test.num, num)
if num != ti.num {
t.Errorf("expected to get workspace num '%d', got '%d'", ti.num, num)
}
}
}

// TestFindAvailableWorkspaceNum tests finding available workspace number.
func TestFindAvailableWorkspaceNum(t *testing.T) {
tests := []struct {
for _, ti := range []struct {
ws []*layout.Workspace
num uint
}{
Expand Down Expand Up @@ -108,12 +170,10 @@ func TestFindAvailableWorkspaceNum(t *testing.T) {
},
2,
},
}

for _, test := range tests {
num := findAvailableWorkspaceNum(test.ws)
if num != test.num {
t.Errorf("expected workspace num %d, got %d", test.num, num)
} {
num := findAvailableWorkspaceNum(ti.ws)
if num != ti.num {
t.Errorf("expected workspace num %d, got %d", ti.num, num)
}
}
}
3 changes: 2 additions & 1 deletion layout/i3/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import (

// NewView adds a new view to the layout. The view will be added to the
// currently focused container.
func (l *Layout) NewView(ctx context.Context, view backend.View) {
func (l *Layout) NewView(ctx context.Context, view backend.View) layout.Container {
// TODO: check if sibling or parent
parent := l.FocusedByType(ctx, layout.CWorkspace)
v := layout.NewView(view, parent)
parent.AddChild(v)
return v
}
6 changes: 5 additions & 1 deletion layout/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,18 @@ type Layout interface {
NewWorkspace(ctx context.Context, output *Output, name string, num uint)

// NewView initializes a new view.
NewView(ctx context.Context, view backend.View)
NewView(ctx context.Context, view backend.View) Container

// ArrangeRoot arranges the whole layout from the root and down.
ArrangeRoot()

// Arrange arranges a subbranch of the layout starting from the
// specified container and moving down the layout.
Arrange(start Container)

// OutputByBackend gets output container from backend output interface.
OutputByBackend(output backend.Output) Container
// ViewByBackend(output backend.Output) Container
}

// Get layout from context.
Expand Down
35 changes: 34 additions & 1 deletion layout/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"github.com/mikkeloscar/flis/backend"
wlc "github.com/mikkeloscar/go-wlc"
)

// Mock mocks the layout interface.
Expand All @@ -28,11 +29,43 @@ func (m Mock) NewOutput(ctx context.Context, output backend.Output) {}
func (m Mock) NewWorkspace(ctx context.Context, output *Output, name string, num uint) {}

// NewView mocks initializing a new view.
func (m Mock) NewView(ctx context.Context, view backend.View) {}
func (m Mock) NewView(ctx context.Context, view backend.View) Container {
return MockView{}
}

// ArrangeRoot mocks arranging the whole layout from the root and down.
func (m Mock) ArrangeRoot() {}

// Arrange mocks arranging a subbranch of the layout starting from the
// specified container and moving down the layout.
func (m Mock) Arrange(start Container) {}

// OutputByBackend gets output container from backend output interface.
func (m Mock) OutputByBackend(output backend.Output) Container { return nil }

// MockView mocks a view container.
type MockView struct{}

// Geometry mocks geometry of the container.
func (v MockView) Geometry() *wlc.Geometry { return nil }

// Children mocks children of the container.
func (v MockView) Children() []Container { return nil }

// Floating mocks floating children of the container.
func (v MockView) Floating() []Container { return nil }

// Focused mocks focused child of the container.
func (v MockView) Focused() Container { return nil }

// Parent mocks getting parent container of the container.
func (v MockView) Parent() Container { return nil }

// Visible mocks return the visibility state of the container.
func (v MockView) Visible() bool { return false }

// AddChild mocks adding a child container.
func (v MockView) AddChild(Container) {}

// Type mocks returning the type of the container.
func (v MockView) Type() ContainerType { return CView }
12 changes: 12 additions & 0 deletions layout/mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,16 @@ func TestMock(t *testing.T) {
m.NewView(nil, nil)
m.ArrangeRoot()
m.Arrange(nil)
m.OutputByBackend(nil)

v := MockView{}

v.Geometry()
v.Children()
v.Floating()
v.Focused()
v.Parent()
v.Visible()
v.AddChild(nil)
v.Type()
}
17 changes: 17 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,12 @@ func main() {
comp := compositor.New(conf, &backend.WLC{}, i3.New())

wlc.SetOutputCreatedCb(comp.OutputCreated)
wlc.SetOutputResolutionCb(comp.OutputResolution)
wlc.SetViewCreatedCb(comp.ViewCreated)
wlc.SetViewRequestGeometryCb(comp.ViewRequestGeometry)
wlc.SetPointerMotionCb(comp.PointerMotion)
wlc.SetKeyboardKeyCb(comp.KeyboardKey)
wlc.LogSetHandler(wlcLogHandler)

if !wlc.Init() {
os.Exit(1)
Expand All @@ -68,3 +71,17 @@ func main() {
wlc.Run()
os.Exit(0)
}

func wlcLogHandler(typ wlc.LogType, msg string) {
format := "[WLC] %s"
switch typ {
case wlc.LogInfo:
log.Debugf(format, msg)
case wlc.LogWarn:
log.Warnf(format, msg)
case wlc.LogError:
log.Errorf(format, msg)
case wlc.LogWayland:
log.Debugf("[WLC - Wayland] %s", msg)
}
}

0 comments on commit 20595a6

Please sign in to comment.