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())]);
|
.unwrap_or_else(|| vec![Rectangle::with_size(viewport.logical_size())]);
|
||||||
|
|
||||||
/// XXX winit shell does not handle skipped present well.
|
|
||||||
if damage.is_empty() {
|
if damage.is_empty() {
|
||||||
if let Some(last_layers) = last_layers {
|
if let Some(last_layers) = last_layers {
|
||||||
surface.layer_stack.push_front(last_layers.clone());
|
surface.layer_stack.push_front(last_layers.clone());
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ use crate::runtime::image;
|
||||||
use crate::runtime::system;
|
use crate::runtime::system;
|
||||||
use crate::runtime::user_interface::{self, UserInterface};
|
use crate::runtime::user_interface::{self, UserInterface};
|
||||||
use crate::runtime::{Action, Task};
|
use crate::runtime::{Action, Task};
|
||||||
|
use crate::subsurface_widget::is_subsurface;
|
||||||
|
|
||||||
use program::Program;
|
use program::Program;
|
||||||
use window::WindowManager;
|
use window::WindowManager;
|
||||||
|
|
@ -77,7 +78,6 @@ use window::WindowManager;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
|
@ -254,6 +254,29 @@ where
|
||||||
| winit::event::WindowEvent::Moved(_)
|
| 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(
|
self.process_event(
|
||||||
event_loop,
|
event_loop,
|
||||||
Some(Event::Winit(window_id, event)),
|
Some(Event::Winit(window_id, event)),
|
||||||
|
|
@ -531,6 +554,32 @@ where
|
||||||
.expect("Send event");
|
.expect("Send event");
|
||||||
}
|
}
|
||||||
Control::Winit(id, e) => {
|
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
|
self.sender
|
||||||
.start_send(Event::Winit(id, e))
|
.start_send(Event::Winit(id, e))
|
||||||
.expect("Send event");
|
.expect("Send event");
|
||||||
|
|
@ -759,8 +808,8 @@ async fn run_instance<P>(
|
||||||
|
|
||||||
'next_event: loop {
|
'next_event: loop {
|
||||||
// Empty the queue if possible
|
// Empty the queue if possible
|
||||||
let event = if let Ok(event) = event_receiver.try_next() {
|
let event = if let Ok(event) = event_receiver.try_recv() {
|
||||||
event
|
Some(event)
|
||||||
} else {
|
} else {
|
||||||
event_receiver.next().await
|
event_receiver.next().await
|
||||||
};
|
};
|
||||||
|
|
@ -950,13 +999,16 @@ async fn run_instance<P>(
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
window.redraw_requested = false;
|
||||||
|
|
||||||
if !window.state.ready {
|
if !window.state.ready {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// XX must force update to corner radius before the surface is committed.
|
// XX must force update to corner radius before the surface is committed.
|
||||||
#[cfg(feature = "wayland")]
|
#[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()
|
|| window.logical_size() != window.state.logical_size()
|
||||||
|
) && !is_subsurface(window_id)
|
||||||
{
|
{
|
||||||
platform_specific_handler.send_wayland(
|
platform_specific_handler.send_wayland(
|
||||||
platform_specific::Action::ResizeWindow(id),
|
platform_specific::Action::ResizeWindow(id),
|
||||||
|
|
@ -1295,8 +1347,6 @@ async fn run_instance<P>(
|
||||||
let skip = events.is_empty() && messages.is_empty();
|
let skip = events.is_empty() && messages.is_empty();
|
||||||
|
|
||||||
if skip && window_manager.is_idle() {
|
if skip && window_manager.is_idle() {
|
||||||
_ = control_sender
|
|
||||||
.start_send(Control::ChangeFlow(ControlFlow::Wait));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1416,18 +1466,6 @@ async fn run_instance<P>(
|
||||||
}
|
}
|
||||||
|
|
||||||
for (id, event) in events.drain(..) {
|
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 {
|
runtime.broadcast(subscription::Event::Interaction {
|
||||||
window: id.unwrap_or(window::Id::NONE),
|
window: id.unwrap_or(window::Id::NONE),
|
||||||
event,
|
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() {
|
if let Some(redraw_at) = window_manager.redraw_at() {
|
||||||
let _ = control_sender.start_send(Control::ChangeFlow(
|
let _ = control_sender.start_send(Control::ChangeFlow(
|
||||||
ControlFlow::WaitUntil(redraw_at),
|
ControlFlow::WaitUntil(redraw_at),
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ pub enum CommonSurface {
|
||||||
Layer(LayerSurface),
|
Layer(LayerSurface),
|
||||||
Lock(SessionLockSurface),
|
Lock(SessionLockSurface),
|
||||||
Subsurface {
|
Subsurface {
|
||||||
|
parent: WlSurface,
|
||||||
wl_surface: WlSurface,
|
wl_surface: WlSurface,
|
||||||
wl_subsurface: WlSubsurface,
|
wl_subsurface: WlSubsurface,
|
||||||
},
|
},
|
||||||
|
|
@ -1821,6 +1822,7 @@ impl SctkState {
|
||||||
parent.wl_surface().clone(),
|
parent.wl_surface().clone(),
|
||||||
wl_surface.clone(),
|
wl_surface.clone(),
|
||||||
CommonSurface::Subsurface {
|
CommonSurface::Subsurface {
|
||||||
|
parent: parent.wl_surface().clone(),
|
||||||
wl_surface,
|
wl_surface,
|
||||||
wl_subsurface,
|
wl_subsurface,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ use cctk::sctk::{
|
||||||
compositor::CompositorHandler,
|
compositor::CompositorHandler,
|
||||||
delegate_compositor,
|
delegate_compositor,
|
||||||
reexports::client::{
|
reexports::client::{
|
||||||
|
Connection, QueueHandle,
|
||||||
protocol::{wl_output, wl_surface},
|
protocol::{wl_output, wl_surface},
|
||||||
Connection, Proxy, QueueHandle,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1498,6 +1498,7 @@ impl SctkEvent {
|
||||||
display,
|
display,
|
||||||
} => {
|
} => {
|
||||||
let CommonSurface::Subsurface {
|
let CommonSurface::Subsurface {
|
||||||
|
parent: _,
|
||||||
wl_surface,
|
wl_surface,
|
||||||
wl_subsurface,
|
wl_subsurface,
|
||||||
} = &common_surface
|
} = &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());
|
_ = surface_ids.insert(wl_surface.id(), wrapper.clone());
|
||||||
let sctk_winit = SctkWinitWindow::new(
|
let sctk_winit = SctkWinitWindow::new(
|
||||||
sctk_tx.clone(),
|
sctk_tx.clone(),
|
||||||
|
|
@ -1542,10 +1543,25 @@ impl SctkEvent {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let Some(compositor) = compositor.as_mut() else {
|
if compositor.is_none() {
|
||||||
log::error!("compositor missing");
|
match create_compositor(
|
||||||
return;
|
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(
|
let window = window_manager.insert(
|
||||||
surface_id,
|
surface_id,
|
||||||
|
|
|
||||||
|
|
@ -747,6 +747,14 @@ pub(crate) fn take_subsurfaces() -> Vec<SubsurfaceInfo> {
|
||||||
SUBSURFACES.with(|subsurfaces| mem::take(&mut *subsurfaces.borrow_mut()))
|
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> {
|
pub(crate) fn subsurface_ids(parent: WindowId) -> Vec<WindowId> {
|
||||||
ICED_SUBSURFACES.with(|subsurfaces| {
|
ICED_SUBSURFACES.with(|subsurfaces| {
|
||||||
subsurfaces
|
subsurfaces
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,11 @@ impl winit::window::Window for SctkWinitWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_redraw(&self) {
|
fn request_redraw(&self) {
|
||||||
|
if let CommonSurface::Subsurface { parent, .. } = &self.surface {
|
||||||
|
_ = self.tx.send(Action::RequestRedraw(parent.id()));
|
||||||
|
}
|
||||||
let surface = self.surface.wl_surface();
|
let surface = self.surface.wl_surface();
|
||||||
|
|
||||||
_ = self.tx.send(Action::RequestRedraw(surface.id()));
|
_ = self.tx.send(Action::RequestRedraw(surface.id()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue