fix: subsurface improvements
this fixes a couple issues in the greeter
This commit is contained in:
parent
2a680eeb32
commit
f7dc180371
7 changed files with 100 additions and 25 deletions
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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<P>(
|
|||
|
||||
'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<P>(
|
|||
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<P>(
|
|||
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<P>(
|
|||
}
|
||||
|
||||
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<P>(
|
|||
}
|
||||
}
|
||||
|
||||
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),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use cctk::sctk::{
|
|||
compositor::CompositorHandler,
|
||||
delegate_compositor,
|
||||
reexports::client::{
|
||||
Connection, QueueHandle,
|
||||
protocol::{wl_output, wl_surface},
|
||||
Connection, Proxy, QueueHandle,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -747,6 +747,14 @@ pub(crate) fn take_subsurfaces() -> Vec<SubsurfaceInfo> {
|
|||
SUBSURFACES.with(|subsurfaces| mem::take(&mut *subsurfaces.borrow_mut()))
|
||||
}
|
||||
|
||||
pub(crate) fn is_subsurface(id: WindowId) -> bool {
|
||||
ICED_SUBSURFACES.with(|subsurfaces| {
|
||||
subsurfaces.borrow_mut().iter().any(|s| {
|
||||
winit::window::WindowId::from_raw(s.4.id().as_ptr() as usize) == id
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn subsurface_ids(parent: WindowId) -> Vec<WindowId> {
|
||||
ICED_SUBSURFACES.with(|subsurfaces| {
|
||||
subsurfaces
|
||||
|
|
|
|||
|
|
@ -67,7 +67,11 @@ impl winit::window::Window for SctkWinitWindow {
|
|||
}
|
||||
|
||||
fn request_redraw(&self) {
|
||||
if let CommonSurface::Subsurface { parent, .. } = &self.surface {
|
||||
_ = self.tx.send(Action::RequestRedraw(parent.id()));
|
||||
}
|
||||
let surface = self.surface.wl_surface();
|
||||
|
||||
_ = self.tx.send(Action::RequestRedraw(surface.id()));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue