aboutsummaryrefslogtreecommitdiff
path: root/src/ui.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-21 21:27:20 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-21 21:27:20 +0300
commit1f2f939862a399e8655d9ce99ab644faf6a32d17 (patch)
treeaf2046db96c194462e9d47f3b8d651cf4efb35b3 /src/ui.rs
parent866aaf740e10fcfce169aaf81380ea0257fbe272 (diff)
fix: keep notifications below floating overlays
refs #228
Diffstat (limited to 'src/ui.rs')
-rw-r--r--src/ui.rs47
1 files changed, 46 insertions, 1 deletions
diff --git a/src/ui.rs b/src/ui.rs
index 7e5187b0..9082ce00 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -355,6 +355,9 @@ pub fn render_with_runtime_registry(
}
render_panes(app, terminal_runtimes, frame, terminal_area);
+ // Ambient notifications sit above panes, but below interactive overlays.
+ render_notifications(app, frame, terminal_area);
+
match app.mode {
Mode::Onboarding => render_onboarding_overlay(app, frame, frame.area()),
Mode::ReleaseNotes => render_release_notes_overlay(app, frame, frame.area()),
@@ -377,8 +380,9 @@ pub fn render_with_runtime_registry(
Mode::KeybindHelp => render_keybind_help_overlay(app, frame),
Mode::Terminal => {}
}
+}
- // Notifications (rendered on top of everything)
+fn render_notifications(app: &AppState, frame: &mut Frame, terminal_area: Rect) {
let has_config_diagnostic = app.config_diagnostic.is_some();
if let Some(message) = &app.config_diagnostic {
render_config_diagnostic(frame, terminal_area, message, &app.palette);
@@ -504,6 +508,47 @@ mod tests {
}
#[test]
+ fn product_announcement_renders_above_config_diagnostic() {
+ let mut app = crate::app::state::AppState::test_new();
+ app.workspaces = vec![Workspace::test_new("one")];
+ app.active = Some(0);
+ app.selected = 0;
+ app.mode = Mode::ProductAnnouncement;
+ app.product_announcement = Some(crate::app::state::ProductAnnouncementState {
+ version: "0.6.0".into(),
+ id: "keybinding-v2".into(),
+ title: "Keybinding syntax changed".into(),
+ body: "### Update\n- Body".into(),
+ scroll: 0,
+ preview: false,
+ });
+ app.config_diagnostic = Some(
+ "unsafe direct keybinding: keys.new_workspace = \"n\"\nunsafe direct keybinding: keys.new_tab = \"c\""
+ .into(),
+ );
+
+ let area = Rect::new(0, 0, 44, 20);
+ compute_view(&mut app, area);
+
+ let backend = TestBackend::new(area.width, area.height);
+ let mut terminal = Terminal::new(backend).unwrap();
+ terminal.draw(|frame| render(&app, frame)).unwrap();
+ let buffer = terminal.backend().buffer();
+
+ let popup = centered_popup_rect(
+ area,
+ PRODUCT_ANNOUNCEMENT_MODAL_SIZE.0,
+ PRODUCT_ANNOUNCEMENT_MODAL_SIZE.1,
+ )
+ .expect("announcement popup");
+ let title_row = popup.y + 1;
+ let row = buffer_row_text(buffer, Rect::new(0, title_row, area.width, 1), title_row);
+
+ assert!(row.contains("Keybinding syntax changed"));
+ assert!(!row.contains("config warning"));
+ }
+
+ #[test]
fn compute_view_clamps_sidebar_width_to_configured_max() {
let mut app = crate::app::state::AppState::test_new();
app.workspaces = vec![Workspace::test_new("one")];