docs: document all of desktop crate
This commit is contained in:
1 parent
e71069883d
commit
b2a4d387c7
7 files changed
+138
-108
No files matched your search
@@ -1,5 +1,4 @@
|
|||||||
use crate::desktop_context::DesktopContext;
|
use crate::desktop_context::{DesktopContext, UserWindowEvent};
|
||||||
use crate::user_window_events::UserWindowEvent;
|
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, VecDeque},
|
collections::{HashMap, VecDeque},
|
||||||
|
|||||||
@@ -3,14 +3,23 @@ use std::rc::Rc;
|
|||||||
use dioxus_core::ScopeState;
|
use dioxus_core::ScopeState;
|
||||||
use wry::application::event_loop::EventLoopProxy;
|
use wry::application::event_loop::EventLoopProxy;
|
||||||
|
|
||||||
use crate::user_window_events::UserWindowEvent;
|
|
||||||
use UserWindowEvent::*;
|
use UserWindowEvent::*;
|
||||||
|
|
||||||
type ProxyType = EventLoopProxy<UserWindowEvent>;
|
pub type ProxyType = EventLoopProxy<UserWindowEvent>;
|
||||||
|
|
||||||
/// Desktop-Window handle api context
|
/// Get an imperative handle to the current window
|
||||||
|
pub fn use_window(cx: &ScopeState) -> &Rc<DesktopContext> {
|
||||||
|
cx.use_hook(|_| cx.consume_context::<DesktopContext>())
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An imperative interface to the current window.
|
||||||
///
|
///
|
||||||
/// you can use this context control some window event
|
/// To get a handle to the current window, use the [`use_window`] hook.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
///
|
///
|
||||||
/// you can use `cx.consume_context::<DesktopContext>` to get this context
|
/// you can use `cx.consume_context::<DesktopContext>` to get this context
|
||||||
///
|
///
|
||||||
@@ -19,7 +28,8 @@ type ProxyType = EventLoopProxy<UserWindowEvent>;
|
|||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DesktopContext {
|
pub struct DesktopContext {
|
||||||
proxy: ProxyType,
|
/// The wry/tao proxy to the current window
|
||||||
|
pub proxy: ProxyType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DesktopContext {
|
impl DesktopContext {
|
||||||
@@ -84,12 +94,12 @@ impl DesktopContext {
|
|||||||
let _ = self.proxy.send_event(AlwaysOnTop(top));
|
let _ = self.proxy.send_event(AlwaysOnTop(top));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set cursor visible or not
|
/// set cursor visible or not
|
||||||
pub fn set_cursor_visible(&self, visible: bool) {
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
let _ = self.proxy.send_event(CursorVisible(visible));
|
let _ = self.proxy.send_event(CursorVisible(visible));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set cursor grab
|
/// set cursor grab
|
||||||
pub fn set_cursor_grab(&self, grab: bool) {
|
pub fn set_cursor_grab(&self, grab: bool) {
|
||||||
let _ = self.proxy.send_event(CursorGrab(grab));
|
let _ = self.proxy.send_event(CursorGrab(grab));
|
||||||
}
|
}
|
||||||
@@ -110,9 +120,73 @@ impl DesktopContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// use this function can get the `DesktopContext` context.
|
use wry::application::event_loop::ControlFlow;
|
||||||
pub fn use_window(cx: &ScopeState) -> &Rc<DesktopContext> {
|
use wry::application::window::Fullscreen as WryFullscreen;
|
||||||
cx.use_hook(|_| cx.consume_context::<DesktopContext>())
|
|
||||||
.as_ref()
|
use crate::controller::DesktopController;
|
||||||
.unwrap()
|
|
||||||
|
pub enum UserWindowEvent {
|
||||||
|
Update,
|
||||||
|
|
||||||
|
CloseWindow,
|
||||||
|
DragWindow,
|
||||||
|
FocusWindow,
|
||||||
|
|
||||||
|
Visible(bool),
|
||||||
|
Minimize(bool),
|
||||||
|
Maximize(bool),
|
||||||
|
MaximizeToggle,
|
||||||
|
Resizable(bool),
|
||||||
|
AlwaysOnTop(bool),
|
||||||
|
Fullscreen(bool),
|
||||||
|
|
||||||
|
CursorVisible(bool),
|
||||||
|
CursorGrab(bool),
|
||||||
|
|
||||||
|
SetTitle(String),
|
||||||
|
SetDecorations(bool),
|
||||||
|
|
||||||
|
DevTool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn handler(
|
||||||
|
user_event: UserWindowEvent,
|
||||||
|
desktop: &mut DesktopController,
|
||||||
|
control_flow: &mut ControlFlow,
|
||||||
|
) {
|
||||||
|
// currently dioxus-desktop supports a single window only,
|
||||||
|
// so we can grab the only webview from the map;
|
||||||
|
let webview = desktop.webviews.values().next().unwrap();
|
||||||
|
let window = webview.window();
|
||||||
|
|
||||||
|
match user_event {
|
||||||
|
Update => desktop.try_load_ready_webviews(),
|
||||||
|
CloseWindow => *control_flow = ControlFlow::Exit,
|
||||||
|
DragWindow => {
|
||||||
|
// if the drag_window has any errors, we don't do anything
|
||||||
|
window.fullscreen().is_none().then(|| window.drag_window());
|
||||||
|
}
|
||||||
|
Visible(state) => window.set_visible(state),
|
||||||
|
Minimize(state) => window.set_minimized(state),
|
||||||
|
Maximize(state) => window.set_maximized(state),
|
||||||
|
MaximizeToggle => window.set_maximized(!window.is_maximized()),
|
||||||
|
Fullscreen(state) => {
|
||||||
|
if let Some(handle) = window.current_monitor() {
|
||||||
|
window.set_fullscreen(state.then(|| WryFullscreen::Borderless(Some(handle))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FocusWindow => window.set_focus(),
|
||||||
|
Resizable(state) => window.set_resizable(state),
|
||||||
|
AlwaysOnTop(state) => window.set_always_on_top(state),
|
||||||
|
|
||||||
|
CursorVisible(state) => window.set_cursor_visible(state),
|
||||||
|
CursorGrab(state) => {
|
||||||
|
let _ = window.set_cursor_grab(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTitle(content) => window.set_title(&content),
|
||||||
|
SetDecorations(state) => window.set_decorations(state),
|
||||||
|
|
||||||
|
DevTool => webview.devtool(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+13
-13
@@ -1,18 +1,23 @@
|
|||||||
#![doc = include_str!("readme.md")]
|
#![doc = include_str!("readme.md")]
|
||||||
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
|
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||||
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
|
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
pub mod cfg;
|
mod cfg;
|
||||||
mod controller;
|
mod controller;
|
||||||
pub mod desktop_context;
|
mod desktop_context;
|
||||||
pub mod escape;
|
mod escape;
|
||||||
pub mod events;
|
mod events;
|
||||||
mod protocol;
|
mod protocol;
|
||||||
mod user_window_events;
|
|
||||||
|
|
||||||
|
use desktop_context::UserWindowEvent;
|
||||||
|
pub use desktop_context::{use_window, DesktopContext};
|
||||||
|
pub use wry;
|
||||||
|
pub use wry::application as tao;
|
||||||
|
|
||||||
|
use crate::events::trigger_from_serialized;
|
||||||
use cfg::DesktopConfig;
|
use cfg::DesktopConfig;
|
||||||
use controller::DesktopController;
|
use controller::DesktopController;
|
||||||
pub use desktop_context::use_window;
|
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
use events::parse_ipc_message;
|
use events::parse_ipc_message;
|
||||||
use tao::{
|
use tao::{
|
||||||
@@ -20,12 +25,8 @@ use tao::{
|
|||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
window::Window,
|
window::Window,
|
||||||
};
|
};
|
||||||
pub use wry;
|
|
||||||
pub use wry::application as tao;
|
|
||||||
use wry::webview::WebViewBuilder;
|
use wry::webview::WebViewBuilder;
|
||||||
|
|
||||||
use crate::events::trigger_from_serialized;
|
|
||||||
|
|
||||||
/// Launch the WebView and run the event loop.
|
/// Launch the WebView and run the event loop.
|
||||||
///
|
///
|
||||||
/// This function will start a multithreaded Tokio runtime as well the WebView event loop.
|
/// This function will start a multithreaded Tokio runtime as well the WebView event loop.
|
||||||
@@ -139,8 +140,7 @@ pub fn launch_with_props<P: 'static + Send>(
|
|||||||
}
|
}
|
||||||
"initialize" => {
|
"initialize" => {
|
||||||
is_ready.store(true, std::sync::atomic::Ordering::Relaxed);
|
is_ready.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
let _ = proxy
|
let _ = proxy.send_event(UserWindowEvent::Update);
|
||||||
.send_event(user_window_events::UserWindowEvent::Update);
|
|
||||||
}
|
}
|
||||||
"browser_open" => {
|
"browser_open" => {
|
||||||
println!("browser_open");
|
println!("browser_open");
|
||||||
@@ -214,7 +214,7 @@ pub fn launch_with_props<P: 'static + Send>(
|
|||||||
},
|
},
|
||||||
|
|
||||||
Event::UserEvent(user_event) => {
|
Event::UserEvent(user_event) => {
|
||||||
user_window_events::handler(user_event, &mut desktop, control_flow)
|
desktop_context::handler(user_event, &mut desktop, control_flow)
|
||||||
}
|
}
|
||||||
Event::MainEventsCleared => {}
|
Event::MainEventsCleared => {}
|
||||||
Event::Resumed => {}
|
Event::Resumed => {}
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
use wry::application::event_loop::ControlFlow;
|
|
||||||
use wry::application::window::Fullscreen as WryFullscreen;
|
|
||||||
|
|
||||||
use crate::controller::DesktopController;
|
|
||||||
|
|
||||||
pub(crate) enum UserWindowEvent {
|
|
||||||
Update,
|
|
||||||
|
|
||||||
CloseWindow,
|
|
||||||
DragWindow,
|
|
||||||
FocusWindow,
|
|
||||||
|
|
||||||
Visible(bool),
|
|
||||||
Minimize(bool),
|
|
||||||
Maximize(bool),
|
|
||||||
MaximizeToggle,
|
|
||||||
Resizable(bool),
|
|
||||||
AlwaysOnTop(bool),
|
|
||||||
Fullscreen(bool),
|
|
||||||
|
|
||||||
CursorVisible(bool),
|
|
||||||
CursorGrab(bool),
|
|
||||||
|
|
||||||
SetTitle(String),
|
|
||||||
SetDecorations(bool),
|
|
||||||
|
|
||||||
DevTool,
|
|
||||||
}
|
|
||||||
|
|
||||||
use UserWindowEvent::*;
|
|
||||||
|
|
||||||
pub(super) fn handler(
|
|
||||||
user_event: UserWindowEvent,
|
|
||||||
desktop: &mut DesktopController,
|
|
||||||
control_flow: &mut ControlFlow,
|
|
||||||
) {
|
|
||||||
// currently dioxus-desktop supports a single window only,
|
|
||||||
// so we can grab the only webview from the map;
|
|
||||||
let webview = desktop.webviews.values().next().unwrap();
|
|
||||||
let window = webview.window();
|
|
||||||
|
|
||||||
match user_event {
|
|
||||||
Update => desktop.try_load_ready_webviews(),
|
|
||||||
CloseWindow => *control_flow = ControlFlow::Exit,
|
|
||||||
DragWindow => {
|
|
||||||
// if the drag_window has any errors, we don't do anything
|
|
||||||
window.fullscreen().is_none().then(|| window.drag_window());
|
|
||||||
}
|
|
||||||
Visible(state) => window.set_visible(state),
|
|
||||||
Minimize(state) => window.set_minimized(state),
|
|
||||||
Maximize(state) => window.set_maximized(state),
|
|
||||||
MaximizeToggle => window.set_maximized(!window.is_maximized()),
|
|
||||||
Fullscreen(state) => {
|
|
||||||
if let Some(handle) = window.current_monitor() {
|
|
||||||
window.set_fullscreen(state.then(|| WryFullscreen::Borderless(Some(handle))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FocusWindow => window.set_focus(),
|
|
||||||
Resizable(state) => window.set_resizable(state),
|
|
||||||
AlwaysOnTop(state) => window.set_always_on_top(state),
|
|
||||||
|
|
||||||
CursorVisible(state) => window.set_cursor_visible(state),
|
|
||||||
CursorGrab(state) => {
|
|
||||||
let _ = window.set_cursor_grab(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetTitle(content) => window.set_title(&content),
|
|
||||||
SetDecorations(state) => window.set_decorations(state),
|
|
||||||
|
|
||||||
DevTool => webview.devtool(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#![deny(missing_docs)]
|
||||||
|
//! Useful foundational hooks for Dioxus
|
||||||
|
|
||||||
mod usestate;
|
mod usestate;
|
||||||
pub use usestate::{use_state, UseState};
|
pub use usestate::{use_state, UseState};
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,30 @@
|
|||||||
|
#![allow(missing_docs)]
|
||||||
use dioxus_core::{ScopeState, TaskId};
|
use dioxus_core::{ScopeState, TaskId};
|
||||||
use std::{cell::Cell, future::Future, rc::Rc};
|
use std::{cell::Cell, future::Future, rc::Rc};
|
||||||
|
|
||||||
|
/// A future that resolves to a value.
|
||||||
|
///
|
||||||
|
/// This runs the future only once - though the future may be regenerated
|
||||||
|
/// through the [`UseFuture::restart`] method.
|
||||||
|
///
|
||||||
|
/// This is commonly used for components that cannot be rendered until some
|
||||||
|
/// asynchronous operation has completed.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
pub fn use_future<'a, T: 'static, F: Future<Output = T> + 'static>(
|
pub fn use_future<'a, T: 'static, F: Future<Output = T> + 'static>(
|
||||||
cx: &'a ScopeState,
|
cx: &'a ScopeState,
|
||||||
new_fut: impl FnOnce() -> F,
|
new_fut: impl FnOnce() -> F,
|
||||||
) -> &'a UseFuture<T> {
|
) -> &'a UseFuture<T> {
|
||||||
let state = cx.use_hook(move |_| {
|
let state = cx.use_hook(move |_| UseFuture {
|
||||||
//
|
update: cx.schedule_update(),
|
||||||
UseFuture {
|
needs_regen: Cell::new(true),
|
||||||
update: cx.schedule_update(),
|
slot: Rc::new(Cell::new(None)),
|
||||||
needs_regen: Cell::new(true),
|
value: None,
|
||||||
slot: Rc::new(Cell::new(None)),
|
task: None,
|
||||||
value: None,
|
pending: true,
|
||||||
task: None,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(value) = state.slot.take() {
|
if let Some(value) = state.slot.take() {
|
||||||
@@ -24,6 +35,7 @@ pub fn use_future<'a, T: 'static, F: Future<Output = T> + 'static>(
|
|||||||
if state.needs_regen.get() {
|
if state.needs_regen.get() {
|
||||||
// We don't need regen anymore
|
// We don't need regen anymore
|
||||||
state.needs_regen.set(false);
|
state.needs_regen.set(false);
|
||||||
|
state.pending = false;
|
||||||
|
|
||||||
// Create the new future
|
// Create the new future
|
||||||
let fut = new_fut();
|
let fut = new_fut();
|
||||||
@@ -42,10 +54,17 @@ pub fn use_future<'a, T: 'static, F: Future<Output = T> + 'static>(
|
|||||||
state
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum FutureState<'a, T> {
|
||||||
|
Pending,
|
||||||
|
Complete(&'a T),
|
||||||
|
Regenerating(&'a T), // the old value
|
||||||
|
}
|
||||||
|
|
||||||
pub struct UseFuture<T> {
|
pub struct UseFuture<T> {
|
||||||
update: Rc<dyn Fn()>,
|
update: Rc<dyn Fn()>,
|
||||||
needs_regen: Cell<bool>,
|
needs_regen: Cell<bool>,
|
||||||
value: Option<T>,
|
value: Option<T>,
|
||||||
|
pending: bool,
|
||||||
slot: Rc<Cell<Option<T>>>,
|
slot: Rc<Cell<Option<T>>>,
|
||||||
task: Option<TaskId>,
|
task: Option<TaskId>,
|
||||||
}
|
}
|
||||||
@@ -72,4 +91,9 @@ impl<T> UseFuture<T> {
|
|||||||
pub fn value(&self) -> Option<&T> {
|
pub fn value(&self) -> Option<&T> {
|
||||||
self.value.as_ref()
|
self.value.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn state(&self) -> FutureState<T> {
|
||||||
|
// self.value.as_ref()
|
||||||
|
FutureState::Pending
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
//! Dioxus WebSys
|
//! Dioxus WebSys
|
||||||
//!
|
//!
|
||||||
//! ## Overview
|
//! ## Overview
|
||||||
|
|||||||
Reference in new issue
Block a user