Browse Source

Merge pull request #227 from mrxiaozhuox/master

Add more Desktop Window Api
Jonathan Kelley 3 years ago
parent
commit
f9a50163c0

+ 0 - 38
examples/borderless.rs

@@ -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"
-                }
-            }
-        }
-    ))
-}

+ 97 - 0
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"
+                    }
+                }
+            }
+        }
+    ))
+}

+ 50 - 2
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.

+ 79 - 1
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<P: 'static + Send>(
                             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<P: 'static + Send>(
                         // 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<P: 'static + Send>(
                             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 {