Skip to content

[bug] CoreHelperUtil.isMobile() misclassifies touchscreen desktops — WalletConnect QR hidden #5648

@farbodghasemlu

Description

@farbodghasemlu

[bug] CoreHelperUtil.isMobile() misclassifies touchscreen desktops/laptops — WalletConnect QR hidden on Windows touch devices

Summary

CoreHelperUtil.isMobile() uses (pointer:coarse) media query as a mobile detection signal, which incorrectly classifies touchscreen desktops and laptops (e.g., Microsoft Surface, Dell XPS with touch, Lenovo Yoga, HP Spectre, etc.) as mobile devices. This causes the WalletConnect QR code connector to be completely excluded from the connect view on these devices, as ConnectorUtil.getConnectViewItems() filters it out when isMobile is true.

Link to minimal reproducible example

https://lab.reown.com/appkit/ (any config — reproducible on any touchscreen Windows/Linux desktop or laptop)

Steps to Reproduce

  1. Open any AppKit-integrated dapp on a Windows laptop with a touchscreen (e.g., Surface Pro, Dell XPS 2-in-1, HP Spectre x360) using Chrome
  2. Open the connect modal
  3. Observe that the WalletConnect QR code option is missing — the view matches the mobile layout
  4. Open DevTools console and run:
    window.matchMedia('(pointer:coarse)').matches // → true
    window.matchMedia('(any-pointer:fine)').matches // → true (trackpad/mouse present)
    navigator.maxTouchPoints // → 10
    window.innerWidth // → 1560 (clearly desktop viewport)
  5. Open the same dapp on a non-touch Ubuntu/macOS desktop — WalletConnect QR appears correctly

Current Behavior

On touchscreen desktops/laptops:

  • CoreHelperUtil.isMobile() returns true because (pointer:coarse) matches
  • ConnectorUtil.getConnectViewItems() excludes the WalletConnect connector (if (!isMobile && wcConnector))
  • User sees the mobile connect view (deep-link wallet list) instead of the desktop view (QR code)
  • WalletConnect QR connection is completely unavailable

Expected Behavior

Touchscreen desktops and laptops should be classified as desktop devices. The WalletConnect QR code should be available, since:

  • The user has a large screen capable of displaying a QR code
  • The user likely has a separate phone with a wallet app to scan the QR
  • Deep-linking to wallet apps on the same device makes no sense on a desktop OS

Root Cause

In packages/controllers/src/utils/CoreHelperUtil.ts:

isMobile() {
  if (this.isClient()) {
    return Boolean(
      (window?.matchMedia &&
        typeof window.matchMedia === 'function' &&
        window.matchMedia('(pointer:coarse)')?.matches) ||
      /Android|webOS|iPhone|iPad|iPod|BlackBerry|Opera Mini/u.test(navigator.userAgent)
    )
  }
  return false
}

(pointer:coarse) reports the primary pointer device. On Windows touch laptops, the OS often reports the touchscreen as the primary pointer, causing this check to return true — even though a trackpad/mouse is also available.

Proposed Fix

Combine pointer:coarse with any-pointer:fine to detect multi-input devices. This approach is recommended by Patrick H. Lauke (W3C Pointer Events spec co-editor) in his CSS-Tricks article on Interaction Media Features:

@media (pointer: coarse) and (any-pointer: fine) suggests the primary input is touchscreen, but that there is a mouse or stylus present.

The W3C also classifies hiding functionality based solely on touch detection as an accessibility failure (F98).

isMobile() {
  if (this.isClient()) {
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|Opera Mini/u.test(navigator.userAgent)) {
      return true
    }

    const isCoarsePointer =
      window.matchMedia?.('(pointer:coarse)')?.matches ?? false
    const hasAnyFinePointer =
      window.matchMedia?.('(any-pointer:fine)')?.matches ?? false

    // Coarse pointer + fine pointer available = touchscreen desktop/laptop, not mobile
    if (isCoarsePointer && hasAnyFinePointer) {
      return false
    }

    return isCoarsePointer
  }
  return false
}

I have a PR ready for this fix: #5649

Environment

  • @reown/appkit version: 1.8.19 (also present in all prior versions)
  • Browser: Chrome 135 (also reproducible in Edge, Firefox)
  • OS: Windows 11 on Dell XPS 15 (touchscreen, maxTouchPoints: 10)
  • Works correctly on: Ubuntu 24.04 (no touchscreen), macOS

Affected Devices (estimated scale)

This affects all touchscreen Windows laptops and desktops, which is a significant market segment:

  • Microsoft Surface lineup (Pro, Laptop, Book, Go, Studio)
  • Dell XPS 13/15 2-in-1, Inspiron 2-in-1
  • Lenovo Yoga series, ThinkPad X1 Yoga
  • HP Spectre x360, Envy x360
  • ASUS ZenBook Flip, VivoBook Flip
  • All-in-one desktop PCs with touchscreens

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions