Skip to content

Commit

Permalink
x11: fix WindowAttributesExtX11::with_x11_screen() (rust-windowing#3974)
Browse files Browse the repository at this point in the history
Based on rust-windowing#3973, which should be merged first.

There's an API to programmatically specify X11 screen id (override what is determined from the `DISPLAY` env variable), but it doesn't work.

Seeting up X Server with 2 screens and calling `DISPLAY=:0 X11_SCREEN_ID=1 cargo run --example window` should be equivalent to calling `DISPLAY=:0.1 cargo run --example window`

The latter works (and places the window on the correct screen), but the former yields

`failed to create initial window: Os(OsError { line: 620, file: "src/platform_impl/linux/x11/window.rs", error: X11Error(X11Error { error_kind: Match, error_code: 8, sequence: 219, bad_value: 1319, minor_opcode: 0, major_opcode: 1, extension_name: None, request_name: Some("CreateWindow") }) })`

_Here `1319` is the root window id for screen 0, which doesn't match the screen 1 that we request._

The problem is that we need to factor in the screen id when determining the parent (root) window when not explicitly set. This patch does that.
  • Loading branch information
strohel committed Oct 31, 2024
1 parent effd870 commit fb66a54
Showing 1 changed file with 16 additions and 15 deletions.
31 changes: 16 additions & 15 deletions src/platform_impl/linux/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,29 @@ impl UnownedWindow {
) -> Result<UnownedWindow, RootOsError> {
let xconn = &event_loop.xconn;
let atoms = xconn.atoms();

let screen_id = match window_attrs.platform_specific.x11.screen_id {
Some(id) => id,
None => xconn.default_screen_index() as c_int,
};

let screen = {
let screen_id_usize = usize::try_from(screen_id)
.map_err(|_| os_error!(OsError::Misc("screen id must be non-negative")))?;
xconn.xcb_connection().setup().roots.get(screen_id_usize).ok_or(os_error!(
OsError::Misc("requested screen id not present in server's response")
))?
};

#[cfg(feature = "rwh_06")]
let root = match window_attrs.parent_window.as_ref().map(|handle| handle.0) {
Some(rwh_06::RawWindowHandle::Xlib(handle)) => handle.window as xproto::Window,
Some(rwh_06::RawWindowHandle::Xcb(handle)) => handle.window.get(),
Some(raw) => unreachable!("Invalid raw window handle {raw:?} on X11"),
None => event_loop.root,
None => screen.root,
};
#[cfg(not(feature = "rwh_06"))]
let root = event_loop.root;
let root = screen.root;

let mut monitors = leap!(xconn.available_monitors());
let guessed_monitor = if monitors.is_empty() {
Expand Down Expand Up @@ -207,19 +221,6 @@ impl UnownedWindow {
dimensions
};

let screen_id = match window_attrs.platform_specific.x11.screen_id {
Some(id) => id,
None => xconn.default_screen_index() as c_int,
};

let screen = {
let screen_id_usize = usize::try_from(screen_id)
.map_err(|_| os_error!(OsError::Misc("screen id must be non-negative")))?;
xconn.xcb_connection().setup().roots.get(screen_id_usize).ok_or(os_error!(
OsError::Misc("requested screen id not present in server's response")
))?
};

// An iterator over the visuals matching screen id combined with their depths.
let mut all_visuals = screen
.allowed_depths
Expand Down

0 comments on commit fb66a54

Please sign in to comment.