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

[GTK] use DP scaling for window size and position. #1713

Merged
merged 4 commits into from
Apr 16, 2021
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ You can find its changes [documented below](#070---2021-01-01).
- `register_for_focus()` should from now on be called from `LifeCycle::BuildFocusChain` instead of `LifeCycle::WidgetAdded` ([#1632] by [@xarvic])
- Flex values that are less than 0.0 will default to 0.0 and warn in release. It will panic in debug mode. ([#1691] by [@arthmis])
- Lens implemented for tuples of Lenses of length 2-8, Tuple2 removed ([#1654] by [@Maan2003])
- Window size and positioning code is now in display points ([#1713] by [@jneem])

### Deprecated

Expand Down Expand Up @@ -678,6 +679,7 @@ Last release without a changelog :(
[#1696]: https://github.com/linebender/druid/pull/1696
[#1698]: https://github.com/linebender/druid/pull/1698
[#1702]: https://github.com/linebender/druid/pull/1702
[#1713]: https://github.com/linebender/druid/pull/1713

[Unreleased]: https://github.com/linebender/druid/compare/v0.7.0...master
[0.7.0]: https://github.com/linebender/druid/compare/v0.6.0...v0.7.0
Expand Down
19 changes: 12 additions & 7 deletions druid-shell/src/platform/gtk/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,10 @@ impl WindowBuilder {
if let Some(min_size_dp) = self.min_size {
let min_area = ScaledArea::from_dp(min_size_dp, scale);
let min_size_px = min_area.size_px();
win_state
.drawing_area
.set_size_request(min_size_px.width as i32, min_size_px.height as i32);
win_state.drawing_area.set_size_request(
min_size_px.width.round() as i32,
min_size_px.height.round() as i32,
);
}

win_state.drawing_area.connect_draw(clone!(handle => move |widget, context| {
Expand Down Expand Up @@ -860,14 +861,15 @@ impl WindowHandle {

pub fn set_position(&self, position: Point) {
if let Some(state) = self.state.upgrade() {
state.window.move_(position.x as i32, position.y as i32)
let px = position.to_px(state.scale.get());
state.window.move_(px.x as i32, px.y as i32)
}
}

pub fn get_position(&self) -> Point {
if let Some(state) = self.state.upgrade() {
let (x, y) = state.window.get_position();
Point::new(x as f64, y as f64)
Point::new(x as f64, y as f64).to_dp(state.scale.get())
} else {
Point::new(0.0, 0.0)
}
Expand Down Expand Up @@ -912,14 +914,17 @@ impl WindowHandle {

pub fn set_size(&self, size: Size) {
if let Some(state) = self.state.upgrade() {
state.window.resize(size.width as i32, size.height as i32)
let px = size.to_px(state.scale.get());
state
.window
.resize(px.width.round() as i32, px.height.round() as i32)
}
}

pub fn get_size(&self) -> Size {
if let Some(state) = self.state.upgrade() {
let (x, y) = state.window.get_size();
Size::new(x as f64, y as f64)
Size::new(x as f64, y as f64).to_dp(state.scale.get())
} else {
warn!("Could not get size for GTK window");
Size::new(0., 0.)
Expand Down
30 changes: 16 additions & 14 deletions druid-shell/src/platform/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,14 +534,15 @@ impl MyWndProc {
fn handle_deferred(&self, op: DeferredOp) {
if let Some(hwnd) = self.handle.borrow().get_hwnd() {
match op {
DeferredOp::SetSize(size) => unsafe {
DeferredOp::SetSize(size_dp) => unsafe {
let size_px = size_dp.to_px(self.scale());
if SetWindowPos(
hwnd,
HWND_TOPMOST,
0,
0,
(size.width * self.scale().x()) as i32,
(size.height * self.scale().y()) as i32,
size_px.width.round() as i32,
size_px.height.round() as i32,
SWP_NOMOVE | SWP_NOZORDER,
) == 0
{
Expand All @@ -551,12 +552,13 @@ impl MyWndProc {
);
};
},
DeferredOp::SetPosition(position) => unsafe {
DeferredOp::SetPosition(pos_dp) => unsafe {
let pos_px = pos_dp.to_px(self.scale());
if SetWindowPos(
hwnd,
HWND_TOPMOST,
position.x as i32,
position.y as i32,
pos_px.x.round() as i32,
pos_px.y.round() as i32,
0,
0,
SWP_NOSIZE | SWP_NOZORDER,
Expand Down Expand Up @@ -1194,10 +1196,9 @@ impl WndProc for MyWndProc {
let min_max_info = unsafe { &mut *(lparam as *mut MINMAXINFO) };
self.with_wnd_state(|s| {
if let Some(min_size_dp) = s.min_size {
let min_area = ScaledArea::from_dp(min_size_dp, self.scale());
let min_size_px = min_area.size_px();
min_max_info.ptMinTrackSize.x = min_size_px.width as i32;
min_max_info.ptMinTrackSize.y = min_size_px.height as i32;
let min_size_px = min_size_dp.to_px(self.scale());
min_max_info.ptMinTrackSize.x = min_size_px.width.round() as i32;
min_max_info.ptMinTrackSize.y = min_size_px.height.round() as i32;
}
});
Some(0)
Expand Down Expand Up @@ -1402,15 +1403,16 @@ impl WindowBuilder {
return Err(Error::NullHwnd);
}

if let Some(size) = self.size {
if let Some(size_dp) = self.size {
if let Ok(scale) = handle.get_scale() {
let size_px = size_dp.to_px(scale);
if SetWindowPos(
hwnd,
HWND_TOPMOST,
0,
0,
(size.width * scale.x()) as i32,
(size.height * scale.y()) as i32,
size_px.width.round() as i32,
size_px.height.round() as i32,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE,
) == 0
{
Expand Down Expand Up @@ -1823,7 +1825,7 @@ impl WindowHandle {
(info.rcClient.right as f64, info.rcClient.bottom as f64),
);

return window_frame - content_frame;
return (window_frame - content_frame).to_dp(w.scale.get());
}
}

Expand Down
32 changes: 23 additions & 9 deletions druid-shell/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,38 +216,46 @@ impl WindowHandle {
self.0.show_titlebar(show_titlebar)
}

/// Sets the position of the window in [pixels](crate::Scale), relative to the origin of the
/// Sets the position of the window in [display points](crate::Scale), relative to the origin of the
/// virtual screen.
pub fn set_position(&self, position: impl Into<Point>) {
self.0.set_position(position.into())
}

/// Returns the position of the top left corner of the window in [pixels](crate::Scale), relative to the origin of the
/// virtual screen.
/// Returns the position of the top left corner of the window in
/// [display points], relative to the origin of the virtual screen.
///
/// [display points]: crate::Scale
pub fn get_position(&self) -> Point {
self.0.get_position()
}

/// Returns the insets of the window content from its position and size in [pixels](crate::Scale).
/// Returns the insets of the window content from its position and size in [display points].
///
/// This is to account for any window system provided chrome, eg. title bars.
///
/// [display points]: crate::Scale
pub fn content_insets(&self) -> Insets {
self.0.content_insets()
}

/// Set the window's size in [display points](crate::Scale).
/// Set the window's size in [display points].
///
/// The actual window size in pixels will depend on the platform DPI settings.
///
/// This should be considered a request to the platform to set the size of the window. The
/// platform might choose a different size depending on its DPI or other platform-dependent
/// configuration. To know the actual size of the window you should handle the
/// [`WinHandler::size`] method.
///
/// [display points]: crate::Scale
pub fn set_size(&self, size: impl Into<Size>) {
self.0.set_size(size.into())
}

/// Gets the window size, in [pixels](crate::Scale).
/// Gets the window size, in [display points].
///
/// [display points]: crate::Scale
pub fn get_size(&self) -> Size {
self.0.get_size()
}
Expand Down Expand Up @@ -430,24 +438,28 @@ impl WindowBuilder {
self.0.set_handler(handler)
}

/// Set the window's initial drawing area size in [display points](crate::Scale).
/// Set the window's initial drawing area size in [display points].
///
/// The actual window size in pixels will depend on the platform DPI settings.
///
/// This should be considered a request to the platform to set the size of the window. The
/// platform might choose a different size depending on its DPI or other platform-dependent
/// configuration. To know the actual size of the window you should handle the
/// [`WinHandler::size`] method.
///
/// [display points]: crate::Scale
pub fn set_size(&mut self, size: Size) {
self.0.set_size(size)
}

/// Set the window's minimum drawing area size in [display points](crate::Scale).
/// Set the window's minimum drawing area size in [display points].
///
/// The actual minimum window size in pixels will depend on the platform DPI settings.
///
/// This should be considered a request to the platform to set the minimum size of the window.
/// The platform might increase the size a tiny bit due to DPI.
///
/// [display points]: crate::Scale
pub fn set_min_size(&mut self, size: Size) {
self.0.set_min_size(size)
}
Expand All @@ -467,8 +479,10 @@ impl WindowBuilder {
self.0.set_transparent(transparent)
}

/// Sets the initial window position in [pixels](crate::Scale), relative to the origin of the
/// Sets the initial window position in [display points], relative to the origin of the
/// virtual screen.
///
/// [display points]: crate::Scale
pub fn set_position(&mut self, position: Point) {
self.0.set_position(position);
}
Expand Down
7 changes: 4 additions & 3 deletions druid/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,10 +557,11 @@ impl<T: Data> WindowDesc<T> {
self
}

/// Sets the initial window position in virtual screen coordinates.
/// [`position`] Position in pixels.
/// Sets the initial window position in [display points], relative to the origin
/// of the [virtual screen].
///
/// [`position`]: struct.Point.html
/// [display points]: crate::Scale
/// [virtual screen]: crate::Screen
pub fn set_position(mut self, position: impl Into<Point>) -> Self {
self.config = self.config.set_position(position.into());
self
Expand Down