Macro panel

Source
macro_rules! panel {
    (
        $class_name:ident {
            $(config: {
                $($method:ident: $value:expr),* $(,)?
            })?
            $(with: {
                $(tracking_area: {
                    options: $tracking_options:expr,
                    auto_resize: $auto_resize:expr $(,)?
                })?
            })?
        }
    ) => { ... };
}
Expand description

Macro to create a custom NSPanel class

This macro generates a custom NSPanel subclass with the specified configuration. The first parameter is the name of your custom panel class.

Implementation Details:

  • The macro generates an internal Raw{ClassName} Objective-C class
  • A public {ClassName} wrapper type that implements Send and Sync
  • All methods are implemented on the wrapper type

Thread Safety: The wrapper type implements Send and Sync to allow passing references through Tauri’s command system. However, all actual panel operations must be performed on the main thread.

§Sections:

  • config: Override NSPanel methods that return boolean values (use snake_case names)
  • with: Optional configurations (tracking_area, etc.)

§Mouse Tracking:

When you enable tracking_area in the with section, mouse event callbacks become available on your event handler. You can set callbacks for:

  • on_mouse_entered() - Called when mouse enters the panel
  • on_mouse_exited() - Called when mouse exits the panel
  • on_mouse_moved() - Called when mouse moves within the panel
  • on_cursor_update() - Called when cursor needs to be updated

§Usage:

use tauri_nspanel::{panel, panel_event};

// Define your custom panel class
panel!(MyCustomPanel {
    // Config overrides - these affect compile-time behavior
    config: {
        can_become_key_window: true,
        can_become_main_window: false,
    },
    // Optional configurations
    with: {
        tracking_area: {
            options: NSTrackingAreaOptions::NSTrackingActiveAlways
                   | NSTrackingAreaOptions::NSTrackingMouseEnteredAndExited
                   | NSTrackingAreaOptions::NSTrackingMouseMoved,
            auto_resize: true,
        }
    }
});

// In your Tauri app:
fn create_panel(window: tauri::WebviewWindow) -> Result<(), Box<dyn std::error::Error>> {
    // Convert existing Tauri window to your custom panel
    let panel = MyCustomPanel::from_window(window)?;

    // Use control methods
    panel.show();
    panel.set_level(5i64); // NSStatusWindowLevel
    panel.set_floating_panel(true);

    // Create and attach an event handler
    let handler = MyPanelEventHandler::new();
    handler.window_did_become_key(|args| {
        println!("Panel became key window");
        None
    });

    // If tracking_area is enabled, you can set mouse event callbacks
    handler.on_mouse_entered(|event| {
        println!("Mouse entered the panel");
    });

    handler.on_mouse_moved(|event| {
        let location = unsafe { event.locationInWindow() };
        println!("Mouse moved to: x={}, y={}", location.x, location.y);
    });

    panel.set_event_handler(Some(handler.as_ref()));

    Ok(())
}

§Available Methods:

  • show(), hide(), to_window()
  • make_key_window(), resign_key_window()
  • set_level(), set_alpha_value(), set_content_size()
  • set_floating_panel(), set_has_shadow(), set_opaque()
  • set_accepts_mouse_moved_events(), set_ignores_mouse_events()
  • And many more…