Closed
Bug 780847
Opened 9 years ago
Closed 9 years ago
fluff out touch click targets
Categories
(Core :: DOM: Events, defect)
Tracking
()
People
(Reporter: gal, Assigned: roc)
References
Details
Attachments
(4 files, 7 obsolete files)
13.45 KB,
patch
|
Details | Diff | Splinter Review | |
2.05 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
2.39 KB,
patch
|
mats
:
review+
|
Details | Diff | Splinter Review |
24.66 KB,
patch
|
mats
:
review+
|
Details | Diff | Splinter Review |
We currently use some code in the frontend code in fennec to fluff out click targets. We should do this in the event handling code proper. The fennec code is in ElementTouchHelper and can be ported pretty easily (JS), and should probably eventually be C++. smaug pointed out that nsLayoutUtils::GetFrameForPoint might be the right place to hook this into.
Reporter | ||
Updated•9 years ago
|
blocking-basecamp: --- → +
Reporter | ||
Comment 1•9 years ago
|
||
If we think this is hard, we can take a shortcut and port over the fennec code 1:1 for now.
Assignee | ||
Comment 2•9 years ago
|
||
You actually want PresShell::HandleEvent to call nsLayoutUtils::GetFramesForArea instead of GetFrameForPoint. The code in ElementTouchHelper could be ported to a helper method in PresShell pretty easily.
Comment 3•9 years ago
|
||
also see bug 547997.
Reporter | ||
Comment 4•9 years ago
|
||
Reporter | ||
Comment 5•9 years ago
|
||
Attachment #649814 -
Attachment is obsolete: true
Comment 6•9 years ago
|
||
Comment on attachment 649815 [details] [diff] [review] patch >diff --git a/dom/base/TouchManager.js b/dom/base/TouchManager.js Please keep this somewhere in b2g land, or at least not in dom/base
Assignee | ||
Comment 7•9 years ago
|
||
Andreas, I think it would be cleaner to go straight to C++. I can do that now. Would you like me to?
Reporter | ||
Comment 9•9 years ago
|
||
roc, I think the fennec code does roughly the right thing, but maybe not really at the right level. I think its good to look at active click targets (links, things with event handlers listening), but we probably want to look at frames, not the DOM.
Reporter | ||
Comment 10•9 years ago
|
||
roc, dougt is suggesting to pull in wesj if you need any help with the fennec code, since he wrote it
Assignee | ||
Comment 11•9 years ago
|
||
Complete as far as I know, but totally untested.
Assignee | ||
Comment 12•9 years ago
|
||
Attachment #651612 -
Attachment is obsolete: true
Attachment #652757 -
Flags: review?(bugs)
Assignee | ||
Comment 13•9 years ago
|
||
Attachment #652758 -
Flags: review?(matspal)
Assignee | ||
Comment 14•9 years ago
|
||
I'd like to think about this a little bit more and add some better documentation. However, it seems to work OK, at least it passes the mochitests I've created.
Assignee | ||
Comment 15•9 years ago
|
||
https://tbpl.mozilla.org/?tree=Try&rev=4cc38f4e7bc8
Comment 16•9 years ago
|
||
Comment on attachment 652757 [details] [diff] [review] Add support for checking for event listeners with an nsIAtom* event name Code looks ok (although I'd put the NS_ASSERTION inside ifdef debug), but I don't quite understand why this is needed. I think you'd want something which checks if there are js implemented event listeners in default group. ListenerStruct has mListenerType.
Attachment #652757 -
Flags: review?(bugs) → review-
Comment 17•9 years ago
|
||
Comment on attachment 652758 [details] [diff] [review] Fix nsLayoutUtils::IsProperAncestorFrame(CrossDoc) to handle cases where aFrame or aAncestorFrame are the root > Bug 780847. Fix nsLayoutUtils::IsProperAncestorFrame(CrossDoc) to handle > cases where aFrame or aAncestorFrame are the root. I can't tell what you mean by "Fix". The documentation (and name) of IsProperAncestorFrame says that it returns false when aAncestorFrame == aFrame. In other words, IsProperAncestorFrame(x,x) is false for all x. This patch makes IsProperAncestorFrame(root,root) return true. r- if that's your intention, because I think it's the wrong result. (you should probably just add a new method in this case) r- if that's not your intention - new patch expected with explanation of what it is you're fixing exactly
Attachment #652758 -
Flags: review?(matspal) → review-
Assignee | ||
Comment 18•9 years ago
|
||
(In reply to Olli Pettay [:smaug] from comment #16) > Code looks ok (although I'd put the NS_ASSERTION inside ifdef debug), but > I don't quite understand why this is needed. > I think you'd want something which checks if there are > js implemented event listeners in default group. > ListenerStruct has mListenerType. I'm just refactoring the existing code used by Fennec's ElementTouchHelper. But I also think that checking all event listeners is the right way to go. We want to select the element as a good touch target if it will respond to the event in any way.
Comment 19•9 years ago
|
||
EventListenerManager check doesn't include all the default handling
Comment 20•9 years ago
|
||
But I guess that is why there is the manual check for certain elements.
Comment 21•9 years ago
|
||
(the check should check namespace)
Assignee | ||
Comment 23•9 years ago
|
||
Added namespace check and some comments. Everything's green on try.
Attachment #652759 -
Attachment is obsolete: true
Attachment #653222 -
Flags: review?(bugs)
Comment 24•9 years ago
|
||
Comment on attachment 653209 [details] [diff] [review] Fix nsLayoutUtils::IsProperAncestorFrame(CrossDoc) v2 I don't see anything wrong with the old code in the case where aFrame or aAncestorFrame are the root (as the commit message claims), can you point out the bug please?
Updated•9 years ago
|
Attachment #652757 -
Flags: review- → review+
Assignee | ||
Comment 25•9 years ago
|
||
(In reply to Mats Palmgren [:mats] from comment #24) > I don't see anything wrong with the old code in the case where > aFrame or aAncestorFrame are the root (as the commit message > claims), can you point out the bug please? Consider aAncestorFrame == aCommonAncestor == aFrame->GetParent(). The current implementation of IsProperAncestorFrameCrossDoc returns false, which is incorrect.
Comment 26•9 years ago
|
||
Comment on attachment 653209 [details] [diff] [review] Fix nsLayoutUtils::IsProperAncestorFrame(CrossDoc) v2 OK, got it. I was confused by "root" in the commit message. Please update it to better describe the problem.
Attachment #653209 -
Flags: review?(matspal) → review+
Comment 27•9 years ago
|
||
Comment on attachment 653222 [details] [diff] [review] Main patch v2 >+static nsIFrame* >+GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame, >+ const char* aPrefBranch, nsIFrame* aRestrictToDescendants, >+ nsTArray<nsIFrame*>& aCandidates) >+{ >+ nsIFrame* bestTarget = nullptr; >+ // Lower is better; distance is in appunits >+ float bestDistance = 1e6f; >+ for (PRUint32 i = 0; i < aCandidates.Length(); ++i) { >+ nsIFrame* f = aCandidates[i]; >+ if (!IsElementClickable(f)) >+ continue; >+ // If our current closest frame is a descendant of 'f', skip 'f' (prefer >+ // the nested frame). >+ if (bestTarget && nsLayoutUtils::IsProperAncestorFrameCrossDoc(f, bestTarget, aRoot)) >+ continue; >+ if (!nsLayoutUtils::IsAncestorFrameCrossDoc(aRestrictToDescendants, f, aRoot)) >+ continue; This misses some {} >+FindFrameTargetedByInputEvent(PRUint8 aEventStructType, >+ nsIFrame* aRootFrame, >+ const nsPoint& aPointRelativeToRootFrame, >+ PRUint32 aFlags) >+{ >+ bool ignoreRootScrollFrame = (aFlags & INPUT_IGNORE_ROOT_SCROLL_FRAME) != 0; >+ const char* prefBranch = nullptr; >+ if (aEventStructType == NS_MOZTOUCH_EVENT || >+ aEventStructType == NS_TOUCH_EVENT) { >+ prefBranch = "touch"; >+ } else if (aEventStructType == NS_MOUSE_EVENT) { >+ // Mostly for testing purposes >+ prefBranch = "mouse"; >+ } >+ bool useSearchRadius = false; >+ if (prefBranch) { >+ nsPrintfCString prefName("ui.%s.radius.enabled", prefBranch); >+ useSearchRadius = Preferences::GetBool(prefName.get()); >+ } I think we should cache the pref values, especially because Preferences::Add*VarCache is just super simple to use. >+ // If the exact target is non-null, only consider candidate targets in the same >+ // document as the exact target. Otherwise, if an ancestor document has >+ // a mouse event handler for example, targets that are !IsElementClickable can >+ // never be targeted --- something nsSubDocumentFrame in an ancestor document >+ // would be targeted instead. >+ nsIFrame* restrictToDescendants = target >+ ? target->PresContext()->PresShell()->GetRootFrame() : aRootFrame; ? should be in the previous line and 2 space indentation.
Attachment #653222 -
Flags: review?(bugs) → review-
Assignee | ||
Comment 28•9 years ago
|
||
(In reply to Olli Pettay [:smaug] from comment #27) > I think we should cache the pref values, especially because > Preferences::Add*VarCache is just super simple to use. I can do that, of course, but it seems a bit pointless to me. Do you think that this could actually ever show up on a profile?
Comment 29•9 years ago
|
||
It might (especially if we end up using the code for other things too on mobile), and since it is trivial to cache the pref values and not cause code to jump to totally different place, I'd prefer caching the values.
Assignee | ||
Comment 30•9 years ago
|
||
Attachment #655514 -
Flags: review?(bugs)
Assignee | ||
Updated•9 years ago
|
Attachment #652758 -
Attachment is obsolete: true
Assignee | ||
Updated•9 years ago
|
Attachment #653222 -
Attachment is obsolete: true
Comment 31•9 years ago
|
||
Comment on attachment 655514 [details] [diff] [review] main patch v3 >+ * Any descendant (in the same document) of a clickable element is also >+ * deemed clickable since events will bubble to the clickable element from its >+ * descendant. s/bubble/propagate/ >+struct EventRadiusPrefs { { goes to next line. >+static bool >+IsElementClickable(nsIFrame* aFrame) >+{ >+ // Input events bubble up the content tree so we'll follow the content >+ // ancestors to look for elements accepting the click. >+ for (nsIContent* content = aFrame->GetContent(); content; >+ content = content->GetParent()) { Nit, missing one space before content >+ } else if (content->IsSVG()) { >+ nsIAtom* tag = content->Tag(); >+ if (tag == nsGkAtoms::a) { >+ return true; >+ } >+ } ] else if (content->IsSVG(nsGkAtoms::a)) { return true; } >+GetAppUnitsFromMMPref(nsIFrame* aFrame, uint32_t aMM, bool aVertical) >+{ >+ nsPresContext* pc = aFrame->PresContext(); >+ nsIPresShell* presShell = pc->PresShell(); >+ float result = float(aMM)* space before * >+ (pc->DeviceContext()->AppUnitsPerPhysicalInch()/25.4f)* space before and after / and before * 25.4f needs some explanation. >+ distance *= aPrefs->mVisitedWeight/100.0f; Nit, space before and after / >+namespace mozilla { >+ >+enum { >+ INPUT_IGNORE_ROOT_SCROLL_FRAME = 0x01 >+}; Enums should be in form eValueName >+ uint32_t aFlags = 0; aFoo is form is reserved for parameters. Just flags >+ if (aEvent->eventStructType == NS_MOUSE_EVENT && >+ static_cast<nsMouseEvent*>(aEvent)->ignoreRootScrollFrame) { >+ aFlags |= INPUT_IGNORE_ROOT_SCROLL_FRAME; Not sure I like assigning enum values to uint32_t, but ok. Mats should also review this.
Attachment #655514 -
Flags: review?(bugs) → review+
Assignee | ||
Comment 32•9 years ago
|
||
(In reply to Olli Pettay [:smaug] from comment #31) > >+namespace mozilla { > >+ > >+enum { > >+ INPUT_IGNORE_ROOT_SCROLL_FRAME = 0x01 > >+}; > Enums should be in form eValueName We have loads of enums that aren't, especially enums that are actually defining bit flags. So I think it's actually more consistent to use A_B style here. > >+ uint32_t aFlags = 0; > aFoo is form is reserved for parameters. Just flags aFlags is a parameter. I don't understand. > >+ if (aEvent->eventStructType == NS_MOUSE_EVENT && > >+ static_cast<nsMouseEvent*>(aEvent)->ignoreRootScrollFrame) { > >+ aFlags |= INPUT_IGNORE_ROOT_SCROLL_FRAME; > Not sure I like assigning enum values to uint32_t, but ok. We use enums as a portable way to define constants inline in classes, all over the place. It's not strictly needed here since we're not in a class scope, but it seems to me we might as well keep doing it.
Assignee | ||
Comment 33•9 years ago
|
||
Asking for re-review because I didn't take all the suggested changes.
Attachment #655514 -
Attachment is obsolete: true
Attachment #656644 -
Flags: review?(bugs)
Assignee | ||
Updated•9 years ago
|
Attachment #656644 -
Flags: review?(matspal)
Comment 34•9 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #32) > > >+ uint32_t aFlags = 0; > > aFoo is form is reserved for parameters. Just flags > > aFlags is a parameter. I don't understand. It is not. You define a local variable called aFlags. Local variables should not be in form aFoo.
Comment 35•9 years ago
|
||
Comment on attachment 656644 [details] [diff] [review] main patch v4 Well, ok for the enum (I still think we should use enums consistently, but we aren't), but fix the aFlags
Attachment #656644 -
Flags: review?(bugs) → review+
Assignee | ||
Comment 36•9 years ago
|
||
(In reply to Olli Pettay [:smaug] from comment #34) > It is not. You define a local variable called aFlags. > Local variables should not be in form aFoo. Oh, *that* aFlags. Absolutely, will fix, sorry :-).
Comment 37•9 years ago
|
||
Comment on attachment 656644 [details] [diff] [review] main patch v4 > layout/base/PositionedEventTargeting.cpp Kudos for the elaborate overview! > + * [snip] For visited links we multiply the distance > + * weight be a specified constants; [snip] huh? > + uint32_t mVisitedWeight; "// in percent" for clarity > + uint32_t mSideRadii[4]; // TRBL order "// TRBL order, in millimeters" for clarity >+IsElementClickable(nsIFrame* aFrame) >... >+ if (tag == nsGkAtoms::a || I'm not sure a plain <a> without href should be in this list. Isn't the IsLink test that comes later better? I actually tested this with a <a>Chapter 1</a> near a link, and it didn't feel right that it should influence the radius of the link. Can you explain why you think it should? While testing (Fx on Linux) I also noted that clicking on the lower part of the File menu button actuated the Back button below it. I'm guessing this feature is meant for Fennec without XUL so it's not important, but perhaps you could add an early return for IsXUL somewhere anyway? >+static nscoord >+GetAppUnitsFromMMPref(nsIFrame* aFrame, uint32_t aMM, bool aVertical) Remove the Get prefix. The Pref suffix also seems unnecessary. > + static const float MM_PER_INCH = 25.4f; Maybe you can use this one instead: ./gfx/src/nsCoord.h:#define MM_PER_INCH_FLOAT 25.4f > modules/libpref/src/init/all.js You have put the prefs in the "#ifdef XP_WIN" section. Please move them to the end of the general section (just above "#ifdef XP_WIN" as it happens). r=mats with those addressed
Attachment #656644 -
Flags: review?(matspal) → review+
Assignee | ||
Comment 38•9 years ago
|
||
(In reply to Mats Palmgren [:mats] from comment #37) > I'm not sure a plain <a> without href should be in this list. > Isn't the IsLink test that comes later better? I copied that from the Fennec code I was adapting. You're right. I'll remove <a> from that list. > While testing (Fx on Linux) I also noted that clicking on the lower part > of the File menu button actuated the Back button below it. I'm guessing > this feature is meant for Fennec without XUL so it's not important, but > perhaps you could add an early return for IsXUL somewhere anyway? I've added some basic support for XUL elements. I've also modified the loop up the DOM tree to use GetFlattenedTreeParent instead of just GetParent to try to support XBL a bit better. But it's true this is for Web content, B2G and Fennec, so XUL and XBL aren't very important and I don't think we should try hard to make them work well, at this stage.
Assignee | ||
Comment 39•9 years ago
|
||
Attachment #656644 -
Attachment is obsolete: true
Attachment #657233 -
Flags: review?(matspal)
Assignee | ||
Comment 40•9 years ago
|
||
https://tbpl.mozilla.org/?tree=Try&rev=4a8c0e1ee624
Comment 41•9 years ago
|
||
Comment on attachment 657233 [details] [diff] [review] main patch v5 (In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #38) > ... I'll remove <a> from that list. OK, please also remove the <svg:a>, it has IsLink: http://mxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGAElement.cpp#191 > I've added some basic support for XUL elements. Thanks, that fixed the File menu problem and UI seems to work reasonably well in general. Clicking on popup menus still have the same problem, e.g. Preferences->When Nightly Starts. Adding menulist to the list of XUL tags makes it work. r=mats
Attachment #657233 -
Flags: review?(matspal) → review+
Assignee | ||
Comment 42•9 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/81e4779cb9db https://hg.mozilla.org/integration/mozilla-inbound/rev/18c5d86ee80f https://hg.mozilla.org/integration/mozilla-inbound/rev/3f93543e0db7
Comment 43•9 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/81e4779cb9db https://hg.mozilla.org/mozilla-central/rev/18c5d86ee80f https://hg.mozilla.org/mozilla-central/rev/3f93543e0db7
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla18
You need to log in
before you can comment on or make changes to this bug.
Description
•