orinium_browser/platform/system/shell.rs
1//! The contract between the browser core and the OS shell.
2//!
3//! The browser core drives the browser; [`App`](super::App) owns the `winit` event loop,
4//! the OS windows and the GPU surface. Neither side may depend on the other's
5//! internals, so the seam is declared *here*, in the layer that owns the OS,
6//! and implemented by the browser core.
7//!
8//! Everything crossing this seam is a value owned by `platform`:
9//!
10//! - [`WindowGeometry`] instead of a per-window UI object
11//! - [`ShellCommand`] instead of a browser-internal command enum
12//! - plain `winit` / GPU handles instead of engine state
13//!
14//! That way the event loop can hold any [`BrowserHost`] — including one
15//! living in another process — without naming a single browser type.
16use winit::event::WindowEvent;
17use winit::window::{CursorIcon, WindowId};
18
19use crate::platform::renderer::draw_sink::DrawSink;
20
21/// An instruction for the OS shell, returned after handling an event.
22#[derive(Debug, Clone, PartialEq)]
23pub enum ShellCommand {
24 /// Nothing to do.
25 None,
26 /// Close the window; the shell exits once no window remains.
27 Exit,
28 /// Repaint the window.
29 RequestRedraw,
30 /// Re-read the window title from the host and apply it.
31 RenameWindowTitle,
32 /// Create an additional window.
33 OpenNewWindow,
34 /// Enable or disable OS IME input near the last click position.
35 SetImeAllowed { allowed: bool, position: (f64, f64) },
36 /// Set the mouse cursor icon for the window.
37 SetCursorIcon(CursorIcon),
38}
39
40/// The properties the shell needs to realise a window.
41#[derive(Debug, Clone)]
42pub struct WindowGeometry {
43 /// Initial inner size, in physical pixels.
44 pub size: (u32, u32),
45 /// Initial title.
46 pub title: String,
47 /// Display scale factor at creation time.
48 pub scale_factor: f64,
49}
50
51/// The browser side of the shell contract.
52///
53/// The shell calls these methods; the browser core implements them. Every
54/// method takes and returns `platform`-owned values only.
55pub trait BrowserHost {
56 /// The size to give a newly opened window.
57 fn default_window_size(&self) -> (u32, u32);
58
59 /// The title to give a newly opened window.
60 fn default_window_title(&self) -> String;
61
62 /// Registers a window with the host.
63 ///
64 /// The host decides what the window shows: the first call installs the UI
65 /// it was given before the loop started, and any later call opens an
66 /// empty window.
67 fn open_window(&mut self, window_id: WindowId, geometry: WindowGeometry);
68
69 /// Whether a UI is still waiting to be installed in the first window.
70 ///
71 /// The shell checks this before creating the first window so it can report
72 /// a misconfigured startup instead of silently opening a blank window.
73 fn has_pending_default_window(&self) -> bool;
74
75 /// Forgets a window that the shell closed.
76 fn close_window(&mut self, window_id: WindowId);
77
78 /// The current title for a window.
79 fn window_title(&self, window_id: WindowId) -> String;
80
81 /// Handles one OS event for a window and reports what the shell should do.
82 fn handle_window_event(
83 &mut self,
84 window_id: WindowId,
85 event: WindowEvent,
86 sink: &mut dyn DrawSink,
87 ) -> ShellCommand;
88
89 /// Uploads the window's pending draw commands to the sink, without
90 /// presenting.
91 fn apply_draw_commands(&mut self, window_id: WindowId, sink: &mut dyn DrawSink);
92
93 /// Advances background page work for a window, returning whether it needs
94 /// a repaint.
95 fn poll_window(&mut self, window_id: WindowId) -> bool;
96}