diff --git a/src/lib.rs b/src/lib.rs index c008105b..13c8fae6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -212,6 +212,17 @@ pub mod window { }); } + pub fn set_window_position(new_x: u32, new_y: u32) { + let mut d = native_display().lock().unwrap(); + d.native_requests.send(native::Request::SetWindowPosition { new_x, new_y }); + } + + /// Get the position of the window. + pub fn get_window_position() -> (u32, u32) { + let mut d = native_display().lock().unwrap(); + d.screen_position + } + pub fn set_fullscreen(fullscreen: bool) { let mut d = native_display().lock().unwrap(); d.native_requests diff --git a/src/native.rs b/src/native.rs index fa28d555..e1a05103 100644 --- a/src/native.rs +++ b/src/native.rs @@ -8,6 +8,7 @@ pub(crate) struct DroppedFiles { pub(crate) struct NativeDisplayData { pub screen_width: i32, pub screen_height: i32, + pub screen_position: (u32, u32), pub dpi_scale: f32, pub high_dpi: bool, pub quit_requested: bool, @@ -38,6 +39,7 @@ impl NativeDisplayData { NativeDisplayData { screen_width, screen_height, + screen_position: (0, 0), dpi_scale: 1., high_dpi: false, quit_requested: false, @@ -61,6 +63,7 @@ pub(crate) enum Request { ShowMouse(bool), SetMouseCursor(crate::CursorIcon), SetWindowSize { new_width: u32, new_height: u32 }, + SetWindowPosition{ new_x: u32, new_y: u32 }, SetFullscreen(bool), ShowKeyboard(bool), } diff --git a/src/native/windows.rs b/src/native/windows.rs index e6086f96..a2b3754f 100644 --- a/src/native/windows.rs +++ b/src/native/windows.rs @@ -130,6 +130,16 @@ impl WindowsDisplay { ) }; } + /// Set the window position in screen coordinates. + fn set_window_position(&mut self, new_x: u32, new_y: u32) { + let mut rect: RECT = unsafe { std::mem::zeroed() }; + if unsafe { GetClientRect(self.wnd, &mut rect as *mut _ as _) } != 0 { + let mut new_rect = rect; + new_rect.right = new_rect.right - new_rect.left + new_x as i32; + new_rect.bottom = new_rect.bottom - new_rect.top + new_y as i32; + unsafe { SetWindowPos(self.wnd, HWND_TOP, new_x as i32, new_y as i32, 0, 0, SWP_NOSIZE) }; + } + } fn set_fullscreen(&mut self, fullscreen: bool) { self.fullscreen = fullscreen as _; @@ -730,28 +740,48 @@ impl WindowsDisplay { } /// updates current window and framebuffer size from the window's client rect, - /// returns true if size has changed + /// and window position from the window's rect. + /// returns true if size or position has changed unsafe fn update_dimensions(&mut self, hwnd: HWND) -> bool { let mut d = crate::native_display().lock().unwrap(); let mut rect: RECT = std::mem::zeroed(); - if GetClientRect(hwnd, &mut rect as *mut _ as _) != 0 { - let window_width = ((rect.right - rect.left) as f32 / self.window_scale) as i32; - let window_height = ((rect.bottom - rect.top) as f32 / self.window_scale) as i32; - - // prevent a framebuffer size of 0 when window is minimized - let fb_width = ((window_width as f32 * self.content_scale) as i32).max(1); - let fb_height = ((window_height as f32 * self.content_scale) as i32).max(1); - if fb_width != d.screen_width || fb_height != d.screen_height { - d.screen_width = fb_width; - d.screen_height = fb_height; - return true; + // Get the outer rectangle of the window in screen coordinates + if GetWindowRect(hwnd, &mut rect as *mut _ as _) != 0 { + // Get the client area rectangle in client coordinates + let mut client_rect: RECT = std::mem::zeroed(); + if GetClientRect(hwnd, &mut client_rect as *mut _ as _) != 0 { + // Calculate window width and height based on the client area + let window_width = ((client_rect.right - client_rect.left) as f32 / self.window_scale) as i32; + let window_height = ((client_rect.bottom - client_rect.top) as f32 / self.window_scale) as i32; + + // Prevent a framebuffer size of 0 when the window is minimized + let fb_width = ((window_width as f32 * self.content_scale) as i32).max(1); + let fb_height = ((window_height as f32 * self.content_scale) as i32).max(1); + + // Check for size changes + if fb_width != d.screen_width || fb_height != d.screen_height { + d.screen_width = fb_width; + d.screen_height = fb_height; + return true; + } + + // Check for position changes + if (rect.left as u32, rect.top as u32) != d.screen_position { + d.screen_position = (rect.left as u32, rect.top as u32); + return true; + } + } else { + // Handle error or default case + d.screen_width = 1; + d.screen_height = 1; } } else { - d.screen_width = 1; - d.screen_height = 1; + // Handle error or default case + d.screen_position = (0, 0); } - return false; + + false } unsafe fn init_dpi(&mut self, high_dpi: bool) { @@ -792,6 +822,7 @@ impl WindowsDisplay { new_width, new_height, } => self.set_window_size(new_width as _, new_height as _), + SetWindowPosition { new_x, new_y } => self.set_window_position(new_x, new_y), SetFullscreen(fullscreen) => self.set_fullscreen(fullscreen), ShowKeyboard(show) => { eprintln!("Not implemented for windows")