From db41a691e67358db65be85363ab60b0dc46c4bd4 Mon Sep 17 00:00:00 2001 From: Jeena Date: Sun, 22 Mar 2026 02:06:57 +0000 Subject: [PATCH 1/5] window: prevent sidebar from covering the content area Add shrink-end-child: false to the Paned so the content panel cannot be squeezed below its minimum size, and set width-request: 360 on the content ToolbarView so there is always a visible reading area. --- data/ui/window.blp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/ui/window.blp b/data/ui/window.blp index 6c0192d..348064b 100644 --- a/data/ui/window.blp +++ b/data/ui/window.blp @@ -11,6 +11,7 @@ template $FeedTheMonkeyWindow : Adw.ApplicationWindow { focusable: false; shrink-start-child: false; resize-start-child: false; + shrink-end-child: false; start-child: Adw.ToolbarView sidebar_toolbar { top-bar-style: raised; @@ -107,6 +108,7 @@ template $FeedTheMonkeyWindow : Adw.ApplicationWindow { end-child: Adw.ToolbarView { top-bar-style: raised; + width-request: 360; [top] Adw.HeaderBar { From 6d6d9287330ed739cb7402203c2993fbb119c3af Mon Sep 17 00:00:00 2001 From: Jeena Date: Sun, 22 Mar 2026 02:10:37 +0000 Subject: [PATCH 2/5] window: collapse sidebar when dragged too narrow; keep controls accessible When the paned divider is dragged left below 120 px, snap the sidebar closed instead of leaving a sliver. This replaces the previous minimum-width approach. When the sidebar is hidden (via toggle or snap-close), show the refresh button and primary menu in the content header so they remain reachable. Both stacks are kept in sync (spinner/button) with their sidebar counterparts during article fetches. --- data/ui/window.blp | 31 +++++++++++++++++++++++++++++-- src/window.rs | 35 ++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/data/ui/window.blp b/data/ui/window.blp index 348064b..99dcd62 100644 --- a/data/ui/window.blp +++ b/data/ui/window.blp @@ -11,7 +11,6 @@ template $FeedTheMonkeyWindow : Adw.ApplicationWindow { focusable: false; shrink-start-child: false; resize-start-child: false; - shrink-end-child: false; start-child: Adw.ToolbarView sidebar_toolbar { top-bar-style: raised; @@ -108,7 +107,6 @@ template $FeedTheMonkeyWindow : Adw.ApplicationWindow { end-child: Adw.ToolbarView { top-bar-style: raised; - width-request: 360; [top] Adw.HeaderBar { @@ -119,10 +117,39 @@ template $FeedTheMonkeyWindow : Adw.ApplicationWindow { action-name: "win.toggle-sidebar"; } + [start] + Stack content_refresh_stack { + visible: false; + StackPage { + name: "button"; + child: Button { + icon-name: "view-refresh-symbolic"; + tooltip-text: _("Refresh"); + action-name: "win.reload"; + }; + } + StackPage { + name: "spinner"; + child: Spinner { + spinning: true; + width-request: 16; + height-request: 16; + }; + } + } + title-widget: Adw.WindowTitle { title: _("FeedTheMonkey"); }; + [end] + MenuButton content_menu_button { + icon-name: "open-menu-symbolic"; + primary: true; + menu-model: primary_menu; + visible: false; + } + [end] MenuButton article_menu_button { icon-name: "view-more-symbolic"; diff --git a/src/window.rs b/src/window.rs index c3c0699..26beaf9 100644 --- a/src/window.rs +++ b/src/window.rs @@ -45,6 +45,10 @@ pub mod imp { #[template_child] pub article_menu_button: TemplateChild, #[template_child] + pub content_refresh_stack: TemplateChild, + #[template_child] + pub content_menu_button: TemplateChild, + #[template_child] pub sidebar_content: TemplateChild, #[template_child] pub article_list_view: TemplateChild, @@ -164,12 +168,18 @@ pub mod imp { self.sidebar_zoom_css.set(zoom_css).ok(); self.update_sidebar_zoom(zoom); - // Persist sidebar width while dragging (only when visible) + // Persist sidebar width while dragging; collapse when dragged too narrow. let s2 = settings.clone(); - let sidebar_weak = self.sidebar_toolbar.downgrade(); + let win_weak = self.obj().downgrade(); self.paned.connect_notify_local(Some("position"), move |paned, _| { - if sidebar_weak.upgrade().map(|s| s.is_visible()).unwrap_or(false) { - s2.set_int("sidebar-width", paned.position()).ok(); + let Some(win) = win_weak.upgrade() else { return }; + let imp = win.imp(); + if !imp.sidebar_toolbar.is_visible() { return; } + let pos = paned.position(); + if pos < 120 { + imp.set_sidebar_visible(false); + } else { + s2.set_int("sidebar-width", pos).ok(); } }); @@ -409,11 +419,16 @@ pub mod imp { fn setup_sidebar_toggle(&self) {} fn do_toggle_sidebar(&self) { - let sidebar = &*self.sidebar_toolbar; - if sidebar.is_visible() { - sidebar.set_visible(false); - } else { - sidebar.set_visible(true); + self.set_sidebar_visible(!self.sidebar_toolbar.is_visible()); + } + + fn set_sidebar_visible(&self, visible: bool) { + self.sidebar_toolbar.set_visible(visible); + // Mirror refresh stack state and primary menu in the content header + // when the sidebar is hidden, so those controls remain accessible. + self.content_refresh_stack.set_visible(!visible); + self.content_menu_button.set_visible(!visible); + if visible { let settings = gio::Settings::new("net.jeena.FeedTheMonkey"); let saved = settings.int("sidebar-width"); self.paned.set_position(if saved > 0 { saved } else { 280 }); @@ -630,6 +645,7 @@ pub mod imp { *self.filter_rules.borrow_mut() = crate::filters::load_rules(); self.refresh_stack.set_visible_child_name("spinner"); + self.content_refresh_stack.set_visible_child_name("spinner"); // Only show the loading screen if there's nothing to show yet. let has_articles = self.article_store.borrow() @@ -725,6 +741,7 @@ pub mod imp { } } imp.refresh_stack.set_visible_child_name("button"); + imp.content_refresh_stack.set_visible_child_name("button"); }, ); } From d75c63a8ce68eb36bf7da005208662ab6ee438a6 Mon Sep 17 00:00:00 2001 From: Jeena Date: Sun, 22 Mar 2026 04:20:02 +0000 Subject: [PATCH 3/5] window: fix sidebar snap-collapse when dragged narrow Remove shrink-start-child: false so the paned divider can actually be dragged below the sidebar's natural minimum width. Defer the snap-close via idle_add_local_once so widget visibility is not changed mid-drag. --- data/ui/window.blp | 1 - src/window.rs | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/data/ui/window.blp b/data/ui/window.blp index 99dcd62..28f0377 100644 --- a/data/ui/window.blp +++ b/data/ui/window.blp @@ -9,7 +9,6 @@ template $FeedTheMonkeyWindow : Adw.ApplicationWindow { Adw.ToastOverlay toast_overlay { Paned paned { focusable: false; - shrink-start-child: false; resize-start-child: false; start-child: Adw.ToolbarView sidebar_toolbar { diff --git a/src/window.rs b/src/window.rs index 26beaf9..cd61845 100644 --- a/src/window.rs +++ b/src/window.rs @@ -176,8 +176,14 @@ pub mod imp { let imp = win.imp(); if !imp.sidebar_toolbar.is_visible() { return; } let pos = paned.position(); - if pos < 120 { - imp.set_sidebar_visible(false); + if pos < 150 { + // Defer so we don't change widget visibility mid-drag. + let win_weak2 = win_weak.clone(); + glib::idle_add_local_once(move || { + if let Some(win) = win_weak2.upgrade() { + win.imp().set_sidebar_visible(false); + } + }); } else { s2.set_int("sidebar-width", pos).ok(); } From 60fc9d7cfd43b1de3574eff0741493688ca54c42 Mon Sep 17 00:00:00 2001 From: Jeena Date: Sun, 22 Mar 2026 04:21:28 +0000 Subject: [PATCH 4/5] window: prevent paned from covering the content area Add shrink-end-child: false and width-request: 320 on the content ToolbarView so the divider cannot be dragged all the way to the right and hide the article view. --- data/ui/window.blp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/ui/window.blp b/data/ui/window.blp index 28f0377..b56a277 100644 --- a/data/ui/window.blp +++ b/data/ui/window.blp @@ -10,6 +10,7 @@ template $FeedTheMonkeyWindow : Adw.ApplicationWindow { Paned paned { focusable: false; resize-start-child: false; + shrink-end-child: false; start-child: Adw.ToolbarView sidebar_toolbar { top-bar-style: raised; @@ -106,6 +107,7 @@ template $FeedTheMonkeyWindow : Adw.ApplicationWindow { end-child: Adw.ToolbarView { top-bar-style: raised; + width-request: 320; [top] Adw.HeaderBar { From 126bd197706596641a79fc336092eb4d60742585 Mon Sep 17 00:00:00 2001 From: Jeena Date: Sun, 22 Mar 2026 04:22:21 +0000 Subject: [PATCH 5/5] build: regenerate window.ui from blueprint --- data/ui/window.ui | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/data/ui/window.ui b/data/ui/window.ui index e9cd9cc..8ecec84 100644 --- a/data/ui/window.ui +++ b/data/ui/window.ui @@ -14,8 +14,8 @@ corresponding .blp file and regenerate this file with blueprint-compiler. false - false false + false 1 @@ -146,6 +146,7 @@ corresponding .blp file and regenerate this file with blueprint-compiler. 1 + 320 @@ -155,11 +156,48 @@ corresponding .blp file and regenerate this file with blueprint-compiler. win.toggle-sidebar + + + false + + + button + + + view-refresh-symbolic + Refresh + win.reload + + + + + + + spinner + + + true + 16 + 16 + + + + + + FeedTheMonkey + + + open-menu-symbolic + true + primary_menu + false + + view-more-symbolic