mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
a70ac1531e
* X11: Fix window creation hangs when another application is fullscreen Previously, the X11 backend would block until a `VisibilityNotify` event is received when creating a Window that is visible or when calling `set_visible(true)` on a Window that is not currently visible. This could cause winit to hang in situations where the WM does not quickly send this event to the application, such as another window being fullscreen at the time. This behavior existed to prevent an X protocol error caused by setting fullscreen state on an invisible window. This fix instead stores desired fullscreen state when `set_fullscreen` is called (iff the window is not visible or not yet visible) and issues X commands to set fullscreen state when a `VisibilityNotify` event is received through the normal processing of events in the event loop. * Add window_debug example to facilitate testing * Add a CHANGELOG entry * Call `XUnmapWindow` if `VisibilityNotify` is received on an invisible window
122 lines
4.4 KiB
Rust
122 lines
4.4 KiB
Rust
// This example is used by developers to test various window functions.
|
|
|
|
use winit::{
|
|
dpi::{LogicalSize, PhysicalSize},
|
|
event::{DeviceEvent, ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
|
event_loop::{ControlFlow, EventLoop},
|
|
window::{Fullscreen, WindowBuilder},
|
|
};
|
|
|
|
fn main() {
|
|
let event_loop = EventLoop::new();
|
|
|
|
let window = WindowBuilder::new()
|
|
.with_title("A fantastic window!")
|
|
.with_inner_size(LogicalSize::from((100, 100)))
|
|
.build(&event_loop)
|
|
.unwrap();
|
|
|
|
eprintln!("debugging keys:");
|
|
eprintln!(" (E) Enter exclusive fullscreen");
|
|
eprintln!(" (F) Toggle borderless fullscreen");
|
|
#[cfg(waiting_for_set_minimized)]
|
|
eprintln!(" (M) Toggle minimized");
|
|
eprintln!(" (Q) Quit event loop");
|
|
eprintln!(" (V) Toggle visibility");
|
|
eprintln!(" (X) Toggle maximized");
|
|
|
|
#[cfg(waiting_for_set_minimized)]
|
|
let mut minimized = false;
|
|
let mut maximized = false;
|
|
let mut visible = true;
|
|
|
|
event_loop.run(move |event, _, control_flow| {
|
|
*control_flow = ControlFlow::Wait;
|
|
|
|
match event {
|
|
Event::DeviceEvent {
|
|
event:
|
|
DeviceEvent::Key(KeyboardInput {
|
|
virtual_keycode: Some(key),
|
|
state: ElementState::Pressed,
|
|
..
|
|
}),
|
|
..
|
|
} => match key {
|
|
#[cfg(waiting_for_set_minimized)]
|
|
VirtualKeyCode::M => {
|
|
if minimized {
|
|
minimized = !minimized;
|
|
window.set_minimized(minimized);
|
|
}
|
|
}
|
|
VirtualKeyCode::V => {
|
|
if !visible {
|
|
visible = !visible;
|
|
window.set_visible(visible);
|
|
}
|
|
}
|
|
_ => (),
|
|
},
|
|
Event::WindowEvent {
|
|
event: WindowEvent::KeyboardInput { input, .. },
|
|
..
|
|
} => match input {
|
|
KeyboardInput {
|
|
virtual_keycode: Some(key),
|
|
state: ElementState::Pressed,
|
|
..
|
|
} => match key {
|
|
VirtualKeyCode::E => {
|
|
fn area(size: PhysicalSize) -> f64 {
|
|
size.width * size.height
|
|
}
|
|
|
|
let monitor = window.current_monitor();
|
|
if let Some(mode) = monitor.video_modes().max_by(|a, b| {
|
|
area(a.size())
|
|
.partial_cmp(&area(b.size()))
|
|
.expect("NaN in video mode size")
|
|
}) {
|
|
window.set_fullscreen(Some(Fullscreen::Exclusive(mode)));
|
|
} else {
|
|
eprintln!("no video modes available");
|
|
}
|
|
}
|
|
VirtualKeyCode::F => {
|
|
if window.fullscreen().is_some() {
|
|
window.set_fullscreen(None);
|
|
} else {
|
|
let monitor = window.current_monitor();
|
|
window.set_fullscreen(Some(Fullscreen::Borderless(monitor)));
|
|
}
|
|
}
|
|
#[cfg(waiting_for_set_minimized)]
|
|
VirtualKeyCode::M => {
|
|
minimized = !minimized;
|
|
window.set_minimized(minimized);
|
|
}
|
|
VirtualKeyCode::Q => {
|
|
*control_flow = ControlFlow::Exit;
|
|
}
|
|
VirtualKeyCode::V => {
|
|
visible = !visible;
|
|
window.set_visible(visible);
|
|
}
|
|
VirtualKeyCode::X => {
|
|
maximized = !maximized;
|
|
window.set_maximized(maximized);
|
|
}
|
|
_ => (),
|
|
},
|
|
_ => (),
|
|
},
|
|
Event::WindowEvent {
|
|
event: WindowEvent::CloseRequested,
|
|
window_id,
|
|
} if window_id == window.id() => *control_flow = ControlFlow::Exit,
|
|
_ => (),
|
|
}
|
|
});
|
|
}
|