Skip to content

Modifer keys for mouse movement #581

Closed

Description

@DanielHeath

I'm testing a radiology application which assigns different meaning to mousedrag vs shift+mousedrag.

Currently that requires dropping all the way down from capybara to node.native.browser.page.command("Input.dispatchMouseEvent", to add the modifiers bitfield to the mousemove call.

Would a PR be accepted adding support for this?

My first thought is extending mouse.rb so you could call

Ferrum::Mouse.with_modifier_key(:shift) do 
  # within this block, all mouse events have the shift modifier added
end

Activity

  1. route commented on Oct 17, 2026

    @route
    Member

    Looked into this more closely. The gap is real: Mouse#down, #up and #click accept modifiers:, but Mouse#move doesn't, so there's no public way to do a modified drag. Even click(modifiers:) sends the preceding mousemove without them.

    I'd rather not go with Ferrum::Mouse.with_modifier_key(:shift) { } though:

    • It's class-level, so the state would be shared across all pages/threads instead of belonging to a page.
    • It keeps keyboard and mouse state separate, while in a real browser holding Shift affects both. Today keyboard.down(:shift) followed by keyboard.down("a") doesn't carry the modifier either, since each call starts from scratch.

    Proposal, similar to how Puppeteer/Playwright model it:

    1. Keyboard tracks held modifiers: keyboard.down(:shift) sets the bit, keyboard.up(:shift) clears it. Both key events and all mouse events (move, down, up, click) pick it up automatically.
    2. Mouse#move gets an explicit modifiers: option like down/up, overriding the held state when given.

    Your case then needs no new API:

    page.keyboard.down(:shift)
    page.mouse.move(x: 10, y: 10).down.move(x: 200, y: 200, steps: 10).up
    page.keyboard.up(:shift)

    On top of that we could add an instance-level helper, e.g. page.keyboard.hold(:shift) { ... } with up in an ensure, if it turns out to be handy. This would also let Cuprite support Capybara's drag_to(..., drop_modifiers: [:shift]).

    If that works for you, PR is welcome, otherwise I'll pick it up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions