mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-02-24 00:37:43 +11:00
On X11, allow building window with parent
This commit is contained in:
parent
bb0f965c57
commit
71094e5703
6 changed files with 104 additions and 1 deletions
|
@ -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, `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, 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 Wayland, if not otherwise specified use upstream automatic CSD theme selection.
|
||||||
|
- On X11, added `WindowExtX11::with_parent` to create child windows.
|
||||||
|
|
||||||
# 0.27.3
|
# 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
|
* X11 Override Redirect Flag
|
||||||
* GTK Theme Variant
|
* GTK Theme Variant
|
||||||
* Base window size
|
* Base window size
|
||||||
|
* Setting the X11 parent window
|
||||||
|
|
||||||
### iOS
|
### iOS
|
||||||
* `winit` has a minimum OS requirement of iOS 8
|
* `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::os::raw;
|
||||||
use std::{ptr, sync::Arc};
|
use std::{ptr, sync::Arc};
|
||||||
|
|
||||||
|
use crate::window::WindowId;
|
||||||
use crate::{
|
use crate::{
|
||||||
event_loop::{EventLoopBuilder, EventLoopWindowTarget},
|
event_loop::{EventLoopBuilder, EventLoopWindowTarget},
|
||||||
monitor::MonitorHandle,
|
monitor::MonitorHandle,
|
||||||
|
@ -171,6 +172,8 @@ pub trait WindowBuilderExtX11 {
|
||||||
fn with_x11_visual<T>(self, visual_infos: *const T) -> Self;
|
fn with_x11_visual<T>(self, visual_infos: *const T) -> Self;
|
||||||
|
|
||||||
fn with_x11_screen(self, screen_id: i32) -> 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.
|
/// Build window with the given `general` and `instance` names.
|
||||||
///
|
///
|
||||||
|
@ -227,6 +230,12 @@ impl WindowBuilderExtX11 for WindowBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn with_parent(mut self, parent_id: WindowId) -> Self {
|
||||||
|
self.platform_specific.parent_id = Some(parent_id.0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_override_redirect(mut self, override_redirect: bool) -> Self {
|
fn with_override_redirect(mut self, override_redirect: bool) -> Self {
|
||||||
self.platform_specific.override_redirect = override_redirect;
|
self.platform_specific.override_redirect = override_redirect;
|
||||||
|
|
|
@ -95,6 +95,8 @@ pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
pub screen_id: Option<i32>,
|
pub screen_id: Option<i32>,
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
|
pub parent_id: Option<WindowId>,
|
||||||
|
#[cfg(feature = "x11")]
|
||||||
pub base_size: Option<Size>,
|
pub base_size: Option<Size>,
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
pub override_redirect: bool,
|
pub override_redirect: bool,
|
||||||
|
@ -115,6 +117,8 @@ impl Default for PlatformSpecificWindowBuilderAttributes {
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
screen_id: None,
|
screen_id: None,
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
|
parent_id: None,
|
||||||
|
#[cfg(feature = "x11")]
|
||||||
base_size: None,
|
base_size: None,
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
override_redirect: false,
|
override_redirect: false,
|
||||||
|
|
|
@ -119,7 +119,12 @@ impl UnownedWindow {
|
||||||
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||||
) -> Result<UnownedWindow, RootOsError> {
|
) -> Result<UnownedWindow, RootOsError> {
|
||||||
let xconn = &event_loop.xconn;
|
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 mut monitors = xconn.available_monitors();
|
||||||
let guessed_monitor = if monitors.is_empty() {
|
let guessed_monitor = if monitors.is_empty() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue