tauri-nspanel converts a standard Tauri WebviewWindow (NSWindow) to NSPanel that can display over fullscreen window.
To run the demo:
pnpm install
pnpm tauri devConfigure the window by setting decorations and fullscreen to false:
{
"decorations": false,
"fullscreen": false
}Set the app's activation policy to auxiliary during startup; this prevents the app icon from appearing in the dock:
.setup(|app| {
// Set activation poicy to Accessory to prevent the app icon from showing on the dock
app.set_activation_policy(tauri::ActivationPolicy::Accessory);
init(app.app_handle());
Ok(())
})Raise the panel to floating window level:
// Set the window to float level
#[allow(non_upper_case_globals)]
const NSFloatWindowLevel: i32 = 4;
panel.set_level(NSFloatWindowLevel);You can set to other levels as long as it is above the normal window level, for example, set the panel above the main menu window level:
use cocoa::appkit::NSMainMenuWindowLevel;
// this level is recommend for a spotlight panel
panel.set_level(NSMainMenuWindowLevel + 1);It's required to prevent the panel from activating the application to display over a fullscreen window:
#[allow(non_upper_case_globals)]
const NSWindowStyleMaskNonActivatingPanel: i32 = 1 << 7;
// Ensures the panel cannot activate the app
panel.set_style_mask(NSWindowStyleMaskNonActivatingPanel);To display the panel over a fullscreen window, we need to ensure it can join all spaces and be in the same space as the fullscreen window:
// Allows the panel to:
// - display on the same space as the full screen window
// - join all spaces
panel.set_collection_behaviour(
NSWindowCollectionBehavior::NSWindowCollectionBehaviorFullScreenAuxiliary |
NSWindowCollectionBehavior::NSWindowCollectionBehaviorCanJoinAllSpaces
);To make the panel resizable, append the appropriate window style mask to the panel:
#[allow(non_upper_case_globals)]
const NSWindowStyleMaskNonActivatingPanel: i32 = 1 << 7;
#[allow(non_upper_case_globals)]
const NSResizableWindowMask: i32 = 1 << 3;
panel.set_style_mask(NSWindowStyleMaskNonActivatingPanel + NSResizableWindowMask);To make the panel dragable, setup a drag region:
<div data-tauri-drag-region>drag me</div>Add the permission to allow dragging:
{
"permissions": [
"core:window:allow-start-dragging",
]
}Now that the panel can be displayed over fullscreen windows, it cannot become fullscreen or be maximised. Therefore, avoid calling {panel, window}.maximize() or {panel, window}.fullscreen() on this panel, as it will result in a crash.
Due to the use of the drag region, the standard macOS behavior is that double-clicking on the drag region maximizes the window. As mentioned earlier, we can no longer call maximize on this panel, so we need to set permission to disable the maximize toggle.
{
"permissions": [
"core:window:deny-internal-toggle-maximize"
]
}
