Skip to content

Commit

Permalink
Add x11rb and replace some Xlib functions
Browse files Browse the repository at this point in the history
Sub-commit messages:

Fix 32-bit builds

Fix clippy warnings

Clean up + better atom handling

Cleanup

fmt

x11rb should be optional

Make sure x11rb doesn't appear in public interface

Rebase on master

Tree shaking
  • Loading branch information
notgull committed Jan 12, 2023
1 parent 9225b28 commit 8af0265
Show file tree
Hide file tree
Showing 30 changed files with 2,500 additions and 3,648 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ And please only add new entries to the top of this list, right below the `# Unre
- **Breaking:** On Android, switched to using [`android-activity`](https://github.com/rib/android-activity) crate as a glue layer instead of [`ndk-glue`](https://github.com/rust-windowing/android-ndk-rs/tree/master/ndk-glue). See [README.md#Android](https://github.com/rust-windowing/winit#Android) for more details. ([#2444](https://github.com/rust-windowing/winit/pull/2444))
- **Breaking:** Removed support for `raw-window-handle` version `0.4`
- On Wayland, `RedrawRequested` not emitted during resize.
- On X11, migrate from Xlib to libxcb.
- **Breaking:** Remove the unstable `xlib_xconnection()` function from the private interface.
- Added Orbital support for Redox OS
- On X11, added `drag_resize_window` method.
Expand Down
8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ rustdoc-args = ["--cfg", "docsrs"]

[features]
default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"]
x11 = ["x11-dl", "mio", "percent-encoding"]
x11 = ["bytemuck", "x11-dl", "x11rb", "mio", "percent-encoding"]
wayland = ["wayland-client", "wayland-protocols", "sctk"]
wayland-dlopen = ["sctk/dlopen", "wayland-client/dlopen"]
wayland-csd-adwaita = ["sctk-adwaita", "sctk-adwaita/ab_glyph"]
wayland-csd-adwaita-crossfont = ["sctk-adwaita", "sctk-adwaita/crossfont"]
wayland-csd-adwaita-notitle = ["sctk-adwaita"]
android-native-activity = [ "android-activity/native-activity" ]
android-game-activity = [ "android-activity/game-activity" ]
android-native-activity = ["android-activity/native-activity"]
android-game-activity = ["android-activity/game-activity"]

[build-dependencies]
cfg_aliases = "0.1.1"
Expand Down Expand Up @@ -104,6 +104,7 @@ features = [
]

[target.'cfg(all(unix, not(any(target_os = "redox", target_arch = "wasm32", target_os = "android", target_os = "ios", target_os = "macos"))))'.dependencies]
bytemuck = { version = "1.12.3", default-features = false, optional = true, features = ["derive", "extern_crate_alloc"] }
libc = "0.2.64"
mio = { version = "0.8", features = ["os-ext"], optional = true }
percent-encoding = { version = "2.0", optional = true }
Expand All @@ -112,6 +113,7 @@ sctk-adwaita = { version = "0.5.1", default_features = false, optional = true }
wayland-client = { version = "0.29.4", default_features = false, features = ["use_system_lib"], optional = true }
wayland-protocols = { version = "0.29.4", features = [ "staging_protocols"], optional = true }
x11-dl = { version = "2.18.5", optional = true }
x11rb = { version = "0.11.0", features = ["allow-unsafe-code", "dl-libxcb", "randr", "resource_manager", "xinput", "xkb"], optional = true }

[target.'cfg(target_os = "redox")'.dependencies]
orbclient = { version = "0.3.42", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
// Doc feature labels can be tested locally by running RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::uninlined_format_args)]

#[allow(unused_imports)]
#[macro_use]
Expand Down
37 changes: 30 additions & 7 deletions src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
#[cfg(x11_platform)]
pub use self::x11::XNotSupported;
#[cfg(x11_platform)]
use self::x11::{ffi::XVisualInfo, util::WindowType as XWindowType, XConnection, XError};
use self::x11::{
ffi::XVisualInfo, util::WindowType as XWindowType, PlatformError, XConnection, XError,
};
#[cfg(x11_platform)]
use crate::platform::x11::XlibErrorHook;
use crate::{
Expand Down Expand Up @@ -120,28 +122,49 @@ pub(crate) static X11_BACKEND: Lazy<Mutex<Result<Arc<XConnection>, XNotSupported
Lazy::new(|| Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new)));

#[derive(Debug, Clone)]
pub enum OsError {
pub(crate) enum OsError {
#[cfg(x11_platform)]
XError(XError),
XError(Arc<PlatformError>),
#[cfg(x11_platform)]
XMisc(&'static str),
#[cfg(wayland_platform)]
WaylandMisc(&'static str),
}

impl fmt::Display for OsError {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
#[cfg(x11_platform)]
OsError::XError(ref e) => _f.pad(&e.description),
OsError::XError(ref e) => fmt::Display::fmt(e, f),
#[cfg(x11_platform)]
OsError::XMisc(e) => _f.pad(e),
OsError::XMisc(e) => f.pad(e),
#[cfg(wayland_platform)]
OsError::WaylandMisc(e) => _f.pad(e),
OsError::WaylandMisc(e) => f.pad(e),
}
}
}

#[cfg(x11_platform)]
impl From<XError> for OsError {
fn from(value: XError) -> Self {
OsError::XError(Arc::new(value.into()))
}
}

#[cfg(x11_platform)]
impl From<PlatformError> for OsError {
fn from(value: PlatformError) -> Self {
OsError::XError(Arc::new(value))
}
}

#[cfg(x11_platform)]
impl From<x11rb::errors::ConnectionError> for OsError {
fn from(value: x11rb::errors::ConnectionError) -> Self {
OsError::XError(Arc::new(value.into()))
}
}

pub(crate) enum Window {
#[cfg(x11_platform)]
X(x11::Window),
Expand Down
158 changes: 158 additions & 0 deletions src/platform_impl/linux/x11/atoms.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
//! Atom management.
use x11rb::{
atom_manager, cookie,
errors::{ConnectionError, ReplyError},
protocol::xproto::{self, ConnectionExt as _},
xcb_ffi::XCBConnection,
};

// Note: text/uri-list is a special case and is handled separately.

macro_rules! make_atom_manager {
(
$($name: ident),*
) => {
/// The various atoms used within `Winit`.
#[allow(non_camel_case_types)]
pub(crate) enum AtomType {
TextUriList,
$(
$name,
)*
}

/// A collection of atoms used within `Winit`.
pub(crate) struct Atoms {
/// The textual atom list.
some_atoms: SomeAtoms,

/// `text/uri-list`.
text_uri_list: xproto::Atom,
}

/// The cookie for the `Atoms` structure.
pub(crate) struct AtomsCookie<'a> {
/// The textual atom list.
some_atoms: SomeAtomsCookie<'a, XCBConnection>,

/// `text/uri-list`.
text_uri_list: cookie::Cookie<'a, XCBConnection, xproto::InternAtomReply>,
}

impl Atoms {
/// Create a new `Atoms` structure.
pub(crate) fn request(conn: &XCBConnection) -> Result<AtomsCookie<'_>, ConnectionError> {
let some_atoms = SomeAtoms::new(conn)?;
let text_uri_list = conn.intern_atom(true, b"text/uri-list")?;
Ok(AtomsCookie {
some_atoms,
text_uri_list,
})
}
}

impl AtomsCookie<'_> {
/// Finish the creation of the `Atoms` structure.
pub(crate) fn reply(self) -> Result<Atoms, ReplyError> {
let some_atoms = self.some_atoms.reply()?;
let text_uri_list = self.text_uri_list.reply()?.atom;
Ok(Atoms {
some_atoms,
text_uri_list,
})
}
}

atom_manager! {
/// A collection of atoms used within `Winit`.
SomeAtoms : SomeAtomsCookie {
$(
$name,
)*
}
}

impl std::ops::Index<AtomType> for Atoms {
type Output = xproto::Atom;

fn index(&self, atom: AtomType) -> &Self::Output {
match atom {
AtomType::TextUriList => &self.text_uri_list,
$(
AtomType::$name => &self.some_atoms.$name,
)*
}
}
}
};
}

make_atom_manager! {
// Window type hints.
_NET_WM_WINDOW_TYPE,
_NET_WM_WINDOW_TYPE_DESKTOP,
_NET_WM_WINDOW_TYPE_DOCK,
_NET_WM_WINDOW_TYPE_TOOLBAR,
_NET_WM_WINDOW_TYPE_MENU,
_NET_WM_WINDOW_TYPE_UTILITY,
_NET_WM_WINDOW_TYPE_SPLASH,
_NET_WM_WINDOW_TYPE_DIALOG,
_NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
_NET_WM_WINDOW_TYPE_POPUP_MENU,
_NET_WM_WINDOW_TYPE_TOOLTIP,
_NET_WM_WINDOW_TYPE_NOTIFICATION,
_NET_WM_WINDOW_TYPE_COMBO,
_NET_WM_WINDOW_TYPE_DND,
_NET_WM_WINDOW_TYPE_NORMAL,

// Other _NET_WM hints
_NET_WM_MOVERESIZE,
_NET_WM_NAME,
_NET_WM_ICON,
_NET_WM_PID,
_NET_WM_PING,
_NET_WM_STATE,
_NET_WM_STATE_ABOVE,
_NET_WM_STATE_BELOW,
_NET_WM_STATE_FULLSCREEN,
_NET_WM_STATE_MAXIMIZED_HORZ,
_NET_WM_STATE_MAXIMIZED_VERT,

// DND atoms.
XdndAware,
XdndEnter,
XdndLeave,
XdndDrop,
XdndPosition,
XdndStatus,
XdndActionPrivate,
XdndSelection,
XdndFinished,
XdndTypeList,

// _NET hints.
_NET_ACTIVE_WINDOW,
_NET_FRAME_EXTENTS,
_NET_CLIENT_LIST,
_NET_SUPPORTED,
_NET_SUPPORTING_WM_CHECK,

// Misc WM hints.
WM_CLIENT_MACHINE,
WM_DELETE_WINDOW,
WM_PROTOCOLS,
WM_STATE,

// Other misc atoms.
_MOTIF_WM_HINTS,
_GTK_THEME_VARIANT,
CARD32,
UTF8_STRING,
None
}

pub(crate) use AtomType::*;

/// Prevent the `None` atom from shadowing `Option::None`.
pub use std::option::Option::None;
Loading

0 comments on commit 8af0265

Please sign in to comment.