Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add {get/set}_window_position for Windows platform. #434

Merged
merged 2 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,19 @@ 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.
/// TODO: implement for other platforms
#[cfg(target_os = "windows")]
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
3 changes: 3 additions & 0 deletions src/native/linux_x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,9 @@ impl X11Display {
new_width,
new_height,
} => self.set_window_size(self.window, new_width as _, new_height as _),
SetWindowPosition { new_x, new_y } => {
eprintln!("Not implemented for X11")
}
SetFullscreen(fullscreen) => self.set_fullscreen(self.window, fullscreen),
ShowKeyboard(show) => {
eprintln!("Not implemented for X11")
Expand Down
3 changes: 3 additions & 0 deletions src/native/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ impl MacosDisplay {
new_height,
} => self.set_window_size(new_width as _, new_height as _),
SetFullscreen(fullscreen) => self.set_fullscreen(fullscreen),
SetWindowPosition{new_x, new_y} => {
eprintln!("Not implemented for macos");
}
_ => {}
}
}
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
Loading