Skip to content

feat: shade the active Windows title bar instead of turning it black - #2121

Open
arshit09 wants to merge 1 commit into
cjpais:mainfrom
arshit09:feat/windows-title-bar
Open

arshit09 wants to merge 1 commit into
cjpais:mainfrom
arshit09:feat/windows-title-bar

Conversation

@arshit09

@arshit09 arshit09 commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Before Submitting This PR

Human Written Description

When the window is active, it has a pure black title bar, which seems odd and doesn't look like part of the app visually. Following in the footsteps of VS Code, Chrome, Telegram, etc., I got the idea to shade the title bar when active instead of coloring it natively. I've checked other Electron apps like Postman, Discord and Notion to see if they do something else, but they have no active window change at all, which I think is an accessibility and QoL issue. We should have some state change, which is why I decided to move forward with shading the color.

Related Issues/Discussions

None. Found while using the app; no existing issue, PR or discussion covers it. Related: #1778 (maximize and Aero Snap on Windows, which this keeps working) and #1659 (appearance setting reaches the native title bar).

Root Cause & Fix

  • Why the bar turns black. On Windows 10 the system paints a dark-mode window's native title bar pure black while the window is active. Apps can't change that color there: DWMWA_CAPTION_COLOR only exists on Windows 11.
  • Custom title bar on Windows. Like VS Code and Chrome, the main window is now undecorated on Windows and a new TitleBar.tsx draws the bar: app icon, title, and minimize/maximize/close buttons using the native Segoe MDL2 / Fluent glyphs. While active, the bar is a shade darker than the background (#222120 dark, #eeeeee light, from a new --color-titlebar-active token in theme.css). While inactive, it matches the background and the title and buttons turn gray.
  • Native window behavior kept. tao keeps the native frame styles on undecorated windows and only trims the caption, and Tauri handles edge resizing for undecorated WebView2 windows. Dragging and double-click to maximize use data-tauri-drag-region. Close goes through CloseRequested, so it still hides to the tray.
  • Focus tracking. Uses the page's focus/blur events and document.hasFocus(). WebView2 holds keyboard focus while the window is active, and Tauri's isFocused() checks the parent window, which never has focus while the webview does.
  • Layout. The bar is inside the window's inner size, so the window is 32px taller and the content area stays the same. On Windows, #root scrolls below the bar instead of the document. Top-level h-screen layouts use a new h-app utility, and the dialog backdrops and onboarding preview button start below the bar. --titlebar-height is 0px on macOS and Linux, so nothing changes there.
  • Permissions and i18n. A new windows-titlebar.json capability (Windows, main window only) allows start-dragging, minimize, toggle-maximize and close. The button labels (titleBar.*) are translated in all 26 locales.

Main files: src/components/TitleBar.tsx (new), src-tauri/src/lib.rs, src/main.tsx, src/App.css, src/styles/theme.css.

Community Feedback

None yet. Visual change on Windows only; macOS and Linux keep their native title bars.

Testing

  • bunx tsc --noEmit, ESLint, Prettier, bun run check:translations and vite build pass; cargo fmt --check and cargo clippy show nothing new
  • Ran the app on Windows 10 22H2 (dark theme): active bar #222120 over #2c2b29 content, inactive bar #2c2b29 with gray title and buttons, no border line along the top edge
  • Maximizing fills the screen edge to edge and swaps the icon to Restore; restoring returns the window to its original size
  • Manual: minimize, maximize and close buttons (close hides to the tray)
  • Manual: drag to move, double-click to maximize, snap to screen edges, resize from every edge

Screenshots/Videos (if applicable)

Before After
Active Native title bar while active, pure black New title bar while active, a shade darker than the background
Inactive Native title bar while inactive New title bar while inactive, matching the background

AI Assistance

  • No AI was used in this PR
  • AI was used (please describe below)

If AI was used:

  • Tools used: Claude Code (Opus 5, Extra High intelligence)
  • How extensively: I noticed the black title bar and asked Claude to change it then tested the fix manually. Claude Code diagnosed the cause, wrote the change and created this PR. I've reviewed the PR manually as well.

🤖 Generated with Claude Code

Windows 10 paints the title bar of a dark-mode window pure black while
it is active, which clashes with the app's warm dark gray. Apps can't
recolor it there: DWMWA_CAPTION_COLOR only exists on Windows 11.

Like VS Code and Chrome, the main window is now undecorated on Windows
and the frontend draws its own title bar. While active it is a shade
darker than the background; while inactive it matches the background,
with the title and buttons grayed out. tao keeps the native frame styles
on undecorated windows and only trims the caption, so resizing, Aero
Snap (cjpais#1778) and the minimize/maximize animations keep working.

The bar sits inside the window's inner size, so the window grows by the
bar's 32px to keep the content area the same. Top-level layouts, dialogs
and the onboarding preview button now start below the bar. Elsewhere
--titlebar-height is 0px and nothing changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
arshit09 added a commit to arshit09/Handy that referenced this pull request Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant