Skip to content

fix(input): resolve alt-tab and shift-tab bugs#1196

Merged
alandtse merged 5 commits into
community-shaders:devfrom
soda3000:dev
Jun 25, 2025
Merged

fix(input): resolve alt-tab and shift-tab bugs#1196
alandtse merged 5 commits into
community-shaders:devfrom
soda3000:dev

Conversation

@soda3000
Copy link
Copy Markdown
Contributor

@soda3000 soda3000 commented Jun 24, 2025

closes 902
closes 862

Addresses an issue where input keys, particularly the tab key, would become
stuck or unresponsive after alt-tabbing out of and back into the application.

This is resolved by:

  • Introducing a focusChanged flag and OnFocusChanged method.
  • Triggering focusChanged on WM_KILLFOCUS and WM_SETFOCUS window messages via a WndProcHandler_Hook.
  • In [OnFocusChanged], resetting the keyboard device state via RE::BSInputDeviceManager::GetSingleton()->GetKeyboard()->Reset().
  • Clearing ImGui's internal input key states using ImGui::GetIO().ClearInputKeys() to ensure proper tab key functionality within the UI.

Additionally:

  • Add OS-level fallback polling via GetAsyncKeyState to force-release stuck Shift and Tab keys
  • Position fallback release logic to after _keyEventQueue.clear() to prevent duplicate Tab events on single taps

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes
    • Resolved an issue where keyboard input could become stuck after using Alt+Tab by improving how input focus changes are handled.
    • Fixed stuck Shift and Tab keys by adding fallback detection and release based on OS key states.
  • New Features
    • The application now more reliably detects and processes focus changes, ensuring smoother user experience when switching between windows.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 24, 2025

Walkthrough

The changes refactor focus handling in the menu system. Focus events in the window procedure now set a flag rather than directly clearing input. The menu class replaces its focus loss handler with a more general focus change handler that resets keyboard input and ImGui keys. Focus changes are processed during the settings drawing phase.

Changes

File(s) Change Summary
src/Hooks.cpp Modified window procedure hook to set a focusChanged flag on WM_KILLFOCUS and WM_SETFOCUS messages instead of clearing input or calling the old handler.
src/Menu.cpp Renamed and updated the focus handler to reset keyboard and ImGui input; invoked this handler in settings drawing if the flag is set; added fallback logic to release stuck Shift and Tab keys using GetAsyncKeyState. Included <Windows.h>.
src/Menu.h Removed OnFocusLost(), added focusChanged atomic boolean member, and introduced OnFocusChanged() method.

Sequence Diagram(s)

sequenceDiagram
    participant OS as Operating System
    participant WndProc as Window Procedure Hook
    participant Menu as Menu
    participant Input as Input Device Manager

    OS->>WndProc: WM_KILLFOCUS or WM_SETFOCUS
    WndProc->>Menu: Set focusChanged = true

    loop On DrawSettings()
        Menu->>Menu: Check focusChanged
        alt focusChanged == true
            Menu->>Menu: OnFocusChanged()
            Menu->>Input: Reset keyboard device
            Menu->>Menu: Clear ImGui input keys
            Menu->>Menu: Set focusChanged = false
        end
    end
Loading

Possibly related issues

Poem

A window lost focus, then found it anew,
The menu now knows just what it must do.
With a flag and a handler, input resets clear,
No more stuck keys when alt-tab is near!
A hop, a skip—code rabbits delight,
For smooth focus changes, everything’s right!
🐇✨


📜 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 a17ab36 and 03e84f2.

📒 Files selected for processing (1)
  • src/Menu.cpp (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (4)
src/Menu.cpp (4)

133-133: LGTM: Named constant addresses previous feedback.

The introduction of KEY_PRESSED_MASK properly replaces the magic number 0x8000 that was flagged in previous reviews, improving code readability and maintainability.


310-313: Correct focus change handling implementation.

The conditional check for focusChanged and subsequent reset is properly placed in the drawing phase, ensuring focus changes are processed during UI rendering as described in the PR objectives.


2741-2751: Effective solution for alt-tab input issues.

The OnFocusChanged() method correctly implements the dual approach:

  1. Resets the keyboard device state via RE::BSInputDeviceManager
  2. Clears ImGui's internal input keys to restore tab functionality

This addresses both the stuck key issue and the tab functionality problem mentioned in the PR objectives.


2724-2732: Well-implemented fallback mechanism for stuck keys.

The OS-level polling using GetAsyncKeyState with the named constant provides a robust fallback to detect and force-release stuck Shift and Tab keys. The placement after _keyEventQueue.clear() prevents duplicate Tab events as intended. The logic correctly handles both left/right Shift keys independently.

✨ Finishing Touches
  • 📝 Generate Docstrings

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

Copy link
Copy Markdown
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: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4bec00c and e99dc41.

📒 Files selected for processing (3)
  • src/Hooks.cpp (1 hunks)
  • src/Menu.cpp (2 hunks)
  • src/Menu.h (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (3)
src/Menu.h (1)

50-53: LGTM! Clean implementation of deferred focus handling.

The flag-based approach properly decouples window message handling from the actual input reset logic. The comment clearly explains the purpose, and the naming is descriptive.

src/Hooks.cpp (1)

617-619: Excellent refactor to lightweight window procedure handling.

Moving from immediate processing to flag-based deferred handling is the right approach. Capturing both WM_KILLFOCUS and WM_SETFOCUS properly addresses the alt-tab scenario where focus is lost and regained.

src/Menu.cpp (1)

308-311: LGTM! Good approach for thread-safe focus handling.

The deferred focus change processing is a good design choice. By checking the flag during the rendering phase rather than handling focus changes immediately in the window message handler, this avoids potential thread safety issues with ImGui and input device operations.

Comment thread src/Menu.cpp
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 24, 2025

✅ A pre-release build is available for this PR:
Download

@soda3000 soda3000 changed the title fix(input): resolve alt-tab stuck key issue fix(input): resolve alt-tab and shift-tab bugs Jun 24, 2025
Automated formatting by clang-format, prettier, and other hooks.
See https://pre-commit.ci for details.
Comment thread src/Menu.cpp Outdated
Comment thread src/Menu.cpp Outdated
@github-actions
Copy link
Copy Markdown

Using provided base ref: 4bec00c
Using base ref: 4bec00c
Base commit date: 2025-06-24T10:55:17+01:00 (Tuesday, June 24, 2025 10:55 AM)
No actionable suggestions for changed features.

Comment thread src/Menu.cpp Outdated
@alandtse
Copy link
Copy Markdown
Collaborator

To merge on CI confirmation.

@alandtse alandtse merged commit 8323dc5 into community-shaders:dev Jun 25, 2025
15 checks passed
alandtse pushed a commit to alandtse/open-shaders that referenced this pull request Jul 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tab + Alt results in Tab key being stuck. UI Bug - Alt+Tab cause loop over all component

3 participants