OpenRCT2 / OpenRCT2/OpenRCT2

Edge Scrolling Breaks Under Wayland Scaling + sdl2-compat

Open
#26,645 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C++
Stars
16.2k
Forks
1.9k
Avg merge
1d 20h
Merged PRs (30d)
80

Description

Operating System

NixOS 26.05 (with KDE Plasma DE)

OpenRCT2 build

OpenRCT2 0.5.1, both from nixpkgs and official AppImage builds

Base game

RollerCoaster Tycoon 2, RollerCoaster Tycoon Classic

Area(s) with this issue?

This is a development issue

Describe the issue

I noticed that the edge scrolling feature wasn't correctly working for me. When I have the window scale factor at 1.0, neither scrolling down or right works by putting the mouse at the edge of the screen. At higher window scale factors, these two directions don't work consistently (eg. at 1.25, right works and down doesn't, while at 1.50, down works and right doesn't). After some troubleshooting, I've identified the issue occurs when using display scaling in Plasma (and presumably other DE's including GNOME) using Wayland to scale the display above 100% and SDL3 + sdl2-compat for the game's SDL2 requirement.

This is potentially related to #23644, but I can't be sure due to the limited information in that report.

Cause of the Problem

I've identified that this issue traces back to how Wayland handles scaling, and the interactions that result with SDL3 and sdl2-compat. When using Wayland, the DE reports the cursor position to applications relative to an "unscaled" resolution. So, for example, if the mouse is at (100, 100) raw pixels, and the display scaling is set to 1.5, then the mouse position will be reported to the application as (75, 75). This is largely due to how Wayland handles compatibility with applications that don't support scaling. SDL3 recognizes this situation, and multiplies the coordinates by the display scaling factor to compensate.

SDL3 defaults to using Wayland, and supports fractional scaling (such as 1.5) like this, which it handled by changing the argument types for SDL_GetMouseState from int * in SDL2 to float * in SDL3. This means that the mouse position can be reported in fractional pixels if display scaling is used. For sdl2-compat, these float values have to be converted to integers, which is done with a basic cast, which results in the value being rounded down. Together, this results in the largest possible x /y position being 2 (or more) less than the width / height of the window, which breaks the edge detection.

Solution

The direct solution requires updating OpenRCT2 to use SDL3 directly. Once OpenRCT2 is using SDL3, we can take the float coordinates from SDL_GetMouseState exactly, and compare them to the width / height minus SDL_GetDisplayContentScale(). This should accurate get the max values for the cursor position, and resolve this issue.

In the meantime, there's potentially a workaround with the current SDL2 code. This issue should be specific to Wayland, so getting the game to use X11 / XWayland, either with environment variables or using SDL2 directly, should be able to fix this. (I tried running the game with SDL_VIDEODRIVER=x11, and it didn't fix the issue for me with sdl2-compat, so either it wasn't properly using XWayland, or XWayland has a similar issue under SDL3).

Steps to reproduce

I've personally tested playing in both fullscreen and fullscreen (borderless window) using KDE Plasma using Wayland with display scaling 150% and 200% on a monitor with a resolution of 2256x1504, but this issue should only depend on using Wayland and display scaling > 100%.

  1. Set Display Scaling in your DE setting to >100%
  2. Launch OpenRCT2
  3. Select either "Fullscreen" or "Fullscreen (borderless window)" (seems like, at least on my machine, the cursor can still report its position to the game when just past the window, which bypasses this issue)
  4. (preferably) set window scale factor to 1.00 (to make it consistent)
  5. Enable "Scroll view when pointer at screen edge"
  6. Load a park (or start a new one)
  7. Note that you can scroll up and left by edge scrolling, but not down or right.
Attachments

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

First reproduce the issue using Wayland display scaling above 100%, fullscreen or borderless mode, and edge scrolling enabled. Trace the edge-scrolling input path around SDL_GetMouseState and compare its coordinates with the window bounds and SDL_GetDisplayContentScale(). Done means down and right edge scrolling work reliably at fractional and whole display scales.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop, game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
43/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.