Move X11Source to smithay under`x11rb_event_source` feature

This commit is contained in:
i509VCB 2021-10-17 02:23:45 -05:00
parent 4d93805814
commit c8d56f1cf3
7 changed files with 45 additions and 19 deletions

View File

@ -27,6 +27,7 @@
#### Backends #### Backends
- `x11rb` event source integration used in anvil's XWayland implementation is now part of smithay at `utils::x11rb`. Enabled through the `x11rb_event_source` feature.
- New `DrmNode` type in drm backend. This is primarily for use a backend which needs to run as client inside another session. - New `DrmNode` type in drm backend. This is primarily for use a backend which needs to run as client inside another session.
### Bugfixes ### Bugfixes

View File

@ -46,6 +46,7 @@ wayland-protocols = { version = "0.29.0", features = ["unstable_protocols", "sta
wayland-server = { version = "0.29.0", optional = true } wayland-server = { version = "0.29.0", optional = true }
wayland-sys = { version = "0.29.0", optional = true } wayland-sys = { version = "0.29.0", optional = true }
winit = { version = "0.25.0", optional = true } winit = { version = "0.25.0", optional = true }
x11rb = { version = "0.9.0", optional = true }
xkbcommon = "0.4.0" xkbcommon = "0.4.0"
scan_fmt = { version = "0.2.3", default-features = false } scan_fmt = { version = "0.2.3", default-features = false }
@ -71,6 +72,7 @@ backend_session_libseat = ["backend_session", "libseat"]
renderer_gl = ["gl_generator", "backend_egl"] renderer_gl = ["gl_generator", "backend_egl"]
use_system_lib = ["wayland_frontend", "wayland-sys", "wayland-server/use_system_lib"] use_system_lib = ["wayland_frontend", "wayland-sys", "wayland-server/use_system_lib"]
wayland_frontend = ["wayland-server", "wayland-commons", "wayland-protocols", "tempfile"] wayland_frontend = ["wayland-server", "wayland-commons", "wayland-protocols", "tempfile"]
x11rb_event_source = ["x11rb"]
xwayland = ["wayland_frontend"] xwayland = ["wayland_frontend"]
test_all_features = ["default", "use_system_lib", "wayland-server/dlopen"] test_all_features = ["default", "use_system_lib", "wayland-server/dlopen"]

View File

@ -28,7 +28,7 @@ features = [ "wayland_frontend", "slog-stdlog" ]
[dependencies.x11rb] [dependencies.x11rb]
optional = true optional = true
version = "0.8" version = "0.9.0"
default-features = false default-features = false
features = [ "composite" ] features = [ "composite" ]
@ -43,6 +43,6 @@ udev = [ "smithay/backend_libinput", "smithay/backend_udev", "smithay/backend_dr
logind = [ "smithay/backend_session_logind" ] logind = [ "smithay/backend_session_logind" ]
elogind = ["logind", "smithay/backend_session_elogind" ] elogind = ["logind", "smithay/backend_session_elogind" ]
libseat = ["smithay/backend_session_libseat" ] libseat = ["smithay/backend_session_libseat" ]
xwayland = [ "smithay/xwayland", "x11rb" ] xwayland = [ "smithay/xwayland", "x11rb", "smithay/x11rb_event_source" ]
debug = [ "fps_ticker", "image/png" ] debug = [ "fps_ticker", "image/png" ]
test_all_features = ["default", "debug"] test_all_features = ["default", "debug"]

View File

@ -4,7 +4,7 @@ use std::{
use smithay::{ use smithay::{
reexports::wayland_server::{protocol::wl_surface::WlSurface, Client}, reexports::wayland_server::{protocol::wl_surface::WlSurface, Client},
utils::{Logical, Point}, utils::{x11rb::X11Source, Logical, Point},
wayland::compositor::give_role, wayland::compositor::give_role,
}; };
@ -27,10 +27,6 @@ use crate::{
AnvilState, AnvilState,
}; };
use x11rb_event_source::X11Source;
mod x11rb_event_source;
impl<BackendData: 'static> AnvilState<BackendData> { impl<BackendData: 'static> AnvilState<BackendData> {
pub fn start_xwayland(&mut self) { pub fn start_xwayland(&mut self) {
if let Err(e) = self.xwayland.start() { if let Err(e) = self.xwayland.start() {
@ -237,7 +233,7 @@ pub fn commit_hook(surface: &WlSurface) {
} }
} }
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct X11Surface { pub struct X11Surface {
surface: WlSurface, surface: WlSurface,
} }

View File

@ -21,3 +21,5 @@ pub use wayland_protocols;
pub use wayland_server; pub use wayland_server;
#[cfg(feature = "backend_winit")] #[cfg(feature = "backend_winit")]
pub use winit; pub use winit;
#[cfg(feature = "x11rb_event_source")]
pub use x11rb;

View File

@ -3,6 +3,9 @@
mod geometry; mod geometry;
pub mod signaling; pub mod signaling;
#[cfg(feature = "x11rb_event_source")]
pub mod x11rb;
pub use self::geometry::{Buffer, Logical, Physical, Point, Raw, Rectangle, Size}; pub use self::geometry::{Buffer, Logical, Physical, Point, Raw, Rectangle, Size};
/// This resource is not managed by Smithay /// This resource is not managed by Smithay

View File

@ -1,3 +1,8 @@
//! Helper utilities for using x11rb as an event source in calloop.
//!
//! The primary use for this module is XWayland integration but is also widely useful for an X11
//! backend in a compositor.
use std::{ use std::{
io::Result as IOResult, io::Result as IOResult,
sync::Arc, sync::Arc,
@ -13,7 +18,7 @@ use x11rb::{
rust_connection::RustConnection, rust_connection::RustConnection,
}; };
use smithay::reexports::calloop::{ use calloop::{
channel::{sync_channel, Channel, Event as ChannelEvent, SyncSender}, channel::{sync_channel, Channel, Event as ChannelEvent, SyncSender},
EventSource, Poll, PostAction, Readiness, Token, TokenFactory, EventSource, Poll, PostAction, Readiness, Token, TokenFactory,
}; };
@ -28,9 +33,10 @@ use smithay::reexports::calloop::{
/// iteration. Calloop only allows "when an FD becomes readable". /// iteration. Calloop only allows "when an FD becomes readable".
/// ///
/// [1]: https://docs.rs/x11rb/0.8.1/x11rb/event_loop_integration/index.html#threads-and-races /// [1]: https://docs.rs/x11rb/0.8.1/x11rb/event_loop_integration/index.html#threads-and-races
#[derive(Debug)]
pub struct X11Source { pub struct X11Source {
connection: Arc<RustConnection>, connection: Arc<RustConnection>,
channel: Channel<Event>, channel: Option<Channel<Event>>,
event_thread: Option<JoinHandle<()>>, event_thread: Option<JoinHandle<()>>,
close_window: Window, close_window: Window,
close_type: Atom, close_type: Atom,
@ -56,9 +62,10 @@ impl X11Source {
let event_thread = Some(spawn(move || { let event_thread = Some(spawn(move || {
run_event_thread(conn, sender, log2); run_event_thread(conn, sender, log2);
})); }));
Self { Self {
connection, connection,
channel, channel: Some(channel),
event_thread, event_thread,
close_window, close_window,
close_type, close_type,
@ -70,9 +77,7 @@ impl X11Source {
impl Drop for X11Source { impl Drop for X11Source {
fn drop(&mut self) { fn drop(&mut self) {
// Signal the worker thread to exit by dropping the read end of the channel. // Signal the worker thread to exit by dropping the read end of the channel.
// There is no easy and nice way to do this, so do it the ugly way: Replace it. self.channel.take();
let (_, channel) = sync_channel(1);
self.channel = channel;
// Send an event to wake up the worker so that it actually exits // Send an event to wake up the worker so that it actually exits
let event = ClientMessageEvent { let event = ClientMessageEvent {
@ -83,6 +88,7 @@ impl Drop for X11Source {
type_: self.close_type, type_: self.close_type,
data: [0; 20].into(), data: [0; 20].into(),
}; };
let _ = self let _ = self
.connection .connection
.send_event(false, self.close_window, EventMask::NO_EVENT, event); .send_event(false, self.close_window, EventMask::NO_EVENT, event);
@ -108,23 +114,39 @@ impl EventSource for X11Source {
C: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret, C: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
{ {
let log = self.log.clone(); let log = self.log.clone();
self.channel
.process_events(readiness, token, move |event, meta| match event { if let Some(channel) = &mut self.channel {
channel.process_events(readiness, token, move |event, meta| match event {
ChannelEvent::Closed => slog::warn!(log, "Event thread exited"), ChannelEvent::Closed => slog::warn!(log, "Event thread exited"),
ChannelEvent::Msg(event) => callback(event, meta), ChannelEvent::Msg(event) => callback(event, meta),
}) })
} else {
Ok(PostAction::Remove)
}
} }
fn register(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> IOResult<()> { fn register(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> IOResult<()> {
self.channel.register(poll, factory) if let Some(channel) = &mut self.channel {
channel.register(poll, factory)?;
}
Ok(())
} }
fn reregister(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> IOResult<()> { fn reregister(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> IOResult<()> {
self.channel.reregister(poll, factory) if let Some(channel) = &mut self.channel {
channel.reregister(poll, factory)?;
}
Ok(())
} }
fn unregister(&mut self, poll: &mut Poll) -> IOResult<()> { fn unregister(&mut self, poll: &mut Poll) -> IOResult<()> {
self.channel.unregister(poll) if let Some(channel) = &mut self.channel {
channel.unregister(poll)?;
}
Ok(())
} }
} }