From 883763c17224c69094340d3abc2f9e4cb656966a Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Tue, 13 Aug 2024 09:15:57 +0300 Subject: Implement stub mutter-x11-interop Allows xdp-gnome dialogs to work with X11 clients. Fixes https://github.com/YaLTeR/niri/issues/594 --- src/protocols/mod.rs | 3 ++ src/protocols/mutter_x11_interop.rs | 93 +++++++++++++++++++++++++++++++++++++ src/protocols/raw.rs | 25 ++++++++++ 3 files changed, 121 insertions(+) create mode 100644 src/protocols/mutter_x11_interop.rs create mode 100644 src/protocols/raw.rs (limited to 'src/protocols') diff --git a/src/protocols/mod.rs b/src/protocols/mod.rs index a58b48bf..3328fb7c 100644 --- a/src/protocols/mod.rs +++ b/src/protocols/mod.rs @@ -1,4 +1,7 @@ pub mod foreign_toplevel; pub mod gamma_control; +pub mod mutter_x11_interop; pub mod output_management; pub mod screencopy; + +pub mod raw; diff --git a/src/protocols/mutter_x11_interop.rs b/src/protocols/mutter_x11_interop.rs new file mode 100644 index 00000000..cce41f15 --- /dev/null +++ b/src/protocols/mutter_x11_interop.rs @@ -0,0 +1,93 @@ +use mutter_x11_interop::MutterX11Interop; +use smithay::reexports::wayland_server::{ + Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, +}; + +use super::raw::mutter_x11_interop::v1::server::mutter_x11_interop; + +const VERSION: u32 = 1; + +pub struct MutterX11InteropManagerState {} + +pub struct MutterX11InteropManagerGlobalData { + filter: Box Fn(&'c Client) -> bool + Send + Sync>, +} + +pub trait MutterX11InteropHandler {} + +impl MutterX11InteropManagerState { + pub fn new(display: &DisplayHandle, filter: F) -> Self + where + D: GlobalDispatch, + D: Dispatch, + D: MutterX11InteropHandler, + D: 'static, + F: for<'c> Fn(&'c Client) -> bool + Send + Sync + 'static, + { + let global_data = MutterX11InteropManagerGlobalData { + filter: Box::new(filter), + }; + display.create_global::(VERSION, global_data); + + Self {} + } +} + +impl GlobalDispatch + for MutterX11InteropManagerState +where + D: GlobalDispatch, + D: Dispatch, + D: MutterX11InteropHandler, + D: 'static, +{ + fn bind( + _state: &mut D, + _handle: &DisplayHandle, + _client: &Client, + manager: New, + _manager_state: &MutterX11InteropManagerGlobalData, + data_init: &mut DataInit<'_, D>, + ) { + data_init.init(manager, ()); + } + + fn can_view(client: Client, global_data: &MutterX11InteropManagerGlobalData) -> bool { + (global_data.filter)(&client) + } +} + +impl Dispatch for MutterX11InteropManagerState +where + D: Dispatch, + D: MutterX11InteropHandler, + D: 'static, +{ + fn request( + _state: &mut D, + _client: &Client, + _resource: &MutterX11Interop, + request: ::Request, + _data: &(), + _dhandle: &DisplayHandle, + _data_init: &mut DataInit<'_, D>, + ) { + match request { + mutter_x11_interop::Request::Destroy => (), + mutter_x11_interop::Request::SetX11Parent { .. } => (), + } + } +} + +#[macro_export] +macro_rules! delegate_mutter_x11_interop { + ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { + smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + $crate::protocols::raw::mutter_x11_interop::v1::server::mutter_x11_interop::MutterX11Interop: $crate::protocols::mutter_x11_interop::MutterX11InteropManagerGlobalData + ] => $crate::protocols::mutter_x11_interop::MutterX11InteropManagerState); + + smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + $crate::protocols::raw::mutter_x11_interop::v1::server::mutter_x11_interop::MutterX11Interop: () + ] => $crate::protocols::mutter_x11_interop::MutterX11InteropManagerState); + }; +} diff --git a/src/protocols/raw.rs b/src/protocols/raw.rs new file mode 100644 index 00000000..fac1e4df --- /dev/null +++ b/src/protocols/raw.rs @@ -0,0 +1,25 @@ +pub mod mutter_x11_interop { + pub mod v1 { + pub use self::generated::server; + + mod generated { + pub mod server { + #![allow(dead_code, non_camel_case_types, unused_unsafe, unused_variables)] + #![allow(non_upper_case_globals, non_snake_case, unused_imports)] + #![allow(missing_docs, clippy::all)] + + use smithay::reexports::wayland_server; + use wayland_server::protocol::*; + + pub mod __interfaces { + use smithay::reexports::wayland_server; + use wayland_server::protocol::__interfaces::*; + wayland_scanner::generate_interfaces!("resources/mutter-x11-interop.xml"); + } + use self::__interfaces::*; + + wayland_scanner::generate_server_code!("resources/mutter-x11-interop.xml"); + } + } + } +} -- cgit