refactor: app state as single src of truth for wayland events

This commit is contained in:
drendog 2025-11-17 00:22:31 +01:00
parent 84121a2162
commit 8cd94cd13e
Signed by: dwenya
GPG key ID: 8DD77074645332D0
3 changed files with 174 additions and 414 deletions

View file

@ -1,13 +1,10 @@
use crate::wayland::surfaces::app_state::AppState; use crate::wayland::surfaces::app_state::AppState;
use crate::wayland::surfaces::display_metrics::DisplayMetrics; use crate::wayland::surfaces::display_metrics::DisplayMetrics;
use log::info; use log::info;
use slint::PhysicalSize;
use slint::platform::{PointerEventButton, WindowEvent};
use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::{ use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::{
zwlr_layer_shell_v1::ZwlrLayerShellV1, zwlr_layer_shell_v1::ZwlrLayerShellV1,
zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1}, zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1},
}; };
use wayland_client::WEnum;
use wayland_client::{ use wayland_client::{
Connection, Dispatch, Proxy, QueueHandle, Connection, Dispatch, Proxy, QueueHandle,
globals::GlobalListContents, globals::GlobalListContents,
@ -35,9 +32,6 @@ use wayland_protocols::xdg::shell::client::{
}; };
impl Dispatch<ZwlrLayerSurfaceV1, ()> for AppState { impl Dispatch<ZwlrLayerSurfaceV1, ()> for AppState {
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::cast_precision_loss)]
fn event( fn event(
state: &mut Self, state: &mut Self,
layer_surface: &ZwlrLayerSurfaceV1, layer_surface: &ZwlrLayerSurfaceV1,
@ -52,9 +46,6 @@ impl Dispatch<ZwlrLayerSurfaceV1, ()> for AppState {
width, width,
height, height,
} => { } => {
info!("Layer surface configured with compositor size: {width}x{height}");
layer_surface.ack_configure(serial);
let layer_surface_id = layer_surface.id(); let layer_surface_id = layer_surface.id();
let Some(window) = state.get_output_by_layer_surface_mut(&layer_surface_id) else { let Some(window) = state.get_output_by_layer_surface_mut(&layer_surface_id) else {
info!( info!(
@ -64,46 +55,13 @@ impl Dispatch<ZwlrLayerSurfaceV1, ()> for AppState {
return; return;
}; };
let output_width = window.output_size().width; window.handle_layer_surface_configure(layer_surface, serial, width, height);
let scale_factor = window.scale_factor();
let target_width = if width == 0 || (width == 1 && output_width > 1) {
if scale_factor > 1.0 {
(output_width as f32 / scale_factor).round() as u32
} else {
output_width
}
} else {
width
};
let target_height = if height > 0 {
height
} else {
let h = window.height();
if scale_factor > 1.0 {
(h as f32 / scale_factor).round() as u32
} else {
h
}
};
let clamped_width = target_width.min(output_width);
info!(
"Using dimensions: {}x{} (clamped from {}x{}, output: {}x{})",
clamped_width,
target_height,
target_width,
target_height,
output_width,
window.output_size().height
);
window.update_size(clamped_width, target_height);
} }
zwlr_layer_surface_v1::Event::Closed => { zwlr_layer_surface_v1::Event::Closed => {
info!("Layer surface closed"); let layer_surface_id = layer_surface.id();
if let Some(window) = state.get_output_by_layer_surface_mut(&layer_surface_id) {
window.handle_layer_surface_closed();
}
} }
_ => {} _ => {}
} }
@ -121,13 +79,9 @@ impl Dispatch<WlOutput, ()> for AppState {
) { ) {
match event { match event {
wl_output::Event::Mode { width, height, .. } => { wl_output::Event::Mode { width, height, .. } => {
info!("WlOutput size changed to {width}x{height}");
let width = width.try_into().unwrap_or_default();
let height = height.try_into().unwrap_or_default();
let output_id = proxy.id(); let output_id = proxy.id();
if let Some(window) = state.get_output_by_output_id_mut(&output_id) { if let Some(window) = state.get_output_by_output_id_mut(&output_id) {
window.set_output_size(PhysicalSize::new(width, height)); window.handle_output_mode(width, height);
} }
} }
wl_output::Event::Description { ref description } => { wl_output::Event::Description { ref description } => {
@ -182,11 +136,7 @@ impl Dispatch<WlPointer, ()> for AppState {
let surface_id = surface.id(); let surface_id = surface.id();
if let Some(window) = state.get_output_by_surface_mut(&surface_id) { if let Some(window) = state.get_output_by_surface_mut(&surface_id) {
window.set_last_pointer_serial(serial); window.handle_pointer_enter(serial, &surface, surface_x, surface_y);
window.set_current_pointer_position(surface_x, surface_y);
window.set_entered_surface(&surface);
let position = window.current_pointer_position();
window.dispatch_to_active_window(WindowEvent::PointerMoved { position });
if let Some(key) = state.get_key_by_surface(&surface_id).cloned() { if let Some(key) = state.get_key_by_surface(&surface_id).cloned() {
state.set_active_output(Some(key)); state.set_active_output(Some(key));
@ -194,11 +144,7 @@ impl Dispatch<WlPointer, ()> for AppState {
} else { } else {
let key = state.get_key_by_popup(&surface_id); let key = state.get_key_by_popup(&surface_id);
if let Some(window) = state.find_output_by_popup_mut(&surface_id) { if let Some(window) = state.find_output_by_popup_mut(&surface_id) {
window.set_last_pointer_serial(serial); window.handle_pointer_enter(serial, &surface, surface_x, surface_y);
window.set_current_pointer_position(surface_x, surface_y);
window.set_entered_surface(&surface);
let position = window.current_pointer_position();
window.dispatch_to_active_window(WindowEvent::PointerMoved { position });
if let Some(key) = key { if let Some(key) = key {
state.set_active_output(Some(key)); state.set_active_output(Some(key));
@ -214,9 +160,7 @@ impl Dispatch<WlPointer, ()> for AppState {
} => { } => {
if let Some(output_key) = state.active_output().cloned() { if let Some(output_key) = state.active_output().cloned() {
if let Some(window) = state.get_output_by_key_mut(&output_key) { if let Some(window) = state.get_output_by_key_mut(&output_key) {
window.set_current_pointer_position(surface_x, surface_y); window.handle_pointer_motion(surface_x, surface_y);
let position = window.current_pointer_position();
window.dispatch_to_active_window(WindowEvent::PointerMoved { position });
} }
} }
} }
@ -224,8 +168,7 @@ impl Dispatch<WlPointer, ()> for AppState {
wl_pointer::Event::Leave { .. } => { wl_pointer::Event::Leave { .. } => {
if let Some(output_key) = state.active_output().cloned() { if let Some(output_key) = state.active_output().cloned() {
if let Some(window) = state.get_output_by_key_mut(&output_key) { if let Some(window) = state.get_output_by_key_mut(&output_key) {
window.dispatch_to_active_window(WindowEvent::PointerExited); window.handle_pointer_leave();
window.clear_entered_surface();
} }
} }
state.set_active_output(None); state.set_active_output(None);
@ -238,21 +181,7 @@ impl Dispatch<WlPointer, ()> for AppState {
} => { } => {
if let Some(output_key) = state.active_output().cloned() { if let Some(output_key) = state.active_output().cloned() {
if let Some(window) = state.get_output_by_key_mut(&output_key) { if let Some(window) = state.get_output_by_key_mut(&output_key) {
window.set_last_pointer_serial(serial); window.handle_pointer_button(serial, button_state);
let position = window.current_pointer_position();
let event = match button_state {
WEnum::Value(wl_pointer::ButtonState::Pressed) => {
WindowEvent::PointerPressed {
button: PointerEventButton::Left,
position,
}
}
_ => WindowEvent::PointerReleased {
button: PointerEventButton::Left,
position,
},
};
window.dispatch_to_active_window(event);
} }
} }
} }
@ -275,7 +204,7 @@ impl Dispatch<WpFractionalScaleV1, ()> for AppState {
info!("Fractional scale received: {scale_float} ({scale}x)"); info!("Fractional scale received: {scale_float} ({scale}x)");
for window in state.all_outputs_mut() { for window in state.all_outputs_mut() {
window.update_scale_for_fractional_scale_object(proxy, scale); window.handle_fractional_scale(proxy, scale);
} }
} }
} }
@ -291,8 +220,8 @@ impl Dispatch<XdgWmBase, ()> for AppState {
_qhandle: &QueueHandle<Self>, _qhandle: &QueueHandle<Self>,
) { ) {
if let xdg_wm_base::Event::Ping { serial } = event { if let xdg_wm_base::Event::Ping { serial } = event {
info!("XdgWmBase ping received, sending pong with serial {serial}"); use crate::wayland::surfaces::surface_state::WindowState;
xdg_wm_base.pong(serial); WindowState::handle_xdg_wm_base_ping(xdg_wm_base, serial);
} }
} }
} }
@ -313,17 +242,11 @@ impl Dispatch<XdgPopup, ()> for AppState {
width, width,
height, height,
} => { } => {
info!("XdgPopup Configure: position=({x}, {y}), size=({width}x{height})");
let popup_id = xdg_popup.id(); let popup_id = xdg_popup.id();
for window in state.all_outputs_mut() { for window in state.all_outputs_mut() {
if let Some(popup_manager) = window.popup_manager() { if let Some(popup_manager) = window.popup_manager() {
if let Some(handle) = popup_manager.find_by_xdg_popup(&popup_id) { if popup_manager.find_by_xdg_popup(&popup_id).is_some() {
info!( window.handle_xdg_popup_configure(xdg_popup, x, y, width, height);
"Marking popup with handle {handle:?} as configured after XdgPopup::Configure"
);
popup_manager.mark_popup_configured(handle.key());
popup_manager.mark_all_popups_dirty();
break; break;
} }
} }
@ -339,11 +262,8 @@ impl Dispatch<XdgPopup, ()> for AppState {
.as_ref() .as_ref()
.and_then(|pm| pm.find_by_xdg_popup(&popup_id)); .and_then(|pm| pm.find_by_xdg_popup(&popup_id));
if let Some(handle) = popup_handle { if popup_handle.is_some() {
info!("Destroying popup with handle {handle:?}"); window.handle_xdg_popup_done(xdg_popup);
if let Some(popup_manager) = window.popup_manager() {
let _result = popup_manager.close(handle);
}
break; break;
} }
} }
@ -366,15 +286,11 @@ impl Dispatch<XdgSurface, ()> for AppState {
_qhandle: &QueueHandle<Self>, _qhandle: &QueueHandle<Self>,
) { ) {
if let xdg_surface::Event::Configure { serial } = event { if let xdg_surface::Event::Configure { serial } = event {
info!("XdgSurface Configure received, sending ack with serial {serial}");
xdg_surface.ack_configure(serial);
let xdg_surface_id = xdg_surface.id(); let xdg_surface_id = xdg_surface.id();
for window in state.all_outputs_mut() { for window in state.all_outputs_mut() {
if let Some(popup_manager) = window.popup_manager() { if let Some(popup_manager) = window.popup_manager() {
if popup_manager.find_by_xdg_surface(&xdg_surface_id).is_some() { if popup_manager.find_by_xdg_surface(&xdg_surface_id).is_some() {
info!("Marking all popups as dirty after Configure"); window.handle_xdg_surface_configure(xdg_surface, serial);
popup_manager.mark_all_popups_dirty();
break; break;
} }
} }

View file

@ -1,4 +1,3 @@
use crate::impl_empty_dispatch;
use crate::wayland::surfaces::surface_state::WindowState; use crate::wayland::surfaces::surface_state::WindowState;
use log::info; use log::info;
use slint::{ use slint::{
@ -6,59 +5,41 @@ use slint::{
platform::{PointerEventButton, WindowEvent}, platform::{PointerEventButton, WindowEvent},
}; };
use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::{ use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::{
zwlr_layer_shell_v1::ZwlrLayerShellV1, zwlr_layer_surface_v1::ZwlrLayerSurfaceV1,
zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1},
}; };
use wayland_client::WEnum; use wayland_client::WEnum;
use wayland_client::{ use wayland_client::{
Connection, Dispatch, Proxy, QueueHandle, Proxy,
globals::GlobalListContents,
protocol::{ protocol::{
wl_compositor::WlCompositor, wl_pointer,
wl_output::{self, WlOutput},
wl_pointer::{self, WlPointer},
wl_registry::WlRegistry,
wl_seat::WlSeat,
wl_surface::WlSurface, wl_surface::WlSurface,
}, },
}; };
use wayland_protocols::wp::fractional_scale::v1::client::{ use wayland_protocols::wp::fractional_scale::v1::client::{
wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1, wp_fractional_scale_v1::WpFractionalScaleV1,
wp_fractional_scale_v1::{self, WpFractionalScaleV1},
};
use wayland_protocols::wp::viewporter::client::{
wp_viewport::WpViewport, wp_viewporter::WpViewporter,
}; };
use wayland_protocols::xdg::shell::client::{ use wayland_protocols::xdg::shell::client::{
xdg_popup::{self, XdgPopup}, xdg_popup::XdgPopup,
xdg_positioner::XdgPositioner, xdg_surface::XdgSurface,
xdg_surface::{self, XdgSurface}, xdg_wm_base::XdgWmBase,
xdg_wm_base::{self, XdgWmBase},
}; };
impl Dispatch<ZwlrLayerSurfaceV1, ()> for WindowState { impl WindowState {
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_sign_loss)] #[allow(clippy::cast_sign_loss)]
#[allow(clippy::cast_precision_loss)] #[allow(clippy::cast_precision_loss)]
fn event( pub(crate) fn handle_layer_surface_configure(
state: &mut Self, &mut self,
layer_surface: &ZwlrLayerSurfaceV1, layer_surface: &ZwlrLayerSurfaceV1,
event: zwlr_layer_surface_v1::Event, serial: u32,
_data: &(), width: u32,
_conn: &Connection, height: u32,
_queue_handle: &QueueHandle<Self>,
) { ) {
match event {
zwlr_layer_surface_v1::Event::Configure {
serial,
width,
height,
} => {
info!("Layer surface configured with compositor size: {width}x{height}"); info!("Layer surface configured with compositor size: {width}x{height}");
layer_surface.ack_configure(serial); layer_surface.ack_configure(serial);
let output_width = state.output_size().width; let output_width = self.output_size().width;
let scale_factor = state.scale_factor(); let scale_factor = self.scale_factor();
let target_width = if width == 0 || (width == 1 && output_width > 1) { let target_width = if width == 0 || (width == 1 && output_width > 1) {
if scale_factor > 1.0 { if scale_factor > 1.0 {
@ -73,7 +54,7 @@ impl Dispatch<ZwlrLayerSurfaceV1, ()> for WindowState {
let target_height = if height > 0 { let target_height = if height > 0 {
height height
} else { } else {
let h = state.height(); let h = self.height();
if scale_factor > 1.0 { if scale_factor > 1.0 {
(h as f32 / scale_factor).round() as u32 (h as f32 / scale_factor).round() as u32
} else { } else {
@ -90,115 +71,60 @@ impl Dispatch<ZwlrLayerSurfaceV1, ()> for WindowState {
target_width, target_width,
target_height, target_height,
output_width, output_width,
state.output_size().height self.output_size().height
); );
state.update_size(clamped_width, target_height); self.update_size(clamped_width, target_height);
} }
zwlr_layer_surface_v1::Event::Closed => {
#[allow(clippy::unused_self)]
pub(crate) fn handle_layer_surface_closed(&mut self) {
info!("Layer surface closed"); info!("Layer surface closed");
} }
_ => {}
}
}
}
impl Dispatch<WlOutput, ()> for WindowState { pub(crate) fn handle_output_mode(&mut self, width: i32, height: i32) {
fn event(
state: &mut Self,
_proxy: &WlOutput,
event: <WlOutput as Proxy>::Event,
_data: &(),
_conn: &Connection,
_qhandle: &QueueHandle<Self>,
) {
match event {
wl_output::Event::Mode { width, height, .. } => {
info!("WlOutput size changed to {width}x{height}"); info!("WlOutput size changed to {width}x{height}");
let width = width.try_into().unwrap_or_default(); let width = width.try_into().unwrap_or_default();
let height = height.try_into().unwrap_or_default(); let height = height.try_into().unwrap_or_default();
state.set_output_size(PhysicalSize::new(width, height)); self.set_output_size(PhysicalSize::new(width, height));
} }
wl_output::Event::Description { ref description } => {
info!("WlOutput description: {description:?}");
}
wl_output::Event::Scale { ref factor } => {
info!("WlOutput factor scale: {factor:?}");
}
wl_output::Event::Name { ref name } => {
info!("WlOutput name: {name:?}");
}
wl_output::Event::Geometry {
x,
y,
physical_width,
physical_height,
subpixel,
make,
model,
transform,
} => {
info!(
"WlOutput geometry: x={x}, y={y}, physical_width={physical_width}, physical_height={physical_height}, subpixel={subpixel:?}, make={make:?}, model={model:?}, transform={transform:?}"
);
}
wl_output::Event::Done => {
info!("WlOutput done");
}
_ => {}
}
}
}
impl Dispatch<WlPointer, ()> for WindowState { pub(crate) fn handle_pointer_enter(
fn event( &mut self,
state: &mut Self, serial: u32,
_proxy: &WlPointer, surface: &WlSurface,
event: <WlPointer as Proxy>::Event, surface_x: f64,
_data: &(), surface_y: f64,
_conn: &Connection,
_qhandle: &QueueHandle<Self>,
) { ) {
match event {
wl_pointer::Event::Enter {
serial,
surface,
surface_x,
surface_y,
} => {
info!("Pointer entered surface {:?}", surface.id()); info!("Pointer entered surface {:?}", surface.id());
state.set_last_pointer_serial(serial); self.set_last_pointer_serial(serial);
state.set_current_pointer_position(surface_x, surface_y); self.set_current_pointer_position(surface_x, surface_y);
state.set_entered_surface(&surface); self.set_entered_surface(surface);
let position = state.current_pointer_position(); let position = self.current_pointer_position();
state.dispatch_to_active_window(WindowEvent::PointerMoved { position }); self.dispatch_to_active_window(WindowEvent::PointerMoved { position });
} }
wl_pointer::Event::Motion { pub(crate) fn handle_pointer_motion(&mut self, surface_x: f64, surface_y: f64) {
surface_x, self.set_current_pointer_position(surface_x, surface_y);
surface_y, let position = self.current_pointer_position();
..
} => {
state.set_current_pointer_position(surface_x, surface_y);
let position = state.current_pointer_position();
state.dispatch_to_active_window(WindowEvent::PointerMoved { position }); self.dispatch_to_active_window(WindowEvent::PointerMoved { position });
} }
wl_pointer::Event::Leave { .. } => { pub(crate) fn handle_pointer_leave(&mut self) {
state.dispatch_to_active_window(WindowEvent::PointerExited); self.dispatch_to_active_window(WindowEvent::PointerExited);
state.clear_entered_surface(); self.clear_entered_surface();
} }
wl_pointer::Event::Button { pub(crate) fn handle_pointer_button(
serial, &mut self,
state: button_state, serial: u32,
.. button_state: WEnum<wl_pointer::ButtonState>,
} => { ) {
state.set_last_pointer_serial(serial); self.set_last_pointer_serial(serial);
let position = state.current_pointer_position(); let position = self.current_pointer_position();
let event = match button_state { let event = match button_state {
WEnum::Value(wl_pointer::ButtonState::Pressed) => WindowEvent::PointerPressed { WEnum::Value(wl_pointer::ButtonState::Pressed) => WindowEvent::PointerPressed {
button: PointerEventButton::Left, button: PointerEventButton::Left,
@ -210,66 +136,27 @@ impl Dispatch<WlPointer, ()> for WindowState {
}, },
}; };
state.dispatch_to_active_window(event); self.dispatch_to_active_window(event);
} }
_ => {}
}
}
}
impl Dispatch<WpFractionalScaleV1, ()> for WindowState { pub(crate) fn handle_fractional_scale(&mut self, proxy: &WpFractionalScaleV1, scale: u32) {
fn event(
state: &mut Self,
proxy: &WpFractionalScaleV1,
event: wp_fractional_scale_v1::Event,
_data: &(),
_conn: &Connection,
_qhandle: &QueueHandle<Self>,
) {
if let wp_fractional_scale_v1::Event::PreferredScale { scale } = event {
use crate::wayland::surfaces::display_metrics::DisplayMetrics; use crate::wayland::surfaces::display_metrics::DisplayMetrics;
let scale_float = DisplayMetrics::scale_factor_from_120ths(scale); let scale_float = DisplayMetrics::scale_factor_from_120ths(scale);
info!("Fractional scale received: {scale_float} ({scale}x)"); info!("Fractional scale received: {scale_float} ({scale}x)");
state.update_scale_for_fractional_scale_object(proxy, scale); self.update_scale_for_fractional_scale_object(proxy, scale);
} }
}
}
impl Dispatch<XdgWmBase, ()> for WindowState { pub(crate) fn handle_xdg_popup_configure(
fn event( &mut self,
_state: &mut Self,
xdg_wm_base: &XdgWmBase,
event: xdg_wm_base::Event,
_data: &(),
_conn: &Connection,
_qhandle: &QueueHandle<Self>,
) {
if let xdg_wm_base::Event::Ping { serial } = event {
info!("XdgWmBase ping received, sending pong with serial {serial}");
xdg_wm_base.pong(serial);
}
}
}
impl Dispatch<XdgPopup, ()> for WindowState {
fn event(
state: &mut Self,
xdg_popup: &XdgPopup, xdg_popup: &XdgPopup,
event: xdg_popup::Event, x: i32,
_data: &(), y: i32,
_conn: &Connection, width: i32,
_qhandle: &QueueHandle<Self>, height: i32,
) { ) {
match event {
xdg_popup::Event::Configure {
x,
y,
width,
height,
} => {
info!("XdgPopup Configure: position=({x}, {y}), size=({width}x{height})"); info!("XdgPopup Configure: position=({x}, {y}), size=({width}x{height})");
if let Some(popup_manager) = state.popup_manager() { if let Some(popup_manager) = self.popup_manager() {
let popup_id = xdg_popup.id(); let popup_id = xdg_popup.id();
if let Some(handle) = popup_manager.find_by_xdg_popup(&popup_id) { if let Some(handle) = popup_manager.find_by_xdg_popup(&popup_id) {
info!( info!(
@ -280,58 +167,35 @@ impl Dispatch<XdgPopup, ()> for WindowState {
} }
} }
} }
xdg_popup::Event::PopupDone => {
pub(crate) fn handle_xdg_popup_done(&mut self, xdg_popup: &XdgPopup) {
info!("XdgPopup dismissed by compositor"); info!("XdgPopup dismissed by compositor");
let popup_id = xdg_popup.id(); let popup_id = xdg_popup.id();
let popup_handle = state let popup_handle = self
.popup_manager() .popup_manager()
.as_ref() .as_ref()
.and_then(|pm| pm.find_by_xdg_popup(&popup_id)); .and_then(|pm| pm.find_by_xdg_popup(&popup_id));
if let Some(handle) = popup_handle { if let Some(handle) = popup_handle {
info!("Destroying popup with handle {handle:?}"); info!("Destroying popup with handle {handle:?}");
if let Some(popup_manager) = state.popup_manager() { if let Some(popup_manager) = self.popup_manager() {
let _result = popup_manager.close(handle); let _result = popup_manager.close(handle);
} }
} }
} }
xdg_popup::Event::Repositioned { token } => {
info!("XdgPopup repositioned with token {token}");
}
_ => {}
}
}
}
impl Dispatch<XdgSurface, ()> for WindowState { pub(crate) fn handle_xdg_surface_configure(&mut self, xdg_surface: &XdgSurface, serial: u32) {
fn event(
state: &mut Self,
xdg_surface: &XdgSurface,
event: xdg_surface::Event,
_data: &(),
_conn: &Connection,
_qhandle: &QueueHandle<Self>,
) {
if let xdg_surface::Event::Configure { serial } = event {
info!("XdgSurface Configure received, sending ack with serial {serial}"); info!("XdgSurface Configure received, sending ack with serial {serial}");
xdg_surface.ack_configure(serial); xdg_surface.ack_configure(serial);
if let Some(popup_manager) = state.popup_manager() { if let Some(popup_manager) = self.popup_manager() {
info!("Marking all popups as dirty after Configure"); info!("Marking all popups as dirty after Configure");
popup_manager.mark_all_popups_dirty(); popup_manager.mark_all_popups_dirty();
} }
} }
pub(crate) fn handle_xdg_wm_base_ping(xdg_wm_base: &XdgWmBase, serial: u32) {
info!("XdgWmBase ping received, sending pong with serial {serial}");
xdg_wm_base.pong(serial);
} }
} }
impl_empty_dispatch!(
(WlRegistry, GlobalListContents),
(WlCompositor, ()),
(WlSurface, ()),
(ZwlrLayerShellV1, ()),
(WlSeat, ()),
(WpFractionalScaleManagerV1, ()),
(WpViewporter, ()),
(WpViewport, ()),
(XdgPositioner, ())
);

View file

@ -1,23 +1,3 @@
#[macro_export]
macro_rules! impl_empty_dispatch {
($(($t:ty, $u:ty)),+) => {
$(
impl Dispatch<$t, $u> for WindowState {
fn event(
_state: &mut Self,
_proxy: &$t,
_event: <$t as wayland_client::Proxy>::Event,
_data: &$u,
_conn: &Connection,
_qhandle: &QueueHandle<Self>,
) {
info!("Implement empty dispatch event for {:?}", stringify!($t));
}
}
)+
};
}
#[macro_export] #[macro_export]
macro_rules! bind_globals { macro_rules! bind_globals {
($global_list:expr, $queue_handle:expr, $(($interface:ty, $name:ident, $version:expr)),+) => { ($global_list:expr, $queue_handle:expr, $(($interface:ty, $name:ident, $version:expr)),+) => {