mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
libservo: Start moving WindowMethods
to WebViewDelegate
(#36223)
`WindowMethods` is used by the embedding layer to get information from the embedder. This change moves the functionality for getting screen size and `WebView` offsets to `WebViewDelegate`. This is important because `WebView`s might be on different screens or have different offsets on the screen itself, so it makes sense for this to be per-`WebView` and not global to the embedder. HiDPI and animation state functionality will move to the embedder in subsequent changes. Signed-off-by: Martin Robinson <mrobinson@igalia.com> <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes do not require tests because they just modify the `WebView` API surface a bit. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
520a7f7bc5
commit
b925c31424
17 changed files with 235 additions and 183 deletions
|
@ -26,7 +26,8 @@ use constellation_traits::{
|
||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
use dpi::PhysicalSize;
|
use dpi::PhysicalSize;
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
Cursor, InputEvent, MouseButtonEvent, MouseMoveEvent, ShutdownState, TouchEventType,
|
Cursor, InputEvent, MouseButtonEvent, MouseMoveEvent, ScreenGeometry, ShutdownState,
|
||||||
|
TouchEventType,
|
||||||
};
|
};
|
||||||
use euclid::{Box2D, Point2D, Rect, Scale, Size2D, Transform3D};
|
use euclid::{Box2D, Point2D, Rect, Scale, Size2D, Transform3D};
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
|
@ -54,11 +55,11 @@ use webrender_api::{
|
||||||
};
|
};
|
||||||
use webrender_traits::display_list::{HitTestInfo, ScrollTree};
|
use webrender_traits::display_list::{HitTestInfo, ScrollTree};
|
||||||
use webrender_traits::rendering_context::RenderingContext;
|
use webrender_traits::rendering_context::RenderingContext;
|
||||||
use webrender_traits::{CrossProcessCompositorMessage, ImageUpdate};
|
use webrender_traits::{CrossProcessCompositorMessage, ImageUpdate, RendererWebView};
|
||||||
|
|
||||||
use crate::InitialCompositorState;
|
use crate::InitialCompositorState;
|
||||||
use crate::webview::{UnknownWebView, WebView, WebViewManager};
|
use crate::webview::{UnknownWebView, WebView, WebViewManager};
|
||||||
use crate::windowing::{self, EmbedderCoordinates, WebRenderDebugOption, WindowMethods};
|
use crate::windowing::{self, WebRenderDebugOption, WindowMethods};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum UnableToComposite {
|
enum UnableToComposite {
|
||||||
|
@ -167,8 +168,9 @@ pub struct IOCompositor {
|
||||||
/// The surfman instance that webrender targets
|
/// The surfman instance that webrender targets
|
||||||
rendering_context: Rc<dyn RenderingContext>,
|
rendering_context: Rc<dyn RenderingContext>,
|
||||||
|
|
||||||
/// The coordinates of the native window, its view and the screen.
|
/// The HighDPI factor of the native window, its view and the screen.
|
||||||
embedder_coordinates: EmbedderCoordinates,
|
/// TODO: Eventually this should be a property of the `WebView`.
|
||||||
|
hidpi_factor: Scale<f32, DeviceIndependentPixel, DevicePixel>,
|
||||||
|
|
||||||
/// The number of frames pending to receive from WebRender.
|
/// The number of frames pending to receive from WebRender.
|
||||||
pending_frames: usize,
|
pending_frames: usize,
|
||||||
|
@ -442,7 +444,7 @@ impl IOCompositor {
|
||||||
cursor_pos: DevicePoint::new(0.0, 0.0),
|
cursor_pos: DevicePoint::new(0.0, 0.0),
|
||||||
})),
|
})),
|
||||||
webviews: WebViewManager::default(),
|
webviews: WebViewManager::default(),
|
||||||
embedder_coordinates: window.get_coordinates(),
|
hidpi_factor: window.hidpi_factor(),
|
||||||
window,
|
window,
|
||||||
needs_repaint: Cell::default(),
|
needs_repaint: Cell::default(),
|
||||||
page_zoom: Scale::new(1.0),
|
page_zoom: Scale::new(1.0),
|
||||||
|
@ -895,27 +897,46 @@ impl IOCompositor {
|
||||||
.collect();
|
.collect();
|
||||||
let _ = result_sender.send((font_keys, font_instance_keys));
|
let _ = result_sender.send((font_keys, font_instance_keys));
|
||||||
},
|
},
|
||||||
CrossProcessCompositorMessage::GetClientWindowRect(req) => {
|
CrossProcessCompositorMessage::GetClientWindowRect(webview_id, response_sender) => {
|
||||||
if let Err(e) = req.send(self.embedder_coordinates.window_rect) {
|
let screen_geometry = self.webview_screen_geometry(webview_id);
|
||||||
warn!("Sending response to get client window failed ({:?}).", e);
|
let rect = DeviceIntRect::from_origin_and_size(
|
||||||
|
screen_geometry.offset,
|
||||||
|
self.rendering_context.size2d().to_i32(),
|
||||||
|
)
|
||||||
|
.to_f32() /
|
||||||
|
self.hidpi_factor;
|
||||||
|
|
||||||
|
if let Err(error) = response_sender.send(rect.to_i32()) {
|
||||||
|
warn!("Sending response to get client window failed ({error:?}).");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CrossProcessCompositorMessage::GetScreenSize(req) => {
|
CrossProcessCompositorMessage::GetScreenSize(webview_id, response_sender) => {
|
||||||
if let Err(e) = req.send(self.embedder_coordinates.screen_size) {
|
let screen_geometry = self.webview_screen_geometry(webview_id);
|
||||||
warn!("Sending response to get screen size failed ({:?}).", e);
|
let screen_size = screen_geometry.size.to_f32() / self.hidpi_factor;
|
||||||
|
|
||||||
|
if let Err(error) = response_sender.send(screen_size.to_i32()) {
|
||||||
|
warn!("Sending response to get screen size failed ({error:?}).");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CrossProcessCompositorMessage::GetAvailableScreenSize(req) => {
|
CrossProcessCompositorMessage::GetAvailableScreenSize(webview_id, response_sender) => {
|
||||||
if let Err(e) = req.send(self.embedder_coordinates.available_screen_size) {
|
let screen_geometry = self.webview_screen_geometry(webview_id);
|
||||||
warn!(
|
let available_screen_size =
|
||||||
"Sending response to get screen avail size failed ({:?}).",
|
screen_geometry.available_size.to_f32() / self.hidpi_factor;
|
||||||
e
|
|
||||||
);
|
if let Err(error) = response_sender.send(available_screen_size.to_i32()) {
|
||||||
|
warn!("Sending response to get screen size failed ({error:?}).");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn webview_screen_geometry(&self, webview_id: WebViewId) -> ScreenGeometry {
|
||||||
|
self.webviews
|
||||||
|
.get(webview_id)
|
||||||
|
.and_then(|webview| webview.renderer_webview.screen_geometry())
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
/// Handle messages sent to the compositor during the shutdown process. In general,
|
/// Handle messages sent to the compositor during the shutdown process. In general,
|
||||||
/// the things the compositor can do in this state are limited. It's very important to
|
/// the things the compositor can do in this state are limited. It's very important to
|
||||||
/// answer any synchronous messages though as other threads might be waiting on the
|
/// answer any synchronous messages though as other threads might be waiting on the
|
||||||
|
@ -961,25 +982,27 @@ impl IOCompositor {
|
||||||
let _ = result_sender.send((font_keys, font_instance_keys));
|
let _ = result_sender.send((font_keys, font_instance_keys));
|
||||||
},
|
},
|
||||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetClientWindowRect(
|
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetClientWindowRect(
|
||||||
req,
|
_,
|
||||||
|
response_sender,
|
||||||
)) => {
|
)) => {
|
||||||
if let Err(e) = req.send(self.embedder_coordinates.window_rect) {
|
if let Err(error) = response_sender.send(Default::default()) {
|
||||||
warn!("Sending response to get client window failed ({:?}).", e);
|
warn!("Sending response to get client window failed ({error:?}).");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetScreenSize(req)) => {
|
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetScreenSize(
|
||||||
if let Err(e) = req.send(self.embedder_coordinates.screen_size) {
|
_,
|
||||||
warn!("Sending response to get screen size failed ({:?}).", e);
|
response_sender,
|
||||||
|
)) => {
|
||||||
|
if let Err(error) = response_sender.send(Default::default()) {
|
||||||
|
warn!("Sending response to get client window failed ({error:?}).");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetAvailableScreenSize(
|
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetAvailableScreenSize(
|
||||||
req,
|
_,
|
||||||
|
response_sender,
|
||||||
)) => {
|
)) => {
|
||||||
if let Err(e) = req.send(self.embedder_coordinates.available_screen_size) {
|
if let Err(error) = response_sender.send(Default::default()) {
|
||||||
warn!(
|
warn!("Sending response to get client window failed ({error:?}).");
|
||||||
"Sending response to get screen avail size failed ({:?}).",
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::NewWebRenderFrameReady(..) => {
|
CompositorMsg::NewWebRenderFrameReady(..) => {
|
||||||
|
@ -1102,10 +1125,10 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_webview(&mut self, webview_id: WebViewId) {
|
pub fn add_webview(&mut self, webview: Box<dyn RendererWebView>) {
|
||||||
let size = self.rendering_context.size2d().to_f32();
|
let size = self.rendering_context.size2d().to_f32();
|
||||||
self.webviews.entry(webview_id).or_insert(WebView::new(
|
self.webviews.entry(webview.id()).or_insert(WebView::new(
|
||||||
webview_id,
|
webview,
|
||||||
Box2D::from_origin_and_size(Point2D::origin(), size),
|
Box2D::from_origin_and_size(Point2D::origin(), size),
|
||||||
self.global.clone(),
|
self.global.clone(),
|
||||||
));
|
));
|
||||||
|
@ -1239,20 +1262,14 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_embedder_window_moved(&mut self) {
|
|
||||||
self.embedder_coordinates = self.window.get_coordinates();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resize_rendering_context(&mut self, new_size: PhysicalSize<u32>) -> bool {
|
pub fn resize_rendering_context(&mut self, new_size: PhysicalSize<u32>) -> bool {
|
||||||
if self.global.borrow().shutdown_state() != ShutdownState::NotShuttingDown {
|
if self.global.borrow().shutdown_state() != ShutdownState::NotShuttingDown {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let old_hidpi_factor = self.embedder_coordinates.hidpi_factor;
|
let old_hidpi_factor = self.hidpi_factor;
|
||||||
self.embedder_coordinates = self.window.get_coordinates();
|
self.hidpi_factor = self.window.hidpi_factor();
|
||||||
if self.embedder_coordinates.hidpi_factor == old_hidpi_factor &&
|
if self.hidpi_factor == old_hidpi_factor && self.rendering_context.size() == new_size {
|
||||||
self.rendering_context.size() == new_size
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1303,10 +1320,6 @@ impl IOCompositor {
|
||||||
self.window.set_animation_state(animation_state);
|
self.window.set_animation_state(animation_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
|
||||||
self.embedder_coordinates.hidpi_factor
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn device_pixels_per_page_pixel(&self) -> Scale<f32, CSSPixel, DevicePixel> {
|
pub(crate) fn device_pixels_per_page_pixel(&self) -> Scale<f32, CSSPixel, DevicePixel> {
|
||||||
self.device_pixels_per_page_pixel_not_including_page_zoom() * self.pinch_zoom_level()
|
self.device_pixels_per_page_pixel_not_including_page_zoom() * self.pinch_zoom_level()
|
||||||
}
|
}
|
||||||
|
@ -1314,7 +1327,7 @@ impl IOCompositor {
|
||||||
fn device_pixels_per_page_pixel_not_including_page_zoom(
|
fn device_pixels_per_page_pixel_not_including_page_zoom(
|
||||||
&self,
|
&self,
|
||||||
) -> Scale<f32, CSSPixel, DevicePixel> {
|
) -> Scale<f32, CSSPixel, DevicePixel> {
|
||||||
self.page_zoom * self.hidpi_factor()
|
self.page_zoom * self.hidpi_factor
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_zoom_reset_window_event(&mut self) {
|
pub fn on_zoom_reset_window_event(&mut self) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ use webrender_api::units::{DeviceIntPoint, DevicePoint, DeviceRect, LayoutVector
|
||||||
use webrender_api::{
|
use webrender_api::{
|
||||||
ExternalScrollId, HitTestFlags, RenderReasons, SampledScrollOffset, ScrollLocation,
|
ExternalScrollId, HitTestFlags, RenderReasons, SampledScrollOffset, ScrollLocation,
|
||||||
};
|
};
|
||||||
|
use webrender_traits::RendererWebView;
|
||||||
|
|
||||||
use crate::IOCompositor;
|
use crate::IOCompositor;
|
||||||
use crate::compositor::{PipelineDetails, ServoRenderer};
|
use crate::compositor::{PipelineDetails, ServoRenderer};
|
||||||
|
@ -50,6 +51,10 @@ enum ScrollZoomEvent {
|
||||||
pub(crate) struct WebView {
|
pub(crate) struct WebView {
|
||||||
/// The [`WebViewId`] of the `WebView` associated with this [`WebViewDetails`].
|
/// The [`WebViewId`] of the `WebView` associated with this [`WebViewDetails`].
|
||||||
pub id: WebViewId,
|
pub id: WebViewId,
|
||||||
|
/// The renderer's view of the embedding layer `WebView` as a trait implementation,
|
||||||
|
/// so that the renderer doesn't need to depend on the embedding layer. This avoids
|
||||||
|
/// a dependency cycle.
|
||||||
|
pub renderer_webview: Box<dyn RendererWebView>,
|
||||||
/// The root [`PipelineId`] of the currently displayed page in this WebView.
|
/// The root [`PipelineId`] of the currently displayed page in this WebView.
|
||||||
pub root_pipeline_id: Option<PipelineId>,
|
pub root_pipeline_id: Option<PipelineId>,
|
||||||
pub rect: DeviceRect,
|
pub rect: DeviceRect,
|
||||||
|
@ -73,9 +78,14 @@ impl Drop for WebView {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebView {
|
impl WebView {
|
||||||
pub(crate) fn new(id: WebViewId, rect: DeviceRect, global: Rc<RefCell<ServoRenderer>>) -> Self {
|
pub(crate) fn new(
|
||||||
|
renderer_webview: Box<dyn RendererWebView>,
|
||||||
|
rect: DeviceRect,
|
||||||
|
global: Rc<RefCell<ServoRenderer>>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id: renderer_webview.id(),
|
||||||
|
renderer_webview,
|
||||||
root_pipeline_id: None,
|
root_pipeline_id: None,
|
||||||
rect,
|
rect,
|
||||||
pipelines: Default::default(),
|
pipelines: Default::default(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::fmt::Debug;
|
||||||
use embedder_traits::{EventLoopWaker, MouseButton};
|
use embedder_traits::{EventLoopWaker, MouseButton};
|
||||||
use euclid::Scale;
|
use euclid::Scale;
|
||||||
use net::protocols::ProtocolRegistry;
|
use net::protocols::ProtocolRegistry;
|
||||||
use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize, DeviceIndependentPixel};
|
use servo_geometry::DeviceIndependentPixel;
|
||||||
use webrender_api::units::{DevicePixel, DevicePoint};
|
use webrender_api::units::{DevicePixel, DevicePoint};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -37,12 +37,14 @@ pub enum AnimationState {
|
||||||
// for creating the GL context, making it current, buffer
|
// for creating the GL context, making it current, buffer
|
||||||
// swapping, etc. Really that should all be done by surfman.
|
// swapping, etc. Really that should all be done by surfman.
|
||||||
pub trait WindowMethods {
|
pub trait WindowMethods {
|
||||||
/// Get the coordinates of the native window, the screen and the framebuffer.
|
/// Get the HighDPI factor of the native window, the screen and the framebuffer.
|
||||||
fn get_coordinates(&self) -> EmbedderCoordinates;
|
/// TODO(martin): Move this to `RendererWebView` when possible.
|
||||||
|
fn hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel>;
|
||||||
/// Set whether the application is currently animating.
|
/// Set whether the application is currently animating.
|
||||||
/// Typically, when animations are active, the window
|
/// Typically, when animations are active, the window
|
||||||
/// will want to avoid blocking on UI events, and just
|
/// will want to avoid blocking on UI events, and just
|
||||||
/// run the event loop at the vsync interval.
|
/// run the event loop at the vsync interval.
|
||||||
|
/// TODO(martin): Move this to `RendererWebView` when possible.
|
||||||
fn set_animation_state(&self, _state: AnimationState);
|
fn set_animation_state(&self, _state: AnimationState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,15 +67,3 @@ pub trait EmbedderMethods {
|
||||||
ProtocolRegistry::default()
|
ProtocolRegistry::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub struct EmbedderCoordinates {
|
|
||||||
/// The pixel density of the display.
|
|
||||||
pub hidpi_factor: Scale<f32, DeviceIndependentPixel, DevicePixel>,
|
|
||||||
/// Size of the screen.
|
|
||||||
pub screen_size: DeviceIndependentIntSize,
|
|
||||||
/// Size of the available screen space (screen without toolbars and docks).
|
|
||||||
pub available_screen_size: DeviceIndependentIntSize,
|
|
||||||
/// Position and size of the native window.
|
|
||||||
pub window_rect: DeviceIndependentIntRect,
|
|
||||||
}
|
|
||||||
|
|
|
@ -35,28 +35,34 @@ impl Screen {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn screen_size(&self) -> Size2D<u32, CSSPixel> {
|
fn screen_size(&self) -> Size2D<u32, CSSPixel> {
|
||||||
let (send, recv) =
|
let (sender, receiver) =
|
||||||
ipc::channel::<DeviceIndependentIntSize>(self.global().time_profiler_chan().clone())
|
ipc::channel::<DeviceIndependentIntSize>(self.global().time_profiler_chan().clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.window
|
self.window
|
||||||
.compositor_api()
|
.compositor_api()
|
||||||
.sender()
|
.sender()
|
||||||
.send(CrossProcessCompositorMessage::GetScreenSize(send))
|
.send(CrossProcessCompositorMessage::GetScreenSize(
|
||||||
|
self.window.webview_id(),
|
||||||
|
sender,
|
||||||
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let size = recv.recv().unwrap_or(Size2D::zero()).to_u32();
|
let size = receiver.recv().unwrap_or(Size2D::zero()).to_u32();
|
||||||
Size2D::new(size.width, size.height)
|
Size2D::new(size.width, size.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn screen_avail_size(&self) -> Size2D<u32, CSSPixel> {
|
fn screen_avail_size(&self) -> Size2D<u32, CSSPixel> {
|
||||||
let (send, recv) =
|
let (sender, receiver) =
|
||||||
ipc::channel::<DeviceIndependentIntSize>(self.global().time_profiler_chan().clone())
|
ipc::channel::<DeviceIndependentIntSize>(self.global().time_profiler_chan().clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.window
|
self.window
|
||||||
.compositor_api()
|
.compositor_api()
|
||||||
.sender()
|
.sender()
|
||||||
.send(CrossProcessCompositorMessage::GetAvailableScreenSize(send))
|
.send(CrossProcessCompositorMessage::GetAvailableScreenSize(
|
||||||
|
self.window.webview_id(),
|
||||||
|
sender,
|
||||||
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let size = recv.recv().unwrap_or(Size2D::zero()).to_u32();
|
let size = receiver.recv().unwrap_or(Size2D::zero()).to_u32();
|
||||||
Size2D::new(size.width, size.height)
|
Size2D::new(size.width, size.height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1859,13 +1859,15 @@ impl Window {
|
||||||
|
|
||||||
fn client_window(&self) -> (Size2D<u32, CSSPixel>, Point2D<i32, CSSPixel>) {
|
fn client_window(&self) -> (Size2D<u32, CSSPixel>, Point2D<i32, CSSPixel>) {
|
||||||
let timer_profile_chan = self.global().time_profiler_chan().clone();
|
let timer_profile_chan = self.global().time_profiler_chan().clone();
|
||||||
let (send, recv) =
|
let (sender, receiver) =
|
||||||
ProfiledIpc::channel::<DeviceIndependentIntRect>(timer_profile_chan).unwrap();
|
ProfiledIpc::channel::<DeviceIndependentIntRect>(timer_profile_chan).unwrap();
|
||||||
let _ = self
|
let _ = self.compositor_api.sender().send(
|
||||||
.compositor_api
|
webrender_traits::CrossProcessCompositorMessage::GetClientWindowRect(
|
||||||
.sender()
|
self.webview_id(),
|
||||||
.send(webrender_traits::CrossProcessCompositorMessage::GetClientWindowRect(send));
|
sender,
|
||||||
let rect = recv.recv().unwrap_or_default();
|
),
|
||||||
|
);
|
||||||
|
let rect = receiver.recv().unwrap_or_default();
|
||||||
(
|
(
|
||||||
Size2D::new(rect.size().width as u32, rect.size().height as u32),
|
Size2D::new(rect.size().width as u32, rect.size().height as u32),
|
||||||
Point2D::new(rect.min.x, rect.min.y),
|
Point2D::new(rect.min.x, rect.min.y),
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
@ -13,7 +12,7 @@ use servo_geometry::DeviceIndependentPixel;
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use webrender_api::ScrollLocation;
|
use webrender_api::ScrollLocation;
|
||||||
use webrender_api::units::{DeviceIntPoint, DeviceIntRect, DevicePixel, LayoutVector2D};
|
use webrender_api::units::{DeviceIntPoint, DevicePixel, LayoutVector2D};
|
||||||
use winit::application::ApplicationHandler;
|
use winit::application::ApplicationHandler;
|
||||||
use winit::dpi::{PhysicalPosition, PhysicalSize};
|
use winit::dpi::{PhysicalPosition, PhysicalSize};
|
||||||
use winit::event::{MouseScrollDelta, WindowEvent};
|
use winit::event::{MouseScrollDelta, WindowEvent};
|
||||||
|
@ -250,26 +249,8 @@ impl WindowDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowMethods for WindowDelegate {
|
impl WindowMethods for WindowDelegate {
|
||||||
fn get_coordinates(&self) -> compositing::windowing::EmbedderCoordinates {
|
fn hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||||
let monitor = self
|
Scale::new(self.window.scale_factor() as f32)
|
||||||
.window
|
|
||||||
.current_monitor()
|
|
||||||
.or_else(|| self.window.available_monitors().nth(0))
|
|
||||||
.expect("Failed to get winit monitor");
|
|
||||||
let scale =
|
|
||||||
Scale::<f64, DeviceIndependentPixel, DevicePixel>::new(self.window.scale_factor());
|
|
||||||
let window_size = winit_size_to_euclid_size(self.window.outer_size()).to_i32();
|
|
||||||
let window_origin = self.window.outer_position().unwrap_or_default();
|
|
||||||
let window_origin = winit_position_to_euclid_point(window_origin).to_i32();
|
|
||||||
let window_rect = DeviceIntRect::from_origin_and_size(window_origin, window_size);
|
|
||||||
|
|
||||||
compositing::windowing::EmbedderCoordinates {
|
|
||||||
hidpi_factor: Scale::new(self.window.scale_factor() as f32),
|
|
||||||
screen_size: (winit_size_to_euclid_size(monitor.size()).to_f64() / scale).to_i32(),
|
|
||||||
available_screen_size: (winit_size_to_euclid_size(monitor.size()).to_f64() / scale)
|
|
||||||
.to_i32(),
|
|
||||||
window_rect: (window_rect.to_f64() / scale).to_i32(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_animation_state(&self, state: compositing::windowing::AnimationState) {
|
fn set_animation_state(&self, state: compositing::windowing::AnimationState) {
|
||||||
|
|
|
@ -321,8 +321,7 @@ impl Servo {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let coordinates: compositing::windowing::EmbedderCoordinates = window.get_coordinates();
|
let device_pixel_ratio = window.hidpi_factor().get();
|
||||||
let device_pixel_ratio = coordinates.hidpi_factor.get();
|
|
||||||
let viewport_size = rendering_context.size2d();
|
let viewport_size = rendering_context.size2d();
|
||||||
|
|
||||||
let (mut webrender, webrender_api_sender) = {
|
let (mut webrender, webrender_api_sender) = {
|
||||||
|
|
|
@ -13,11 +13,12 @@ use compositing::windowing::WebRenderDebugOption;
|
||||||
use constellation_traits::{ConstellationMsg, TraversalDirection};
|
use constellation_traits::{ConstellationMsg, TraversalDirection};
|
||||||
use dpi::PhysicalSize;
|
use dpi::PhysicalSize;
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
Cursor, InputEvent, LoadStatus, MediaSessionActionType, Theme, TouchEventType,
|
Cursor, InputEvent, LoadStatus, MediaSessionActionType, ScreenGeometry, Theme, TouchEventType,
|
||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use webrender_api::ScrollLocation;
|
use webrender_api::ScrollLocation;
|
||||||
use webrender_api::units::{DeviceIntPoint, DeviceRect};
|
use webrender_api::units::{DeviceIntPoint, DeviceRect};
|
||||||
|
use webrender_traits::RendererWebView;
|
||||||
|
|
||||||
use crate::ConstellationProxy;
|
use crate::ConstellationProxy;
|
||||||
use crate::clipboard_delegate::{ClipboardDelegate, DefaultClipboardDelegate};
|
use crate::clipboard_delegate::{ClipboardDelegate, DefaultClipboardDelegate};
|
||||||
|
@ -96,11 +97,10 @@ impl WebView {
|
||||||
compositor: Rc<RefCell<IOCompositor>>,
|
compositor: Rc<RefCell<IOCompositor>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let id = WebViewId::new();
|
let id = WebViewId::new();
|
||||||
compositor.borrow_mut().add_webview(id);
|
let webview = Self(Rc::new(RefCell::new(WebViewInner {
|
||||||
Self(Rc::new(RefCell::new(WebViewInner {
|
|
||||||
id,
|
id,
|
||||||
constellation_proxy: constellation_proxy.clone(),
|
constellation_proxy: constellation_proxy.clone(),
|
||||||
compositor,
|
compositor: compositor.clone(),
|
||||||
delegate: Rc::new(DefaultWebViewDelegate),
|
delegate: Rc::new(DefaultWebViewDelegate),
|
||||||
clipboard_delegate: Rc::new(DefaultClipboardDelegate),
|
clipboard_delegate: Rc::new(DefaultClipboardDelegate),
|
||||||
rect: DeviceRect::zero(),
|
rect: DeviceRect::zero(),
|
||||||
|
@ -111,7 +111,16 @@ impl WebView {
|
||||||
favicon_url: None,
|
favicon_url: None,
|
||||||
focused: false,
|
focused: false,
|
||||||
cursor: Cursor::Pointer,
|
cursor: Cursor::Pointer,
|
||||||
})))
|
})));
|
||||||
|
|
||||||
|
compositor
|
||||||
|
.borrow_mut()
|
||||||
|
.add_webview(Box::new(ServoRendererWebView {
|
||||||
|
weak_handle: webview.weak_handle(),
|
||||||
|
id,
|
||||||
|
}));
|
||||||
|
|
||||||
|
webview
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inner(&self) -> Ref<'_, WebViewInner> {
|
fn inner(&self) -> Ref<'_, WebViewInner> {
|
||||||
|
@ -382,13 +391,6 @@ impl WebView {
|
||||||
.resize_rendering_context(new_size);
|
.resize_rendering_context(new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn notify_embedder_window_moved(&self) {
|
|
||||||
self.inner()
|
|
||||||
.compositor
|
|
||||||
.borrow_mut()
|
|
||||||
.on_embedder_window_moved();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_zoom(&self, new_zoom: f32) {
|
pub fn set_zoom(&self, new_zoom: f32) {
|
||||||
self.inner()
|
self.inner()
|
||||||
.compositor
|
.compositor
|
||||||
|
@ -452,3 +454,21 @@ impl WebView {
|
||||||
self.inner().compositor.borrow_mut().render()
|
self.inner().compositor.borrow_mut().render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A structure used to expose a view of the [`WebView`] to the Servo
|
||||||
|
/// renderer, without having the Servo renderer depend on the embedding layer.
|
||||||
|
struct ServoRendererWebView {
|
||||||
|
id: WebViewId,
|
||||||
|
weak_handle: Weak<RefCell<WebViewInner>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RendererWebView for ServoRendererWebView {
|
||||||
|
fn screen_geometry(&self) -> Option<ScreenGeometry> {
|
||||||
|
let webview = WebView::from_weak_handle(&self.weak_handle)?;
|
||||||
|
webview.delegate().screen_geometry(webview)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id(&self) -> WebViewId {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use constellation_traits::ConstellationMsg;
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
AllowOrDeny, AuthenticationResponse, ContextMenuResult, Cursor, FilterPattern,
|
AllowOrDeny, AuthenticationResponse, ContextMenuResult, Cursor, FilterPattern,
|
||||||
GamepadHapticEffectType, InputMethodType, LoadStatus, MediaSessionEvent, Notification,
|
GamepadHapticEffectType, InputMethodType, LoadStatus, MediaSessionEvent, Notification,
|
||||||
PermissionFeature, SimpleDialog, WebResourceRequest, WebResourceResponse,
|
PermissionFeature, ScreenGeometry, SimpleDialog, WebResourceRequest, WebResourceResponse,
|
||||||
WebResourceResponseMsg,
|
WebResourceResponseMsg,
|
||||||
};
|
};
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
@ -297,6 +297,12 @@ impl Drop for InterceptedWebResourceLoad {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait WebViewDelegate {
|
pub trait WebViewDelegate {
|
||||||
|
/// Get the [`ScreenGeometry`] for this [`WebView`]. If this is unimplemented or returns `None`
|
||||||
|
/// the screen will have the size of the [`WebView`]'s `RenderingContext` and `WebView` will be
|
||||||
|
/// considered to be positioned at the screen's origin.
|
||||||
|
fn screen_geometry(&self, _webview: WebView) -> Option<ScreenGeometry> {
|
||||||
|
None
|
||||||
|
}
|
||||||
/// The URL of the currently loaded page in this [`WebView`] has changed. The new
|
/// The URL of the currently loaded page in this [`WebView`] has changed. The new
|
||||||
/// URL can accessed via [`WebView::url`].
|
/// URL can accessed via [`WebView::url`].
|
||||||
fn notify_url_changed(&self, _webview: WebView, _url: Url) {}
|
fn notify_url_changed(&self, _webview: WebView, _url: Url) {}
|
||||||
|
|
|
@ -636,3 +636,22 @@ pub struct NotificationAction {
|
||||||
/// Icon's raw image data and metadata.
|
/// Icon's raw image data and metadata.
|
||||||
pub icon_resource: Option<Arc<Image>>,
|
pub icon_resource: Option<Arc<Image>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Information about a `WebView`'s screen geometry and offset. This is used
|
||||||
|
/// for the [Screen](https://drafts.csswg.org/cssom-view/#the-screen-interface)
|
||||||
|
/// CSSOM APIs and `window.screenLeft` / `window.screenTop`.
|
||||||
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
|
pub struct ScreenGeometry {
|
||||||
|
/// The size of the screen in device pixels. This will be converted to
|
||||||
|
/// CSS pixels based on the pixel scaling of the `WebView`.
|
||||||
|
pub size: DeviceIntSize,
|
||||||
|
/// The available size of the screen in device pixels. This size is the size
|
||||||
|
/// available for web content on the screen, and should be `size` minus any system
|
||||||
|
/// toolbars, docks, and interface elements of the browser. This will be converted to
|
||||||
|
/// CSS pixels based on the pixel scaling of the `WebView`.
|
||||||
|
pub available_size: DeviceIntSize,
|
||||||
|
/// The offset of the `WebView` in device pixels for the purposes of the `window.screenLeft`
|
||||||
|
/// and `window.screenTop` APIs. This will be converted to CSS pixels based on the pixel scaling
|
||||||
|
/// of the `WebView`.
|
||||||
|
pub offset: DeviceIntPoint,
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use std::sync::{Arc, Mutex};
|
||||||
use base::id::WebViewId;
|
use base::id::WebViewId;
|
||||||
use constellation_traits::CompositorHitTestResult;
|
use constellation_traits::CompositorHitTestResult;
|
||||||
use display_list::CompositorDisplayListInfo;
|
use display_list::CompositorDisplayListInfo;
|
||||||
|
use embedder_traits::ScreenGeometry;
|
||||||
use euclid::default::Size2D as UntypedSize2D;
|
use euclid::default::Size2D as UntypedSize2D;
|
||||||
use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory};
|
use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
@ -82,12 +83,12 @@ pub enum CrossProcessCompositorMessage {
|
||||||
RemoveFonts(Vec<FontKey>, Vec<FontInstanceKey>),
|
RemoveFonts(Vec<FontKey>, Vec<FontInstanceKey>),
|
||||||
|
|
||||||
/// Get the client window size and position.
|
/// Get the client window size and position.
|
||||||
GetClientWindowRect(IpcSender<DeviceIndependentIntRect>),
|
GetClientWindowRect(WebViewId, IpcSender<DeviceIndependentIntRect>),
|
||||||
/// Get the size of the screen that the client window inhabits.
|
/// Get the size of the screen that the client window inhabits.
|
||||||
GetScreenSize(IpcSender<DeviceIndependentIntSize>),
|
GetScreenSize(WebViewId, IpcSender<DeviceIndependentIntSize>),
|
||||||
/// Get the available screen size (without toolbars and docks) for the screen
|
/// Get the available screen size (without toolbars and docks) for the screen
|
||||||
/// the client window inhabits.
|
/// the client window inhabits.
|
||||||
GetAvailableScreenSize(IpcSender<DeviceIndependentIntSize>),
|
GetAvailableScreenSize(WebViewId, IpcSender<DeviceIndependentIntSize>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for CrossProcessCompositorMessage {
|
impl fmt::Debug for CrossProcessCompositorMessage {
|
||||||
|
@ -478,3 +479,11 @@ impl From<SerializableImageData> for ImageData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A trait that exposes the embedding layer's `WebView` to the Servo renderer.
|
||||||
|
/// This is to prevent a dependency cycle between the renderer and the embedding
|
||||||
|
/// layer.
|
||||||
|
pub trait RendererWebView {
|
||||||
|
fn id(&self) -> WebViewId;
|
||||||
|
fn screen_geometry(&self) -> Option<ScreenGeometry>;
|
||||||
|
}
|
||||||
|
|
|
@ -11,13 +11,16 @@ use std::rc::Rc;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::{env, fs};
|
use std::{env, fs};
|
||||||
|
|
||||||
|
use euclid::Scale;
|
||||||
use log::{info, trace, warn};
|
use log::{info, trace, warn};
|
||||||
use servo::compositing::windowing::{AnimationState, WindowMethods};
|
use servo::compositing::windowing::{AnimationState, WindowMethods};
|
||||||
use servo::config::opts::Opts;
|
use servo::config::opts::Opts;
|
||||||
use servo::config::prefs::Preferences;
|
use servo::config::prefs::Preferences;
|
||||||
use servo::servo_config::pref;
|
use servo::servo_config::pref;
|
||||||
|
use servo::servo_geometry::DeviceIndependentPixel;
|
||||||
use servo::servo_url::ServoUrl;
|
use servo::servo_url::ServoUrl;
|
||||||
use servo::user_content_manager::{UserContentManager, UserScript};
|
use servo::user_content_manager::{UserContentManager, UserScript};
|
||||||
|
use servo::webrender_api::units::DevicePixel;
|
||||||
use servo::webxr::glwindow::GlWindowDiscovery;
|
use servo::webxr::glwindow::GlWindowDiscovery;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use servo::webxr::openxr::{AppInfo, OpenXrDiscovery};
|
use servo::webxr::openxr::{AppInfo, OpenXrDiscovery};
|
||||||
|
@ -140,8 +143,8 @@ impl App {
|
||||||
// <https://github.com/rust-lang/rust/issues/65991>
|
// <https://github.com/rust-lang/rust/issues/65991>
|
||||||
struct UpcastedWindow(Rc<dyn WindowPortsMethods>);
|
struct UpcastedWindow(Rc<dyn WindowPortsMethods>);
|
||||||
impl WindowMethods for UpcastedWindow {
|
impl WindowMethods for UpcastedWindow {
|
||||||
fn get_coordinates(&self) -> servo::compositing::windowing::EmbedderCoordinates {
|
fn hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||||
self.0.get_coordinates()
|
self.0.hidpi_factor()
|
||||||
}
|
}
|
||||||
fn set_animation_state(&self, state: AnimationState) {
|
fn set_animation_state(&self, state: AnimationState) {
|
||||||
self.0.set_animation_state(state);
|
self.0.set_animation_state(state);
|
||||||
|
|
|
@ -392,6 +392,10 @@ impl ServoDelegate for ServoShellServoDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebViewDelegate for RunningAppState {
|
impl WebViewDelegate for RunningAppState {
|
||||||
|
fn screen_geometry(&self, _webview: WebView) -> Option<servo::ScreenGeometry> {
|
||||||
|
Some(self.inner().window.screen_geometry())
|
||||||
|
}
|
||||||
|
|
||||||
fn notify_status_text_changed(&self, _webview: servo::WebView, _status: Option<String>) {
|
fn notify_status_text_changed(&self, _webview: servo::WebView, _status: Option<String>) {
|
||||||
self.inner_mut().need_update = true;
|
self.inner_mut().need_update = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,18 +14,16 @@ use euclid::{Angle, Length, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vec
|
||||||
use keyboard_types::{Modifiers, ShortcutMatcher};
|
use keyboard_types::{Modifiers, ShortcutMatcher};
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawWindowHandle};
|
use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawWindowHandle};
|
||||||
use servo::compositing::windowing::{
|
use servo::compositing::windowing::{AnimationState, WebRenderDebugOption, WindowMethods};
|
||||||
AnimationState, EmbedderCoordinates, WebRenderDebugOption, WindowMethods,
|
|
||||||
};
|
|
||||||
use servo::servo_config::pref;
|
use servo::servo_config::pref;
|
||||||
use servo::servo_geometry::DeviceIndependentPixel;
|
use servo::servo_geometry::DeviceIndependentPixel;
|
||||||
use servo::webrender_api::ScrollLocation;
|
use servo::webrender_api::ScrollLocation;
|
||||||
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixel};
|
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize, DevicePixel};
|
||||||
use servo::{
|
use servo::{
|
||||||
Cursor, ImeEvent, InputEvent, Key, KeyState, KeyboardEvent, MouseButton as ServoMouseButton,
|
Cursor, ImeEvent, InputEvent, Key, KeyState, KeyboardEvent, MouseButton as ServoMouseButton,
|
||||||
MouseButtonAction, MouseButtonEvent, MouseMoveEvent, OffscreenRenderingContext,
|
MouseButtonAction, MouseButtonEvent, MouseMoveEvent, OffscreenRenderingContext,
|
||||||
RenderingContext, Theme, TouchEvent, TouchEventType, TouchId, WebView, WheelDelta, WheelEvent,
|
RenderingContext, ScreenGeometry, Theme, TouchEvent, TouchEventType, TouchId, WebView,
|
||||||
WheelMode, WindowRenderingContext,
|
WheelDelta, WheelEvent, WheelMode, WindowRenderingContext,
|
||||||
};
|
};
|
||||||
use surfman::{Context, Device};
|
use surfman::{Context, Device};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -114,7 +112,7 @@ impl Window {
|
||||||
.expect("No monitor detected");
|
.expect("No monitor detected");
|
||||||
|
|
||||||
let (screen_size, screen_scale) = servoshell_preferences.screen_size_override.map_or_else(
|
let (screen_size, screen_scale) = servoshell_preferences.screen_size_override.map_or_else(
|
||||||
|| (monitor.size(), monitor.scale_factor()),
|
|| (monitor.size(), winit_window.scale_factor()),
|
||||||
|size| (PhysicalSize::new(size.width, size.height), 1.0),
|
|size| (PhysicalSize::new(size.width, size.height), 1.0),
|
||||||
);
|
);
|
||||||
let screen_scale: Scale<f64, DeviceIndependentPixel, DevicePixel> =
|
let screen_scale: Scale<f64, DeviceIndependentPixel, DevicePixel> =
|
||||||
|
@ -446,6 +444,26 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowPortsMethods for Window {
|
impl WindowPortsMethods for Window {
|
||||||
|
fn screen_geometry(&self) -> ScreenGeometry {
|
||||||
|
let hidpi_factor = self.hidpi_factor();
|
||||||
|
let toolbar_size = Size2D::new(0.0, (self.toolbar_height.get() * self.hidpi_factor()).0);
|
||||||
|
|
||||||
|
let screen_size = self.screen_size.to_f32() * hidpi_factor;
|
||||||
|
let available_screen_size = screen_size - toolbar_size;
|
||||||
|
|
||||||
|
// Offset the WebView origin by the toolbar so that it reflects the actual viewport and
|
||||||
|
// not the window origin.
|
||||||
|
let window_origin = self.winit_window.inner_position().unwrap_or_default();
|
||||||
|
let window_origin = winit_position_to_euclid_point(window_origin).to_f32();
|
||||||
|
let offset = window_origin + toolbar_size;
|
||||||
|
|
||||||
|
ScreenGeometry {
|
||||||
|
size: screen_size.to_i32(),
|
||||||
|
available_size: available_screen_size.to_i32(),
|
||||||
|
offset: offset.to_i32(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn device_hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
fn device_hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||||
Scale::new(self.winit_window.scale_factor() as f32)
|
Scale::new(self.winit_window.scale_factor() as f32)
|
||||||
}
|
}
|
||||||
|
@ -646,9 +664,6 @@ impl WindowPortsMethods for Window {
|
||||||
winit::window::Theme::Dark => Theme::Dark,
|
winit::window::Theme::Dark => Theme::Dark,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
WindowEvent::Moved(_new_position) => {
|
|
||||||
webview.notify_embedder_window_moved();
|
|
||||||
},
|
|
||||||
WindowEvent::Ime(ime) => match ime {
|
WindowEvent::Ime(ime) => match ime {
|
||||||
Ime::Enabled => {
|
Ime::Enabled => {
|
||||||
webview.notify_input_event(InputEvent::Ime(ImeEvent::Composition(
|
webview.notify_input_event(InputEvent::Ime(ImeEvent::Composition(
|
||||||
|
@ -753,23 +768,9 @@ impl WindowPortsMethods for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowMethods for Window {
|
impl WindowMethods for Window {
|
||||||
fn get_coordinates(&self) -> EmbedderCoordinates {
|
fn hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||||
let window_size = winit_size_to_euclid_size(self.winit_window.outer_size()).to_i32();
|
self.device_pixel_ratio_override()
|
||||||
let window_origin = self.winit_window.outer_position().unwrap_or_default();
|
.unwrap_or_else(|| self.device_hidpi_factor())
|
||||||
let window_origin = winit_position_to_euclid_point(window_origin).to_i32();
|
|
||||||
let window_rect = DeviceIntRect::from_origin_and_size(window_origin, window_size);
|
|
||||||
let window_scale: Scale<f64, DeviceIndependentPixel, DevicePixel> =
|
|
||||||
Scale::new(self.winit_window.scale_factor());
|
|
||||||
let window_rect = (window_rect.to_f64() / window_scale).to_i32();
|
|
||||||
let screen_size = self.screen_size.to_i32();
|
|
||||||
|
|
||||||
EmbedderCoordinates {
|
|
||||||
window_rect,
|
|
||||||
screen_size,
|
|
||||||
// FIXME: Winit doesn't have API for available size. Fallback to screen size
|
|
||||||
available_screen_size: screen_size,
|
|
||||||
hidpi_factor: self.hidpi_factor(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_animation_state(&self, state: AnimationState) {
|
fn set_animation_state(&self, state: AnimationState) {
|
||||||
|
|
|
@ -8,11 +8,11 @@ use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use euclid::num::Zero;
|
use euclid::num::Zero;
|
||||||
use euclid::{Box2D, Length, Point2D, Scale, Size2D};
|
use euclid::{Length, Scale, Size2D};
|
||||||
use servo::compositing::windowing::{AnimationState, EmbedderCoordinates, WindowMethods};
|
use servo::compositing::windowing::{AnimationState, WindowMethods};
|
||||||
use servo::servo_geometry::DeviceIndependentPixel;
|
use servo::servo_geometry::DeviceIndependentPixel;
|
||||||
use servo::webrender_api::units::{DeviceIntSize, DevicePixel};
|
use servo::webrender_api::units::{DeviceIntSize, DevicePixel};
|
||||||
use servo::{RenderingContext, SoftwareRenderingContext};
|
use servo::{RenderingContext, ScreenGeometry, SoftwareRenderingContext};
|
||||||
use winit::dpi::PhysicalSize;
|
use winit::dpi::PhysicalSize;
|
||||||
|
|
||||||
use super::app_state::RunningAppState;
|
use super::app_state::RunningAppState;
|
||||||
|
@ -24,8 +24,7 @@ pub struct Window {
|
||||||
fullscreen: Cell<bool>,
|
fullscreen: Cell<bool>,
|
||||||
device_pixel_ratio_override: Option<Scale<f32, DeviceIndependentPixel, DevicePixel>>,
|
device_pixel_ratio_override: Option<Scale<f32, DeviceIndependentPixel, DevicePixel>>,
|
||||||
inner_size: Cell<DeviceIntSize>,
|
inner_size: Cell<DeviceIntSize>,
|
||||||
screen_size: Size2D<i32, DeviceIndependentPixel>,
|
screen_size: Size2D<i32, DevicePixel>,
|
||||||
window_rect: Box2D<i32, DeviceIndependentPixel>,
|
|
||||||
rendering_context: Rc<SoftwareRenderingContext>,
|
rendering_context: Rc<SoftwareRenderingContext>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,12 +43,11 @@ impl Window {
|
||||||
let rendering_context =
|
let rendering_context =
|
||||||
SoftwareRenderingContext::new(physical_size).expect("Failed to create WR surfman");
|
SoftwareRenderingContext::new(physical_size).expect("Failed to create WR surfman");
|
||||||
|
|
||||||
let window_rect = Box2D::from_origin_and_size(Point2D::zero(), size.to_i32());
|
let screen_size = servoshell_preferences
|
||||||
|
.screen_size_override
|
||||||
let screen_size = servoshell_preferences.screen_size_override.map_or_else(
|
.map_or(inner_size, |screen_size_override| {
|
||||||
|| window_rect.size(),
|
(screen_size_override.to_f32() * hidpi_factor).to_i32()
|
||||||
|screen_size_override| screen_size_override.to_i32(),
|
});
|
||||||
);
|
|
||||||
|
|
||||||
let window = Window {
|
let window = Window {
|
||||||
animation_state: Cell::new(AnimationState::Idle),
|
animation_state: Cell::new(AnimationState::Idle),
|
||||||
|
@ -57,7 +55,6 @@ impl Window {
|
||||||
device_pixel_ratio_override,
|
device_pixel_ratio_override,
|
||||||
inner_size: Cell::new(inner_size),
|
inner_size: Cell::new(inner_size),
|
||||||
screen_size,
|
screen_size,
|
||||||
window_rect,
|
|
||||||
rendering_context: Rc::new(rendering_context),
|
rendering_context: Rc::new(rendering_context),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,6 +67,14 @@ impl WindowPortsMethods for Window {
|
||||||
winit::window::WindowId::dummy()
|
winit::window::WindowId::dummy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn screen_geometry(&self) -> servo::ScreenGeometry {
|
||||||
|
ScreenGeometry {
|
||||||
|
size: self.screen_size,
|
||||||
|
available_size: self.screen_size,
|
||||||
|
offset: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn request_resize(
|
fn request_resize(
|
||||||
&self,
|
&self,
|
||||||
webview: &::servo::WebView,
|
webview: &::servo::WebView,
|
||||||
|
@ -148,13 +153,9 @@ impl WindowPortsMethods for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowMethods for Window {
|
impl WindowMethods for Window {
|
||||||
fn get_coordinates(&self) -> EmbedderCoordinates {
|
fn hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||||
EmbedderCoordinates {
|
self.device_pixel_ratio_override()
|
||||||
window_rect: self.window_rect,
|
.unwrap_or_else(|| self.device_hidpi_factor())
|
||||||
screen_size: self.screen_size,
|
|
||||||
available_screen_size: self.screen_size,
|
|
||||||
hidpi_factor: self.hidpi_factor(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_animation_state(&self, state: AnimationState) {
|
fn set_animation_state(&self, state: AnimationState) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use euclid::{Length, Scale};
|
||||||
use servo::compositing::windowing::WindowMethods;
|
use servo::compositing::windowing::WindowMethods;
|
||||||
use servo::servo_geometry::DeviceIndependentPixel;
|
use servo::servo_geometry::DeviceIndependentPixel;
|
||||||
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize, DevicePixel};
|
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize, DevicePixel};
|
||||||
use servo::{Cursor, RenderingContext, WebView};
|
use servo::{Cursor, RenderingContext, ScreenGeometry, WebView};
|
||||||
|
|
||||||
use super::app_state::RunningAppState;
|
use super::app_state::RunningAppState;
|
||||||
|
|
||||||
|
@ -20,10 +20,7 @@ pub const LINE_HEIGHT: f32 = 38.0;
|
||||||
|
|
||||||
pub trait WindowPortsMethods: WindowMethods {
|
pub trait WindowPortsMethods: WindowMethods {
|
||||||
fn id(&self) -> winit::window::WindowId;
|
fn id(&self) -> winit::window::WindowId;
|
||||||
fn hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
fn screen_geometry(&self) -> ScreenGeometry;
|
||||||
self.device_pixel_ratio_override()
|
|
||||||
.unwrap_or_else(|| self.device_hidpi_factor())
|
|
||||||
}
|
|
||||||
fn device_hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel>;
|
fn device_hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel>;
|
||||||
fn device_pixel_ratio_override(
|
fn device_pixel_ratio_override(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -11,10 +11,8 @@ use keyboard_types::{CompositionEvent, CompositionState};
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use raw_window_handle::{RawWindowHandle, WindowHandle};
|
use raw_window_handle::{RawWindowHandle, WindowHandle};
|
||||||
use servo::base::id::WebViewId;
|
use servo::base::id::WebViewId;
|
||||||
use servo::compositing::windowing::{
|
use servo::compositing::windowing::{AnimationState, EmbedderMethods, WindowMethods};
|
||||||
AnimationState, EmbedderCoordinates, EmbedderMethods, WindowMethods,
|
use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
|
||||||
};
|
|
||||||
use servo::euclid::{Box2D, Point2D, Rect, Scale, Size2D, Vector2D};
|
|
||||||
use servo::servo_geometry::DeviceIndependentPixel;
|
use servo::servo_geometry::DeviceIndependentPixel;
|
||||||
use servo::webrender_api::ScrollLocation;
|
use servo::webrender_api::ScrollLocation;
|
||||||
use servo::webrender_api::units::{DeviceIntRect, DeviceIntSize, DevicePixel};
|
use servo::webrender_api::units::{DeviceIntRect, DeviceIntSize, DevicePixel};
|
||||||
|
@ -683,15 +681,8 @@ impl EmbedderMethods for ServoEmbedderCallbacks {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowMethods for ServoWindowCallbacks {
|
impl WindowMethods for ServoWindowCallbacks {
|
||||||
fn get_coordinates(&self) -> EmbedderCoordinates {
|
fn hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||||
let coords = self.coordinates.borrow();
|
self.hidpi_factor
|
||||||
let screen_size = (coords.viewport.size.to_f32() / self.hidpi_factor).to_i32();
|
|
||||||
EmbedderCoordinates {
|
|
||||||
window_rect: Box2D::from_origin_and_size(Point2D::zero(), screen_size),
|
|
||||||
screen_size,
|
|
||||||
available_screen_size: screen_size,
|
|
||||||
hidpi_factor: self.hidpi_factor,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_animation_state(&self, state: AnimationState) {
|
fn set_animation_state(&self, state: AnimationState) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue