Skip to content

Add GTK-themed client-side decoration for Wayland without xdg-decoration#4178

Open
pdecarvalhogomes wants to merge 1 commit into
chromiumembedded:masterfrom
pdecarvalhogomes:fix_wayland_window_decoration
Open

Add GTK-themed client-side decoration for Wayland without xdg-decoration#4178
pdecarvalhogomes wants to merge 1 commit into
chromiumembedded:masterfrom
pdecarvalhogomes:fix_wayland_window_decoration

Conversation

@pdecarvalhogomes

@pdecarvalhogomes pdecarvalhogomes commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add LinuxFrameView using GTK WindowFrameProvider for native CSD borders, shadows, and caption buttons, replacing the blue DefaultFrameView
  • Set window opacity to kTranslucent when GTK frame provider is available so Wayland renders shadows with alpha instead of opaque black
  • Override GetCustomInsetsInDIP in both ChromeBrowserWidget (Chrome style) and CefWidgetImpl (Alloy style) to report frame border insets to the Wayland compositor via xdg_surface.set_window_geometry

How to test

  1. Build the branch above following the instructions here. Additionally, pass rtc_use_pipewire=true when exporting GN_DEFINES.  A few packages are required to build it. Here's a list for Ubuntu:
sudo apt update && sudo apt install -y \
  build-essential pkg-config git python3 weston libglib2.0-dev libdbus-1-dev libpango1.0-dev \
  libgtk-3-dev libgbm-dev mesa-common-dev  libgl1-mesa-dev libegl1-mesa-dev \
  libgles2-mesa-dev libpulse-dev libnss3-dev libx11-dev libxcomposite-dev libxcursor-dev \
  libxdamage-dev libxext-dev libxfixes-dev  libxi-dev libxrandr-dev libxrender-dev \
  libxss-dev libxtst-dev libasound2-dev libatk1.0-dev libatk-bridge2.0-dev libcups2-dev libdrm-dev
  1. Start a Weston composer:
weston --socket=wayland-1
  1. Run cefclient pointing to Weston's socket
WAYLAND_DISPLAY=wayland-1 $YOUR_LOCAL_CEF/chromium_git/chromium/src/out/Debug_GN_x64/cefclient --enable-features=UseOzonePlatform --ozone-platform=wayland --use-native --use-views --
enable-chrome-runtime --no-sandbox

The result should be similar to the following
cefclient_weston_gtk_decoration

…tion

- Add LinuxFrameView using GTK WindowFrameProvider for native CSD
  borders, shadows, and caption buttons, replacing the blue DefaultFrameView
- Set window opacity to kTranslucent when GTK frame provider is available
  so Wayland renders shadows with alpha instead of opaque black
- Override GetCustomInsetsInDIP in both ChromeBrowserWidget (Chrome style)
  and CefWidgetImpl (Alloy style) to report frame border insets to the
  Wayland compositor via xdg_surface.set_window_geometry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@magreenblatt

Copy link
Copy Markdown
Collaborator

Review Comments

Main concern: this reimplements what Chromium already provides. Currently CefWindowView::CreateFrameView returns nullptr for the non-frameless, non-native-frame case, which falls through to DesktopWindowTreeHostLinux::CreateFrameView(). That already creates NativeFrameViewLinux (GTK nav buttons + frame provider) or FrameViewLinux (vector icon caption buttons), with proper shadow/border/Wayland inset handling via FrameViewLayoutLinux. The 522-line LinuxFrameView reimplements all of this — layout, painting, hit testing, button caching — from scratch. If the existing fallback path isn't working for CEF, the fix should diagnose why and address that, not rewrite the frame view.

Additional issues:

  1. Stale API signatures. Calls CreateNavButtonProvider() (no args) and GetWindowFrameProvider(solid_frame, tiled, maximized) (3 args), but current Chromium requires CreateNavButtonProvider(FrameType type) and GetWindowFrameProvider(FrameType type, bool solid_frame, bool tiled, bool maximized). This won't compile against current Chromium.

  2. GetCustomInsetsInDIP may conflict with upstream. DesktopWindowTreeHostLinux already handles decoration insets via UpdateFrameHints() when using FrameViewLinux. The new overrides in ChromeBrowserWidget and CefWidgetImpl may double-report.

  3. Hardcoded kCaptionButtonHeightWithPadding = 19. Upstream FrameViewLayoutLinux sizes this dynamically based on actual button layout. This will look wrong at different DPI scales or GTK themes.

  4. Tiled state is hardcoded to false in GetFrameProvider(), so snapped/tiled windows get the wrong frame provider. Upstream tracks this via SetTiled() callbacks.

  5. Include ordering — the new #if BUILDFLAG(IS_LINUX) block in window_view.cc is inserted between non-conditional includes, violating Chromium include ordering conventions.

Recommendation: Investigate why the existing DesktopWindowTreeHostLinux::CreateFrameView() fallback doesn't produce correct CSD for CEF framed windows, and fix that specific issue rather than reimplementing frame rendering.

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.

2 participants