Windows & X11: Window::set_resizable (#558)

* Windows: Window::set_resizable

* X11: Window::set_resizable

* Code style regarding resizable

* X11: set_resizable remember max/min window size

* Stub out set_resizable on Android, iOS, and emscripten

* remove comment block from docs

* Windows: set_resizable in fullscreen

* Special case Xfwm

* Added fun provisos to docs
This commit is contained in:
Danny Fritz 2018-06-11 16:47:50 -06:00 committed by Francesca Frangipane
parent 2b4b64f499
commit be5a2b0e87
11 changed files with 155 additions and 26 deletions

View file

@ -232,6 +232,14 @@ impl Window {
&Window::Wayland(ref w) => w.set_max_dimensions(dimensions)
}
}
#[inline]
pub fn set_resizable(&self, resizable: bool) {
match self {
&Window::X(ref w) => w.set_resizable(resizable),
&Window::Wayland(ref _w) => unimplemented!(),
}
}
#[inline]
pub fn set_cursor(&self, cursor: MouseCursor) {

View file

@ -38,6 +38,8 @@ pub struct SharedState {
pub last_monitor: Option<X11MonitorId>,
pub dpi_adjusted: Option<(f64, f64)>,
pub frame_extents: Option<util::FrameExtentsHeuristic>,
pub min_dimensions: Option<(u32, u32)>,
pub max_dimensions: Option<(u32, u32)>,
}
unsafe impl Send for UnownedWindow {}
@ -216,9 +218,11 @@ impl UnownedWindow {
// set size hints
{
(*window.shared_state.lock()).min_dimensions = window_attrs.min_dimensions;
(*window.shared_state.lock()).max_dimensions = window_attrs.max_dimensions;
let mut min_dimensions = window_attrs.min_dimensions;
let mut max_dimensions = window_attrs.max_dimensions;
if !window_attrs.resizable {
if !window_attrs.resizable && !util::wm_name_is_one_of(&["Xfwm4"]) {
max_dimensions = Some(dimensions);
min_dimensions = Some(dimensions);
}
@ -699,6 +703,7 @@ impl UnownedWindow {
}
pub fn set_min_dimensions(&self, dimensions: Option<(u32, u32)>) {
(*self.shared_state.lock()).min_dimensions = dimensions;
unsafe {
self.update_normal_hints(|size_hints| {
if let Some((width, height)) = dimensions {
@ -713,6 +718,7 @@ impl UnownedWindow {
}
pub fn set_max_dimensions(&self, dimensions: Option<(u32, u32)>) {
(*self.shared_state.lock()).max_dimensions = dimensions;
unsafe {
self.update_normal_hints(|size_hints| {
if let Some((width, height)) = dimensions {
@ -726,6 +732,33 @@ impl UnownedWindow {
}.expect("Failed to call XSetWMNormalHints");
}
pub fn set_resizable(&self, resizable: bool) {
if util::wm_name_is_one_of(&["Xfwm4"]) {
// Making the window unresizable on Xfwm prevents further changes to `WM_NORMAL_HINTS` from being detected.
// This makes it impossible for resizing to be re-enabled, and also breaks DPI scaling. As such, we choose
// the lesser of two evils and do nothing.
return;
}
if resizable {
let min_dimensions = (*self.shared_state.lock()).min_dimensions;
let max_dimensions = (*self.shared_state.lock()).max_dimensions;
self.set_min_dimensions(min_dimensions);
self.set_max_dimensions(max_dimensions);
} else {
unsafe {
self.update_normal_hints(|size_hints| {
(*size_hints).flags |= ffi::PMinSize | ffi::PMaxSize;
if let Some((width, height)) = self.get_inner_size() {
(*size_hints).min_width = width as c_int;
(*size_hints).min_height = height as c_int;
(*size_hints).max_width = width as c_int;
(*size_hints).max_height = height as c_int;
}
})
}.expect("Failed to call XSetWMNormalHints");
}
}
#[inline]
pub fn get_xlib_display(&self) -> *mut c_void {
self.xconn.display as _