From da3bd4dabcfb6ba7e09815f77ae9c1a75eed6683 Mon Sep 17 00:00:00 2001 From: Danny Fritz Date: Thu, 7 Jun 2018 14:28:51 -0600 Subject: [PATCH 1/9] Windows: Window::set_resizable --- CHANGELOG.md | 1 + examples/no_resize.rs | 22 --------------------- examples/resizable.rs | 36 ++++++++++++++++++++++++++++++++++ src/platform/windows/window.rs | 27 +++++++++++++++++++++++++ src/window.rs | 10 ++++++++++ 5 files changed, 74 insertions(+), 22 deletions(-) delete mode 100644 examples/no_resize.rs create mode 100644 examples/resizable.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a00b88d3d..a7b30c4838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - On X11, the `Moved` event is no longer sent when the window is resized without changing position. - `MouseCursor` and `CursorState` now implement `Default`. - `WindowBuilder::with_resizable` implemented for Windows, X11, and macOS. +- `Window::set_resizable` implemented for MacOS and Windows. - On X11, if the monitor's width or height in millimeters is reported as 0, the DPI is now 1.0 instead of +inf. - On X11, the environment variable `WINIT_HIDPI_FACTOR` has been added for overriding DPI factor. - On X11, enabling transparency no longer causes the window contents to flicker when resizing. diff --git a/examples/no_resize.rs b/examples/no_resize.rs deleted file mode 100644 index 888c19bdc9..0000000000 --- a/examples/no_resize.rs +++ /dev/null @@ -1,22 +0,0 @@ -extern crate winit; - -fn main() { - let mut events_loop = winit::EventsLoop::new(); - - let _window = winit::WindowBuilder::new() - .with_title("A non-resizable window!") - .with_dimensions(200, 200) - .with_resizable(false) - .build(&events_loop) - .unwrap(); - - events_loop.run_forever(|event| { - match event { - winit::Event::WindowEvent { - event: winit::WindowEvent::CloseRequested, - .. - } => winit::ControlFlow::Break, - _ => winit::ControlFlow::Continue, - } - }); -} diff --git a/examples/resizable.rs b/examples/resizable.rs new file mode 100644 index 0000000000..6b445e9cb2 --- /dev/null +++ b/examples/resizable.rs @@ -0,0 +1,36 @@ +extern crate winit; + +fn main() { + let mut events_loop = winit::EventsLoop::new(); + + let window = winit::WindowBuilder::new() + .with_title("Hit space to toggle resizability.") + .with_dimensions(400, 200) + .with_resizable(false) + .build(&events_loop) + .unwrap(); + + let mut resizable = false; + + events_loop.run_forever(|event| match event { + winit::Event::WindowEvent { event, .. } => match event { + winit::WindowEvent::CloseRequested => winit::ControlFlow::Break, + winit::WindowEvent::KeyboardInput { + input: + winit::KeyboardInput { + virtual_keycode: Some(winit::VirtualKeyCode::Space), + state: winit::ElementState::Released, + .. + }, + .. + } => { + resizable = !resizable; + println!("Resizable: {}", resizable); + window.set_resizable(resizable); + winit::ControlFlow::Continue + } + _ => winit::ControlFlow::Continue, + }, + _ => winit::ControlFlow::Continue, + }); +} diff --git a/src/platform/windows/window.rs b/src/platform/windows/window.rs index 5c8987a233..5f05889496 100644 --- a/src/platform/windows/window.rs +++ b/src/platform/windows/window.rs @@ -239,6 +239,33 @@ impl Window { } } } + + /// See the docs in the crate root file. + #[inline] + pub fn set_resizable(&self, resizable: bool) { + if let Ok(mut window_state) = self.window_state.lock() { + if window_state.attributes.resizable == resizable { + return; + } + let window = self.window.clone(); + let mut style = unsafe { + winuser::GetWindowLongW(self.window.0, winuser::GWL_STYLE) + }; + if resizable { + style |= winuser::WS_SIZEBOX as i32; + } else { + style &= !winuser::WS_SIZEBOX as i32; + } + unsafe { + winuser::SetWindowLongW( + window.0, + winuser::GWL_STYLE, + style as _, + ); + }; + window_state.attributes.resizable = resizable; + } + } // TODO: remove pub fn platform_display(&self) -> *mut ::libc::c_void { diff --git a/src/window.rs b/src/window.rs index ebf025c038..ba9d90ac7f 100644 --- a/src/window.rs +++ b/src/window.rs @@ -316,6 +316,16 @@ impl Window { pub fn set_max_dimensions(&self, dimensions: Option<(u32, u32)>) { self.window.set_max_dimensions(dimensions) } + + /// Sets whether the window is resizable or not. + /// + /// ## Platform-specific + /// + /// This only has an effect on Windows and MacOS. + #[inline] + pub fn set_resizable(&self, resizable: bool) { + self.window.set_resizable(resizable) + } /// DEPRECATED. Gets the native platform specific display for this window. /// This is typically only required when integrating with From 1933165ffd5e38413a550b85ed2ca0fcd3d3f837 Mon Sep 17 00:00:00 2001 From: Danny Fritz Date: Thu, 7 Jun 2018 15:12:56 -0600 Subject: [PATCH 2/9] X11: Window::set_resizable --- CHANGELOG.md | 2 +- src/lib.rs | 2 +- src/platform/linux/mod.rs | 9 +++++++++ src/platform/linux/x11/window.rs | 20 ++++++++++++++++++++ src/window.rs | 2 +- 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7b30c4838..af2a206043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ - On X11, the `Moved` event is no longer sent when the window is resized without changing position. - `MouseCursor` and `CursorState` now implement `Default`. - `WindowBuilder::with_resizable` implemented for Windows, X11, and macOS. -- `Window::set_resizable` implemented for MacOS and Windows. +- `Window::set_resizable` implemented for MacOS, X11, and Windows. - On X11, if the monitor's width or height in millimeters is reported as 0, the DPI is now 1.0 instead of +inf. - On X11, the environment variable `WINIT_HIDPI_FACTOR` has been added for overriding DPI factor. - On X11, enabling transparency no longer causes the window contents to flicker when resizing. diff --git a/src/lib.rs b/src/lib.rs index dd1b889587..24ea46b5be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -422,7 +422,7 @@ pub struct WindowAttributes { /// The default is `None`. pub max_dimensions: Option<(u32, u32)>, - /// [Windows & X11 only] Whether the window is resizable or not + /// [Windows, MacOS, and X11 only] Whether the window is resizable or not /// /// The default is `true`. pub resizable: bool, diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 020420ad22..562a8e11de 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -232,6 +232,15 @@ 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) => w.set_resizable(resizable), + _ => {} + } + } #[inline] pub fn set_cursor(&self, cursor: MouseCursor) { diff --git a/src/platform/linux/x11/window.rs b/src/platform/linux/x11/window.rs index 9f64f29655..627e75d75f 100644 --- a/src/platform/linux/x11/window.rs +++ b/src/platform/linux/x11/window.rs @@ -726,6 +726,26 @@ impl UnownedWindow { }.expect("Failed to call XSetWMNormalHints"); } + pub fn set_resizable(&self, resizable: bool) { + unsafe { + self.update_normal_hints(|size_hints| { + if resizable { + (*size_hints).flags &= !ffi::PMinSize; + (*size_hints).flags &= !ffi::PMaxSize; + } else { + (*size_hints).flags |= ffi::PMinSize; + (*size_hints).flags |= 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 _ diff --git a/src/window.rs b/src/window.rs index ba9d90ac7f..e6743fb473 100644 --- a/src/window.rs +++ b/src/window.rs @@ -321,7 +321,7 @@ impl Window { /// /// ## Platform-specific /// - /// This only has an effect on Windows and MacOS. + /// This only has an effect on Windows, X11, and MacOS. #[inline] pub fn set_resizable(&self, resizable: bool) { self.window.set_resizable(resizable) From dd1022a097ce6f6b8ff0e76bac28f357f9d8446e Mon Sep 17 00:00:00 2001 From: Danny Fritz Date: Fri, 8 Jun 2018 14:39:38 -0600 Subject: [PATCH 3/9] Code style regarding resizable --- CHANGELOG.md | 2 +- examples/resizable.rs | 48 +++++++++++++++++--------------- src/lib.rs | 2 +- src/platform/linux/mod.rs | 3 +- src/platform/linux/x11/window.rs | 6 ++-- src/platform/windows/window.rs | 5 ++-- src/window.rs | 6 ++-- 7 files changed, 36 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af2a206043..9996049e8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ - On X11, the `Moved` event is no longer sent when the window is resized without changing position. - `MouseCursor` and `CursorState` now implement `Default`. - `WindowBuilder::with_resizable` implemented for Windows, X11, and macOS. -- `Window::set_resizable` implemented for MacOS, X11, and Windows. +- `Window::set_resizable` implemented for Windows, X11, and macOS. - On X11, if the monitor's width or height in millimeters is reported as 0, the DPI is now 1.0 instead of +inf. - On X11, the environment variable `WINIT_HIDPI_FACTOR` has been added for overriding DPI factor. - On X11, enabling transparency no longer causes the window contents to flicker when resizing. diff --git a/examples/resizable.rs b/examples/resizable.rs index 6b445e9cb2..f1557445eb 100644 --- a/examples/resizable.rs +++ b/examples/resizable.rs @@ -3,34 +3,36 @@ extern crate winit; fn main() { let mut events_loop = winit::EventsLoop::new(); + let mut resizable = false; + let window = winit::WindowBuilder::new() .with_title("Hit space to toggle resizability.") .with_dimensions(400, 200) - .with_resizable(false) + .with_resizable(resizable) .build(&events_loop) .unwrap(); - let mut resizable = false; - - events_loop.run_forever(|event| match event { - winit::Event::WindowEvent { event, .. } => match event { - winit::WindowEvent::CloseRequested => winit::ControlFlow::Break, - winit::WindowEvent::KeyboardInput { - input: - winit::KeyboardInput { - virtual_keycode: Some(winit::VirtualKeyCode::Space), - state: winit::ElementState::Released, - .. - }, - .. - } => { - resizable = !resizable; - println!("Resizable: {}", resizable); - window.set_resizable(resizable); - winit::ControlFlow::Continue - } - _ => winit::ControlFlow::Continue, - }, - _ => winit::ControlFlow::Continue, + events_loop.run_forever(|event| { + match event { + winit::Event::WindowEvent { event, .. } => match event { + winit::WindowEvent::CloseRequested => return winit::ControlFlow::Break, + winit::WindowEvent::KeyboardInput { + input: + winit::KeyboardInput { + virtual_keycode: Some(winit::VirtualKeyCode::Space), + state: winit::ElementState::Released, + .. + }, + .. + } => { + resizable = !resizable; + println!("Resizable: {}", resizable); + window.set_resizable(resizable); + } + _ => (), + }, + _ => (), + }; + winit::ControlFlow::Continue }); } diff --git a/src/lib.rs b/src/lib.rs index 24ea46b5be..5a32433395 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -422,7 +422,7 @@ pub struct WindowAttributes { /// The default is `None`. pub max_dimensions: Option<(u32, u32)>, - /// [Windows, MacOS, and X11 only] Whether the window is resizable or not + /// Whether the window is resizable or not. /// /// The default is `true`. pub resizable: bool, diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 562a8e11de..686ec46586 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -237,8 +237,7 @@ impl Window { pub fn set_resizable(&self, resizable: bool) { match self { &Window::X(ref w) => w.set_resizable(resizable), - // &Window::Wayland(ref w) => w.set_resizable(resizable), - _ => {} + &Window::Wayland(ref _w) => unimplemented!(), } } diff --git a/src/platform/linux/x11/window.rs b/src/platform/linux/x11/window.rs index 627e75d75f..71028554b9 100644 --- a/src/platform/linux/x11/window.rs +++ b/src/platform/linux/x11/window.rs @@ -730,11 +730,9 @@ impl UnownedWindow { unsafe { self.update_normal_hints(|size_hints| { if resizable { - (*size_hints).flags &= !ffi::PMinSize; - (*size_hints).flags &= !ffi::PMaxSize; + (*size_hints).flags &= !(ffi::PMinSize | ffi::PMaxSize); } else { - (*size_hints).flags |= ffi::PMinSize; - (*size_hints).flags |= ffi::PMaxSize; + (*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; diff --git a/src/platform/windows/window.rs b/src/platform/windows/window.rs index 5f05889496..b7b03d9763 100644 --- a/src/platform/windows/window.rs +++ b/src/platform/windows/window.rs @@ -240,7 +240,6 @@ impl Window { } } - /// See the docs in the crate root file. #[inline] pub fn set_resizable(&self, resizable: bool) { if let Ok(mut window_state) = self.window_state.lock() { @@ -252,9 +251,9 @@ impl Window { winuser::GetWindowLongW(self.window.0, winuser::GWL_STYLE) }; if resizable { - style |= winuser::WS_SIZEBOX as i32; + style |= winuser::WS_SIZEBOX as LONG; } else { - style &= !winuser::WS_SIZEBOX as i32; + style &= !winuser::WS_SIZEBOX as LONG; } unsafe { winuser::SetWindowLongW( diff --git a/src/window.rs b/src/window.rs index e6743fb473..b804220cdc 100644 --- a/src/window.rs +++ b/src/window.rs @@ -317,15 +317,17 @@ impl Window { self.window.set_max_dimensions(dimensions) } + /* /// Sets whether the window is resizable or not. /// /// ## Platform-specific /// - /// This only has an effect on Windows, X11, and MacOS. - #[inline] + /// This only has an effect on Windows, X11, and macOS. + #[inline] pub fn set_resizable(&self, resizable: bool) { self.window.set_resizable(resizable) } + */ /// DEPRECATED. Gets the native platform specific display for this window. /// This is typically only required when integrating with From 7351b4c7565a29418b5c1e70720aded9d62e89f0 Mon Sep 17 00:00:00 2001 From: Danny Fritz Date: Fri, 8 Jun 2018 15:33:03 -0600 Subject: [PATCH 4/9] X11: set_resizable remember max/min window size --- src/platform/linux/x11/window.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/platform/linux/x11/window.rs b/src/platform/linux/x11/window.rs index 71028554b9..675b3bcb2f 100644 --- a/src/platform/linux/x11/window.rs +++ b/src/platform/linux/x11/window.rs @@ -38,6 +38,8 @@ pub struct SharedState { pub last_monitor: Option, pub dpi_adjusted: Option<(f64, f64)>, pub frame_extents: Option, + pub min_dimensions: Option<(u32, u32)>, + pub max_dimensions: Option<(u32, u32)>, } unsafe impl Send for UnownedWindow {} @@ -216,6 +218,8 @@ 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 { @@ -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 { @@ -727,11 +733,14 @@ impl UnownedWindow { } pub fn set_resizable(&self, resizable: bool) { - unsafe { - self.update_normal_hints(|size_hints| { - if resizable { - (*size_hints).flags &= !(ffi::PMinSize | ffi::PMaxSize); - } else { + 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; @@ -739,9 +748,9 @@ impl UnownedWindow { (*size_hints).max_width = width as c_int; (*size_hints).max_height = height as c_int; } - } - }) - }.expect("Failed to call XSetWMNormalHints"); + }) + }.expect("Failed to call XSetWMNormalHints"); + } } #[inline] From eff001243198ec5572071ea3c5557864b6f74484 Mon Sep 17 00:00:00 2001 From: Danny Fritz Date: Fri, 8 Jun 2018 16:06:51 -0600 Subject: [PATCH 5/9] Stub out set_resizable on Android, iOS, and emscripten --- src/platform/android/mod.rs | 5 +++++ src/platform/emscripten/mod.rs | 5 +++++ src/platform/ios/mod.rs | 5 +++++ src/window.rs | 2 +- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/platform/android/mod.rs b/src/platform/android/mod.rs index 89ab74021e..ad08e51276 100644 --- a/src/platform/android/mod.rs +++ b/src/platform/android/mod.rs @@ -258,6 +258,11 @@ impl Window { #[inline] pub fn set_max_dimensions(&self, _dimensions: Option<(u32, u32)>) { } + #[inline] + pub fn set_resizable(&self, _resizable: bool) { + // N/A + } + #[inline] pub fn get_inner_size(&self) -> Option<(u32, u32)> { if self.native_window.is_null() { diff --git a/src/platform/emscripten/mod.rs b/src/platform/emscripten/mod.rs index b54ae1a2cc..9bd7f636fb 100644 --- a/src/platform/emscripten/mod.rs +++ b/src/platform/emscripten/mod.rs @@ -462,6 +462,11 @@ impl Window { #[inline] pub fn set_max_dimensions(&self, _dimensions: Option<(u32, u32)>) { } + + #[inline] + pub fn set_resizable(&self, _resizable: bool) { + // N/A + } #[inline] pub fn show(&self) {} diff --git a/src/platform/ios/mod.rs b/src/platform/ios/mod.rs index 5a3645c0d6..e135585102 100644 --- a/src/platform/ios/mod.rs +++ b/src/platform/ios/mod.rs @@ -317,6 +317,11 @@ impl Window { #[inline] pub fn set_max_dimensions(&self, _dimensions: Option<(u32, u32)>) { } + #[inline] + pub fn set_resizable(&self, _resizable: bool) { + // N/A + } + #[inline] pub fn platform_display(&self) -> *mut libc::c_void { unimplemented!(); diff --git a/src/window.rs b/src/window.rs index b804220cdc..865ec93ca5 100644 --- a/src/window.rs +++ b/src/window.rs @@ -323,11 +323,11 @@ impl Window { /// ## Platform-specific /// /// This only has an effect on Windows, X11, and macOS. + */ #[inline] pub fn set_resizable(&self, resizable: bool) { self.window.set_resizable(resizable) } - */ /// DEPRECATED. Gets the native platform specific display for this window. /// This is typically only required when integrating with From ebc930cf5e243a35fa5d588addaefb7da711e18b Mon Sep 17 00:00:00 2001 From: Danny Fritz Date: Fri, 8 Jun 2018 18:58:03 -0600 Subject: [PATCH 6/9] remove comment block from docs --- src/window.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/window.rs b/src/window.rs index 865ec93ca5..f7aa6d618f 100644 --- a/src/window.rs +++ b/src/window.rs @@ -317,13 +317,11 @@ impl Window { self.window.set_max_dimensions(dimensions) } - /* /// Sets whether the window is resizable or not. /// /// ## Platform-specific /// /// This only has an effect on Windows, X11, and macOS. - */ #[inline] pub fn set_resizable(&self, resizable: bool) { self.window.set_resizable(resizable) From 098ad70fd0553cec675a5accb908acc305fd9935 Mon Sep 17 00:00:00 2001 From: Danny Fritz Date: Mon, 11 Jun 2018 12:02:07 -0600 Subject: [PATCH 7/9] Windows: set_resizable in fullscreen --- src/platform/windows/window.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/platform/windows/window.rs b/src/platform/windows/window.rs index b7b03d9763..926118c616 100644 --- a/src/platform/windows/window.rs +++ b/src/platform/windows/window.rs @@ -246,6 +246,10 @@ impl Window { if window_state.attributes.resizable == resizable { return; } + if window_state.attributes.fullscreen.is_some() { + window_state.attributes.resizable = resizable; + return; + } let window = self.window.clone(); let mut style = unsafe { winuser::GetWindowLongW(self.window.0, winuser::GWL_STYLE) @@ -504,14 +508,20 @@ impl Window { let rect = saved_window_info.rect.clone(); let window = self.window.clone(); - let (style, ex_style) = (saved_window_info.style, saved_window_info.ex_style); + let (mut style, ex_style) = (saved_window_info.style, saved_window_info.ex_style); let maximized = window_state.attributes.maximized; + let resizable = window_state.attributes.resizable; // On restore, resize to the previous saved rect size. // And because SetWindowPos will resize the window // We call it in the main thread self.events_loop_proxy.execute_in_thread(move |_| { + if resizable { + style |= winuser::WS_SIZEBOX as LONG; + } else { + style &= !winuser::WS_SIZEBOX as LONG; + } winuser::SetWindowLongW(window.0, winuser::GWL_STYLE, style); winuser::SetWindowLongW(window.0, winuser::GWL_EXSTYLE, ex_style); From 13978a85f340330a605e5c48942ac13158fc6787 Mon Sep 17 00:00:00 2001 From: Francesca Frangipane Date: Mon, 11 Jun 2018 17:43:36 -0400 Subject: [PATCH 8/9] Special case Xfwm --- src/platform/linux/x11/window.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/platform/linux/x11/window.rs b/src/platform/linux/x11/window.rs index 675b3bcb2f..affa075f08 100644 --- a/src/platform/linux/x11/window.rs +++ b/src/platform/linux/x11/window.rs @@ -222,7 +222,7 @@ impl UnownedWindow { (*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); } @@ -733,6 +733,12 @@ impl UnownedWindow { } 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; @@ -752,7 +758,7 @@ impl UnownedWindow { }.expect("Failed to call XSetWMNormalHints"); } } - + #[inline] pub fn get_xlib_display(&self) -> *mut c_void { self.xconn.display as _ From 3195c2a1fb05117081823105e8a68a5697d41fea Mon Sep 17 00:00:00 2001 From: Francesca Frangipane Date: Mon, 11 Jun 2018 17:57:17 -0400 Subject: [PATCH 9/9] Added fun provisos to docs --- src/window.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/window.rs b/src/window.rs index f7aa6d618f..814fdeba21 100644 --- a/src/window.rs +++ b/src/window.rs @@ -51,9 +51,14 @@ impl WindowBuilder { /// Sets whether the window is resizable or not /// + /// Note that making the window unresizable doesn't exempt you from handling `Resized`, as that event can still be + /// triggered by DPI scaling, entering fullscreen mode, etc. + /// /// ## Platform-specific /// - /// This only has an effect on Windows, X11, and macOS. + /// This only has an effect on desktop platforms. + /// + /// Due to a bug in XFCE, this has no effect on Xfwm. #[inline] pub fn with_resizable(mut self, resizable: bool) -> WindowBuilder { self.window.resizable = resizable; @@ -316,13 +321,18 @@ impl Window { pub fn set_max_dimensions(&self, dimensions: Option<(u32, u32)>) { self.window.set_max_dimensions(dimensions) } - + /// Sets whether the window is resizable or not. /// + /// Note that making the window unresizable doesn't exempt you from handling `Resized`, as that event can still be + /// triggered by DPI scaling, entering fullscreen mode, etc. + /// /// ## Platform-specific /// - /// This only has an effect on Windows, X11, and macOS. - #[inline] + /// This only has an effect on desktop platforms. + /// + /// Due to a bug in XFCE, this has no effect on Xfwm. + #[inline] pub fn set_resizable(&self, resizable: bool) { self.window.set_resizable(resizable) }