From ff0ce9d065431c93e1d7e5d88bb8cfb15f7f2f60 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Mon, 10 Jul 2023 04:02:26 +0000 Subject: [PATCH] Rename `Window::set_inner_size` to `Window::request_inner_size` Some systems could resize the window immediately and we'd rather inform the users right away if that was the case, so they could create e.g. EGLSurface without waiting for resize, which is really important for Wayland. Fixes #2868. --- CHANGELOG.md | 4 +-- examples/multithreaded.rs | 16 +++++----- src/platform_impl/android/mod.rs | 4 +-- src/platform_impl/ios/window.rs | 4 +-- src/platform_impl/linux/mod.rs | 4 +-- src/platform_impl/linux/wayland/window/mod.rs | 5 +-- .../linux/x11/event_processor.rs | 9 +++--- src/platform_impl/linux/x11/window.rs | 8 +++-- src/platform_impl/macos/window.rs | 3 +- src/platform_impl/orbital/window.rs | 3 +- src/platform_impl/web/window.rs | 4 ++- src/platform_impl/windows/window.rs | 11 ++++--- src/window.rs | 31 +++++++++++++------ 13 files changed, 65 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50330eb9..7fe9a583 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,8 @@ And please only add new entries to the top of this list, right below the `# Unre # Unreleased -- On X11, fix false positive flagging of key repeats when pressing different keys with no release - between presses. +- **Breaking:** Rename `Window::set_inner_size` to `Window::request_inner_size` and indicate if the size was applied immediately. +- On X11, fix false positive flagging of key repeats when pressing different keys with no release between presses. - Implement `PartialOrd` and `Ord` for `KeyCode` and `NativeKeyCode`. - On Web, implement `WindowEvent::Occluded`. - On Web, fix touch location to be as accurate as mouse position. diff --git a/examples/multithreaded.rs b/examples/multithreaded.rs index d1bff70f..cc427636 100644 --- a/examples/multithreaded.rs +++ b/examples/multithreaded.rs @@ -137,13 +137,15 @@ fn main() { }), "q" => window.request_redraw(), "r" => window.set_resizable(state), - "s" => window.set_inner_size(match state { - true => PhysicalSize::new( - WINDOW_SIZE.width + 100, - WINDOW_SIZE.height + 100, - ), - false => WINDOW_SIZE, - }), + "s" => { + let _ = window.request_inner_size(match state { + true => PhysicalSize::new( + WINDOW_SIZE.width + 100, + WINDOW_SIZE.height + 100, + ), + false => WINDOW_SIZE, + }); + } "w" => { if let Size::Physical(size) = WINDOW_SIZE.into() { window diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index e607f625..cd10d6b8 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -802,8 +802,8 @@ impl Window { self.outer_size() } - pub fn set_inner_size(&self, _size: Size) { - warn!("Cannot set window size on Android"); + pub fn request_inner_size(&self, _size: Size) -> Option> { + Some(self.inner_size()) } pub fn outer_size(&self) -> PhysicalSize { diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 7e0cbdcb..72735645 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -139,8 +139,8 @@ impl Inner { } } - pub fn set_inner_size(&self, _size: Size) { - warn!("not clear what `Window::set_inner_size` means on iOS"); + pub fn request_inner_size(&self, _size: Size) -> Option> { + Some(self.inner_size()) } pub fn set_min_inner_size(&self, _dimensions: Option) { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 5df360e8..24cf135c 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -367,8 +367,8 @@ impl Window { } #[inline] - pub fn set_inner_size(&self, size: Size) { - x11_or_wayland!(match self; Window(w) => w.set_inner_size(size)) + pub fn request_inner_size(&self, size: Size) -> Option> { + x11_or_wayland!(match self; Window(w) => w.request_inner_size(size)) } #[inline] diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 74f6370d..46c1b4b5 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -292,13 +292,14 @@ impl Window { } #[inline] - pub fn set_inner_size(&self, size: Size) { - // TODO should we issue the resize event? I don't think other platforms do so. + pub fn request_inner_size(&self, size: Size) -> Option> { let mut window_state = self.window_state.lock().unwrap(); let scale_factor = window_state.scale_factor(); window_state.resize(size.to_logical::(scale_factor)); self.request_redraw(); + + Some(window_state.inner_size().to_physical(scale_factor)) } /// Set the minimum inner size for the window. diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index d86216b6..053ccc09 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -419,7 +419,7 @@ impl EventProcessor { }); if new_inner_size != old_inner_size { - window.set_inner_size_physical( + window.request_inner_size_physical( new_inner_size.width, new_inner_size.height, ); @@ -443,7 +443,7 @@ impl EventProcessor { // When this finally happens, the event will not be synthetic. shared_state_lock.dpi_adjusted = None; } else { - window.set_inner_size_physical(adjusted_size.0, adjusted_size.1); + window.request_inner_size_physical(adjusted_size.0, adjusted_size.1); } } @@ -1232,8 +1232,9 @@ impl EventProcessor { if new_inner_size != old_inner_size { let (new_width, new_height) = new_inner_size.into(); - window - .set_inner_size_physical(new_width, new_height); + window.request_inner_size_physical( + new_width, new_height, + ); } } } diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index e64d4178..c361c5ea 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -1143,7 +1143,7 @@ impl UnownedWindow { } } - pub(crate) fn set_inner_size_physical(&self, width: u32, height: u32) { + pub(crate) fn request_inner_size_physical(&self, width: u32, height: u32) { unsafe { (self.xconn.xlib.XResizeWindow)( self.xconn.display, @@ -1157,7 +1157,7 @@ impl UnownedWindow { } #[inline] - pub fn set_inner_size(&self, size: Size) { + pub fn request_inner_size(&self, size: Size) -> Option> { let scale_factor = self.scale_factor(); let size = size.to_physical::(scale_factor).into(); if !self.shared_state_lock().is_resizable { @@ -1167,7 +1167,9 @@ impl UnownedWindow { }) .expect("Failed to call `XSetWMNormalHints`"); } - self.set_inner_size_physical(size.0, size.1); + self.request_inner_size_physical(size.0, size.1); + + None } fn update_normal_hints(&self, callback: F) -> Result<(), XError> diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 1df683fc..1413b05f 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -608,9 +608,10 @@ impl WinitWindow { } #[inline] - pub fn set_inner_size(&self, size: Size) { + pub fn request_inner_size(&self, size: Size) -> Option> { let scale_factor = self.scale_factor(); util::set_content_size_sync(self, size.to_logical(scale_factor)); + None } pub fn set_min_inner_size(&self, dimensions: Option) { diff --git a/src/platform_impl/orbital/window.rs b/src/platform_impl/orbital/window.rs index 922c6c47..11ec6c7e 100644 --- a/src/platform_impl/orbital/window.rs +++ b/src/platform_impl/orbital/window.rs @@ -209,11 +209,12 @@ impl Window { } #[inline] - pub fn set_inner_size(&self, size: Size) { + pub fn request_inner_size(&self, size: Size) -> Option> { let (w, h): (u32, u32) = size.to_physical::(self.scale_factor()).into(); self.window_socket .write(format!("S,{w},{h}").as_bytes()) .expect("failed to set size"); + None } #[inline] diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index 0d577b86..da5c0a02 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -148,12 +148,14 @@ impl Window { } #[inline] - pub fn set_inner_size(&self, size: Size) { + pub fn request_inner_size(&self, size: Size) -> Option> { self.inner.dispatch(move |inner| { let size = size.to_logical(inner.scale_factor()); let canvas = inner.canvas.borrow(); backend::set_canvas_size(canvas.window(), canvas.raw(), size); }); + + None } #[inline] diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 23ec2947..fc4543e7 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -210,7 +210,7 @@ impl Window { } #[inline] - pub fn set_inner_size(&self, size: Size) { + pub fn request_inner_size(&self, size: Size) -> Option> { let scale_factor = self.scale_factor(); let physical_size = size.to_physical::(scale_factor); @@ -225,6 +225,7 @@ impl Window { let window_flags = self.window_state_lock().window_flags; window_flags.set_size(self.hwnd(), physical_size); + None } #[inline] @@ -232,7 +233,7 @@ impl Window { self.window_state_lock().min_size = size; // Make windows re-check the window size bounds. let size = self.inner_size(); - self.set_inner_size(size.into()); + self.request_inner_size(size.into()); } #[inline] @@ -240,7 +241,7 @@ impl Window { self.window_state_lock().max_size = size; // Make windows re-check the window size bounds. let size = self.inner_size(); - self.set_inner_size(size.into()); + self.request_inner_size(size.into()); } #[inline] @@ -1051,11 +1052,11 @@ impl<'a, T: 'static> InitData<'a, T> { .min_inner_size .unwrap_or_else(|| PhysicalSize::new(0, 0).into()); let clamped_size = Size::clamp(size, min_size, max_size, win.scale_factor()); - win.set_inner_size(clamped_size); + win.request_inner_size(clamped_size); if attributes.maximized { // Need to set MAXIMIZED after setting `inner_size` as - // `Window::set_inner_size` changes MAXIMIZED to false. + // `Window::request_inner_size` changes MAXIMIZED to false. win.set_maximized(true); } } diff --git a/src/window.rs b/src/window.rs index c61b5d99..9e3f1690 100644 --- a/src/window.rs +++ b/src/window.rs @@ -188,7 +188,7 @@ impl WindowBuilder { /// /// If this is not set, some platform-specific dimensions will be used. /// - /// See [`Window::set_inner_size`] for details. + /// See [`Window::request_inner_size`] for details. #[inline] pub fn with_inner_size>(mut self, size: S) -> Self { self.window.inner_size = Some(size.into()); @@ -652,10 +652,21 @@ impl Window { self.window.inner_size() } - /// Modifies the inner size of the window. + /// Request the new size for the window. + /// + /// On platforms where the size is entirely controlled by the user the + /// applied size will be returned immediately, resize event in such case + /// may not be generated. + /// + /// On platforms where resizing is disallowed by the windowing system, the current + /// inner size is returned immidiatelly, and the user one is ignored. + /// + /// When `None` is returned, it means that the request went to the display system, + /// and the actual size will be delivered later with the [`WindowEvent::Resized`]. /// /// See [`Window::inner_size`] for more information about the values. - /// This automatically un-maximizes the window if it's maximized. + /// + /// The request could automatically un-maximize the window if it's maximized. /// /// ```no_run /// # use winit::dpi::{LogicalSize, PhysicalSize}; @@ -664,19 +675,21 @@ impl Window { /// # let mut event_loop = EventLoop::new(); /// # let window = Window::new(&event_loop).unwrap(); /// // Specify the size in logical dimensions like this: - /// window.set_inner_size(LogicalSize::new(400.0, 200.0)); + /// let _ = window.request_inner_size(LogicalSize::new(400.0, 200.0)); /// /// // Or specify the size in physical dimensions like this: - /// window.set_inner_size(PhysicalSize::new(400, 200)); + /// let _ = window.request_inner_size(PhysicalSize::new(400, 200)); /// ``` /// /// ## Platform-specific /// - /// - **iOS / Android:** Unsupported. /// - **Web:** Sets the size of the canvas element. + /// + /// [`WindowEvent::Resized`]: crate::event::WindowEvent::Resized. #[inline] - pub fn set_inner_size>(&self, size: S) { - self.window.set_inner_size(size.into()) + #[must_use] + pub fn request_inner_size>(&self, size: S) -> Option> { + self.window.request_inner_size(size.into()) } /// Returns the physical size of the entire window. @@ -827,7 +840,7 @@ impl Window { /// /// Note that making the window unresizable doesn't exempt you from handling [`WindowEvent::Resized`], as that /// event can still be triggered by DPI scaling, entering fullscreen mode, etc. Also, the - /// window could still be resized by calling [`Window::set_inner_size`]. + /// window could still be resized by calling [`Window::request_inner_size`]. /// /// ## Platform-specific ///