Skip to content

Commit

Permalink
Add {get/set}_window_position to enable hot-reloading.
Browse files Browse the repository at this point in the history
  • Loading branch information
mandroll committed May 16, 2024
1 parent 8a15083 commit 0a621f2
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 15 deletions.
11 changes: 11 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -38,6 +39,7 @@ impl NativeDisplayData {
NativeDisplayData {
screen_width,
screen_height,
screen_position: (0, 0),
dpi_scale: 1.,
high_dpi: false,
quit_requested: false,
Expand All @@ -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),
}
Expand Down
61 changes: 46 additions & 15 deletions src/native/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 _;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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")
Expand Down

0 comments on commit 0a621f2

Please sign in to comment.