<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mxhlix</title>
    <description>The latest articles on DEV Community by Mxhlix (@mxhlix).</description>
    <link>https://dev.to/mxhlix</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4024719%2F0e97f1ff-508f-4e20-aeab-13ce2a7cdcca.png</url>
      <title>DEV Community: Mxhlix</title>
      <link>https://dev.to/mxhlix</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mxhlix"/>
    <language>en</language>
    <item>
      <title>Claude in Chrome keeps missing clicks. I measured why — there are exactly two causes.</title>
      <dc:creator>Mxhlix</dc:creator>
      <pubDate>Sat, 11 Jul 2026 05:43:04 +0000</pubDate>
      <link>https://dev.to/mxhlix/claude-in-chrome-keeps-missing-clicks-i-measured-why-there-are-exactly-two-causes-2m8p</link>
      <guid>https://dev.to/mxhlix/claude-in-chrome-keeps-missing-clicks-i-measured-why-there-are-exactly-two-causes-2m8p</guid>
      <description>&lt;p&gt;If you use Claude in Chrome (Chrome MCP) for browser automation, you have probably hit some of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clicks land next to the target, not on it&lt;/li&gt;
&lt;li&gt;The pointer drifts right of the element, and retrying never fixes it&lt;/li&gt;
&lt;li&gt;You take a screenshot, and moments later the page dimensions have changed&lt;/li&gt;
&lt;li&gt;Double-clicks don't enter edit mode — you get a row selection instead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I run 600+ web tools built and QA'd through AI-driven browser automation, so I hit these constantly. I burned hours suspecting the page elements. They were fine.&lt;/p&gt;

&lt;p&gt;The real problem: the assumptions behind coordinate-based clicking were breaking. It comes down to exactly two causes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cause 1: the window width settles late, so coordinates drift right
&lt;/h2&gt;

&lt;p&gt;Right after a page loads, &lt;code&gt;innerWidth&lt;/code&gt; can report a smaller value than the real window. On my machine it started at 1664. Even after &lt;code&gt;document.readyState&lt;/code&gt; hits &lt;code&gt;complete&lt;/code&gt;, it keeps widening for 2–3 seconds until it reaches the true width (1920). During that window, &lt;code&gt;outerWidth&lt;/code&gt; / &lt;code&gt;outerHeight&lt;/code&gt; sometimes return 0.&lt;/p&gt;

&lt;p&gt;Now take a screenshot during that settling period and click using its coordinates. The page has widened since the capture, so your click lands to the right of the target. 1664→1920 is a 1.15× stretch — the further right the element, the bigger the miss.&lt;/p&gt;

&lt;p&gt;That's the whole mystery: "the page changed size after my screenshot" and "the pointer keeps drifting" are the same bug.&lt;/p&gt;

&lt;p&gt;This is not limited to exotic canvas apps. Ordinary HTML pages with lazy loading or dynamic layout do it too. Some of my "this input just won't click" sessions were nothing more than coordinates swinging at empty air.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to diagnose it
&lt;/h3&gt;

&lt;p&gt;Read the viewport with &lt;code&gt;javascript_tool&lt;/code&gt; and check whether it has stabilized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;readyState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;dpr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;devicePixelRatio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;innerW&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;innerH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;outerW&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outerWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;outerH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outerHeight&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three rules. If &lt;code&gt;outerW&lt;/code&gt; is 0, the window size hasn't settled — do not interact yet. Read again after a moment; if &lt;code&gt;innerW&lt;/code&gt; changed, it's still settling — keep waiting. Two consecutive identical &lt;code&gt;innerW&lt;/code&gt; readings with a non-zero &lt;code&gt;outerW&lt;/code&gt; means you're clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cause 2: &lt;code&gt;double_click&lt;/code&gt; fires too slowly and becomes two single clicks
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;computer&lt;/code&gt; tool's &lt;code&gt;double_click&lt;/code&gt; action can leave a gap between the two clicks that exceeds the app's double-click threshold. The app interprets it as two single clicks — so instead of entering text-edit mode, you get a row selection or nothing.&lt;/p&gt;

&lt;p&gt;The nasty part: the tool believes it sent a double-click. The logs look correct.&lt;/p&gt;

&lt;p&gt;You cannot see this failure in any log.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Plan A (preferred): stop using coordinates, use element references
&lt;/h3&gt;

&lt;p&gt;On a normal HTML page this is the reliable path. Drop coordinate clicks entirely. Use &lt;code&gt;find&lt;/code&gt; (natural-language element search) or &lt;code&gt;read_page&lt;/code&gt; (accessibility tree) to get element references, then click and fill through those references (&lt;code&gt;form_input&lt;/code&gt; for values). Element references survive layout shifts, so the settling problem simply doesn't apply.&lt;/p&gt;

&lt;p&gt;The exception: canvas/Flutter apps (the Rive editor, for example). Their UI doesn't exist as HTML elements, so &lt;code&gt;find&lt;/code&gt; and &lt;code&gt;read_page&lt;/code&gt; return nothing. Then Plan B is your only option.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plan B: if you must use coordinates, pair "wait for settle" with "rapid double-fire"
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Wait for the size to settle before doing anything — use the diagnostic snippet above until &lt;code&gt;innerW&lt;/code&gt; stabilizes, then take your screenshot&lt;/li&gt;
&lt;li&gt;Don't let time pass between screenshot and click. Capture → click on those fresh coordinates, as one unit. If anything intervened, re-capture&lt;/li&gt;
&lt;li&gt;Never use &lt;code&gt;double_click&lt;/code&gt;. Build your own with two rapid &lt;code&gt;left_click&lt;/code&gt;s at the same coordinates via &lt;code&gt;browser_batch&lt;/code&gt; — the gap gets tight enough to pass the threshold:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;browser_batch&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;computer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left_click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;coordinate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;tabId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;computer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left_click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;coordinate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;tabId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;After every click, &lt;code&gt;zoom&lt;/code&gt; into the target and verify the expected state change (selection, edit mode, highlight) before moving on. One unnoticed miss desyncs everything after it&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Cheat sheet
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;First suspect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Clicks miss&lt;/td&gt;
&lt;td&gt;Size not settled (Cause 1) — wait&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Double-click doesn't work&lt;/td&gt;
&lt;td&gt;Switch to rapid double-fire (Cause 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stuck on a normal HTML page&lt;/td&gt;
&lt;td&gt;Switch to Plan A (element refs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canvas/Flutter app&lt;/td&gt;
&lt;td&gt;Plan B only — there are no elements&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Limits and caveats
&lt;/h2&gt;

&lt;p&gt;The numbers here (1664→1920, 2–3 seconds) are from my setup (Windows, 1920×1080). Display config and DPI scaling will change them. Take the principle, not the numbers: wait for settle before you capture.&lt;/p&gt;

&lt;p&gt;Claude in Chrome ships updates frequently. If the tool ever starts waiting for size-settle itself, this whole workaround becomes unnecessary. And coordinate-based automation is inherently fragile — whenever element references are available, they win.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Verified: June 2026. Environment: Windows 11 / Chrome + Claude in Chrome extension / 1920×1080, including automation of the Rive editor (Flutter/canvas).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>chrome</category>
      <category>automation</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
