Skip to content

Fix for Focus related issues at start up - #4501

Closed
creamy-corn wants to merge 4 commits into
wailsapp:masterfrom
creamy-corn:WebView-Focus-Issue
Closed

Fix for Focus related issues at start up#4501
creamy-corn wants to merge 4 commits into
wailsapp:masterfrom
creamy-corn:WebView-Focus-Issue

Conversation

@creamy-corn

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

Copy link
Copy Markdown

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 automatically moves into web content after navigation, enabling immediate typing without an extra click.
    • Focus is also restored when the app window becomes active, improving continuity when switching back to the app.
    • Respects hidden/minimized start states; no focus change when the window is intentionally hidden or minimized, improving accessibility and keyboard 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.
@coderabbitai

coderabbitai Bot commented Aug 12, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds programmatic focus moves into WebView2 in two places on Windows: after navigation completes (if the window is visible and not minimized) and when the window is activated (WM_ACTIVATE). Both call the Chromium controller’s MoveFocus with PROGRAMMATIC when a controller exists. No public API changes.

Changes

Cohort / File(s) Summary
Post-navigation WebView focus
v2/internal/frontend/desktop/windows/frontend.go
After navigation completes, if StartHidden is false and WindowStartState is not minimized (window visible), retrieve the WebView2 controller and call MoveFocus(PROGRAMMATIC) to place keyboard focus into the WebView (nil-checked).
Activation-driven WebView focus
v2/internal/frontend/desktop/windows/window.go
On WM_ACTIVATE when the window becomes active, obtain the WebView2 controller and call MoveFocus(PROGRAMMATIC) to shift focus into the WebView; call is guarded by a nil check and includes a commented fallback for older constants.

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 and controller exists
        WinWindow->>WebView: MoveFocus(PROGRAMMATIC)
    end
Loading
sequenceDiagram
    participant App
    participant WinWindow as Windows Window
    participant WebView as WebView2 Controller

    App->>WinWindow: Navigation completes
    alt StartHidden == false && WindowStartState != Minimized && controller exists
        WinWindow->>WebView: MoveFocus(PROGRAMMATIC)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to nil-checks around the controller and the precise conditions gating focus calls (StartHidden, WindowStartState, activation).
  • Review the use of the programmatic MoveFocus constant and the commented fallback for compatibility.

Suggested labels

go, size:XS

Suggested reviewers

  • leaanthony

Poem

I hop through windows, soft and spry,
I nudge the focus, keys reply.
No click required, just a gentle nudge,
Into the WebView the cursor trudge.
A rabbit's tap — your typing won't budge. 🐇⌨️

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description uses the template structure but is largely incomplete: the issue number placeholder is unfilled, no implementation details are provided, test configuration is missing, and most checklist items are unchecked despite the claim that code follows style guidelines. Fill in the issue number in 'Fixes #', provide a summary of the fix, include wails doctor output, and check completed checklist items honestly (self-review, comments, warnings verification).
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding focus initialization for WebView after navigation and on window activation to fix focus-related startup issues.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

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

📒 Files selected for processing (1)
  • v2/internal/frontend/desktop/windows/frontend.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-17T23:16:11.570Z
Learnt from: Sammy-T
Repo: wailsapp/wails PR: 4570
File: v2/internal/frontend/desktop/linux/window_webkit6.go:97-108
Timestamp: 2025-10-17T23:16:11.570Z
Learning: For webkit_6/GTK4 builds in v2/internal/frontend/desktop/linux/window_webkit6.go, GTK widget creation should not be wrapped in invokeOnMainThread. The activation mechanism (activateWg + onActivate export) already handles thread safety, and additional wrapping would cause issues.

Applied to files:

  • v2/internal/frontend/desktop/windows/frontend.go
🧬 Code graph analysis (1)
v2/internal/frontend/desktop/windows/frontend.go (1)
v2/pkg/options/options.go (2)
  • WindowStartState (22-22)
  • Minimised (27-27)

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@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
@sonarqubecloud

Copy link
Copy Markdown

@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: 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)
}
}

@coderabbitai coderabbitai Bot Aug 12, 2025

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.

🛠️ 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
Copy Markdown
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
Copy Markdown
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 thread v2/internal/frontend/desktop/windows/window.go
@leaanthony

Copy link
Copy Markdown
Member

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

@leaanthony

Copy link
Copy Markdown
Member

@creamy-corn - Any chance you could review the Rabbit's comments and add an entry to the changelog? Thanks 🙏

@sonarqubecloud

Copy link
Copy Markdown

@leaanthony

Copy link
Copy Markdown
Member

@creamy-corn ping 😄

@sonarqubecloud

sonarqubecloud Bot commented Nov 3, 2025

Copy link
Copy Markdown

@leaanthony

Copy link
Copy Markdown
Member

Thanks for this focused fix. The remaining request was to review the comments and add the changelog entry, but there has been no recent update. I’m closing the PR for now to keep the queue current. Please reopen or reapply the change on the current branch if the issue is still present.

@leaanthony leaanthony closed this Aug 26, 2026
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