mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 13:51:30 +11:00
f7a84a5b50
The utils in this module should help the users to activate the windows they create, as well as manage activation tokens environment variables. The API is essential for Wayland in the first place, since some compositors may decide initial focus of the window based on whether the activation token was during the window creation. Fixes #2279. Co-authored-by: John Nunley <jtnunley01@gmail.com>
128 lines
4.2 KiB
Rust
128 lines
4.2 KiB
Rust
//! Demonstrates the use of startup notifications on Linux.
|
|
|
|
fn main() {
|
|
example::main();
|
|
}
|
|
|
|
#[cfg(any(x11_platform, wayland_platform))]
|
|
#[path = "./util/fill.rs"]
|
|
mod fill;
|
|
|
|
#[cfg(any(x11_platform, wayland_platform))]
|
|
mod example {
|
|
use std::collections::HashMap;
|
|
use std::rc::Rc;
|
|
|
|
use winit::event::{ElementState, Event, KeyEvent, WindowEvent};
|
|
use winit::event_loop::EventLoop;
|
|
use winit::keyboard::Key;
|
|
use winit::platform::startup_notify::{
|
|
EventLoopExtStartupNotify, WindowBuilderExtStartupNotify, WindowExtStartupNotify,
|
|
};
|
|
use winit::window::{Window, WindowBuilder, WindowId};
|
|
|
|
pub(super) fn main() {
|
|
// Create the event loop and get the activation token.
|
|
let event_loop = EventLoop::new();
|
|
let mut current_token = match event_loop.read_token_from_env() {
|
|
Some(token) => Some(token),
|
|
None => {
|
|
println!("No startup notification token found in environment.");
|
|
None
|
|
}
|
|
};
|
|
|
|
let mut windows: HashMap<WindowId, Rc<Window>> = HashMap::new();
|
|
let mut counter = 0;
|
|
let mut create_first_window = false;
|
|
|
|
event_loop.run(move |event, elwt, flow| {
|
|
match event {
|
|
Event::Resumed => create_first_window = true,
|
|
|
|
Event::WindowEvent {
|
|
window_id,
|
|
event:
|
|
WindowEvent::KeyboardInput {
|
|
event:
|
|
KeyEvent {
|
|
logical_key,
|
|
state: ElementState::Pressed,
|
|
..
|
|
},
|
|
..
|
|
},
|
|
} => {
|
|
if logical_key == Key::Character("n".into()) {
|
|
if let Some(window) = windows.get(&window_id) {
|
|
// Request a new activation token on this window.
|
|
// Once we get it we will use it to create a window.
|
|
window
|
|
.request_activation_token()
|
|
.expect("Failed to request activation token.");
|
|
}
|
|
}
|
|
}
|
|
|
|
Event::WindowEvent {
|
|
window_id,
|
|
event: WindowEvent::CloseRequested,
|
|
} => {
|
|
// Remove the window from the map.
|
|
windows.remove(&window_id);
|
|
if windows.is_empty() {
|
|
flow.set_exit();
|
|
return;
|
|
}
|
|
}
|
|
|
|
Event::WindowEvent {
|
|
event: WindowEvent::ActivationTokenDone { token, .. },
|
|
..
|
|
} => {
|
|
current_token = Some(token);
|
|
}
|
|
|
|
Event::RedrawRequested(id) => {
|
|
if let Some(window) = windows.get(&id) {
|
|
super::fill::fill_window(window);
|
|
}
|
|
}
|
|
|
|
_ => {}
|
|
}
|
|
|
|
// See if we've passed the deadline.
|
|
if current_token.is_some() || create_first_window {
|
|
// Create the initial window.
|
|
let window = {
|
|
let mut builder =
|
|
WindowBuilder::new().with_title(format!("Window {}", counter));
|
|
|
|
if let Some(token) = current_token.take() {
|
|
println!("Creating a window with token {token:?}");
|
|
builder = builder.with_activation_token(token);
|
|
}
|
|
|
|
Rc::new(builder.build(elwt).unwrap())
|
|
};
|
|
|
|
// Add the window to the map.
|
|
windows.insert(window.id(), window.clone());
|
|
|
|
counter += 1;
|
|
create_first_window = false;
|
|
}
|
|
|
|
flow.set_wait();
|
|
});
|
|
}
|
|
}
|
|
|
|
#[cfg(not(any(x11_platform, wayland_platform)))]
|
|
mod example {
|
|
pub(super) fn main() {
|
|
println!("This example is only supported on X11 and Wayland platforms.");
|
|
}
|
|
}
|