Skip to content

Commit a4abf48

Browse files
committed
wip
1 parent bb46eb3 commit a4abf48

6 files changed

Lines changed: 79 additions & 78 deletions

File tree

examples/open_parented/src/main.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ use baseview::{
55
};
66
use std::cell::{Cell, RefCell};
77
use std::num::NonZeroU32;
8-
use std::thread;
9-
use std::time::Duration;
108

119
struct ParentWindowHandler {
1210
surface: RefCell<softbuffer::Surface<WindowContext, WindowContext>>,

src/platform/win/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub type Result<T> = std::result::Result<T, Error>;
66
#[derive(Debug)]
77
pub enum Error {
88
Win32(windows_core::Error),
9+
ResizeFailed,
910
Handler(HandlerError),
1011
}
1112

@@ -26,6 +27,7 @@ impl Display for Error {
2627
match self {
2728
Error::Win32(e) => Display::fmt(e, f),
2829
Error::Handler(e) => Display::fmt(e, f),
30+
Error::ResizeFailed => f.write_str("Window resize request failed."),
2931
}
3032
}
3133
}
@@ -35,6 +37,7 @@ impl std::error::Error for Error {
3537
match self {
3638
Error::Win32(e) => Some(e),
3739
Error::Handler(e) => Some(e.source()),
40+
_ => None,
3841
}
3942
}
4043
}

src/platform/win/window.rs

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ use crate::wrappers::win32::{
3232
WindowStyle,
3333
};
3434
use crate::{
35-
Event, MouseButton, MouseEvent, ScrollDelta, WindowEvent, WindowOpenOptions, WindowScalePolicy,
36-
WindowSize,
35+
Event, MouseButton, MouseEvent, ScrollDelta, WindowEvent, WindowOpenOptions, WindowSize,
3736
};
3837

3938
#[allow(non_snake_case)]
@@ -65,6 +64,26 @@ impl WindowHandle {
6564
pub fn is_open(&self) -> bool {
6665
self.state.is_alive.get()
6766
}
67+
68+
pub fn size(&self) -> WindowSize {
69+
self.state.size()
70+
}
71+
72+
pub fn resize(&self, new_size: Size) -> Result<()> {
73+
let Some(hwnd) = self.hwnd.get() else { return Ok(()) };
74+
let new_size = new_size.to_physical(self.state.scale_factor());
75+
hwnd.resize_and_activate(new_size, self.state.current_dpi.get(), &self.state.user32)?;
76+
77+
if self.state.current_size.get() == new_size {
78+
Ok(())
79+
} else {
80+
Err(Error::ResizeFailed)
81+
}
82+
}
83+
84+
pub fn suggest_scale_factor(&self, _scale_factor: f64) -> Result<()> {
85+
todo!()
86+
}
6887
}
6988

7089
impl Drop for WindowHandle {
@@ -106,22 +125,19 @@ impl WindowImpl for BaseviewWindow {
106125
// Now we can get the actual dpi of the window.
107126
let dpi = window.get_dpi(&self.window_state.user32)?;
108127

109-
if dpi != window_state.current_dpi.get() {
110-
window_state.current_dpi.set(dpi);
111-
112-
// If the user's requested initial size was in system-scaled logical pixels
113-
if let WindowScalePolicy::SystemScaleFactor = self.window_state.scale_policy {
114-
// We cannot create a window in "logical" pixels, and we can't DPI-scale to physical pixels because we
115-
// have no way to know where the window will end up.
116-
// So, at window creation, we assume a DPI=96, and if it ends up wrong, we resize the window
117-
// to the actual logical size the user desired.
118-
let new_size = self.initial_size.to_physical(dpi.scale_factor());
119-
120-
// Preemptively update so a synchronous WM_SIZE from SetWindowPos below
121-
// doesn't also emit Resized.
122-
window_state.current_size.set(new_size);
123-
window.resize_and_activate(new_size, dpi, &window_state.user32)?;
124-
}
128+
if dpi != window_state.shared.current_dpi.get() {
129+
window_state.shared.current_dpi.set(dpi);
130+
131+
// We cannot create a window in "logical" pixels, and we can't DPI-scale to physical pixels because we
132+
// have no way to know where the window will end up.
133+
// So, at window creation, we assume a DPI=96, and if it ends up wrong, we resize the window
134+
// to the actual logical size the user desired.
135+
let new_size = self.initial_size.to_physical(dpi.scale_factor());
136+
137+
// Preemptively update so a synchronous WM_SIZE from SetWindowPos below
138+
// doesn't also emit Resized.
139+
window_state.shared.current_size.set(new_size);
140+
window.resize_and_activate(new_size, dpi, &window_state.user32)?;
125141
}
126142

127143
let drop_target = ComObject::new(DropTarget::new(Rc::downgrade(window_state), window));
@@ -330,24 +346,26 @@ unsafe fn wnd_proc_inner(
330346
let height = ((lparam >> 16) & 0xFFFF) as u16 as u32;
331347

332348
let new_size = PhysicalSize { width, height };
333-
let current_size = window_state.current_size.get();
349+
let current_size = window_state.shared.current_size.get();
334350

335351
// Only send the event if anything changed
336352
if current_size == new_size {
337353
return None;
338354
}
339355

340-
let previous = window_state.current_size.replace(new_size);
341-
let new_size = WindowSize::from_physical(new_size, window_state.scale_factor());
356+
let previous = window_state.shared.current_size.replace(new_size);
357+
let new_size = WindowSize::from_physical(new_size, window_state.shared.scale_factor());
342358

343359
let handler = window_state.handler.get()?;
344360
if let Err(e) = handler.resized(new_size) {
345361
warn!("Window Handler failed to resize: {}", e);
346-
window_state.current_size.set(previous);
362+
window_state.shared.current_size.set(previous);
347363

348364
if let Err(e) = window_state.resize(previous.into()) {
349365
warn!("Failed to resize back to previous window size: {}", e);
350366
}
367+
368+
return Some(-1);
351369
}
352370

353371
None
@@ -363,11 +381,11 @@ unsafe fn wnd_proc_inner(
363381

364382
let new_size = suggested_rect.size();
365383

366-
let changed = window_state.current_size.get() != new_size
367-
|| window_state.current_dpi.get() != dpi;
384+
let changed = window_state.shared.current_size.get() != new_size
385+
|| window_state.shared.current_dpi.get() != dpi;
368386

369-
window_state.current_dpi.replace(dpi);
370-
let previous_size = window_state.current_size.replace(new_size);
387+
window_state.shared.current_dpi.replace(dpi);
388+
let previous_size = window_state.shared.current_size.replace(new_size);
371389

372390
// Windows makes us resize the window manually. This however will not send a WM_SIZE event,
373391
// hence why we are notifying the window handler manually below.
@@ -379,7 +397,7 @@ unsafe fn wnd_proc_inner(
379397

380398
if let Err(e) = handler.resized(new_size) {
381399
warn!("Window Handler failed to resize: {}", e);
382-
window_state.current_size.set(previous_size);
400+
window_state.shared.current_size.set(previous_size);
383401

384402
if let Err(e) = window_state.resize(previous_size.into()) {
385403
warn!("Failed to resize back to previous window size: {}", e);
@@ -422,10 +440,7 @@ impl WindowHandle {
422440
let extended_user_32 = ExtendedUser32::load()?;
423441
let title = HSTRING::from(options.title);
424442

425-
let scaling_factor = match options.scale {
426-
WindowScalePolicy::SystemScaleFactor => 1.0,
427-
WindowScalePolicy::ScaleFactor(scale) => scale,
428-
};
443+
let scaling_factor = 1.0;
429444

430445
let window_size = options.size.to_physical(scaling_factor);
431446

@@ -435,20 +450,21 @@ impl WindowHandle {
435450
WindowStyle::embedded()
436451
};
437452
let dpi_ctx = DpiAwarenessContext::new(&extended_user_32)?;
438-
439-
let rect = dpi_ctx.client_area_to_nc_area(window_size.into(), style, Dpi::default())?;
453+
let shared_state = WindowSharedState::new(window_size, extended_user_32.clone());
440454

441455
let initializer = {
442456
let extended_user_32 = extended_user_32.clone();
457+
let shared_state = shared_state.clone();
443458

444459
move |hwnd: HWnd| {
445460
let window_state =
446-
Rc::new(WindowState::new(hwnd, window_size, options.scale, extended_user_32));
461+
Rc::new(WindowState::new(hwnd, extended_user_32, shared_state.clone()));
447462

448463
BaseviewWindow {
449464
window_state,
450465
initial_size: options.size,
451466
handler_builder: Cell::new(Some(build)),
467+
shared_state,
452468

453469
_drop_target: None.into(),
454470
_keyboard_hook: None.into(),
@@ -460,6 +476,7 @@ impl WindowHandle {
460476
};
461477

462478
let parent = options.parent.map(|p| p.handle);
479+
let rect = dpi_ctx.client_area_to_nc_area(window_size.into(), style, Dpi::default())?;
463480

464481
let window = create_window(&title, style, rect.size(), parent, &dpi_ctx, initializer)?;
465482

@@ -472,7 +489,7 @@ impl WindowHandle {
472489

473490
window.show_and_activate();
474491

475-
Ok(WindowHandle { hwnd: Some(window).into(), is_open: Rc::clone(&is_open) })
492+
Ok(WindowHandle { hwnd: Some(window).into(), state: shared_state })
476493
}
477494
}
478495

src/platform/win/window_state.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::wrappers::win32::cursor::SystemCursor;
55
use crate::wrappers::win32::h_instance::HInstance;
66
use crate::wrappers::win32::window::HWnd;
77
use crate::wrappers::win32::{Dpi, ExtendedUser32};
8-
use crate::{Event, EventStatus, MouseCursor, WindowHandler, WindowScalePolicy, WindowSize};
8+
use crate::{Event, EventStatus, MouseCursor, WindowHandler, WindowSize};
99
use dpi::{PhysicalSize, Size};
1010
use raw_window_handle::{DisplayHandle, Win32WindowHandle};
1111
use std::cell::{Cell, OnceCell, Ref, RefCell};
@@ -23,28 +23,25 @@ pub(crate) struct WindowState {
2323
pub cursor_icon: Cell<MouseCursor>,
2424
// Initialized late so the `Window` can hold a reference to this `WindowState`
2525
pub handler: OnceCell<Box<dyn WindowHandler>>,
26-
pub scale_policy: WindowScalePolicy,
2726

2827
pub user32: ExtendedUser32,
28+
pub shared: Rc<WindowSharedState>,
2929

3030
#[cfg(feature = "opengl")]
3131
pub gl_context: OnceCell<super::gl::GlContext>,
3232
}
3333

3434
impl WindowState {
35-
pub fn new(
36-
hwnd: HWnd, current_size: PhysicalSize<u32>, scale_policy: WindowScalePolicy,
37-
user32: ExtendedUser32,
38-
) -> Self {
35+
pub fn new(hwnd: HWnd, user32: ExtendedUser32, shared: Rc<WindowSharedState>) -> Self {
3936
Self {
4037
hwnd,
4138
keyboard_state: RefCell::new(KeyboardState::new()),
4239
mouse_button_counter: Cell::new(0),
4340
mouse_was_outside_window: true.into(),
4441
cursor_icon: Cell::new(MouseCursor::Default),
4542
handler: OnceCell::new(),
46-
scale_policy,
4743
user32,
44+
shared,
4845

4946
#[cfg(feature = "opengl")]
5047
gl_context: OnceCell::new(),
@@ -68,15 +65,14 @@ impl WindowState {
6865
handler.on_event(event)
6966
}
7067

68+
/// Returns the current size of this window.
7169
pub fn size(&self) -> WindowSize {
72-
WindowSize::from_physical(self.current_size.get(), self.scale_factor())
70+
self.shared.size()
7371
}
7472

73+
/// Returns the current scale factor of this window.
7574
pub fn scale_factor(&self) -> f64 {
76-
match self.scale_policy {
77-
WindowScalePolicy::ScaleFactor(scale) => scale,
78-
WindowScalePolicy::SystemScaleFactor => self.current_dpi.get().scale_factor(),
79-
}
75+
self.shared.scale_factor()
8076
}
8177

8278
pub(crate) fn keyboard_state(&self) -> Ref<'_, KeyboardState> {
@@ -106,7 +102,7 @@ impl WindowState {
106102
pub fn resize(&self, size: Size) -> Result<(), super::Error> {
107103
// `self.window_info` will be modified in response to the `WM_SIZE` event that
108104
// follows the `SetWindowPos()` call
109-
let dpi = self.current_dpi.get();
105+
let dpi = self.shared.current_dpi.get();
110106
let new_size = size.to_physical(dpi.scale_factor());
111107

112108
self.hwnd.resize_and_activate(new_size, dpi, &self.user32)?;
@@ -149,15 +145,26 @@ pub struct WindowSharedState {
149145
pub is_alive: Cell<bool>,
150146
pub current_size: Cell<PhysicalSize<u32>>,
151147
pub current_dpi: Cell<Dpi>, // None if in non-system scale policy
148+
149+
pub user32: ExtendedUser32,
152150
}
153151

154152
impl WindowSharedState {
155-
pub fn new(current_size: PhysicalSize<u32>) -> Rc<Self> {
153+
pub fn new(current_size: PhysicalSize<u32>, user32: ExtendedUser32) -> Rc<Self> {
156154
Self {
157155
is_alive: true.into(),
158156
current_dpi: Dpi::default().into(),
159157
current_size: current_size.into(),
158+
user32,
160159
}
161160
.into()
162161
}
162+
163+
pub fn size(&self) -> WindowSize {
164+
WindowSize::from_physical(self.current_size.get(), self.scale_factor())
165+
}
166+
167+
pub fn scale_factor(&self) -> f64 {
168+
self.current_dpi.get().scale_factor()
169+
}
163170
}

src/platform/x11/window_shared.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::platform::x11::visual_info::WindowVisualConfig;
33
use crate::platform::x11::window_thread::WindowThreadShared;
44
use crate::platform::x11::xcb_window::XcbWindow;
55
use crate::platform::*;
6-
use crate::{warn, MouseCursor, WindowHandler, WindowOpenOptions, WindowScalePolicy, WindowSize};
6+
use crate::{warn, MouseCursor, WindowHandler, WindowOpenOptions, WindowSize};
77
use calloop::LoopSignal;
88
use dpi::{PhysicalSize, Size};
99
use raw_window_handle::{DisplayHandle, XlibWindowHandle};
@@ -40,8 +40,7 @@ impl ScalingFactor {
4040

4141
impl From<Option<f64>> for ScalingFactor {
4242
fn from(value: Option<f64>) -> Self {
43-
// FIXME
44-
Self { system: None.into(), suggested: None.into() }
43+
Self { system: value.into(), suggested: None.into() }
4544
}
4645
}
4746

@@ -73,10 +72,7 @@ impl WindowInner {
7372
// Connect to the X server
7473
let xcb_connection = X11Connection::new()?;
7574

76-
let scaling = match options.scale {
77-
WindowScalePolicy::SystemScaleFactor => xcb_connection.get_scaling(),
78-
WindowScalePolicy::ScaleFactor(scale) => Some(scale),
79-
};
75+
let scaling = xcb_connection.get_scaling();
8076

8177
let initial_scale_factor = scaling.unwrap_or(1.0);
8278
shared.set_scaling_factor(initial_scale_factor);

src/window_open_options.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@ use crate::platform::ParentWindowHandle;
44
use dpi::{LogicalSize, Size};
55
use raw_window_handle::HasWindowHandle;
66

7-
/// The dpi scaling policy of the window
8-
#[derive(Default, Debug, Clone, Copy, PartialEq)]
9-
pub enum WindowScalePolicy {
10-
/// Use the system's dpi scale factor
11-
#[default]
12-
SystemScaleFactor,
13-
/// Use the given dpi scale factor (e.g. `1.0` = 96 dpi)
14-
ScaleFactor(f64),
15-
}
16-
177
/// The options for opening a new window
188
#[derive(Debug, Clone, PartialEq)]
199
pub struct WindowOpenOptions {
@@ -22,9 +12,6 @@ pub struct WindowOpenOptions {
2212
/// The size of the window, either in physical or logical coordinates
2313
pub size: Size,
2414

25-
/// The dpi scaling policy
26-
pub scale: WindowScalePolicy,
27-
2815
pub(crate) parent: Option<ParentWindowHandle>,
2916

3017
/// If provided, then an OpenGL context will be created for this window. You'll be able to
@@ -53,12 +40,6 @@ impl WindowOpenOptions {
5340
self
5441
}
5542

56-
#[inline]
57-
pub fn with_scale_policy(mut self, scale: WindowScalePolicy) -> Self {
58-
self.scale = scale;
59-
self
60-
}
61-
6243
#[inline]
6344
pub fn with_parent(mut self, parent: &impl HasWindowHandle) -> Self {
6445
let parent = match ParentWindowHandle::extract(parent) {
@@ -85,7 +66,6 @@ impl Default for WindowOpenOptions {
8566
Self {
8667
title: String::from("baseview window"),
8768
size: LogicalSize { width: 500.0, height: 400.0 }.into(),
88-
scale: WindowScalePolicy::default(),
8969
parent: None,
9070
#[cfg(feature = "opengl")]
9171
gl_config: None,

0 commit comments

Comments
 (0)