1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use crate::config::{RendererConfig, RendererKind as ConfigRendererKind, WindowConfig};
use crate::ipc::IpcHandler;
use crate::window::WindowHandle;
/// The kind of renderer being used.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RendererKind {
/// System WebView (WebView2/WebKit)
WebView,
/// Chrome Embedded (CDP)
Chrome,
}
impl From<&ConfigRendererKind> for RendererKind {
fn from(kind: &ConfigRendererKind) -> Self {
match kind {
ConfigRendererKind::WebView => Self::WebView,
ConfigRendererKind::Chrome => Self::Chrome,
}
}
}
impl From<&RendererConfig> for RendererKind {
fn from(config: &RendererConfig) -> Self {
Self::from(&config.kind)
}
}
/// Core trait that both WebView and Chrome backends must implement.
///
/// This provides a unified API for creating windows, loading content,
/// executing JavaScript, and handling IPC regardless of the underlying
/// rendering engine.
pub trait Renderer {
/// Initialize the renderer.
fn init(&mut self) -> crate::Result<()>;
/// Create a new window with the given configuration.
fn create_window(&mut self, config: &WindowConfig) -> crate::Result<WindowHandle>;
/// Load a URL in the specified window.
fn load_url(&self, window: WindowHandle, url: &str) -> crate::Result<()>;
/// Load HTML content directly.
fn load_html(&self, window: WindowHandle, html: &str) -> crate::Result<()>;
/// Execute JavaScript in the specified window.
fn eval_script(&self, window: WindowHandle, script: &str) -> crate::Result<()>;
/// Set the IPC handler for messages from the frontend.
fn set_ipc_handler(&mut self, handler: Box<dyn IpcHandler>);
/// Send a message to the frontend JavaScript.
fn send_to_frontend(&self, window: WindowHandle, message: &str) -> crate::Result<()>;
/// Set the window title.
fn set_title(&self, window: WindowHandle, title: &str) -> crate::Result<()>;
/// Set the window size.
fn set_size(&self, window: WindowHandle, width: u32, height: u32) -> crate::Result<()>;
/// Set whether the window is resizable.
fn set_resizable(&self, window: WindowHandle, resizable: bool) -> crate::Result<()>;
/// Show or hide the window.
fn set_visible(&self, window: WindowHandle, visible: bool) -> crate::Result<()>;
/// Close a window.
fn close_window(&mut self, window: WindowHandle) -> crate::Result<()>;
// ── Frameless / Custom Title Bar ────────────────────────────────
/// Minimize the window.
fn minimize_window(&self, window: WindowHandle) -> crate::Result<()>;
/// Toggle maximize/restore.
fn maximize_window(&self, window: WindowHandle) -> crate::Result<()>;
/// Check whether the window is currently maximized.
fn is_maximized(&self, window: WindowHandle) -> crate::Result<bool>;
/// Toggle fullscreen mode.
fn set_fullscreen(&self, window: WindowHandle, fullscreen: bool) -> crate::Result<()>;
/// Check whether the window is currently fullscreen.
fn is_fullscreen(&self, window: WindowHandle) -> crate::Result<bool>;
/// Begin an interactive window drag.
///
/// Call this from a `mousedown` handler on a custom title bar element
/// to allow the user to drag the window from any region.
fn start_drag(&self, window: WindowHandle) -> crate::Result<()>;
/// Begin an interactive window resize.
///
/// `edge` specifies which edge/corner to resize from.
fn start_resize(&self, window: WindowHandle, edge: ResizeEdge) -> crate::Result<()>;
/// Set whether the window has OS decorations (title bar + borders).
fn set_decorations(&self, window: WindowHandle, decorations: bool) -> crate::Result<()>;
/// Set the window's always-on-top state.
fn set_always_on_top(&self, window: WindowHandle, always: bool) -> crate::Result<()>;
/// Enable or disable click-through: when enabled, pointer events fall
/// through the window to whatever is behind it (used by wallpaper and
/// click-through overlays). Applied at window creation by default; this
/// method allows toggling it at runtime where the platform supports it.
///
/// Default implementation is a no-op; backends override it to call the
/// platform-specific window API.
fn set_click_through(&self, _window: WindowHandle, _enabled: bool) -> crate::Result<()> {
Ok(())
}
// ── Lifecycle ───────────────────────────────────────────────────
/// Run the main event loop. This blocks until the application exits.
fn run(self: Box<Self>) -> crate::Result<()>;
/// Get the renderer kind.
fn kind(&self) -> RendererKind;
}
/// Edge or corner for interactive resize.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResizeEdge {
Top,
Bottom,
Left,
Right,
TopLeft,
TopRight,
BottomLeft,
BottomRight,
}