mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
servoshell: Remove HeadedWindow-specific methods from PlatformWindow (#41773)
Instead of having `HeadedWindow`-specific methods here, just expose a way to access the concrete type of a window. This is also exposed for embedded ports and unused. They will use it in an upcoming change. Testing: This shouldn't change behavior and is thus covered by existing tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
@@ -28,7 +28,7 @@ use crate::desktop::tracing::trace_winit_event;
|
||||
use crate::parser::get_default_url;
|
||||
use crate::prefs::ServoShellPreferences;
|
||||
use crate::running_app_state::RunningAppState;
|
||||
use crate::window::PlatformWindow;
|
||||
use crate::window::{PlatformWindow, ServoShellWindowId};
|
||||
|
||||
pub(crate) enum AppState {
|
||||
Initializing,
|
||||
@@ -186,17 +186,13 @@ impl ApplicationHandler<AppEvent> for App {
|
||||
);
|
||||
self.t = now;
|
||||
|
||||
{
|
||||
let AppState::Running(state) = &self.state else {
|
||||
return;
|
||||
};
|
||||
let window_id: u64 = window_id.into();
|
||||
if let Some(window) = state.window(window_id.into()) {
|
||||
window.platform_window().handle_winit_window_event(
|
||||
state.clone(),
|
||||
window,
|
||||
window_event,
|
||||
);
|
||||
let AppState::Running(state) = &self.state else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(window) = state.window(ServoShellWindowId::from(u64::from(window_id))) {
|
||||
if let Some(headed_window) = window.platform_window().as_headed_window() {
|
||||
headed_window.handle_winit_window_event(state.clone(), window, window_event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,15 +204,16 @@ impl ApplicationHandler<AppEvent> for App {
|
||||
}
|
||||
|
||||
fn user_event(&mut self, event_loop: &ActiveEventLoop, app_event: AppEvent) {
|
||||
let AppState::Running(state) = &self.state else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(window) = app_event
|
||||
.window_id()
|
||||
.and_then(|window_id| state.window(ServoShellWindowId::from(u64::from(window_id))))
|
||||
{
|
||||
let AppState::Running(state) = &self.state else {
|
||||
return;
|
||||
};
|
||||
if let Some(window_id) = app_event.window_id() {
|
||||
let window_id: u64 = window_id.into();
|
||||
if let Some(window) = state.window(window_id.into()) {
|
||||
window.platform_window().handle_winit_app_event(app_event);
|
||||
}
|
||||
if let Some(headed_window) = window.platform_window().as_headed_window() {
|
||||
headed_window.handle_winit_app_event(app_event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -533,68 +533,8 @@ impl HeadedWindow {
|
||||
fn toolbar_height(&self) -> Length<f32, DeviceIndependentPixel> {
|
||||
self.gui.borrow().toolbar_height()
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformWindow for HeadedWindow {
|
||||
fn has_winit_window(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn screen_geometry(&self) -> ScreenGeometry {
|
||||
let hidpi_factor = self.hidpi_scale_factor();
|
||||
let toolbar_size = Size2D::new(0.0, (self.toolbar_height() * self.hidpi_scale_factor()).0);
|
||||
let screen_size = self.screen_size.to_f32() * hidpi_factor;
|
||||
|
||||
// FIXME: In reality, this should subtract screen space used by the system interface
|
||||
// elements, but it is difficult to get this value with `winit` currently. See:
|
||||
// See https://github.com/rust-windowing/winit/issues/2494
|
||||
let available_screen_size = screen_size - toolbar_size;
|
||||
|
||||
let window_rect = DeviceIntRect::from_origin_and_size(
|
||||
winit_position_to_euclid_point(self.winit_window.outer_position().unwrap_or_default()),
|
||||
winit_size_to_euclid_size(self.winit_window.outer_size()).to_i32(),
|
||||
);
|
||||
|
||||
ScreenGeometry {
|
||||
size: screen_size.to_i32(),
|
||||
available_size: available_screen_size.to_i32(),
|
||||
window_rect,
|
||||
}
|
||||
}
|
||||
|
||||
fn device_hidpi_scale_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||
Scale::new(self.winit_window.scale_factor() as f32)
|
||||
}
|
||||
|
||||
fn hidpi_scale_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||
self.device_pixel_ratio_override
|
||||
.map(Scale::new)
|
||||
.unwrap_or_else(|| self.device_hidpi_scale_factor())
|
||||
}
|
||||
|
||||
fn rebuild_user_interface(&self, state: &RunningAppState, window: &ServoShellWindow) {
|
||||
self.gui.borrow_mut().update(state, window, self);
|
||||
}
|
||||
|
||||
fn update_user_interface_state(&self, _: &RunningAppState, window: &ServoShellWindow) -> bool {
|
||||
let title = window
|
||||
.active_webview()
|
||||
.and_then(|webview| {
|
||||
webview
|
||||
.page_title()
|
||||
.filter(|title| !title.is_empty())
|
||||
.map(|title| title.to_string())
|
||||
.or_else(|| webview.url().map(|url| url.to_string()))
|
||||
})
|
||||
.unwrap_or_else(|| INITIAL_WINDOW_TITLE.to_string());
|
||||
if title != *self.last_title.borrow() {
|
||||
self.winit_window.set_title(&title);
|
||||
*self.last_title.borrow_mut() = title;
|
||||
}
|
||||
|
||||
self.gui.borrow_mut().update_webview_data(window)
|
||||
}
|
||||
|
||||
fn handle_winit_window_event(
|
||||
pub(crate) fn handle_winit_window_event(
|
||||
&self,
|
||||
state: Rc<RunningAppState>,
|
||||
window: Rc<ServoShellWindow>,
|
||||
@@ -816,7 +756,7 @@ impl PlatformWindow for HeadedWindow {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_winit_app_event(&self, app_event: AppEvent) {
|
||||
pub(crate) fn handle_winit_app_event(&self, app_event: AppEvent) {
|
||||
if let AppEvent::Accessibility(ref event) = app_event {
|
||||
if self
|
||||
.gui
|
||||
@@ -827,6 +767,67 @@ impl PlatformWindow for HeadedWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformWindow for HeadedWindow {
|
||||
fn as_headed_window(&self) -> Option<&Self> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn screen_geometry(&self) -> ScreenGeometry {
|
||||
let hidpi_factor = self.hidpi_scale_factor();
|
||||
let toolbar_size = Size2D::new(0.0, (self.toolbar_height() * self.hidpi_scale_factor()).0);
|
||||
let screen_size = self.screen_size.to_f32() * hidpi_factor;
|
||||
|
||||
// FIXME: In reality, this should subtract screen space used by the system interface
|
||||
// elements, but it is difficult to get this value with `winit` currently. See:
|
||||
// See https://github.com/rust-windowing/winit/issues/2494
|
||||
let available_screen_size = screen_size - toolbar_size;
|
||||
|
||||
let window_rect = DeviceIntRect::from_origin_and_size(
|
||||
winit_position_to_euclid_point(self.winit_window.outer_position().unwrap_or_default()),
|
||||
winit_size_to_euclid_size(self.winit_window.outer_size()).to_i32(),
|
||||
);
|
||||
|
||||
ScreenGeometry {
|
||||
size: screen_size.to_i32(),
|
||||
available_size: available_screen_size.to_i32(),
|
||||
window_rect,
|
||||
}
|
||||
}
|
||||
|
||||
fn device_hidpi_scale_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||
Scale::new(self.winit_window.scale_factor() as f32)
|
||||
}
|
||||
|
||||
fn hidpi_scale_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||
self.device_pixel_ratio_override
|
||||
.map(Scale::new)
|
||||
.unwrap_or_else(|| self.device_hidpi_scale_factor())
|
||||
}
|
||||
|
||||
fn rebuild_user_interface(&self, state: &RunningAppState, window: &ServoShellWindow) {
|
||||
self.gui.borrow_mut().update(state, window, self);
|
||||
}
|
||||
|
||||
fn update_user_interface_state(&self, _: &RunningAppState, window: &ServoShellWindow) -> bool {
|
||||
let title = window
|
||||
.active_webview()
|
||||
.and_then(|webview| {
|
||||
webview
|
||||
.page_title()
|
||||
.filter(|title| !title.is_empty())
|
||||
.map(|title| title.to_string())
|
||||
.or_else(|| webview.url().map(|url| url.to_string()))
|
||||
})
|
||||
.unwrap_or_else(|| INITIAL_WINDOW_TITLE.to_string());
|
||||
if title != *self.last_title.borrow() {
|
||||
self.winit_window.set_title(&title);
|
||||
*self.last_title.borrow_mut() = title;
|
||||
}
|
||||
|
||||
self.gui.borrow_mut().update_webview_data(window)
|
||||
}
|
||||
|
||||
fn request_repaint(&self, window: &ServoShellWindow) {
|
||||
self.winit_window.request_redraw();
|
||||
@@ -1036,6 +1037,10 @@ impl PlatformWindow for HeadedWindow {
|
||||
self.winit_window.focus_window();
|
||||
}
|
||||
|
||||
fn has_platform_focus(&self) -> bool {
|
||||
self.winit_window.has_focus()
|
||||
}
|
||||
|
||||
fn show_embedder_control(&self, webview_id: WebViewId, embedder_control: EmbedderControl) {
|
||||
let control_id = embedder_control.id();
|
||||
match embedder_control {
|
||||
|
||||
@@ -13,7 +13,7 @@ pub(crate) mod event_loop;
|
||||
pub(crate) mod gamepad;
|
||||
pub mod geometry;
|
||||
mod gui;
|
||||
mod headed_window;
|
||||
pub(crate) mod headed_window;
|
||||
mod headless_window;
|
||||
mod keyutils;
|
||||
mod protocols;
|
||||
|
||||
@@ -25,7 +25,7 @@ use crate::prefs::ServoShellPreferences;
|
||||
use crate::running_app_state::{RunningAppState, UserInterfaceCommand};
|
||||
use crate::window::{PlatformWindow, ServoShellWindow, ServoShellWindowId};
|
||||
|
||||
pub(super) struct EmbeddedPlatformWindow {
|
||||
pub(crate) struct EmbeddedPlatformWindow {
|
||||
host: Box<dyn HostTrait>,
|
||||
rendering_context: Rc<WindowRenderingContext>,
|
||||
refresh_driver: Rc<VsyncRefreshDriver>,
|
||||
@@ -47,6 +47,10 @@ pub(super) struct EmbeddedPlatformWindow {
|
||||
}
|
||||
|
||||
impl PlatformWindow for EmbeddedPlatformWindow {
|
||||
fn as_headed_window(&self) -> Option<&Self> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn id(&self) -> ServoShellWindowId {
|
||||
0.into()
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
mod android;
|
||||
mod app;
|
||||
pub(crate) mod app;
|
||||
#[cfg(feature = "gamepad")]
|
||||
pub(crate) mod gamepad;
|
||||
mod host_trait;
|
||||
|
||||
@@ -247,18 +247,17 @@ impl RunningAppState {
|
||||
platform_window: Rc<dyn PlatformWindow>,
|
||||
initial_url: Url,
|
||||
) -> Rc<ServoShellWindow> {
|
||||
let has_winit_window = platform_window.has_winit_window();
|
||||
let window = Rc::new(ServoShellWindow::new(platform_window));
|
||||
|
||||
// For [`HeadedWindow`], it is up to the `winit::event::WindowEvent::Focused`.
|
||||
// Otherwise, newly created windows are automatically focused.
|
||||
if !has_winit_window {
|
||||
self.focus_window(window.clone());
|
||||
}
|
||||
let window = Rc::new(ServoShellWindow::new(platform_window.clone()));
|
||||
window.create_and_activate_toplevel_webview(self.clone(), initial_url);
|
||||
self.windows
|
||||
.borrow_mut()
|
||||
.insert(window.id(), window.clone());
|
||||
|
||||
// If the window already has platform focus, mark it as focused in our application state.
|
||||
if platform_window.has_platform_focus() {
|
||||
self.focus_window(window.clone());
|
||||
}
|
||||
|
||||
window
|
||||
}
|
||||
|
||||
|
||||
@@ -366,26 +366,6 @@ pub(crate) trait PlatformWindow {
|
||||
fn update_user_interface_state(&self, _: &RunningAppState, _: &ServoShellWindow) -> bool {
|
||||
false
|
||||
}
|
||||
/// Handle a winit [`WindowEvent`]. Returns `true` if the event loop should continue
|
||||
/// and `false` otherwise.
|
||||
///
|
||||
/// TODO: This should be handled internally in the winit window if possible so that it
|
||||
/// makes more sense when we are mixing headed and headless windows.
|
||||
#[cfg(not(any(target_os = "android", target_env = "ohos")))]
|
||||
fn handle_winit_window_event(
|
||||
&self,
|
||||
_: Rc<RunningAppState>,
|
||||
_: Rc<ServoShellWindow>,
|
||||
_: winit::event::WindowEvent,
|
||||
) {
|
||||
}
|
||||
/// Handle a winit [`AppEvent`]. Returns `true` if the event loop should continue and
|
||||
/// `false` otherwise.
|
||||
///
|
||||
/// TODO: This should be handled internally in the winit window if possible so that it
|
||||
/// makes more sense when we are mixing headed and headless windows.
|
||||
#[cfg(not(any(target_os = "android", target_env = "ohos")))]
|
||||
fn handle_winit_app_event(&self, _: crate::desktop::event_loop::AppEvent) {}
|
||||
/// Request that the window redraw itself. It is up to the window to do this
|
||||
/// once the windowing system is ready. If this is a headless window, the redraw
|
||||
/// will happen immediately.
|
||||
@@ -413,6 +393,9 @@ pub(crate) trait PlatformWindow {
|
||||
fn window_rect(&self) -> DeviceIndependentIntRect;
|
||||
fn maximize(&self, _: &WebView) {}
|
||||
fn focus(&self) {}
|
||||
fn has_platform_focus(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn show_embedder_control(&self, _: WebViewId, _: EmbedderControl) {}
|
||||
fn hide_embedder_control(&self, _: WebViewId, _: EmbedderControlId) {}
|
||||
@@ -438,7 +421,16 @@ pub(crate) trait PlatformWindow {
|
||||
fn notify_media_session_event(&self, _: MediaSessionEvent) {}
|
||||
fn notify_crashed(&self, _: WebView, _reason: String, _backtrace: Option<String>) {}
|
||||
fn show_console_message(&self, _level: ConsoleLogLevel, _message: &str) {}
|
||||
fn has_winit_window(&self) -> bool {
|
||||
false
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_env = "ohos")))]
|
||||
/// If this window is a headed window, access the concrete type.
|
||||
fn as_headed_window(&self) -> Option<&crate::desktop::headed_window::HeadedWindow> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_env = "ohos"))]
|
||||
/// If this window is a headed window, access the concrete type.
|
||||
fn as_headed_window(&self) -> Option<&crate::egl::app::EmbeddedPlatformWindow> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user