mirror of
https://github.com/aaddrick/claude-desktop-debian.git
synced 2026-05-17 00:26:21 +03:00
* feat(linux): hybrid titlebar mode for clickable in-app topbar Default `CLAUDE_TITLEBAR_STYLE` is now `hybrid`: native OS frame plus a BrowserView preload shim that convinces claude.ai's bundle to render its in-app topbar (hamburger / sidebar / search / nav / Cowork ghost). Stacked layout instead of Windows's combined bar, but every button is clickable. Why not the upstream `frame:false` + WCO config: investigation (see docs/learnings/linux-topbar-shim.md) ruled out `titleBarOverlay`, `titleBarStyle:'hidden'`, and the `.draggable` CSS class as the source of the topbar click-eating drag region. The remaining cause is a Chromium-level implicit drag region for `frame:false` windows that exists on both X11 and Wayland and has no Electron-API knob. With `frame:true` the OS handles dragging and Chromium pushes no drag-region map, so the buttons receive mouse events normally. Modes: - `hybrid` (default) — system frame + shim, topbar visible and clickable - `native` — system frame, no shim, no in-app topbar - `hidden` — frameless + WCO config, matches Windows/macOS upstream; topbar visible but not clickable on Linux. Kept for Wayland comparison and future investigation Tests: tests/launcher-common.bats grew 16 cases covering `_resolve_titlebar_style`, `build_electron_args` flag selection per mode, and `setup_electron_env` env-var wiring per mode. `claude-desktop --doctor` now reports the resolved mode and warns when `hidden` is set. Co-Authored-By: Claude <claude@anthropic.com> * docs(learnings): add hybrid-mode screenshot Visual reference of the stacked layout: DE-drawn titlebar on top with native window controls, claude.ai's in-app topbar (hamburger / search / back-forward) immediately below it. Co-Authored-By: Claude <claude@anthropic.com> * docs(learnings): fix codespell hit (Pre-emptive → Preemptive) Codespell flags hyphenated "Pre-emptive" as a misspelling of "Preemptive". Drops the hyphen to clear the spellcheck CI gate on PR #538. Co-Authored-By: Claude <claude@anthropic.com> --------- Co-authored-by: Claude <claude@anthropic.com>
41 lines
1.5 KiB
Bash
41 lines
1.5 KiB
Bash
#===============================================================================
|
|
# Inject Window Controls Overlay shim into the BrowserView preload.
|
|
#
|
|
# Sourced by: build.sh
|
|
# Sourced globals: source_dir
|
|
# Modifies globals: (none)
|
|
#===============================================================================
|
|
|
|
patch_wco_shim() {
|
|
echo '##############################################################'
|
|
echo 'Inlining WCO shim into mainView.js (Linux topbar workaround)'
|
|
|
|
local main_view='app.asar.contents/.vite/build/mainView.js'
|
|
|
|
if [[ ! -f $main_view ]]; then
|
|
echo "Error: mainView.js not found at $main_view." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if grep -q '__claude_wco_shim' "$main_view"; then
|
|
echo 'mainView.js already has WCO shim, skipping inject'
|
|
echo '##############################################################'
|
|
return 0
|
|
fi
|
|
|
|
# Sandboxed preloads can only require a fixed allowlist of modules
|
|
# (electron, ipcRenderer, contextBridge, webFrame…). A relative
|
|
# require to a sibling file fails with "module not found" and
|
|
# aborts the entire preload — taking desktopBootFeatures and the
|
|
# rest of mainView's exposeInMainWorld surface down with it.
|
|
# So we inline the shim source directly at the top of mainView.js
|
|
# instead of pulling it in via require.
|
|
local shim_content
|
|
shim_content=$(cat "$source_dir/scripts/wco-shim.js")
|
|
local original
|
|
original=$(cat "$main_view")
|
|
printf '%s\n%s' "$shim_content" "$original" > "$main_view"
|
|
echo 'Inlined WCO shim at top of mainView.js'
|
|
echo '##############################################################'
|
|
}
|