The --in-process-gpu flag broke <webview> guest compositing entirely,
leaving connection views blank on all Linux configurations. SwiftShader
(--use-gl=angle --use-angle=swiftshader) keeps the GPU process
out-of-process (required for webview compositing) while using software
rendering to avoid the driver-level /dev/shm crashes that originally
motivated the in-process flag.
The local Open WebUI server is a singleton — it's either installed or not.
Previously it was modeled as a type:'local' entry in the connections[]
config array, which broke when installing from Settings (the entry was
only created during the Get Started flow).
Now:
- connections[] is remote-only
- Local server is implicit when open-webui package is installed
- 'local' is a virtual connection ID, synthesized on the fly
- Main process: add getDefaultConnection/buildLocalConnection/resolveConnectionUrl
helpers, replacing ~70 lines of duplicated config lookup across 5 handlers
- Renderer: localConn derived from localInstalled state, not connections store
- Push-based reactivity: main process emits connections:changed events
- Tray: virtual local entry when package is installed
- Migration: strip legacy type:'local' entries from config on startup
On macOS, app.focus({ steal: true }) activates the entire application,
causing the window manager to switch back to whichever Space the app was
originally launched on. Replace it with targeted window-level focus and
add visibleOnAllWorkspaces to ensure Spotlight appears on the current
Space without triggering a desktop switch.
Previously, startOpenTerminal threw 'Python is not installed' which was
caught by the IPC handler but only produced a generic error toast with no
actionable guidance. On a fresh install where the user hasn't started a
Local Server first, this made Open Terminal appear completely broken.
Now startOpenTerminal automatically triggers installPython() when Python
is missing, reusing the same download/extract/uv-install flow that the
Local Server setup uses. Install progress (download %, extraction) is
forwarded to the renderer via a new status:open-terminal-setup event and
displayed in the log panel status bar.
Fixes#168
Both --disable-gpu and --disable-gpu-compositing kill the display
compositor, preventing <webview> guest surfaces from painting (gray
rectangle). --in-process-gpu moves the GPU thread into the browser
process, sidestepping the cross-process shared-memory IPC crashes
while keeping the compositor alive so webview content renders.
llama-server's --models-dir scanner only checks one level of
subdirectories. Downloaded models were stored two levels deep at
models/huggingface/<repo-slug>/<filename>, making them invisible.
Changed the cache directory from models/huggingface/ to models/ so
models land at models/<repo-slug>/<filename> — exactly one level deep.
Includes automatic migration of existing models from the legacy
huggingface/ subdirectory on first run.
Fixes#177
- Add ubuntu-24.04-arm and windows-11-arm to CI matrix
- Linux ARM64 builds AppImage + deb (Raspberry Pi, DGX Spark)
- Windows ARM64 builds NSIS installer (Snapdragon devices)
- Add arch to NSIS and AppImage artifact names to prevent collisions
- Add latest-linux.yml and latest.yml merge steps for auto-updater
- Update README with ARM64 download links
Closes#140
Escalate from --disable-gpu-compositing to --disable-gpu on Linux.
The GPU process crashes during shared memory allocation in /tmp even
with --disable-dev-shm-usage, and disabling compositing alone still
leaves the GPU process running. --disable-gpu prevents the process
from spawning entirely, resolving both the crash and grey screen.
Closes#157, Closes#119
Escape, click-away, hotkey toggle, and blur now hide the spotlight
overlay silently. Only spotlight:submit restores the main window
so the user sees their query delivered.
On many Linux setups (Intel iGPU, mixed NVIDIA/Intel, Wayland
compositors), the GPU compositor fails silently without crashing
the GPU process — producing a grey rectangle where the webview
content should be. The existing GPU crash recovery marker never
fires because the process stays alive.
Adding --disable-gpu-compositing on Linux is the standard Electron
workaround (used by VS Code, Brave, etc.) for this class of issue.
It disables only the compositor, not all hardware acceleration,
so video decode and basic GPU ops still work.
Also adds render-process-gone listeners to auto-reload the main
window on renderer crashes and log webview guest crashes for
diagnostics.
Closes#119
The Copy button in the Open WebUI interface silently failed on
GNOME/Wayland/Flatpak because the webview session permission handlers
did not include 'clipboard-sanitized-write'. Electron denied the
navigator.clipboard.writeText() call, but the web app saw no error
and briefly showed 'Copied' without actually writing to the clipboard.
Added 'clipboard-sanitized-write' to both permission handler whitelists:
- Per-connection content window handler
- session-created handler for webview partition sessions
Add --disable-dev-shm-usage flag on Linux so Chromium writes shared
memory to /tmp instead of /dev/shm. AppImage's FUSE mount restricts
child-process access to /dev/shm, causing FATAL zygote/renderer crashes
with 'Unable to access(W_OK|X_OK) /dev/shm' — resulting in a blank/grey
screen. Also affects .deb and Snap packages on some distros.
Fixes#136
- Set npmRebuild: true so native modules are compiled against
Electron's Node ABI on each platform during packaging
- Add node_modules/node-pty/** to asarUnpack so the native pty.node
binary is extracted to the real filesystem instead of being
trapped inside app.asar where require() cannot load it
When connecting to remote or auth-enabled instances, the webview could
fail to load silently — leaving users with a blank grey screen and no
feedback (#119, #124).
Changes:
- Add did-fail-load, crashed, and did-navigate event listeners to
webviews so load failures are captured per-connection
- Surface the existing webviewLoading state in the loading overlay
(was tracked but never rendered)
- Show an error overlay with the failure description, Retry button,
and Open in Browser fallback when the webview fails to load
- Fix preload race condition: webviews created before the async
contentPreloadPath resolves now get the correct preload reapplied
- Add console-message listener (warnings/errors) for diagnosing
blank-page issues where the page loads but JS fails silently
- Enable native Wayland backend with ozone-platform-hint=auto on Linux,
allowing Chromium's built-in GlobalShortcutsPortal (default since Cr134)
to route globalShortcut.register() through xdg-desktop-portal
- Add org.freedesktop.portal.Desktop talk-name to Flatpak finishArgs so
the sandbox permits portal D-Bus calls
- Refactor shortcut registration into tryRegisterShortcut() helper with
consistent error handling and user-facing notifications for all four
shortcuts (global, spotlight, voice input, call)
Fixes#126
- Save window bounds (size + position) and maximized state to config on
resize, move, maximize, and unmaximize with debounced writes
- Restore saved geometry on launch with display visibility validation
to handle disconnected monitors gracefully
- Lower minimum window size from 1280x800 to 480x360 to support
smaller screens and compact layouts
- Extract magic numbers into named constants and consolidate event
handlers for cleaner maintainability
Closes#145, Closes#109
Add a 'spotlightClipboardPaste' setting (default: true) that controls
whether clipboard contents are automatically pasted into the Spotlight
prompt window. Users can disable this in Settings > General to prevent
sensitive data (e.g. passwords) from being exposed.
Closes#123
The build/entitlements.mac.plist was missing the critical
com.apple.security.cs.disable-library-validation entitlement, causing
macOS to reject loading the Electron Framework due to Team ID mismatch.
Also syncs all other entitlements (network, camera, microphone, etc.)
from the root entitlements.plist to ensure consistency.
Bypass certificate verification globally so the desktop app can connect
to Open WebUI instances using self-signed, private-CA, ZeroSSL, or any
other non-publicly-trusted certificates.
Three layers:
- session.defaultSession.setCertificateVerifyProc: covers net.fetch()
used by validateRemoteUrl / checkUrlAndOpen
- app.on('session-created'): covers partitioned webview sessions
(persist:connection-*) including in-page API calls
- app.on('certificate-error'): fallback for BrowserWindow navigations
Also switches validateRemoteUrl and checkUrlAndOpen from Node fetch()
to Electron net.fetch() so they route through Chromium's network stack
and respect the session certificate overrides.
When the GPU process crashes fatally (common with certain NVIDIA/Intel
driver versions on Windows), automatically write a marker file and
relaunch with --disable-gpu-sandbox so users don't have to manually
edit shortcut targets.
- Detect GPU crashes via child-process-gone event
- Persist .gpu-sandbox-disabled marker across restarts
- Apply --disable-gpu-sandbox preemptively on subsequent launches
- Call disableDomainBlockingFor3DAPIs() to prevent WebGL blacklisting
- Clean up marker on app reset so users can re-test after driver updates
- Expose gpuSandboxDisabled in app:info for diagnostics
Fixes#110
The API key is now saved in config.json and reused on subsequent
startups instead of being regenerated every time, which was breaking
existing integrations that relied on a stable key.
Closes#102
- Wire up dead voiceInput:micPermission IPC handler via preload API
- Add pre-flight mic permission check before starting recording (macOS)
- Add pre-flight connection/auth validation in toggleVoiceInput
- Show OS notifications for all voice input failure points:
shortcut registration, mic denied, no connection, auth missing,
transcription HTTP errors, and generic voice input errors
- Improve renderer error messages for NotAllowedError/NotFoundError
- Forward renderer errors to main process for OS-level notifications