Skip to content

I fixed your godawful touch controls - #7697

Closed
ifilipis wants to merge 1 commit into
utmapp:mainfrom
ifilipis:v5.0.2
Closed

ifilipis wants to merge 1 commit into
utmapp:mainfrom
ifilipis:v5.0.2

Conversation

@ifilipis

@ifilipis ifilipis commented May 1, 2026

Copy link
Copy Markdown

It's a complete rewrite of everything, but I did also preserve some old code for the time being

Let's start with issues:

  • Old system had conflicts all over the place. Scroll would trigger pinch and taps all the time
  • Gesture types were very limited
  • Some recognizers were super flawed, like scroll that would only trigger if you drag it across half the screen
  • I also discovered a few undocumented and unconfigurable gestures

At the times it was so bad that I just gave up and switched to Microsoft Remote Desktop, and a lot of gestures are inspired by it. They are quite typical to Microsoft tablets as well.

The list of changes is massive

  • Old Touch mode conserved, new Multitouch mode added
  • Tap / click still works the same way!
  • 1 finger drag now does scroll and does not trigger erroneous clicks
  • Added long press with default right click. Also added a visual indicator for when it is triggered.
  • Added long press + drag for left clicking and dragging
  • 2 finger tap now uses the location of first touch for mouse position. Much easier to aim this way
  • 2 finger drag resolved conflicts with everything else and MUCH improved recognition. There's no more delay at all - it triggers instantly
  • 2 finger swipe is also resolved correctly now and is fine-tunable. It took a lot of code to distinguish it from 2F drag
  • 2 finger pinch also has a new resolver based on absolute finger travel instead of percentage to avoid erroneous triggers. This is what fixed it
  • It is also 2 fingers only now. You can't do pinch with 3 or more fingers anymore
  • Same set of fixes for 3 finger gestures + exposed 3 finger swipe in settings
  • All gestures now persist! You can't trigger different gestures after any recognizer has fired.
  • Added new types of mouse events, too. Middle drag, right drag, left drag + clicks
  • Fixed a bug with gestures near the edges of the screen. There was a border where they were blocked, I even thought there's something wrong with my iPad
  • I also played with defaults a bit. They are set to what MS RDP does at the moment
  • Nothing in the driver was changed. All fixes are in the UI

Hoping to see it in the upcoming release, because otherwise, the UX is horrible and made me dust off a MacBook, install macOS updates and Xcode for this sole purpose

@osy

osy commented May 1, 2026

Copy link
Copy Markdown
Contributor

Please confirm you have read and followed all of the contribution guidelines: https://github.com/utmapp/UTM/blob/main/CONTRIBUTING.md

@keesverruijt

Copy link
Copy Markdown

@ifilipis your PR might the most wonderful PR ever, but why the attitude? Can't you keep it civil please? Some modesty, kindness and politeness goes a long way.

@GBirkel

GBirkel commented Jun 5, 2026

Copy link
Copy Markdown

Calling software godawful and UX horrible is certainly harsh and a disservice to the effort of the authors, but I don't know if it crosses the line into uncivil... When UX has deep flaws, the frustration it causes can be really intense. :D

But it's moot. By the end of this year it's likely that every PR summary we read, everywhere on this site, will be auto-generated by LLM, and they will all sound the same, and we will not be reading words that came out of actual humans in PRs ever again. Indicators of politeness and positive attitude will become so ubiquitous they will stop having their intended effect and instead become useless bulk in the language and in due time they will be also scraped out, and PRs will consist entirely of terse bulleted lists (which is what this PR description mostly is, coincidentally)

End of an era, folks!

@ifilipis

ifilipis commented Jun 5, 2026

Copy link
Copy Markdown
Author

@GBirkel Thank you for calling my hand-written list AI-generated. Your paranoia is definitely accurate. And honestly? Enjoy the godawful UX, too!

@keesverruijt

Copy link
Copy Markdown

@ifilipis You need to learn to read more carefully. @GBirkel was actually defending you somewhat IMO. He did certainly not suggest that you used AI. He suggested that soon everyone will use AI for all PRs. I don't agree with him, human only texts may become rare voices but I don't think everything will be AI, unless Github gives them an extra leg up like "PRs only allowed by AIs that follow the submission rules of the repository."

@Ickerday

Ickerday commented Jul 6, 2026

Copy link
Copy Markdown

So @ifilipis backs down with the attitude, adjusts the PR title and description, someone reviews the code and we all win, right?

@osy

osy commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

@Ickerday no as I've stated above

Please confirm you have read and followed all of the contribution guidelines: https://github.com/utmapp/UTM/blob/main/CONTRIBUTING.md

There's nothing about attitude or PR title there. I don't care if you're an arsehole as long as you can follow instructions.

@osy

osy commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Superseded by #7893.

The list of problems in this PR's description was useful: most of them were real, and #7893 goes through all twenty points one by one and says what was done about each. The changes here can't be merged as they are, though, because they don't follow the contribution guidelines:

  • It is a single 900-line commit covering many unrelated fixes and features, where the guidelines ask for one well-defined change per PR and commits titled component: short description that explain why.
  • Despite "Old Touch mode conserved", it changes behaviour for existing users: pinch to zoom and the three finger keyboard swipe are gated behind new settings that default to Disabled, the two finger "Mouse Wheel (per swipe)" stops working in the old modes, and several gesture defaults are changed for everyone who never opened Settings.
  • It adds four new settings, against "prefer simplicity over options".
  • There is no record of the required testing (device and OS version, and for bug fixes reproducing the bug before and confirming the fix after), and the confirmation requested above was never given.

#7893 is a rewrite that follows the guidelines and does the required testing: one commit per issue, each reproduced and verified before and after on iOS 17, 18, 26 and 27 simulators, then tested on a device. It also fixes some latent bugs that this PR worked around or didn't cover (the long press waiting on the tap recognizer in every mode, every pan waiting up to half a second on the keyboard swipes, a cancelled drag leaving the button held down in the guest, the pinch taking three finger gestures on iOS 17, and double tap in the new mode), and the code is considerably smaller: two pieces of state instead of about thirty, the existing touch modes left untouched, and the public SwiftUI modifier for edge gestures instead of patching UIViewController.

Thank you for identifying these issues. Closing in favour of #7893.

@osy osy closed this Sep 20, 2026
changanmoon pushed a commit to changanmoon/UTM that referenced this pull request Sep 21, 2026
The long press recognizer required the tap recognizers to fail first. A
tap only fails once the finger has been held for well over a second, so
a normal long press was delivered as a tap when the finger lifted: the
"Right Click" action produced a left click (or nothing in touch mode)
and "Click & Hold" never pressed the button.

Reverse the dependency so the tap waits for the long press, which fails
as soon as a short touch ends and so adds no delay to taps. When the
long press action is disabled the recognizer is not allowed to begin,
otherwise holding before lifting would no longer click.

Reworked from utmapp#7697.

Assisted-by: Claude:claude-fable-5-1
changanmoon pushed a commit to changanmoon/UTM that referenced this pull request Sep 21, 2026
Every pan and the pinch required the three finger keyboard swipes to
fail first, and a swipe recognizer only fails once the touch has moved
far enough to be judged or after about half a second. Moving the cursor
with one finger, scrolling with two or pinching therefore did nothing
for a quarter to half a second, and a short or slow two finger scroll
was mostly lost.

A swipe can only be confused with a pan that uses the same number of
touches, so only the three finger pan still waits for the keyboard
swipes. The pinch needs a guard instead: before iOS 18 it begins with
two of three fingers and would take the touches from the swipe, so it is
not allowed to begin while three fingers are down. That also stops three
fingers from zooming the display on those versions.

The two finger pan still waits for the two finger swipe when the two are
bound to different actions. When both scroll the mouse wheel there is
nothing to tell apart: the pan scrolls right away and a swipe adds its
wheel tick on top, where before any steady two finger drag was taken for
a swipe and scrolled a single tick. Because the two now scroll together,
the swipe follows the "Invert Scroll" setting like the pan.

Reworked from utmapp#7697.

Assisted-by: Claude:claude-fable-5-1
changanmoon pushed a commit to changanmoon/UTM that referenced this pull request Sep 21, 2026
A touch that starts at the top or bottom edge of the screen is held
back by the system in case it turns into a system gesture. A drag from
the top edge of the VM display pulled down Notification Center and the
guest never saw the touch at all.

Ask the system to defer its edge gestures while the VM display is up,
next to where the home indicator is already hidden, so the first swipe
goes to the guest and only a second one is taken by the system. This
uses the SwiftUI modifier, which needs iOS 16. Overriding the view
controller preference instead needs the hosting controller patched to
forward it, and was ignored on iOS 17.

On iOS 18 and later a swipe up from the bottom edge still goes home,
because the system ignores the deferral there while the home indicator
is hidden. Touches at the bottom edge do reach the guest immediately.

Reworked from utmapp#7697.

Assisted-by: Claude:claude-fable-5-1
changanmoon pushed a commit to changanmoon/UTM that referenced this pull request Sep 21, 2026
Touch gestures could only produce a left drag and a right click, so a
guest that needs the middle button (paste or pan in many Linux and CAD
programs) or a right button drag could not be used without a mouse.

Add "Middle Click" to the long press and two finger tap actions, and
"Right Click & Hold" and "Middle Click & Hold" to the two and three
finger pan actions. These are new values for existing settings and the
defaults are unchanged.

Reworked from utmapp#7697.

Assisted-by: Claude:claude-fable-5-1
changanmoon pushed a commit to changanmoon/UTM that referenced this pull request Sep 21, 2026
In the touch modes the left button goes down the moment a finger lands,
because the touch itself is the drag. Every other gesture starts with a
finger landing too, so a two finger tap, scroll or pinch first clicked
and dragged whatever was under the first finger until the gesture was
recognized, and a long press held the left button for half a second
before its right click.

Add "Touch mode (drag to scroll)" as a third touch mode that behaves
like a touch screen and never presses a button on touch down. A tap is
a left click, a long press runs the long press action, and dragging one
finger scrolls the mouse wheel so that the content follows the finger.
Since a touch no longer drags, a long press that moves turns into a left
button drag so windows and selections can still be moved with one
finger. A ring is shown when the long press is recognized because
nothing in the guest reacts until the finger lifts.

A finger never lands on the same spot twice, and a guest only counts two
clicks on the same spot as a double click, so a second tap that follows
quickly and close by clicks where the first one did.

The existing touch modes are unchanged.

Reworked from utmapp#7697.

Assisted-by: Claude:claude-fable-5-1
changanmoon pushed a commit to changanmoon/UTM that referenced this pull request Sep 21, 2026
A gesture that holds a mouse button only released it when the gesture
ended. When the system takes over the touch instead, for example a long
press drag that starts at the bottom edge and turns into the swipe to go
home, the gesture is cancelled and the guest was left with the button
held down until the next click.

Reworked from utmapp#7697.

Assisted-by: Claude:claude-fable-5-1
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.

5 participants