Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Demo

tauri-nspanel converts a standard Tauri WebviewWindow (NSWindow) to NSPanel that can display over fullscreen window.

A panel displaying over a fullscreen window

To run the demo:

pnpm install

pnpm tauri dev

What you should know

Remove Window Decorations

Configure the window by setting decorations and fullscreen to false:

tauri-config.json

{
    "decorations": false,
    "fullscreen": false
}

Set Activation Policy (Optional)

Set the app's activation policy to auxiliary during startup; this prevents the app icon from appearing in the dock:

main.rs

    .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(())
    })

Set Window Level

Raise the panel to floating window level:

main.rs

  // 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);

Prevent Panel From Activating The Application

It's required to prevent the panel from activating the application to display over a fullscreen window:

main.rs

  #[allow(non_upper_case_globals)]
  const NSWindowStyleMaskNonActivatingPanel: i32 = 1 << 7;
  // Ensures the panel cannot activate the app
  panel.set_style_mask(NSWindowStyleMaskNonActivatingPanel);

Set Window Collection Behaviour

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:

main.rs

  // 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
  );

Make The Panel Resizeable

To make the panel resizable, append the appropriate window style mask to the panel:

main.rs

  #[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);

Add A Drag Region (Optional)

To make the panel dragable, setup a drag region:

index.html

<div data-tauri-drag-region>drag me</div>

Add the permission to allow dragging:

migrated.json

{
  "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.

migrated.json

{
  "permissions": [
    "core:window:deny-internal-toggle-maximize"
  ]
}