Skip to content

Document focus-stealing issue with workaround - #3575

Merged
hluk merged 4 commits into
masterfrom
fix/avoid-focus-stealing
Apr 30, 2026
Merged

Document focus-stealing issue with workaround#3575
hluk merged 4 commits into
masterfrom
fix/avoid-focus-stealing

Conversation

@hluk

@hluk hluk commented Apr 25, 2026

Copy link
Copy Markdown
Owner

When CopyQ shows its main window or tray menu, it steals keyboard focus
from the previously active window. This can cause side effects such as
file renames aborting, combo boxes selecting content, and short-lived
widgets dismissing.

Add a known-issues.rst section documenting the problem and a practical
workaround: use next()/previous() global shortcuts to cycle clipboard
history without opening any window.

Closes: #3540

Assisted-by: Claude (Anthropic)

@codecov

codecov Bot commented Apr 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.46%. Comparing base (5fa35a0) to head (9489be2).
⚠️ Report is 64 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3575      +/-   ##
==========================================
+ Coverage   74.39%   74.46%   +0.06%     
==========================================
  Files         253      253              
  Lines       37817    37817              
  Branches     5107     5109       +2     
==========================================
+ Hits        28135    28159      +24     
+ Misses       9682     9658      -24     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hluk
hluk force-pushed the fix/avoid-focus-stealing branch 3 times, most recently from 6af9bcb to 45595d6 Compare April 26, 2026 06:17
@hluk
hluk requested a review from Copilot April 26, 2026 08:41

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

Pull request overview

Adds a user-facing option to show CopyQ’s main window and tray menu without taking keyboard focus from the currently active application, with platform-specific implementations and a new regression test.

Changes:

  • Adds “Avoid grabbing keyboard focus” preference and corresponding avoid_focus_stealing config option.
  • Introduces platform hooks for non-activating raise and (on X11) a keyboard grab–based intercept for non-activated main window interaction.
  • Adds an automated test covering focus retention when showing the window with the option enabled.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/ui/configtabgeneral.ui Adds the new preference checkbox and tab order entry.
src/gui/configurationmanager.cpp Binds the new config option and hides the checkbox on unsupported platforms.
src/common/appconfig.h Defines Config::avoid_focus_stealing with default false.
src/gui/windowgeometryguard.h Declares raiseWindowWithoutActivating().
src/gui/windowgeometryguard.cpp Implements raiseWindowWithoutActivating() and calls into platform window raise.
src/platform/platformwindow.h Adds PlatformWindow::raiseWithoutActivating() API (default fallback to raise()).
src/platform/platformnativeinterface.h Adds canAvoidFocusStealing(), focus-on-show hint, and keyboard intercept hooks.
src/platform/x11/x11platform.h Declares X11 support for focus avoidance and keyboard intercept.
src/platform/x11/x11platform.cpp Implements X11 focus-on-show hint and XGrabKeyboard/XUngrabKeyboard intercept.
src/platform/x11/x11platformwindow.h Adds raiseWithoutActivating() override.
src/platform/x11/x11platformwindow.cpp Implements non-activating raise via XRaiseWindow.
src/platform/win/winplatform.h Reports focus-avoidance capability on Windows.
src/platform/win/winplatformwindow.h Adds raiseWithoutActivating() override.
src/platform/win/winplatformwindow.cpp Implements non-activating raise via SetWindowPos.
src/platform/mac/macplatform.h Reports focus-avoidance capability on macOS.
src/platform/mac/macplatformwindow.h Adds raiseWithoutActivating() override.
src/platform/mac/macplatformwindow.mm Implements non-activating raise via orderFrontRegardless.
src/platform/dummy/dummyplatform.h Implements new capability API as unsupported.
src/gui/mainwindow.h Adds option field and state tracking for non-activating show.
src/gui/mainwindow.cpp Uses the option to show menu/window without activation and installs/removes keyboard intercept.
src/tests/tests.h Declares new avoidFocusStealing() test slot.
src/tests/tests_other.cpp Adds a focus-retention test for the new option.
docs/known-issues.rst Documents the issue and points users to the new preference.
Comments suppressed due to low confidence (1)

src/gui/mainwindow.cpp:3030

  • m_shownWithoutActivating is used to suppress close-on-unfocus behavior, but it’s never cleared when the window later becomes active (QEvent::WindowActivate). This means close_on_unfocus stays disabled for the rest of the visible lifetime, and the “shown without activating” state can leak into normal interactions. Consider clearing m_shownWithoutActivating (and removing the keyboard intercept if it’s no longer needed) once the window is actually activated, so close-on-unfocus can work again.
    if (m_options.closeOnUnfocus && !m_shownWithoutActivating) {
        if (
            type == QEvent::WindowDeactivate
        ) {
            hideWindowOnUnfocus(AppConfig().option<Config::close_on_unfocus_delay_ms>());
        } else if (

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/platform/x11/x11platform.cpp Outdated
Comment thread src/gui/windowgeometryguard.cpp Outdated
Comment thread src/gui/mainwindow.cpp Outdated
Comment thread src/platform/win/winplatformwindow.cpp Outdated
Comment thread docs/known-issues.rst Outdated
@hluk
hluk force-pushed the fix/avoid-focus-stealing branch 4 times, most recently from 40fc6ec to 8877bb3 Compare April 27, 2026 10:40
@hluk hluk changed the title Add option to show window/menu without stealing focus Document focus-stealing issue with workaround Apr 27, 2026
When CopyQ shows its main window or tray menu, it steals keyboard focus
from the previously active window. This can cause side effects such as
file renames aborting, combo boxes selecting content, and short-lived
widgets dismissing.

Add a known-issues.rst section documenting the problem and a practical
workaround: use next()/previous() global shortcuts to cycle clipboard
history without opening any window.

Closes: #3540

Assisted-by: Claude (Anthropic)
@hluk
hluk force-pushed the fix/avoid-focus-stealing branch from 8877bb3 to c65e039 Compare April 27, 2026 10:42

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

Comment thread docs/known-issues.rst Outdated
Comment thread docs/known-issues.rst Outdated
Co-authored-by: Philippe Cloutier <chealer@gmail.com>
@hluk

hluk commented Apr 28, 2026

Copy link
Copy Markdown
Owner Author

Thanks, @Chealer. I've applied your suggestions.

Comment thread docs/known-issues.rst Outdated
hluk and others added 2 commits April 30, 2026 08:35
Co-authored-by: Philippe Cloutier <chealer@gmail.com>
@hluk
hluk merged commit f232a60 into master Apr 30, 2026
10 of 11 checks passed
@hluk
hluk deleted the fix/avoid-focus-stealing branch May 16, 2026 06:24
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.

Opening (main window or tray menu) steals focus from target window, disrupting file renames, combo boxes, Windows File Explorer/picker address bar, etc.

3 participants