diff --git a/tiny_skia/src/window/compositor.rs b/tiny_skia/src/window/compositor.rs index e5303567..b841c242 100644 --- a/tiny_skia/src/window/compositor.rs +++ b/tiny_skia/src/window/compositor.rs @@ -186,7 +186,6 @@ pub fn present( }) .unwrap_or_else(|| vec![Rectangle::with_size(viewport.logical_size())]); - /// XXX winit shell does not handle skipped present well. if damage.is_empty() { if let Some(last_layers) = last_layers { surface.layer_stack.push_front(last_layers.clone()); diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 1243376c..1a50505b 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -70,6 +70,7 @@ use crate::runtime::image; use crate::runtime::system; use crate::runtime::user_interface::{self, UserInterface}; use crate::runtime::{Action, Task}; +use crate::subsurface_widget::is_subsurface; use program::Program; use window::WindowManager; @@ -77,7 +78,6 @@ use window::WindowManager; use rustc_hash::FxHashMap; use std::borrow::Cow; use std::mem::ManuallyDrop; -use std::ops::ControlFlow; use std::slice; use std::sync::Arc; @@ -254,6 +254,29 @@ where | winit::event::WindowEvent::Moved(_) ); + #[cfg(feature = "wayland")] + { + if matches!(event, WindowEvent::RedrawRequested) { + for id in + crate::subsurface_widget::subsurface_ids(window_id) + { + _ = self.sender.start_send(Event::Winit( + id, + WindowEvent::RedrawRequested, + )); + } + } else if matches!(event, WindowEvent::CloseRequested) { + for id in + crate::subsurface_widget::subsurface_ids(window_id) + { + _ = self.sender.start_send(Event::Winit( + id, + WindowEvent::CloseRequested, + )); + } + } + } + self.process_event( event_loop, Some(Event::Winit(window_id, event)), @@ -531,6 +554,32 @@ where .expect("Send event"); } Control::Winit(id, e) => { + #[cfg(feature = "wayland")] + { + if matches!(e, WindowEvent::RedrawRequested) + { + + for id in crate::subsurface_widget::subsurface_ids(id) { + _ = self.sender + .unbounded_send(Event::Winit( + id, + WindowEvent::RedrawRequested, + )); + } + } else if matches!( + e, + WindowEvent::CloseRequested + ) { + for id in crate::subsurface_widget::subsurface_ids(id) { + _ = self.sender + .start_send(Event::Winit( + id, + WindowEvent::CloseRequested, + )); + } + } + } + self.sender .start_send(Event::Winit(id, e)) .expect("Send event"); @@ -759,8 +808,8 @@ async fn run_instance
( 'next_event: loop { // Empty the queue if possible - let event = if let Ok(event) = event_receiver.try_next() { - event + let event = if let Ok(event) = event_receiver.try_recv() { + Some(event) } else { event_receiver.next().await }; @@ -950,13 +999,16 @@ async fn run_instance
( else { continue; }; + window.redraw_requested = false; + if !window.state.ready { continue; } // XX must force update to corner radius before the surface is committed. #[cfg(feature = "wayland")] - if window.surface_version != window.state.surface_version() + if (window.surface_version != window.state.surface_version() || window.logical_size() != window.state.logical_size() + ) && !is_subsurface(window_id) { platform_specific_handler.send_wayland( platform_specific::Action::ResizeWindow(id), @@ -1295,8 +1347,6 @@ async fn run_instance
( let skip = events.is_empty() && messages.is_empty(); if skip && window_manager.is_idle() { - _ = control_sender - .start_send(Control::ChangeFlow(ControlFlow::Wait)); continue; } @@ -1416,18 +1466,6 @@ async fn run_instance
( } for (id, event) in events.drain(..) { - if id.is_none() - && matches!( - event, - core::Event::Keyboard(_) - | core::Event::Touch(_) - | core::Event::Mouse(_) - ) - { - _ = control_sender - .start_send(Control::ChangeFlow(ControlFlow::Wait)); - continue; - } runtime.broadcast(subscription::Event::Interaction { window: id.unwrap_or(window::Id::NONE), event, @@ -1484,6 +1522,14 @@ async fn run_instance
(
}
}
+ for (_id, window) in window_manager.iter_mut() {
+ if let Some(redraw_at) = window.redraw_at
+ && redraw_at <= Instant::now()
+ {
+ window.raw.request_redraw();
+ window.redraw_at = None;
+ }
+ }
if let Some(redraw_at) = window_manager.redraw_at() {
let _ = control_sender.start_send(Control::ChangeFlow(
ControlFlow::WaitUntil(redraw_at),
diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs
index 69113743..51ab8d90 100644
--- a/winit/src/platform_specific/wayland/event_loop/state.rs
+++ b/winit/src/platform_specific/wayland/event_loop/state.rs
@@ -206,6 +206,7 @@ pub enum CommonSurface {
Layer(LayerSurface),
Lock(SessionLockSurface),
Subsurface {
+ parent: WlSurface,
wl_surface: WlSurface,
wl_subsurface: WlSubsurface,
},
@@ -1821,6 +1822,7 @@ impl SctkState {
parent.wl_surface().clone(),
wl_surface.clone(),
CommonSurface::Subsurface {
+ parent: parent.wl_surface().clone(),
wl_surface,
wl_subsurface,
},
diff --git a/winit/src/platform_specific/wayland/handlers/compositor.rs b/winit/src/platform_specific/wayland/handlers/compositor.rs
index 92b5c773..422a561d 100644
--- a/winit/src/platform_specific/wayland/handlers/compositor.rs
+++ b/winit/src/platform_specific/wayland/handlers/compositor.rs
@@ -3,8 +3,8 @@ use cctk::sctk::{
compositor::CompositorHandler,
delegate_compositor,
reexports::client::{
+ Connection, QueueHandle,
protocol::{wl_output, wl_surface},
- Connection, Proxy, QueueHandle,
},
};
diff --git a/winit/src/platform_specific/wayland/sctk_event.rs b/winit/src/platform_specific/wayland/sctk_event.rs
index fa512bf3..1e621451 100755
--- a/winit/src/platform_specific/wayland/sctk_event.rs
+++ b/winit/src/platform_specific/wayland/sctk_event.rs
@@ -1498,6 +1498,7 @@ impl SctkEvent {
display,
} => {
let CommonSurface::Subsurface {
+ parent: _,
wl_surface,
wl_subsurface,
} = &common_surface
@@ -1515,7 +1516,7 @@ impl SctkEvent {
));
}
- let wrapper = SurfaceIdWrapper::Popup(surface_id);
+ let wrapper = SurfaceIdWrapper::Subsurface(surface_id);
_ = surface_ids.insert(wl_surface.id(), wrapper.clone());
let sctk_winit = SctkWinitWindow::new(
sctk_tx.clone(),
@@ -1542,10 +1543,25 @@ impl SctkEvent {
},
);
}
- let Some(compositor) = compositor.as_mut() else {
- log::error!("compositor missing");
- return;
- };
+ if compositor.is_none() {
+ match create_compositor(
+ sctk_winit.clone(),
+ create_compositor_data,
+ )
+ .await
+ {
+ Ok(c) => *compositor = Some(c),
+ Err(error) => {
+ control_sender
+ .start_send(Control::Crash(
+ Error::GraphicsCreationFailed(error),
+ ))
+ .expect("Send control message");
+ return;
+ }
+ };
+ }
+ let compositor = compositor.as_mut().unwrap();
let window = window_manager.insert(
surface_id,
diff --git a/winit/src/platform_specific/wayland/subsurface_widget.rs b/winit/src/platform_specific/wayland/subsurface_widget.rs
index b082bf3b..ed53d9ea 100644
--- a/winit/src/platform_specific/wayland/subsurface_widget.rs
+++ b/winit/src/platform_specific/wayland/subsurface_widget.rs
@@ -747,6 +747,14 @@ pub(crate) fn take_subsurfaces() -> Vec