Skip to content

[Bug] Text blur after window resize on Wayland with gaps/positioning #1727

@atlasatakahraman

Description

@atlasatakahraman

[Bug] Text blur after window resize on Wayland with gaps/positioning

Description

WebKit2GTK text rendering becomes blurry after resizing a window on Wayland. The blur persists through page reloads and only disappears when the app is restarted at the new size. This issue is specific to Wayland and does not occur on X11.

Environment

  • OS: Linux (Hyprland on Wayland)
  • wry version: 0.55.1
  • webkit2gtk: 2.50.6 (GTK3-based)
  • gtk: 3.24.x
  • Tauri: 2.x

Reproduction Steps

  1. Create a Tauri app with decorations: false and transparent: true
  2. Launch the app floating/maximized on Wayland
  3. Tile the window using a tiling window manager with gaps (e.g., Hyprland with gaps_out)
  4. Observe text rendering quality

Expected: Sharp text matching the initially-launched-at-this-size render quality Actual: Text appears soft/blurry, as if antialiased with subpixel rendering disabled

Root Cause Analysis

Through extensive debugging, we identified the issue:

1. Size Mismatch Between Hyprland and WebKit

  • Hyprland reports window size: 2404x1334
  • WebKit reports (via window.innerHeight): 1034
  • Difference: 300 pixels

Debug logs:

[wry set_bounds] Raw bounds: Rect { ... size: Logical(LogicalSize { width: 2404.0, height: 1334.0 }) }
[wry set_bounds] After logical: x=0, y=0, width=2404, height=1334

But WebKit only renders at 1034 pixels height.

2. wry's set_bounds() Behavior on Wayland

The issue is in wry's webkitgtk/mod.rs around line 876-881:

if self.is_in_fixed_parent {
    self.webview.size_allocate(&gtk::Allocation::new(x, y, width, height));
}

Problem:

  • For standalone Tauri apps on Wayland, the container is GtkBox, not GtkFixed
  • Therefore is_in_fixed_parent = false
  • The size_allocate() call is skipped
  • WebKit is never actually resized to the new dimensions
  • Even though set_size_request() and queue_resize() are called, they're insufficient for GTK3 on Wayland

Result: WebKit stays at old size while Hyprland expects it at the new size.

3. GPU Compositor Places Tiles at Fractional Coordinates

With the size mismatch:

  1. WebKit's GPU compositor doesn't know the actual target size
  2. It places text rendering tiles at fractional pixel coordinates (e.g., 123.5px, 456.7px)
  3. During rendering, bilinear texture filtering samples these fractionally-positioned tiles
  4. Result: Visible blur in the compositor output (confirmed via grim screenshot)

Evidence

Screenshots via grim

  • Blurry state: Text rendered with soft edges, appears incorrectly antialiased
  • Sharp state: Same text crisp when app launched at that size
  • Solid geometry (borders, boxes) renders sharp — only text is blurry
  • This confirms it's font rendering, not GL texture scaling

Workarounds Tested (All Failed)

Workaround Result Notes
HardwareAccelerationPolicy::Never ✅ Sharp, 1-2 fps Software rendering only
HardwareAccelerationPolicy::Always ❌ Blurry GPU compositor still has issue
WEBKIT_DISABLE_COMPOSITING_MODE=1 ✅ Sharp, 1-2 fps Same as Never
WEBKIT_DISABLE_DMABUF_RENDERER=1 ❌ Blurry Doesn't fix GPU tile positioning
queue_resize() after set_size_request() ❌ Blurry GTK doesn't force WebKit recalc
Disabling Cairo antialiasing ❌ Blurry Blur isn't from AA mode
CSS text-rendering hints ❌ Blurry WebKit buffer already baked blur in

Conclusion: Only disabling GPU compositing helps, indicating the root cause is in WebKit's GPU compositor tile grid calculation.

Proposed Fix

Modify wry's set_bounds() in webkitgtk/mod.rs to handle Wayland properly:

Current code (incomplete for Wayland):

if self.is_in_fixed_parent {
    self.webview.size_allocate(&gtk::Allocation::new(x, y, width, height));
}

Proposed fix:

// For Wayland (GtkBox container), force size directly
if !self.is_in_fixed_parent {
    self.webview.set_size_request(width, height);
    self.webview.queue_resize();
    // May need additional GTK3 Wayland-specific calls to fully propagate size
}

// For X11 (GtkFixed parent), use size_allocate
if self.is_in_fixed_parent {
self.webview.size_allocate(&gtk::Allocation::new(x, y, width, height));
}

Note: This may not fully resolve the issue if GTK3 itself has limitations in Wayland buffer size propagation. A proper fix might require GTK4 support (see section below).

Root Cause: GTK3 Limitations

This is ultimately a GTK3 architectural limitation on Wayland:

  • GTK3: Limited Wayland buffer scaling support, no native fractional scaling
  • GTK4 (since 4.14): Proper Wayland buffer scaling, fractional-scale-v1 protocol support
  • webkit2gtk-4.0 (current): GTK3-based, inherits the limitation
  • webkit2gtk-4.1 (available): GTK4-based, would likely fix this issue entirely

The system has webkit2gtk-4.1 installed, but wry is locked to webkit2gtk 2.0.2 (GTK3). Upgrading would require:

  1. Updating all GTK dependencies to GTK4 versions
  2. Rewriting wry's entire GTK backend (GTK3 and GTK4 have breaking API changes)
  3. Testing and validation

This is a significant undertaking but would resolve Wayland blur issues comprehensively.

System Details

Display Setup:
  Monitor 1: DP-1
    - Resolution: 2560x1440
    - Position: 0x0
    - Scale: 1.00

Monitor 2: HDMI-A-1 (270° rotation)
- Resolution: 1920x1080 (rotated)
- Position: 1080x0
- Scale: 1.00
- Transform: 3 (270°)

Hyprland Configuration:
gaps_in: 10
gaps_out: 40

Tauri Window Config:
decorations: false
transparent: true
resizable: true
background: transparent (RGBA with alpha=0)

Additional Notes

  1. This issue does not occur when:

    • App is launched directly at the tiled size (sharp)
    • Using X11 instead of Wayland (sharp)
    • GPU compositing is disabled (sharp, but 1-2 fps unusable)
  2. The blur is not caused by:

    • Hyprland's compositor blur effect (tested with decoration:blur = false)
    • Hyprland's rounding shader (tested with decoration:rounding = 0)
    • Monitor scaling/fractional scaling (both monitors at 1.00 scale)
    • Antialiasing mode (Cairo antialiasing disabled - still blurry)
    • WebKit DPR (confirmed window.devicePixelRatio = 1 in both states)
  3. Related upstream issues:

    • GTK3 Wayland buffer scaling: https://gitlab.gnome.org/GNOME/gtk/-/issues/4345
    • Wayland fractional-scale-v1 protocol: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/47
    • Firefox Wayland fractional scaling: https://bugzilla.mozilla.org/show_bug.cgi?id=1767142

Written and diagnosed with Claude Haiku 4.5 and AtlasAta

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions