detached bfcbf1a

fix(ui): reattach floating sessions after workspace rebuild

commit
bfcbf1a503b9c4d3fddbd35e62018af46c943cd6
author
brice · · 2026-02-10 06:00 UTC
parent
ff584d1
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +28 -11
M internal/ui/app.go +28 -11
@@ -1031,6 +1031,8 @@ func (a *App) rebuildAndAttachWorkspace(ctx context.Context, tabID entity.TabID,
10311031 return
10321032 }
10331033 _ = wsView.Rebuild(ctx)
1034+ a.reattachFloatingSessions(tabID, wsView)
1035+ a.syncFloatingFocus()
10341036
10351037 if tab == nil || tab.Workspace == nil || a.contentCoord == nil {
10361038 return
@@ -1041,6 +1043,31 @@ func (a *App) rebuildAndAttachWorkspace(ctx context.Context, tabID entity.TabID,
10411043 }
10421044 }
10431045
1046+func (a *App) reattachFloatingSessions(tabID entity.TabID, wsView *component.WorkspaceView) {
1047+ if wsView == nil {
1048+ return
1049+ }
1050+
1051+ for key, session := range a.floatingSessions {
1052+ if key.tabID != tabID || session == nil || session.pane == nil {
1053+ continue
1054+ }
1055+
1056+ session.pane.SetParentOverlay(wsView.WorkspaceOverlayWidget())
1057+ if session.widget != nil {
1058+ wsView.AddWorkspaceOverlayWidget(session.widget)
1059+ configureFloatingOverlayMeasurement(wsView.WorkspaceOverlayWidget(), session.widget)
1060+ setFloatingWidgetShown(session.widget, session.pane.IsVisible())
1061+ }
1062+ if session.paneView != nil {
1063+ wsView.RegisterPaneView(session.paneID, session.paneView)
1064+ if session.focusWidget == nil {
1065+ session.focusWidget = session.paneView.WebViewWidget()
1066+ }
1067+ }
1068+ }
1069+}
1070+
10441071 func (a *App) switchToTargetTabIfConfigured(ctx context.Context, out *usecase.MovePaneToTabOutput) {
10451072 if out == nil || out.TargetTab == nil {
10461073 return
@@ -1954,17 +1981,7 @@ func (a *App) createWorkspaceViewWithoutAttach(ctx context.Context, tab *entity.
19541981
19551982 // Store in map
19561983 a.workspaceViews[tab.ID] = wsView
1957- for key, session := range a.floatingSessions {
1958- if key.tabID != tab.ID || session == nil || session.pane == nil {
1959- continue
1960- }
1961- session.pane.SetParentOverlay(wsView.WorkspaceOverlayWidget())
1962- if session.widget != nil {
1963- wsView.AddWorkspaceOverlayWidget(session.widget)
1964- configureFloatingOverlayMeasurement(wsView.WorkspaceOverlayWidget(), session.widget)
1965- setFloatingWidgetShown(session.widget, session.pane.IsVisible())
1966- }
1967- }
1984+ a.reattachFloatingSessions(tab.ID, wsView)
19681985 a.syncFloatingFocus()
19691986
19701987 log.Debug().Str("tab_id", string(tab.ID)).Msg("workspace view created")
@@ -1031,6 +1031,8 @@ func (a *App) rebuildAndAttachWorkspace(ctx context.Context, tabID entity.TabID,
1031 return1031 return
1032 }1032 }
1033 _ = wsView.Rebuild(ctx)1033 _ = wsView.Rebuild(ctx)
1034+ a.reattachFloatingSessions(tabID, wsView)
1035+ a.syncFloatingFocus()
1034 1036
1035 if tab == nil || tab.Workspace == nil || a.contentCoord == nil {1037 if tab == nil || tab.Workspace == nil || a.contentCoord == nil {
1036 return1038 return
@@ -1041,6 +1043,31 @@ func (a *App) rebuildAndAttachWorkspace(ctx context.Context, tabID entity.TabID,
1041 }1043 }
1042 }1044 }
1043 1045
1046+func (a *App) reattachFloatingSessions(tabID entity.TabID, wsView *component.WorkspaceView) {
1047+ if wsView == nil {
1048+ return
1049+ }
1050+
1051+ for key, session := range a.floatingSessions {
1052+ if key.tabID != tabID || session == nil || session.pane == nil {
1053+ continue
1054+ }
1055+
1056+ session.pane.SetParentOverlay(wsView.WorkspaceOverlayWidget())
1057+ if session.widget != nil {
1058+ wsView.AddWorkspaceOverlayWidget(session.widget)
1059+ configureFloatingOverlayMeasurement(wsView.WorkspaceOverlayWidget(), session.widget)
1060+ setFloatingWidgetShown(session.widget, session.pane.IsVisible())
1061+ }
1062+ if session.paneView != nil {
1063+ wsView.RegisterPaneView(session.paneID, session.paneView)
1064+ if session.focusWidget == nil {
1065+ session.focusWidget = session.paneView.WebViewWidget()
1066+ }
1067+ }
1068+ }
1069+}
1070+
1044 func (a *App) switchToTargetTabIfConfigured(ctx context.Context, out *usecase.MovePaneToTabOutput) {1071 func (a *App) switchToTargetTabIfConfigured(ctx context.Context, out *usecase.MovePaneToTabOutput) {
1045 if out == nil || out.TargetTab == nil {1072 if out == nil || out.TargetTab == nil {
1046 return1073 return
@@ -1954,17 +1981,7 @@ func (a *App) createWorkspaceViewWithoutAttach(ctx context.Context, tab *entity.
1954 1981
1955 // Store in map1982 // Store in map
1956 a.workspaceViews[tab.ID] = wsView1983 a.workspaceViews[tab.ID] = wsView
1957- for key, session := range a.floatingSessions {1984+ a.reattachFloatingSessions(tab.ID, wsView)
1958- if key.tabID != tab.ID || session == nil || session.pane == nil {
1959- continue
1960- }
1961- session.pane.SetParentOverlay(wsView.WorkspaceOverlayWidget())
1962- if session.widget != nil {
1963- wsView.AddWorkspaceOverlayWidget(session.widget)
1964- configureFloatingOverlayMeasurement(wsView.WorkspaceOverlayWidget(), session.widget)
1965- setFloatingWidgetShown(session.widget, session.pane.IsVisible())
1966- }
1967- }
1968 a.syncFloatingFocus()1985 a.syncFloatingFocus()
1969 1986
1970 log.Debug().Str("tab_id", string(tab.ID)).Msg("workspace view created")1987 log.Debug().Str("tab_id", string(tab.ID)).Msg("workspace view created")

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close