versoview_messages/
lib.rs

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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
use std::path::PathBuf;

use dpi::{PhysicalPosition, PhysicalSize, Position, Size};
use ipc_channel::ipc;
use serde::{Deserialize, Serialize};

// Note: the reason why we didn't send `IpcSender` in those messages is because it panics on MacOS,
// see https://github.com/versotile-org/verso/pull/222#discussion_r1939111585,
// the work around is let verso send back the message through the initial sender and we map them back manually

// Can't use `PipelineId` directly or else we need to pull in servo as a dependency
type SerializedPipelineId = Vec<u8>;

/// Message sent from the controller to versoview
#[derive(Debug, Serialize, Deserialize)]
#[non_exhaustive]
pub enum ToVersoMessage {
    /// Initial configs for versoview
    /// this will be the first message sent to Verso once we received the sender from [`ToControllerMessage::SetToVersoSender`]
    SetConfig(ConfigFromController),
    /// Exit
    Exit,
    /// Register a listener on versoview for getting notified on close requested from the OS,
    /// veroview will send a [`ToControllerMessage::OnCloseRequested`] when that happens
    ListenToOnCloseRequested,
    /// Navigate to this URL
    NavigateTo(url::Url),
    /// Reload the current webview
    Reload,
    /// Register a listener on versoview for getting notified on navigation starting,
    /// veroview will send a [`ToControllerMessage::OnNavigationStarting`] when that happens
    ListenToOnNavigationStarting,
    /// Response to a [`ToControllerMessage::OnNavigationStarting`] message from versoview
    OnNavigationStartingResponse(SerializedPipelineId, bool),
    /// Execute JavaScript
    ExecuteScript(String),
    /// Register a listener on versoview for getting notified on web resource requests
    ListenToWebResourceRequests,
    /// Response to a [`ToControllerMessage::OnWebResourceRequested`] message from versoview
    WebResourceRequestResponse(WebResourceRequestResponse),
    /// Sets the webview window's size
    SetSize(Size),
    /// Sets the webview window's position
    SetPosition(Position),
    /// Maximize or unmaximize the window
    SetMaximized(bool),
    /// Minimize or unminimize the window
    SetMinimized(bool),
    /// Sets the window to fullscreen or back
    SetFullscreen(bool),
    /// Show or hide the window
    SetVisible(bool),
    /// Moves the window with the left mouse button until the button is released
    StartDragging,
    /// Bring the window to the front, and capture input focus
    Focus,
    /// Get the window's size, need a response with [`ToControllerMessage::GetSizeResponse`]
    GetSize(uuid::Uuid, SizeType),
    /// Get the window's position, need a response with [`ToControllerMessage::GetPositionResponse`]
    GetPosition(uuid::Uuid, PositionType),
    /// Get if the window is currently maximized or not, need a response with [`ToControllerMessage::GetMaximizedResponse`]
    GetMaximized(uuid::Uuid),
    /// Get if the window is currently minimized or not, need a response with [`ToControllerMessage::GetMinimizedResponse`]
    GetMinimized(uuid::Uuid),
    /// Get if the window is currently fullscreen or not, need a response with [`ToControllerMessage::GetFullscreenResponse`]
    GetFullscreen(uuid::Uuid),
    /// Get the visibility of the window, need a response with [`ToControllerMessage::GetVisibleResponse`]
    GetVisible(uuid::Uuid),
    /// Get the scale factor of the window, need a response with [`ToControllerMessage::GetScaleFactorResponse`]
    GetScaleFactor(uuid::Uuid),
    /// Get the current URL of the webview, need a response with [`ToControllerMessage::GetCurrentUrlResponse`]
    GetCurrentUrl(uuid::Uuid),
}

#[derive(Debug, Serialize, Deserialize)]
pub enum PositionType {
    Inner,
    Outer,
}

#[derive(Debug, Serialize, Deserialize)]
pub enum SizeType {
    Inner,
    Outer,
}

/// Message sent from versoview to the controller
#[derive(Debug, Serialize, Deserialize)]
#[non_exhaustive]
pub enum ToControllerMessage {
    /// IPC sender for the controller to send commands to versoview,
    /// this will be the first message sent to the controller once connected
    SetToVersoSender(ipc::IpcSender<ToVersoMessage>),
    /// Sent on a new navigation starting, need a response with [`ToVersoMessage::OnNavigationStartingResponse`]
    OnNavigationStarting(SerializedPipelineId, url::Url),
    /// Sent on a new web resource request, need a response with [`ToVersoMessage::WebResourceRequestResponse`]
    OnWebResourceRequested(WebResourceRequest),
    /// Response to a [`ToVersoMessage::GetSize`]
    GetSizeResponse(uuid::Uuid, PhysicalSize<u32>),
    /// Response to a [`ToVersoMessage::GetPosition`]
    GetPositionResponse(uuid::Uuid, Option<PhysicalPosition<i32>>),
    /// Response to a [`ToVersoMessage::GetMaximized`]
    GetMaximizedResponse(uuid::Uuid, bool),
    /// Response to a [`ToVersoMessage::GetMinimized`]
    GetMinimizedResponse(uuid::Uuid, bool),
    /// Response to a [`ToVersoMessage::GetFullscreen`]
    GetFullscreenResponse(uuid::Uuid, bool),
    /// Response to a [`ToVersoMessage::GetVisible`]
    GetVisibleResponse(uuid::Uuid, bool),
    /// Response to a [`ToVersoMessage::GetScaleFactor`]
    GetScaleFactorResponse(uuid::Uuid, f64),
    /// Response to a [`ToVersoMessage::GetCurrentUrl`]
    GetCurrentUrlResponse(uuid::Uuid, url::Url),
    /// Verso have recieved a close request from the OS
    OnCloseRequested,
}

/// Configuration of Verso instance.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ConfigFromController {
    /// URL to load initially.
    pub url: Option<url::Url>,
    /// Should launch without or without control panel
    pub with_panel: bool,
    /// Window size for the initial winit window
    pub inner_size: Option<Size>,
    /// Window position for the initial winit window
    pub position: Option<Position>,
    /// Launch maximized or not for the initial winit window
    pub maximized: bool,
    /// Launch visible or not for the initial winit window
    pub visible: bool,
    /// Launch fullscreen or not for the initial winit window
    pub fullscreen: bool,
    /// Launch focused or not for the initial winit window
    pub focused: bool,
    /// Launch decorated or not for the initial winit window
    pub decorated: bool,
    /// Launch transparent or not for the initial winit window
    pub transparent: bool,
    /// Title of the initial winit window in the title bar.
    pub title: Option<String>,
    /// Window icon of the initial winit window.
    pub icon: Option<Icon>,
    /// Port number to start a server to listen to remote Firefox devtools connections. 0 for random port.
    pub devtools_port: Option<u16>,
    /// Servo time profile settings
    pub profiler_settings: Option<ProfilerSettings>,
    /// Override the user agent
    pub user_agent: Option<String>,
    /// Script to run on document started to load
    pub user_scripts: Vec<UserScript>,
    /// Initial window's zoom level
    pub zoom_level: Option<f32>,
    /// Path to resource directory. If None, Verso will try to get default directory. And if that
    /// still doesn't exist, all resource configuration will set to default values.
    pub resources_directory: Option<PathBuf>,
}

impl Default for ConfigFromController {
    fn default() -> Self {
        Self {
            url: None,
            with_panel: false,
            inner_size: None,
            position: None,
            maximized: false,
            visible: true,
            focused: true,
            decorated: false,
            transparent: true,
            title: None,
            icon: None,
            fullscreen: false,
            devtools_port: None,
            profiler_settings: None,
            user_agent: None,
            user_scripts: Vec::new(),
            zoom_level: None,
            resources_directory: None,
        }
    }
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Icon {
    /// RGBA bytes of the icon.
    pub rgba: Vec<u8>,
    /// Icon width.
    pub width: u32,
    /// Icon height.
    pub height: u32,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct UserScript {
    pub script: String,
    pub source_file: Option<PathBuf>,
}

impl<T: Into<String>> From<T> for UserScript {
    fn from(script: T) -> Self {
        UserScript {
            script: script.into(),
            source_file: None,
        }
    }
}

/// Servo time profile settings
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ProfilerSettings {
    /// Servo time profile settings
    pub output_options: OutputOptions,
    /// When servo profiler is enabled, this is an optional path to dump a self-contained HTML file
    /// visualizing the traces as a timeline.
    pub trace_path: Option<String>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum OutputOptions {
    /// Database connection config (hostname, name, user, pass)
    FileName(String),
    Stdout(f64),
}

#[derive(Debug, Serialize, Deserialize)]
pub struct WebResourceRequest {
    pub id: uuid::Uuid,
    #[serde(with = "http_serde_ext::request")]
    pub request: http::Request<Vec<u8>>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct WebResourceRequestResponse {
    pub id: uuid::Uuid,
    #[serde(with = "http_serde_ext::response::option")]
    pub response: Option<http::Response<Vec<u8>>>,
}