Skip to content

Commit dfcc748

Browse files
committed
Don't assume x11 in python.
1 parent 03616a4 commit dfcc748

3 files changed

Lines changed: 79 additions & 56 deletions

File tree

‎Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ processing_glfw = { workspace = true }
9494
rand = { workspace = true }
9595

9696
[target.'cfg(target_os = "linux")'.dev-dependencies]
97-
processing_glfw = { workspace = true, features = ["wayland"] }
97+
processing_glfw = { workspace = true, features = ["wayland", "x11"] }
9898

9999
## TODO: Remove these patches once we've moved back to depending on upstream bevy
100100
[patch."https://github.com/bevyengine/bevy"]

‎crates/processing_glfw/src/lib.rs‎

Lines changed: 77 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ use processing_input::{
1717
};
1818
use processing_render::surface::{MonitorWorkarea, WindowControls};
1919

20+
fn is_wayland(glfw: &Glfw) -> bool {
21+
cfg!(target_os = "linux") && glfw.get_platform() == glfw::Platform::Wayland
22+
}
23+
2024
/// A single GLFW instance drives every window (GLFW's event pump is global). The
2125
/// main window is `windows[0]`; `create_window` appends more.
2226
pub struct GlfwContext {
@@ -96,30 +100,33 @@ impl GlfwContext {
96100

97101
// Set _NET_WM_WINDOW_TYPE_DIALOG so tiling WMs (i3, sway) float the window
98102
#[cfg(all(target_os = "linux", feature = "x11"))]
99-
unsafe {
103+
if glfw.get_platform() == glfw::Platform::X11 {
100104
use std::ffi::CString;
101-
let display = window.glfw.get_x11_display() as *mut x11::xlib::Display;
102-
let xwindow = window.get_x11_window() as x11::xlib::Window;
103-
let net_wm_window_type = x11::xlib::XInternAtom(
104-
display,
105-
CString::new("_NET_WM_WINDOW_TYPE").unwrap().as_ptr(),
106-
0,
107-
);
108-
let net_wm_window_type_dialog = x11::xlib::XInternAtom(
109-
display,
110-
CString::new("_NET_WM_WINDOW_TYPE_DIALOG").unwrap().as_ptr(),
111-
0,
112-
);
113-
x11::xlib::XChangeProperty(
114-
display,
115-
xwindow,
116-
net_wm_window_type,
117-
x11::xlib::XA_ATOM,
118-
32,
119-
x11::xlib::PropModeReplace,
120-
&net_wm_window_type_dialog as *const _ as *const u8,
121-
1,
122-
);
105+
// SAFETY: GLFW is on X11, so the display and window handles are live Xlib objects.
106+
unsafe {
107+
let display = window.glfw.get_x11_display() as *mut x11::xlib::Display;
108+
let xwindow = window.get_x11_window() as x11::xlib::Window;
109+
let net_wm_window_type = x11::xlib::XInternAtom(
110+
display,
111+
CString::new("_NET_WM_WINDOW_TYPE").unwrap().as_ptr(),
112+
0,
113+
);
114+
let net_wm_window_type_dialog = x11::xlib::XInternAtom(
115+
display,
116+
CString::new("_NET_WM_WINDOW_TYPE_DIALOG").unwrap().as_ptr(),
117+
0,
118+
);
119+
x11::xlib::XChangeProperty(
120+
display,
121+
xwindow,
122+
net_wm_window_type,
123+
x11::xlib::XA_ATOM,
124+
32,
125+
x11::xlib::PropModeReplace,
126+
&net_wm_window_type_dialog as *const _ as *const u8,
127+
1,
128+
);
129+
}
123130
}
124131

125132
window.show();
@@ -275,19 +282,41 @@ impl GlfwContext {
275282
let handle = self.windows[idx].window.get_win32_window() as u64;
276283
surface_create_windows(handle, width, height, scale_factor, transparent)?
277284
};
278-
#[cfg(all(target_os = "linux", feature = "wayland"))]
279-
let entity = {
280-
use processing_render::surface_create_wayland;
281-
let wh = self.windows[idx].window.get_wayland_window() as u64;
282-
let dh = self.glfw.get_wayland_display() as u64;
283-
surface_create_wayland(wh, dh, width, height, scale_factor, transparent)?
284-
};
285-
#[cfg(all(target_os = "linux", feature = "x11", not(feature = "wayland")))]
286-
let entity = {
287-
use processing_render::surface_create_x11;
288-
let wh = self.windows[idx].window.get_x11_window() as u64;
289-
let dh = self.glfw.get_x11_display() as u64;
290-
surface_create_x11(wh, dh, width, height, scale_factor, transparent)?
285+
#[cfg(target_os = "linux")]
286+
let entity = match self.glfw.get_platform() {
287+
#[cfg(feature = "wayland")]
288+
glfw::Platform::Wayland => {
289+
let wh = self.windows[idx].window.get_wayland_window() as u64;
290+
let dh = self.glfw.get_wayland_display() as u64;
291+
processing_render::surface_create_wayland(
292+
wh,
293+
dh,
294+
width,
295+
height,
296+
scale_factor,
297+
transparent,
298+
)?
299+
}
300+
#[cfg(feature = "x11")]
301+
glfw::Platform::X11 => {
302+
let wh = self.windows[idx].window.get_x11_window() as u64;
303+
let dh = self.glfw.get_x11_display() as u64;
304+
processing_render::surface_create_x11(
305+
wh,
306+
dh,
307+
width,
308+
height,
309+
scale_factor,
310+
transparent,
311+
)?
312+
}
313+
platform => {
314+
return Err(processing_core::error::ProcessingError::InvalidArgument(
315+
format!(
316+
"GLFW is running on {platform:?}, which this build doesn't support; enable the matching `x11`/`wayland` feature"
317+
),
318+
));
319+
}
291320
};
292321

293322
self.windows[idx].surface = Some(entity);
@@ -438,8 +467,7 @@ impl ManagedWindow {
438467
if desired.maximize {
439468
self.window.maximize();
440469
}
441-
#[cfg(not(all(target_os = "linux", feature = "wayland")))]
442-
if desired.focus {
470+
if desired.focus && !is_wayland(glfw) {
443471
self.window.focus();
444472
}
445473

@@ -463,28 +491,25 @@ impl ManagedWindow {
463491
self.last_applied.size = bevy::math::UVec2::new(w.max(0) as u32, h.max(0) as u32);
464492
}
465493

466-
#[cfg(not(feature = "wayland"))]
467494
fn frame_pos(&self) -> IVec2 {
495+
if is_wayland(&self.window.glfw) {
496+
return self.last_applied.position;
497+
}
468498
let (cx, cy) = self.window.get_pos();
469499
let (inset_l, inset_t, _, _) = self.window.get_frame_size();
470500
IVec2::new(cx - inset_l, cy - inset_t)
471501
}
472502

473-
#[cfg(feature = "wayland")]
474-
fn frame_pos(&self) -> IVec2 {
475-
self.last_applied.position
476-
}
477-
478503
fn apply_window(&mut self, glfw: &mut Glfw, desired: &DesiredWindow) {
479504
let last = &mut self.last_applied;
480505

481506
if desired.title != last.title {
482507
self.window.set_title(&desired.title);
483508
last.title.clone_from(&desired.title);
484509
}
485-
#[cfg(not(feature = "wayland"))]
486510
if let Some(pos) = desired.position
487511
&& pos != last.position
512+
&& !is_wayland(glfw)
488513
{
489514
let (inset_l, inset_t, _, _) = self.window.get_frame_size();
490515
self.window.set_pos(pos.x + inset_l, pos.y + inset_t);
@@ -512,16 +537,18 @@ impl ManagedWindow {
512537
last.decorations = desired.decorations;
513538
}
514539
if desired.window_level != last.window_level {
515-
#[cfg(not(all(target_os = "linux", feature = "wayland")))]
516-
self.window
517-
.set_floating(matches!(desired.window_level, BevyWindowLevel::AlwaysOnTop));
540+
if !is_wayland(glfw) {
541+
self.window
542+
.set_floating(matches!(desired.window_level, BevyWindowLevel::AlwaysOnTop));
543+
}
518544
last.window_level = desired.window_level;
519545
}
520546
if let Some(opacity) = desired.opacity
521547
&& (opacity - last.opacity).abs() > f32::EPSILON
522548
{
523-
#[cfg(not(all(target_os = "linux", feature = "wayland")))]
524-
self.window.set_opacity(opacity);
549+
if !is_wayland(glfw) {
550+
self.window.set_opacity(opacity);
551+
}
525552
last.opacity = opacity;
526553
}
527554
if desired.fullscreen_on != last.fullscreen_on {
@@ -590,7 +617,6 @@ impl ManagedWindow {
590617
#[derive(Clone, Debug)]
591618
struct DesiredWindow {
592619
title: String,
593-
#[cfg(not(feature = "wayland"))]
594620
position: Option<IVec2>,
595621
size: bevy::math::UVec2,
596622
visible: bool,
@@ -602,7 +628,6 @@ struct DesiredWindow {
602628
iconify: bool,
603629
restore: bool,
604630
maximize: bool,
605-
#[cfg(not(all(target_os = "linux", feature = "wayland")))]
606631
focus: bool,
607632
}
608633

@@ -624,7 +649,6 @@ fn read_desired_window(surface: Entity) -> Option<DesiredWindow> {
624649
};
625650
Ok(Some(DesiredWindow {
626651
title: window.title.clone(),
627-
#[cfg(not(feature = "wayland"))]
628652
position: match window.position {
629653
WindowPosition::At(p) => Some(p),
630654
_ => None,
@@ -642,7 +666,6 @@ fn read_desired_window(surface: Entity) -> Option<DesiredWindow> {
642666
iconify: controls.pending_iconify,
643667
restore: controls.pending_restore,
644668
maximize: controls.pending_maximize,
645-
#[cfg(not(all(target_os = "linux", feature = "wayland")))]
646669
focus: controls.pending_focus,
647670
}))
648671
})

‎crates/processing_pyo3/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ name = "mewnala"
1111
crate-type = ["cdylib", "rlib"]
1212

1313
[features]
14-
default = ["wayland", "static-link"]
14+
default = ["wayland", "x11", "static-link"]
1515
wayland = ["processing/wayland", "processing_glfw/wayland"]
1616
static-link = ["processing_glfw/static-link"]
1717
x11 = ["processing/x11", "processing_glfw/x11"]

0 commit comments

Comments
 (0)