mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
On X11, allow building window with parent
This commit is contained in:
parent
bb0f965c57
commit
71094e5703
|
@ -23,6 +23,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
|||
- 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.
|
||||
- On X11, added `WindowExtX11::with_parent` to create child windows.
|
||||
|
||||
# 0.27.3
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ If your PR makes notable changes to Winit's features, please update this section
|
|||
* X11 Override Redirect Flag
|
||||
* GTK Theme Variant
|
||||
* Base window size
|
||||
* Setting the X11 parent window
|
||||
|
||||
### iOS
|
||||
* `winit` has a minimum OS requirement of iOS 8
|
||||
|
|
83
examples/child_window.rs
Normal file
83
examples/child_window.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
#[cfg(all(target_os = "linux", feature = "x11"))]
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[cfg(all(target_os = "linux", feature = "x11"))]
|
||||
use winit::{
|
||||
dpi::{LogicalPosition, LogicalSize, Position},
|
||||
event::{ElementState, Event, KeyboardInput, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
|
||||
platform::x11::{WindowBuilderExtX11, WindowExtX11},
|
||||
window::{Window, WindowBuilder, WindowId},
|
||||
};
|
||||
|
||||
#[cfg(all(target_os = "linux", feature = "x11"))]
|
||||
fn spawn_child_window(
|
||||
parent: u32,
|
||||
event_loop: &EventLoopWindowTarget<()>,
|
||||
windows: &mut HashMap<u32, Window>,
|
||||
) {
|
||||
let child_window = WindowBuilder::new()
|
||||
.with_parent(WindowId::from(parent as u64))
|
||||
.with_title("child window")
|
||||
.with_inner_size(LogicalSize::new(200.0f32, 200.0f32))
|
||||
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
|
||||
.with_visible(true)
|
||||
.build(event_loop)
|
||||
.unwrap();
|
||||
|
||||
let id = child_window.xlib_window().unwrap() as u32;
|
||||
windows.insert(id, child_window);
|
||||
println!("child window created with id: {}", id);
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "linux", feature = "x11"))]
|
||||
fn main() {
|
||||
let mut windows = HashMap::new();
|
||||
|
||||
let event_loop: EventLoop<()> = EventLoop::new();
|
||||
let parent_window = WindowBuilder::new()
|
||||
.with_title("parent window")
|
||||
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
|
||||
.with_inner_size(LogicalSize::new(640.0f32, 480.0f32))
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
let root = parent_window.xlib_window().unwrap() as u32;
|
||||
println!("parent window id: {})", root);
|
||||
|
||||
event_loop.run(move |event: Event<'_, ()>, event_loop, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
|
||||
if let Event::WindowEvent { event, window_id } = event {
|
||||
match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
windows.clear();
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
WindowEvent::CursorEntered { device_id: _ } => {
|
||||
// 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::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
spawn_child_window(root, event_loop, &mut windows);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_os = "linux", feature = "x11")))]
|
||||
fn main() {
|
||||
panic!("This example is supported only on x11.");
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
use std::os::raw;
|
||||
use std::{ptr, sync::Arc};
|
||||
|
||||
use crate::window::WindowId;
|
||||
use crate::{
|
||||
event_loop::{EventLoopBuilder, EventLoopWindowTarget},
|
||||
monitor::MonitorHandle,
|
||||
|
@ -171,6 +172,8 @@ pub trait WindowBuilderExtX11 {
|
|||
fn with_x11_visual<T>(self, visual_infos: *const T) -> Self;
|
||||
|
||||
fn with_x11_screen(self, screen_id: i32) -> Self;
|
||||
/// Build window with parent window.
|
||||
fn with_parent(self, parent_id: WindowId) -> Self;
|
||||
|
||||
/// Build window with the given `general` and `instance` names.
|
||||
///
|
||||
|
@ -227,6 +230,12 @@ impl WindowBuilderExtX11 for WindowBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_parent(mut self, parent_id: WindowId) -> Self {
|
||||
self.platform_specific.parent_id = Some(parent_id.0);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_override_redirect(mut self, override_redirect: bool) -> Self {
|
||||
self.platform_specific.override_redirect = override_redirect;
|
||||
|
|
|
@ -95,6 +95,8 @@ pub struct PlatformSpecificWindowBuilderAttributes {
|
|||
#[cfg(feature = "x11")]
|
||||
pub screen_id: Option<i32>,
|
||||
#[cfg(feature = "x11")]
|
||||
pub parent_id: Option<WindowId>,
|
||||
#[cfg(feature = "x11")]
|
||||
pub base_size: Option<Size>,
|
||||
#[cfg(feature = "x11")]
|
||||
pub override_redirect: bool,
|
||||
|
@ -115,6 +117,8 @@ impl Default for PlatformSpecificWindowBuilderAttributes {
|
|||
#[cfg(feature = "x11")]
|
||||
screen_id: None,
|
||||
#[cfg(feature = "x11")]
|
||||
parent_id: None,
|
||||
#[cfg(feature = "x11")]
|
||||
base_size: None,
|
||||
#[cfg(feature = "x11")]
|
||||
override_redirect: false,
|
||||
|
|
|
@ -119,7 +119,12 @@ impl UnownedWindow {
|
|||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<UnownedWindow, RootOsError> {
|
||||
let xconn = &event_loop.xconn;
|
||||
let root = event_loop.root;
|
||||
let root = if let Some(id) = pl_attribs.parent_id {
|
||||
// WindowId is XID under the hood which doesn't exceed u32, so this conversion is lossless
|
||||
u64::from(id) as _
|
||||
} else {
|
||||
event_loop.root
|
||||
};
|
||||
|
||||
let mut monitors = xconn.available_monitors();
|
||||
let guessed_monitor = if monitors.is_empty() {
|
||||
|
|
Loading…
Reference in a new issue