ionic-framework icon indicating copy to clipboard operation
ionic-framework copied to clipboard

bug: isMobile returns true for touch screen laptops

Open NormanV41 opened this issue 4 years ago • 6 comments

Prerequisites

Ionic Framework Version

  • [ ] v4.x
  • [X] v5.x
  • [X] v6.x

Current Behavior

Platform#isMobile function is querying for (any-pointer: coarse), which means it will return true when at least one input device uses a touch mechanism. An app running on my laptop Platform#isMobile is returning true because it has an input device that uses a touch mechanism.

Expected Behavior

Platform#isMobile function should be querying for (pointer: coarse), which means it will return true only when the primary input device uses a touch mechanism. An app running on my laptop Platform#isMobile is returning false because it has not an input device that uses a touch mechanism as its primary input device.

Steps to Reproduce

  • Get a laptop that has a touch screen.
  • Start a new ionic app with a blank template
  • use the platform service and note that platform#platforms return ["mobile", "mobileweb"]

Code Reproduction URL

https://github.com/NormanV41/ionic-issues-demo

Ionic Info

[WARN] Error loading @capacitor/ios package.json: Error: Cannot find module '@capacitor/ios/package'

   Require stack:
   - /usr/lib/node_modules/@ionic/cli/lib/project/index.js
   - /usr/lib/node_modules/@ionic/cli/lib/index.js
   - /usr/lib/node_modules/@ionic/cli/index.js
   - /usr/lib/node_modules/@ionic/cli/bin/ionic

[WARN] Error loading @capacitor/android package.json: Error: Cannot find module '@capacitor/android/package'

   Require stack:
   - /usr/lib/node_modules/@ionic/cli/lib/project/index.js
   - /usr/lib/node_modules/@ionic/cli/lib/index.js
   - /usr/lib/node_modules/@ionic/cli/index.js
   - /usr/lib/node_modules/@ionic/cli/bin/ionic

Ionic:

Ionic CLI : 6.18.0 (/usr/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/angular 6.0.0-rc.2 @angular-devkit/build-angular : 12.1.4 @angular-devkit/schematics : 12.1.4 @angular/cli : 12.1.4 @ionic/angular-toolkit : 4.0.0

Capacitor:

Capacitor CLI : 3.2.5 @capacitor/android : not installed @capacitor/core : 3.2.5 @capacitor/ios : not installed

Utility:

cordova-res : 0.15.3 native-run : 1.5.0

System:

NodeJS : v14.16.1 (/usr/bin/node) npm : 6.14.12 OS : Linux 5.14

Additional Information

No response

NormanV41 avatar Nov 07 '21 18:11 NormanV41

I corroborate this. On a Surface Laptop Studio device, which has a touch screen but is really a laptop, getPlatforms returns mobile and mobileweb: image

@liamdebeasi I read the discussion on Pixel 7 devices. While for that one the issue seems to lie inside Chromium, I don't know what can be done here.

EDIT: I ran the following snippet

["none", "coarse", "fine"].forEach(precision => {
	console.log(`matchMedia("(any-pointer:${precision})"): ${matchMedia(`(any-pointer:${precision})`).matches}`);
	console.log(`matchMedia("(pointer:${precision})"): ${matchMedia(`(pointer:${precision})`).matches}`);
});

in the console for both Chrome and Edge and both any-pointer:coarse and pointer:coarse return true on the Surface.

Etchelon avatar Nov 15 '22 11:11 Etchelon

Thanks for checking! Are you able to provide the raw results for all the precision types?

liamdebeasi avatar Nov 15 '22 14:11 liamdebeasi

@liamdebeasi I was making a mistake in the media query (forgot the parenthesis), I get true for both any-pointer:coarse and pointer:coarse on both Chrome and Edge. To recap:

["none", "coarse", "fine"].forEach(precision => {
	console.log(`matchMedia("(any-pointer:${precision})"): ${matchMedia(`(any-pointer:${precision})`).matches}`);
	console.log(`matchMedia("(pointer:${precision})"): ${matchMedia(`(pointer:${precision}`).matches})`);
});

Chrome: image

Edge: image

even when I only use an external monitor and disable the Surface's monitor!

Not sure what to do 🤔

Etchelon avatar Nov 15 '22 14:11 Etchelon

Thanks! It sounds like this may be an issue with browsers instead of Ionic:

Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1638556 Chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=1088262&q=windows%20surface%20pointer&can=2

It sounds like pointer:fine should be returning true when a mouse is attached/tablet mode is disabled, but browsers do not report this currently. I am going to update this thread to mark the issue as an external bug. If this is a browser bug you need fixed, I recommend commenting on the bug threads above.

liamdebeasi avatar Nov 15 '22 15:11 liamdebeasi

This issue is not specific for surface devices. It probably happens on any device with a touchscreen. For example I have a Dell Laptop with a touchscreen and isMobile returns true.

Maybe there is a bug in the browsers, I don't know. But I still think there is also a bug in Ionic. For me the media queries seem to return valid results. Same result in three browsers (Chrome / Edge / Firefox): window.matchMedia("(any-pointer:none)"): false window.matchMedia("(pointer:none)"): false) window.matchMedia("(any-pointer:coarse)"): true window.matchMedia("(pointer:coarse)"): false) window.matchMedia("(any-pointer:fine)"): true window.matchMedia("(pointer:fine)"): true)

So the initial question remains. Why does isMobile check for (any-pointer: coarse). Shouldn't it be (pointer: coarse) to check the primary input device, or (any-pointer:fine)?

There have also been other issues to report that problem, like #18388 and #17833. They were closed refering to #17631. But the latter is closed now and the issue still exists. Is there any plan on how to proceed with this issue?

astaerk avatar Feb 03 '23 09:02 astaerk

Even if this is not an ionic bug we should find a solution for it as a framework we should abstract this bug from the consumers.

What if we add a check for || !!window.cordova || !!window.Capacitor

Since it's my understanding those only get injected into the native builds. This might be a breaking change for anyone accidentally loading cordova or capacitor on web but I think it's an acceptable.

When (if) the browsers fix the issue we can remove

Lindsor avatar Aug 08 '23 01:08 Lindsor