The required range for the `animDropElementIndex` is between 0 and `this.ariaFocusableItems.length`, inclusive. That maximum value signifies that all tab strip items (and particularly the last one) need to shift out of the way because the user is dragging something to the end of the tab strip.
When dragging past the last tab strip item, `animDropElementIndex == this.ariaFocusableItems.length` and there is no overlapping element. In that scenario, we fall back to setting `dropElement = this.ariaFocusableItems[oldDropElementIndex]` but there is no such element. The `dropElement` is undefined, which ultimately results in calling `Tabbrowser.moveTabsAfter` and appending the dragged tab(s). That happens to be the right result.
However, if you do a short vertical drag, `dropElement` also does not get set, so whatever you were dragging moves to the end of the tab strip. That was bug 1959350 and we tried to fix it by not moving tabs if `dropElement` wasn't set. https://phabricator.services.mozilla.com/D247339
This had the side effect of not making it possible to drop a tab at the end of the tab strip if you were dragging forward. It was still possible to drag forward to the last position, then drag backward slightly to get the front edge of the tab to overlap the last tab in the tab strip, which would allow dropping into the last position.
I think the main thing that would help is to make sure that `dropElement` is always set for valid moves. When dragging past the last tab and there is no overlap, we can fall back to the last non-moving tab strip item.
I needed to swap around how we derive `dropElement` and `newDropElementIndex`. If we fall back to making `dropElement` the last tab, the existing code will try to use `dropElement.elementIndex` as the `newDropElementIndex`, which means the `animDropElementIndex` can never achieve the maximum value that it needs to show all of the tabs moving over. I made it so that we independently determine the `newDropElementIndex` fallback and the `dropElement` fallback without using `newDropElementIndex`.
After this change, `dropElement` should always be a valid non-moving tab strip item if a move should occur. If `dropElement` is undefined, then it's correct that no move should occur.
Differential Revision: https://phabricator.services.mozilla.com/D249715
This is more visible on Linux because the decorations there are bigger, but I
believe this also fixes issues on windows specially if you have the titlebar
checkbox on.
You need to use mozInnerScreen* coords in order to get the screen coordinates
of the client area.
Differential Revision: https://phabricator.services.mozilla.com/D246829
When using the tab context menu or drag-dropping tabs to put them into a group, record a metric for the number of tabs added to the group.
Data Science asked us to launch with this metric disabled so that they could control it using server knobs. They expect a high volume of events, so they expect to only enable this metric for some proportion of users.
I converted the existing `TabMove` event derived from `UIEvent` being fired when tabs change their tab index in the tab strip. `UIEvent` doesn't allow for attaching additional context/detail to the event. `TabMove` is now a `CustomEvent` that provides more context about the moved tab and it fires in more cases -- it's possible for the tab index not to change despite the tab having "moved" into/out of a tab group.
This approach would not capture tab movements that occur across multiple frames/event loop iterations.
Differential Revision: https://phabricator.services.mozilla.com/D244616
I expect that bug 1955112 was really a duplicate of bug 1954163. Based on that, let's remove this workaround since it's causing trouble.
Differential Revision: https://phabricator.services.mozilla.com/D244564
When dragging a pinned tab into an overflowing tab strip, it's possible to drop the pinned tab after the first unpinned tab. This causes one of the pinned tabs to be covered up, it breaks the browser's count of pinned tabs, and it can lead to breakages in drag-drop and the visual rendering of the tab strip.
An additional constraint on the drop position will make sure that a pinned tab can't drop between unpinned tabs and an unpinned tab can't drop between pinned tabs.
Differential Revision: https://phabricator.services.mozilla.com/D242748