Skip to content

feature: V3 alpha feature/snapassist support - #4463

Merged
leaanthony merged 5 commits into
v3-alphafrom
v3-alpha-feature/snapassist-support
Aug 2, 2025
Merged

leaanthony merged 5 commits into
v3-alphafrom
v3-alpha-feature/snapassist-support

Conversation

@leaanthony

@leaanthony leaanthony commented Jul 30, 2025 •

Copy link
Copy Markdown
Member

Implements programmatic SnapAssist feature for v3.
Adds a new method for the runtime: ShowSnapAssist which will be stubbed for Mac/Linux to be a NOOP. Updated examples/window to show this in action.

Closes: #2237

Summary by CodeRabbit

  • New Features

    • Added a "Snap Assist" option to the application menu on Windows, enabling quick access to Windows Snap Assist for window layout management.
    • The Snap Assist feature triggers the Windows Snap Assist UI (Win+Z) to show snap layout options.
    • This feature is exclusive to Windows; on macOS and Linux, the option is not available or has no effect.
  • Documentation

    • Updated window management docs to include the new SnapAssist method and Windows 11 snap layout support with usage examples.

@coderabbitai

coderabbitai Bot commented Jul 30, 2025 •

Copy link
Copy Markdown
Contributor

Walkthrough

A Snap Assist feature was introduced for Windows platforms. New methods and interface extensions were added to trigger Snap Assist via simulated key events. The application menu now conditionally displays a "Snap Assist" item on Windows, which invokes the new logic. Platform-specific no-op implementations were added for Linux and macOS.

Changes

Cohort / File(s) Change Summary
Snap Assist Menu Integration
v3/examples/window/main.go
Added "Snap Assist" menu item under "State" submenu, visible only on Windows, triggering SnapAssist on window.
WebviewWindow API & Interface
v3/pkg/application/webview_window.go,
v3/pkg/application/window.go
Extended WebviewWindow and Window interfaces with SnapAssist() method; added implementation and docs.
Platform-specific SnapAssist Implementations
v3/pkg/application/webview_window_windows.go,
v3/pkg/application/webview_window_darwin.go,
v3/pkg/application/webview_window_linux.go
Implemented snapAssist() for Windows (simulates Win+Z), and as no-ops for macOS and Linux.
Windows API Keyboard Event Support
v3/pkg/w32/constants.go,
v3/pkg/w32/user32.go
Added keyboard event flag constants and a Go wrapper for the Windows keybd_event API.
Window Message Processing
v3/pkg/application/messageprocessor_window.go
Added new window method constant and handling for SnapAssist method in message processor.
Runtime Desktop Window API
v3/internal/runtime/desktop/@wailsio/runtime/src/window.ts
Added SnapAssist method constant and implementation in desktop runtime window class.
Documentation
docs/src/content/docs/learn/windows.mdx
Added documentation for SnapAssist method and Windows 11 snap layout support under window methods section.
Changelog
v3/UNRELEASED_CHANGELOG.md
Added entry documenting the Windows SnapAssist feature addition.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AppMenu
    participant WebviewWindow
    participant WindowsAPI

    User->>AppMenu: Select "Snap Assist" (Windows only)
    AppMenu->>WebviewWindow: Call SnapAssist()
    WebviewWindow->>WindowsAPI: Simulate Win+Z key events
    WindowsAPI-->>WebviewWindow: Snap Assist UI triggered
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Assessment against linked issues

Objective Addressed Explanation
Implement Snap Assist trigger for Windows (simulate Snap Assist UI) (#2237) ✅
Limit Snap Assist functionality to Windows platforms only (#2237) ✅
Expose Snap Assist via application menu and API (#2237) ✅
Provide platform-appropriate (no-op) implementations for non-Windows (#2237) ✅

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes detected related to the objectives from the linked issues.

Possibly related PRs

Poem

A window snaps with just a click,
On Windows, Snap Assist does the trick!
Mac and Linux, don’t feel blue,
For you, there’s nothing you must do.
With keys that dance and menus new,
This rabbit’s proud of what you drew! 🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55cc3a3 and d43570e.

📒 Files selected for processing (1)
  • v3/UNRELEASED_CHANGELOG.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • v3/UNRELEASED_CHANGELOG.md
⏰ 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). (7)
  • 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 (javascript-typescript)
  • GitHub Check: Analyze (go)
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch v3-alpha-feature/snapassist-support

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Missing Changelog Update

Hi @leaanthony, please update v3/UNRELEASED_CHANGELOG.md with a description of your changes.

This helps us keep track of changes for the next release.

@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jul 30, 2025
@dosubot dosubot Bot added the Enhancement New feature or request label Jul 30, 2025
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 30, 2025 •

Copy link
Copy Markdown

Deploying wails with  Cloudflare Pages  Cloudflare Pages

Latest commit: d43570e
Status: ✅  Deploy successful!
Preview URL: https://5d46b636.wails.pages.dev
Branch Preview URL: https://v3-alpha-feature-snapassist.wails.pages.dev

View logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
v3/pkg/application/webview_window_linux.go (1)

428-432: Add !cgo build constraint to webview_window_linux.go to avoid duplicate snapAssist methods

When CGO is enabled, both of the following files are built, resulting in two definitions of

func (w *linuxWebviewWindow) snapAssist() {}

and a compilation error:

  • v3/pkg/application/linux_cgo.go  //go:build linux && cgo
  • v3/pkg/application/webview_window_linux.go  //go:build linux

To restore the intended symmetry, update webview_window_linux.go so it only builds when CGO is not enabled.

• In v3/pkg/application/webview_window_linux.go, change the file’s build tag from:

- //go:build linux
+ //go:build linux && !cgo

(Optionally add the matching // +build linux,!cgo line for pre-1.17 tooling.)

♻️ Duplicate comments (1)
v3/pkg/application/linux_cgo.go (1)

1884-1888: Same duplicate stub introduced here

See comment on webview_window_linux.go. Having this second definition under linux && cgo is fine if the pure-Go file is constrained to linux && !cgo; otherwise one of the two must be removed.

🧹 Nitpick comments (1)
v3/pkg/application/webview_window_darwin.go (1)

1440-1442: Consider a short doc-comment to clarify the intentional NO-OP

Every other platform-specific stub explains why the operation is a no-op. A one-liner such as

// snapAssist is not applicable on macOS – Windows-only feature.

will prevent future “todo?” questions during maintenance.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d999ba and 6f34063.

📒 Files selected for processing (7)
  • v3/examples/window/main.go (1 hunks)
  • v3/pkg/application/linux_cgo.go (1 hunks)
  • v3/pkg/application/webview_window.go (2 hunks)
  • v3/pkg/application/webview_window_darwin.go (1 hunks)
  • v3/pkg/application/webview_window_linux.go (1 hunks)
  • v3/pkg/w32/constants.go (1 hunks)
  • v3/pkg/w32/user32.go (2 hunks)
🧰 Additional context used
🧠 Learnings (5)
v3/pkg/application/webview_window_linux.go (1)

Learnt from: nixpare
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.

v3/pkg/application/webview_window_darwin.go (1)

Learnt from: nixpare
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.

v3/pkg/application/linux_cgo.go (1)

Learnt from: nixpare
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.

v3/examples/window/main.go (6)

Learnt from: leaanthony
PR: #4031
File: v3/pkg/application/menu.go:199-202
Timestamp: 2025-01-24T22:41:18.566Z
Learning: In the Wails menu system (v3/pkg/application/menu.go), shared state between menus is intentionally designed and desirable. Methods like Append() and Prepend() should maintain shared references to menu items rather than creating deep copies.

Learnt from: leaanthony
PR: #3763
File: v3/examples/window/main.go:472-475
Timestamp: 2024-09-30T06:13:46.595Z
Learning: In v3/examples/window/main.go, time.Sleep is used within a goroutine and does not block the UI thread.

Learnt from: leaanthony
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.

Learnt from: nixpare
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.

Learnt from: leaanthony
PR: #3763
File: v3/internal/commands/appimage_testfiles/main.go:295-299
Timestamp: 2024-10-08T22:11:37.054Z
Learning: In v3/internal/commands/appimage_testfiles/main.go, time.Sleep is used within a goroutine and does not block the UI thread.

Learnt from: leaanthony
PR: #3763
File: v3/internal/commands/appimage_testfiles/main.go:295-299
Timestamp: 2024-09-30T06:14:32.602Z
Learning: In v3/internal/commands/appimage_testfiles/main.go, time.Sleep is used within a goroutine and does not block the UI thread.

v3/pkg/application/webview_window.go (2)

Learnt from: nixpare
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.

Learnt from: leaanthony
PR: #4031
File: v3/pkg/application/menu.go:199-202
Timestamp: 2025-01-24T22:41:18.566Z
Learning: In the Wails menu system (v3/pkg/application/menu.go), shared state between menus is intentionally designed and desirable. Methods like Append() and Prepend() should maintain shared references to menu items rather than creating deep copies.

🧬 Code Graph Analysis (2)
v3/examples/window/main.go (1)
v3/internal/runtime/runtime_debug_desktop_windows.js (1)
  • function (336-346)
v3/pkg/w32/user32.go (1)
v2/internal/frontend/desktop/windows/winc/w32/user32.go (1)
  • SetWindowsHookEx (1195-1203)
⏰ 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). (7)
  • GitHub Check: Run Go Tests v3 (ubuntu-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (macos-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (windows-latest, 1.24)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep/ci
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
v3/pkg/w32/constants.go (1)

2903-2908: Adds missing KEYEVENTF flags – looks correct

Values align with Win32 winuser.h (0x0001, 0x0002, 0x0004, 0x0008) and fill the gap required for keybd_event usage. No issues spotted.

v3/examples/window/main.go (1)

716-723: LGTM! Clean implementation of the SnapAssist feature demonstration.

The code correctly follows established patterns in the file by using platform-specific checks and the currentWindow helper function. The menu item is appropriately placed under the "State" submenu and is conditionally included only for Windows platforms, which aligns with the feature's availability.

v3/pkg/w32/user32.go (2)

152-152: LGTM! Correctly adds the keybd_event procedure binding.

The addition follows the established pattern used for other Windows API procedure bindings in this file.


1497-1509: LGTM! Well-implemented Windows API wrapper function.

The KeybdEvent function correctly wraps the Windows keybd_event API call with:

  • Comprehensive documentation explaining all parameters
  • Proper type conversion to uintptr for syscall parameters
  • Consistent style with other wrapper functions in the file
  • Appropriate void return type matching the underlying API behavior

This provides the necessary building block for keyboard event synthesis in the SnapAssist feature.

v3/pkg/application/webview_window.go (2)

113-113: LGTM! Correctly extends the interface for platform-specific implementations.

The addition of snapAssist() to the webviewWindowImpl interface ensures all platform-specific implementations must provide this method, maintaining architectural consistency.


1433-1440: LGTM! Well-implemented public API method.

The SnapAssist() method correctly follows established patterns in the codebase:

  • Includes comprehensive documentation explaining cross-platform behavior
  • Uses proper safety checks for implementation existence and window state
  • Employs InvokeSync for thread-safe execution, consistent with other window methods
  • Method naming and signature align with codebase conventions

This provides a clean public API for the SnapAssist feature while delegating platform-specific implementation details appropriately.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Missing Changelog Update

Hi @leaanthony, please update v3/UNRELEASED_CHANGELOG.md with a description of your changes.

This helps us keep track of changes for the next release.

@github-actions github-actions Bot added Documentation Improvements or additions to documentation runtime labels Jul 30, 2025
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Jul 30, 2025
@leaanthony
leaanthony enabled auto-merge (squash) July 30, 2025 10:03
@leaanthony
leaanthony disabled auto-merge July 30, 2025 10:03
@leaanthony
leaanthony enabled auto-merge (squash) July 30, 2025 10:04
@leaanthony
leaanthony disabled auto-merge August 2, 2025 06:44
@sonarqubecloud

sonarqubecloud Bot commented Aug 2, 2025

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
4.3% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@leaanthony
leaanthony enabled auto-merge (squash) August 2, 2025 06:54
@leaanthony
leaanthony disabled auto-merge August 2, 2025 06:59
@leaanthony
leaanthony merged commit 55277fd into v3-alpha Aug 2, 2025
@leaanthony
leaanthony deleted the v3-alpha-feature/snapassist-support branch August 2, 2025 06:59
@coderabbitai coderabbitai Bot mentioned this pull request Mar 20, 2026
4 of 5 tasks
Grantmartin2002 pushed a commit to Grantmartin2002/wails that referenced this pull request Apr 29, 2026
* initial implementation

* Push missed files

* linux fix

* Update changelog, runtime and docs.
@taliesin-ai taliesin-ai added v3 and removed v3-alpha labels Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation Improvements or additions to documentation Enhancement New feature or request Linux MacOS runtime size:L This PR changes 100-499 lines, ignoring generated files. v3 Windows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants