tweaks to the LastWindowClose to make it more imperative
This commit is contained in:
1 parent
9573af115a
commit
ff762cec84
11 files changed
+74
-214
No files matched your search
Generated
+4
-25
@@ -3965,7 +3965,7 @@ dependencies = [
|
|||||||
"jni",
|
"jni",
|
||||||
"lazy-js-bundle",
|
"lazy-js-bundle",
|
||||||
"libc",
|
"libc",
|
||||||
"muda 0.17.0",
|
"muda",
|
||||||
"ndk",
|
"ndk",
|
||||||
"ndk-context",
|
"ndk-context",
|
||||||
"ndk-sys 0.6.0+11769913",
|
"ndk-sys 0.6.0+11769913",
|
||||||
@@ -8985,27 +8985,6 @@ dependencies = [
|
|||||||
"nasm-rs",
|
"nasm-rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "muda"
|
|
||||||
version = "0.16.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4de14a9b5d569ca68d7c891d613b390cf5ab4f851c77aaa2f9e435555d3d9492"
|
|
||||||
dependencies = [
|
|
||||||
"crossbeam-channel",
|
|
||||||
"dpi",
|
|
||||||
"gtk",
|
|
||||||
"keyboard-types",
|
|
||||||
"libxdo",
|
|
||||||
"objc2 0.6.1",
|
|
||||||
"objc2-app-kit 0.3.1",
|
|
||||||
"objc2-core-foundation",
|
|
||||||
"objc2-foundation 0.3.1",
|
|
||||||
"once_cell",
|
|
||||||
"png",
|
|
||||||
"thiserror 2.0.12",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "muda"
|
name = "muda"
|
||||||
version = "0.17.0"
|
version = "0.17.0"
|
||||||
@@ -15177,14 +15156,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tray-icon"
|
name = "tray-icon"
|
||||||
version = "0.20.1"
|
version = "0.21.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f7eee98ec5c90daf179d55c20a49d8c0d043054ce7c26336c09a24d31f14fa0"
|
checksum = "2da75ec677957aa21f6e0b361df0daab972f13a5bee3606de0638fd4ee1c666a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"dirs 6.0.0",
|
"dirs 6.0.0",
|
||||||
"libappindicator",
|
"libappindicator",
|
||||||
"muda 0.16.1",
|
"muda",
|
||||||
"objc2 0.6.1",
|
"objc2 0.6.1",
|
||||||
"objc2-app-kit 0.3.1",
|
"objc2-app-kit 0.3.1",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
|
|||||||
+1
-1
@@ -325,7 +325,7 @@ cocoa = "0.26"
|
|||||||
core-foundation = "0.10.1"
|
core-foundation = "0.10.1"
|
||||||
objc = { version = "0.2.7", features = ["exception"] }
|
objc = { version = "0.2.7", features = ["exception"] }
|
||||||
objc_id = "0.1.1"
|
objc_id = "0.1.1"
|
||||||
tray-icon = "0.20.0"
|
tray-icon = "0.21.0"
|
||||||
open = "5.1.2"
|
open = "5.1.2"
|
||||||
|
|
||||||
# web
|
# web
|
||||||
|
|||||||
+2
-10
@@ -5,22 +5,14 @@
|
|||||||
//! own context, root elements, etc.
|
//! own context, root elements, etc.
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus::{desktop::Config, desktop::DefaultWindowCloseBehaviour};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::LaunchBuilder::desktop()
|
dioxus::launch(app);
|
||||||
// We can choose the close behavior of the last window to hide. See DefaultWindowCloseBehaviour for more options.
|
|
||||||
.with_cfg(
|
|
||||||
Config::new()
|
|
||||||
.with_default_window_close_behaviour(DefaultWindowCloseBehaviour::LastWindowHides),
|
|
||||||
)
|
|
||||||
.launch(app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
let onclick = move |_| {
|
let onclick = move |_| {
|
||||||
let dom = VirtualDom::new(popup);
|
dioxus::desktop::window().new_window(VirtualDom::new(popup), Default::default());
|
||||||
dioxus::desktop::window().new_window(dom, Default::default());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
|
|||||||
@@ -3,31 +3,37 @@
|
|||||||
//! This example shows how to implement a simple multiwindow application and tray icon using dioxus.
|
//! This example shows how to implement a simple multiwindow application and tray icon using dioxus.
|
||||||
//! This works by spawning a new window when the user clicks a button. We have to build a new virtualdom which has its
|
//! This works by spawning a new window when the user clicks a button. We have to build a new virtualdom which has its
|
||||||
//! own context, root elements, etc.
|
//! own context, root elements, etc.
|
||||||
|
//!
|
||||||
|
//! This is useful for apps that incorporate settings panels or persistent windows like Raycast.
|
||||||
|
|
||||||
use dioxus::desktop::{
|
use dioxus::desktop::{
|
||||||
trayicon::{default_tray_icon, init_tray_icon},
|
trayicon::{default_tray_icon, init_tray_icon},
|
||||||
Config, WindowCloseBehaviour,
|
window, WindowCloseBehaviour,
|
||||||
};
|
};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::LaunchBuilder::desktop()
|
dioxus::launch(app);
|
||||||
// We can choose the close behavior of this window to hide. See WindowCloseBehaviour for more options.
|
|
||||||
.with_cfg(Config::new().with_window_close_behaviour(WindowCloseBehaviour::WindowHides))
|
|
||||||
.launch(app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
// async should not be needed, check if issue 3542 has been resolved
|
use_hook(|| {
|
||||||
let onclick = move |_| async {
|
// Set the close behavior for the main window
|
||||||
let dom = VirtualDom::new(popup);
|
// This will hide the window instead of closing it when the user clicks the close button
|
||||||
dioxus::desktop::window().new_window(dom, Default::default());
|
window().set_close_behavior(WindowCloseBehaviour::WindowHides);
|
||||||
};
|
|
||||||
|
|
||||||
init_tray_icon(default_tray_icon(), None);
|
// Initialize the tray icon with a default icon and no menu
|
||||||
|
// This will provide the tray into context for the application
|
||||||
|
init_tray_icon(default_tray_icon(), None)
|
||||||
|
});
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
button { onclick, "New Window" }
|
button {
|
||||||
|
onclick: move |_| {
|
||||||
|
window().new_window(VirtualDom::new(popup), Default::default());
|
||||||
|
},
|
||||||
|
"New Window"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-107
@@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::{Config, DefaultWindowCloseBehaviour, WindowCloseBehaviour},
|
config::{Config, WindowCloseBehaviour},
|
||||||
edits::EditWebsocket,
|
edits::EditWebsocket,
|
||||||
event_handlers::WindowEventHandlers,
|
event_handlers::WindowEventHandlers,
|
||||||
file_upload::{DesktopFileUploadForm, FileDialogRequest, NativeFileEngine},
|
file_upload::{DesktopFileUploadForm, FileDialogRequest, NativeFileEngine},
|
||||||
@@ -23,7 +23,7 @@ use tao::{
|
|||||||
dpi::PhysicalSize,
|
dpi::PhysicalSize,
|
||||||
event::Event,
|
event::Event,
|
||||||
event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget},
|
event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget},
|
||||||
window::{Window, WindowId},
|
window::WindowId,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The single top-level object that manages all the running windows, assets, shortcuts, etc
|
/// The single top-level object that manages all the running windows, assets, shortcuts, etc
|
||||||
@@ -36,7 +36,7 @@ pub(crate) struct App {
|
|||||||
// Stuff we need mutable access to
|
// Stuff we need mutable access to
|
||||||
pub(crate) control_flow: ControlFlow,
|
pub(crate) control_flow: ControlFlow,
|
||||||
pub(crate) is_visible_before_start: bool,
|
pub(crate) is_visible_before_start: bool,
|
||||||
pub(crate) default_window_close_behavior: DefaultWindowCloseBehaviour,
|
pub(crate) exit_on_last_window_close: bool,
|
||||||
pub(crate) webviews: HashMap<WindowId, WebviewInstance>,
|
pub(crate) webviews: HashMap<WindowId, WebviewInstance>,
|
||||||
pub(crate) float_all: bool,
|
pub(crate) float_all: bool,
|
||||||
pub(crate) show_devtools: bool,
|
pub(crate) show_devtools: bool,
|
||||||
@@ -65,7 +65,7 @@ impl App {
|
|||||||
.unwrap_or_else(|| EventLoopBuilder::<UserWindowEvent>::with_user_event().build());
|
.unwrap_or_else(|| EventLoopBuilder::<UserWindowEvent>::with_user_event().build());
|
||||||
|
|
||||||
let app = Self {
|
let app = Self {
|
||||||
default_window_close_behavior: cfg.default_window_close_behaviour,
|
exit_on_last_window_close: cfg.exit_on_last_window_close,
|
||||||
is_visible_before_start: true,
|
is_visible_before_start: true,
|
||||||
webviews: HashMap::new(),
|
webviews: HashMap::new(),
|
||||||
control_flow: ControlFlow::Wait,
|
control_flow: ControlFlow::Wait,
|
||||||
@@ -188,89 +188,37 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_window_close_behaviour(
|
|
||||||
&mut self,
|
|
||||||
id: WindowId,
|
|
||||||
behaviour: Option<WindowCloseBehaviour>,
|
|
||||||
) {
|
|
||||||
if let Some(webview) = self.webviews.get_mut(&id) {
|
|
||||||
webview.close_behaviour = behaviour
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_close_requested(&mut self, id: WindowId) {
|
pub fn handle_close_requested(&mut self, id: WindowId) {
|
||||||
use DefaultWindowCloseBehaviour::*;
|
let Some(window) = self.webviews.get(&id) else {
|
||||||
use WindowCloseBehaviour::*;
|
// If the window is not found, we can just return
|
||||||
|
|
||||||
let mut remove = false;
|
|
||||||
|
|
||||||
if let Some(webview) = self.webviews.get(&id) {
|
|
||||||
if let Some(close_behaviour) = &webview.close_behaviour {
|
|
||||||
match close_behaviour {
|
|
||||||
WindowExitsApp => {
|
|
||||||
self.control_flow = ControlFlow::Exit;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
WindowHides => {
|
|
||||||
hide_window(&webview.desktop_context.window);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
WindowCloses => {
|
|
||||||
remove = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// needed in case of `default_window_close_behavior WindowsHides | LastWindowHides` since they may not remove a window on `WindowCloses`
|
|
||||||
if remove {
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
self.persist_window_state();
|
|
||||||
|
|
||||||
self.webviews.remove(&id);
|
|
||||||
if matches!(self.default_window_close_behavior, LastWindowExitsApp)
|
|
||||||
&& self.webviews.is_empty()
|
|
||||||
{
|
|
||||||
self.control_flow = ControlFlow::Exit
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
};
|
||||||
|
|
||||||
match self.default_window_close_behavior {
|
match window.desktop_context.close_behaviour.get() {
|
||||||
LastWindowExitsApp => {
|
// If the window is just set to hide when closed, we can just hide it
|
||||||
|
WindowCloseBehaviour::WindowHides => {
|
||||||
|
window.desktop_context.window.set_visible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the window is set to close, we can remove it from the list of webviews
|
||||||
|
// If the app is set to exit when the last window closes, we should also exit the app
|
||||||
|
WindowCloseBehaviour::WindowCloses => {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
self.persist_window_state();
|
self.persist_window_state();
|
||||||
|
|
||||||
self.webviews.remove(&id);
|
self.webviews.remove(&id);
|
||||||
if self.webviews.is_empty() {
|
|
||||||
|
if self.exit_on_last_window_close && self.webviews.is_empty() {
|
||||||
self.control_flow = ControlFlow::Exit
|
self.control_flow = ControlFlow::Exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
LastWindowHides if self.webviews.len() > 1 => {
|
|
||||||
self.webviews.remove(&id);
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowsHides | LastWindowHides => {
|
|
||||||
if let Some(webview) = self.webviews.get(&id) {
|
|
||||||
hide_window(&webview.desktop_context.window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowsCloses => {
|
|
||||||
self.webviews.remove(&id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_destroyed(&mut self, id: WindowId) {
|
pub fn window_destroyed(&mut self, id: WindowId) {
|
||||||
self.webviews.remove(&id);
|
self.webviews.remove(&id);
|
||||||
|
|
||||||
if matches!(
|
if self.exit_on_last_window_close && self.webviews.is_empty() {
|
||||||
self.default_window_close_behavior,
|
|
||||||
DefaultWindowCloseBehaviour::LastWindowExitsApp
|
|
||||||
) && self.webviews.is_empty()
|
|
||||||
{
|
|
||||||
self.control_flow = ControlFlow::Exit
|
self.control_flow = ControlFlow::Exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -723,41 +671,6 @@ struct PreservedWindowState {
|
|||||||
url: Option<String>,
|
url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hides a window.
|
|
||||||
///
|
|
||||||
/// On macOS, if we use `set_visibility(false)` on the window, it will hide the window but not show
|
|
||||||
/// it again when the user switches back to the app. `NSApplication::hide:` has the correct behaviour,
|
|
||||||
/// so we need to special case it.
|
|
||||||
#[allow(unused)]
|
|
||||||
fn hide_window(window: &Window) {
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
{
|
|
||||||
use tao::platform::windows::WindowExtWindows;
|
|
||||||
window.set_visible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
{
|
|
||||||
use tao::platform::unix::WindowExtUnix;
|
|
||||||
window.set_visible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
{
|
|
||||||
// window.set_visible(false); has the wrong behaviour on macOS
|
|
||||||
// It will hide the window but not show it again when the user switches
|
|
||||||
// back to the app. `NSApplication::hide:` has the correct behaviour
|
|
||||||
use objc::runtime::Object;
|
|
||||||
use objc::{msg_send, sel, sel_impl};
|
|
||||||
#[allow(unexpected_cfgs)]
|
|
||||||
objc::rc::autoreleasepool(|| unsafe {
|
|
||||||
let app: *mut Object = msg_send![objc::class!(NSApplication), sharedApplication];
|
|
||||||
let nil = std::ptr::null_mut::<Object>();
|
|
||||||
let _: () = msg_send![app, hide: nil];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the location of a tempfile with our window state in it such that we can restore it later
|
/// Return the location of a tempfile with our window state in it such that we can restore it later
|
||||||
fn restore_file() -> std::path::PathBuf {
|
fn restore_file() -> std::path::PathBuf {
|
||||||
let dir = dioxus_cli_config::session_cache_dir().unwrap_or_else(std::env::temp_dir);
|
let dir = dioxus_cli_config::session_cache_dir().unwrap_or_else(std::env::temp_dir);
|
||||||
|
|||||||
@@ -17,28 +17,13 @@ type CustomEventHandler = Box<
|
|||||||
),
|
),
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// The closing behaviour of the application when the last window is closed, you can overwrite this behaviour for specific window with WindowCloseBehaviour.
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
||||||
#[non_exhaustive]
|
|
||||||
pub enum DefaultWindowCloseBehaviour {
|
|
||||||
/// Default behaviour, closing the last window will exit the app, others will close,
|
|
||||||
LastWindowExitsApp,
|
|
||||||
/// Closing the last window will hide it, others will close
|
|
||||||
LastWindowHides,
|
|
||||||
/// Every window will hide
|
|
||||||
WindowsHides,
|
|
||||||
/// Every window will close
|
|
||||||
WindowsCloses,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The closing behaviour of specific application window.
|
/// The closing behaviour of specific application window.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum WindowCloseBehaviour {
|
pub enum WindowCloseBehaviour {
|
||||||
/// Closing the window will exit the app
|
/// Window will hide instead of closing
|
||||||
WindowExitsApp,
|
|
||||||
/// Window will hide
|
|
||||||
WindowHides,
|
WindowHides,
|
||||||
|
|
||||||
/// Window will close
|
/// Window will close
|
||||||
WindowCloses,
|
WindowCloses,
|
||||||
}
|
}
|
||||||
@@ -75,8 +60,8 @@ pub struct Config {
|
|||||||
pub(crate) custom_index: Option<String>,
|
pub(crate) custom_index: Option<String>,
|
||||||
pub(crate) root_name: String,
|
pub(crate) root_name: String,
|
||||||
pub(crate) background_color: Option<(u8, u8, u8, u8)>,
|
pub(crate) background_color: Option<(u8, u8, u8, u8)>,
|
||||||
pub(crate) default_window_close_behaviour: DefaultWindowCloseBehaviour,
|
pub(crate) exit_on_last_window_close: bool,
|
||||||
pub(crate) window_close_behaviour: Option<WindowCloseBehaviour>,
|
pub(crate) window_close_behavior: WindowCloseBehaviour,
|
||||||
pub(crate) custom_event_handler: Option<CustomEventHandler>,
|
pub(crate) custom_event_handler: Option<CustomEventHandler>,
|
||||||
pub(crate) disable_file_drop_handler: bool,
|
pub(crate) disable_file_drop_handler: bool,
|
||||||
}
|
}
|
||||||
@@ -122,8 +107,8 @@ impl Config {
|
|||||||
custom_index: None,
|
custom_index: None,
|
||||||
root_name: "main".to_string(),
|
root_name: "main".to_string(),
|
||||||
background_color: None,
|
background_color: None,
|
||||||
default_window_close_behaviour: DefaultWindowCloseBehaviour::LastWindowExitsApp,
|
exit_on_last_window_close: true,
|
||||||
window_close_behaviour: None,
|
window_close_behavior: WindowCloseBehaviour::WindowCloses,
|
||||||
custom_event_handler: None,
|
custom_event_handler: None,
|
||||||
disable_file_drop_handler: false,
|
disable_file_drop_handler: false,
|
||||||
}
|
}
|
||||||
@@ -185,18 +170,19 @@ impl Config {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the behaviour of the application when the last window is closed.
|
/// When the last window is closed, the application will exit.
|
||||||
pub fn with_default_window_close_behaviour(
|
///
|
||||||
mut self,
|
/// This is the default behaviour.
|
||||||
behaviour: DefaultWindowCloseBehaviour,
|
///
|
||||||
) -> Self {
|
/// If the last window is hidden, the application will not exit.
|
||||||
self.default_window_close_behaviour = behaviour;
|
pub fn with_exits_when_last_window_closes(mut self, exit: bool) -> Self {
|
||||||
|
self.exit_on_last_window_close = exit;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the behaviour of the application when the last window is closed.
|
/// Sets the behaviour of the application when the last window is closed.
|
||||||
pub fn with_window_close_behaviour(mut self, behaviour: WindowCloseBehaviour) -> Self {
|
pub fn with_close_behaviour(mut self, behaviour: WindowCloseBehaviour) -> Self {
|
||||||
self.window_close_behaviour = Some(behaviour);
|
self.window_close_behavior = behaviour;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use dioxus_core::{prelude::Callback, VirtualDom};
|
use dioxus_core::{prelude::Callback, VirtualDom};
|
||||||
use std::{
|
use std::{
|
||||||
|
cell::Cell,
|
||||||
future::{Future, IntoFuture},
|
future::{Future, IntoFuture},
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
rc::{Rc, Weak},
|
rc::{Rc, Weak},
|
||||||
@@ -66,6 +67,7 @@ pub struct DesktopService {
|
|||||||
pub(super) query: QueryEngine,
|
pub(super) query: QueryEngine,
|
||||||
pub(crate) asset_handlers: AssetHandlerRegistry,
|
pub(crate) asset_handlers: AssetHandlerRegistry,
|
||||||
pub(crate) file_hover: NativeFileHover,
|
pub(crate) file_hover: NativeFileHover,
|
||||||
|
pub(crate) close_behaviour: Rc<Cell<WindowCloseBehaviour>>,
|
||||||
|
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
pub(crate) views: Rc<std::cell::RefCell<Vec<*mut objc::runtime::Object>>>,
|
pub(crate) views: Rc<std::cell::RefCell<Vec<*mut objc::runtime::Object>>>,
|
||||||
@@ -87,6 +89,7 @@ impl DesktopService {
|
|||||||
shared: Rc<SharedContext>,
|
shared: Rc<SharedContext>,
|
||||||
asset_handlers: AssetHandlerRegistry,
|
asset_handlers: AssetHandlerRegistry,
|
||||||
file_hover: NativeFileHover,
|
file_hover: NativeFileHover,
|
||||||
|
close_behaviour: WindowCloseBehaviour,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
window,
|
window,
|
||||||
@@ -94,6 +97,7 @@ impl DesktopService {
|
|||||||
shared,
|
shared,
|
||||||
asset_handlers,
|
asset_handlers,
|
||||||
file_hover,
|
file_hover,
|
||||||
|
close_behaviour: Rc::new(Cell::new(close_behaviour)),
|
||||||
query: Default::default(),
|
query: Default::default(),
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
views: Default::default(),
|
views: Default::default(),
|
||||||
@@ -165,6 +169,14 @@ impl DesktopService {
|
|||||||
self.window.set_maximized(!self.window.is_maximized())
|
self.window.set_maximized(!self.window.is_maximized())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the close behavior of this window
|
||||||
|
///
|
||||||
|
/// By default, windows close when the user clicks the close button.
|
||||||
|
/// If this is set to `WindowCloseBehaviour::WindowHides`, the window will hide instead of closing.
|
||||||
|
pub fn set_close_behavior(&self, behaviour: WindowCloseBehaviour) {
|
||||||
|
self.close_behaviour.set(behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
/// Close this window
|
/// Close this window
|
||||||
pub fn close(&self) {
|
pub fn close(&self) {
|
||||||
let _ = self
|
let _ = self
|
||||||
@@ -181,26 +193,6 @@ impl DesktopService {
|
|||||||
.send_event(UserWindowEvent::CloseWindow(id));
|
.send_event(UserWindowEvent::CloseWindow(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change close behaviour of this window
|
|
||||||
pub fn change_close_behaviour(&self, behaviour: Option<WindowCloseBehaviour>) {
|
|
||||||
let _ = self
|
|
||||||
.shared
|
|
||||||
.proxy
|
|
||||||
.send_event(UserWindowEvent::CloseBehaviour(self.id(), behaviour));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Change close behaviour of a specific window, given its ID
|
|
||||||
pub fn change_window_close_behaviour(
|
|
||||||
&self,
|
|
||||||
id: WindowId,
|
|
||||||
behaviour: Option<WindowCloseBehaviour>,
|
|
||||||
) {
|
|
||||||
let _ = self
|
|
||||||
.shared
|
|
||||||
.proxy
|
|
||||||
.send_event(UserWindowEvent::CloseBehaviour(id, behaviour));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// change window to fullscreen
|
/// change window to fullscreen
|
||||||
pub fn set_fullscreen(&self, fullscreen: bool) {
|
pub fn set_fullscreen(&self, fullscreen: bool) {
|
||||||
if let Some(handle) = &self.window.current_monitor() {
|
if let Some(handle) = &self.window.current_monitor() {
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tao::window::WindowId;
|
use tao::window::WindowId;
|
||||||
|
|
||||||
use crate::WindowCloseBehaviour;
|
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum UserWindowEvent {
|
pub enum UserWindowEvent {
|
||||||
@@ -19,8 +17,6 @@ pub enum UserWindowEvent {
|
|||||||
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
|
||||||
TrayMenuEvent(tray_icon::menu::MenuEvent),
|
TrayMenuEvent(tray_icon::menu::MenuEvent),
|
||||||
|
|
||||||
CloseBehaviour(WindowId, Option<WindowCloseBehaviour>),
|
|
||||||
|
|
||||||
/// Poll the virtualdom
|
/// Poll the virtualdom
|
||||||
Poll(WindowId),
|
Poll(WindowId),
|
||||||
|
|
||||||
|
|||||||
@@ -103,9 +103,6 @@ pub fn launch_virtual_dom_blocking(virtual_dom: VirtualDom, mut desktop_config:
|
|||||||
IpcMethod::BrowserOpen => app.handle_browser_open(msg),
|
IpcMethod::BrowserOpen => app.handle_browser_open(msg),
|
||||||
IpcMethod::Other(_) => {}
|
IpcMethod::Other(_) => {}
|
||||||
},
|
},
|
||||||
UserWindowEvent::CloseBehaviour(window_id, window_close_behaviour) => {
|
|
||||||
app.change_window_close_behaviour(window_id, window_close_behaviour)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ pub mod trayicon;
|
|||||||
|
|
||||||
// Public exports
|
// Public exports
|
||||||
pub use assets::AssetRequest;
|
pub use assets::AssetRequest;
|
||||||
pub use config::{Config, DefaultWindowCloseBehaviour, WindowCloseBehaviour};
|
pub use config::{Config, WindowCloseBehaviour};
|
||||||
pub use desktop_context::{
|
pub use desktop_context::{
|
||||||
window, DesktopContext, DesktopService, PendingDesktopContext, WeakDesktopContext,
|
window, DesktopContext, DesktopService, PendingDesktopContext, WeakDesktopContext,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -161,7 +161,6 @@ pub(crate) struct WebviewInstance {
|
|||||||
pub edits: WebviewEdits,
|
pub edits: WebviewEdits,
|
||||||
pub desktop_context: DesktopContext,
|
pub desktop_context: DesktopContext,
|
||||||
pub waker: Waker,
|
pub waker: Waker,
|
||||||
pub close_behaviour: Option<WindowCloseBehaviour>,
|
|
||||||
|
|
||||||
// Wry assumes the webcontext is alive for the lifetime of the webview.
|
// Wry assumes the webcontext is alive for the lifetime of the webview.
|
||||||
// We need to keep the webcontext alive, otherwise the webview will crash
|
// We need to keep the webcontext alive, otherwise the webview will crash
|
||||||
@@ -414,6 +413,7 @@ impl WebviewInstance {
|
|||||||
shared.clone(),
|
shared.clone(),
|
||||||
asset_handlers,
|
asset_handlers,
|
||||||
file_hover,
|
file_hover,
|
||||||
|
WindowCloseBehaviour::WindowCloses,
|
||||||
));
|
));
|
||||||
|
|
||||||
// Provide the desktop context to the virtual dom and edit handler
|
// Provide the desktop context to the virtual dom and edit handler
|
||||||
@@ -433,7 +433,6 @@ impl WebviewInstance {
|
|||||||
desktop_context,
|
desktop_context,
|
||||||
_menu: menu,
|
_menu: menu,
|
||||||
_web_context: web_context,
|
_web_context: web_context,
|
||||||
close_behaviour: cfg.window_close_behaviour,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user