From c93b585a8702901593b12106915ab03b0a4e8678 Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 24 Jul 2026 10:59:40 +0300 Subject: [PATCH 1/4] fix(desktop): prefer WebKit Skia CPU rendering on Linux Non-conformant radv on AMD RDNA4 leaves a transparent window; CPU raster paints. Signed-off-by: Taksh Co-authored-by: Cursor --- desktop/scripts/fix-appimage.sh | 30 ++++++++++++++++++++++++++++++ desktop/src-tauri/src/lib.rs | 8 ++++++++ 2 files changed, 38 insertions(+) diff --git a/desktop/scripts/fix-appimage.sh b/desktop/scripts/fix-appimage.sh index 45f537bb72..8b07a85ecb 100755 --- a/desktop/scripts/fix-appimage.sh +++ b/desktop/scripts/fix-appimage.sh @@ -114,6 +114,36 @@ echo "==> Symlinking system GStreamer plugin directory" rm -rf "$LIBDIR/gstreamer-1.0" ln -s "/usr/lib/$MULTIARCH/gstreamer-1.0" "$LIBDIR/gstreamer-1.0" +# WebKitGTK 2.52 Skia's GPU path goes through Vulkan/radv. On non-conformant +# AMD RDNA4 (gfx1200) that path paints nothing — transparent ghost window — +# while WEBKIT_DISABLE_DMABUF_RENDERER does not help (#2643). Prefer Skia CPU +# raster for AppImage launches; operators can override with =0. +echo "==> Preferring WebKitGTK Skia CPU rendering for AppImage launches" +HOOK_DIR="$WORKDIR/squashfs-root/apprun-hooks" +mkdir -p "$HOOK_DIR" +cat > "$HOOK_DIR/99-buzz-webkit-skia-cpu.sh" <<'EOF' +# Allow operators to override (e.g. WEBKIT_SKIA_ENABLE_CPU_RENDERING=0) if needed. +export WEBKIT_SKIA_ENABLE_CPU_RENDERING="${WEBKIT_SKIA_ENABLE_CPU_RENDERING:-1}" +EOF +if [[ -f "$WORKDIR/squashfs-root/AppRun" ]] \ + && ! grep -q 'WEBKIT_SKIA_ENABLE_CPU_RENDERING' "$WORKDIR/squashfs-root/AppRun"; then + if ! grep -q 'apprun-hooks' "$WORKDIR/squashfs-root/AppRun"; then + tmp_apprun="$(mktemp)" + { + if head -n1 "$WORKDIR/squashfs-root/AppRun" | grep -q '^#!'; then + head -n1 "$WORKDIR/squashfs-root/AppRun" + echo 'export WEBKIT_SKIA_ENABLE_CPU_RENDERING="${WEBKIT_SKIA_ENABLE_CPU_RENDERING:-1}"' + tail -n +2 "$WORKDIR/squashfs-root/AppRun" + else + echo 'export WEBKIT_SKIA_ENABLE_CPU_RENDERING="${WEBKIT_SKIA_ENABLE_CPU_RENDERING:-1}"' + cat "$WORKDIR/squashfs-root/AppRun" + fi + } > "$tmp_apprun" + mv "$tmp_apprun" "$WORKDIR/squashfs-root/AppRun" + chmod +x "$WORKDIR/squashfs-root/AppRun" + fi +fi + echo "==> Repacking AppImage" # Pass a pinned type2 runtime when provided (CI sets APPIMAGETOOL_RUNTIME_FILE); # without it appimagetool downloads the runtime from its mutable `continuous` diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index 3688ee3a62..b09b00e88b 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -135,6 +135,14 @@ async fn wait_for_stable_initial_window_geometry(window: &tau #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { + // WebKitGTK 2.52 Skia GPU/Vulkan paints nothing on non-conformant AMD RDNA4 + // (radv gfx1200): transparent ghost window (#2643). Prefer CPU raster when + // unset; operators can force GPU with WEBKIT_SKIA_ENABLE_CPU_RENDERING=0. + #[cfg(target_os = "linux")] + if std::env::var_os("WEBKIT_SKIA_ENABLE_CPU_RENDERING").is_none() { + std::env::set_var("WEBKIT_SKIA_ENABLE_CPU_RENDERING", "1"); + } + // mesh-llm's async chains (model download, node start/join) overflow // tokio's default 2 MiB worker stacks — a stack-guard SIGABRT, not a // panic. Upstream mesh-llm and mesh-console both run on 8 MiB worker From aa90ccbdec847ff41eedd842665c1c9711e066c1 Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 24 Jul 2026 10:59:40 +0300 Subject: [PATCH 2/4] fix(desktop): reject COLRv1 Noto Color Emoji in AppImage Fedora's color-emoji face asserts inside bundled WebKitGTK/Skia. Signed-off-by: Taksh Co-authored-by: Cursor --- desktop/scripts/fix-appimage.sh | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/desktop/scripts/fix-appimage.sh b/desktop/scripts/fix-appimage.sh index 8b07a85ecb..973d9fbb62 100755 --- a/desktop/scripts/fix-appimage.sh +++ b/desktop/scripts/fix-appimage.sh @@ -144,6 +144,54 @@ if [[ -f "$WORKDIR/squashfs-root/AppRun" ]] \ fi fi +# Fedora's COLRv1 Noto Color Emoji trips an assertion in WebKitGTK/Skia and +# aborts the AppImage after a blank window (#2548). Reject that family so +# emoji fall back to a non-COLRv1 face (or to monochrome glyphs). +echo "==> Rejecting COLRv1 system color-emoji fonts for AppImage launches" +FC_DIR="$WORKDIR/squashfs-root/usr/etc/fonts" +mkdir -p "$FC_DIR" +cat > "$FC_DIR/fonts.conf" <<'EOF' + + + + + /etc/fonts/fonts.conf + + + + Noto Color Emoji + + + + +EOF +cat > "$HOOK_DIR/98-buzz-fontconfig-no-colrv1.sh" <<'EOF' +# Prefer the AppImage fontconfig that rejects COLRv1 Noto Color Emoji (#2548). +# Operators can point FONTCONFIG_FILE elsewhere to override. +if [ -z "${FONTCONFIG_FILE:-}" ] && [ -n "${APPDIR:-}" ] && [ -f "$APPDIR/usr/etc/fonts/fonts.conf" ]; then + export FONTCONFIG_FILE="$APPDIR/usr/etc/fonts/fonts.conf" +fi +EOF +if [[ -f "$WORKDIR/squashfs-root/AppRun" ]] \ + && ! grep -q 'buzz-fontconfig-no-colrv1\|FONTCONFIG_FILE=.*usr/etc/fonts' "$WORKDIR/squashfs-root/AppRun"; then + if ! grep -q 'apprun-hooks' "$WORKDIR/squashfs-root/AppRun"; then + tmp_apprun="$(mktemp)" + { + if head -n1 "$WORKDIR/squashfs-root/AppRun" | grep -q '^#!'; then + head -n1 "$WORKDIR/squashfs-root/AppRun" + echo 'if [ -z "${FONTCONFIG_FILE:-}" ] && [ -n "${APPDIR:-}" ] && [ -f "$APPDIR/usr/etc/fonts/fonts.conf" ]; then export FONTCONFIG_FILE="$APPDIR/usr/etc/fonts/fonts.conf"; fi' + tail -n +2 "$WORKDIR/squashfs-root/AppRun" + else + echo 'if [ -z "${FONTCONFIG_FILE:-}" ] && [ -n "${APPDIR:-}" ] && [ -f "$APPDIR/usr/etc/fonts/fonts.conf" ]; then export FONTCONFIG_FILE="$APPDIR/usr/etc/fonts/fonts.conf"; fi' + cat "$WORKDIR/squashfs-root/AppRun" + fi + } > "$tmp_apprun" + mv "$tmp_apprun" "$WORKDIR/squashfs-root/AppRun" + chmod +x "$WORKDIR/squashfs-root/AppRun" + fi +fi + echo "==> Repacking AppImage" # Pass a pinned type2 runtime when provided (CI sets APPIMAGETOOL_RUNTIME_FILE); # without it appimagetool downloads the runtime from its mutable `continuous` From 02043570ae59f2475ef409f6971950414f4264b4 Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 24 Jul 2026 10:59:40 +0300 Subject: [PATCH 3/4] fix(desktop): skip WindowsApps bash aliases in agent discovery Those aliases launch WSL, not Git Bash, and flash consoles on every probe. Signed-off-by: Taksh Co-authored-by: Cursor --- .../src-tauri/src/managed_agents/git_bash.rs | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/desktop/src-tauri/src/managed_agents/git_bash.rs b/desktop/src-tauri/src/managed_agents/git_bash.rs index dab9e887c8..32e9bdc6f2 100644 --- a/desktop/src-tauri/src/managed_agents/git_bash.rs +++ b/desktop/src-tauri/src/managed_agents/git_bash.rs @@ -302,7 +302,10 @@ fn scan_path_for_command( ) -> Option { let needs_exe = name.extension().is_none(); std::env::split_paths(path_env).find_map(|dir| { - if system_root.is_some_and(|root| is_under_dir(&dir, root)) { + // System32 bash and %LOCALAPPDATA%\Microsoft\WindowsApps\bash.exe are + // WSL app-execution aliases, not Git Bash (#2685). + if system_root.is_some_and(|root| is_under_dir(&dir, root)) || is_windows_apps_dir(&dir) + { return None; } let candidate = dir.join(name); @@ -320,6 +323,19 @@ fn scan_path_for_command( }) } +/// Windows exposes `bash.exe` app-execution aliases under WindowsApps that +/// launch WSL rather than Git Bash. Skip those PATH entries so discovery does +/// not boot `wsl.exe` on every unresolved command probe. +#[cfg(windows)] +fn is_windows_apps_dir(dir: &Path) -> bool { + dir.components().any(|component| { + component + .as_os_str() + .to_string_lossy() + .eq_ignore_ascii_case("WindowsApps") + }) +} + #[cfg(windows)] fn is_under_dir(dir: &Path, root: &Path) -> bool { let mut dir_components = dir.components(); @@ -501,6 +517,37 @@ mod tests { ); } + #[test] + fn test_windows_apps_bash_alias_is_not_treated_as_git_bash() { + let temp = tempdir().expect("tempdir"); + let windows_apps = temp.path().join("Microsoft").join("WindowsApps"); + let alias = windows_apps.join("bash.exe"); + let git = temp.path().join("Git").join("cmd").join("git.exe"); + let bash = temp.path().join("Git").join("bin").join("bash.exe"); + std::fs::create_dir_all(&windows_apps).expect("mkdir WindowsApps"); + std::fs::create_dir_all(git.parent().expect("git parent")).expect("mkdir git"); + std::fs::create_dir_all(bash.parent().expect("bash parent")).expect("mkdir bash"); + std::fs::write(alias, []).expect("alias"); + std::fs::write(&git, []).expect("git"); + std::fs::write(&bash, []).expect("bash"); + + let path = + std::env::join_paths([windows_apps, git.parent().expect("cmd dir").to_path_buf()]) + .expect("PATH"); + assert_eq!( + resolve_git_bash_no_registry( + path.to_str().expect("utf8"), + None, + None, + None, + None, + None, + None, + ), + Some(bash) + ); + } + #[test] fn test_effective_buzz_shell_override_marks_agent_ready() { let temp = tempdir().expect("tempdir"); From cacebaf5d5fe876b68ec563e68a3b84c60620779 Mon Sep 17 00:00:00 2001 From: Taksh Date: Fri, 24 Jul 2026 11:10:52 +0300 Subject: [PATCH 4/4] style: rustfmt WindowsApps bash guard Signed-off-by: Taksh Co-authored-by: Cursor --- desktop/src-tauri/src/managed_agents/git_bash.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/desktop/src-tauri/src/managed_agents/git_bash.rs b/desktop/src-tauri/src/managed_agents/git_bash.rs index 32e9bdc6f2..fdfc4e60e7 100644 --- a/desktop/src-tauri/src/managed_agents/git_bash.rs +++ b/desktop/src-tauri/src/managed_agents/git_bash.rs @@ -304,8 +304,7 @@ fn scan_path_for_command( std::env::split_paths(path_env).find_map(|dir| { // System32 bash and %LOCALAPPDATA%\Microsoft\WindowsApps\bash.exe are // WSL app-execution aliases, not Git Bash (#2685). - if system_root.is_some_and(|root| is_under_dir(&dir, root)) || is_windows_apps_dir(&dir) - { + if system_root.is_some_and(|root| is_under_dir(&dir, root)) || is_windows_apps_dir(&dir) { return None; } let candidate = dir.join(name);