From 2deca549f5a1b01aeb86e88e983130a9693154e9 Mon Sep 17 00:00:00 2001 From: Joe Julian Date: Fri, 10 Apr 2026 23:05:30 -0700 Subject: [PATCH] Fix desktop header menu layout --- internal/appui/app.go | 1 + internal/appui/frame.go | 18 ++++++++++++++++++ internal/appui/header.go | 41 ++++++++++++++++++---------------------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/internal/appui/app.go b/internal/appui/app.go index fa9d237..0e7f1cf 100644 --- a/internal/appui/app.go +++ b/internal/appui/app.go @@ -2024,6 +2024,7 @@ func (u *ui) detailPanel(gtx layout.Context) layout.Dimensions { if u.shouldShowDesktopWorkingHeader() { return layout.Flex{Axis: layout.Vertical}.Layout(gtx, layout.Rigid(u.headerActions), + layout.Rigid(u.desktopHeaderMenus), layout.Rigid(layout.Spacer{Height: unit.Dp(12)}.Layout), layout.Flexed(1, func(gtx layout.Context) layout.Dimensions { return u.detailPanelContent(gtx) diff --git a/internal/appui/frame.go b/internal/appui/frame.go index 1df45a2..23f71ae 100644 --- a/internal/appui/frame.go +++ b/internal/appui/frame.go @@ -1312,6 +1312,9 @@ func (u *ui) primaryContent(gtx layout.Context) layout.Dimensions { case u.shouldUseLockedSinglePane(): return u.detailPanel(gtx) case !u.shouldShowDetailPane(): + if !u.usesCompactViewport() { + return u.desktopListOnlyContent(gtx) + } return u.listPanel(gtx) case u.usesCompactViewport(): return u.compactPrimaryContent(gtx) @@ -1368,6 +1371,21 @@ func (u *ui) widePrimaryContent(gtx layout.Context) layout.Dimensions { ) } +func (u *ui) desktopListOnlyContent(gtx layout.Context) layout.Dimensions { + return layout.Flex{Axis: layout.Vertical}.Layout(gtx, + layout.Rigid(func(gtx layout.Context) layout.Dimensions { + return card(gtx, func(gtx layout.Context) layout.Dimensions { + return layout.Flex{Axis: layout.Vertical}.Layout(gtx, + layout.Rigid(u.headerActions), + layout.Rigid(u.desktopHeaderMenus), + ) + }) + }), + layout.Rigid(layout.Spacer{Height: unit.Dp(12)}.Layout), + layout.Flexed(1, u.listPanel), + ) +} + func (u *ui) syncDialogOverlay(gtx layout.Context) layout.Dimensions { if !u.syncDialogOpen { return layout.Dimensions{} diff --git a/internal/appui/header.go b/internal/appui/header.go index 97469c2..31939f2 100644 --- a/internal/appui/header.go +++ b/internal/appui/header.go @@ -49,9 +49,6 @@ func (u *ui) headerActions(gtx layout.Context) layout.Dimensions { cluster.prepareCompactMenus(gtx, u) return layout.Dimensions{Size: image.Pt(gtx.Constraints.Max.X, rowDims.Size.Y)} } - - cluster.drawOverlayMenus(gtx, u, headerlayout.DropdownSurface{ContainerWidth: gtx.Constraints.Max.X, LeftInset: 0, TopInset: 0}) - return rowDims } @@ -146,24 +143,7 @@ func (c *headerActionCluster) prepareCompactMenus(gtx layout.Context, u *ui) { } } -func (c headerActionCluster) drawOverlayMenus(gtx layout.Context, u *ui, surface headerlayout.DropdownSurface) { - if c.ShowSyncMenu() { - placement, menuCall := surface.Place(gtx, c.Metrics.SyncAnchor(), c.SyncMenu) - u.maybeLogHeaderMenuPlacement("sync", surface, placement) - stack := op.Offset(placement.Origin).Push(gtx.Ops) - menuCall.Add(gtx.Ops) - stack.Pop() - } - if c.ShowMainMenu() { - placement, menuCall := surface.Place(gtx, c.Metrics.MainAnchor(), c.MainMenu) - u.maybeLogHeaderMenuPlacement("main", surface, placement) - stack := op.Offset(placement.Origin).Push(gtx.Ops) - menuCall.Add(gtx.Ops) - stack.Pop() - } -} - -func (c headerActionCluster) layoutCompactMenuRow(gtx layout.Context) layout.Dimensions { +func (c headerActionCluster) layoutMenuRow(gtx layout.Context) layout.Dimensions { menu := c.activeMenu() if menu == nil { return layout.Dimensions{} @@ -223,7 +203,7 @@ func (u *ui) phoneHeaderMenus(gtx layout.Context) layout.Dimensions { return layout.UniformInset(unit.Dp(16)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { stack := op.Offset(image.Pt(0, max(0, u.phoneSyncMenuOrigin.Y-u.frameInsetPx))).Push(gtx.Ops) defer stack.Pop() - dims := cluster.layoutCompactMenuRow(gtx) + dims := cluster.layoutMenuRow(gtx) return layout.Dimensions{Size: image.Pt(gtx.Constraints.Max.X, max(dims.Size.Y, u.phoneSyncMenuOrigin.Y))} }) } @@ -231,13 +211,28 @@ func (u *ui) phoneHeaderMenus(gtx layout.Context) layout.Dimensions { return layout.UniformInset(unit.Dp(16)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { stack := op.Offset(image.Pt(0, max(0, u.phoneMainMenuOrigin.Y-u.frameInsetPx))).Push(gtx.Ops) defer stack.Pop() - dims := cluster.layoutCompactMenuRow(gtx) + dims := cluster.layoutMenuRow(gtx) return layout.Dimensions{Size: image.Pt(gtx.Constraints.Max.X, max(dims.Size.Y, u.phoneMainMenuOrigin.Y))} }) } return layout.Dimensions{} } +func (u *ui) desktopHeaderMenus(gtx layout.Context) layout.Dimensions { + if u.usesCompactViewport() || (!u.syncMenuOpen && !u.mainMenuOpen) { + return layout.Dimensions{} + } + cluster := u.newHeaderActionCluster(gtx) + dims := cluster.layoutMenuRow(gtx) + if dims.Size.Y == 0 { + return dims + } + return layout.Flex{Axis: layout.Vertical}.Layout(gtx, + layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout), + layout.Rigid(func(gtx layout.Context) layout.Dimensions { return dims }), + ) +} + func (u *ui) syncMenuVisibleOnPhone() bool { return u.usesCompactViewport() && u.phoneSyncMenuVisible && u.syncMenuOpen }