Promote CSSPointerCapabilities into FPP
Categories
(Core :: Privacy: Anti-Tracking, enhancement)
Tracking
()
People
(Reporter: tjr, Unassigned)
References
(Blocks 1 open bug)
Details
- On Windows, ~0.43% of users have a primary pointing device that is 'coarse' (touch-laptop primary input)
- On Windows, ~0.07% of users have no pointing device
- On Android, ~0.66% of users have a fine primary pointing device (Firefox on Chromebooks)
These users, while in the small minority, stand out because of their unusualness.
CSSPointerCapabilities hardcodes the pointer / any-pointer / hover / any-hover behavior to the platform defaults (Fine|Hover on Desktop, and Coarse on Android)
For these minority users, they might get CSS that doesn't match them perfectly: no hover effects on a Chromebook where they could use them, hover effects on a touchpad where they can't. I'm not sure how common that is and if it would explicitly break a necessary workflow or just be a stylistic difference that's largely unnoticeable. I'm guessing/hoping mostly the latter?
Comment 1•4 months ago
•
|
||
how did you measure it? because the spec says any-input [1][2] can return multiple results
- https://www.w3.org/TR/mediaqueries-4/#@media/any-input
- see https://bugzilla.mozilla.org/show_bug.cgi?id=2005506#c0
-
The any-pointer and any-hover media features are identical to the pointer and hover media features, but they correspond to the union of capabilities of all the pointing devices available to the user. In the case of any-pointer, more than one of the values can match, if different pointing devices have different characteristics
- [1] e.g .my phone reports:
any-pointerasfine(test 1) +coarse(test 2)- you simply reverse the order of the tested capabilities
- [2]
any-hovercurrently only has one capabilities (besides none) so no such thing (yet) as a "union of capabilities" for this test
any-pointer: if you're not testing both, then your data will be tainted: in cases of devices with both capabilities, your results will favor one over the other
edit: and now I see you said "primary", but my info still stands
edit: clarified some points
Comment 2•4 months ago
•
|
||
(In reply to Tom Ritter [:tjr] from comment #0)
CSSPointerCapabilitieshardcodes the pointer / any-pointer / hover / any-hover behavior to the platform defaults (Fine|Hover on Desktop, and Coarse on Android)
I don't think this is true for desktop, it's been a few years and maybe something has changed that I missed - would be nice to clarify exactly what is protected for RFP and TZP health checks, so pinging pierov: AFAIK (this is what TZp checks for)
- desktop:
any-pointer: only allows the capabilityfinei.e we should befine + finepointer: we don't protect because we thought everyone would befine- but sounds like we should? see 0.5% windows users who have a primary pointer of none or coarse
hoverandany-hover: we don't protect because everyone should be hover already?
android: RFP/TZP health should currently be as follows (pending bug 2005506)
any-pointer: only allows the capabilitycoarsei.e we should becoarse + coarsepointer:coarsehover,any-hover:none
note: the origins of my knowledge on what is and what isn't is lost in the fog of time and bugzillas
pierov, can you confirm what the desktop protections currently are, thanks
Comment 3•4 months ago
|
||
I don't really remember how all of this work, either.
From a quick search to refresh my memory, it seems media queries are the only way to obtain these information.
In case, what Tom said is correct: https://searchfox.org/firefox-main/rev/e28b34ab33dbf49364999070168cbb7e11e8e5bd/layout/style/nsMediaFeatures.cpp#400-446
Both pointer and any-pointer go through GetPointerCapabilities, and the spoofed value is returned regardless or whether the primary or any pointer was requested.
As for the double value, I think this is your relevant code:
/* any-pointer order matters: https://www.w3.org/TR/mediaqueries-4/#any-input */
#cssAP:before{content:"n/a";}
@media (any-pointer:coarse){#cssAP:before{content:"coarse";}}
@media (any-pointer:fine){#cssAP:before{content:"fine";}} /* fine over coarse */
@media (any-pointer:none){#cssAP:before{content:"none ";}}
#cssAP:after{content:" + n/a";}
@media (any-pointer:fine){#cssAP:after{content:" + fine";}}
@media (any-pointer:coarse){#cssAP:after{content:" + coarse";}} /* coarse over fine */
@media (any-pointer:none){#cssAP:after{content:" + none ";}}
As you noticed, it's order dependent.
If you want to make it more clear, you can try to use this instead (tested only very quickly):
@media (any-pointer: fine) or (any-pointer: coarse) { #cssAP:before { content: "any"; } }
@media (any-pointer: fine) and (not (any-pointer: coarse)) { #cssAP:before { content: "only fine"; } }
@media (any-pointer: coarse) and (not (any-pointer: fine)) { #cssAP:before { content: "only coarse"; } }
@media (any-pointer:none) { #cssAP:before { content:"none "; } }
With RFP, you should get the "only" cases.
Finally, platform-specific pointer detection (might be helpful for Bug 2005506 too):
- Windows: https://searchfox.org/firefox-main/rev/e28b34ab33dbf49364999070168cbb7e11e8e5bd/widget/windows/WinUtils.cpp#1502-1590
- Android:
- https://searchfox.org/firefox-main/rev/e28b34ab33dbf49364999070168cbb7e11e8e5bd/widget/android/nsLookAndFeel.cpp#366-379: this means that if there's coarse, the primary pointer will be transformed to Coarse + Not Hover, as it's not possible to detect stuff more in details
- https://searchfox.org/firefox-main/rev/e28b34ab33dbf49364999070168cbb7e11e8e5bd/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java#1335-1378
- basically, on your phone you get also pointer fine because you can use a stylus with it (I believe), so it's not a matter of being a modern or old device
- Linux, macOS: not explicitly implemented in their
nsLookAndFeel::NativeGetIntas far as I can tell, therefore it falls back to the default value, which is the same one used by RFP
Comment 4•4 months ago
|
||
Sorry, but this still isn't clear to me. Does RFP explicitly protect desktop in pointer, hover and any-hover?
-
Linux/Mac: ... as far as I can tell, therefore it falls back to the default value
- does this refers to
any-pointer? and orpointer,hoverandany-hover? - IIUIC then it (whatever it is) is not protected, right? i.e we rely on some default value that could change in the future, or be changed by some other criteria on it's way to being calculated?
- does this refers to
-
Windows
- it is still my understanding that
pointer,hoverandany-hoverare not explicitly protected
- it is still my understanding that
3 desktop platforms x 4 "inputs" = 12 protections or not. Can I/we have some clarity please?
Comment 5•4 months ago
|
||
(In reply to Thorin [:thorin] from comment #4)
Sorry, but this still isn't clear to me. Does RFP explicitly protect desktop in
pointer,hoverandany-hover?
Linux/Mac: ... as far as I can tell, therefore it falls back to the default value
- does this refers to
any-pointer? and orpointer,hoverandany-hover?- IIUIC then it (whatever it is) is not protected, right? i.e we rely on some default value that could change in the future, or be changed by some other criteria on it's way to being calculated?
Windows
- it is still my understanding that
pointer,hoverandany-hoverare not explicitly protected3 desktop platforms x 4 "inputs" = 12 protections or not. Can I/we have some clarity please?
RFP happens here, regardless of the platforms (except desktop vs Android) and regardless of any-pointer vs. pointer: https://searchfox.org/firefox-main/rev/e28b34ab33dbf49364999070168cbb7e11e8e5bd/layout/style/nsMediaFeatures.cpp#416-421
- desktop: fine pointer, hover supported
- Android: coarse pointer, hover not supported
any-pointer and pointer match.
Comment 6•4 months ago
|
||
Sorry about the noise, but it's pointless testing from my perspective if I don't know what's going on - and apologies for being so dumb
So that code is the pointer - RFP doesn't explicitly control the value, it just enforces the default - which could change e.g. what if code was added to change the default based on tablet logic (see potential automatic desktop-mode for userAgent) as one example
- so we're not as robust as we could be but I guess it works until a potential footgun lands later?
where is the hover code?
| Reporter | ||
Comment 7•4 months ago
|
||
It's tough tracing CSS queries because they go through rust.
The media queries (pointer, any-pointer, hover, any-hover) wind up here where they go into primary_pointer_capabilities and all_pointer_capabilities (for all four media queries). That takes them into nsMediaFeatures.cpp and from there into GetPointerCapabilities.
That function can branch depending on whether you want the primary (or hover) or any-pointer (or any-hover) - but before that branch we check the CSSPointerCapabilities RFPTarget and return either Coarse on Android or Fine+Hover on Desktop.
Under any circumstance any of these queries can return multiple values (however primary-pointer/hover will always be a subset or equal to any-pointer/any-hover). With RFP enabled we will only return Coarse on Android or Fine+Hover on Desktop. There isn't any ordering.
Comment 8•4 months ago
•
|
||
With RFP enabled we will only return ... Fine+Hover on Desktop
so not protected then?
edit: nevermind: I was asking about hover and misread your answer as *hover returning two values. Of course fine refers to pointer. The info about android in the same sentence only returns *pointer which makes the sentence hard to parse TBH. Thanks for the confirmation
There isn't any ordering
that was just for tests in order for css to return the last matching rule
Description
•