Closed Bug 1306634 Opened 8 years ago Closed 5 years ago

Long-pressing on an iframe which doesn't have focus puts selection in unexpected place

Categories

(Core :: DOM: Selection, defect)

51 Branch
All
Android
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla74
Tracking Status
firefox49 --- wontfix
firefox50 --- wontfix
firefox51 --- wontfix
firefox52 --- wontfix
firefox74 --- fixed

People

(Reporter: kats, Assigned: TYLin)

References

(Blocks 1 open bug)

Details

Attachments

(3 files)

On Fennec, or Windows e10s with touch: 1. Load a page like http://people.mozilla.org/~kgupta/gridframe.html which has an iframe 2. Tap outside the iframe to make sure the parent window has focus 3. Long-press inside the iframe (on some blank space) to bring up the text-selection carets ER: text selection carets show up inside the iframe AR: text selection carets show up outside the iframe Note that in step 2 if you tap inside the iframe (on blank space) then the iframe gets focus and things work as expected. I believe what we need to do is give the iframe focus once we detect the long-press. Chrome seems to do this as well.
I thought this would be fixable by simply copying the code at [1] down into the eLongTap case, but that doesn't work. After looking at the code some more I then thought that the problem was the AccessibleCaretEventHub schedules its internal long-tap injector when it receives the touchstart, but at that point the focus is still in the parent window. So the long-tap injector triggers a long-tap on the parent window, regardless of whether the focus changes later. But disabling the long-tap injector and using the eMouseLongTap event didn't fix the problem either. Still digging... [1] http://searchfox.org/mozilla-central/rev/d1276b5b84e6cf7991c8e640b5e0ffffd54575a6/dom/ipc/TabChild.cpp#1781-1783
I think it might be related to how the EventHub is delivered events from nsPresShell. It looks like it always sends it from the focused presShell, or the top-level presShell. In this case we want it to go to the presShell that's under the finger which is only computed later in the code. I haven't yet confirmed.
Attached patch HackSplinter Review
Indeed, that is the problem. A patch like the one attached, which passes positioned events to the AccessibleCaretEventHub of the presshell *after* hit-testing fixes this bug. It probably breaks other things, though. I'm not sure what the correct mechanism here is to fix this.
Unassigning since I'm not familiar enough with the intricacies of the AccessibleCaret event delivery timing to really tackle this.
Assignee: bugmail → nobody
On Windows this will affect 52 and up, but on Fennec it is already in release (48 and up).
OS: Unspecified → Android
Hardware: Unspecified → All
I feel the patch in comment 3 makes some sense. However, after applying the patch, sometimes I cannot drag caret. Each PresShell owns an EventHub, and we should want to let the event hub under the finger to handle the event. The event retargeting code [1] was from the very first implementation in bug 924692. Morris, do you recall why we did [1]? [1] http://searchfox.org/mozilla-central/rev/d1276b5b84e6cf7991c8e640b5e0ffffd54575a6/layout/base/nsPresShell.cpp#7341-7347
Flags: needinfo?(mtseng)
That because we want to active only one caret at the same time. Otherwise it might have multiple caret appeared on the screen.
Flags: needinfo?(mtseng)
Mass wontfix for bugs affecting firefox 52.
Assignee: nobody → aethanyc
Status: NEW → ASSIGNED

Long-pressing on a text in an unfocused iframe to select a word never
works. Currently, you need to single tap to focus the iframe first.

Each PresShell has an associated AccessibleCaretEventHub. This patch
fixes this bug by routing the event to the AccessibleCaretEventHub under
the event point, and handle it there. If the event is not handled, then
we handle it by the focused AccessibleCaretEventHub as before.

I've experimented with only routing the event to the
AccessibleCaretEventHub under the event point, without routing to the
fallback focused AccessibleCaretEventHub. However, caret dragging didn't
work in iframes. I didn't debug further.

Consider the following scenario:

  1. Select a word in an iframe.
  2. Select a word in the parent document. (The carets in iframe hide
    due to blur, but the selection is still there.)
  3. Scroll the parent document.

The selection in the iframe (made in step 1) has a non-collapsed range.
Thus the carets show again after scrolling due to UpdateCarets()
called in the end of AccessibleCaretManager::OnScrollEnd().

To fix the dual AccessibleCaret in the same page (described in bug
1199967), we can simply show no carets if the window is not focused.
This behavior always matches Google Chrome on Android.

Depends on D52767

Pushed by aethanyc@gmail.com: https://hg.mozilla.org/integration/autoland/rev/35651fd9e240 Part 1 - Handle a long press to select a word in an unfocused iframe. r=mats,marionette-reviewers,whimboo https://hg.mozilla.org/integration/autoland/rev/fb20602d0c39 Part 2 - Do not show carets if the window is not focused. r=mats

OK, so by looking at the failure log, the assertion is "display list building in the middle of frame construction."

That is, we are in the middle of destroying some frames, and some windows-only related stuff [1] can send WidgetQueryContentEvent with eQuerySelectedText messages that PresShell needs to handle. My new code added in Part 1 uses PresShell::EventHandler::ComputeEventTargetFrameAndPresShellAtEventPoint() to find the desired target frame and PresShell, which requires building display lists to do the hit test.

In fact, AccessibleCaretEventHub [2] handles only mouse, touch, and keyboard events. To fix this, I think it is reasonable to filter the event classes upfront in PresShell::EventHandler::MaybeHandleEventWithAccessibleCaret(), and add an assertion in AccessibleCaretEventHub::HandleEvent() that it never gets events other than the three types it cares about.

[1] https://searchfox.org/mozilla-central/rev/68b2e0fd4323261a229233ec2ab8606228979141/widget/windows/TSFTextStore.cpp#2977-2979
[2] https://searchfox.org/mozilla-central/rev/68b2e0fd4323261a229233ec2ab8606228979141/layout/base/AccessibleCaretEventHub.cpp#405

Flags: needinfo?(aethanyc)
Pushed by aethanyc@gmail.com: https://hg.mozilla.org/integration/autoland/rev/3ad87a37592b Part 1 - Handle a long press to select a word in an unfocused iframe. r=mats,marionette-reviewers,whimboo https://hg.mozilla.org/integration/autoland/rev/29c9a00754c1 Part 2 - Do not show carets if the window is not focused. r=mats
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla74
Attachment #9108272 - Attachment description: Bug 1306634 Part 2 - Do not show carets if the window is not focused. → Bug 1306634 Part 2 - Do not show carets if the window is not focused. r=mats
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: