diff --git a/client/src/launcher/tests/ui_runtime.rs b/client/src/launcher/tests/ui_runtime.rs index c6b8ac0..a65de02 100644 --- a/client/src/launcher/tests/ui_runtime.rs +++ b/client/src/launcher/tests/ui_runtime.rs @@ -227,6 +227,97 @@ fn populated_launcher_runtime_widgets_stay_compact() { ); } +#[gtk::test] +#[serial] +fn launcher_shell_installs_native_window_chrome() { + if gtk::gdk::Display::default().is_none() { + return; + } + + let app = gtk::Application::builder() + .application_id("dev.lesavka.test-window-chrome") + .build(); + let _ = app.register(None::<>k::gio::Cancellable>); + + let view = build_launcher_view( + &app, + "http://127.0.0.1:50051", + &DeviceCatalog::default(), + &LauncherState::new(), + ); + present_and_settle(&view.window); + + let titlebar = view + .window + .titlebar() + .expect("launcher titlebar") + .downcast::() + .expect("launcher header bar"); + assert!(view.window.is_decorated()); + assert!(titlebar.shows_title_buttons()); +} + +#[gtk::test] +#[serial] +fn diagnostics_and_log_popouts_install_native_window_chrome() { + if gtk::gdk::Display::default().is_none() { + return; + } + + let app = gtk::Application::builder() + .application_id("dev.lesavka.test-popout-chrome") + .build(); + let _ = app.register(None::<>k::gio::Cancellable>); + + let diagnostics_handle = Rc::new(RefCell::new(None::)); + let diagnostics_label = Rc::new(RefCell::new(None::)); + let diagnostics_scroll = Rc::new(RefCell::new(None::)); + let rendered_text = Rc::new(RefCell::new("diagnostics".to_string())); + + open_diagnostics_popout( + &app, + &diagnostics_handle, + &diagnostics_label, + &diagnostics_scroll, + &rendered_text, + ); + + let diagnostics_window = diagnostics_handle + .borrow() + .as_ref() + .expect("diagnostics window") + .clone(); + let diagnostics_titlebar = diagnostics_window + .titlebar() + .expect("diagnostics titlebar") + .downcast::() + .expect("diagnostics header bar"); + assert!(diagnostics_window.is_decorated()); + assert!(diagnostics_titlebar.shows_title_buttons()); + + let log_handle = Rc::new(RefCell::new(None::)); + let log_scroll = Rc::new(RefCell::new(None::)); + let log_buffer = gtk::TextBuffer::new(None); + log_buffer.set_text("session log"); + + open_session_log_popout(&app, &log_handle, &log_buffer); + + let log_window = log_handle.borrow().as_ref().expect("log window").clone(); + let log_titlebar = log_window + .titlebar() + .expect("log titlebar") + .downcast::() + .expect("log header bar"); + assert!(log_window.is_decorated()); + assert!(log_titlebar.shows_title_buttons()); + + diagnostics_window.close(); + log_window.close(); + diagnostics_label.borrow_mut().take(); + diagnostics_scroll.borrow_mut().take(); + log_scroll.borrow_mut().take(); +} + #[gtk::test] #[serial] fn breakout_size_changes_resize_the_open_popout_window() { diff --git a/client/src/launcher/ui_components/build_shell.rs b/client/src/launcher/ui_components/build_shell.rs index f81b3a2..8a42a93 100644 --- a/client/src/launcher/ui_components/build_shell.rs +++ b/client/src/launcher/ui_components/build_shell.rs @@ -8,6 +8,7 @@ .build(); install_css(&window); install_window_icon(&window); + install_window_chrome(&window, "Lesavka"); let root = gtk::Box::new(gtk::Orientation::Vertical, 6); root.add_css_class("launcher-root"); diff --git a/client/src/launcher/ui_components/style.rs b/client/src/launcher/ui_components/style.rs index 684cdd9..c215f2e 100644 --- a/client/src/launcher/ui_components/style.rs +++ b/client/src/launcher/ui_components/style.rs @@ -203,3 +203,14 @@ pub fn install_window_icon(window: &impl IsA) { gtk::Window::set_default_icon_name(LESAVKA_ICON_NAME); window.as_ref().set_icon_name(Some(LESAVKA_ICON_NAME)); } + +pub fn install_window_chrome(window: >k::ApplicationWindow, title: &str) { + window.set_decorated(true); + + let header = gtk::HeaderBar::builder().show_title_buttons(true).build(); + let title_label = gtk::Label::new(Some(title)); + title_label.set_ellipsize(pango::EllipsizeMode::End); + header.set_title_widget(Some(&title_label)); + + window.set_titlebar(Some(&header)); +} diff --git a/client/src/launcher/ui_runtime/display_popouts.rs b/client/src/launcher/ui_runtime/display_popouts.rs index 22807f6..8548b5a 100644 --- a/client/src/launcher/ui_runtime/display_popouts.rs +++ b/client/src/launcher/ui_runtime/display_popouts.rs @@ -30,18 +30,16 @@ pub fn open_popout_window( state.breakout_display_size(), ) }; + let title = format!("Lesavka {}", widgets.display_panes[monitor_id].title); let window = gtk::ApplicationWindow::builder() .application(app) - .title(format!( - "Lesavka {}", - widgets.display_panes[monitor_id].title - )) + .title(&title) .default_width(breakout_size.width) .default_height(breakout_size.height) .build(); super::ui_components::install_css(&window); super::ui_components::install_window_icon(&window); - window.set_decorated(false); + super::ui_components::install_window_chrome(&window, &title); window.set_resizable(false); let picture = gtk::Picture::new(); diff --git a/client/src/launcher/ui_runtime/report_popouts.rs b/client/src/launcher/ui_runtime/report_popouts.rs index bccfac5..681b86b 100644 --- a/client/src/launcher/ui_runtime/report_popouts.rs +++ b/client/src/launcher/ui_runtime/report_popouts.rs @@ -34,6 +34,7 @@ pub fn open_diagnostics_popout( .build(); super::ui_components::install_css(&window); super::ui_components::install_window_icon(&window); + super::ui_components::install_window_chrome(&window, "Lesavka Diagnostics"); let root = gtk::Box::new(gtk::Orientation::Vertical, 10); root.set_margin_start(14); @@ -117,6 +118,7 @@ fn open_text_buffer_popout( .build(); super::ui_components::install_css(&window); super::ui_components::install_window_icon(&window); + super::ui_components::install_window_chrome(&window, title); let root = gtk::Box::new(gtk::Orientation::Vertical, 10); root.set_margin_start(14);