Skip to content

Commit

Permalink
feat: smooth resizing (#221)
Browse files Browse the repository at this point in the history
* Only render on window event

* Update check condition

* Remove redundant variant

* Try different strategy on different platforms

* Update resizing condition

* Update request check

* Yet another kind of check

* Cleanup

* Add method

---------

Co-authored-by: Wu Yuwei <Wu Yu Wei>
  • Loading branch information
wusyong authored Nov 8, 2024
1 parent 35a96f3 commit 3d29571
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,8 @@ impl IOCompositor {
self.pending_paint_metrics.insert(pipeline_id, epoch);
}

CompositorMsg::CrossProcess(cross_proces_message) => {
self.handle_cross_process_message(cross_proces_message);
CompositorMsg::CrossProcess(cross_process_message) => {
self.handle_cross_process_message(cross_process_message);
}
}

Expand Down
14 changes: 3 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,12 @@ impl ApplicationHandler<EventLoopProxyMessage> for App {

fn window_event(
&mut self,
_event_loop: &winit::event_loop::ActiveEventLoop,
event_loop: &winit::event_loop::ActiveEventLoop,
window_id: winit::window::WindowId,
event: winit::event::WindowEvent,
) {
if let Some(v) = self.verso.as_mut() {
v.handle_winit_window_event(window_id, event);
// XXX: Windows seems to be able to handle servo directly.
// We can think about how to handle all platforms the same way in the future.
#[cfg(windows)]
v.handle_servo_messages(_event_loop);
#[cfg(not(windows))]
if let Err(e) = self.proxy.send_event(EventLoopProxyMessage::Wake) {
log::error!("Failed to send wake message to Verso: {e}");
}
v.handle_window_event(event_loop, window_id, event);
}
}

Expand All @@ -46,7 +38,7 @@ impl ApplicationHandler<EventLoopProxyMessage> for App {
if let Some(v) = self.verso.as_mut() {
match event {
EventLoopProxyMessage::Wake => {
v.handle_servo_messages(event_loop);
v.request_redraw(event_loop);
}
EventLoopProxyMessage::IpcMessage(message) => {
v.handle_incoming_webview_message(message);
Expand Down
54 changes: 52 additions & 2 deletions src/verso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl Verso {

// Initialize servo media with dummy backend
// This will create a thread to initialize a global static of servo media.
// The thread will be closed once the static is initialzed.
// The thread will be closed once the static is initialized.
// TODO: This is used by content process. Spawn it there once if we have multiprocess mode.
servo_media::ServoMedia::init::<servo_media_dummy::DummyBackend>();

Expand Down Expand Up @@ -412,8 +412,42 @@ impl Verso {
verso
}

/// Handle Winit window events. The strategy to handle event are different between platforms
/// because the order of events might be different.
pub fn handle_window_event(
&mut self,
event_loop: &ActiveEventLoop,
window_id: WindowId,
event: WindowEvent,
) {
#[cfg(linux)]
if let WindowEvent::Resized(_) = event {
self.handle_winit_window_event(window_id, event);
} else {
self.handle_winit_window_event(window_id, event);
self.handle_servo_messages(event_loop);
}

#[cfg(apple)]
if let WindowEvent::RedrawRequested = event {
let resizing = self.handle_winit_window_event(window_id, event);
if !resizing {
self.handle_servo_messages(event_loop);
}
} else {
self.handle_winit_window_event(window_id, event);
self.handle_servo_messages(event_loop);
}

#[cfg(windows)]
{
self.handle_winit_window_event(window_id, event);
self.handle_servo_messages(event_loop);
}
}

/// Handle Winit window events
pub fn handle_winit_window_event(&mut self, window_id: WindowId, event: WindowEvent) {
fn handle_winit_window_event(&mut self, window_id: WindowId, event: WindowEvent) -> bool {
log::trace!("Verso is handling Winit event: {event:?}");
if let Some(compositor) = &mut self.compositor {
if let WindowEvent::CloseRequested = event {
Expand All @@ -423,8 +457,11 @@ impl Verso {
window
.0
.handle_winit_window_event(&self.constellation_sender, compositor, &event);
return window.0.resizing;
}
}

false
}

/// Handle message came from Servo.
Expand Down Expand Up @@ -518,6 +555,18 @@ impl Verso {
}
}

/// Request Verso to redraw. It will queue a redraw event on current focused window.
pub fn request_redraw(&mut self, evl: &ActiveEventLoop) {
if let Some(compositor) = &mut self.compositor {
if let Some(window) = self.windows.get(&compositor.current_window) {
// evl.set_control_flow(ControlFlow::Poll);
window.0.request_redraw();
} else {
self.handle_servo_messages(evl);
}
}
}

/// Handle message came from webview controller.
pub fn handle_incoming_webview_message(&self, message: ControllerMessage) {
match message {
Expand Down Expand Up @@ -558,6 +607,7 @@ impl Verso {
}

/// Message send to the event loop
#[derive(Debug)]
pub enum EventLoopProxyMessage {
/// Wake
Wake,
Expand Down
13 changes: 12 additions & 1 deletion src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ pub struct Window {
mouse_position: Cell<Option<PhysicalPosition<f64>>>,
/// Modifiers state of the keyboard.
modifiers_state: Cell<ModifiersState>,
/// State to indicate if the window is resizing.
pub(crate) resizing: bool,
}

impl Window {
Expand Down Expand Up @@ -94,6 +96,7 @@ impl Window {
webview: None,
mouse_position: Default::default(),
modifiers_state: Cell::new(ModifiersState::default()),
resizing: false,
},
rendering_context,
)
Expand Down Expand Up @@ -130,6 +133,7 @@ impl Window {
webview: None,
mouse_position: Default::default(),
modifiers_state: Cell::new(ModifiersState::default()),
resizing: false,
};
compositor.swap_current_window(&mut window);
window
Expand Down Expand Up @@ -200,6 +204,7 @@ impl Window {
match event {
WindowEvent::RedrawRequested => {
if compositor.ready_to_present {
self.window.pre_present_notify();
if let Err(err) = compositor.rendering_context.present(&self.surface) {
log::warn!("Failed to present surface: {:?}", err);
}
Expand All @@ -212,6 +217,9 @@ impl Window {
}
}
WindowEvent::Resized(size) => {
if self.window.has_focus() {
self.resizing = true;
}
let size = Size2D::new(size.width, size.height);
compositor.resize(size.to_i32(), self);
}
Expand Down Expand Up @@ -272,7 +280,10 @@ impl Window {

let event: MouseWindowEvent = match state {
ElementState::Pressed => MouseWindowEvent::MouseDown(button, position),
ElementState::Released => MouseWindowEvent::MouseUp(button, position),
ElementState::Released => {
self.resizing = false;
MouseWindowEvent::MouseUp(button, position)
}
};
compositor.on_mouse_window_event_class(event);

Expand Down

0 comments on commit 3d29571

Please sign in to comment.