aboutsummaryrefslogtreecommitdiffstats
path: root/ports/servoshell/egl
diff options
context:
space:
mode:
authorJonathan Schwender <55576758+jschwe@users.noreply.github.com>2025-01-29 16:45:17 +0100
committerGitHub <noreply@github.com>2025-01-29 15:45:17 +0000
commit53fcc98585807b43e049718b1d04d89733cc846a (patch)
tree6fa4db8aca4f3ab9562c6f4e59a0ca97429d1d8c /ports/servoshell/egl
parentf6d1b30e9785414562f22cf6ee545d7f3387d779 (diff)
downloadservo-53fcc98585807b43e049718b1d04d89733cc846a.tar.gz
servo-53fcc98585807b43e049718b1d04d89733cc846a.zip
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>
Diffstat (limited to 'ports/servoshell/egl')
-rw-r--r--ports/servoshell/egl/ohos.rs66
-rw-r--r--ports/servoshell/egl/ohos/simpleservo.rs33
-rw-r--r--ports/servoshell/egl/servo_glue.rs16
3 files changed, 85 insertions, 30 deletions
diff --git a/ports/servoshell/egl/ohos.rs b/ports/servoshell/egl/ohos.rs
index 66e568972b0..908a4c75240 100644
--- a/ports/servoshell/egl/ohos.rs
+++ b/ports/servoshell/egl/ohos.rs
@@ -26,14 +26,14 @@ use simpleservo::EventLoopWaker;
use xcomponent_sys::{
OH_NativeXComponent, OH_NativeXComponent_Callback, OH_NativeXComponent_GetKeyEvent,
OH_NativeXComponent_GetKeyEventAction, OH_NativeXComponent_GetKeyEventCode,
- OH_NativeXComponent_GetTouchEvent, OH_NativeXComponent_KeyAction, OH_NativeXComponent_KeyCode,
- OH_NativeXComponent_KeyEvent, OH_NativeXComponent_RegisterCallback,
- OH_NativeXComponent_RegisterKeyEventCallback, OH_NativeXComponent_TouchEvent,
- OH_NativeXComponent_TouchEventType,
+ OH_NativeXComponent_GetTouchEvent, OH_NativeXComponent_GetXComponentSize,
+ OH_NativeXComponent_KeyAction, OH_NativeXComponent_KeyCode, OH_NativeXComponent_KeyEvent,
+ OH_NativeXComponent_RegisterCallback, OH_NativeXComponent_RegisterKeyEventCallback,
+ OH_NativeXComponent_TouchEvent, OH_NativeXComponent_TouchEventType,
};
use super::host_trait::HostTrait;
-use super::servo_glue::ServoGlue;
+use super::servo_glue::{Coordinates, ServoGlue};
mod resources;
mod simpleservo;
@@ -104,6 +104,10 @@ pub(super) enum ServoAction {
ImeSendEnter,
Initialize(Box<InitOpts>),
Vsync,
+ Resize {
+ width: i32,
+ height: i32,
+ },
}
/// Queue length for the thread-safe function to submit URL updates to ArkTS
@@ -180,6 +184,9 @@ impl ServoAction {
servo.notify_vsync();
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");
}
-// Todo: Probably we need to block here, until the main thread has processed the change.
-extern "C" fn on_surface_changed_cb(_component: *mut OH_NativeXComponent, _window: *mut c_void) {
- error!("on_surface_changed_cb is currently not implemented!");
+/// Returns the size of the surface
+///
+/// # 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) {
diff --git a/ports/servoshell/egl/ohos/simpleservo.rs b/ports/servoshell/egl/ohos/simpleservo.rs
index 3498531a949..ff0a37c6105 100644
--- a/ports/servoshell/egl/ohos/simpleservo.rs
+++ b/ports/servoshell/egl/ohos/simpleservo.rs
@@ -9,7 +9,6 @@ use std::rc::Rc;
use log::{debug, info};
use servo::compositing::CompositeTarget;
-use servo::euclid::Size2D;
use servo::webrender_traits::SurfmanRenderingContext;
/// The EventLoopWaker::wake function will be called from any thread.
/// 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;
use servo::{self, resources, Servo};
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::ohos::resources::ResourceReaderInstance;
@@ -68,24 +67,13 @@ pub fn init(
.create_adapter()
.or(Err("Failed to create adapter"))?;
- let mut width: u64 = 0;
- let mut height: u64 = 0;
- let res = unsafe {
- OH_NativeXComponent_GetXComponentSize(
- xcomponent,
- native_window,
- &mut width as *mut _,
- &mut height as *mut _,
- )
+ let Ok(window_size) = (unsafe { super::get_xcomponent_size(xcomponent, native_window) }) else {
+ return Err("Failed to get xcomponent size");
};
- 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}");
- let native_widget = unsafe {
- connection.create_native_widget_from_ptr(native_window, Size2D::new(width, height))
- };
+ debug!("Creating surfman widget with {window_size:?}");
+ let native_widget =
+ unsafe { connection.create_native_widget_from_ptr(native_window, window_size) };
let surface_type = SurfaceType::Widget { native_widget };
info!("Creating rendering context");
@@ -102,7 +90,14 @@ pub fn init(
let window_callbacks = Rc::new(ServoWindowCallbacks::new(
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,
));
diff --git a/ports/servoshell/egl/servo_glue.rs b/ports/servoshell/egl/servo_glue.rs
index 0a12bd9c713..f485ed56b9c 100644
--- a/ports/servoshell/egl/servo_glue.rs
+++ b/ports/servoshell/egl/servo_glue.rs
@@ -15,7 +15,7 @@ use servo::compositing::windowing::{
};
use servo::euclid::{Box2D, Point2D, Rect, Scale, Size2D, Vector2D};
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_traits::SurfmanRenderingContext;
use servo::{
@@ -222,8 +222,16 @@ impl ServoGlue {
/// Let Servo know that the window has been resized.
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()
+ .move_resize(DeviceRect::from_size(size.to_f32()));
self.maybe_perform_updates()
}
@@ -638,10 +646,12 @@ impl ServoGlue {
EmbedderMsg::Keyboard(..) => {
error!("Received unexpected keyboard event");
},
+ EmbedderMsg::ResizeTo(size) => {
+ error!("Received resize event (to {size:?}). Currently only the user can resize windows");
+ },
EmbedderMsg::Status(..) |
EmbedderMsg::SelectFiles(..) |
EmbedderMsg::MoveTo(..) |
- EmbedderMsg::ResizeTo(..) |
EmbedderMsg::SetCursor(..) |
EmbedderMsg::NewFavicon(..) |
EmbedderMsg::HeadParsed |