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

Reduce flashing on window creation #1272

Merged
merged 1 commit into from
Oct 28, 2020
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 @@ -50,6 +50,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 @@ -492,6 +493,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 @@ -178,8 +178,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 @@ -200,8 +200,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