KDE Quick Window Blur/Hide Patch for Focus Issues in Claude Desktop on Linux
The KDE quick window blur/hide patch forces the quick-entry window to release focus before hiding, preventing a stale focus state that blocks the main window from appearing on KDE Plasma.
The aaddrick/claude-desktop-debian repository packages Claude Desktop for Debian-based Linux distributions, addressing platform-specific Electron quirks. One critical fix involves the KDE quick window blur/hide patch for focus issues, which resolves a desktop environment-specific bug where the quick-entry window's focus state persists incorrectly after hiding.
The Focus Stale Bug on KDE Plasma
Claude Desktop bundles an Electron front-end that displays a quick-entry window for rapid interactions. On KDE Plasma, this window's isFocused() check can remain true even after the window is hidden, which creates a stale focus state.
When the user submits a quick-entry request, the application checks focus status to determine whether to call show() on the main window. Because the stale focus signals the window is already active, the upstream code skips the show() call entirely. The user never sees the main window appear, leaving the application seemingly unresponsive.
How the KDE Blur/Hide Patch Works
The repository implements a KDE-gated patch that modifies the quick-window lifecycle without affecting other desktop environments. The solution operates on three levels:
Runtime Environment Detection
The patch first checks the XDG_CURRENT_DESKTOP environment variable to identify KDE specifically. This ensures the fix only executes on affected systems:
(process.env.XDG_CURRENT_DESKTOP||"").toLowerCase().includes("kde")
Blur Before Hide Implementation
When the quick window needs to close, the patch inserts a blur() call before hide(). This explicitly clears the focus state rather than relying on the window manager to release it:
// Original pattern
quickWindow.hide()
// Patched pattern (KDE only)
(process.env.XDG_CURRENT_DESKTOP||"").toLowerCase().includes("kde")?(quickWindow.blur(),quickWindow.hide()):quickWindow.hide()
Visibility Check Replacement
The patch also modifies the logic that guards the main window's show() call. It replaces the isWindowFocused-based check with a KDE-gated visibility check, ensuring the main window appears regardless of the stale focus state.
Build Script Implementation Details
The core implementation resides in build.sh within the function patch_quick_window(). This function executes during the build step by editing the minified index.js that ships inside app.asar.
Variable Extraction
The script dynamically identifies the minified variable name assigned to the quick window (for example, e) by searching for the unique setAlwaysOnTop call signature:
# Extract the variable name from the minified source
quick_var=$(grep -oP 'setAlwaysOnTop\(\K[^)]+' app.asar.contents/.vite/build/index.js)
Patch Application
The build script performs an idempotent replacement that inserts the blur call only if it does not already exist. According to the source in build.sh#L26-L38, the transformation wraps the hide() invocation with the KDE environment check and blur operation:
# Pattern replacement in build.sh
sed -i "s/${quick_var}\.hide()/${de_check}?(${quick_var}.blur(),${quick_var}.hide()):${quick_var}.hide()/g" index.js
Where de_check represents the JavaScript snippet evaluating XDG_CURRENT_DESKTOP for the "kde" substring.
Secondary Visibility Patch
Lines 64-48 of the embedded Node.js script within build.sh handle the visibility-check replacement, rewriting the logic that conditionally shows the main window to bypass the focus check on KDE systems.
Verification and Testing
After building the package, you can verify the patch was applied correctly by inspecting the modified JavaScript.
Check for Blur Injection
# Locate the built index.js inside the unpacked app.asar
cat app.asar.contents/.vite/build/index.js | grep -E 'blur\(\),.*hide\(\)'
# Expected output (example):
# e.blur(),e.hide()
Runtime Environment Check
To confirm the runtime detection works within the running application:
// Execute in the Electron DevTools console
console.log((process.env.XDG_CURRENT_DESKTOP||"").toLowerCase().includes("kde"));
On KDE Plasma, this returns true and the blur patch executes; on other environments, it returns false and the original hide behavior persists.
Build Integration
The patch applies automatically when invoking the build script:
#!/usr/bin/env bash
set -e
git clone https://github.com/aaddrick/claude-desktop-debian.git
cd claude-desktop-debian
./build.sh # automatically applies the KDE blur/hide patch
The build output will display "Added KDE‑gated blur() before hide() on quick window" when the patch is successfully injected.
Summary
- The KDE quick window blur/hide patch resolves a focus-stale bug where
isFocused()remains true after hiding the quick-entry window on KDE Plasma. - The fix inserts a
blur()call beforehide()exclusively on KDE, detected viaXDG_CURRENT_DESKTOP, preventing regressions on GNOME or Ubuntu. - Implementation lives in
build.shwithin thepatch_quick_window()function, which modifies the minifiedindex.jsinsideapp.asarduring the build process. - The patch is idempotent and applies automatically to all Linux builds, ensuring consistent behavior across Debian packages, RPMs, and AppImages.
Frequently Asked Questions
Why does the quick window need a blur patch only on KDE?
KDE Plasma's window manager handles focus differently than GNOME or other X11/Wayland compositors. On KDE, Electron's isFocused() state can persist as true even after calling hide(), creating a stale focus flag that prevents the main window from showing. The blur patch explicitly clears this state before hiding, but only on KDE to avoid breaking the focus flow on other desktop environments where the bug does not occur.
How does the build script detect it is running on KDE?
The patch uses a runtime JavaScript check embedded directly into the modified source code: (process.env.XDG_CURRENT_DESKTOP||"").toLowerCase().includes("kde"). This evaluates the XDG_CURRENT_DESKTOP environment variable, which KDE sets to "KDE" (or variations like "kde" on some distributions). The build script injects this conditional into the minified index.js during the patch_quick_window() step in build.sh.
Will the blur patch cause issues on GNOME or other desktop environments?
No. The patch is explicitly gated to only execute when the KDE desktop environment is detected. The modified code uses a ternary operator that evaluates the desktop environment check: if KDE is detected, it runs blur() followed by hide(); otherwise, it executes the original hide() call alone. This design prevents the regression reported in issue #393, where an unconditional blur broke quick-entry workflows on Ubuntu/GNOME systems.
Where can I verify the patch was applied in my built package?
After running ./build.sh, you can inspect the modified JavaScript inside the unpacked application archive. Run cat app.asar.contents/.vite/build/index.js | grep -E 'blur\(\),.*hide\(\)' to locate the injected code. You should see a pattern like e.blur(),e.hide() (where e is the minified variable name for the quick window) wrapped inside the KDE environment check. The build script also prints "Added KDE‑gated blur() before hide() on quick window" to stdout when the patch succeeds.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →