X11: Properly update window size constraints on DPI change (#1356)

* In `WindowBuilderExtUnix` methods, use `Size` instead of `LogicalSize`
This commit is contained in:
Murarth 2020-01-03 23:14:11 -07:00 committed by Osspial
parent 3aa3880e69
commit ec1ae68cfc
4 changed files with 37 additions and 22 deletions

View file

@ -5,7 +5,7 @@ use std::{os::raw, ptr, sync::Arc};
use smithay_client_toolkit::window::{ButtonState, Theme}; use smithay_client_toolkit::window::{ButtonState, Theme};
use crate::{ use crate::{
dpi::LogicalSize, dpi::Size,
event_loop::{EventLoop, EventLoopWindowTarget}, event_loop::{EventLoop, EventLoopWindowTarget},
monitor::MonitorHandle, monitor::MonitorHandle,
window::{Window, WindowBuilder}, window::{Window, WindowBuilder},
@ -380,9 +380,9 @@ pub trait WindowBuilderExtUnix {
/// Build window with `_GTK_THEME_VARIANT` hint set to the specified value. Currently only relevant on X11. /// Build window with `_GTK_THEME_VARIANT` hint set to the specified value. Currently only relevant on X11.
fn with_gtk_theme_variant(self, variant: String) -> Self; fn with_gtk_theme_variant(self, variant: String) -> Self;
/// Build window with resize increment hint. Only implemented on X11. /// Build window with resize increment hint. Only implemented on X11.
fn with_resize_increments(self, increments: LogicalSize<f64>) -> Self; fn with_resize_increments<S: Into<Size>>(self, increments: S) -> Self;
/// Build window with base size hint. Only implemented on X11. /// Build window with base size hint. Only implemented on X11.
fn with_base_size(self, base_size: LogicalSize<f64>) -> Self; fn with_base_size<S: Into<Size>>(self, base_size: S) -> Self;
/// Build window with a given application ID. It should match the `.desktop` file distributed with /// Build window with a given application ID. It should match the `.desktop` file distributed with
/// your program. Only relevant on Wayland. /// your program. Only relevant on Wayland.
@ -431,13 +431,13 @@ impl WindowBuilderExtUnix for WindowBuilder {
} }
#[inline] #[inline]
fn with_resize_increments(mut self, increments: LogicalSize<f64>) -> Self { fn with_resize_increments<S: Into<Size>>(mut self, increments: S) -> Self {
self.platform_specific.resize_increments = Some(increments.into()); self.platform_specific.resize_increments = Some(increments.into());
self self
} }
#[inline] #[inline]
fn with_base_size(mut self, base_size: LogicalSize<f64>) -> Self { fn with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self {
self.platform_specific.base_size = Some(base_size.into()); self.platform_specific.base_size = Some(base_size.into());
self self
} }

View file

@ -34,8 +34,8 @@ const BACKEND_PREFERENCE_ENV_VAR: &str = "WINIT_UNIX_BACKEND";
pub struct PlatformSpecificWindowBuilderAttributes { pub struct PlatformSpecificWindowBuilderAttributes {
pub visual_infos: Option<XVisualInfo>, pub visual_infos: Option<XVisualInfo>,
pub screen_id: Option<i32>, pub screen_id: Option<i32>,
pub resize_increments: Option<(u32, u32)>, pub resize_increments: Option<Size>,
pub base_size: Option<(u32, u32)>, pub base_size: Option<Size>,
pub class: Option<(String, String)>, pub class: Option<(String, String)>,
pub override_redirect: bool, pub override_redirect: bool,
pub x11_window_types: Vec<XWindowType>, pub x11_window_types: Vec<XWindowType>,

View file

@ -420,6 +420,7 @@ impl<T: 'static> EventProcessor<T> {
new_scale_factor, new_scale_factor,
width, width,
height, height,
&shared_state_lock,
); );
let old_inner_size = PhysicalSize::new(width, height); let old_inner_size = PhysicalSize::new(width, height);
@ -1134,6 +1135,7 @@ impl<T: 'static> EventProcessor<T> {
new_monitor.scale_factor, new_monitor.scale_factor,
width, width,
height, height,
&*window.shared_state.lock(),
); );
let window_id = crate::window::WindowId( let window_id = crate::window::WindowId(

View file

@ -47,6 +47,8 @@ pub struct SharedState {
pub frame_extents: Option<util::FrameExtentsHeuristic>, pub frame_extents: Option<util::FrameExtentsHeuristic>,
pub min_inner_size: Option<Size>, pub min_inner_size: Option<Size>,
pub max_inner_size: Option<Size>, pub max_inner_size: Option<Size>,
pub resize_increments: Option<Size>,
pub base_size: Option<Size>,
pub visibility: Visibility, pub visibility: Visibility,
} }
@ -83,6 +85,8 @@ impl SharedState {
frame_extents: None, frame_extents: None,
min_inner_size: None, min_inner_size: None,
max_inner_size: None, max_inner_size: None,
resize_increments: None,
base_size: None,
}) })
} }
} }
@ -235,7 +239,7 @@ impl UnownedWindow {
) )
}; };
let window = UnownedWindow { let mut window = UnownedWindow {
xconn: Arc::clone(xconn), xconn: Arc::clone(xconn),
xwindow, xwindow,
root, root,
@ -324,6 +328,7 @@ impl UnownedWindow {
let mut max_inner_size = window_attrs let mut max_inner_size = window_attrs
.max_inner_size .max_inner_size
.map(|size| size.to_physical::<u32>(dpi_factor)); .map(|size| size.to_physical::<u32>(dpi_factor));
if !window_attrs.resizable { if !window_attrs.resizable {
if util::wm_name_is_one_of(&["Xfwm4"]) { if util::wm_name_is_one_of(&["Xfwm4"]) {
warn!("To avoid a WM bug, disabling resizing has no effect on Xfwm4"); warn!("To avoid a WM bug, disabling resizing has no effect on Xfwm4");
@ -331,9 +336,11 @@ impl UnownedWindow {
max_inner_size = Some(dimensions.into()); max_inner_size = Some(dimensions.into());
min_inner_size = Some(dimensions.into()); min_inner_size = Some(dimensions.into());
let mut shared_state_lock = window.shared_state.lock(); let mut shared_state = window.shared_state.get_mut();
shared_state_lock.min_inner_size = window_attrs.min_inner_size; shared_state.min_inner_size = window_attrs.min_inner_size;
shared_state_lock.max_inner_size = window_attrs.max_inner_size; shared_state.max_inner_size = window_attrs.max_inner_size;
shared_state.resize_increments = pl_attribs.resize_increments;
shared_state.base_size = pl_attribs.base_size;
} }
} }
@ -341,8 +348,16 @@ impl UnownedWindow {
normal_hints.set_size(Some(dimensions)); normal_hints.set_size(Some(dimensions));
normal_hints.set_min_size(min_inner_size.map(Into::into)); normal_hints.set_min_size(min_inner_size.map(Into::into));
normal_hints.set_max_size(max_inner_size.map(Into::into)); normal_hints.set_max_size(max_inner_size.map(Into::into));
normal_hints.set_resize_increments(pl_attribs.resize_increments); normal_hints.set_resize_increments(
normal_hints.set_base_size(pl_attribs.base_size); pl_attribs
.resize_increments
.map(|size| size.to_physical::<u32>(dpi_factor).into()),
);
normal_hints.set_base_size(
pl_attribs
.base_size
.map(|size| size.to_physical::<u32>(dpi_factor).into()),
);
xconn.set_normal_hints(window.xwindow, normal_hints).queue(); xconn.set_normal_hints(window.xwindow, normal_hints).queue();
} }
@ -1086,18 +1101,16 @@ impl UnownedWindow {
new_dpi_factor: f64, new_dpi_factor: f64,
width: u32, width: u32,
height: u32, height: u32,
shared_state: &SharedState,
) -> (u32, u32) { ) -> (u32, u32) {
let scale_factor = new_dpi_factor / old_dpi_factor; let scale_factor = new_dpi_factor / old_dpi_factor;
self.update_normal_hints(|normal_hints| { self.update_normal_hints(|normal_hints| {
let dpi_adjuster = |(width, height): (u32, u32)| -> (u32, u32) { let dpi_adjuster =
let new_width = width as f64 * scale_factor; |size: Size| -> (u32, u32) { size.to_physical::<u32>(new_dpi_factor).into() };
let new_height = height as f64 * scale_factor; let max_size = shared_state.max_inner_size.map(&dpi_adjuster);
(new_width.round() as u32, new_height.round() as u32) let min_size = shared_state.min_inner_size.map(&dpi_adjuster);
}; let resize_increments = shared_state.resize_increments.map(&dpi_adjuster);
let max_size = normal_hints.get_max_size().map(&dpi_adjuster); let base_size = shared_state.base_size.map(&dpi_adjuster);
let min_size = normal_hints.get_min_size().map(&dpi_adjuster);
let resize_increments = normal_hints.get_resize_increments().map(&dpi_adjuster);
let base_size = normal_hints.get_base_size().map(&dpi_adjuster);
normal_hints.set_max_size(max_size); normal_hints.set_max_size(max_size);
normal_hints.set_min_size(min_size); normal_hints.set_min_size(min_size);
normal_hints.set_resize_increments(resize_increments); normal_hints.set_resize_increments(resize_increments);