diff --git a/.changes/x11-feature.md b/.changes/x11-feature.md new file mode 100644 index 00000000..ad03e06a --- /dev/null +++ b/.changes/x11-feature.md @@ -0,0 +1,5 @@ +--- +tao: minor +--- + +Added `x11` feature flag (enabled by default). diff --git a/Cargo.toml b/Cargo.toml index 8a69abc9..e5bd5c7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ documentation = "https://docs.rs/tao" categories = [ "gui" ] [package.metadata.docs.rs] -features = [ "rwh_04", "rwh_05", "rwh_06", "serde" ] +features = [ "rwh_04", "rwh_05", "rwh_06", "serde", "x11" ] default-target = "x86_64-unknown-linux-gnu" targets = [ "i686-pc-windows-msvc", @@ -27,11 +27,12 @@ targets = [ ] [features] -default = [ "rwh_06" ] +default = [ "rwh_06", "x11" ] serde = [ "dep:serde", "dpi/serde" ] rwh_04 = [ "dep:rwh_04" ] rwh_05 = [ "dep:rwh_05" ] rwh_06 = [ "dep:rwh_06" ] +x11 = [ "dep:gdkx11-sys", "dep:x11-dl" ] [workspace] members = [ "tao-macros" ] @@ -147,8 +148,8 @@ scopeguard = "1.2" [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies] gtk = "0.18" -gdkx11-sys = "0.18" +gdkx11-sys = { version = "0.18", optional = true } gdkwayland-sys = "0.18.0" -x11-dl = "2.21" +x11-dl = { version = "2.21", optional = true } parking_lot = "0.12" dlopen2 = "0.7.0" diff --git a/src/platform/unix.rs b/src/platform/unix.rs index 2113220a..88584869 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -10,21 +10,26 @@ target_os = "openbsd" ))] +#[cfg(feature = "x11")] use std::{os::raw::c_int, sync::Arc}; // XConnection utilities #[doc(hidden)] +#[cfg(feature = "x11")] pub use crate::platform_impl::x11; +#[cfg(feature = "x11")] +use crate::platform_impl::x11::xdisplay::XError; pub use crate::platform_impl::EventLoop as UnixEventLoop; use crate::{ error::{ExternalError, OsError}, event_loop::{EventLoopBuilder, EventLoopWindowTarget}, monitor::MonitorHandle, - platform_impl::{x11::xdisplay::XError, Parent, Window as UnixWindow}, + platform_impl::{Parent, Window as UnixWindow}, window::{Window, WindowBuilder}, }; +#[cfg(feature = "x11")] use self::x11::xdisplay::XConnection; /// Additional methods on `EventLoop` that are specific to Unix. @@ -201,8 +206,10 @@ pub trait EventLoopWindowTargetExtUnix { fn is_wayland(&self) -> bool; /// True if the `EventLoopWindowTarget` uses X11. + #[cfg(feature = "x11")] fn is_x11(&self) -> bool; + #[cfg(feature = "x11")] fn xlib_xconnection(&self) -> Option>; // /// Returns a pointer to the `wl_display` object of wayland that is used by this @@ -226,11 +233,13 @@ impl EventLoopWindowTargetExtUnix for EventLoopWindowTarget { self.p.is_wayland() } + #[cfg(feature = "x11")] #[inline] fn is_x11(&self) -> bool { !self.p.is_wayland() } + #[cfg(feature = "x11")] #[inline] fn xlib_xconnection(&self) -> Option> { if self.is_x11() { @@ -266,6 +275,7 @@ impl EventLoopWindowTargetExtUnix for EventLoopWindowTarget { } } +#[cfg(feature = "x11")] unsafe extern "C" fn x_error_callback( _display: *mut x11::ffi::Display, event: *mut x11::ffi::XErrorEvent, diff --git a/src/platform_impl/linux/event_loop.rs b/src/platform_impl/linux/event_loop.rs index 39bb014d..7409eea7 100644 --- a/src/platform_impl/linux/event_loop.rs +++ b/src/platform_impl/linux/event_loop.rs @@ -24,6 +24,8 @@ use gtk::{ Settings, }; +#[cfg(feature = "x11")] +use crate::platform_impl::platform::device; use crate::{ dpi::{LogicalPosition, LogicalSize, PhysicalPosition}, error::ExternalError, @@ -33,7 +35,7 @@ use crate::{ event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW}, keyboard::ModifiersState, monitor::MonitorHandle as RootMonitorHandle, - platform_impl::platform::{device, DEVICE_ID}, + platform_impl::platform::DEVICE_ID, window::{ CursorIcon, Fullscreen, ProgressBarState, ResizeDirection, Theme, WindowId as RootWindowId, }, @@ -123,6 +125,7 @@ impl EventLoopWindowTarget { let display_handle = rwh_06::WaylandDisplayHandle::new(display); Ok(rwh_06::RawDisplayHandle::Wayland(display_handle)) } else { + #[cfg(feature = "x11")] unsafe { if let Ok(xlib) = x11_dl::xlib::Xlib::open() { let display = (xlib.XOpenDisplay)(std::ptr::null()); @@ -134,6 +137,8 @@ impl EventLoopWindowTarget { Err(rwh_06::HandleError::Unavailable) } } + #[cfg(not(feature = "x11"))] + Err(rwh_06::HandleError::Unavailable) } } @@ -141,6 +146,7 @@ impl EventLoopWindowTarget { self.display.backend().is_wayland() } + #[cfg(feature = "x11")] pub fn is_x11(&self) -> bool { self.display.backend().is_x11() } @@ -249,6 +255,7 @@ impl EventLoop { }; // Spawn x11 thread to receive Device events. + #[cfg(feature = "x11")] let run_device_thread = if window_target.is_x11() { let (device_tx, device_rx) = glib::MainContext::channel(glib::Priority::default()); let user_event_tx = user_event_tx.clone(); @@ -272,6 +279,8 @@ impl EventLoop { } else { None }; + #[cfg(not(feature = "x11"))] + let run_device_thread = None; let mut taskbar = TaskbarIndicator::new(); let is_wayland = window_target.is_wayland(); diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index e6b0d8f6..704d3cf5 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -2,6 +2,7 @@ // Copyright 2021-2023 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 +#[cfg(feature = "x11")] mod device; mod event_loop; mod icon; @@ -13,6 +14,7 @@ mod window; pub mod taskbar; pub mod wayland; +#[cfg(feature = "x11")] pub mod x11; pub use self::keycode::{keycode_from_scancode, keycode_to_scancode}; diff --git a/src/platform_impl/linux/window.rs b/src/platform_impl/linux/window.rs index 08c53a12..2c37843c 100644 --- a/src/platform_impl/linux/window.rs +++ b/src/platform_impl/linux/window.rs @@ -952,9 +952,14 @@ impl Window { let window_handle = rwh_06::WaylandWindowHandle::new(surface); Ok(rwh_06::RawWindowHandle::Wayland(window_handle)) } else { - let xid = unsafe { gdk_x11_sys::gdk_x11_window_get_xid(window.as_ptr() as *mut _) }; - let window_handle = rwh_06::XlibWindowHandle::new(xid); - Ok(rwh_06::RawWindowHandle::Xlib(window_handle)) + #[cfg(feature = "x11")] + { + let xid = unsafe { gdk_x11_sys::gdk_x11_window_get_xid(window.as_ptr() as *mut _) }; + let window_handle = rwh_06::XlibWindowHandle::new(xid); + Ok(rwh_06::RawWindowHandle::Xlib(window_handle)) + } + #[cfg(not(feature = "x11"))] + Err(rwh_06::HandleError::Unavailable) } } else { Err(rwh_06::HandleError::Unavailable) @@ -972,6 +977,7 @@ impl Window { let display_handle = rwh_06::WaylandDisplayHandle::new(display); Ok(rwh_06::RawDisplayHandle::Wayland(display_handle)) } else { + #[cfg(feature = "x11")] if let Ok(xlib) = x11_dl::xlib::Xlib::open() { unsafe { let display = (xlib.XOpenDisplay)(std::ptr::null()); @@ -983,6 +989,8 @@ impl Window { } else { Err(rwh_06::HandleError::Unavailable) } + #[cfg(not(feature = "x11"))] + Err(rwh_06::HandleError::Unavailable) } }