Skip to content

fix: Linux Wayland 改用应用级自定义标题栏,绕过 GTK CSD 点击无响应问题#531

Merged
H-Chris233 merged 2 commits into
Open-Less:betafrom
aeoform:feat/linux-custom-titlebar
May 26, 2026
Merged

fix: Linux Wayland 改用应用级自定义标题栏,绕过 GTK CSD 点击无响应问题#531
H-Chris233 merged 2 commits into
Open-Less:betafrom
aeoform:feat/linux-custom-titlebar

Conversation

@aeoform
Copy link
Copy Markdown
Contributor

@aeoform aeoform commented May 25, 2026

User description

Summary

  • KDE/Wayland 下 GTK CSD 标题栏按钮无法响应点击(tao#1218, tauri#9394),WebKit 环境变量 + nudge resize 均不能可靠修复
  • 参考 cc-switch 方案,设置 decorations: false + transparent: true,用 React 组件绘制应用级标题栏
  • 36px 拖拽栏 + 最小化/最大化/关闭三键,通过 @tauri-apps/api/windowgetCurrentWindow() 控制窗口
  • 同时保留 WEBKIT_DISABLE_COMPOSITING_MODE / DMABUF_RENDERER 环境变量和 async nudge 作为辅助修复

Changes

File Change
tauri.linux.conf.json 主窗口 decorations: false + transparent: true
WindowChrome.tsx 新增 LinuxTitlebar 组件(动态 import Tauri API + 内联 SVG 图标)
main.rs WebKit 合成模式环境变量(GTK 初始化前设置)
lib.rs async nudge(set_focus + ±1px resize)辅助修复 webview surface 输入区域

Test plan

  • KDE Wayland 下窗口控制按钮可点击(最小化/最大化/关闭)
  • 拖拽标题栏可移动窗口
  • 双击标题栏切换最大化/还原
  • macOS/Windows 不受影响(OS 条件渲染隔离)

🤖 Generated with Claude Code


PR Type

Bug fix, Enhancement


Description

  • Add Linux custom titlebar controls

  • Disable GTK decorations on Wayland

  • Set WebKit Linux compatibility env vars

  • Nudge WebView after initial show


Diagram Walkthrough

flowchart LR
  cfg["tauri.linux.conf.json window config"] -- "decorations:false, transparent:true" --> chrome["WindowChrome.tsx LinuxTitlebar UI"]
  chrome -- "window controls and state sync" --> tauri["Tauri window API"]
  main["main.rs WebKit env vars"] -- "compositing compatibility" --> webkit["WebKitGTK"]
  lib["`lib.rs` post-show nudge" -- "focus + ±1px resize" --> webview["Webview input region"]
Loading

File Walkthrough

Relevant files
Bug fix
lib.rs
Add Linux post-show window nudge                                                 

openless-all/app/src-tauri/src/lib.rs

  • Adds a Linux-only workaround after main.show()
  • Forces focus and a small resize cycle
  • Reconciles the window size after the nudge
  • Avoids overwriting real user or compositor resizes
+41/-2   
Configuration changes
main.rs
Set Linux WebKit compatibility variables                                 

openless-all/app/src-tauri/src/main.rs

  • Sets WEBKIT_DISABLE_DMABUF_RENDERER=1 on Linux
  • Sets WEBKIT_DISABLE_COMPOSITING_MODE=1 on Linux
  • Preserves existing values when already configured
  • Applies the workaround before app startup
+15/-0   
tauri.linux.conf.json
Switch Linux window to frameless mode                                       

openless-all/app/src-tauri/tauri.linux.conf.json

  • Disables native window decorations on Linux
  • Enables transparency for the custom shell
  • Keeps the main window hidden at startup
+2/-2     
Enhancement
WindowChrome.tsx
Add Linux custom window titlebar                                                 

openless-all/app/src/components/WindowChrome.tsx

  • Adds a Linux-only draggable titlebar
  • Implements minimize, maximize, restore, and close actions
  • Syncs maximize state from tauri://resize
  • Uses inline SVG icons and hover styling
+155/-9 

KDE/Wayland 下 GTK Client-Side Decorations 的 minimize/maximize/close
按钮无法响应鼠标事件(tao#1218, tauri#9394)。此前尝试的 WebKit 环境变量 +
async nudge resize 均不能可靠修复,最终方案参考 cc-switch,完全放弃系统装饰:

- decorations: false → 应用级 WindowChrome 绘制 36px 拖拽栏 + 三键窗口控制
- transparent: true → 配合 CSS 磨砂玻璃背景
- WEBKIT_DISABLE_COMPOSITING_MODE + DMABUF_RENDERER 兜底 WebKit 合成异常
- async nudge(set_focus + ±1px resize)保留为辅助修复,防止 show() 后
  webview surface 输入区域未初始化

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

PR Reviewer Guide 🔍

(Review updated until commit a4705fa)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Click handling

The Linux titlebar is marked as a drag region, but the control buttons are not opted out of dragging. In Tauri, that can cause clicks on minimize/maximize/close to start a window drag instead of firing the button handler, especially on Wayland where drag regions are handled natively.

<div
  data-tauri-drag-region
  style={{
    height: LINUX_TITLEBAR_HEIGHT,
    flexShrink: 0,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    padding: '0 6px 0 14px',
    background: 'rgba(245,245,247,0.85)',
    backdropFilter: 'blur(12px) saturate(180%)',
    WebkitBackdropFilter: 'blur(12px) saturate(180%)',
    borderBottom: '0.5px solid rgba(0,0,0,0.08)',
    color: 'var(--ol-ink-3)',
    fontSize: 13,
    fontWeight: 500,
    cursor: 'default',
    userSelect: 'none',
    zIndex: 50,
  }}
>
  <span style={{ color: 'var(--ol-ink-2)' }}>OpenLess</span>
  <div
    style={{ display: 'flex', gap: 4, pointerEvents: 'auto' }}
    onMouseDown={(e) => e.stopPropagation()}
  >
    <button onClick={onMinimize} aria-label="Minimize" style={ctrlBtn}>
      <MinimizeSvg />
    </button>
    <button onClick={onToggleMaximize} aria-label={maximized ? 'Restore' : 'Maximize'} style={ctrlBtn}>
      {maximized ? <RestoreSvg /> : <MaximizeSvg />}
    </button>
    <button
      onClick={onClose}
      aria-label="Close"
      className="ol-linux-close-btn"
      style={ctrlBtn}
    >
      <CloseSvg />
    </button>
  </div>
Missing Double-Click

The custom Linux titlebar does not handle double-clicks on the empty titlebar area, so the usual maximize/restore shortcut is lost after replacing the native decorations. Users who rely on double-clicking the titlebar will now get no response.

<div
  data-tauri-drag-region
  style={{
    height: LINUX_TITLEBAR_HEIGHT,
    flexShrink: 0,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    padding: '0 6px 0 14px',
    background: 'rgba(245,245,247,0.85)',
    backdropFilter: 'blur(12px) saturate(180%)',
    WebkitBackdropFilter: 'blur(12px) saturate(180%)',
    borderBottom: '0.5px solid rgba(0,0,0,0.08)',
    color: 'var(--ol-ink-3)',
    fontSize: 13,
    fontWeight: 500,
    cursor: 'default',
    userSelect: 'none',
    zIndex: 50,
  }}
>

- 最大化状态同步:mount 后监听 tauri://resize 事件,每次 resize 都重新查询
  isMaximized(),确保双击拖拽栏/键盘快捷键触发最大化时图标不脱节
- 按钮点击后 300ms 再次查询 isMaximized(),防止窗口管理器拒绝 toggle 时
  状态错误
- 启动 nudge drift check:只修正 ±1px 的 nudge 产物,不再覆盖用户/合成器
  的实质性窗口大小变化
- 还原误删的中文注释,移除冗余 closeBtn 常量,<style> 移到 WindowChrome
  层级避免每个 LinuxTitlebar 实例重复注入

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit a4705fa

@aeoform
Copy link
Copy Markdown
Contributor Author

aeoform commented May 25, 2026

经过我的测试,这两个问题不存在

@H-Chris233 H-Chris233 merged commit 4723863 into Open-Less:beta May 26, 2026
4 checks passed
@aeoform aeoform deleted the feat/linux-custom-titlebar branch May 27, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants