Skip to content

Commit

Permalink
live-preview(macOs): Add a Window menu with keep on top item
Browse files Browse the repository at this point in the history
Fixes #7371
  • Loading branch information
tronical committed Jan 15, 2025
1 parent 2724d60 commit b8ffca0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
27 changes: 24 additions & 3 deletions tools/lsp/preview/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,19 @@ fn close_ui_impl(preview_state: &mut PreviewState) {
}
}

#[cfg(target_vendor = "apple")]
fn toggle_always_on_top() {
i_slint_core::api::invoke_from_event_loop(move || {
super::PREVIEW_STATE.with(move |preview_state| {
let preview_state = preview_state.borrow_mut();
let Some(ui) = preview_state.ui.as_ref() else { return };
let api = ui.global::<crate::preview::ui::Api>();
api.set_always_on_top(!api.get_always_on_top());
});
})
.unwrap(); // TODO: Handle Error
}

static SERVER_NOTIFIER: Mutex<Option<ServerNotifier>> = Mutex::new(None);

/// Give the UI thread a handle to send message back to the LSP thread
Expand Down Expand Up @@ -270,9 +283,10 @@ pub fn send_message_to_lsp(message: PreviewToLspMessage) {
// be kept alive for the duration of the event loop, as otherwise muda crashes.
#[cfg(target_vendor = "apple")]
fn init_apple_platform(
) -> Result<(muda::MenuItem, muda::MenuItem), i_slint_core::api::PlatformError> {
) -> Result<(muda::MenuItem, muda::MenuItem, muda::CheckMenuItem), i_slint_core::api::PlatformError>
{
use i_slint_backend_winit::winit;
use muda::{accelerator, Menu, MenuItem, PredefinedMenuItem, Submenu};
use muda::{accelerator, CheckMenuItem, Menu, MenuItem, PredefinedMenuItem, Submenu};
use winit::platform::macos::EventLoopBuilderExtMacOS;
let mut builder = winit::event_loop::EventLoop::with_user_event();
builder.with_default_menu(false);
Expand Down Expand Up @@ -301,12 +315,15 @@ fn init_apple_platform(
accelerator::Code::KeyR,
)),
);
let keep_on_top_menu_item = CheckMenuItem::new(format!("Keep on Top"), true, false, None);

let menu_bar = Menu::new();
menu_bar.init_for_nsapp();
let app_m = Submenu::new("App", true);
let window_m = Submenu::new("&Window", true);
menu_bar
.append(&app_m)
.and_then(|_| menu_bar.append(&window_m))
.and_then(|_| {
app_m.append_items(&[
&PredefinedMenuItem::services(None),
Expand All @@ -318,20 +335,24 @@ fn init_apple_platform(
&close_app_menu_item,
])
})
.and_then(|_| window_m.append_items(&[&keep_on_top_menu_item]))
.map_err(|menu_bar_err| {
i_slint_core::api::PlatformError::Other(menu_bar_err.to_string())
})?;

let close_id = close_app_menu_item.id().clone();
let reload_id = reload_menu_item.id().clone();
let keep_on_top_id = keep_on_top_menu_item.id().clone();

muda::MenuEvent::set_event_handler(Some(move |menu_event: muda::MenuEvent| {
if menu_event.id == close_id {
close_ui();
} else if menu_event.id == reload_id {
super::reload_preview();
} else if menu_event.id == keep_on_top_id {
toggle_always_on_top();
}
}));

Ok((close_app_menu_item, reload_menu_item))
Ok((close_app_menu_item, reload_menu_item, keep_on_top_menu_item))
}
1 change: 1 addition & 0 deletions tools/lsp/ui/api.slint
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export global Api {
in property <bool> show-preview-ui: true;
// std-widgets are used (=> show style dropdown)
in-out property <bool> uses-widgets;
in-out property <bool> always-on-top;

// ## Component Data for ComponentList:
// All the components
Expand Down
1 change: 1 addition & 0 deletions tools/lsp/ui/main.slint
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export component PreviewUi inherits Window {

title: "Slint Live-Preview";
icon: @image-url("assets/slint-logo-small-light.png");
always-on-top <=> Api.always-on-top;

VerticalLayout {
if !Api.show-preview-ui: no-ui-drawing-rect := Rectangle {
Expand Down

0 comments on commit b8ffca0

Please sign in to comment.