domferr / domferr/tilingshell

Bug: Snap Assistant appears too large at >100% display scaling on GNOME 50

Open Beginner friendly
#541 1 comment 4 reactions 0 assignees View on GitHub
bug next release
Dominant language
TypeScript
Stars
2k
Forks
116
PR merge metrics
No merged PRs in 30d

Description

## Summary

On GNOME 50, the Snap Assistant is rendered at incorrect (oversized) dimensions when display scaling is set above 100%. At 200% scaling it appears twice as large as intended; the degree of oversizing scales proportionally with the scaling factor.

## Steps to Reproduce

1. Set display scaling to 200% (or any value above 100%) in GNOME Settings → Displays
2. Enable Tiling Shell
3. Grab a window and drag it toward the top of the screen to trigger the Snap Assistant

**Screenshots**

![Image](https://github.com/user-attachments/assets/b5b02418-e232-48bb-8e18-447ef6d8d4c0)

**Information (please complete the following):**

- GNOME Shell: 50
- Extension version: 18.0 (compiled from GitHub)
- Display scaling: 200% (reproduced at other values above 100%)
- Session type: Wayland

## Additional context

I was able to fix this with Claude Code on my personal fork, but I won't PR the vibe coded fix here because I didn't write it. Here's a summary from Claude of the root cause and fix:

### Root Cause

The extension uses a manual widget dimension scaling system controlled by `_isFractionalScalingEnabled()`. When this returns `true`, manual scaling is disabled (correct for GNOME's logical-pixel coordinate system). When it returns `false`, widget dimensions are multiplied by the monitor scale factor.

`_isFractionalScalingEnabled()` detects fractional scaling by checking for `scale-monitor-framebuffer` in `org.gnome.mutter` `experimental-features`. In GNOME 50, fractional scaling graduated from experimental to stable and is **no longer listed in `experimental-features`**, so the check always returns `false`. Manual scaling is then applied even though the Clutter stage now uses logical pixel coordinates for all scale factors — resulting in widget dimensions being multiplied by the scale factor when they should not be.

### Fix

In `_isFractionalScalingEnabled()` (`src/extension.ts`), short-circuit to return `true` on GNOME 50+, since the old experimental-features check is no longer meaningful and the Clutter stage always uses logical pixel coordinates:

```typescript
private _isFractionalScalingEnabled(
_mutterSettings: Gio.Settings,
): boolean {
// In GNOME 50+, fractional scaling (scale-monitor-framebuffer) graduated
// from experimental to stable and is no longer listed in experimental-features.
// The Clutter stage now always uses logical pixel coordinates, so manual
// scaling of widget dimensions is never needed.
const GNOME_VERSION_MAJOR = Number(
Config.PACKAGE_VERSION.split('.')[0],
);
if (GNOME_VERSION_MAJOR >= 50) return true;

return (
_mutterSettings
.get_strv('experimental-features')
.find(
(feat) =>
feat === 'scale-monitor-framebuffer' ||
feat === 'x11-randr-fractional-scaling',
) !== undefined
);
}
```

This fix resolves the issue without affecting behaviour on GNOME 49 and earlier.

### Notes

- The same manual scaling system is used in several other components (window border, layout switcher, window menu, editor). These may have similar issues on GNOME 50 that have not been fully investigated.
- A longer-term fix would be to audit and remove the manual scaling system entirely for GNOME 50+, since the Clutter stage coordinate system no longer requires it.

Contributor guide

Open the contributing guide

Research direction

Start in src/extension.ts at _isFractionalScalingEnabled() and inspect how its result controls manual widget dimension scaling. Reproduce the Snap Assistant at 200% scaling on GNOME 50, then verify that the oversized rendering is corrected without changing behavior on GNOME 49 and earlier; consider the noted scaling uses in the window border, layout switcher, window menu, and editor.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
desktop, operating-systems
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.