mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-12-23 13:35:56 +00:00
refactor: app state as single src of truth for wayland events
This commit is contained in:
parent
84121a2162
commit
8cd94cd13e
3 changed files with 174 additions and 414 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 => {
|
|
||||||
info!("Layer surface closed");
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dispatch<WlOutput, ()> for WindowState {
|
#[allow(clippy::unused_self)]
|
||||||
fn event(
|
pub(crate) fn handle_layer_surface_closed(&mut self) {
|
||||||
state: &mut Self,
|
info!("Layer surface closed");
|
||||||
_proxy: &WlOutput,
|
}
|
||||||
event: <WlOutput as Proxy>::Event,
|
|
||||||
_data: &(),
|
pub(crate) fn handle_output_mode(&mut self, width: i32, height: i32) {
|
||||||
_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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_empty_dispatch!(
|
pub(crate) fn handle_xdg_wm_base_ping(xdg_wm_base: &XdgWmBase, serial: u32) {
|
||||||
(WlRegistry, GlobalListContents),
|
info!("XdgWmBase ping received, sending pong with serial {serial}");
|
||||||
(WlCompositor, ()),
|
xdg_wm_base.pong(serial);
|
||||||
(WlSurface, ()),
|
}
|
||||||
(ZwlrLayerShellV1, ()),
|
}
|
||||||
(WlSeat, ()),
|
|
||||||
(WpFractionalScaleManagerV1, ()),
|
|
||||||
(WpViewporter, ()),
|
|
||||||
(WpViewport, ()),
|
|
||||||
(XdgPositioner, ())
|
|
||||||
);
|
|
||||||
|
|
|
||||||
|
|
@ -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)),+) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue