From 9360ffff499d78aa94bf20514972a18ea980b5f3 Mon Sep 17 00:00:00 2001 From: Jakub Sobon Date: Sun, 27 Dec 2020 02:53:08 -0500 Subject: [PATCH 1/3] Bugfix: avoid crash on terminal rezise with tcell. --- CHANGELOG.md | 5 +++++ private/canvas/canvas.go | 21 +++++++-------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aedbf0f..729e75e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 func (*BarChart) Mouse(m *terminalapi.Mouse, meta *widgetapi.EventMeta) error { ... } ``` +### Fixed + +- `termdash` no longer crashes when `tcell` is used and the terminal window + downsizes while content is being drawn. + ### Added #### Infrastructure changes diff --git a/private/canvas/canvas.go b/private/canvas/canvas.go index 65a1e69..9682d98 100644 --- a/private/canvas/canvas.go +++ b/private/canvas/canvas.go @@ -195,21 +195,14 @@ func (c *Canvas) copyTo(offset image.Point, dstSetCell setCellFunc) error { } // Apply applies the canvas to the corresponding area of the terminal. -// Guarantees to stay within limits of the area the canvas was created with. func (c *Canvas) Apply(t terminalapi.Terminal) error { - termArea, err := area.FromSize(t.Size()) - if err != nil { - return err - } - - bufArea, err := area.FromSize(c.buffer.Size()) - if err != nil { - return err - } - - if !bufArea.In(termArea) { - return fmt.Errorf("the canvas area %+v doesn't fit onto the terminal %+v", bufArea, termArea) - } + // Note - the size of the terminal might have changed since we started + // drawing, since terminal windows are inherently racy (the user can resize + // them at any time). + // + // This is ok, since the underlying terminal layer will just ignore cells + // that are out of bounds and termdash will redraw again once it receives + // the resize event. Regression for #281. // The image.Point{0, 0} of this canvas isn't always exactly at // image.Point{0, 0} on the terminal. From 7ac5acfd6b79f269605bbb9ca3d982570069ae22 Mon Sep 17 00:00:00 2001 From: Jakub Sobon Date: Sun, 27 Dec 2020 03:08:57 -0500 Subject: [PATCH 2/3] Container option that sets the container as focused. --- CHANGELOG.md | 2 ++ container/focus_test.go | 45 ++++++++++++++++++++++++++++++++++++++++- container/options.go | 11 ++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 729e75e..c992aea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - containers can register into separate focus groups and specific keyboard keys can be configured to move the focus within each focus group. - widgets can now request keyboard events exclusively when focused. +- users can now set a `container` as focused using a new `container.Focused` + option. #### Updates to the `button` widget diff --git a/container/focus_test.go b/container/focus_test.go index 95faa2f..58c8ce3 100644 --- a/container/focus_test.go +++ b/container/focus_test.go @@ -541,7 +541,7 @@ func TestFocusTrackerNextAndPrevious(t *testing.T) { wantProcessed int }{ { - desc: "initially the root is focused", + desc: "initially the root is focused by default", container: func(ft *faketerm.Terminal) (*Container, error) { return New( ft, @@ -554,6 +554,49 @@ func TestFocusTrackerNextAndPrevious(t *testing.T) { }, wantFocused: contLocA, }, + { + desc: "focus root explicitly", + container: func(ft *faketerm.Terminal) (*Container, error) { + return New( + ft, + Focused(), + SplitVertical( + Left(), + Right(), + ), + KeyFocusNext(keyNext), + ) + }, + wantFocused: contLocA, + }, + { + desc: "focus can be set to a container other than root", + container: func(ft *faketerm.Terminal) (*Container, error) { + return New( + ft, + SplitVertical( + Left(Focused()), + Right(), + ), + KeyFocusNext(keyNext), + ) + }, + wantFocused: contLocB, + }, + { + desc: "option Focused used on multiple containers, the last one takes effect", + container: func(ft *faketerm.Terminal) (*Container, error) { + return New( + ft, + SplitVertical( + Left(Focused()), + Right(Focused()), + ), + KeyFocusNext(keyNext), + ) + }, + wantFocused: contLocC, + }, { desc: "keyNext does nothing when only root exists", container: func(ft *faketerm.Terminal) (*Container, error) { diff --git a/container/options.go b/container/options.go index db50058..795e61c 100644 --- a/container/options.go +++ b/container/options.go @@ -1033,3 +1033,14 @@ func KeyFocusGroupsPrevious(key keyboard.Key, groups ...FocusGroup) Option { return nil }) } + +// Focused moves the keyboard focus to this container. +// If not specified, termdash will start with the root container focused. +// If specified on multiple containers, the last container with this option +// will be focused. +func Focused() Option { + return option(func(c *Container) error { + c.focusTracker.setActive(c) + return nil + }) +} From bcd25c80e90924596ce5273fc828f6d3ab1e4b01 Mon Sep 17 00:00:00 2001 From: Jakub Sobon Date: Sun, 27 Dec 2020 03:10:43 -0500 Subject: [PATCH 3/3] Fixing a grammar mistake in the CHANGELOG. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c992aea..104a68f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,7 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - containers can register into separate focus groups and specific keyboard keys can be configured to move the focus within each focus group. - widgets can now request keyboard events exclusively when focused. -- users can now set a `container` as focused using a new `container.Focused` +- users can now set a `container` as focused using the new `container.Focused` option. #### Updates to the `button` widget