Skip to content

Commit

Permalink
Use display points for window size and position. (#1713)
Browse files Browse the repository at this point in the history
Also for content insets.
  • Loading branch information
jneem authored Apr 16, 2021
1 parent ac3e0a6 commit 5958963
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 33 deletions.
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

0 comments on commit 5958963

Please sign in to comment.