fix: wayland inconsistencies
This commit is contained in:
38
Cargo.lock
generated
38
Cargo.lock
generated
@@ -842,22 +842,23 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "drm"
|
name = "drm"
|
||||||
version = "0.12.0"
|
version = "0.14.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "98888c4bbd601524c11a7ed63f814b8825f420514f78e96f752c437ae9cbb5d1"
|
checksum = "80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"drm-ffi",
|
"drm-ffi",
|
||||||
"drm-fourcc",
|
"drm-fourcc",
|
||||||
|
"libc",
|
||||||
"rustix",
|
"rustix",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "drm-ffi"
|
name = "drm-ffi"
|
||||||
version = "0.8.0"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97c98727e48b7ccb4f4aea8cfe881e5b07f702d17b7875991881b41af7278d53"
|
checksum = "d8e41459d99a9b529845f6d2c909eb9adf3b6d2f82635ae40be8de0601726e8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"drm-sys",
|
"drm-sys",
|
||||||
"rustix",
|
"rustix",
|
||||||
@@ -871,9 +872,9 @@ checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "drm-sys"
|
name = "drm-sys"
|
||||||
version = "0.7.0"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd39dde40b6e196c2e8763f23d119ddb1a8714534bf7d77fa97a65b0feda3986"
|
checksum = "bafb66c8dbc944d69e15cfcc661df7e703beffbaec8bd63151368b06c5f9858c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.6.5",
|
"linux-raw-sys 0.6.5",
|
||||||
@@ -1519,7 +1520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2449,12 +2450,6 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scan_fmt"
|
|
||||||
version = "0.2.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0b53b0a5db882a8e2fdaae0a43f7b39e7e9082389e978398bdf223a55b581248"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scoped-tls"
|
name = "scoped-tls"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@@ -2600,8 +2595,8 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay"
|
name = "smithay"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "git+https://github.com/smithay/smithay.git#656178be0a19ae4c577c9c93a3d4ebfdb80e649c"
|
source = "git+https://github.com/smithay/smithay.git#0c2230f858580b52d628087d6dae1795278b8756"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"appendlist",
|
"appendlist",
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
@@ -2615,14 +2610,11 @@ dependencies = [
|
|||||||
"errno",
|
"errno",
|
||||||
"gl_generator",
|
"gl_generator",
|
||||||
"indexmap 2.5.0",
|
"indexmap 2.5.0",
|
||||||
"lazy_static",
|
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading",
|
||||||
"once_cell",
|
|
||||||
"profiling",
|
"profiling",
|
||||||
"rand",
|
"rand",
|
||||||
"rustix",
|
"rustix",
|
||||||
"scan_fmt",
|
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 1.0.63",
|
"thiserror 1.0.63",
|
||||||
@@ -3302,9 +3294,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-protocols"
|
name = "wayland-protocols"
|
||||||
version = "0.32.4"
|
version = "0.32.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b5755d77ae9040bb872a25026555ce4cb0ae75fd923e90d25fba07d81057de0"
|
checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
@@ -3351,9 +3343,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-server"
|
name = "wayland-server"
|
||||||
version = "0.31.5"
|
version = "0.31.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f18d47038c0b10479e695d99ed073e400ccd9bdbb60e6e503c96f62adcb12b6"
|
checksum = "c89532cc712a2adb119eb4d09694b402576052254d0bb284f82ac1c47fb786ad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"downcast-rs",
|
"downcast-rs",
|
||||||
@@ -3396,7 +3388,7 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -8,18 +8,20 @@ use crate::{
|
|||||||
wayland::surface::CoreSurface,
|
wayland::surface::CoreSurface,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use portable_atomic::{AtomicU32, Ordering};
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::utils::{on_commit_buffer_handler, RendererSurfaceStateUserData},
|
backend::renderer::utils::{on_commit_buffer_handler, RendererSurfaceStateUserData},
|
||||||
delegate_compositor,
|
delegate_compositor,
|
||||||
|
desktop::PopupKind,
|
||||||
reexports::wayland_server::{protocol::wl_surface::WlSurface, Client},
|
reexports::wayland_server::{protocol::wl_surface::WlSurface, Client},
|
||||||
wayland::compositor::{
|
wayland::compositor::{
|
||||||
self, add_post_commit_hook, CompositorClientState, CompositorHandler, CompositorState,
|
add_post_commit_hook, CompositorClientState, CompositorHandler, CompositorState,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::debug;
|
use tracing::{debug, warn};
|
||||||
|
|
||||||
|
pub struct ConfiguredSurface;
|
||||||
|
|
||||||
impl CompositorHandler for WaylandState {
|
impl CompositorHandler for WaylandState {
|
||||||
fn compositor_state(&mut self) -> &mut CompositorState {
|
fn compositor_state(&mut self) -> &mut CompositorState {
|
||||||
@@ -30,19 +32,27 @@ impl CompositorHandler for WaylandState {
|
|||||||
debug!(?surface, "Surface commit");
|
debug!(?surface, "Surface commit");
|
||||||
|
|
||||||
on_commit_buffer_handler::<WaylandState>(surface);
|
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 {
|
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));
|
surface.insert_data(SurfaceId::Child(id));
|
||||||
CoreSurface::add_to(surface);
|
CoreSurface::add_to(surface);
|
||||||
let Some(parent_surface_id) = parent.get_data::<SurfaceId>() else {
|
let Some(parent_surface_id) = parent.get_data::<SurfaceId>() else {
|
||||||
|
warn!("Parent surface has no SurfaceId");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
surface.insert_data(Mutex::new(ChildInfo {
|
surface.insert_data(Mutex::new(ChildInfo {
|
||||||
@@ -68,6 +79,7 @@ impl CompositorHandler for WaylandState {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
let Some(panel_item) = surface_panel_item(parent) else {
|
let Some(panel_item) = surface_panel_item(parent) else {
|
||||||
|
warn!("Parent has no panel item");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let panel_item_weak = Arc::downgrade(&panel_item);
|
let panel_item_weak = Arc::downgrade(&panel_item);
|
||||||
@@ -75,11 +87,19 @@ impl CompositorHandler for WaylandState {
|
|||||||
if surface_panel_item(surf).is_some() {
|
if surface_panel_item(surf).is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
debug!("Linking surface to panel item");
|
||||||
surf.insert_data(panel_item_weak.clone());
|
surf.insert_data(panel_item_weak.clone());
|
||||||
|
|
||||||
let Some(panel_item) = surface_panel_item(surf) else {
|
let Some(panel_item) = surface_panel_item(surf) else {
|
||||||
|
warn!("Failed to link surface to panel item");
|
||||||
return;
|
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);
|
panel_item.backend.new_child(surf);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -88,6 +108,7 @@ impl CompositorHandler for WaylandState {
|
|||||||
.get_data_raw::<RendererSurfaceStateUserData, _, _>(|s| s.lock().ok()?.view())
|
.get_data_raw::<RendererSurfaceStateUserData, _, _>(|s| s.lock().ok()?.view())
|
||||||
.flatten()
|
.flatten()
|
||||||
else {
|
else {
|
||||||
|
debug!("No view data for surface");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
@@ -96,11 +117,13 @@ impl CompositorHandler for WaylandState {
|
|||||||
&& info.geometry.origin.y != view.offset.y
|
&& info.geometry.origin.y != view.offset.y
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
|
debug!("Surface position changed");
|
||||||
}
|
}
|
||||||
if info.geometry.size.x != view.dst.w as u32
|
if info.geometry.size.x != view.dst.w as u32
|
||||||
&& info.geometry.size.y != view.dst.h as u32
|
&& info.geometry.size.y != view.dst.h as u32
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
|
debug!("Surface size changed");
|
||||||
}
|
}
|
||||||
info.geometry.size = [view.dst.w as u32, view.dst.h as u32].into();
|
info.geometry.size = [view.dst.w as u32, view.dst.h as u32].into();
|
||||||
});
|
});
|
||||||
@@ -109,6 +132,7 @@ impl CompositorHandler for WaylandState {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if changed {
|
if changed {
|
||||||
|
debug!("Repositioning child due to geometry change");
|
||||||
panel_item.backend.reposition_child(surf);
|
panel_item.backend.reposition_child(surf);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -119,6 +143,7 @@ impl CompositorHandler for WaylandState {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if surface.get_child_info().is_some() {
|
if surface.get_child_info().is_some() {
|
||||||
|
debug!("Dropping destroyed child surface");
|
||||||
panel_item.backend.drop_child(surface);
|
panel_item.backend.drop_child(surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ impl SeatWrapper {
|
|||||||
}
|
}
|
||||||
keyboard.input(
|
keyboard.input(
|
||||||
&mut state.lock(),
|
&mut state.lock(),
|
||||||
key,
|
key.into(),
|
||||||
if pressed {
|
if pressed {
|
||||||
KeyState::Pressed
|
KeyState::Pressed
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use smithay::{
|
|||||||
renderer::gles::GlesRenderer,
|
renderer::gles::GlesRenderer,
|
||||||
},
|
},
|
||||||
delegate_dmabuf, delegate_output, delegate_shm,
|
delegate_dmabuf, delegate_output, delegate_shm,
|
||||||
|
desktop::PopupManager,
|
||||||
input::{keyboard::XkbConfig, SeatState},
|
input::{keyboard::XkbConfig, SeatState},
|
||||||
output::{Mode, Output, Scale, Subpixel},
|
output::{Mode, Output, Scale, Subpixel},
|
||||||
reexports::{
|
reexports::{
|
||||||
@@ -76,6 +77,7 @@ pub struct WaylandState {
|
|||||||
pub seat_state: SeatState<Self>,
|
pub seat_state: SeatState<Self>,
|
||||||
pub seat: Arc<SeatWrapper>,
|
pub seat: Arc<SeatWrapper>,
|
||||||
pub xdg_shell: XdgShellState,
|
pub xdg_shell: XdgShellState,
|
||||||
|
pub popup_manager: PopupManager,
|
||||||
pub output: Output,
|
pub output: Output,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,6 +160,7 @@ impl WaylandState {
|
|||||||
output.set_preferred(mode);
|
output.set_preferred(mode);
|
||||||
|
|
||||||
let mut xdg_shell = XdgShellState::new::<Self>(&display_handle);
|
let mut xdg_shell = XdgShellState::new::<Self>(&display_handle);
|
||||||
|
let popup_manager = PopupManager::default();
|
||||||
let mut capabilities = WmCapabilitySet::default();
|
let mut capabilities = WmCapabilitySet::default();
|
||||||
capabilities.set(WmCapabilities::Maximize);
|
capabilities.set(WmCapabilities::Maximize);
|
||||||
capabilities.set(WmCapabilities::Fullscreen);
|
capabilities.set(WmCapabilities::Fullscreen);
|
||||||
@@ -182,6 +185,7 @@ impl WaylandState {
|
|||||||
seat_state,
|
seat_state,
|
||||||
seat: Arc::new(SeatWrapper::new(weak.clone(), seat)),
|
seat: Arc::new(SeatWrapper::new(weak.clone(), seat)),
|
||||||
xdg_shell,
|
xdg_shell,
|
||||||
|
popup_manager,
|
||||||
output,
|
output,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use rand::Rng;
|
|||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
delegate_xdg_shell,
|
delegate_xdg_shell,
|
||||||
|
desktop::PopupKind,
|
||||||
reexports::{
|
reexports::{
|
||||||
wayland_protocols::xdg::{
|
wayland_protocols::xdg::{
|
||||||
decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode,
|
decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode,
|
||||||
@@ -90,7 +91,6 @@ impl XdgShellHandler for WaylandState {
|
|||||||
s.states.set(State::Maximized);
|
s.states.set(State::Maximized);
|
||||||
s.states.unset(State::Fullscreen);
|
s.states.unset(State::Fullscreen);
|
||||||
});
|
});
|
||||||
toplevel.send_configure();
|
|
||||||
|
|
||||||
let initial_size = toplevel
|
let initial_size = toplevel
|
||||||
.wl_surface()
|
.wl_surface()
|
||||||
@@ -225,14 +225,17 @@ impl XdgShellHandler for WaylandState {
|
|||||||
};
|
};
|
||||||
panel_item.toplevel_title_changed(&title)
|
panel_item.toplevel_title_changed(&title)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_popup(&mut self, popup: PopupSurface, positioner: PositionerState) {
|
fn new_popup(&mut self, popup: PopupSurface, positioner: PositionerState) {
|
||||||
|
self.popup_manager
|
||||||
|
.track_popup(PopupKind::Xdg(popup.clone()))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let id = rand::thread_rng().gen_range(0..u64::MAX);
|
let id = rand::thread_rng().gen_range(0..u64::MAX);
|
||||||
popup.wl_surface().insert_data(SurfaceId::Child(id));
|
popup.wl_surface().insert_data(SurfaceId::Child(id));
|
||||||
let Some(parent) = popup.get_parent_surface() else {
|
let Some(parent) = popup.get_parent_surface() else {
|
||||||
|
warn!("No parent surface found for popup");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let _ = popup.send_configure();
|
|
||||||
CoreSurface::add_to(popup.wl_surface());
|
CoreSurface::add_to(popup.wl_surface());
|
||||||
|
|
||||||
popup.wl_surface().insert_data(Mutex::new(ChildInfo {
|
popup.wl_surface().insert_data(Mutex::new(ChildInfo {
|
||||||
@@ -244,6 +247,7 @@ impl XdgShellHandler for WaylandState {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
let Some(panel_item) = surface_panel_item(&parent) else {
|
let Some(panel_item) = surface_panel_item(&parent) else {
|
||||||
|
warn!("No panel item found for popup parent");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let panel_item_weak = Arc::downgrade(&panel_item);
|
let panel_item_weak = Arc::downgrade(&panel_item);
|
||||||
@@ -255,6 +259,7 @@ impl XdgShellHandler for WaylandState {
|
|||||||
}
|
}
|
||||||
surf.insert_data(panel_item_weak.clone());
|
surf.insert_data(panel_item_weak.clone());
|
||||||
let Some(panel) = surface_panel_item(surf) else {
|
let Some(panel) = surface_panel_item(surf) else {
|
||||||
|
warn!("Failed to get panel item for popup surface");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
panel.backend.new_child(surf);
|
panel.backend.new_child(surf);
|
||||||
|
|||||||
Reference in New Issue
Block a user