Bugfix: Unresponsive native window controls on Linux#160
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe PR conditionally disables main-window show/focus on Linux via three ChangesPlatform-Specific Window Management
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src-tauri/src/lib.rs (1)
3541-3541:⚠️ Potential issue | 🟠 Major | ⚡ Quick winLinux: also guard
main_window.show()intry_select_in_notes_folder()
try_select_in_notes_folder()unconditionally callsmain_window.show()when a note inside the configured notes folder is selected (CLI/Open With/DragDrop). Othermain_window.show()calls are wrapped with#[cfg(not(target_os = "linux"))], and the Tauri main window is configured with"visible": false, so this unguarded call is inconsistent and can reintroduce the Linux window-chrome issue. Add the same Linux guard aroundshow()(keepset_focus()consistent with the surrounding patterns).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src-tauri/src/lib.rs` at line 3541, In try_select_in_notes_folder(), the unguarded call to main_window.show() can reintroduce the Linux window-chrome issue; wrap that show() call with the same conditional compilation used elsewhere (i.e. #[cfg(not(target_os = "linux"))]) so it only runs on non-Linux builds, and leave main_window.set_focus() following the existing pattern (keep set_focus() as-is or guarded the same way if surrounding calls do so) to match surrounding code paths and maintain consistency with other main_window.show() usages.
🧹 Nitpick comments (6)
.devcontainer/devcontainer.json (3)
28-29: ⚡ Quick winCross-platform compatibility concern with bind mount paths.
The bind mounts on lines 28-29 use paths that are Unix/Linux/macOS specific:
${localEnv:HOME}/.codex${localEnv:HOME}/.config/Code/User/globalStorageThese mounts will fail or have incorrect paths on Windows hosts, where VS Code's global storage is typically at
%APPDATA%\Code\User\globalStorage. If your team includes Windows developers, consider either:
- Removing these bind mounts and accepting that settings won't persist
- Using platform-specific devcontainer configs
- Documenting that the devcontainer is Linux/macOS-only
Additionally, these bind mounts combined with
updateRemoteUserUID: false(line 10) may cause permission issues if the host user's UID ≠ 1000.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.devcontainer/devcontainer.json around lines 28 - 29, The devcontainer bind mounts use Unix-only HOME paths and will break on Windows; update .devcontainer/devcontainer.json to either remove the two bind entries ("source=${localEnv:HOME}/.codex,..." and "source=${localEnv:HOME}/.config/Code/User/globalStorage,..."), replace them with platform-specific alternatives (use a Windows conditional config that maps %APPDATA%\Code\User\globalStorage for Windows hosts), or document that the devcontainer is Linux/macOS-only; also address potential UID mapping by setting updateRemoteUserUID to true or adding documentation/instructions so host UID mismatches do not cause permission issues.
20-20: 💤 Low valueVerify that the ChatGPT extension should be in the shared devcontainer config.
The
openai.chatgptextension is included in the shared devcontainer configuration. While this may be intentional for team collaboration, AI assistant extensions are often a personal preference. Consider whether this should be in the shared config or left to individual developers to install via their personal VS Code settings.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.devcontainer/devcontainer.json at line 20, The shared devcontainer currently includes the AI extension "openai.chatgpt"; decide whether this is intentional—if not, remove "openai.chatgpt" from the devcontainer extensions array in devcontainer.json so it is not forced for all developers, or alternatively make it optional by documenting it in the repo README (or a dev setup doc) so developers can install "openai.chatgpt" individually; update devcontainer.json to remove the extension or add a comment pointing to the documentation and commit that change.
10-10: Potential UID/GID permission mismatch withupdateRemoteUserUID: false(bind mounts into/home/vscode/...)
.devcontainer/Dockerfilecreates thevscodeuser with defaultUSER_UID=1000/USER_GID=1000, and.devcontainer/devcontainer.jsonsets"remoteUser": "vscode"+"updateRemoteUserUID": false, so the container user stays UID 1000.- The bind mounts from
${localEnv:HOME}into/home/vscode/.codexand/home/vscode/.vscode-server/data/User/globalStoragemay be unwritable when the host’s HOME files are owned by a different UID than 1000.Set
"updateRemoteUserUID"totrue(or omit it) unless all developers consistently use UID 1000 or the host mount permissions are compatible.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.devcontainer/devcontainer.json at line 10, The devcontainer sets "remoteUser": "vscode" while leaving "updateRemoteUserUID": false which can cause host bind-mounted HOME files under /home/vscode/.codex and /home/vscode/.vscode-server to be unwritable if the host UID differs from 1000; update the devcontainer.json to set "updateRemoteUserUID": true (or remove the setting so it defaults to true) so the container adjusts the vscode user's UID/GID to match the host and avoid permission issues with the bind mounts referenced (/home/vscode/.codex, /home/vscode/.vscode-server/data/User/globalStorage)..devcontainer/Dockerfile (2)
71-71: ⚡ Quick winClarify the purpose of the
.codexdirectory.The
.codexdirectory is created in the container and mounted from the host (perdevcontainer.jsonline 28), but its purpose is not documented. Consider adding a comment explaining what this directory is used for.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.devcontainer/Dockerfile at line 71, Add a short comment above the line creating/mounting "/home/${USERNAME}/.codex" in the Dockerfile explaining the directory's purpose and why it's mounted from the host (e.g., cache for models, local tool state, credentials, or workspace artifacts); reference the ".codex" directory name and the corresponding mount configured in devcontainer.json so future readers know what data lives there and why it must be persisted on the host.
80-80: ⚡ Quick winConsider pinning the Rust toolchain version for reproducibility.
Using
--default-toolchain stableinstalls the latest stable Rust version at build time, which can change and cause reproducibility issues. Consider pinning to a specific version (e.g.,1.70to match the README minimum, or a more recent stable version) to ensure consistent builds across time and developers.📌 Example: Pin to a specific Rust version
RUN curl https://sh.rustup.rs -sSf \ - | sh -s -- -y --profile minimal --default-toolchain stable \ + | sh -s -- -y --profile minimal --default-toolchain 1.83.0 \ && chmod -R a+w ${CARGO_HOME} ${RUSTUP_HOME}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.devcontainer/Dockerfile at line 80, The Dockerfile currently uses the rustup installer flag `--default-toolchain stable`; change this to pin a specific toolchain (for example `1.70` or a chosen patch-level like `1.70.0`) so builds are reproducible—update the `sh -s -- -y --profile minimal --default-toolchain stable \` invocation to use the pinned version (or read a build ARG and use that value) so the Rust toolchain is deterministic across builds.src-tauri/tauri.macos.conf.json (1)
5-7: ⚡ Quick winVerify consistency between main window and preview window titlebar configuration.
This config sets
trafficLightPositionfor the main window, but the preview window creation code at lines 3590-3592 inlib.rsonly setstitle_bar_styleandhidden_titlefor macOS—no traffic light positioning. This might cause visual inconsistency between the main window and preview windows on macOS.Consider either:
- Adding
trafficLightPositionto preview windows in lib.rs, or- Documenting why preview windows intentionally use default positioning
Suggested alignment for preview windows
#[cfg(target_os = "macos")] let builder = builder .title_bar_style(tauri::TitleBarStyle::Overlay) - .hidden_title(true); + .hidden_title(true) + .traffic_light_position(tauri::LogicalPosition { x: 16.0, y: 24.0 });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src-tauri/tauri.macos.conf.json` around lines 5 - 7, The macOS main window JSON sets trafficLightPosition but the preview window creation in lib.rs only sets title_bar_style and hidden_title, causing visual inconsistency; locate the preview window creation function (the code that constructs the preview window in lib.rs—e.g., the function that calls WindowBuilder or sets title_bar_style/hidden_title for preview windows) and either add a matching traffic_light_position with {x: 16, y: 24} to its macOS WindowBuilder options to mirror the main window, or add a one-line comment/docstring near that preview window creation explaining why the preview intentionally omits traffic_light_position so reviewers understand this is deliberate.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.devcontainer/Dockerfile:
- Line 81: Remove the insecure world-writable permission on the Rust directories
by deleting (or replacing) the chmod -R a+w ${CARGO_HOME} ${RUSTUP_HOME} step;
since ownership is already set with chown -R "${USER_UID}:${USER_GID}", either
remove the chmod line entirely or change it to a more restrictive permission
change (e.g., grant only the owner write permission) on CARGO_HOME and
RUSTUP_HOME to avoid making them writable by all users.
In `@src-tauri/src/lib.rs`:
- Around line 3664-3666: In handle_cli_args ensure Linux focus handling matches
show(): either wrap main_window.set_focus() with the same #[cfg(not(target_os =
"linux"))] attribute used for main_window.show(), or add a concise comment on
why calling main_window.set_focus() on Linux is safe when the window is hidden;
locate the calls to main_window.show() and main_window.set_focus() in
handle_cli_args and apply the same conditional guard (or add the rationale)
consistently in both the "directory-open" and "no files were opened" paths.
In `@src-tauri/tauri.linux.conf.json`:
- Around line 1-9: The Linux override is replacing the entire app.windows array
so you lose base window settings; instead of setting app.windows to a single
anonymous entry, patch only the main window’s visible property (e.g., target the
"main" window entry) so you preserve title, width/height, minWidth/minHeight,
resizable, and decorations from the base tauri.conf.json; update
src-tauri/tauri.linux.conf.json to modify app.windows["main"].visible (or the
array element keyed as "main") rather than replacing the whole app.windows
array.
---
Outside diff comments:
In `@src-tauri/src/lib.rs`:
- Line 3541: In try_select_in_notes_folder(), the unguarded call to
main_window.show() can reintroduce the Linux window-chrome issue; wrap that
show() call with the same conditional compilation used elsewhere (i.e.
#[cfg(not(target_os = "linux"))]) so it only runs on non-Linux builds, and leave
main_window.set_focus() following the existing pattern (keep set_focus() as-is
or guarded the same way if surrounding calls do so) to match surrounding code
paths and maintain consistency with other main_window.show() usages.
---
Nitpick comments:
In @.devcontainer/devcontainer.json:
- Around line 28-29: The devcontainer bind mounts use Unix-only HOME paths and
will break on Windows; update .devcontainer/devcontainer.json to either remove
the two bind entries ("source=${localEnv:HOME}/.codex,..." and
"source=${localEnv:HOME}/.config/Code/User/globalStorage,..."), replace them
with platform-specific alternatives (use a Windows conditional config that maps
%APPDATA%\Code\User\globalStorage for Windows hosts), or document that the
devcontainer is Linux/macOS-only; also address potential UID mapping by setting
updateRemoteUserUID to true or adding documentation/instructions so host UID
mismatches do not cause permission issues.
- Line 20: The shared devcontainer currently includes the AI extension
"openai.chatgpt"; decide whether this is intentional—if not, remove
"openai.chatgpt" from the devcontainer extensions array in devcontainer.json so
it is not forced for all developers, or alternatively make it optional by
documenting it in the repo README (or a dev setup doc) so developers can install
"openai.chatgpt" individually; update devcontainer.json to remove the extension
or add a comment pointing to the documentation and commit that change.
- Line 10: The devcontainer sets "remoteUser": "vscode" while leaving
"updateRemoteUserUID": false which can cause host bind-mounted HOME files under
/home/vscode/.codex and /home/vscode/.vscode-server to be unwritable if the host
UID differs from 1000; update the devcontainer.json to set
"updateRemoteUserUID": true (or remove the setting so it defaults to true) so
the container adjusts the vscode user's UID/GID to match the host and avoid
permission issues with the bind mounts referenced (/home/vscode/.codex,
/home/vscode/.vscode-server/data/User/globalStorage).
In @.devcontainer/Dockerfile:
- Line 71: Add a short comment above the line creating/mounting
"/home/${USERNAME}/.codex" in the Dockerfile explaining the directory's purpose
and why it's mounted from the host (e.g., cache for models, local tool state,
credentials, or workspace artifacts); reference the ".codex" directory name and
the corresponding mount configured in devcontainer.json so future readers know
what data lives there and why it must be persisted on the host.
- Line 80: The Dockerfile currently uses the rustup installer flag
`--default-toolchain stable`; change this to pin a specific toolchain (for
example `1.70` or a chosen patch-level like `1.70.0`) so builds are
reproducible—update the `sh -s -- -y --profile minimal --default-toolchain
stable \` invocation to use the pinned version (or read a build ARG and use that
value) so the Rust toolchain is deterministic across builds.
In `@src-tauri/tauri.macos.conf.json`:
- Around line 5-7: The macOS main window JSON sets trafficLightPosition but the
preview window creation in lib.rs only sets title_bar_style and hidden_title,
causing visual inconsistency; locate the preview window creation function (the
code that constructs the preview window in lib.rs—e.g., the function that calls
WindowBuilder or sets title_bar_style/hidden_title for preview windows) and
either add a matching traffic_light_position with {x: 16, y: 24} to its macOS
WindowBuilder options to mirror the main window, or add a one-line
comment/docstring near that preview window creation explaining why the preview
intentionally omits traffic_light_position so reviewers understand this is
deliberate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 03239157-5b2c-48d5-8fbd-b01ad8596f5d
📒 Files selected for processing (6)
.devcontainer/Dockerfile.devcontainer/devcontainer.jsonsrc-tauri/src/lib.rssrc-tauri/tauri.conf.jsonsrc-tauri/tauri.linux.conf.jsonsrc-tauri/tauri.macos.conf.json
💤 Files with no reviewable changes (1)
- src-tauri/tauri.conf.json
561bcd7 to
d7c616e
Compare
|
I deleted the devcontainer from the branch and addressed the two other coderabbit concerns. |
Issue / Repro
On Linux (Ubuntu 26.04 with 7.0.0-22 kernel on amd64), the native window controls were broken on first launch: minimize, maximize, and close didn’t respond, even though the window could still be resized and double-clicking the titlebar would maximize it. Once the window was maximized, the native buttons started working normally.
Repro was just:
Root Cause
The main window was being created hidden and then shown later during startup. On Linux, that hidden-then-show flow was leaving the native window chrome in a bad initial state, so the caption buttons didn’t receive clicks until the window was reconfigured by maximizing.
There was also some macOS-specific titlebar config living in the shared Tauri config, which wasn’t related to the main Linux bug but didn’t belong in cross-platform window settings.
Fix
Linux now starts the main window visible instead of creating it hidden and showing it afterward. I also skipped the redundant normal-startup
show()calls on Linux so it stays on that visible-from-creation path.Separately, I split the macOS titlebar settings into a dedicated
tauri.macos.conf.jsonso overlay titlebar options stay macOS-only and don’t leak into Linux/Windows config.I only verified the fix on Ubuntu 26.04, not on Windows or Linux.
Dev Container
Separately, this branch includes a devcontainer since I don't have these dev tools on my local machine. If you don't want it in
main, exclude.devcontainer/**Summary by CodeRabbit
Bug Fixes
Chores