Skip to content

Commit

Permalink
Reduce flashing on window creation (#1272)
Browse files Browse the repository at this point in the history
  • Loading branch information
rhzk committed Oct 28, 2020
1 parent 40604ae commit 9e5f19a
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 42 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ You can find its changes [documented below](#060---2020-06-01).

### Changed

- Windows: Reduced flashing when windows are created on high-dpi displays ([#1272] by [@rhzk])
- Windows: Improved DPI handling. Druid should now redraw correctly when dpi changes. ([#1037] by [@rhzk])
- windows: Window created with OS default size if not set. ([#1037] by [@rhzk])
- `Scale::from_scale` to `Scale::new`, and `Scale` methods `scale_x` / `scale_y` to `x` / `y`. ([#1042] by [@xStrom])
Expand Down Expand Up @@ -502,6 +503,7 @@ Last release without a changelog :(
[#1251]: https://github.com/linebender/druid/pull/1251
[#1252]: https://github.com/linebender/druid/pull/1252
[#1255]: https://github.com/linebender/druid/pull/1255
[#1272]: https://github.com/linebender/druid/pull/1272
[#1276]: https://github.com/linebender/druid/pull/1276
[#1278]: https://github.com/linebender/druid/pull/1278
[#1280]: https://github.com/linebender/druid/pull/1280
Expand Down
80 changes: 44 additions & 36 deletions druid-shell/src/platform/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub(crate) struct WindowBuilder {
show_titlebar: bool,
size: Option<Size>,
min_size: Option<Size>,
position: Point,
position: Option<Point>,
state: window::WindowState,
}

Expand Down Expand Up @@ -582,7 +582,6 @@ impl WndProc for MyWndProc {
} else {
1.0
};

let scale = Scale::new(scale_factor, scale_factor);
self.set_scale(scale);

Expand Down Expand Up @@ -689,25 +688,6 @@ impl WndProc for MyWndProc {
(*rect).bottom - (*rect).top,
SWP_NOZORDER | SWP_FRAMECHANGED | SWP_DRAWFRAME,
);
/*
if let Ok(mut s) = self.state.try_borrow_mut() {
let s = s.as_mut().unwrap();
if s.dxgi_state.is_some() {
let scale = self.scale();
let rt = paint::create_render_target(&self.d2d_factory, hwnd, scale);
s.render_target = rt.ok();
{
let rect_dp = self.area().size_dp().to_rect();
s.handler.rebuild_resources();
s.render(&self.d2d_factory, &self.dwrite_factory, &rect_dp.into());
self.clear_invalid();
}
}
} else {
self.log_dropped_msg(hwnd, msg, wparam, lparam);
}
*/
Some(0)
},
WM_NCCALCSIZE => unsafe {
Expand Down Expand Up @@ -1180,7 +1160,7 @@ impl WindowBuilder {
present_strategy: Default::default(),
size: None,
min_size: None,
position: Point::new(CW_USEDEFAULT as f64, CW_USEDEFAULT as f64),
position: None,
state: window::WindowState::RESTORED,
}
}
Expand Down Expand Up @@ -1215,7 +1195,7 @@ impl WindowBuilder {
}

pub fn set_position(&mut self, position: Point) {
self.position = position;
self.position = Some(position);
}

pub fn set_window_state(&mut self, state: window::WindowState) {
Expand All @@ -1240,7 +1220,12 @@ impl WindowBuilder {
present_strategy: self.present_strategy,
};

let (pos_x, pos_y) = match self.position {
Some(pos) => (pos.x as i32, pos.y as i32),
None => (CW_USEDEFAULT, CW_USEDEFAULT),
};
let scale = Scale::new(1.0, 1.0);

let mut area = ScaledArea::default();
let (width, height) = self
.size
Expand Down Expand Up @@ -1305,13 +1290,19 @@ impl WindowBuilder {
dwExStyle |= WS_EX_NOREDIRECTIONBITMAP;
}

match self.state {
window::WindowState::MAXIMIZED => dwStyle |= WS_MAXIMIZE,
window::WindowState::MINIMIZED => dwStyle |= WS_MINIMIZE,
_ => (),
};

let hwnd = create_window(
dwExStyle,
class_name.as_ptr(),
self.title.to_wide().as_ptr(),
dwStyle,
self.position.x as i32,
self.position.y as i32,
pos_x,
pos_y,
width,
height,
0 as HWND,
Expand All @@ -1322,20 +1313,32 @@ impl WindowBuilder {
if hwnd.is_null() {
return Err(Error::NullHwnd);
}

if let Some(size) = self.size {
if let Ok(scale) = handle.get_scale() {
if SetWindowPos(
hwnd,
HWND_TOPMOST,
0,
0,
(size.width * scale.x()) as i32,
(size.height * scale.y()) as i32,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE,
) == 0
{
warn!(
"failed to resize window: {}",
Error::Hr(HRESULT_FROM_WIN32(GetLastError()))
);
};
}
}

self.app.add_window(hwnd);

if let Some(accels) = accels {
register_accel(hwnd, &accels);
}

if let Some(size) = self.size {
// TODO: because this is deferred, it causes some flashing.
// Investigate a proper fix that gets the window created with
// the correct size.
handle.set_size(size);
}
handle.set_window_state(self.state);

Ok(handle)
}
}
Expand Down Expand Up @@ -1520,7 +1523,12 @@ impl WindowHandle {
if let Some(w) = self.state.upgrade() {
let hwnd = w.hwnd.get();
unsafe {
ShowWindow(hwnd, SW_SHOWNORMAL);
let show = match self.get_window_state() {
window::WindowState::MAXIMIZED => SW_MAXIMIZE,
window::WindowState::MINIMIZED => SW_MINIMIZE,
_ => SW_SHOWNORMAL,
};
ShowWindow(hwnd, show);
UpdateWindow(hwnd);
}
}
Expand Down Expand Up @@ -1673,7 +1681,7 @@ impl WindowHandle {
}

// Sets the window state.
pub fn set_window_state(&self, state: window::WindowState) {
pub fn set_window_state(&mut self, state: window::WindowState) {
DeferredQueue::add(self.state.clone(), DeferredOp::SetWindowSizeState(state));
}

Expand Down
8 changes: 4 additions & 4 deletions druid-shell/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ impl WindowHandle {
/// [`position`] The position in pixels.
///
/// [`position`]: struct.Point.html
pub fn set_position(&self, position: Point) {
self.0.set_position(position)
pub fn set_position(&self, position: impl Into<Point>) {
self.0.set_position(position.into())
}

/// Returns the position in virtual screen coordinates.
Expand All @@ -251,8 +251,8 @@ impl WindowHandle {
///
/// [`WinHandler::size`]: trait.WinHandler.html#method.size
/// [display points]: struct.Scale.html
pub fn set_size(&self, size: Size) {
self.0.set_size(size)
pub fn set_size(&self, size: impl Into<Size>) {
self.0.set_size(size.into())
}

/// Gets the window size.
Expand Down
4 changes: 2 additions & 2 deletions druid/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,8 @@ impl<T: Data> WindowDesc<T> {
/// [`position`] Position in pixels.
///
/// [`position`]: struct.Point.html
pub fn set_position(mut self, position: Point) -> Self {
self.config = self.config.set_position(position);
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 9e5f19a

Please sign in to comment.