Repository navigation
feat(macos): add CollectionBehavior option to MacWindow - #4799
Conversation
Add configurable NSWindowCollectionBehavior support for macOS windows, allowing control over window behavior across Spaces and fullscreen. New options include: - MacWindowCollectionBehaviorCanJoinAllSpaces - MacWindowCollectionBehaviorFullScreenAuxiliary - MacWindowCollectionBehaviorMoveToActiveSpace - And more... This enables building Spotlight-like apps that appear on all Spaces or overlay fullscreen applications. Closes #4756 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
WalkthroughAdds macOS NSWindow collectionBehavior support: new MacWindow types and constants, a CollectionBehavior field, CGO bridge and Go setter to apply the bitmask at runtime, updated docs/examples, and minor CI workflow permission edits. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant AppGo as Go app (v3)
participant CGO as C bridge
participant Cocoa as NSWindow (macOS)
Note over AppGo,Cocoa: Window creation & configuration
User->>AppGo: launch app / create window with MacWindow.CollectionBehavior
AppGo->>AppGo: construct NSWindow, set WindowLevel
AppGo->>CGO: windowSetCollectionBehavior(nsWindowPtr, behavior)
CGO->>Cocoa: apply collectionBehavior bitmask to NSWindow (or default FullScreenPrimary when 0)
Cocoa-->>AppGo: applied
AppGo->>User: window visible with configured spaces/fullscreen behavior
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…ain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…ain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
|
Semgrep found 1 Risk: Affected versions of rollup are vulnerable to Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'). Manual Review Advice: A vulnerability from this advisory is reachable if you use Rollup to bundle JavaScript with Fix: Upgrade this library to at least version 3.29.5 at wails/v3/examples/dev/frontend/package-lock.json:569. Reference(s): GHSA-gcx4-mw62-g8wm, CVE-2024-47068 |
Demonstrates creating a Spotlight-like launcher window that: - Appears on all macOS Spaces - Floats above other windows - Uses accessory activation policy (no Dock icon) - Has frameless translucent design 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Update CollectionBehavior to use actual NSWindowCollectionBehavior
bitmask values, allowing multiple behaviors to be combined:
```go
CollectionBehavior: application.MacWindowCollectionBehaviorCanJoinAllSpaces |
application.MacWindowCollectionBehaviorFullScreenAuxiliary,
```
Changes:
- Update Go constants to use actual bitmask values (1<<0, 1<<1, etc.)
- Simplify C function to pass through combined bitmask directly
- Add ParticipatesInCycle, IgnoresCycle, FullScreenDisallowsTiling options
- Update documentation with combined behavior examples
- Update spotlight example to demonstrate combining behaviors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/src/content/docs/features/windows/options.mdx (1)
867-870: Complete example uses outdated API structure.The "Complete Example" section still uses
application.MacOptionswithTitleBarAppearsTransparent, but the documentation above (lines 658-669) shows the newapplication.MacWindowwith nestedTitleBar: application.MacTitleBar{...}structure. This inconsistency will confuse users and may not compile.Update the complete example to use the new API:
// Platform-Specific - Mac: application.MacOptions{ - TitleBarAppearsTransparent: true, - Backdrop: application.MacBackdropTranslucent, - }, + Mac: application.MacWindow{ + TitleBar: application.MacTitleBar{ + AppearsTransparent: true, + }, + Backdrop: application.MacBackdropTranslucent, + },
🧹 Nitpick comments (2)
.github/workflows/automated-releases.yml (1)
26-26: Consider completing the permissions blocks for remaining jobs.While the
check-permissionsjob now has explicit permissions, the other jobs in this workflow (lines 46-92, 93-140, 141-232, 233-326, 327-373) still lack explicitpermissionsblocks and will continue to trigger security warnings. Consider adding appropriate permissions to each job based on their needs:
detect-v2-changesanddetect-v3-changes: needcontents: readrelease-v2andrelease-v3: needcontents: write(for commits/tags/releases)summary: can usepermissions: {}Example for the
detect-v2-changesjob:detect-v2-changes: name: Detect v2 Changes + permissions: + contents: read runs-on: ubuntu-latestv3/examples/spotlight/main.go (1)
29-34: Consider handling the write error for robustness.The
w.Writereturn value is ignored. While acceptable for a simple example, handling the error would be more robust.Assets: application.AssetOptions{ Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) - w.Write([]byte(spotlightHTML)) + _, _ = w.Write([]byte(spotlightHTML)) }), },
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
.github/workflows/automated-releases.yml(1 hunks).github/workflows/test-nightly-releases.yml(1 hunks)docs/src/content/docs/features/windows/basics.mdx(1 hunks)docs/src/content/docs/features/windows/options.mdx(1 hunks)v3/UNRELEASED_CHANGELOG.md(1 hunks)v3/examples/spotlight/README.md(1 hunks)v3/examples/spotlight/main.go(1 hunks)v3/pkg/application/webview_window_darwin.go(4 hunks)v3/pkg/application/webview_window_options.go(2 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-12-13T19:52:13.812Z
Learnt from: leaanthony
Repo: wailsapp/wails PR: 4783
File: v3/pkg/events/events.go:72-100
Timestamp: 2025-12-13T19:52:13.812Z
Learning: In Wails v3, the linux:WindowLoadChanged event was intentionally removed as a breaking change and replaced with four granular WebKit2 load events: linux:WindowLoadStarted, linux:WindowLoadRedirected, linux:WindowLoadCommitted, and linux:WindowLoadFinished. Users should migrate to linux:WindowLoadFinished for detecting when the WebView has finished loading.
Applied to files:
v3/UNRELEASED_CHANGELOG.mdv3/pkg/application/webview_window_darwin.go
📚 Learning: 2024-10-08T22:11:37.054Z
Learnt from: leaanthony
Repo: wailsapp/wails PR: 3763
File: v3/examples/window/main.go:472-475
Timestamp: 2024-10-08T22:11:37.054Z
Learning: In `v3/examples/window/main.go`, `time.Sleep` is used within a goroutine and does not block the UI thread.
Applied to files:
v3/examples/spotlight/main.go
📚 Learning: 2024-09-21T09:56:48.126Z
Learnt from: nixpare
Repo: wailsapp/wails PR: 3763
File: v3/pkg/application/webview_panel_darwin.go:88-89
Timestamp: 2024-09-21T09:56:48.126Z
Learning: Safety checks for `p.nsPanel` are performed in the `SetFloating` method of `WebviewPanel`, following the `WebviewWindow` and `macosWebviewWindow` implementations and code style.
Applied to files:
v3/pkg/application/webview_window_darwin.go
📚 Learning: 2024-12-02T22:13:32.421Z
Learnt from: stavros-k
Repo: wailsapp/wails PR: 3917
File: docs/src/content/docs/api/events_mac.md:9-9
Timestamp: 2024-12-02T22:13:32.421Z
Learning: In `docs/src/content/docs/api/events_mac.md`, the heading levels are intentionally adjusted to improve sizing on the browser, to avoid manually customizing the styling of the doc generator.
Applied to files:
docs/src/content/docs/features/windows/basics.mdxdocs/src/content/docs/features/windows/options.mdx
📚 Learning: 2024-09-20T23:34:29.841Z
Learnt from: nixpare
Repo: wailsapp/wails PR: 3763
File: v3/examples/keybindings/main.go:16-17
Timestamp: 2024-09-20T23:34:29.841Z
Learning: In the codebase, `application.Options.KeyBindings` uses the `application.Window` type, whereas `application.WebviewWindowOptions.KeyBindings` uses `*application.WebviewWindow`. This is intentional and acceptable.
Applied to files:
docs/src/content/docs/features/windows/basics.mdxv3/pkg/application/webview_window_options.godocs/src/content/docs/features/windows/options.mdx
🧬 Code graph analysis (1)
v3/pkg/application/webview_window_darwin.go (1)
v3/pkg/application/webview_window_options.go (1)
MacWindowCollectionBehavior(515-515)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Analyze (go)
- GitHub Check: Cloudflare Pages
- GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (14)
.github/workflows/test-nightly-releases.yml (1)
2-3: Good security practice: workflow-level permissions added.The workflow-level
permissions: contents: readblock correctly addresses the security warnings and follows least-privilege principles. This grants minimal read access to all jobs that need to checkout code..github/workflows/automated-releases.yml (1)
26-26: Appropriate empty permissions for authorization check.The
permissions: {}is correct for thecheck-permissionsjob, which only evaluates thegithub.actorvalue and requires no repository access.v3/pkg/application/webview_window_darwin.go (4)
37-38: LGTM!The comment clearly explains the deferred initialization pattern for collectionBehavior, which aligns with the new configuration-based approach introduced in this PR.
1175-1177: LGTM!The method follows the established pattern used by other setters like
setWindowLevel, with a clean delegation to the C function.
1277-1278: LGTM!The collection behavior is correctly applied after the window level is set, and the default handling in the C layer ensures backwards compatibility when
CollectionBehavioris not explicitly configured.
237-248: Verify that MacWindowCollectionBehavior constants match Apple's NSWindowCollectionBehavior values.The C function implementation correctly handles the default case and properly applies the bitmask cast. Ensure the
MacWindowCollectionBehaviorconstants defined inwebview_window_options.gomatch Apple's values (e.g., NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7).v3/UNRELEASED_CHANGELOG.md (1)
20-20: LGTM!The changelog entry follows the established format, uses present tense, and properly references the linked issue #4756.
v3/examples/spotlight/README.md (1)
1-66: LGTM!Comprehensive documentation that clearly explains the Spotlight example features, how to combine behaviors with bitwise OR, and provides a complete reference table for all
CollectionBehavioroptions. The platform status table correctly indicates this is a macOS-specific feature.v3/examples/spotlight/main.go (2)
47-64: LGTM!Excellent demonstration of the new
CollectionBehaviorfeature. The combination ofCanJoinAllSpaces | FullScreenAuxiliarywithMacWindowLevelFloatingand translucent backdrop creates the intended Spotlight-like behavior. Well-commented configuration.
72-142: LGTM!Clean, minimal HTML that demonstrates a Spotlight-like UI with proper system font usage, dark/light mode support, and autofocus on the search input for immediate usability.
docs/src/content/docs/features/windows/basics.mdx (1)
413-437: LGTM!Documentation correctly reflects the new
MacWindowAPI structure with nestedTitleBarconfiguration. The collection behavior options are well-documented with clear descriptions ofCanJoinAllSpacesandFullScreenAuxiliary.v3/pkg/application/webview_window_options.go (2)
492-494: LGTM!The
CollectionBehaviorfield is well-placed within theMacWindowstruct and includes clear documentation explaining its purpose. This aligns with the PR objective to exposecollectionBehavioras a configurable option.
512-544: Well-structured bitmask constants accurately matching Apple's NSWindowCollectionBehavior.The constants correctly map to Apple's NSWindowCollectionBehavior bitmask values. The gap at bit 10 (between 512 and 2048) is intentional as Apple's API doesn't define a value there. MacWindowCollectionBehaviorDefault being 0 means it won't combine with other flags via bitwise OR, but the Darwin implementation falls back to FullScreenPrimary when the value is 0, maintaining backwards compatibility.
docs/src/content/docs/features/windows/options.mdx (1)
658-729: Comprehensive documentation for the new MacWindow API.The documentation clearly explains:
- The new nested structure with
MacTitleBar- All
MacWindowLevelvaluesCollectionBehaviorbitmask usage with practical examples (spotlight-like window)The spotlight-like window example is particularly helpful as it directly addresses the linked issue's use case.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/src/content/docs/features/windows/options.mdx (1)
877-880: Inconsistency: Complete Example uses outdated API structure.The Complete Example section uses the old
MacOptionswithTitleBarAppearsTransparent, but the documentation above (lines 668-679) shows the newMacWindowstructure with nestedMacTitleBar. This should be updated for consistency.🔎 Suggested fix to align with new API structure
// Platform-Specific - Mac: application.MacOptions{ - TitleBarAppearsTransparent: true, - Backdrop: application.MacBackdropTranslucent, + Mac: application.MacWindow{ + TitleBar: application.MacTitleBar{ + AppearsTransparent: true, + }, + Backdrop: application.MacBackdropTranslucent, },
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
docs/src/content/docs/features/windows/options.mdxv3/UNRELEASED_CHANGELOG.mdv3/pkg/application/webview_window_darwin.go
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2024-09-21T09:56:48.126Z
Learnt from: nixpare
Repo: wailsapp/wails PR: 3763
File: v3/pkg/application/webview_panel_darwin.go:88-89
Timestamp: 2024-09-21T09:56:48.126Z
Learning: Safety checks for `p.nsPanel` are performed in the `SetFloating` method of `WebviewPanel`, following the `WebviewWindow` and `macosWebviewWindow` implementations and code style.
Applied to files:
v3/pkg/application/webview_window_darwin.go
📚 Learning: 2025-12-13T19:52:13.812Z
Learnt from: leaanthony
Repo: wailsapp/wails PR: 4783
File: v3/pkg/events/events.go:72-100
Timestamp: 2025-12-13T19:52:13.812Z
Learning: In Wails v3, the linux:WindowLoadChanged event was intentionally removed as a breaking change and replaced with four granular WebKit2 load events: linux:WindowLoadStarted, linux:WindowLoadRedirected, linux:WindowLoadCommitted, and linux:WindowLoadFinished. Users should migrate to linux:WindowLoadFinished for detecting when the WebView has finished loading.
Applied to files:
v3/pkg/application/webview_window_darwin.go
📚 Learning: 2024-09-20T23:34:29.841Z
Learnt from: nixpare
Repo: wailsapp/wails PR: 3763
File: v3/examples/keybindings/main.go:16-17
Timestamp: 2024-09-20T23:34:29.841Z
Learning: In the codebase, `application.Options.KeyBindings` uses the `application.Window` type, whereas `application.WebviewWindowOptions.KeyBindings` uses `*application.WebviewWindow`. This is intentional and acceptable.
Applied to files:
docs/src/content/docs/features/windows/options.mdx
📚 Learning: 2024-12-02T22:13:32.421Z
Learnt from: stavros-k
Repo: wailsapp/wails PR: 3917
File: docs/src/content/docs/api/events_mac.md:9-9
Timestamp: 2024-12-02T22:13:32.421Z
Learning: In `docs/src/content/docs/api/events_mac.md`, the heading levels are intentionally adjusted to improve sizing on the browser, to avoid manually customizing the styling of the doc generator.
Applied to files:
docs/src/content/docs/features/windows/options.mdx
🧬 Code graph analysis (1)
v3/pkg/application/webview_window_darwin.go (1)
v3/pkg/application/webview_window_options.go (1)
MacWindowCollectionBehavior(515-515)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Run Go Tests v3 (ubuntu-latest, 1.24)
- GitHub Check: Run Go Tests v3 (windows-latest, 1.24)
- GitHub Check: Run Go Tests v3 (macos-latest, 1.24)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: semgrep/ci
- GitHub Check: Analyze (go)
🔇 Additional comments (8)
v3/pkg/application/webview_window_darwin.go (4)
37-38: LGTM!The comment clearly documents that collectionBehavior is now configured later via
windowSetCollectionBehavior()rather than being hard-coded at window creation time, which aligns with the PR objective of making this configurable.
237-248: LGTM! The C implementation correctly handles the bitmask and default fallback.The function properly:
- Defaults to
NSWindowCollectionBehaviorFullScreenPrimarywhen behavior is 0, maintaining backwards compatibility- Passes through combined bitmask values directly when non-zero, enabling the flexible configuration described in PR objectives
1178-1180: LGTM!The Go method correctly delegates to the C function, converting the
MacWindowCollectionBehaviortype toC.int.
1280-1282: LGTM!The collection behavior is set after the window level configuration, which is the appropriate place in the initialization sequence. The comment accurately describes the default behavior for backwards compatibility.
v3/UNRELEASED_CHANGELOG.md (1)
20-20: LGTM!The changelog entry follows the project's format guidelines: present tense, references the issue number, and credits the author.
docs/src/content/docs/features/windows/options.mdx (3)
668-679: LGTM!The updated Mac options structure example clearly demonstrates the new
MacWindowandMacTitleBarnested structure, along with the newWindowLevelandCollectionBehaviorfields.
682-695: LGTM!The TitleBar, Backdrop, and InvisibleTitleBarHeight documentation is clear and well-structured.
697-739: Excellent documentation for the new CollectionBehavior feature.The documentation thoroughly covers:
- All available behavior constants with clear descriptions
- Grouping by category (Space behavior, Window cycling, Fullscreen behavior)
- Bitmask combination usage with the bitwise OR operator
- Practical Spotlight-like window example matching the PR objectives
|
* feat(macos): add CollectionBehavior option to MacWindow (wailsapp#4756) Add configurable NSWindowCollectionBehavior support for macOS windows, allowing control over window behavior across Spaces and fullscreen. New options include: - MacWindowCollectionBehaviorCanJoinAllSpaces - MacWindowCollectionBehaviorFullScreenAuxiliary - MacWindowCollectionBehaviorMoveToActiveSpace - And more... This enables building Spotlight-like apps that appear on all Spaces or overlay fullscreen applications. Closes wailsapp#4756 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Potential fix for code scanning alert no. 140: Workflow does not contain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Potential fix for code scanning alert no. 139: Workflow does not contain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * feat(examples): add spotlight example for CollectionBehavior Demonstrates creating a Spotlight-like launcher window that: - Appears on all macOS Spaces - Floats above other windows - Uses accessory activation policy (no Dock icon) - Has frameless translucent design 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat(macos): support bitwise OR for CollectionBehavior options Update CollectionBehavior to use actual NSWindowCollectionBehavior bitmask values, allowing multiple behaviors to be combined: ```go CollectionBehavior: application.MacWindowCollectionBehaviorCanJoinAllSpaces | application.MacWindowCollectionBehaviorFullScreenAuxiliary, ``` Changes: - Update Go constants to use actual bitmask values (1<<0, 1<<1, etc.) - Simplify C function to pass through combined bitmask directly - Add ParticipatesInCycle, IgnoresCycle, FullScreenDisallowsTiling options - Update documentation with combined behavior examples - Update spotlight example to demonstrate combining behaviors 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>




Summary
NSWindowCollectionBehaviorsupport for macOS windowsNew Options
The
MacWindowstruct now includes aCollectionBehaviorfield with these options:MacWindowCollectionBehaviorDefaultMacWindowCollectionBehaviorCanJoinAllSpacesMacWindowCollectionBehaviorMoveToActiveSpaceMacWindowCollectionBehaviorManagedMacWindowCollectionBehaviorTransientMacWindowCollectionBehaviorStationaryMacWindowCollectionBehaviorFullScreenPrimaryMacWindowCollectionBehaviorFullScreenAuxiliaryMacWindowCollectionBehaviorFullScreenNoneMacWindowCollectionBehaviorFullScreenAllowsTilingUsage Example
Test plan
CanJoinAllSpaces- window should appear on all SpacesFullScreenAuxiliary- window should overlay fullscreen appsCloses #4756
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.