Closed Bug 1955625 Opened 1 year ago Closed 5 months ago

Mouse cursor should not affect ctrl+tab cycling unless it moves

Categories

(Firefox :: Tabbed Browser, defect, P3)

Firefox 139
x86_64
macOS
defect

Tracking

()

RESOLVED FIXED
147 Branch
Tracking Status
firefox147 --- fixed

People

(Reporter: mreid, Assigned: aaronkplus2, NeedInfo)

References

(Blocks 1 open bug)

Details

Attachments

(1 file, 1 obsolete file)

The behaviour of mouse interactions with "Ctrl+Tab cycles through tabs in recently used order" has changed in the past couple of Firefox versions, I think the old behaviour was correct.

Steps to reproduce:

Actual behaviour:
Tab A selected.

Expected behaviour:
Tab C selected.

I would only expect the mouse position to override the ctrl+tab selection if the mouse moves after ctrl is pressed down.

If you move the mouse cursor to the bottom of the screen where it doesn't overlap with the tab previews, it behaves as expected.

Also note that if I cycle tabs very quickly (before the tab previews show up), it behaves as expected.

This should be fixed in 137.

Status: NEW → RESOLVED
Closed: 1 year ago
Duplicate of bug: 1935022
Resolution: --- → DUPLICATE

This is happening in Firefox 139.0.1 - though now it seems to occasionally work as expected.

Status: RESOLVED → REOPENED
No longer duplicate of bug: 1935022
Resolution: DUPLICATE → ---
Version: Firefox 136 → Firefox 139
Depends on: 1935022
Duplicate of this bug: 1968253
Severity: -- → S3
Component: Keyboard Navigation → Tabbed Browser
Priority: -- → P3

Bug 1955670 is a duplicate of this. Not sure which bug should be a duplicate of the other. I have been facing this issue for a while on macOS. Sometimes it works correctly and selects the next tab, but most of the time it doesn't. The bug is reproducible in a new profile.

The fix in commit 84d4137 will wait for two animation frames before the panel begins handling mouseover events. See firefox/browser/components/tabbrowser/content/browser-ctrlTab.js:541 (setupGui). The bug occurs with the same frequency on a freshly created profile with the system at 95% idle and only three tabs open as it does on my main profile with 100 tabs open, which proves the problem is not related to performance. Either two animation frames are passing before the initial mouseover event is sent or a mouseover event is being sent before setupGui is called.

Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:140.0) Gecko/20100101 Firefox/140.0

Duplicate of this bug: 1955670
Depends on: 1978837

(In reply to Terence Noone from comment #5)

The fix in commit 84d4137 will wait for two animation frames before the panel begins handling mouseover events. See firefox/browser/components/tabbrowser/content/browser-ctrlTab.js:541 (setupGui). The bug occurs with the same frequency on a freshly created profile with the system at 95% idle and only three tabs open as it does on my main profile with 100 tabs open, which proves the problem is not related to performance. Either two animation frames are passing before the initial mouseover event is sent or a mouseover event is being sent before setupGui is called.

Thanks for your analysis. I filed bug 1978837 to cover the potential case of mousover being sent before setupGui runs. Would you mind testing if this helps in Nightly?

Flags: needinfo?(me)
Flags: needinfo?(bugilla)

(In reply to Dão Gottwald [:dao] from comment #7)

Thanks for your analysis. I filed bug 1978837 to cover the potential case of mousover being sent before setupGui runs. Would you mind testing if this helps in Nightly?

I just tested this on Nightly build 20250723215755 on macOS 15.5 - doesn't seem to have helped, I can still see the incorrect behavior.

Attached patch ctrlTab.patch (obsolete) — Splinter Review

The bug was still present with your fix. I built my own copy of Nightly and added some logging to understand the bug more, and two mouseover events were being fired initially.

I tried ignoring the first two events, but the problem is that if the user then moves the mouse a small amount to signal they really do want to select that option, an event will not be fired.

I quickly whipped up a patch that replaces the mouseover event with a mousemove event. This works perfectly on macOS, but I have not tested it on any other platform yet. The only downside I can see from using mousemove over mouseover is that a lot more events are fired. Let me know if this method of detecting the mouse would not work.

Flags: needinfo?(me)

(In reply to Terence Noone from comment #9)

I quickly whipped up a patch that replaces the mouseover event with a mousemove event. This works perfectly on macOS, but I have not tested it on any other platform yet.

I thought we also synthesized mousemove events so I'm surprised this works...

The only downside I can see from using mousemove over mouseover is that a lot more events are fired. Let me know if this method of detecting the mouse would not work.

Perhaps we could also use the first mousemove as a guard before accepting mouseover events. 🤔

Have you considered switching to pointerenter? I think pointerenter won't fire until the cursor moves

(In reply to Gregory Pappas [:gregp] from comment #11)

Have you considered switching to pointerenter? I think pointerenter won't fire until the cursor moves

That's essentially the same as mouseenter for our purposes, right? From what I know mouseenter is discouraged for performance reasons, see https://searchfox.org/mozilla-central/rev/488c0c38dbe349a068bb72bc8b67905038826c66/dom/events/EventListenerManager.cpp#489-492

I think the solution is probably not to change which event we listen for, and instead we should change the behavior of mouseover and mouseenter. There are three ways I see that these events could behave when an element appears below the mouse without the mouse moving:

a) mouseenter and mouseover events are fired when the element appears
b) mouseenter and mouseover events are not fired until the cursor leaves and reenters the element.
c) mouseenter and mouseover events are not fired until the cursor leaves and reenters the element or the mouse moves a certain distance.

(a) is what Firefox does, (b) is what Google Chrome does, and (c) is what I think would probably be best, but it would require setting an arbitrary threshold. Note that we could use a speed threshold instead of a distance threshold.

Here is a simple site for testing the behavior
data:text/html,%3Cdiv%20onmouseenter%3D%22console.log%28event%29%22%20onmouseover%3D%22console.log%28event%29%22%20style%3D%22width%3A100px%3Bheight%3A100px%3Bborder%3Asolid%20red%3Bmargin%3A40svh%20auto%3B%22%3E%3C%2Fdiv%3E

I don't know if changing the behavior of an event is out of scope for fixing this bug, but I think the current behavior of these events is bad and this is a chance to fix a bigger issue.

Actually there's a fourth option

d) mouseenter and mouseover events are not fired until the mouse moves

I think that may be the best option. But probably we should choose whichever of (b) or (d) has a cleaner implementation. In trying to understand the code right now and I'll submit a patch soon.

After thinking more, this behavior is fine in most cases, and it's a natural consequence of synthetic mouse events which are a pretty clean solution to the problems they solve. This behavior is only annoying when mouseover events take a significant action, ie impact some state. The tab switcher is the only example I can find where mouseover events do something more than transient.

Assignee: nobody → aaronkplus2
Attachment #9502793 - Attachment is obsolete: true
Status: REOPENED → RESOLVED
Closed: 1 year ago5 months ago
Resolution: --- → FIXED
Target Milestone: --- → 147 Branch
QA Whiteboard: [qa-triage-done-c148/b147] [qa-ver-opt-c148/b147]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: