Add WindowBuilder::with_outer_position (#1866)

This commit is contained in:
Michal Srb 2021-03-25 21:18:51 +03:00 committed by GitHub
parent 86748fbc68
commit 0d634a0061
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 108 additions and 16 deletions

View file

@ -190,6 +190,24 @@ impl<'a> NormalHints<'a> {
}
}
pub fn get_position(&self) -> Option<(i32, i32)> {
if has_flag(self.size_hints.flags, ffi::PPosition) {
Some((self.size_hints.x as i32, self.size_hints.y as i32))
} else {
None
}
}
pub fn set_position(&mut self, position: Option<(i32, i32)>) {
if let Some((x, y)) = position {
self.size_hints.flags |= ffi::PPosition;
self.size_hints.x = x as c_int;
self.size_hints.y = y as c_int;
} else {
self.size_hints.flags &= !ffi::PPosition;
}
}
// WARNING: This hint is obsolete
pub fn set_size(&mut self, size: Option<(u32, u32)>) {
if let Some((width, height)) = size {

View file

@ -23,6 +23,7 @@ pub use self::{
use std::{
mem::{self, MaybeUninit},
ops::BitAnd,
os::raw::*,
ptr,
};
@ -39,6 +40,13 @@ pub fn maybe_change<T: PartialEq>(field: &mut Option<T>, value: T) -> bool {
}
}
pub fn has_flag<T>(bitset: T, flag: T) -> bool
where
T: Copy + PartialEq + BitAnd<T, Output = T>,
{
bitset & flag == flag
}
#[must_use = "This request was made asynchronously, and is still in the output buffer. You must explicitly choose to either `.flush()` (empty the output buffer, sending the request now) or `.queue()` (wait to send the request, allowing you to continue to add more requests without additional round-trips). For more information, see the documentation for `util::flush_requests`."]
pub struct Flusher<'a> {
xconn: &'a XConnection,

View file

@ -146,6 +146,10 @@ impl UnownedWindow {
.min_inner_size
.map(|size| size.to_physical::<u32>(scale_factor).into());
let position = window_attrs
.position
.map(|position| position.to_physical::<i32>(scale_factor).into());
let dimensions = {
// x11 only applies constraints when the window is actively resized
// by the user, so we have to manually apply the initial constraints
@ -211,8 +215,8 @@ impl UnownedWindow {
(xconn.xlib.XCreateWindow)(
xconn.display,
root,
0,
0,
position.map_or(0, |p: PhysicalPosition<i32>| p.x as c_int),
position.map_or(0, |p: PhysicalPosition<i32>| p.y as c_int),
dimensions.0 as c_uint,
dimensions.1 as c_uint,
0,
@ -344,6 +348,7 @@ impl UnownedWindow {
}
let mut normal_hints = util::NormalHints::new(xconn);
normal_hints.set_position(position.map(|PhysicalPosition { x, y }| (x, y)));
normal_hints.set_size(Some(dimensions));
normal_hints.set_min_size(min_inner_size.map(Into::into));
normal_hints.set_max_size(max_inner_size.map(Into::into));
@ -439,6 +444,12 @@ impl UnownedWindow {
window
.set_fullscreen_inner(window_attrs.fullscreen.clone())
.map(|flusher| flusher.queue());
if let Some(PhysicalPosition { x, y }) = position {
let shared_state = window.shared_state.get_mut();
shared_state.restore_position = Some((x, y));
}
}
if window_attrs.always_on_top {
window