diff --git a/examples/borderless.rs b/examples/borderless.rs deleted file mode 100644 index d52e9fb5a..000000000 --- a/examples/borderless.rs +++ /dev/null @@ -1,38 +0,0 @@ -use dioxus::prelude::*; - -fn main() { - dioxus::desktop::launch_cfg(app, |cfg| { - cfg.with_window(|w| w.with_title("BorderLess Demo").with_decorations(false)) - }); -} - -fn app(cx: Scope) -> Element { - let window = dioxus::desktop::use_window(&cx); - - cx.render(rsx!( - link { href:"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css", rel:"stylesheet" } - header { - class: "text-gray-400 bg-gray-900 body-font", - onmousedown: move |_| window.drag(), - div { - class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center", - a { class: "flex title-font font-medium items-center text-white mb-4 md:mb-0", - span { class: "ml-3 text-xl", "Dioxus"} - } - nav { class: "md:ml-auto flex flex-wrap items-center text-base justify-center" } - button { - class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", - onmousedown: |evt| evt.cancel_bubble(), - onclick: move |_| window.minimize(true), - "Minimize" - } - button { - class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", - onmousedown: |evt| evt.cancel_bubble(), - onclick: move |_| window.close(), - "Close" - } - } - } - )) -} diff --git a/examples/window_event.rs b/examples/window_event.rs new file mode 100644 index 000000000..cb578829f --- /dev/null +++ b/examples/window_event.rs @@ -0,0 +1,97 @@ +use dioxus::prelude::*; + +fn main() { + dioxus::desktop::launch_cfg(app, |cfg| { + cfg.with_window(|w| w.with_title("BorderLess Demo").with_decorations(false)) + }); +} + +fn app(cx: Scope) -> Element { + let window = dioxus::desktop::use_window(&cx); + + // if you want to make window fullscreen, you need close the resizable. + // window.set_fullscreen(true); + // window.set_resizable(false); + + let (fullscreen, set_fullscreen) = use_state(&cx, || false); + let (always_on_top, set_always_on_top) = use_state(&cx, || false); + let (decorations, set_decorations) = use_state(&cx, || false); + + cx.render(rsx!( + link { href:"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css", rel:"stylesheet" } + header { + class: "text-gray-400 bg-gray-900 body-font", + onmousedown: move |_| window.drag(), + div { + class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center", + a { class: "flex title-font font-medium items-center text-white mb-4 md:mb-0", + span { class: "ml-3 text-xl", "Dioxus"} + } + nav { class: "md:ml-auto flex flex-wrap items-center text-base justify-center" } + button { + class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", + onmousedown: |evt| evt.cancel_bubble(), + onclick: move |_| window.set_minimized(true), + "Minimize" + } + button { + class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", + onmousedown: |evt| evt.cancel_bubble(), + onclick: move |_| { + + window.set_fullscreen(!fullscreen); + window.set_resizable(*fullscreen); + + set_fullscreen(!fullscreen); + }, + "Fullscreen" + } + button { + class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", + onmousedown: |evt| evt.cancel_bubble(), + onclick: move |_| window.close(), + "Close" + } + } + } + br {} + div { + class: "container mx-auto", + div { + class: "grid grid-cols-5", + div { + button { + class: "inline-flex items-center text-white bg-green-500 border-0 py-1 px-3 hover:bg-green-700 rounded", + onmousedown: |evt| evt.cancel_bubble(), + onclick: move |_| { + window.set_always_on_top(!always_on_top); + set_always_on_top(!always_on_top); + }, + "Always On Top" + } + } + div { + button { + class: "inline-flex items-center text-white bg-blue-500 border-0 py-1 px-3 hover:bg-green-700 rounded", + onmousedown: |evt| evt.cancel_bubble(), + onclick: move |_| { + window.set_decorations(!decorations); + set_decorations(!decorations); + }, + "Set Decorations" + } + } + div { + button { + class: "inline-flex items-center text-white bg-blue-500 border-0 py-1 px-3 hover:bg-green-700 rounded", + onmousedown: |evt| evt.cancel_bubble(), + onclick: move |_| { + window.set_title("Dioxus Application"); + }, + "Change Title" + } + } + } + } + )) +} diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index 9c0404477..d180e1235 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -39,15 +39,20 @@ impl DesktopContext { } /// set window minimize state - pub fn minimize(&self, minimized: bool) { + pub fn set_minimized(&self, minimized: bool) { let _ = self.proxy.send_event(UserWindowEvent::Minimize(minimized)); } /// set window maximize state - pub fn maximize(&self, maximized: bool) { + pub fn set_maximized(&self, maximized: bool) { let _ = self.proxy.send_event(UserWindowEvent::Maximize(maximized)); } + /// set window visible or not + pub fn set_visible(&self, visible: bool) { + let _ = self.proxy.send_event(UserWindowEvent::Visible(visible)); + } + /// close window pub fn close(&self) { let _ = self.proxy.send_event(UserWindowEvent::CloseWindow); @@ -57,6 +62,49 @@ impl DesktopContext { pub fn focus(&self) { let _ = self.proxy.send_event(UserWindowEvent::FocusWindow); } + + /// change window to fullscreen + pub fn set_fullscreen(&self, fullscreen: bool) { + let _ = self + .proxy + .send_event(UserWindowEvent::Fullscreen(fullscreen)); + } + + /// set resizable state + pub fn set_resizable(&self, resizable: bool) { + let _ = self.proxy.send_event(UserWindowEvent::Resizable(resizable)); + } + + /// set the window always on top + pub fn set_always_on_top(&self, top: bool) { + let _ = self.proxy.send_event(UserWindowEvent::AlwaysOnTop(top)); + } + + // set cursor visible or not + pub fn set_cursor_visible(&self, visible: bool) { + let _ = self + .proxy + .send_event(UserWindowEvent::CursorVisible(visible)); + } + + // set cursor grab + pub fn set_cursor_grab(&self, grab: bool) { + let _ = self.proxy.send_event(UserWindowEvent::CursorGrab(grab)); + } + + /// set window title + pub fn set_title(&self, title: &str) { + let _ = self + .proxy + .send_event(UserWindowEvent::SetTitle(String::from(title))); + } + + /// change window to borderless + pub fn set_decorations(&self, decoration: bool) { + let _ = self + .proxy + .send_event(UserWindowEvent::SetDecorations(decoration)); + } } /// use this function can get the `DesktopContext` context. diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index 9181d04dc..143225f6a 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -72,7 +72,7 @@ use tao::{ pub use wry; pub use wry::application as tao; use wry::{ - application::event_loop::EventLoopProxy, + application::{event_loop::EventLoopProxy, window::Fullscreen}, webview::RpcRequest, webview::{WebView, WebViewBuilder}, }; @@ -292,6 +292,11 @@ pub fn launch_with_props( let window = webview.window(); // start to drag the window. // if the drag_window have any err. we don't do anything. + + if window.fullscreen().is_some() { + return; + } + let _ = window.drag_window(); } } @@ -299,6 +304,12 @@ pub fn launch_with_props( // close window *control_flow = ControlFlow::Exit; } + UserWindowEvent::Visible(state) => { + for webview in desktop.webviews.values() { + let window = webview.window(); + window.set_visible(state); + } + } UserWindowEvent::Minimize(state) => { // this loop just run once, because dioxus-desktop is unsupport multi-window. for webview in desktop.webviews.values() { @@ -315,12 +326,69 @@ pub fn launch_with_props( window.set_maximized(state); } } + UserWindowEvent::Fullscreen(state) => { + for webview in desktop.webviews.values() { + let window = webview.window(); + + let current_monitor = window.current_monitor(); + + if current_monitor.is_none() { + return; + } + + let fullscreen = if state { + Some(Fullscreen::Borderless(current_monitor)) + } else { + None + }; + + window.set_fullscreen(fullscreen); + } + } UserWindowEvent::FocusWindow => { for webview in desktop.webviews.values() { let window = webview.window(); window.set_focus(); } } + UserWindowEvent::Resizable(state) => { + for webview in desktop.webviews.values() { + let window = webview.window(); + window.set_resizable(state); + } + } + UserWindowEvent::AlwaysOnTop(state) => { + for webview in desktop.webviews.values() { + let window = webview.window(); + window.set_always_on_top(state); + } + } + + UserWindowEvent::CursorVisible(state) => { + for webview in desktop.webviews.values() { + let window = webview.window(); + window.set_cursor_visible(state); + } + } + UserWindowEvent::CursorGrab(state) => { + for webview in desktop.webviews.values() { + let window = webview.window(); + let _ = window.set_cursor_grab(state); + } + } + + UserWindowEvent::SetTitle(content) => { + for webview in desktop.webviews.values() { + let window = webview.window(); + window.set_title(&content); + } + } + UserWindowEvent::SetDecorations(state) => { + for webview in desktop.webviews.values() { + let window = webview.window(); + window.set_decorations(state); + } + } } } Event::MainEventsCleared => {} @@ -338,8 +406,18 @@ pub enum UserWindowEvent { DragWindow, CloseWindow, FocusWindow, + Visible(bool), Minimize(bool), Maximize(bool), + Resizable(bool), + AlwaysOnTop(bool), + Fullscreen(bool), + + CursorVisible(bool), + CursorGrab(bool), + + SetTitle(String), + SetDecorations(bool), } pub struct DesktopController {