1
0
mirror of https://github.com/mum4k/termdash.git synced 2025-04-25 13:48:50 +08:00

Correctly track container focus when the terminal size increases.

Fixes #169.
This commit is contained in:
Jakub Sobon 2019-03-11 01:04:03 -04:00
parent 926d5226fa
commit 4203d0e794
No known key found for this signature in database
GPG Key ID: F2451A77FB05D3B7
4 changed files with 99 additions and 2 deletions

View File

@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The termdash_test now correctly waits until all subscribers processed events,
not just received them.
- Container focus tracker now correctly tracks focus changes in enlarged areas,
i.e. when the terminal size increased.
#### Breaking API changes

View File

@ -214,6 +214,14 @@ func (c *Container) createSecond(opts []Option) error {
func (c *Container) Draw() error {
c.mu.Lock()
defer c.mu.Unlock()
// Update the area we are tracking for focus in case the terminal size
// changed.
ar, err := area.FromSize(c.term.Size())
if err != nil {
return err
}
c.focusTracker.updateArea(ar)
return drawTree(c)
}

View File

@ -1240,7 +1240,7 @@ func TestMouse(t *testing.T) {
},
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
// Widgets that aren't focused don't get the mouse clicks.
// Widgets that aren't targeted don't get the mouse clicks.
fakewidget.MustDraw(
ft,
testcanvas.MustNew(image.Rect(0, 0, 25, 20)),
@ -1253,7 +1253,7 @@ func TestMouse(t *testing.T) {
&terminalapi.Keyboard{},
)
// The focused widget receives the key.
// The target widget receives the mouse event.
fakewidget.MustDraw(
ft,
testcanvas.MustNew(image.Rect(25, 0, 50, 10)),
@ -1265,6 +1265,87 @@ func TestMouse(t *testing.T) {
},
wantProcessed: 8,
},
{
desc: "event focuses the target container after terminal resize (falls onto the new area), regression for #169",
termSize: image.Point{50, 20},
container: func(ft *faketerm.Terminal) (*Container, error) {
// Decrease the terminal size, so when container is created, it
// only sees width of 30.
if err := ft.Resize(image.Point{30, 20}); err != nil {
return nil, err
}
c, err := New(
ft,
SplitVertical(
Left(
PlaceWidget(fakewidget.New(widgetapi.Options{WantMouse: widgetapi.MouseScopeWidget})),
),
Right(
SplitHorizontal(
Top(
Border(linestyle.Light),
PlaceWidget(fakewidget.New(widgetapi.Options{WantMouse: widgetapi.MouseScopeWidget})),
),
Bottom(
PlaceWidget(fakewidget.New(widgetapi.Options{WantMouse: widgetapi.MouseScopeWidget})),
),
),
),
),
)
if err != nil {
return nil, err
}
// Increase the width back to 50 so the mouse clicks land on the "new" area.
if err := ft.Resize(image.Point{50, 20}); err != nil {
return nil, err
}
// Draw once so the container has a chance to update the tracked area.
if err := c.Draw(); err != nil {
return nil, err
}
return c, nil
},
events: []terminalapi.Event{
&terminalapi.Mouse{Position: image.Point{48, 8}, Button: mouse.ButtonLeft},
&terminalapi.Mouse{Position: image.Point{48, 8}, Button: mouse.ButtonRelease},
},
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
// The yellow border signifies that the container was focused.
cvs := testcanvas.MustNew(ft.Area())
testdraw.MustBorder(
cvs,
image.Rect(25, 0, 50, 10),
draw.BorderCellOpts(cell.FgColor(cell.ColorYellow)),
)
testcanvas.MustApply(cvs, ft)
// Widgets that aren't targeted don't get the mouse clicks.
fakewidget.MustDraw(
ft,
testcanvas.MustNew(image.Rect(0, 0, 25, 20)),
widgetapi.Options{},
)
fakewidget.MustDraw(
ft,
testcanvas.MustNew(image.Rect(25, 10, 50, 20)),
widgetapi.Options{WantMouse: widgetapi.MouseScopeWidget},
&terminalapi.Keyboard{},
)
// The target widget receives the mouse event.
fakewidget.MustDraw(
ft,
testcanvas.MustNew(image.Rect(26, 1, 49, 9)),
widgetapi.Options{WantMouse: widgetapi.MouseScopeWidget},
&terminalapi.Mouse{Position: image.Point{22, 7}, Button: mouse.ButtonLeft},
&terminalapi.Mouse{Position: image.Point{22, 7}, Button: mouse.ButtonRelease},
)
return ft
},
wantProcessed: 8,
},
{
desc: "event not forwarded if the widget didn't request it",
termSize: image.Point{20, 20},

View File

@ -92,3 +92,9 @@ func (ft *focusTracker) mouse(target *Container, m *terminalapi.Mouse) {
}
}
}
// updateArea updates the area that the focus tracker considers active for
// mouse clicks.
func (ft *focusTracker) updateArea(ar image.Rectangle) {
ft.buttonFSM.UpdateArea(ar)
}