Skip to content

Commit 6094a7f

Browse files
authored
Add support for delaying window creation until parent is set (#303)
1 parent 50e26a4 commit 6094a7f

12 files changed

Lines changed: 187 additions & 104 deletions

File tree

examples/open_parented/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ impl ParentWindowHandler {
2626
.with_title("baseview child");
2727

2828
let child_window = Window::create(window_open_options, ChildWindowHandler::new)?;
29+
child_window.show()?;
2930

3031
Ok(Self { surface: surface.into(), damaged: true.into(), child_window })
3132
}

examples/plugin_clack/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ crate-type = ["cdylib"]
88

99
[dependencies]
1010
clack-plugin = "0.1.0"
11-
clack-extensions = { version = "0.1.0", features = ["gui", "clack-plugin", "raw-window-handle_06"] }
11+
clack-extensions = { version = "0.1.0", features = ["gui", "state", "clack-plugin", "raw-window-handle_06"] }
1212
baseview = { path = "../..", features = ["opengl"] }
1313
softbuffer = "0.4.8"
1414
raw-window-handle = "0.6.2"

examples/plugin_clack/src/gui.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ impl PluginGuiImpl for ExamplePluginMainThread<'_> {
3232

3333
fn create(&mut self, _configuration: GuiConfiguration) -> Result<(), PluginError> {
3434
let options = WindowSettings::new()
35+
.parented()
3536
.with_size(PhysicalSize::new(400, 200))
3637
.with_gl_config(GlConfig::default());
3738

examples/plugin_clack/src/lib.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::audio::ExamplePluginAudioProcessor;
22
use crate::gui::ExamplePluginGui;
33
use clack_extensions::gui::{HostGui, PluginGui};
4+
use clack_extensions::state::{PluginState, PluginStateImpl};
45
use clack_plugin::prelude::*;
6+
use clack_plugin::stream::{InputStream, OutputStream};
57

68
mod audio;
79
mod gui;
@@ -18,7 +20,7 @@ impl Plugin for ExamplePlugin {
1820
type MainThread<'a> = ExamplePluginMainThread<'a>;
1921

2022
fn declare_extensions(builder: &mut PluginExtensions<Self>, _shared: Option<&()>) {
21-
builder.register::<PluginGui>();
23+
builder.register::<PluginGui>().register::<PluginState>();
2224
}
2325
}
2426

@@ -59,4 +61,14 @@ impl<'a> PluginMainThread<'a, ()> for ExamplePluginMainThread<'a> {
5961
}
6062
}
6163

64+
impl PluginStateImpl for ExamplePluginMainThread<'_> {
65+
fn save(&mut self, _output: &mut OutputStream) -> Result<(), PluginError> {
66+
Ok(())
67+
}
68+
69+
fn load(&mut self, _input: &mut InputStream) -> Result<(), PluginError> {
70+
Ok(())
71+
}
72+
}
73+
6274
clack_export_entry!(SinglePluginEntry<ExamplePlugin>);

src/handler.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,16 @@ pub trait WindowHandler: 'static {
99
fn on_frame(&self) -> core::result::Result<(), HandlerError>;
1010
/// Informs the handler that the window has been resized.
1111
///
12-
/// If this returns an error, the resize operation will be reverted in order to keep the current
13-
/// size.
12+
/// # Errors
13+
///
14+
/// This operation can fail, in which case an [`HandlerError`] can be returned.
15+
/// This can happen if e.g. an underlying buffer could not be resized, or some kind of driver error.
16+
///
17+
/// In case this `resized` operation fails, `baseview` will assume that it did not meaningfully
18+
/// change anything, and that the window is still able to render and operate at the previous size.
19+
///
20+
/// It will also attempt to resize the underlying platform window and parent window back to the
21+
/// previous size, but this is only a best-effort attempt since those operations can also fail.
1422
fn resized(&self, new_size: WindowSize) -> core::result::Result<(), HandlerError>;
1523
fn on_event(&self, event: Event) -> EventStatus;
1624
}

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ mod handler;
66
pub mod host;
77
mod keyboard;
88
mod mouse_cursor;
9+
mod settings;
910
mod tracing;
1011
mod window;
11-
mod window_open_options;
1212

1313
pub(crate) mod platform;
1414

@@ -22,8 +22,8 @@ pub use error::*;
2222
pub use event::*;
2323
pub use handler::WindowHandler;
2424
pub use mouse_cursor::MouseCursor;
25+
pub use settings::*;
2526
pub use window::*;
26-
pub use window_open_options::*;
2727

2828
#[allow(unused)]
2929
pub(crate) use tracing::*;

src/platform/macos/view.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
use super::keyboard::{make_modifiers, KeyboardState};
44
use super::window::WindowSharedState;
5-
use crate::handler::WindowHandlerBuilder;
65
use crate::host::Host;
76
use crate::platform::*;
87
use crate::tracing::warn;
8+
use crate::window::WindowInitializer;
99
use crate::wrappers::appkit::*;
1010
use crate::MouseEvent::{ButtonPressed, ButtonReleased};
1111
use crate::{
1212
DropData, DropEffect, Event, EventStatus, MouseButton, MouseEvent, ScrollDelta, WindowEvent,
13-
WindowHandler, WindowSettings, WindowSize,
13+
WindowHandler, WindowSize,
1414
};
1515
use dpi::{LogicalPosition, LogicalSize, Size};
1616
use objc2::__framework_prelude::Retained;
@@ -79,8 +79,8 @@ pub(crate) struct BaseviewView {
7979

8080
impl BaseviewView {
8181
pub fn new(
82-
_options: WindowSettings, builder: WindowHandlerBuilder, parenting: ViewParentingType,
83-
host: Host, final_size: LogicalSize<f64>, mtm: MainThreadMarker,
82+
init: WindowInitializer, parenting: ViewParentingType, final_size: LogicalSize<f64>,
83+
mtm: MainThreadMarker,
8484
) -> Result<(Retained<View<Self>>, Rc<WindowSharedState>)> {
8585
let view_rect =
8686
NSRect::new(NSPoint::ZERO, NSSize::new(final_size.width, final_size.height));
@@ -96,7 +96,7 @@ impl BaseviewView {
9696
window_handler: WindowHandlerContainer::new(),
9797
notification_center_observer: None.into(),
9898
parenting: ViewParentingType::Uninitialized.into(),
99-
host,
99+
host: init.host,
100100
lifetime_tied_to_app: None.into(),
101101

102102
#[cfg(feature = "opengl")]
@@ -112,13 +112,13 @@ impl BaseviewView {
112112
view.state.size.set(view.view.size());
113113

114114
#[cfg(feature = "opengl")]
115-
if let Some(gl_config) = _options.gl_config {
115+
if let Some(gl_config) = init.settings.gl_config {
116116
let gl_context = super::gl::GlContext::create(view.view, gl_config, view.mtm)?;
117117
let Ok(()) = view.gl_context.set(gl_context) else { unreachable!() };
118118
}
119119

120120
let context = WindowContext::new(view);
121-
let handler = builder.build(crate::WindowContext::new(context))?;
121+
let handler = init.builder.build(crate::WindowContext::new(context))?;
122122

123123
// Initialize handler
124124
view.window_handler.set(handler);

src/platform/macos/window.rs

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ use objc2_foundation::{NSSize, NSString};
66
use std::cell::Cell;
77
use std::rc::Rc;
88

9-
use crate::handler::WindowHandlerBuilder;
10-
use crate::host::Host;
119
use crate::platform::macos::view::{BaseviewView, ViewParentingType};
1210
use crate::platform::ParentWindowHandle;
1311
use crate::platform::Result;
@@ -31,9 +29,7 @@ impl Drop for WindowHandle {
3129
}
3230

3331
impl WindowHandle {
34-
pub fn create_window(
35-
mut options: WindowSettings, handler: WindowHandlerBuilder, host: Host,
36-
) -> Result<Self> {
32+
pub fn create_window(mut init: WindowInitializer) -> Result<Self> {
3733
autoreleasepool(|_| {
3834
let Some(mtm) = MainThreadMarker::new() else {
3935
panic!("macOS: Windows can only be created on the main thread!")
@@ -42,48 +38,40 @@ impl WindowHandle {
4238
// Creates the global NSApplication instance, if it doesn't exist yet
4339
let _ = NSApplication::sharedApplication(mtm);
4440

45-
if let Some(parent) = options.parent.take() {
46-
return Self::create_window_parented(
47-
options,
48-
handler,
49-
host,
50-
parent.inner.view,
51-
mtm,
52-
);
41+
if let Some(parent) = init.settings.parent.take() {
42+
return Self::create_window_parented(init, parent.inner.view, mtm);
5343
}
5444

55-
Self::create_window_standalone(options, handler, host, mtm)
45+
Self::create_window_standalone(init, mtm)
5646
})
5747
}
5848

5949
pub fn create_window_parented(
60-
builder: WindowSettings, handler: WindowHandlerBuilder, host: Host,
61-
parent_view: Retained<NSView>, mtm: MainThreadMarker,
50+
init: WindowInitializer, parent_view: Retained<NSView>, mtm: MainThreadMarker,
6251
) -> Result<Self> {
6352
let parenting =
6453
ViewParentingType::Parented { parent_view: Weak::from_retained(&parent_view) };
6554

6655
let backing_scale_factor =
6756
parent_view.window().map(|w| w.backingScaleFactor()).unwrap_or(1.0);
68-
let final_size = builder.size.to_logical(backing_scale_factor);
57+
let final_size = init.settings.size.to_logical(backing_scale_factor);
6958

70-
let (ns_view, state) =
71-
BaseviewView::new(builder, handler, parenting, host, final_size, mtm)?;
59+
let (ns_view, state) = BaseviewView::new(init, parenting, final_size, mtm)?;
7260

7361
Ok(Self { mtm, state, _window: None, view: Weak::from_retained(&ns_view) })
7462
}
7563

7664
pub fn create_window_standalone(
77-
builder: WindowSettings, handler: WindowHandlerBuilder, host: Host, mtm: MainThreadMarker,
65+
init: WindowInitializer, mtm: MainThreadMarker,
7866
) -> Result<Self> {
79-
let window = create_window_with_options(&builder, mtm);
67+
let window = create_window_with_options(&init.settings, mtm);
8068

8169
let final_size = window.contentRectForFrameRect(window.frame()).size;
8270
let final_size = LogicalSize::new(final_size.width, final_size.height);
8371

8472
let parenting = ViewParentingType::Windowed { owned_window: Weak::from_retained(&window) };
8573

86-
let (view, state) = BaseviewView::new(builder, handler, parenting, host, final_size, mtm)?;
74+
let (view, state) = BaseviewView::new(init, parenting, final_size, mtm)?;
8775

8876
Ok(Self { mtm, state, view: Weak::from_retained(&view), _window: Some(window) })
8977
}

0 commit comments

Comments
 (0)