This commit is contained in:
Laurent Stéphenne 2025-08-26 19:08:31 +02:00 committed by GitHub
commit 73ebbc7ee1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 36 additions and 6 deletions

View file

@ -32,6 +32,7 @@ use util::{ResultExt, debug_panic};
#[cfg(any(feature = "inspector", debug_assertions))]
use crate::InspectorElementRegistry;
use crate::colors::{Colors, GlobalColors};
use crate::{
Action, ActionBuildError, ActionRegistry, Any, AnyView, AnyWindowHandle, AppContext, Asset,
AssetSource, BackgroundExecutor, Bounds, ClipboardItem, CursorStyle, DispatchPhase, DisplayId,
@ -40,9 +41,7 @@ use crate::{
PlatformDisplay, PlatformKeyboardLayout, Point, PromptBuilder, PromptButton, PromptHandle,
PromptLevel, Render, RenderImage, RenderablePromptHandle, Reservation, ScreenCaptureSource,
SubscriberSet, Subscription, SvgRenderer, Task, TextSystem, Window, WindowAppearance,
WindowHandle, WindowId, WindowInvalidator,
colors::{Colors, GlobalColors},
current_platform, hash, init_app_menus,
WindowHandle, WindowId, WindowInvalidator, current_platform, hash, init_app_menus,
};
mod async_context;
@ -168,6 +167,16 @@ impl Application {
self
}
/// Sets the behaviour of the event loop when all windows are closed.
pub fn keep_running(self, keep_running: bool) -> Self {
let mut context_lock = self.0.borrow_mut();
context_lock
.platform
.set_quit_when_last_window_closes(!keep_running);
drop(context_lock);
self
}
/// Start the application. The provided callback will be called once the
/// app is fully launched.
pub fn run<F>(self, on_finish_launching: F)

View file

@ -232,6 +232,7 @@ pub(crate) trait Platform: 'static {
fn on_quit(&self, callback: Box<dyn FnMut()>);
fn on_reopen(&self, callback: Box<dyn FnMut()>);
fn on_keyboard_layout_change(&self, callback: Box<dyn FnMut()>);
fn set_quit_when_last_window_closes(&self, should_quit: bool);
fn set_menus(&self, menus: Vec<Menu>, keymap: &Keymap);
fn get_menus(&self) -> Option<Vec<OwnedMenu>> {

View file

@ -92,6 +92,7 @@ pub(crate) struct LinuxCommon {
pub(crate) text_system: Arc<dyn PlatformTextSystem>,
pub(crate) appearance: WindowAppearance,
pub(crate) auto_hide_scrollbars: bool,
pub(crate) quit_when_last_window_closes: bool,
pub(crate) callbacks: PlatformHandlers,
pub(crate) signal: LoopSignal,
pub(crate) menus: Vec<OwnedMenu>,
@ -118,6 +119,7 @@ impl LinuxCommon {
text_system,
appearance: WindowAppearance::Light,
auto_hide_scrollbars: false,
quit_when_last_window_closes: true,
callbacks,
signal,
menus: Vec::new(),
@ -148,6 +150,10 @@ impl<P: LinuxClient + 'static> Platform for P {
self.with_common(|common| common.callbacks.keyboard_layout_change = Some(callback));
}
fn set_quit_when_last_window_closes(&self, should_quit: bool) {
self.with_common(|common| common.quit_when_last_window_closes = should_quit);
}
fn run(&self, on_finish_launching: Box<dyn FnOnce()>) {
on_finish_launching();

View file

@ -383,7 +383,8 @@ impl WaylandClientStatePtr {
{
state.keyboard_focused_window = Some(window);
}
if state.windows.is_empty() {
if state.common.quit_when_last_window_closes && state.windows.is_empty() {
state.common.signal.stop();
}
}

View file

@ -247,7 +247,7 @@ impl X11ClientStatePtr {
}
state.cursor_styles.remove(&x_window);
if state.windows.is_empty() {
if state.common.quit_when_last_window_closes && state.windows.is_empty() {
state.common.signal.stop();
}
}

View file

@ -162,6 +162,7 @@ pub(crate) struct MacPlatformState {
metadata_pasteboard_type: id,
reopen: Option<Box<dyn FnMut()>>,
on_keyboard_layout_change: Option<Box<dyn FnMut()>>,
quit_when_last_window_closes: bool,
quit: Option<Box<dyn FnMut()>>,
menu_command: Option<Box<dyn FnMut(&dyn Action)>>,
validate_menu_command: Option<Box<dyn FnMut(&dyn Action) -> bool>>,
@ -208,6 +209,7 @@ impl MacPlatform {
finish_launching: None,
dock_menu: None,
on_keyboard_layout_change: None,
quit_when_last_window_closes: false,
menus: None,
}))
}
@ -866,6 +868,11 @@ impl Platform for MacPlatform {
self.0.lock().on_keyboard_layout_change = Some(callback);
}
fn set_quit_when_last_window_closes(&self, should_quit: bool) {
self.0.lock().quit_when_last_window_closes = should_quit;
unimplemented!("quit_when_last_window_closes is not implemented on macOS yet");
}
fn on_app_menu_action(&self, callback: Box<dyn FnMut(&dyn Action)>) {
self.0.lock().menu_command = Some(callback);
}

View file

@ -52,6 +52,7 @@ pub(crate) struct WindowsPlatformState {
callbacks: PlatformCallbacks,
menus: Vec<OwnedMenu>,
jump_list: JumpList,
quit_when_last_window_closes: bool,
// NOTE: standard cursor handles don't need to close.
pub(crate) current_cursor: Option<HCURSOR>,
}
@ -78,6 +79,7 @@ impl WindowsPlatformState {
jump_list,
current_cursor,
menus: Vec::new(),
quit_when_last_window_closes: true,
}
}
}
@ -161,7 +163,7 @@ impl WindowsPlatform {
.unwrap();
lock.remove(index);
lock.is_empty()
self.state.borrow().quit_when_last_window_closes && lock.is_empty()
}
#[inline]
@ -355,6 +357,10 @@ impl Platform for WindowsPlatform {
self.state.borrow_mut().callbacks.keyboard_layout_change = Some(callback);
}
fn set_quit_when_last_window_closes(&self, should_quit: bool) {
self.state.borrow_mut().quit_when_last_window_closes = should_quit;
}
fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>) {
on_finish_launching();
self.begin_vsync_thread();