From da947992ac92938d653fe7c68868b5a4575dc8df Mon Sep 17 00:00:00 2001 From: John Nunley Date: Tue, 28 Nov 2023 16:20:36 -0800 Subject: [PATCH] bugfix(x11): Use the right atom type in focus_window() Closes #3248 by removing an Xlibism I forgot about Signed-off-by: John Nunley --- CHANGELOG.md | 1 + examples/focus.rs | 56 +++++++++++++++++++++++++++ src/platform_impl/linux/x11/ffi.rs | 5 --- src/platform_impl/linux/x11/mod.rs | 1 + src/platform_impl/linux/x11/window.rs | 4 +- 5 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 examples/focus.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index c91dd90b..ff9f3f4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Unreleased` header. - On macOS, remove spurious error logging when handling `Fn`. - On X11, fix an issue where floating point data from the server is misinterpreted during a drag and drop operation. +- On X11, fix a bug where focusing the window would panic. # 0.29.4 diff --git a/examples/focus.rs b/examples/focus.rs new file mode 100644 index 00000000..29d3c621 --- /dev/null +++ b/examples/focus.rs @@ -0,0 +1,56 @@ +#![allow(clippy::single_match)] + +//! Example for focusing a window. + +use simple_logger::SimpleLogger; +#[cfg(not(wasm_platform))] +use std::time; +#[cfg(wasm_platform)] +use web_time as time; +use winit::{ + event::{Event, StartCause, WindowEvent}, + event_loop::EventLoop, + window::WindowBuilder, +}; + +#[path = "util/fill.rs"] +mod fill; + +fn main() -> Result<(), impl std::error::Error> { + SimpleLogger::new().init().unwrap(); + let event_loop = EventLoop::new().unwrap(); + + let window = WindowBuilder::new() + .with_title("A fantastic window!") + .with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0)) + .build(&event_loop) + .unwrap(); + + let mut deadline = time::Instant::now() + time::Duration::from_secs(3); + event_loop.run(move |event, elwt| { + match event { + Event::NewEvents(StartCause::ResumeTimeReached { .. }) => { + // Timeout reached; focus the window. + println!("Re-focusing the window."); + deadline += time::Duration::from_secs(3); + window.focus_window(); + } + Event::WindowEvent { event, window_id } if window_id == window.id() => match event { + WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::RedrawRequested => { + // Notify the windowing system that we'll be presenting to the window. + window.pre_present_notify(); + fill::fill_window(&window); + } + _ => (), + }, + Event::AboutToWait => { + window.request_redraw(); + } + + _ => (), + } + + elwt.set_control_flow(winit::event_loop::ControlFlow::WaitUntil(deadline)); + }) +} diff --git a/src/platform_impl/linux/x11/ffi.rs b/src/platform_impl/linux/x11/ffi.rs index 1561803a..f44f9b5a 100644 --- a/src/platform_impl/linux/x11/ffi.rs +++ b/src/platform_impl/linux/x11/ffi.rs @@ -1,6 +1 @@ -use x11_dl::xmd::CARD32; pub use x11_dl::{error::OpenError, xcursor::*, xinput2::*, xlib::*, xlib_xcb::*}; - -// Isn't defined by x11_dl -#[allow(non_upper_case_globals)] -pub const IconicState: CARD32 = 3; diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 3e6cdc3f..6d8d9fd3 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -81,6 +81,7 @@ use crate::{ // Xinput constants not defined in x11rb const ALL_DEVICES: u16 = 0; const ALL_MASTER_DEVICES: u16 = 1; +const ICONIC_STATE: u32 = 3; type X11Source = Generic>; diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index 5bcd38d7..3c4f29e0 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -1785,9 +1785,9 @@ impl UnownedWindow { let state_type_atom = atoms[CARD32]; let is_minimized = if let Ok(state) = self.xconn - .get_property(self.xwindow, state_atom, state_type_atom) + .get_property::(self.xwindow, state_atom, state_type_atom) { - state.contains(&(ffi::IconicState as c_ulong)) + state.contains(&super::ICONIC_STATE) } else { false };