fix: promote remaining browser window on close
- commit
- 68837f5f00be6598114310febc874a074fe5a04e
- author
- brice · · 2026-04-14 15:37 UTC
- parent
- 7109c5e
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +51 -0
M internal/ui/browser_window.go +8 -0
| @@ -27,7 +27,15 @@ func (a *App) removeBrowserWindow(id string) { | |||
| 27 | 27 | return | |
| 28 | 28 | } | |
| 29 | 29 | if bw := a.browserWindows[id]; bw != nil && bw.mainWindow == a.mainWindow { | |
| 30 | + | delete(a.browserWindows, id) | |
| 31 | + | for _, remaining := range a.browserWindows { | |
| 32 | + | if remaining != nil && remaining.mainWindow != nil { | |
| 33 | + | a.mainWindow = remaining.mainWindow | |
| 34 | + | return | |
| 35 | + | } | |
| 36 | + | } | |
| 30 | 37 | a.mainWindow = nil | |
| 38 | + | return | |
| 31 | 39 | } | |
| 32 | 40 | delete(a.browserWindows, id) | |
| 33 | 41 | } | |
| @@ -27,7 +27,15 @@ func (a *App) removeBrowserWindow(id string) { | |||||
| 27 | return | 27 | return | ||
| 28 | } | 28 | } | ||
| 29 | if bw := a.browserWindows[id]; bw != nil && bw.mainWindow == a.mainWindow { | 29 | if bw := a.browserWindows[id]; bw != nil && bw.mainWindow == a.mainWindow { | ||
| 30 | + | delete(a.browserWindows, id) | |||
| 31 | + | for _, remaining := range a.browserWindows { | |||
| 32 | + | if remaining != nil && remaining.mainWindow != nil { | |||
| 33 | + | a.mainWindow = remaining.mainWindow | |||
| 34 | + | return | |||
| 35 | + | } | |||
| 36 | + | } | |||
| 30 | a.mainWindow = nil | 37 | a.mainWindow = nil | ||
| 38 | + | return | |||
| 31 | } | 39 | } | ||
| 32 | delete(a.browserWindows, id) | 40 | delete(a.browserWindows, id) | ||
| 33 | } | 41 | } | ||
M internal/ui/browser_window_test.go +43 -0
| @@ -3,6 +3,8 @@ package ui | |||
| 3 | 3 | import ( | |
| 4 | 4 | "context" | |
| 5 | 5 | "testing" | |
| 6 | + | ||
| 7 | + | "github.com/bnema/dumber/internal/ui/window" | |
| 6 | 8 | ) | |
| 7 | 9 | ||
| 8 | 10 | func TestBrowserWindow_RegisterAndRemoveTrackCollection(t *testing.T) { | |
| @@ -33,6 +35,47 @@ func TestBrowserWindow_RegisterAndRemoveTrackCollection(t *testing.T) { | |||
| 33 | 35 | } | |
| 34 | 36 | } | |
| 35 | 37 | ||
| 38 | + | func TestBrowserWindow_RemovePromotesRemainingMainWindow(t *testing.T) { | |
| 39 | + | mainWindow := &window.MainWindow{} | |
| 40 | + | otherWindow := &window.MainWindow{} | |
| 41 | + | first := &browserWindow{id: "window-1", mainWindow: mainWindow} | |
| 42 | + | second := &browserWindow{id: "window-2", mainWindow: otherWindow} | |
| 43 | + | app := &App{ | |
| 44 | + | mainWindow: mainWindow, | |
| 45 | + | browserWindows: map[string]*browserWindow{first.id: first, second.id: second}, | |
| 46 | + | } | |
| 47 | + | ||
| 48 | + | app.removeBrowserWindow(first.id) | |
| 49 | + | ||
| 50 | + | if app.mainWindow != otherWindow { | |
| 51 | + | t.Fatalf("mainWindow = %p, want promoted window %p", app.mainWindow, otherWindow) | |
| 52 | + | } | |
| 53 | + | if len(app.browserWindows) != 1 { | |
| 54 | + | t.Fatalf("browserWindows length = %d, want 1", len(app.browserWindows)) | |
| 55 | + | } | |
| 56 | + | if _, ok := app.browserWindows[second.id]; !ok { | |
| 57 | + | t.Fatalf("remaining browser window was not kept") | |
| 58 | + | } | |
| 59 | + | } | |
| 60 | + | ||
| 61 | + | func TestBrowserWindow_RemoveLastClearsMainWindow(t *testing.T) { | |
| 62 | + | mainWindow := &window.MainWindow{} | |
| 63 | + | first := &browserWindow{id: "window-1", mainWindow: mainWindow} | |
| 64 | + | app := &App{ | |
| 65 | + | mainWindow: mainWindow, | |
| 66 | + | browserWindows: map[string]*browserWindow{first.id: first}, | |
| 67 | + | } | |
| 68 | + | ||
| 69 | + | app.removeBrowserWindow(first.id) | |
| 70 | + | ||
| 71 | + | if app.mainWindow != nil { | |
| 72 | + | t.Fatalf("mainWindow = %p, want nil", app.mainWindow) | |
| 73 | + | } | |
| 74 | + | if len(app.browserWindows) != 0 { | |
| 75 | + | t.Fatalf("browserWindows length = %d, want 0", len(app.browserWindows)) | |
| 76 | + | } | |
| 77 | + | } | |
| 78 | + | ||
| 36 | 79 | func TestOpenFreshWindow_DispatchesAndTracksBrowserWindow(t *testing.T) { | |
| 37 | 80 | app := &App{browserWindows: make(map[string]*browserWindow)} | |
| 38 | 81 | ||
| @@ -3,6 +3,8 @@ package ui | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "context" | 4 | "context" | ||
| 5 | "testing" | 5 | "testing" | ||
| 6 | + | ||||
| 7 | + | "github.com/bnema/dumber/internal/ui/window" | |||
| 6 | ) | 8 | ) | ||
| 7 | 9 | ||||
| 8 | func TestBrowserWindow_RegisterAndRemoveTrackCollection(t *testing.T) { | 10 | func TestBrowserWindow_RegisterAndRemoveTrackCollection(t *testing.T) { | ||
| @@ -33,6 +35,47 @@ func TestBrowserWindow_RegisterAndRemoveTrackCollection(t *testing.T) { | |||||
| 33 | } | 35 | } | ||
| 34 | } | 36 | } | ||
| 35 | 37 | ||||
| 38 | + | func TestBrowserWindow_RemovePromotesRemainingMainWindow(t *testing.T) { | |||
| 39 | + | mainWindow := &window.MainWindow{} | |||
| 40 | + | otherWindow := &window.MainWindow{} | |||
| 41 | + | first := &browserWindow{id: "window-1", mainWindow: mainWindow} | |||
| 42 | + | second := &browserWindow{id: "window-2", mainWindow: otherWindow} | |||
| 43 | + | app := &App{ | |||
| 44 | + | mainWindow: mainWindow, | |||
| 45 | + | browserWindows: map[string]*browserWindow{first.id: first, second.id: second}, | |||
| 46 | + | } | |||
| 47 | + | ||||
| 48 | + | app.removeBrowserWindow(first.id) | |||
| 49 | + | ||||
| 50 | + | if app.mainWindow != otherWindow { | |||
| 51 | + | t.Fatalf("mainWindow = %p, want promoted window %p", app.mainWindow, otherWindow) | |||
| 52 | + | } | |||
| 53 | + | if len(app.browserWindows) != 1 { | |||
| 54 | + | t.Fatalf("browserWindows length = %d, want 1", len(app.browserWindows)) | |||
| 55 | + | } | |||
| 56 | + | if _, ok := app.browserWindows[second.id]; !ok { | |||
| 57 | + | t.Fatalf("remaining browser window was not kept") | |||
| 58 | + | } | |||
| 59 | + | } | |||
| 60 | + | ||||
| 61 | + | func TestBrowserWindow_RemoveLastClearsMainWindow(t *testing.T) { | |||
| 62 | + | mainWindow := &window.MainWindow{} | |||
| 63 | + | first := &browserWindow{id: "window-1", mainWindow: mainWindow} | |||
| 64 | + | app := &App{ | |||
| 65 | + | mainWindow: mainWindow, | |||
| 66 | + | browserWindows: map[string]*browserWindow{first.id: first}, | |||
| 67 | + | } | |||
| 68 | + | ||||
| 69 | + | app.removeBrowserWindow(first.id) | |||
| 70 | + | ||||
| 71 | + | if app.mainWindow != nil { | |||
| 72 | + | t.Fatalf("mainWindow = %p, want nil", app.mainWindow) | |||
| 73 | + | } | |||
| 74 | + | if len(app.browserWindows) != 0 { | |||
| 75 | + | t.Fatalf("browserWindows length = %d, want 0", len(app.browserWindows)) | |||
| 76 | + | } | |||
| 77 | + | } | |||
| 78 | + | ||||
| 36 | func TestOpenFreshWindow_DispatchesAndTracksBrowserWindow(t *testing.T) { | 79 | func TestOpenFreshWindow_DispatchesAndTracksBrowserWindow(t *testing.T) { | ||
| 37 | app := &App{browserWindows: make(map[string]*browserWindow)} | 80 | app := &App{browserWindows: make(map[string]*browserWindow)} | ||
| 38 | 81 | ||||