mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
ohos: Support resizing the surface (#35158)
A window resize requires to also resize the webview, otherwise it will stay at the original size. Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
parent
f6d1b30e97
commit
53fcc98585
5 changed files with 87 additions and 31 deletions
|
@ -20,7 +20,7 @@ pub struct WebViewManager<WebView> {
|
||||||
webviews: HashMap<WebViewId, WebView>,
|
webviews: HashMap<WebViewId, WebView>,
|
||||||
|
|
||||||
/// The order to paint them in, topmost last.
|
/// The order to paint them in, topmost last.
|
||||||
painting_order: Vec<WebViewId>,
|
pub(crate) painting_order: Vec<WebViewId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
|
|
@ -85,6 +85,7 @@ backtrace = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(target_env = "ohos")'.dependencies]
|
[target.'cfg(target_env = "ohos")'.dependencies]
|
||||||
env_filter = "0.1.3"
|
env_filter = "0.1.3"
|
||||||
|
euclid = { workspace = true }
|
||||||
# force inprocess, until libc-rs 0.2.156 is released containing
|
# force inprocess, until libc-rs 0.2.156 is released containing
|
||||||
# https://github.com/rust-lang/libc/commit/9e248e212c5602cb4e98676e4c21ea0382663a12
|
# https://github.com/rust-lang/libc/commit/9e248e212c5602cb4e98676e4c21ea0382663a12
|
||||||
ipc-channel = { workspace = true, features = ["force-inprocess"] }
|
ipc-channel = { workspace = true, features = ["force-inprocess"] }
|
||||||
|
|
|
@ -26,14 +26,14 @@ use simpleservo::EventLoopWaker;
|
||||||
use xcomponent_sys::{
|
use xcomponent_sys::{
|
||||||
OH_NativeXComponent, OH_NativeXComponent_Callback, OH_NativeXComponent_GetKeyEvent,
|
OH_NativeXComponent, OH_NativeXComponent_Callback, OH_NativeXComponent_GetKeyEvent,
|
||||||
OH_NativeXComponent_GetKeyEventAction, OH_NativeXComponent_GetKeyEventCode,
|
OH_NativeXComponent_GetKeyEventAction, OH_NativeXComponent_GetKeyEventCode,
|
||||||
OH_NativeXComponent_GetTouchEvent, OH_NativeXComponent_KeyAction, OH_NativeXComponent_KeyCode,
|
OH_NativeXComponent_GetTouchEvent, OH_NativeXComponent_GetXComponentSize,
|
||||||
OH_NativeXComponent_KeyEvent, OH_NativeXComponent_RegisterCallback,
|
OH_NativeXComponent_KeyAction, OH_NativeXComponent_KeyCode, OH_NativeXComponent_KeyEvent,
|
||||||
OH_NativeXComponent_RegisterKeyEventCallback, OH_NativeXComponent_TouchEvent,
|
OH_NativeXComponent_RegisterCallback, OH_NativeXComponent_RegisterKeyEventCallback,
|
||||||
OH_NativeXComponent_TouchEventType,
|
OH_NativeXComponent_TouchEvent, OH_NativeXComponent_TouchEventType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::host_trait::HostTrait;
|
use super::host_trait::HostTrait;
|
||||||
use super::servo_glue::ServoGlue;
|
use super::servo_glue::{Coordinates, ServoGlue};
|
||||||
|
|
||||||
mod resources;
|
mod resources;
|
||||||
mod simpleservo;
|
mod simpleservo;
|
||||||
|
@ -104,6 +104,10 @@ pub(super) enum ServoAction {
|
||||||
ImeSendEnter,
|
ImeSendEnter,
|
||||||
Initialize(Box<InitOpts>),
|
Initialize(Box<InitOpts>),
|
||||||
Vsync,
|
Vsync,
|
||||||
|
Resize {
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Queue length for the thread-safe function to submit URL updates to ArkTS
|
/// Queue length for the thread-safe function to submit URL updates to ArkTS
|
||||||
|
@ -180,6 +184,9 @@ impl ServoAction {
|
||||||
servo.notify_vsync();
|
servo.notify_vsync();
|
||||||
servo.present_if_needed();
|
servo.present_if_needed();
|
||||||
},
|
},
|
||||||
|
Resize { width, height } => {
|
||||||
|
servo.resize(Coordinates::new(0, 0, *width, *height, *width, *height))
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,9 +270,52 @@ extern "C" fn on_surface_created_cb(xcomponent: *mut OH_NativeXComponent, window
|
||||||
info!("Returning from on_surface_created_cb");
|
info!("Returning from on_surface_created_cb");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: Probably we need to block here, until the main thread has processed the change.
|
/// Returns the size of the surface
|
||||||
extern "C" fn on_surface_changed_cb(_component: *mut OH_NativeXComponent, _window: *mut c_void) {
|
///
|
||||||
error!("on_surface_changed_cb is currently not implemented!");
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `xcomponent` and `native_window` must be valid, non-null and aligned pointers to a
|
||||||
|
/// live xcomponent and associated native window surface.
|
||||||
|
unsafe fn get_xcomponent_size(
|
||||||
|
xcomponent: *mut OH_NativeXComponent,
|
||||||
|
native_window: *mut c_void,
|
||||||
|
) -> Result<euclid::default::Size2D<i32>, i32> {
|
||||||
|
let mut width: u64 = 0;
|
||||||
|
let mut height: u64 = 0;
|
||||||
|
let result = unsafe {
|
||||||
|
OH_NativeXComponent_GetXComponentSize(
|
||||||
|
xcomponent,
|
||||||
|
native_window,
|
||||||
|
&raw mut width,
|
||||||
|
&raw mut height,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if result != 0 {
|
||||||
|
debug!("OH_NativeXComponent_GetXComponentSize failed with {result}");
|
||||||
|
return Err(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
let width: i32 = width.try_into().expect("Width too large");
|
||||||
|
let height: i32 = height.try_into().expect("Height too large");
|
||||||
|
Ok(euclid::Size2D::new(width, height))
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" fn on_surface_changed_cb(
|
||||||
|
xcomponent: *mut OH_NativeXComponent,
|
||||||
|
native_window: *mut c_void,
|
||||||
|
) {
|
||||||
|
debug!("on_surface_changed_cb: xc: {xcomponent:?}, window: {native_window:?}");
|
||||||
|
// SAFETY: We just obtained these pointers from the callback, so we can assume them to be valid.
|
||||||
|
if let Ok(size) = unsafe { get_xcomponent_size(xcomponent, native_window) } {
|
||||||
|
info!("on_surface_changed_cb: Resizing to {size:?}");
|
||||||
|
call(ServoAction::Resize {
|
||||||
|
width: size.width,
|
||||||
|
height: size.height,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
error!("on_surface_changed_cb: Surface changed, but failed to obtain new size")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn on_surface_destroyed_cb(_component: *mut OH_NativeXComponent, _window: *mut c_void) {
|
extern "C" fn on_surface_destroyed_cb(_component: *mut OH_NativeXComponent, _window: *mut c_void) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ use std::rc::Rc;
|
||||||
|
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use servo::compositing::CompositeTarget;
|
use servo::compositing::CompositeTarget;
|
||||||
use servo::euclid::Size2D;
|
|
||||||
use servo::webrender_traits::SurfmanRenderingContext;
|
use servo::webrender_traits::SurfmanRenderingContext;
|
||||||
/// The EventLoopWaker::wake function will be called from any thread.
|
/// The EventLoopWaker::wake function will be called from any thread.
|
||||||
/// It will be called to notify embedder that some events are available,
|
/// It will be called to notify embedder that some events are available,
|
||||||
|
@ -17,7 +16,7 @@ use servo::webrender_traits::SurfmanRenderingContext;
|
||||||
pub use servo::EventLoopWaker;
|
pub use servo::EventLoopWaker;
|
||||||
use servo::{self, resources, Servo};
|
use servo::{self, resources, Servo};
|
||||||
use surfman::{Connection, SurfaceType};
|
use surfman::{Connection, SurfaceType};
|
||||||
use xcomponent_sys::{OH_NativeXComponent, OH_NativeXComponent_GetXComponentSize};
|
use xcomponent_sys::OH_NativeXComponent;
|
||||||
|
|
||||||
use crate::egl::host_trait::HostTrait;
|
use crate::egl::host_trait::HostTrait;
|
||||||
use crate::egl::ohos::resources::ResourceReaderInstance;
|
use crate::egl::ohos::resources::ResourceReaderInstance;
|
||||||
|
@ -68,24 +67,13 @@ pub fn init(
|
||||||
.create_adapter()
|
.create_adapter()
|
||||||
.or(Err("Failed to create adapter"))?;
|
.or(Err("Failed to create adapter"))?;
|
||||||
|
|
||||||
let mut width: u64 = 0;
|
let Ok(window_size) = (unsafe { super::get_xcomponent_size(xcomponent, native_window) }) else {
|
||||||
let mut height: u64 = 0;
|
return Err("Failed to get xcomponent size");
|
||||||
let res = unsafe {
|
|
||||||
OH_NativeXComponent_GetXComponentSize(
|
|
||||||
xcomponent,
|
|
||||||
native_window,
|
|
||||||
&mut width as *mut _,
|
|
||||||
&mut height as *mut _,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
assert_eq!(res, 0, "OH_NativeXComponent_GetXComponentSize failed");
|
|
||||||
let width: i32 = width.try_into().expect("Width too large");
|
|
||||||
let height: i32 = height.try_into().expect("Height too large");
|
|
||||||
|
|
||||||
debug!("Creating surfman widget with width {width} and height {height}");
|
debug!("Creating surfman widget with {window_size:?}");
|
||||||
let native_widget = unsafe {
|
let native_widget =
|
||||||
connection.create_native_widget_from_ptr(native_window, Size2D::new(width, height))
|
unsafe { connection.create_native_widget_from_ptr(native_window, window_size) };
|
||||||
};
|
|
||||||
let surface_type = SurfaceType::Widget { native_widget };
|
let surface_type = SurfaceType::Widget { native_widget };
|
||||||
|
|
||||||
info!("Creating rendering context");
|
info!("Creating rendering context");
|
||||||
|
@ -102,7 +90,14 @@ pub fn init(
|
||||||
|
|
||||||
let window_callbacks = Rc::new(ServoWindowCallbacks::new(
|
let window_callbacks = Rc::new(ServoWindowCallbacks::new(
|
||||||
callbacks,
|
callbacks,
|
||||||
RefCell::new(Coordinates::new(0, 0, width, height, width, height)),
|
RefCell::new(Coordinates::new(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
window_size.width,
|
||||||
|
window_size.height,
|
||||||
|
window_size.width,
|
||||||
|
window_size.height,
|
||||||
|
)),
|
||||||
options.display_density as f32,
|
options.display_density as f32,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ use servo::compositing::windowing::{
|
||||||
};
|
};
|
||||||
use servo::euclid::{Box2D, 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::units::DevicePixel;
|
use servo::webrender_api::units::{DevicePixel, DeviceRect};
|
||||||
use servo::webrender_api::ScrollLocation;
|
use servo::webrender_api::ScrollLocation;
|
||||||
use servo::webrender_traits::SurfmanRenderingContext;
|
use servo::webrender_traits::SurfmanRenderingContext;
|
||||||
use servo::{
|
use servo::{
|
||||||
|
@ -222,8 +222,16 @@ impl ServoGlue {
|
||||||
|
|
||||||
/// Let Servo know that the window has been resized.
|
/// Let Servo know that the window has been resized.
|
||||||
pub fn resize(&mut self, coordinates: Coordinates) {
|
pub fn resize(&mut self, coordinates: Coordinates) {
|
||||||
info!("resize");
|
info!("resize to {:?}", coordinates);
|
||||||
|
let size = coordinates.viewport.size;
|
||||||
|
let _ = self
|
||||||
|
.rendering_context
|
||||||
|
.resize(Size2D::new(size.width, size.height))
|
||||||
|
.inspect_err(|e| error!("Failed to resize rendering context: {e:?}"));
|
||||||
|
*self.callbacks.coordinates.borrow_mut() = coordinates;
|
||||||
self.active_webview().notify_rendering_context_resized();
|
self.active_webview().notify_rendering_context_resized();
|
||||||
|
self.active_webview()
|
||||||
|
.move_resize(DeviceRect::from_size(size.to_f32()));
|
||||||
self.maybe_perform_updates()
|
self.maybe_perform_updates()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,10 +646,12 @@ impl ServoGlue {
|
||||||
EmbedderMsg::Keyboard(..) => {
|
EmbedderMsg::Keyboard(..) => {
|
||||||
error!("Received unexpected keyboard event");
|
error!("Received unexpected keyboard event");
|
||||||
},
|
},
|
||||||
|
EmbedderMsg::ResizeTo(size) => {
|
||||||
|
error!("Received resize event (to {size:?}). Currently only the user can resize windows");
|
||||||
|
},
|
||||||
EmbedderMsg::Status(..) |
|
EmbedderMsg::Status(..) |
|
||||||
EmbedderMsg::SelectFiles(..) |
|
EmbedderMsg::SelectFiles(..) |
|
||||||
EmbedderMsg::MoveTo(..) |
|
EmbedderMsg::MoveTo(..) |
|
||||||
EmbedderMsg::ResizeTo(..) |
|
|
||||||
EmbedderMsg::SetCursor(..) |
|
EmbedderMsg::SetCursor(..) |
|
||||||
EmbedderMsg::NewFavicon(..) |
|
EmbedderMsg::NewFavicon(..) |
|
||||||
EmbedderMsg::HeadParsed |
|
EmbedderMsg::HeadParsed |
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue