Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

creamy-corn
Copy link

@creamy-corn creamy-corn commented Aug 12, 2025

Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

Fixes # (issue)

Type of change

Please select the option that is relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration using wails doctor.

  • Windows
  • macOS
  • Linux

If you checked Linux, please specify the distro and version.

Test Configuration

Please paste the output of wails doctor. If you are unable to run this command, please describe your environment in as much detail as possible.

Checklist:

  • I have updated website/src/pages/changelog.mdx with details of this PR
  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • Bug Fixes
    • Windows desktop: Keyboard focus now moves automatically into the web content after navigation and when the app window becomes active, allowing immediate typing without an extra click.
    • Behavior respects hidden/minimized start states; no changes when the window is minimized or intentionally hidden.
    • Improves accessibility and reduces friction for keyboard-driven workflows.

Fixes the potential of losing focus from actions like ALT-Tab, Clicking the Titlebar, opening and closing dialogs.
Fixes the focus error when application starts up.  When an input has autofocus, the user should instantly be able to type.
Copy link
Contributor

coderabbitai bot commented Aug 12, 2025

Walkthrough

Implements programmatic focus transfer into the WebView2 after navigation completion and upon window activation on Windows. Uses the Chromium controller’s MoveFocus with PROGRAMMATIC reason when available, guarded by nil checks. No public API changes.

Changes

Cohort / File(s) Summary
Post-navigation WebView focus
v2/internal/frontend/desktop/windows/frontend.go
After navigation, if the window is visible and not minimized, retrieves the WebView2 controller and calls MoveFocus(PROGRAMMATIC) to place keyboard focus into the WebView.
Activation-driven WebView focus
v2/internal/frontend/desktop/windows/window.go
On WM_ACTIVATE when the window becomes active, obtains the WebView2 controller and issues MoveFocus(PROGRAMMATIC) to shift focus into WebView; includes guarded call and commented fallback.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant WinWindow as Windows Window
    participant WebView as WebView2 Controller

    User->>WinWindow: Activate window (WM_ACTIVATE)
    alt Window becomes active
        WinWindow->>WebView: MoveFocus(PROGRAMMATIC)
    end
Loading
sequenceDiagram
    participant App
    participant WinWindow as Windows Window
    participant WebView as WebView2 Controller

    App->>WinWindow: Navigation completes
    alt Window visible and not minimized
        WinWindow->>WebView: MoveFocus(PROGRAMMATIC)
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

I hop through windows, bright and keen,
Nudging focus where keys convene.
After a voyage, clickless grace—
The WebView wakes to take its place.
Ears perked high, I tap the stream,
Programmatic hops—type like a dream. 🐇⌨️

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.2.2)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/product/migration-guide for migration instructions

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@dosubot dosubot bot added size:S This PR changes 10-29 lines, ignoring generated files. Bug Something isn't working Windows labels Aug 12, 2025
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
v2/internal/frontend/desktop/windows/frontend.go (1)

945-952: DRY the focus-transfer logic (shared with window.go).

The same MoveFocus sequence is implemented here and in window.go. Centralize it in a small helper to keep behavior consistent and simplify future changes.

Example helper (place in a shared file in this package):

func focusWebView(chromium *edge.Chromium) {
    if chromium == nil {
        return
    }
    if ctrl := chromium.GetController(); ctrl != nil {
        if err := ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC); err != nil {
            _ = ctrl.MoveFocus(0)
            chromium.Focus()
        }
    }
}

Then call:

  • In navigationCompleted: focusWebView(f.chromium)
  • In WM_ACTIVATE: focusWebView(w.chromium)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 857f7b7 and 0fe2f5f.

📒 Files selected for processing (2)
  • v2/internal/frontend/desktop/windows/frontend.go (1 hunks)
  • v2/internal/frontend/desktop/windows/window.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
v2/internal/frontend/desktop/windows/frontend.go (1)
v2/pkg/options/options.go (2)
  • WindowStartState (22-22)
  • Minimised (27-27)
🔇 Additional comments (2)
v2/internal/frontend/desktop/windows/frontend.go (1)

945-952: Request validation across startup states and Windows versions.

Please validate these scenarios to ensure no regressions:

  • StartHidden=true (no focus push)
  • WindowStartState=Minimised (no focus push)
  • Maximised, Fullscreen, Frameless with/without decorations
  • Activation via Alt+Tab and mouse click
  • Older WebView2 runtimes/bindings (fallbacks exercised)
v2/internal/frontend/desktop/windows/window.go (1)

240-247: Confirm no focus churn or loops with OnSetFocus handler.

Since OnSetFocus already calls chromium.Focus(), adding MoveFocus here might duplicate the effect. It should be harmless, but please verify no flicker or focus-loop occurs on activation.

Comment on lines +945 to +952
// Ensure initial keyboard focus goes into the WebView so typing works without a click.
if !f.frontendOptions.StartHidden && f.frontendOptions.WindowStartState != options.Minimised {
if ctrl := f.chromium.GetController(); ctrl != nil {
_ = ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC)
// _ = ctrl.MoveFocus(0)
}
}

Copy link
Contributor

@coderabbitai coderabbitai bot Aug 12, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add fallback and minimal error handling for MoveFocus to increase compatibility.

Some WebView2 versions/bindings may not support the PROGRAMMATIC constant or may return an error. Fall back to 0 (PROGRAMMATIC in the enum) and finally to Chromium.Focus() so initial typing reliably works.

-        if ctrl := f.chromium.GetController(); ctrl != nil {
-            _ = ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC)
-            // _ = ctrl.MoveFocus(0)
-        }
+        if ctrl := f.chromium.GetController(); ctrl != nil {
+            if err := ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC); err != nil {
+                _ = ctrl.MoveFocus(0) // fallback: enum 0 is PROGRAMMATIC
+                f.chromium.Focus()    // last-resort fallback
+            }
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Ensure initial keyboard focus goes into the WebView so typing works without a click.
if !f.frontendOptions.StartHidden && f.frontendOptions.WindowStartState != options.Minimised {
if ctrl := f.chromium.GetController(); ctrl != nil {
_ = ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC)
// _ = ctrl.MoveFocus(0)
}
}
// Ensure initial keyboard focus goes into the WebView so typing works without a click.
if !f.frontendOptions.StartHidden && f.frontendOptions.WindowStartState != options.Minimised {
if ctrl := f.chromium.GetController(); ctrl != nil {
if err := ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC); err != nil {
_ = ctrl.MoveFocus(0) // fallback: enum 0 is PROGRAMMATIC
f.chromium.Focus() // last-resort fallback
}
}
}
🤖 Prompt for AI Agents
In v2/internal/frontend/desktop/windows/frontend.go around lines 945 to 952,
replace the single MoveFocus call with a small fallback sequence: attempt
ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC) and if it
returns an error (or is unsupported) retry with ctrl.MoveFocus(0); if that also
errors, call f.chromium.Focus() as a last resort; capture any returned errors
and log a minimal debug/warn message (or ignore if logger not available) but do
not panic — this increases compatibility across WebView2 versions and bindings.

Copy link
Member

Choose a reason for hiding this comment

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

@creamy-corn - what do you make of the committable suggestion?

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Comment on lines +240 to +247
if w.isActive && w.chromium != nil {
if ctrl := w.chromium.GetController(); ctrl != nil {
// Push keyboard focus into WebView2 when activated
_ = ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC)
// _ = ctrl.MoveFocus(0) // fallback if your bindings lack the constant
}
}

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Harden focus transfer on activation with fallbacks.

Don’t ignore errors from MoveFocus. Add a fallback to enum 0 and finally Chromium.Focus() to maximize compatibility and ensure keyboard input works immediately after activation.

-        if ctrl := w.chromium.GetController(); ctrl != nil {
-            // Push keyboard focus into WebView2 when activated
-            _ = ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC)
-            // _ = ctrl.MoveFocus(0) // fallback if your bindings lack the constant
-        }
+        if ctrl := w.chromium.GetController(); ctrl != nil {
+            // Push keyboard focus into WebView2 when activated
+            if err := ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC); err != nil {
+                _ = ctrl.MoveFocus(0) // fallback: enum 0 is PROGRAMMATIC
+                w.chromium.Focus()    // last-resort fallback
+            }
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if w.isActive && w.chromium != nil {
if ctrl := w.chromium.GetController(); ctrl != nil {
// Push keyboard focus into WebView2 when activated
_ = ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC)
// _ = ctrl.MoveFocus(0) // fallback if your bindings lack the constant
}
}
if w.isActive && w.chromium != nil {
if ctrl := w.chromium.GetController(); ctrl != nil {
// Push keyboard focus into WebView2 when activated
if err := ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC); err != nil {
_ = ctrl.MoveFocus(0) // fallback: enum 0 is PROGRAMMATIC
w.chromium.Focus() // last-resort fallback
}
}
}
🤖 Prompt for AI Agents
In v2/internal/frontend/desktop/windows/window.go around lines 240 to 247,
harden the focus transfer: do not ignore MoveFocus errors — call
ctrl.MoveFocus(edge.COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC) and if it
returns an error, retry with ctrl.MoveFocus(0) as a fallback; if that also
fails, call w.chromium.Focus() (or its safe equivalent) as a final fallback.
Ensure nil checks for w.chromium and ctrl remain and propagate or log any errors
as appropriate while still attempting the subsequent fallback steps.

@leaanthony
Copy link
Member

Thanks 🙏 Please could you add an entry to the changelog located at website/src/pages/changelog.mdx?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working size:S This PR changes 10-29 lines, ignoring generated files. Windows
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants