fix: wayland inconsistencies
This commit is contained in:
@@ -8,18 +8,20 @@ use crate::{
|
||||
wayland::surface::CoreSurface,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use portable_atomic::{AtomicU32, Ordering};
|
||||
use rand::Rng;
|
||||
use smithay::{
|
||||
backend::renderer::utils::{on_commit_buffer_handler, RendererSurfaceStateUserData},
|
||||
delegate_compositor,
|
||||
desktop::PopupKind,
|
||||
reexports::wayland_server::{protocol::wl_surface::WlSurface, Client},
|
||||
wayland::compositor::{
|
||||
self, add_post_commit_hook, CompositorClientState, CompositorHandler, CompositorState,
|
||||
add_post_commit_hook, CompositorClientState, CompositorHandler, CompositorState,
|
||||
},
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use tracing::debug;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
pub struct ConfiguredSurface;
|
||||
|
||||
impl CompositorHandler for WaylandState {
|
||||
fn compositor_state(&mut self) -> &mut CompositorState {
|
||||
@@ -30,19 +32,27 @@ impl CompositorHandler for WaylandState {
|
||||
debug!(?surface, "Surface commit");
|
||||
|
||||
on_commit_buffer_handler::<WaylandState>(surface);
|
||||
let mut count = 0;
|
||||
compositor::with_states(surface, |data| {
|
||||
let count_new = data
|
||||
.data_map
|
||||
.insert_if_missing_threadsafe(|| AtomicU32::new(0));
|
||||
if !count_new {
|
||||
if let Some(stored_count) = data.data_map.get::<AtomicU32>() {
|
||||
count = stored_count.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
data.data_map.get::<Arc<CoreSurface>>().cloned()
|
||||
});
|
||||
if let Some(toplevel) = self
|
||||
.xdg_shell
|
||||
.toplevel_surfaces()
|
||||
.iter()
|
||||
.find(|s| s.wl_surface() == surface)
|
||||
{
|
||||
if !toplevel.is_initial_configure_sent() {
|
||||
debug!("Sending initial configure for toplevel surface");
|
||||
toplevel.send_configure();
|
||||
surface.insert_data(ConfiguredSurface);
|
||||
}
|
||||
}
|
||||
|
||||
self.popup_manager.commit(surface);
|
||||
if let Some(PopupKind::Xdg(popup)) = self.popup_manager.find_popup(surface) {
|
||||
if surface.insert_data(ConfiguredSurface) {
|
||||
debug!("Configuring popup surface");
|
||||
let _ = popup.send_configure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState {
|
||||
@@ -54,6 +64,7 @@ impl CompositorHandler for WaylandState {
|
||||
surface.insert_data(SurfaceId::Child(id));
|
||||
CoreSurface::add_to(surface);
|
||||
let Some(parent_surface_id) = parent.get_data::<SurfaceId>() else {
|
||||
warn!("Parent surface has no SurfaceId");
|
||||
return;
|
||||
};
|
||||
surface.insert_data(Mutex::new(ChildInfo {
|
||||
@@ -68,6 +79,7 @@ impl CompositorHandler for WaylandState {
|
||||
}));
|
||||
|
||||
let Some(panel_item) = surface_panel_item(parent) else {
|
||||
warn!("Parent has no panel item");
|
||||
return;
|
||||
};
|
||||
let panel_item_weak = Arc::downgrade(&panel_item);
|
||||
@@ -75,11 +87,19 @@ impl CompositorHandler for WaylandState {
|
||||
if surface_panel_item(surf).is_some() {
|
||||
return;
|
||||
}
|
||||
debug!("Linking surface to panel item");
|
||||
surf.insert_data(panel_item_weak.clone());
|
||||
|
||||
let Some(panel_item) = surface_panel_item(surf) else {
|
||||
warn!("Failed to link surface to panel item");
|
||||
return;
|
||||
};
|
||||
|
||||
surf.with_child_info(|_info| {
|
||||
panel_item.backend.reposition_child(surf);
|
||||
});
|
||||
|
||||
debug!("Adding new child to panel item");
|
||||
panel_item.backend.new_child(surf);
|
||||
});
|
||||
|
||||
@@ -88,6 +108,7 @@ impl CompositorHandler for WaylandState {
|
||||
.get_data_raw::<RendererSurfaceStateUserData, _, _>(|s| s.lock().ok()?.view())
|
||||
.flatten()
|
||||
else {
|
||||
debug!("No view data for surface");
|
||||
return;
|
||||
};
|
||||
let mut changed = false;
|
||||
@@ -96,11 +117,13 @@ impl CompositorHandler for WaylandState {
|
||||
&& info.geometry.origin.y != view.offset.y
|
||||
{
|
||||
changed = true;
|
||||
debug!("Surface position changed");
|
||||
}
|
||||
if info.geometry.size.x != view.dst.w as u32
|
||||
&& info.geometry.size.y != view.dst.h as u32
|
||||
{
|
||||
changed = true;
|
||||
debug!("Surface size changed");
|
||||
}
|
||||
info.geometry.size = [view.dst.w as u32, view.dst.h as u32].into();
|
||||
});
|
||||
@@ -109,6 +132,7 @@ impl CompositorHandler for WaylandState {
|
||||
return;
|
||||
};
|
||||
if changed {
|
||||
debug!("Repositioning child due to geometry change");
|
||||
panel_item.backend.reposition_child(surf);
|
||||
}
|
||||
});
|
||||
@@ -119,6 +143,7 @@ impl CompositorHandler for WaylandState {
|
||||
return;
|
||||
};
|
||||
if surface.get_child_info().is_some() {
|
||||
debug!("Dropping destroyed child surface");
|
||||
panel_item.backend.drop_child(surface);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user