Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Child windows on Wayland #3487

Closed
17 changes: 9 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Unreleased` header.
- On X11, don't require XIM to run.
- On X11, fix xkb state not being updated correctly sometimes leading to wrong input.
- Fix compatibility with 32-bit platforms without 64-bit atomics.
- Implement `Sync` for `EventLoopProxy<T: Send>`.
- On X11, fix swapped instance and general class names.
- **Breaking:** Removed unnecessary generic parameter `T` from `EventLoopWindowTarget`.
- On Windows, macOS, X11, Wayland and Web, implement setting images as cursors. See the `custom_cursors.rs` example.
Expand Down Expand Up @@ -132,7 +133,7 @@ Unreleased` header.
# 0.29.3

- On Wayland, apply correct scale to `PhysicalSize` passed in `WindowBuilder::with_inner_size` when possible.
- On Wayland, fix `RedrawRequsted` being always sent without decorations and `sctk-adwaita` feature.
- On Wayland, fix `RedrawRequested` being always sent without decorations and `sctk-adwaita` feature.
- On Wayland, ignore resize requests when the window is fully tiled.
- On Wayland, use `configure_bounds` to constrain `with_inner_size` when compositor wants users to pick size.
- On Windows, fix deadlock when accessing the state during `Cursor{Enter,Leave}`.
Expand Down Expand Up @@ -384,7 +385,7 @@ Unreleased` header.
- **Breaking:**: Removed deprecated method `platform::unix::WindowExtUnix::is_ready`.
- Removed `parking_lot` dependency.
- **Breaking:** On macOS, add support for two-finger touchpad magnification and rotation gestures with new events `WindowEvent::TouchpadMagnify` and `WindowEvent::TouchpadRotate`. Also add support for touchpad smart-magnification gesture with a new event `WindowEvent::SmartMagnify`.
- **Breaking:** On web, the `WindowBuilderExtWebSys::with_prevent_default` setting (enabled by default), now additionally prevents scrolling of the webpage in mobile browsers, previously it only disabled scrolling on desktop.
- **Breaking:** On Web, the `WindowBuilderExtWebSys::with_prevent_default` setting (enabled by default), now additionally prevents scrolling of the webpage in mobile browsers, previously it only disabled scrolling on desktop.
- On Wayland, `wayland-csd-adwaita` now uses `ab_glyph` instead of `crossfont` to render the title for decorations.
- On Wayland, a new `wayland-csd-adwaita-crossfont` feature was added to use `crossfont` instead of `ab_glyph` for decorations.
- On Wayland, if not otherwise specified use upstream automatic CSD theme selection.
Expand All @@ -404,7 +405,7 @@ Unreleased` header.
- Added `Window::set_transparent` to provide a hint about transparency of the window on Wayland and macOS.
- On macOS, fix the mouse buttons other than left/right/middle being reported as middle.
- On Wayland, support fractional scaling via the wp-fractional-scale protocol.
- On web, fix removal of mouse event listeners from the global object upon window distruction.
- On Web, fix removal of mouse event listeners from the global object upon window destruction.
- Add WindowAttributes getter to WindowBuilder to allow introspection of default values.
- Added `Window::set_ime_purpose` for setting the IME purpose, currently implemented on Wayland only.

Expand Down Expand Up @@ -510,7 +511,7 @@ Unreleased` header.
- On Web, add `with_prevent_default` and `with_focusable` to `WindowBuilderExtWebSys` to control whether events should be propagated.
- On Windows, fix focus events being sent to inactive windows.
- **Breaking**, update `raw-window-handle` to `v0.5` and implement `HasRawDisplayHandle` for `Window` and `EventLoopWindowTarget`.
- On X11, add function `register_xlib_error_hook` into `winit::platform::unix` to subscribe for errors comming from Xlib.
- On X11, add function `register_xlib_error_hook` into `winit::platform::unix` to subscribe for errors coming from Xlib.
- On Android, upgrade `ndk` and `ndk-glue` dependencies to the recently released `0.7.0`.
- All platforms can now be relied on to emit a `Resumed` event. Applications are recommended to lazily initialize graphics state and windows on first resume for portability.
- **Breaking:**: Reverse horizontal scrolling sign in `MouseScrollDelta` to match the direction of vertical scrolling. A positive X value now means moving the content to the right. The meaning of vertical scrolling stays the same: a positive Y value means moving the content down.
Expand Down Expand Up @@ -809,7 +810,7 @@ Unreleased` header.
- On Windows, fix handling of surrogate pairs when dispatching `ReceivedCharacter`.
- On macOS 10.15, fix freeze upon exiting exclusive fullscreen mode.
- On iOS, fix panic upon closing the app.
- On X11, allow setting mulitple `XWindowType`s.
- On X11, allow setting multiple `XWindowType`s.
- On iOS, fix null window on initial `HiDpiFactorChanged` event.
- On Windows, fix fullscreen window shrinking upon getting restored to a normal window.
- On macOS, fix events not being emitted during modal loops, such as when windows are being resized
Expand Down Expand Up @@ -962,7 +963,7 @@ and `WindowEvent::HoveredFile`.
- On Windows, hiding the cursor no longer hides the cursor for all Winit windows - just the one `hide_cursor` was called on.
- On Windows, cursor grabs used to get perpetually canceled when the grabbing window lost focus. Now, cursor grabs automatically get re-initialized when the window regains focus and the mouse moves over the client area.
- On Windows, only vertical mouse wheel events were handled. Now, horizontal mouse wheel events are also handled.
- On Windows, ignore the AltGr key when populating the `ModifersState` type.
- On Windows, ignore the AltGr key when populating the `ModifiersState` type.

# Version 0.18.1 (2018-12-30)

Expand Down Expand Up @@ -1242,7 +1243,7 @@ _Yanked_

# Version 0.8.2 (2017-09-28)

- Uniformize keyboard scancode values accross Wayland and X11 (#297).
- Uniformize keyboard scancode values across Wayland and X11 (#297).
- Internal rework of the wayland event loop
- Added method `os::linux::WindowExt::is_ready`

Expand All @@ -1256,7 +1257,7 @@ _Yanked_
- Added `Window::set_maximized`, `WindowAttributes::maximized` and `WindowBuilder::with_maximized`.
- Added `Window::set_fullscreen`.
- Changed `with_fullscreen` to take a `Option<MonitorId>` instead of a `MonitorId`.
- Removed `MonitorId::get_native_identifer()` in favor of platform-specific traits in the `os`
- Removed `MonitorId::get_native_identifier()` in favor of platform-specific traits in the `os`
module.
- Changed `get_available_monitors()` and `get_primary_monitor()` to be methods of `EventsLoop`
instead of stand-alone methods.
Expand Down
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ rustdoc-args = ["--cfg", "docsrs"]
[features]
default = ["rwh_06", "x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"]
x11 = ["x11-dl", "bytemuck", "percent-encoding", "xkbcommon-dl/x11", "x11rb"]
wayland = ["wayland-client", "wayland-backend", "wayland-protocols", "wayland-protocols-plasma", "sctk", "ahash", "memmap2"]
wayland = ["wayland-client", "wayland-backend", "wayland-sys", "wayland-protocols", "wayland-protocols-plasma", "sctk", "ahash", "memmap2"]
wayland-dlopen = ["wayland-backend/dlopen"]
wayland-csd-adwaita = ["sctk-adwaita", "sctk-adwaita/ab_glyph"]
wayland-csd-adwaita-crossfont = ["sctk-adwaita", "sctk-adwaita/crossfont"]
Expand Down Expand Up @@ -183,8 +183,9 @@ percent-encoding = { version = "2.0", optional = true }
rustix = { version = "0.38.4", default-features = false, features = ["std", "system", "thread", "process"] }
sctk = { package = "smithay-client-toolkit", version = "0.18.0", default-features = false, features = ["calloop"], optional = true }
sctk-adwaita = { version = "0.8.0", default_features = false, optional = true }
wayland-sys = { version = "0.31.1" , optional = true}
wayland-backend = { version = "0.3.0", default_features = false, features = ["client_system"], optional = true }
wayland-client = { version = "0.31.1", optional = true }
wayland-client = { version = "0.31.0", optional = true }
wayland-protocols = { version = "0.31.0", features = [ "staging"], optional = true }
wayland-protocols-plasma = { version = "0.2.0", features = [ "client" ], optional = true }
x11-dl = { version = "2.18.5", optional = true }
Expand Down
85 changes: 46 additions & 39 deletions examples/child_window.rs
Original file line number Diff line number Diff line change
@@ -1,97 +1,104 @@
#[cfg(all(
feature = "rwh_06",
any(x11_platform, macos_platform, windows_platform)
any(x11_platform, wayland_platform, macos_platform, windows_platform)
))]
#[path = "util/fill.rs"]
mod fill;

#[cfg(all(
feature = "rwh_06",
any(x11_platform, macos_platform, windows_platform)
any(x11_platform, wayland_platform, macos_platform, windows_platform)
))]
#[allow(deprecated)]
fn main() -> Result<(), impl std::error::Error> {
use std::collections::HashMap;

use rwh_06::HasRawWindowHandle;
use winit::{
dpi::{LogicalPosition, LogicalSize, Position},
dpi::{LogicalPosition, LogicalSize},
event::{ElementState, Event, KeyEvent, WindowEvent},
event_loop::{EventLoop, EventLoopWindowTarget},
raw_window_handle::HasRawWindowHandle,
keyboard::{Key, NamedKey},
window::{Window, WindowId},
};

fn spawn_child_window(
fn spawn_child(
parent: &Window,
event_loop: &EventLoopWindowTarget,
windows: &mut HashMap<WindowId, Window>,
children: &mut HashMap<WindowId, Window>,
) {
let parent = parent.raw_window_handle().unwrap();
let mut builder = Window::builder()
.with_title("child window")
.with_position(LogicalPosition::new(0, 0))
.with_inner_size(LogicalSize::new(200.0f32, 200.0f32))
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
.with_visible(true);
// `with_parent_window` is unsafe. Parent window must be a valid window.
builder = unsafe { builder.with_parent_window(Some(parent)) };
let child_window = builder.build(event_loop).unwrap();

let id = child_window.id();
windows.insert(id, child_window);
println!("child window created with id: {id:?}");
// Adding a parent window handle is inherently unsafe, as it is the programmer's
// responsibility to ensure that the parent handle is valid.
builder = unsafe { builder.with_parent_window(parent.raw_window_handle().ok()) };

let child = builder.build(event_loop).unwrap();
let child_id = child.id();
println!("child ID: {child_id:?}");

children.insert(child_id, child);
}

let mut windows = HashMap::new();
let event_loop = EventLoop::new().unwrap();

let event_loop: EventLoop<()> = EventLoop::new().unwrap();
let parent_window = Window::builder()
let window = Window::builder()
.with_title("parent window")
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
.with_inner_size(LogicalSize::new(640.0f32, 480.0f32))
.with_inner_size(winit::dpi::LogicalSize::new(640.0, 480.0))
.build(&event_loop)
.unwrap();
let mut children = HashMap::<WindowId, Window>::new();

println!("parent window: {parent_window:?})");

event_loop.run(move |event: Event<()>, elwt| {
if let Event::WindowEvent { event, window_id } = event {
match event {
event_loop.run(move |event, elwt| {
match event {
Event::WindowEvent { event, window_id } => match event {
WindowEvent::CloseRequested => {
windows.clear();
children.clear();
elwt.exit();
}
WindowEvent::CursorEntered { device_id: _ } => {
// On x11, println when the cursor entered in a window even if the child window is created
// by some key inputs.
// the child windows are always placed at (0, 0) with size (200, 200) in the parent window,
// so we also can see this log when we move the cursor arround (200, 200) in parent window.
println!("cursor entered in the window {window_id:?}");
WindowEvent::RedrawRequested => {
// Notify the windowing system that we'll be presenting to the window.
if let Some(child_window) = children.get(&window_id) {
child_window.pre_present_notify();
fill::fill_window(&child_window);
} else if window_id == window.id() {
window.pre_present_notify();
fill::fill_window(&window);
}
}
WindowEvent::KeyboardInput {
event:
KeyEvent {
logical_key: Key::Named(NamedKey::Enter),
state: ElementState::Pressed,
..
},
..
} => {
spawn_child_window(&parent_window, elwt, &mut windows);
println!("Spawning child...");
spawn_child(&window, &elwt, &mut children);
}
WindowEvent::RedrawRequested => {
if let Some(window) = windows.get(&window_id) {
fill::fill_window(window);
}
WindowEvent::CursorEntered { .. } => {
println!("cursor entered window {window_id:?}");
}
_ => (),
},
Event::AboutToWait => {
window.request_redraw();
}

_ => (),
}
})
}

#[cfg(not(all(
feature = "rwh_06",
any(x11_platform, macos_platform, windows_platform)
any(x11_platform, wayland_platform, macos_platform, windows_platform)
)))]
fn main() {
panic!("This example is supported only on x11, macOS, and Windows, with the `rwh_06` feature enabled.");
panic!("This example is supported only on X11, Wayland, macOS, and Windows, with the `rwh_06` feature enabled.");
}
2 changes: 1 addition & 1 deletion examples/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn main() -> Result<(), impl std::error::Error> {
},
..
} => match key.as_ref() {
// WARNING: Consider using `key_without_modifers()` if available on your platform.
// WARNING: Consider using `key_without_modifiers()` if available on your platform.
// See the `key_binding` example
Key::Character("1") => {
mode = Mode::Wait;
Expand Down
2 changes: 1 addition & 1 deletion examples/fullscreen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn main() -> Result<(), impl std::error::Error> {
..
} => match key {
Key::Named(NamedKey::Escape) => elwt.exit(),
// WARNING: Consider using `key_without_modifers()` if available on your platform.
// WARNING: Consider using `key_without_modifiers()` if available on your platform.
// See the `key_binding` example
Key::Character(ch) => match ch.to_lowercase().as_str() {
"f" | "b" if window.fullscreen().is_some() => {
Expand Down
2 changes: 1 addition & 1 deletion examples/handling_close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn main() -> Result<(), impl std::error::Error> {
},
..
} => {
// WARNING: Consider using `key_without_modifers()` if available on your platform.
// WARNING: Consider using `key_without_modifiers()` if available on your platform.
// See the `key_binding` example
match key.as_ref() {
Key::Character("y") => {
Expand Down
2 changes: 1 addition & 1 deletion examples/multithreaded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ fn main() -> Result<(), impl std::error::Error> {
}
println!("Picking video mode: {}", video_modes[video_mode_id]);
}
// WARNING: Consider using `key_without_modifers()` if available on your platform.
// WARNING: Consider using `key_without_modifiers()` if available on your platform.
// See the `key_binding` example
Key::Character(ch) => match ch.to_lowercase().as_str() {
"1" => window.set_window_level(WindowLevel::AlwaysOnTop),
Expand Down
1 change: 0 additions & 1 deletion examples/web_aspect_ratio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ pub fn main() {
#[cfg(web_platform)]
mod wasm {
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::HtmlCanvasElement;
use winit::{
dpi::PhysicalSize,
Expand Down
4 changes: 2 additions & 2 deletions examples/window_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn main() -> Result<(), impl std::error::Error> {
eprintln!("debugging keys:");
eprintln!(" (E) Enter exclusive fullscreen");
eprintln!(" (F) Toggle borderless fullscreen");
eprintln!(" (P) Toggle borderless fullscreen on system's preffered monitor");
eprintln!(" (P) Toggle borderless fullscreen on system's preferred monitor");
eprintln!(" (M) Toggle minimized");
eprintln!(" (Q) Quit event loop");
eprintln!(" (V) Toggle visibility");
Expand Down Expand Up @@ -76,7 +76,7 @@ fn main() -> Result<(), impl std::error::Error> {
},
..
} => match key_str.as_ref() {
// WARNING: Consider using `key_without_modifers()` if available on your platform.
// WARNING: Consider using `key_without_modifiers()` if available on your platform.
// See the `key_binding` example
"e" => {
fn area(size: PhysicalSize<u32>) -> u32 {
Expand Down
2 changes: 1 addition & 1 deletion src/dpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ pub fn validate_scale_factor(scale_factor: f64) -> bool {
/// A position represented in logical pixels.
///
/// The position is stored as floats, so please be careful. Casting floats to integers truncates the
/// fractional part, which can cause noticable issues. To help with that, an `Into<(i32, i32)>`
/// fractional part, which can cause noticeable issues. To help with that, an `Into<(i32, i32)>`
/// implementation is provided which does the rounding for you.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand Down
8 changes: 4 additions & 4 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ pub enum WindowEvent {
/// The activation token was delivered back and now could be used.
///
#[cfg_attr(
not(any(x11_platform, wayland_platfrom)),
not(any(x11_platform, wayland_platform)),
allow(rustdoc::broken_intra_doc_links)
)]
/// Delivered in response to [`request_activation_token`].
Expand Down Expand Up @@ -473,7 +473,7 @@ pub enum WindowEvent {
/// The event is general enough that its generating gesture is allowed to vary
/// across platforms. It could also be generated by another device.
///
/// Unfortunatly, neither [Windows](https://support.microsoft.com/en-us/windows/touch-gestures-for-windows-a9d28305-4818-a5df-4e2b-e5590f850741)
/// Unfortunately, neither [Windows](https://support.microsoft.com/en-us/windows/touch-gestures-for-windows-a9d28305-4818-a5df-4e2b-e5590f850741)
/// nor [Wayland](https://wayland.freedesktop.org/libinput/doc/latest/gestures.html)
/// support this gesture or any other gesture with the same effect.
///
Expand Down Expand Up @@ -1112,7 +1112,7 @@ pub enum MouseScrollDelta {
PixelDelta(PhysicalPosition<f64>),
}

/// Handle to synchroniously change the size of the window from the
/// Handle to synchronously change the size of the window from the
/// [`WindowEvent`].
#[derive(Debug, Clone)]
pub struct InnerSizeWriter {
Expand All @@ -1125,7 +1125,7 @@ impl InnerSizeWriter {
Self { new_inner_size }
}

/// Try to request inner size which will be set synchroniously on the window.
/// Try to request inner size which will be set synchronously on the window.
pub fn request_inner_size(
&mut self,
new_inner_size: PhysicalSize<u32>,
Expand Down
Loading