Page MenuHomePhabricator

In iOS Safari, buttons must be tapped twice to fire.
Closed, ResolvedPublic

Description

It appears that the first tap on a button in a diff, such as "Hide comment" or "Reply" in Safari in iOS, only "selects" the button and shows its tooltip. It takes another tap to actually make the button activate. Since the buttons are fairly small on a mobile device, this second tap can be easy to miss.

Furthermore, double tapping right away does not work. One has to wait for the tooltip to show up. If one taps too soon, the tooltip won't show up at all and the process has to be restarted. The only way to activate the button is to tap, wait patiently for the tooltip, and then tap again.

I'm not sure if this is a bug or a feature (maybe someone is really keen to showcase these tooltips), but it is unexpected and could frustrate a buddhist monk. The button is small, pinch to zoom is disabled and the button refuses to be hurried in any way and angrily punishes any undue urgency by not working at all.

Steps to reproduce:

  1. Open a diff in iOS Safari.
  2. Tap "Hide comment" once only, or many times quickly.

Expected result:

Comment hides.

Actual result:

Tooltip shows for single tap, nothing happens at all for double tap. Only tap, wait, tap, with precision, works.


iOS 9.2 on iPad
phabricator 864d3984ebdb42b9a2670103ca3607342e46b7dc (Sat, Jan 23)
arcanist 2412c31346add8be2a6acf18ebf812632b678f41 (Fri, Jan 15)
phutil 9c472e7c9b64395424c6cd25734bf239cb3c113d (Sat, Jan 23)

Event Timeline

Is this report on all buttons in Phabricator or just ones that contain tooltips?

I can't say I have tried every button, but the same behaviour affects even buttons without tooltips.

For example, in the "Reply" box in a diff, tapping the "Cancel" button, which has no tooltip, will on the first tap make the button subtly change colour but nothing else.

Tapping a second time, while this colour change is in effect, triggers the button and cancels the reply.

Tapping anywhere but on the cancel button makes it change its colour back to normal, resetting the process. And again, double tapping doesn't work either. It must be a "patient double tap".

Tapping a second time, while this colour change is in effect, triggers the button and cancels the reply.

Actually strike that. While tapping away does undo the colour change, a second tap still triggers the button it seems.

I'm attaching a video showing the behaviour recreated using the iOS simulator emulating an iPad Air 2 with iOS 9.2. Note how I tap "Cancel" and then wait and nothing happens, but on the second tap it reacts. The reply button behaviour is also shown at the beginning of the clip.

I can't say I have tried every button, but the same behaviour affects even buttons without tooltips.

Do you mind testing other buttons, by other buttons I mean any form anywhere on Phabricator that is not on the "diff" page.

In T10229#155876, @chad wrote:

I can't say I have tried every button, but the same behaviour affects even buttons without tooltips.

Do you mind testing other buttons, by other buttons I mean any form anywhere on Phabricator that is not on the "diff" page.

Sure, no problem. I did some quick testing and actually this might be localised to source code blocks, in diffs and audits. For example in Maniphest, Create Task, the "cancel" button responds to a single tap. In fact the "View options" button right above a code block on the same diff page works with a single tap.

I think this is a duplicate of T9969. Basically between Safari 9.1 and 9.2 somewhere, it now reports a "diff" page to us as a desktop page, where if we normally detect being on a phone or tablet, we do not trigger tooltips, hovers, etc.

Maaaybe an issue with how we detect and decide to use the 1-up renderer? cc @epriestley

Not sure what the "1-up renderer" is but if it's 1 vs 2 columns, that's not the problem really. The formatting of the diff is fine (it's a large, desktop size screen).

Although the task is closed I'd like to add this for future reference: I was unable to reproduce the problem in Chrome 48 on Max OS X with mobile device emulation. I used a screen resolution of 1302x1024 (iPad Pro) with retina pixels and the user agent string Mozilla/5.0 (iPad; CPU OS 9_2_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13D11. But even with "emulate touch screen" on, Phabricator reacts to the first click, unlike on the real device.

Okay I don't think it's related to the 1up vs 2up renderer. Reading the source code I found out that the "1up" renderer seems to be triggered for certain screen widths. So I used an iOS Split View to reduce the width of my browser until it was fairly narrow, and as result I got a unified diff instead, which I believe is the "1up" view.

The cancel button on a diff comment box still required two taps.

Here's some more failed research that might save someone some time. I don't know how Phabrictor is wired, but just to do some light exploring I hooked up iOS Safari with a remote debugger and set some breakpoints. As a kind of brute force thing I added breakpoints on everything that looked related to killing events (e.kill()).

The breakpoints were not triggered by "dud" touches.

I'd have liked to have debugged all the way down from this 'Stratcom dispatch' thing, but apparently breaking there affects the outcome of the experiment. It becomes impossible to trigger the correct behaviour. It could be because in touch browsers there is a 300 ms delay from touchstart until click, to determine the nature of the touch, and maybe setting a breakpoint interferes with that process and makes it impossible to get that 'click'.

Coming from the other direction, setting a breakpoint in the inline-edit-cancel handler, I can see that it is not triggered on the first tap. On the second tap it is triggered as a result of processing a 'click' event from dispatch.

Not sure what conclusion to draw from this. Maybe no click event is sent on the first tap due to some other event handler doing something (although whatever it does, calling e.kill() does not seem to be part of it). Or maybe no click event is sent on the first tap due to the DOM changing somehow (there's this selection thing happening). Changing the DOM between touchstart and click could perhaps affect things. Or maybe the click event is sent but to some other target.

I can reproduce this on my iPhone 4s which correctly selects 1-up mode, so I agree that this is probably not a duplicate of T9969.

I can also reproduce this in iOS Simulator, by selecting the iPhone 4s as the device.

I have found the bug. For iOS Safari to send a click event, the handlers of mouseover and mousemove must not change the document content. (Presumably to allow a touch user to reveal things that require mousing over, without actually clicking things.)

However in the differential view there is a kind of selection highlight set through updateReticle on mouseover. Disabling this feature makes tapping work as normal.

Nice work! I arrived at the same conclusion shortly after you did.

I'm just going to disable the mouseover/mouseout behaviors if the detected device is not a desktop. (In theory we could be more surgical about this and disable them if the mouse events follow touch events, but that's harder to detect and I think there should be no practical difference between the behaviors.)

Yeah. On a pure touch device, mouseover is not the most useful event to listen for when it comes to highlighting rows.

One wrinkle though is that the iPad Pro is detected as a "desktop" device currently (which is nice because you, appropriately, get the 2up view instead of the 1up).

One solution could be to add a touchstart event handler to set a temporary flag with the meaning "we're handling a touch event".

Then add the updateRecticle event handling code to both mouseover and mousedown, but modify the code so that:

  1. if "we're handling a touch event" and the event is "mouseover", ignore it.
  2. if !"we're handling a touch event" and the event is "mousedown", ignore it.

That way we get selection highlights on mouseover for actual mice, but on mousedown for touch -- even on devices that have both a mouse and touch.

(Changing the DOM in the mousedown handler does not prevent a click)

I gave this solution a quick whirl and it works. It preserves mouse over behaviour in regular browsers, and removes the need for double tapping in iOS (while still getting the selection highlights). Let me know if you'd like a patch or if you prefer your device detection approach.

Either way I can now go back to reviewing code with my sanity intact. :)

D15136 distinguishes between "touch-device" mouseovers and "mouse-device" mouseovers rather than relying on device detection, since the screen resolution of the iPad Pro is apparently a billion pixels by a trillion pixels and device detection is clearly increasingly hopeless.

Yep and to be honest this huge iPad is fairly desktop-y. The first time I saw it I kind of had to look twice to make sure it wasn't some run away item from Alice in Wonderland that had snuck into my reality.

epriestley triaged this task as Normal priority.

This is live on this server (secure.phabricator.com) -- let us know if you're still seeing issues. Seems OK for me on a physical iPhone 4s.

Seems OK for me on a physical iPhone 4s.

...

Works for me on the iPad Pro. Thank you!