Skip to content

script: Use constellation event's mouse button state instead of tracking count - #45628

Merged
mrobinson merged 1 commit into
servo:mainfrom
rhventures:steigeo/stuck-pointer-bug
Aug 19, 2026
Merged

mrobinson merged 1 commit into
servo:mainfrom
rhventures:steigeo/stuck-pointer-bug

Conversation

@steigeo

@steigeo steigeo commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Instead of keeping track of the number of mouse buttons currently pressed from within the document event handler, we use the input event from the constellation as the source of truth for currently pressed mouse buttons. This fixes an issue where the internal count would permanently increase, preventing the firing of pointerup/pointerdown events.

This also fixes an issue where the buttons field of pointer capture boundary transition events was improperly set to a button count instead of an integer bitmap.

Testing: The issue is caused by the embedder not sending a corresponding mouse up event with a mouse down one, so I'm not sure if WPT can enable us to test this.
Fixes: Partially fixes #45491, prevents pointerup/pointerdown events from breaking entirely.
Fixes #47300.

@steigeo
steigeo requested a review from gterzian as a code owner June 12, 2026 20:18
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Jun 12, 2026
@steigeo
steigeo marked this pull request as draft June 12, 2026 20:19
@steigeo

steigeo commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

Marking as draft for now so I can find which WPT tests have changed state.

@yezhizhen yezhizhen added the T-linux-wpt Do a try run of the WPT label Jun 15, 2026
@github-actions github-actions Bot removed the T-linux-wpt Do a try run of the WPT label Jun 15, 2026
@github-actions

Copy link
Copy Markdown

🔨 Triggering try run (#27528675703) for Linux (WPT)

@github-actions

Copy link
Copy Markdown

Test results for linux-wpt from try job (#27528675703):

Flaky unexpected result (56)
  • OK /IndexedDB/idbdatabase_deleteObjectStore.any.html (#43823)
    • PASS [expected FAIL] subtest: Deleted object store's name should be removed from database's list. Attempting to use a deleted IDBObjectStore should throw an InvalidStateError
  • FAIL [expected PASS] /css/css-backgrounds/background-size-041.html
  • OK /css/css-fonts/generic-family-keywords-001.html (#37467)
    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted generic(fangsong)

      assert_equals: quoted generic(fangsong) matches  @font-face rule expected 30 but got 50
      

    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted generic(kai)

      assert_equals: quoted generic(kai) matches  @font-face rule expected 30 but got 50
      

    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted generic(khmer-mul)

      assert_equals: quoted generic(khmer-mul) matches  @font-face rule expected 30 but got 50
      

    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted generic(nastaliq)

      assert_equals: quoted generic(nastaliq) matches  @font-face rule expected 30 but got 50
      

  • OK /css/css-fonts/variations/at-font-face-font-matching.html (#20684)
    • FAIL [expected PASS] subtest: Matching font-style: 'oblique 21deg' should prefer 'oblique 20deg' over 'oblique 10deg'

      assert_equals: Unexpected font on test element expected 487 but got 532
      

  • OK [expected ERROR] /fetch/fetch-later/quota/same-origin-iframe/multiple-iframes.https.window.html (#35176)
  • OK /fetch/metadata/window-open.https.sub.html (#40339)
    • FAIL [expected PASS] subtest: Same-site window, forced, reloaded

      The operation is insecure.
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-204.html (#44521)
    • FAIL [expected PASS] subtest: Navigating to a different document with link click

      Location's relevant Document is not same origin-domain with the entry settings object's origin
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/refresh/same-document-refresh.html (#34597)
    • FAIL [expected PASS] subtest: Same-Document Referrer from Refresh

      assert_equals: original page loads expected "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/refresh/resources/refresh-with-section.sub.html?url=%23section" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/refresh/resources/refresh-with-section.sub.html?url=%23section#section"
      

  • OK [expected TIMEOUT] /html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/form-submit-button-click.html (#44099)
    • FAIL [expected TIMEOUT] subtest: Replace before load, triggered by submitButton.click()

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?thereplacement=" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/resources/code-injector.html?pipe=sub(none)&code=%0A%20%20%20%20const%20form%20%3D%20document.createElement(%22form%22)%3B%0A%20%20%20%20form.action%20%3D%20%22%2Fcommon%2Fblank.html%22%3B%0A%0A%20%20%20%20const%20input%20%3D%20document.createElement(%22input%22)%3B%0A%20%20%20%20input.type%20%3D%20%22hidden%22%3B%0A%20%20%20%20input.name%20%3D%20%22thereplacement%22%3B%0A%20%20%20%20form.append(input)%3B%0A%0A%20%20%20%20const%20button%20%3D%20document.createElement(%22button%22)%3B%0A%20%20%20%20button.type%20%3D%20%22submit%22%3B%0A%20%20%20%20form.append(button)%3B%0A%0A%20%20%20%20document.currentScript.before(form)%3B%0A%20%20%20%20button.click()%3B%0A%20%20"
      

  • OK /html/browsers/history/the-history-interface/traverse_the_history_3.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • CRASH [expected OK] /html/browsers/history/the-location-interface/location_assign.html
  • CRASH [expected OK] /html/browsers/windows/nested-browsing-contexts/frameElement-siblings.sub.html
  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-replace-set-src.html (#32697)
    • PASS [expected FAIL] subtest: Navigating iframe loading='lazy' and then setting src: location.replace
  • OK /html/semantics/forms/form-submission-0/jsurl-form-submit.tentative.html (#36489)
    • PASS [expected FAIL] subtest: Verifies that form submissions scheduled inside javascript: urls take precedence over the javascript: url's return value.
  • CRASH [expected ERROR] /html/semantics/forms/the-select-element/customizable-select/select-appearance-button-after-span.html
  • TIMEOUT [expected OK] /html/syntax/parsing/html5lib_write.html?file=isindex
    • TIMEOUT [expected PASS] subtest: <isindex>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <isindex name="A" action="B" prompt="C" foo="D">

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <form><isindex>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <!doctype html><isindex>x</isindex>x

      Test timed out
      

  • OK /html/webappapis/dynamic-markup-insertion/document-write/module-tla-import.html (#42419)
    • FAIL [expected PASS] subtest: document.write in an imported module

      assert_true: onload must be called expected true got false
      

  • TIMEOUT [expected OK] /pointerevents/compat/pointerevent_touch-action_two-finger_interaction.html (#44693)
    • NOTRUN [expected PASS] subtest: touch two-finger pan on 'touch-action: pan-x pan-y'
    • NOTRUN [expected FAIL] subtest: touch two-finger pan on 'touch-action: pinch-zoom'
  • OK /pointerevents/compat/pointerevent_touch_target_after_pointerdown_target_removed.tentative.html (#42813)
    • PASS [expected FAIL] subtest: After a touchstart listener removes its target, touch events should be fired on the touchstart target even though an orphan and pointer events should be fired on the parent
    • PASS [expected FAIL] subtest: After a touchstart listener removes its target, touchmove event should be fired on the pointerdown target
  • OK /pointerevents/pointerevent_pointercapture_in_frame.html?pen (#45536)
    • FAIL [expected PASS] subtest: Test penpointer capture in same-origin frame: Pointer down at inner frame and set pointer capture.

      assert_true: Timed out waiting for lostpointercapture expected true got false
      

    • FAIL [expected PASS] subtest: Test penpointer capture in same-origin frame: Pointer down at inner frame and set pointer capture to outer frame should not capture.

      assert_array_equals: Received events: innerFrame received pointerdown,innerFrame received pointermove,innerFrame received pointerup,innerFrame received lostpointercapture lengths differ, expected array ["innerFrame received pointerdown", "innerFrame received pointermove", "innerFrame received pointerup"] length 3, got ["innerFrame received pointerdown", "innerFrame received pointermove", "innerFrame received pointerup", "innerFrame received lostpointercapture"] length 4
      

  • OK /pointerevents/pointerevent_pointercapture_in_frame.html?touch (#45445)
    • FAIL [expected PASS] subtest: Test touchpointer capture in same-origin frame: Pointer down at inner frame and set pointer capture.

      assert_true: Timed out waiting for lostpointercapture expected true got false
      

    • FAIL [expected PASS] subtest: Test touchpointer capture in same-origin frame: Pointer down at inner frame and set pointer capture to outer frame should not capture.

      assert_array_equals: Received events: innerFrame received pointerdown,innerFrame received pointermove,innerFrame received pointerup,innerFrame received lostpointercapture lengths differ, expected array ["innerFrame received pointerdown", "innerFrame received pointermove", "innerFrame received pointerup"] length 3, got ["innerFrame received pointerdown", "innerFrame received pointermove", "innerFrame received pointerup", "innerFrame received lostpointercapture"] length 4
      

  • CRASH [expected OK] /resource-timing/render-blocking-status-link.html (#41664)
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • PASS [expected TIMEOUT] subtest: Navigate a window via anchor with javascript:-urls in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ default policy in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a frame via anchor with javascript:-urls in enforcing mode.
  • TIMEOUT /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • PASS [expected FAIL] subtest: Navigate a frame via anchor with javascript:-urls in report-only mode.
  • OK /trusted-types/trusted-types-navigation.html?16-20 (#44835)
    • FAIL [expected PASS] subtest: Navigate a frame via area with javascript:-urls in report-only mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?26-30 (#38807)
    • PASS [expected TIMEOUT] subtest: Navigate a window via form-submission with javascript:-urls in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ default policy in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a frame via form-submission with javascript:-urls in enforcing mode.
    • PASS [expected NOTRUN] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in enforcing mode.
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?31-35 (#38034)
    • PASS [expected TIMEOUT] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in report-only mode.
    • FAIL [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy throwing an exception in enforcing mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

    • FAIL [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy throwing an exception in report-only mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

    • FAIL [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy making the URL invalid in enforcing mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

  • OK /visual-viewport/resize-event-order.html (#41981)
    • PASS [expected FAIL] subtest: Popup: DOMWindow resize fired before VisualViewport.
  • CRASH [expected OK] /workers/SharedWorker-extendedLifetime-data.html
  • CRASH [expected ERROR] /workers/Worker-replace-self.any.sharedworker.html
  • CRASH [expected OK] /workers/Worker-timeout-increasing-order.html
  • CRASH [expected OK] /workers/WorkerLocation-origin.sub.window.html
  • CRASH [expected OK] /workers/WorkerLocation_search.htm
  • CRASH [expected OK] /workers/WorkerLocation_search_fragment.htm
  • CRASH [expected OK] /workers/WorkerNavigator_appName.htm
  • CRASH [expected OK] /workers/WorkerNavigator_userAgentData.http.html
  • CRASH [expected OK] /workers/constructors/SharedWorker/URLMismatchError.htm
  • CRASH [expected OK] /workers/constructors/SharedWorker/null-arguments.html
  • CRASH [expected OK] /workers/constructors/SharedWorker/same-origin.html
  • CRASH [expected OK] /workers/constructors/SharedWorker/unexpected-global-properties.html
  • CRASH [expected OK] /workers/constructors/Worker/constructor-utf16-bom.html
  • CRASH [expected TIMEOUT] /workers/data-url-shared.html
  • CRASH [expected OK] /workers/dedicated-worker-from-blob-url.window.html (#22286)
  • CRASH [expected OK] /workers/dedicated-worker-parse-error-failure.html
  • CRASH [expected OK] /workers/interfaces/DedicatedWorkerGlobalScope/EventTarget.worker.html
  • CRASH [expected OK] /workers/interfaces/DedicatedWorkerGlobalScope/postMessage/second-argument-undefined.html
  • CRASH [expected ERROR] /workers/interfaces/WorkerGlobalScope/location/returns-same-object.any.sharedworker.html
  • CRASH [expected TIMEOUT] /workers/interfaces/WorkerGlobalScope/onerror/message-classic-DOMException.html
  • CRASH [expected ERROR] /workers/interfaces/WorkerGlobalScope/self.any.serviceworker.html
  • CRASH [expected OK] /workers/interfaces/WorkerUtils/WindowTimers/002.html
  • CRASH [expected OK] /workers/interfaces/WorkerUtils/importScripts/004.html
  • CRASH [expected ERROR] /workers/interfaces/WorkerUtils/importScripts/report-error-redirect-to-cross-origin.sub.any.sharedworker.html
  • CRASH [expected OK] /workers/modules/dedicated-worker-import-blob-url.any.worker.html
  • CRASH [expected OK] /workers/modules/shared-worker-import-failure.html
  • CRASH [expected OK] /workers/modules/shared-worker-import-meta.html
  • CRASH [expected OK] /workers/modules/shared-worker-import.window.html
Stable unexpected results that are known to be intermittent (16)
  • TIMEOUT /FileAPI/url/url-in-tags-revoke.window.html (#19978)
    • PASS [expected TIMEOUT] subtest: Fetching a blob URL immediately before revoking it works in <script> tags.
  • OK /beacon/beacon-basic.https.window.html (#41723)
    • FAIL [expected PASS] subtest: Payload size restriction should be accumulated: type = string

      assert_false: expected false got true
      

  • TIMEOUT [expected OK] /content-security-policy/inheritance/auxiliary-blank-document.html (#44821)
    • TIMEOUT [expected PASS] subtest: window.open() inherits CSPs on transient about:blank.

      Test timed out
      

  • OK [expected CRASH] /content-security-policy/meta/sandbox-iframe.html (#43478)
    • FAIL [expected PASS] subtest: img-src 'self' works when specified in a meta tag.

      assert_equals: expected "PASS" but got "FAIL"
      

  • PASS [expected FAIL] /css/css-fonts/font-feature-settings-descriptor-01.html (#45418)
  • FAIL [expected PASS] /css/css-text-decor/text-underline-position-from-font-variable.html (#45615)
  • CRASH [expected TIMEOUT] /html/browsers/history/the-location-interface/location_replace_session_history.html (#41896)
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • TIMEOUT [expected FAIL] subtest: Host element with delegatesFocus including no focusable descendants should be skipped

      Test timed out
      

    • NOTRUN [expected FAIL] subtest: Area element should support autofocus
  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/update-the-rendering.html (#24145)
    • FAIL [expected TIMEOUT] subtest: "Flush autofocus candidates" should be happen before a scroll event and animation frame callbacks

      assert_array_equals: animationFrame lengths differ, expected array ["autofocus", "scroll", "animationFrame"] length 3, got ["animationFrame"] length 1
      

  • OK [expected TIMEOUT] /html/semantics/embedded-content/media-elements/src_object_blob.html (#40340)
    • PASS [expected TIMEOUT] subtest: HTMLMediaElement.srcObject blob
  • OK /html/user-activation/navigation-state-reset-sameorigin.html (#45151)
    • FAIL [expected PASS] subtest: Post-navigation state reset.

      assert_true: child-two sticky user activation state after loaded expected true got false
      

  • TIMEOUT [expected OK] /infrastructure/testdriver/click_nested.html (#43887)
    • NOTRUN [expected FAIL] subtest: TestDriver click method with multiple windows and nested iframe
  • OK /resource-timing/test_resource_timing.https.html (#25216)
    • PASS [expected FAIL] subtest: PerformanceEntry has correct name, initiatorType, startTime, and duration (img)
  • OK /touch-events/single-tap-when-touchend-listener-use-sync-xhr.html (#41175)
    • PASS [expected FAIL] subtest: Click event should be fired when touchend opens synchronous XHR
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?11-15 (#44834)
    • PASS [expected TIMEOUT] subtest: Navigate a window via area with javascript:-urls in report-only mode.
  • TIMEOUT [expected OK] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • TIMEOUT [expected FAIL] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe

      Test timed out
      

Stable unexpected results (7)
  • TIMEOUT [expected OK] /pointerevents/pointerevent_boundary_events_at_implicit_release_hoverable_pointers.html
    • NOTRUN [expected PASS] subtest: mouse Event sequence at implicit release on click
  • TIMEOUT [expected OK] /pointerevents/pointerevent_capture_mouse.html
    • NOTRUN [expected PASS] subtest: lostpointercapture event received
  • OK /pointerevents/pointerevent_click_during_capture.html?mouse-click
    • FAIL [expected PASS] subtest: pointerdown/up at child1, capture at child1

      assert_equals: expected "pointerdown@child1,gotpointercapture@child1,pointerup@child1,lostpointercapture@child1,click@child1" but got "pointerdown@child1,gotpointercapture@child1,pointerup@child1,click@child1,pointerdown@child1,pointerup@child1"
      

  • OK /pointerevents/pointerevent_pointercapture-not-lost-in-chorded-buttons.html
    • FAIL [expected PASS] subtest: Pointer Events Capture Test - capture not lost due to chorded buttons interaction

      assert_equals: Current Phase should be up_done.lostpointercapture should happen after pointerup event. expected "up_done" but got "up"
      

    • FAIL [expected PASS] subtest: Pointer Events Capture Test - capture not lost due to combination of left and right chorded buttons interaction.

      assert_equals: Current Phase should be up expected "up" but got "down"
      

  • TIMEOUT [expected OK] /pointerevents/pointerevent_releasepointercapture_onpointerup_mouse.html
  • OK /pointerevents/pointerevent_sequence_at_implicit_release_on_click.html?mouse
    • FAIL [expected PASS] subtest: mouse Boundary events are emitted after lostpointercapture

      assert_true: expected true got false
      

    • FAIL [expected PASS] subtest: No extra events are emitted

      assert_equals: expected "" but got "pointerup, pointerup"
      

  • OK /pointerevents/pointerevent_setpointercapture_to_same_element_twice.html?mouse
    • FAIL [expected PASS] subtest: A repeated setPointerCapture call does not redispatch capture events

      assert_array_equals: events received lengths differ, expected array ["pointerdown@target", "gotpointercapture@other", "pointermove@other", "pointerup@other", "lostpointercapture@other"] length 5, got ["pointerdown@target", "gotpointercapture@other", "pointermove@other", "pointerup@other", "pointerdown@other", "pointerup@other"] length 6
      

    • FAIL [expected PASS] subtest: A failed setPointerCapture call does not affect existing capture

      assert_array_equals: events received expected property 0 to be "pointerdown@target" but got "pointerdown@other" (expected array ["pointerdown@target", "gotpointercapture@other", "pointermove@other", "pointerup@other", "lostpointercapture@other"] got ["pointerdown@other", "pointermove@other", "pointerup@other", "pointerdown@other", "pointerup@other"])
      

@github-actions

Copy link
Copy Markdown

⚠️ Try run (#27528675703) failed!

@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

🤖 Opened new upstream WPT pull request (web-platform-tests/wpt#60647) with upstreamable changes.

@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

✍ Updated existing upstream WPT pull request (web-platform-tests/wpt#60647) title and body.

@steigeo
steigeo marked this pull request as ready for review June 15, 2026 19:00
@steigeo

steigeo commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

The test seems to have timeout issues in other browsers. I'll probably reduce the number of chords tested to increase the speed of the tests to see if that addresses these issues.

@steigeo
steigeo force-pushed the steigeo/stuck-pointer-bug branch from cb4ae21 to c3a273f Compare June 16, 2026 13:02
@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#60647).

@steigeo

steigeo commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Not sure why we're still running into timeout issues in other browsers -- upon manual testing, the same behavior seems to work fine in both Firefox and Chromium. Maybe the other browsers are somehow reading the mouse inputs (forward/back buttons) as navigation instructions? But performing the same actions manually doesn't cause navigation in these browsers. I'll look into setting up a WPT environment for other browsers on my machine to find the cause of this issue.

@steigeo
steigeo force-pushed the steigeo/stuck-pointer-bug branch from c3a273f to da61ce9 Compare June 30, 2026 18:17
@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#60647).

@steigeo
steigeo force-pushed the steigeo/stuck-pointer-bug branch from da61ce9 to 64490c7 Compare August 19, 2026 13:23
@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

🤖 This change no longer contains upstreamable changes to WPT; closed existing upstream pull request (web-platform-tests/wpt#60647).

@servo-highfive servo-highfive added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Aug 19, 2026
Signed-off-by: Oskar Steiger <steigeo@rose-hulman.edu>
@steigeo
steigeo force-pushed the steigeo/stuck-pointer-bug branch from 64490c7 to 7f8bd5c Compare August 19, 2026 14:33
@servo-highfive servo-highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Aug 19, 2026
@steigeo

steigeo commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Also fixes #47300

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Aug 19, 2026
@mrobinson
mrobinson added this pull request to the merge queue Aug 19, 2026
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Aug 19, 2026
Merged via the queue into servo:main with commit 808e652 Aug 19, 2026
40 checks passed
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Aug 19, 2026
RichardTjokroutomo pushed a commit to RichardTjokroutomo/servo that referenced this pull request Oct 6, 2026
…ing count (servo#45628)

Instead of keeping track of the number of mouse buttons currently
pressed from within the document event handler, we use the input event
from the constellation as the source of truth for currently pressed
mouse buttons. This fixes an issue where the internal count would
permanently increase, preventing the firing of `pointerup`/`pointerdown`
events.

This also fixes an issue where the `buttons` field of pointer capture
boundary transition events was improperly set to a button count instead
of an integer bitmap.

Testing: The issue is caused by the embedder not sending a corresponding
mouse up event with a mouse down one, so I'm not sure if WPT can enable
us to test this.
Fixes: Partially fixes servo#45491, prevents `pointerup`/`pointerdown` events
from breaking entirely.
Fixes servo#47300.

Signed-off-by: Oskar Steiger <steigeo@rose-hulman.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The buttons argument passed to PointerEvent::new is wrong in fire_pointer_boundary_event Mouseup events are not sent if mouse is dragged off page

5 participants