Skip to content
Open
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
8 changes: 7 additions & 1 deletion examples/plugin_clack/src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,13 @@ impl PluginGuiImpl for ExamplePluginMainThread<'_> {
let Some(gui) = self.borrow_window() else {
return Err(PluginError::Message("set_scale called without a GUI active"));
};
gui.suggest_fallback_scale_factor(scale)?;
// An error tells the host the scale was ignored (clap_plugin_gui::set_scale returns
// false), so it takes the size from get_size rather than assume its own scale.
if !gui.suggest_fallback_scale_factor(scale)? {
return Err(PluginError::Message(
"set_scale ignored: the platform provides its own scale factor",
));
}

Ok(())
}
Expand Down
8 changes: 7 additions & 1 deletion examples/plugin_clack_femtovg/src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ impl PluginGuiImpl for ExamplePluginMainThread<'_> {
let Some(gui) = self.borrow_window() else {
return Err(PluginError::Message("set_scale called without a GUI active"));
};
gui.suggest_fallback_scale_factor(scale)?;
// An error tells the host the scale was ignored (clap_plugin_gui::set_scale returns
// false), so it takes the size from get_size rather than assume its own scale.
if !gui.suggest_fallback_scale_factor(scale)? {
return Err(PluginError::Message(
"set_scale ignored: the platform provides its own scale factor",
));
}

Ok(())
}
Expand Down
9 changes: 7 additions & 2 deletions host/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,19 @@ pub trait HostedWindow {
/// If the given fallback scale factor is actually useful and different from the current one
/// (1.0 by default), this will resize and redraw the window accordingly.
///
/// Returns `true` if the given scale factor is now the one the window uses, and `false` if it
/// was ignored because the platform provides its own. Plugins can pass this on to the host:
/// CLAP's `clap_plugin_gui::set_scale` returns `false` when the call was ignored, which tells
/// the host to take the size from `get_size` rather than assume its own scale.
///
/// # Platform compatibility notes.
///
/// On Win32, this value is used if running on early versions of Windows 10 (or earlier).
///
/// On X11, this value is used if no `Xft.dpi`setting is set.
///
/// On macOS, this function is always a no-op.
fn suggest_fallback_scale_factor(&self, scale_factor: f64) -> Result<(), Box<dyn Error>>;
/// On macOS, this function is always a no-op, and always returns `false`.
fn suggest_fallback_scale_factor(&self, scale_factor: f64) -> Result<bool, Box<dyn Error>>;

/// Closes and destroys the window.
///
Expand Down
4 changes: 2 additions & 2 deletions src/platform/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ impl WindowHandle {
Ok(())
}

pub fn suggest_scale_factor(&self, _scale_factor: f64) -> Result<()> {
pub fn suggest_scale_factor(&self, _scale_factor: f64) -> Result<bool> {
// This does not do anything on macOS: all coordinates are already logical
Ok(())
Ok(false)
}

pub fn set_parent(&self, new_parent: ParentWindowHandle) -> Result<()> {
Expand Down
12 changes: 7 additions & 5 deletions src/platform/win/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ impl WindowHandle {
#[inline(always)]
pub fn host_timer_callback(&self, _: crate::host::TimerId) {}

pub fn suggest_scale_factor(&self, new_host_scale_factor: f64) -> Result<()> {
/// Returns whether the suggested scale factor is now the one in use (`false` when the OS
/// provides per-monitor scaling itself).
pub fn suggest_scale_factor(&self, new_host_scale_factor: f64) -> Result<bool> {
let new_dpi = Dpi::from_scale_factor(new_host_scale_factor)
.ok_or(PlatformError::InvalidScaleFactor)?;

Expand All @@ -101,12 +103,12 @@ impl WindowHandle {
let dpi_scaling_strategy = self.state.dpi_scaling_strategy.get();

if !dpi_scaling_strategy.should_use_host_suggested_scale_factor {
return Ok(());
return Ok(false);
}

self.state.current_dpi.set(new_dpi);

let Some(hwnd) = self.hwnd.get() else { return Ok(()) };
let Some(hwnd) = self.hwnd.get() else { return Ok(true) };

let current_size = self.state.current_size.get();
let new_size = self
Expand All @@ -118,7 +120,7 @@ impl WindowHandle {

// This call doesn't meaningfully change the scaling factor, ignore the result
if current_size == new_size {
return Ok(());
return Ok(true);
}

let _guard = self.state.originate_host_resize();
Expand All @@ -127,7 +129,7 @@ impl WindowHandle {
hwnd.resize_and_activate(new_size, new_dpi, &dpi_ctx)?;

if self.state.current_size.get() == new_size {
Ok(())
Ok(true)
} else {
Err(PlatformError::UnexpectedResizeResult {
new_actual_size: self.state.current_size.get(),
Expand Down
2 changes: 1 addition & 1 deletion src/platform/x11/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ impl EventLoop {
self.sizing_state.handle_host_resize(new_size, &self.handler, &self.shared)
}

pub fn suggest_scale_factor(&self, scale: f64) -> PlatformResult<()> {
pub fn suggest_scale_factor(&self, scale: f64) -> PlatformResult<bool> {
self.sizing_state.handle_host_suggest_scale_factor(scale, &self.handler, &self.shared)
}

Expand Down
9 changes: 6 additions & 3 deletions src/platform/x11/sizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,23 @@ impl SizingState {
shared.sizing_state.resize_from_host(new_size, handler, shared)
}

/// Returns whether the suggested scale factor is now the one in use (`false` if the system
/// provides its own, which takes precedence).
pub fn handle_host_suggest_scale_factor(
&self, scale: f64, handler: &Handler, shared: &WindowShared,
) -> Result<(), PlatformError> {
) -> Result<bool, PlatformError> {
shared.sizing_state.host_suggested_scale_factor.set(Some(scale));

// If the scaling factor is already provided by the system, do nothing
if shared.sizing_state.system_scale_factor.get().is_some() {
return Ok(());
return Ok(false);
};

let current_logical_size = shared.sizing_state.size().to_logical::<f64>(1.0);
let new_physical_size = current_logical_size.to_physical(scale);

shared.sizing_state.resize_from_host(new_physical_size, handler, shared)
shared.sizing_state.resize_from_host(new_physical_size, handler, shared)?;
Ok(true)
}
}

Expand Down
13 changes: 8 additions & 5 deletions src/platform/x11/window_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ impl WindowHandle {
self.handle_evloop(|e| e.resize(new_size))
}

pub fn suggest_scale_factor(&self, scale: f64) -> PlatformResult<()> {
/// Returns whether the suggested scale factor is now the one in use.
pub fn suggest_scale_factor(&self, scale: f64) -> PlatformResult<bool> {
self.handle_evloop(|e| e.suggest_scale_factor(scale))
}

Expand Down Expand Up @@ -87,10 +88,12 @@ impl WindowHandle {
}

impl WindowHandle {
fn handle_evloop(
&self, handler: impl FnOnce(&EventLoop) -> PlatformResult<()>,
) -> PlatformResult<()> {
let Some(event_loop) = self.ev_loop.get() else { return Ok(()) };
/// Runs `handler` on the event loop. Once the window is closed this does nothing, and returns
/// the default value (`()`, or `false`: a closed window has used nothing it was given).
fn handle_evloop<T: Default>(
&self, handler: impl FnOnce(&EventLoop) -> PlatformResult<T>,
) -> PlatformResult<T> {
let Some(event_loop) = self.ev_loop.get() else { return Ok(T::default()) };
let res = handler(&event_loop);

if self.shared.close_requested.get() {
Expand Down
17 changes: 10 additions & 7 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,21 @@ impl Window {
/// If the given fallback scale factor is actually useful and different from the current one
/// (1.0 by default), this will resize and redraw the window accordingly.
///
/// Returns `true` if the given scale factor is now the one the window uses, and `false` if it
/// was ignored because the platform provides its own. Plugins can pass this on to the host:
/// CLAP's `clap_plugin_gui::set_scale` returns `false` when the call was ignored, which tells
/// the host to take the size from `get_size` rather than assume its own scale.
///
/// # Platform compatibility notes.
///
/// On Win32, this value is used if running on early versions of Windows 10 (or earlier).
///
/// On X11, this value is used if no `Xft.dpi`setting is set.
///
/// On macOS, this function is always a no-op.
/// On macOS, this function is always a no-op, and always returns `false`.
#[inline]
pub fn suggest_fallback_scale_factor(&self, scale_factor: f64) -> Result<(), Error> {
self.inner.suggest_scale_factor(scale_factor)?;
Ok(())
pub fn suggest_fallback_scale_factor(&self, scale_factor: f64) -> Result<bool, Error> {
Ok(self.inner.suggest_scale_factor(scale_factor)?)
}

/// Closes and destroys the window.
Expand Down Expand Up @@ -261,9 +265,8 @@ impl HostedWindow for Window {
#[inline]
fn suggest_fallback_scale_factor(
&self, scale_factor: f64,
) -> Result<(), Box<dyn std::error::Error>> {
self.suggest_fallback_scale_factor(scale_factor)?;
Ok(())
) -> Result<bool, Box<dyn std::error::Error>> {
Ok(self.suggest_fallback_scale_factor(scale_factor)?)
}

#[inline]
Expand Down
Loading