Skip to content

Commit

Permalink
Add a knob to specify a class for window creation.
Browse files Browse the repository at this point in the history
This is useful to allow overriding some behaviours that are not
sent to WindowsDelegate (for example canBecomeKey, etc). Will default to
NSWindow so it will be a noop for existing code.
  • Loading branch information
vseguip authored and Vicent Segui committed Jul 10, 2023
1 parent d417289 commit 8fd451c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/appkit/window/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ extern "C" fn cancel<T: WindowDelegate>(this: &Object, _: Sel, _: id) {

/// Injects an `NSWindowDelegate` subclass, with some callback and pointer ivars for what we
/// need to do.
pub(crate) fn register_window_class_with_delegate<T: WindowDelegate>(instance: &T) -> *const Class {
load_or_register_class("NSWindow", instance.subclass_name(), |decl| unsafe {
pub(crate) fn register_window_class_with_delegate<T: WindowDelegate>(class_name: &'static str, instance: &T) -> *const Class {
load_or_register_class(class_name, instance.subclass_name(), |decl| unsafe {
decl.add_ivar::<usize>(WINDOW_DELEGATE_PTR);

// NSWindowDelegate methods
Expand Down
16 changes: 14 additions & 2 deletions src/appkit/window/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
//! mask). This configuration object acts as a way to orchestrate enabling customization before the
//! window object is created - it's returned in your `WindowDelegate` object.
use objc::class;
use objc::runtime::Class;

use crate::appkit::window::enums::{WindowStyle, WindowToolbarStyle};
use crate::foundation::NSUInteger;
use crate::geometry::Rect;
Expand Down Expand Up @@ -32,7 +35,11 @@ pub struct WindowConfig {
/// for other variants.
///
/// This setting is notably important for Preferences windows.
pub toolbar_style: WindowToolbarStyle
pub toolbar_style: WindowToolbarStyle,

/// The base class to use for Window construction, by default will be
/// NSWindow but you can use any class here that inherits from NSWindow.
pub window_class: &'static Class,
}

impl Default for WindowConfig {
Expand All @@ -41,7 +48,8 @@ impl Default for WindowConfig {
style: 0,
initial_dimensions: Rect::new(100., 100., 1024., 768.),
defer: true,
toolbar_style: WindowToolbarStyle::Automatic
toolbar_style: WindowToolbarStyle::Automatic,
window_class: class!(NSWindow),
};

config.set_styles(&[
Expand Down Expand Up @@ -83,4 +91,8 @@ impl WindowConfig {
pub fn set_toolbar_style(&mut self, style: WindowToolbarStyle) {
self.toolbar_style = style;
}

pub fn set_window_class(&mut self, cls : &'static Class) {
self.window_class = cls;
}
}
8 changes: 4 additions & 4 deletions src/appkit/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ impl Window {
let objc = unsafe {
// This behavior might make sense to keep as default (YES), but I think the majority of
// apps that would use this toolkit wouldn't be tab-oriented...
let _: () = msg_send![class!(NSWindow), setAllowsAutomaticWindowTabbing: NO];
let _: () = msg_send![config.window_class, setAllowsAutomaticWindowTabbing: NO];

let alloc: id = msg_send![class!(NSWindow), alloc];
let alloc: id = msg_send![config.window_class, alloc];

// Other types of backing (Retained/NonRetained) are archaic, dating back to the
// NeXTSTEP era, and are outright deprecated... so we don't allow setting them.
Expand Down Expand Up @@ -131,13 +131,13 @@ where
/// enables easier structure of your codebase, and in a way simulates traditional class based
/// architectures... just without the subclassing.
pub fn with(config: WindowConfig, delegate: T) -> Self {
let class = register_window_class_with_delegate::<T>(&delegate);
let class = register_window_class_with_delegate::<T>(config.window_class.name(), &delegate);
let mut delegate = Box::new(delegate);

let objc = unsafe {
// This behavior might make sense to keep as default (YES), but I think the majority of
// apps that would use this toolkit wouldn't be tab-oriented...
let _: () = msg_send![class!(NSWindow), setAllowsAutomaticWindowTabbing: NO];
let _: () = msg_send![config.window_class, setAllowsAutomaticWindowTabbing: NO];

let alloc: id = msg_send![class, alloc];

Expand Down

0 comments on commit 8fd451c

Please sign in to comment.