Skip to content

fix(v3,linux): enable frameless resize edge detection on Linux (#4680)#5366

Open
leaanthony wants to merge 2 commits intomasterfrom
fix/frameless-resize-scrollbar-linux
Open

fix(v3,linux): enable frameless resize edge detection on Linux (#4680)#5366
leaanthony wants to merge 2 commits intomasterfrom
fix/frameless-resize-scrollbar-linux

Conversation

@leaanthony
Copy link
Copy Markdown
Member

@leaanthony leaanthony commented May 8, 2026

Summary

Fixes #4680 — frameless window resize blocked by scrollbar at window edges on Linux.

Root cause: drag.ts's onMouseMove() had a !IsWindows() guard that completely disabled JavaScript resize-edge detection on non-Windows platforms. On Linux, frameless windows have no WM-managed resize handles; the only resize path is:

  1. JS detects mouse near window edge → sets resizeEdge
  2. On mousedown in resize zone → canResize = true
  3. On first mousemove → invoke("wails:resize:<edge>") → Go calls gtk_window_begin_resize_drag()

With the guard in place, resizeEdge was never set on Linux, so invoke("wails:resize:...") was never called and the entire resize mechanism was dead. A DOM scrollbar at the window edge made this obvious: users reaching for the resize handle found the scrollbar area completely unresponsive to resize.

Fix: Change the guard from !IsWindows() to !IsWindows() && !IsLinux():

// Before
if (!resizable || !IsWindows()) {

// After  
if (!resizable || (!IsWindows() && !IsLinux())) {

macOS is unchanged — it was and remains excluded from JavaScript edge detection, relying on WM/native behaviour.

Why it was Windows-only originally: The GTK startResize() backend was a no-op stub until PR #5159 wired up gtk_window_begin_resize_drag() / gdk_toplevel_begin_resize(). There was no point detecting edges if the backend couldn't act on them. Now that both GTK3 and GTK4 backends are connected, enabling the JS detection side completes the fix.

Scrollbar interaction: The event listeners use { capture: true }, so the resize handler's mousemove fires in the capture phase before any scrollbar element can consume it. clientX/clientY coordinates remain viewport-relative regardless of which DOM element is under the cursor, so the edge detection arithmetic is correct even when the mouse is over a DOM scrollbar.

Changed files

File Change
v3/internal/runtime/desktop/@wailsio/runtime/src/drag.ts Add IsLinux to import; change !IsWindows()!IsWindows() && !IsLinux()
v3/internal/assetserver/bundledassets/runtime.debug.js Rebuilt from source
v3/internal/assetserver/bundledassets/runtime.js Rebuilt from source

Test plan

  • Frameless window with scrollable content on Linux: hover over right/bottom edge — resize cursor appears
  • Click-drag from right/bottom edge — window resizes correctly
  • Hover over DOM scrollbar sitting at the right edge — resize cursor appears and resize works
  • Windows: no regression in frameless resize behaviour
  • macOS: no regression in frameless resize behaviour
  • Non-resizable frameless window: resize cursor does NOT appear

Distro tested: Ubuntu 24.04 LTS, GTK 3.24, webkit2gtk-4.0
Wails version: master

🤖 Generated with Claude Code

CC @leaanthony

Summary by CodeRabbit

  • New Features

    • Window resize and drag now work on Linux (matching Windows behavior).
    • Resizable state is mirrored to the web layer so UI reflects native resize changes.
  • Refactor

    • Regenerated Wails runtime bridge bundle with internal improvements while preserving the public API and existing behaviors.

The resize border detection in drag.ts was gated behind !IsWindows(),
which silently disabled JavaScript edge detection on Linux (and macOS).
On Linux, frameless windows have no WM-managed resize handles, so the
JavaScript path — detect edge → invoke("wails:resize:<edge>") → GTK's
gtk_window_begin_resize_drag() — is the only mechanism available.

When a DOM scrollbar sits at the window's right or bottom edge, the
mouse never leaves the WebView viewport, so clientX/clientY coordinates
are still correct. The capture-phase mousemove listener fires first,
detects the resize zone, and sets resizeEdge. Without this fix, though,
the !IsWindows() guard drops the event and resizeEdge stays empty,
making resize unresponsive regardless of the scrollbar.

Change the guard to !IsWindows() && !IsLinux() so Linux follows the same
JavaScript edge-detection path as Windows, while macOS keeps its current
(native-WM) behaviour unchanged.

Also rebuild runtime.js and runtime.debug.js from the updated source.

Fixes #4680.

CC @leaanthony

Co-authored-by: multica-agent <github@multica.ai>
Copilot AI review requested due to automatic review settings May 8, 2026 02:26
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9c18c0fe-54d8-4e01-bbb7-c0d7c4e2eb9a

📥 Commits

Reviewing files that changed from the base of the PR and between add7238 and b836eb9.

📒 Files selected for processing (2)
  • v3/pkg/application/linux_cgo.go
  • v3/pkg/application/linux_cgo_gtk4.go
✅ Files skipped from review due to trivial changes (1)
  • v3/pkg/application/linux_cgo.go

Hidden review stack artifact

Walkthrough

This PR widens the drag runtime platform guard to allow frameless-window resize on Linux (in addition to Windows), makes Linux backend setResizable calls forward the resizable boolean to the frontend via window._wails.setResizable(...), and regenerates the bundled minified runtime to reflect the updated wiring while keeping the same public exports.

Changes

Linux Resize Support

Layer / File(s) Summary
Platform Gate Update
v3/internal/runtime/desktop/@wailsio/runtime/src/drag.ts
Imports expanded to include IsLinux; resize-initiation OS guard changed from Windows-only to Windows-or-Linux.
Backend: setResizable → frontend
v3/pkg/application/linux_cgo.go, v3/pkg/application/linux_cgo_gtk4.go
linuxWebviewWindow.setResizable now calls w.execJS("window._wails.setResizable(resizable)") in addition to existing GTK resizable handling.
Bundled Runtime Artifact
v3/internal/assetserver/bundledassets/runtime.js
Entire minified bundle regenerated with updated internal symbol bindings for drag/resize, file-drop, context-menu, transport, and cancellable promise machinery; public exports preserved.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • wailsapp/wails#5159: Implements native Linux startResize backend corresponding to this JS-side drag runtime change.
  • wailsapp/wails#4616: Updates file-drop handler wiring in the same runtime bundle.
  • wailsapp/wails#4953: Updates Go call site for the window._wails.handlePlatformFileDrop bridge.

Suggested labels

Bug, runtime, Linux, v3, size:M

Poem

🐰 A hop across the Linux plains,
Resize now flows through Tux's veins,
Backend whispers to the page,
Bundled scripts renew their stage,
Now windows stretch at rabbit's pace.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description comprehensively covers the issue, root cause, fix details, changed files, and test plan. However, the required PR template checklist items are not filled out (Type of change, Testing, Test Configuration, and Checklist sections lack selections/confirmation). Complete the template checklist by selecting the change type, confirming test coverage across platforms, providing wails doctor output or environment details, and checking off all applicability boxes.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main fix: enabling frameless resize edge detection on Linux. It directly corresponds to the primary change in the changeset.
Linked Issues check ✅ Passed The PR directly addresses issue #4680 by enabling JS resize-edge detection on Linux through guard condition changes and propagating setResizable to the JS runtime, fully meeting the objective of allowing frameless window resizing when a scrollbar is at window edges.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to fixing the frameless resize issue: drag.ts guard updates for Linux, Linux backend propagation of setResizable state, and rebuilding bundled JS assets. No unrelated or extraneous changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/frameless-resize-scrollbar-linux

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.1)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Enables the v3 desktop runtime’s JavaScript resize-edge detection on Linux so frameless windows can initiate native GTK resize drags when the pointer is near the window edge (e.g., even when hovering a DOM scrollbar at the edge).

Changes:

  • Update drag.ts to allow resize-edge detection on Linux (previously Windows-only).
  • Rebuild the bundled runtime assets (runtime.js / runtime.debug.js) to include the updated logic.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
v3/internal/runtime/desktop/@wailsio/runtime/src/drag.ts Allows edge detection to run on Linux by extending the OS guard to permit Linux.
v3/internal/assetserver/bundledassets/runtime.debug.js Rebuilt debug bundle to include the Linux-enabled edge detection logic.
v3/internal/assetserver/bundledassets/runtime.js Rebuilt production/minified bundle to include the Linux-enabled edge detection logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +224 to 226
if (!resizable || (!IsWindows() && !IsLinux())) {
if (resizeEdge) { setResize(); }
return;
The Linux setResizable implementation only called gtk_window_set_resizable
but never notified the JS side via window._wails.setResizable(). This left
the drag.ts `resizable` flag permanently false on Linux, causing the
!resizable guard in onMouseMove to always short-circuit before edge
detection could run — making the frameless resize fix in this PR a no-op.

Apply the same execJS call that the Windows backend already uses. The call
is dispatched asynchronously after wails:runtime:ready fires the
SetResizable init, so window._wails.setResizable is guaranteed to exist
when the JS runs.

Both GTK3 (linux_cgo.go) and GTK4 (linux_cgo_gtk4.go) paths fixed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
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.

[v3] Frameless Window Cannot Resize When Scrollbar is at the Window Edges

3 participants