diff --git a/CHANGELOG.md b/CHANGELOG.md index a465b51c2..6e27079f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Branch, changes and pull request on the cards and the footer catch up within a second of a commit, checkout or edit made outside a turn, where they could lag up to three seconds, and selecting a card reads its checkout at once instead of showing what the last read found. +- Hiding the pull request list in Pulls slides it away at once, where the list stayed on screen until the mouse moved or Pulls next checked GitHub. Showing it again no longer waits a frame either. - Kiro CLI sessions follow `KIRO_HOME`. With it set, lich read Kiro's conversations, cost and context from `~/.kiro` while Kiro kept them under `KIRO_HOME`, so they showed nothing and History listed none; the agent that carries lich's hooks was installed where Kiro never looked, and a sandboxed session was not given the directory it writes into. - Opening or closing the dock no longer leaves the session's terminal cut off at its edge for a beat once the dock stops. The terminal takes its new width as the dock starts moving, so the agent redraws while the dock slides in, where the terminal waited until a tenth of a second after the dock stopped and then jumped. A split layout's terminals fit the moment the dock stops. diff --git a/native/cmd/lich-native/pulls.go b/native/cmd/lich-native/pulls.go index ad13f4b7f..f298a1939 100644 --- a/native/cmd/lich-native/pulls.go +++ b/native/cmd/lich-native/pulls.go @@ -180,6 +180,14 @@ func (p *pullsScreen) layout(gtx C, th *ui.Theme) pullsAction { if p.selected == 0 && p.branchPR == 0 && len(rows.val) > 0 { p.selected = filterPulls(rows.val, filterAll, "")[0].Number } + // Before the slide reads listHidden, so it starts in the frame that + // took the click. + for p.toggleList.click.Clicked(gtx) { + p.listHidden = true + } + for p.view.showList.click.Clicked(gtx) { + p.listHidden = false + } share := p.slide.at(gtx, !p.listHidden) size := gtx.Constraints.Max w := p.listWidth(gtx, th, filterCounts(rows.val, p.query.Text())) diff --git a/native/cmd/lich-native/pulls_list.go b/native/cmd/lich-native/pulls_list.go index fc23b4ecd..5485cc25a 100644 --- a/native/cmd/lich-native/pulls_list.go +++ b/native/cmd/lich-native/pulls_list.go @@ -62,9 +62,6 @@ func (p *pullsScreen) listLayout(gtx C, th *ui.Theme, list pullsRead[[]backend.P // listHeader is the h-11 strip: the field, the hide button beside it. func (p *pullsScreen) listHeader(gtx C, th *ui.Theme) D { - if p.toggleList.click.Clicked(gtx) { - p.listHidden = true - } field := th.Input(&p.query, i18n.T("pulls.pullsList.searchHint")) field.Leading, field.Height, field.TextSize, field.Clear = icPullSearch, ui.Space(7), ui.TextXS, &p.clearQuery return layout.UniformInset(ui.Space(2)).Layout(gtx, func(gtx C) D { diff --git a/native/cmd/lich-native/pulls_view.go b/native/cmd/lich-native/pulls_view.go index 04a2c8ed6..1e2765cb4 100644 --- a/native/cmd/lich-native/pulls_view.go +++ b/native/cmd/lich-native/pulls_view.go @@ -151,9 +151,6 @@ func (v *pullView) tip(key string) *ui.Tooltip { func (v *pullView) layout(gtx C, th *ui.Theme, p *pullsScreen, act *pullsAction) D { v.runQueued() - if v.showList.click.Clicked(gtx) { - p.listHidden = false - } if p.selected == 0 { return v.withToolbar(gtx, th, p, nil, act, func(gtx C) D { return v.empty(gtx, th, p, act) }) } diff --git a/native/cmd/lich-native/stale_pulls_test.go b/native/cmd/lich-native/stale_pulls_test.go index 0f552836f..3ecdd8eac 100644 --- a/native/cmd/lich-native/stale_pulls_test.go +++ b/native/cmd/lich-native/stale_pulls_test.go @@ -6,6 +6,7 @@ import ( "net/http" "testing" + "gioui.org/f32" "gioui.org/widget" "github.com/lichdotdev/lich/native/backend" @@ -195,3 +196,28 @@ func TestPullsViewedTickCountsInTheFrameThatTookTheClick(t *testing.T) { t.Fatal("the click missed the tick") } } + +// The list's slide draws its first frame where it stood, so a click on hide +// or show changes nothing the frame that took it drew: that frame must ask +// for the next one, or the slide waits for the next mouse move. +func TestPullsListSlidesFromTheFrameThatTookTheClick(t *testing.T) { + u, r := pullsDetailShown(t) + listEnd := u.pulls.spans[0].x1 + slideFromClick(t, r, r.smallestClickIn(t, image.Rect(listEnd-40, 0, listEnd, 48))) + if !u.pulls.listHidden { + t.Fatal("the click missed hide") + } + r.settle(t) + slideFromClick(t, r, r.smallestClickIn(t, image.Rect(0, 0, 48, 48))) + if u.pulls.listHidden { + t.Fatal("the click missed show") + } +} + +func slideFromClick(t *testing.T, r *frameRig, p f32.Point) { + t.Helper() + r.queueClick(p) + if _, redraw := r.frame(); !redraw { + t.Error("the frame that took the click asked for no next frame") + } +}