Compare commits

...

4 Commits
1.21.3b ... dev

Author SHA1 Message Date
Bernhard
183c583841 gh-14320: fix workspace change icon picker state when opening (gh-14321)
The picker reset its page with a smooth scrollIntoView while the popup
was hiding, and positioned the page before the popup was laid out, so it
could animate/jump on open. Reset instantly on popupshown (after layout)
instead, and drop the on-hide scroll so there's no visible animation.
2026-06-21 21:43:44 +02:00
fen4flo
40080a25dc gh-11245: Fix tab placement with Move Tab / Space Routing (gh-14324)
Fixes #11245
2026-06-21 15:18:02 +02:00
Connor Griffin
733061fbe3 gh-11766: Fixed video fullscreen not working while in glance (gh-14272)
Co-authored-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
Signed-off-by: mr. m <91018726+mr-cheffy@users.noreply.github.com>
2026-06-21 11:20:37 +02:00
Andrey Bochkarev
61e631902c gh-14131: Prevent sidebar from flickering when moving a tab (gh-14293)
Co-authored-by: mr. m <mr.m@tuta.com>
2026-06-20 17:18:41 +02:00
5 changed files with 124 additions and 62 deletions

View File

@@ -1,8 +1,23 @@
diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js
index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9ea21b6f6 100644 index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..b9a1cfe3a4a5035d9b06b0b3826a97c52cfcb39e 100644
--- a/browser/components/tabbrowser/content/tabs.js --- a/browser/components/tabbrowser/content/tabs.js
+++ b/browser/components/tabbrowser/content/tabs.js +++ b/browser/components/tabbrowser/content/tabs.js
@@ -220,7 +220,7 @@ @@ -197,8 +197,12 @@
XPCOMUtils.defineLazyPreferenceGetter(
this,
"_sidebarPositionStart",
- "sidebar.position_start",
- true
+ "zen.tabs.vertical.right-side",
+ true,
+ null,
+ newValue => {
+ return !newValue;
+ }
);
if (gMultiProcessBrowser) {
@@ -220,7 +224,7 @@
this.tooltip = "tabbrowser-tab-tooltip"; this.tooltip = "tabbrowser-tab-tooltip";
@@ -11,7 +26,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
this.tabDragAndDrop.init(); this.tabDragAndDrop.init();
} }
@@ -444,7 +444,7 @@ @@ -444,7 +448,7 @@
// and we're not hitting the scroll buttons. // and we're not hitting the scroll buttons.
if ( if (
event.button != 0 || event.button != 0 ||
@@ -20,7 +35,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
event.composedTarget.localName == "toolbarbutton" event.composedTarget.localName == "toolbarbutton"
) { ) {
return; return;
@@ -525,7 +525,6 @@ @@ -525,7 +529,6 @@
}); });
} }
} else if (isTabGroupLabel(event.target)) { } else if (isTabGroupLabel(event.target)) {
@@ -28,7 +43,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
} else if ( } else if (
event.originalTarget.closest("scrollbox") && event.originalTarget.closest("scrollbox") &&
!Services.prefs.getBoolPref( !Services.prefs.getBoolPref(
@@ -561,6 +560,9 @@ @@ -561,6 +564,9 @@
} }
on_keydown(event) { on_keydown(event) {
@@ -38,7 +53,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
let { altKey, shiftKey } = event; let { altKey, shiftKey } = event;
let [accel, nonAccel] = let [accel, nonAccel] =
AppConstants.platform == "macosx" AppConstants.platform == "macosx"
@@ -755,7 +757,6 @@ @@ -755,7 +761,6 @@
this._updateCloseButtons(); this._updateCloseButtons();
if (!this.#animatingGroups.size) { if (!this.#animatingGroups.size) {
@@ -46,7 +61,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
} }
document document
@@ -822,7 +823,7 @@ @@ -822,7 +827,7 @@
} }
get newTabButton() { get newTabButton() {
@@ -55,7 +70,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
} }
get verticalMode() { get verticalMode() {
@@ -838,6 +839,7 @@ @@ -838,6 +843,7 @@
} }
get overflowing() { get overflowing() {
@@ -63,7 +78,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
return this.hasAttribute("overflow"); return this.hasAttribute("overflow");
} }
@@ -851,29 +853,56 @@ @@ -851,29 +857,56 @@
if (pinnedChildren?.at(-1)?.id == "pinned-tabs-container-periphery") { if (pinnedChildren?.at(-1)?.id == "pinned-tabs-container-periphery") {
pinnedChildren.pop(); pinnedChildren.pop();
} }
@@ -93,7 +108,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
+ } else if (!isTab(tab)) { + } else if (!isTab(tab)) {
+ tabs.splice(i, 1); + tabs.splice(i, 1);
+ } + }
} + }
+ }; + };
+ expandTabs(pinnedTabs); + expandTabs(pinnedTabs);
+ expandTabs(unpinnedChildren); + expandTabs(unpinnedChildren);
@@ -114,7 +129,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
+ // remove the separator from the list + // remove the separator from the list
+ allTabs.splice(i, 1); + allTabs.splice(i, 1);
+ i--; + i--;
+ } }
+ i++; + i++;
} }
- -
@@ -130,7 +145,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
} }
get allSplitViews() { get allSplitViews() {
@@ -958,29 +987,28 @@ @@ -958,29 +991,28 @@
return this.#focusableItems; return this.#focusableItems;
} }
@@ -170,7 +185,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
this.#focusableItems = focusableItems; this.#focusableItems = focusableItems;
return this.#focusableItems; return this.#focusableItems;
@@ -993,6 +1021,7 @@ @@ -993,6 +1025,7 @@
* focusable (ex, we don't want the splitview container to be focusable, only its children). * focusable (ex, we don't want the splitview container to be focusable, only its children).
*/ */
get dragAndDropElements() { get dragAndDropElements() {
@@ -178,7 +193,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
if (this.#dragAndDropElements) { if (this.#dragAndDropElements) {
return this.#dragAndDropElements; return this.#dragAndDropElements;
} }
@@ -1063,6 +1092,7 @@ @@ -1063,6 +1096,7 @@
_invalidateCachedTabs() { _invalidateCachedTabs() {
this.#allTabs = null; this.#allTabs = null;
this._invalidateCachedVisibleTabs(); this._invalidateCachedVisibleTabs();
@@ -186,7 +201,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
} }
_invalidateCachedVisibleTabs() { _invalidateCachedVisibleTabs() {
@@ -1082,7 +1112,8 @@ @@ -1082,7 +1116,8 @@
isContainerVerticalPinnedGrid(tab) { isContainerVerticalPinnedGrid(tab) {
return ( return (
@@ -196,7 +211,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
this.verticalMode && this.verticalMode &&
this.hasAttribute("expanded") && this.hasAttribute("expanded") &&
!this.expandOnHover !this.expandOnHover
@@ -1176,7 +1207,7 @@ @@ -1176,7 +1211,7 @@
if (node == null) { if (node == null) {
// We have a container for non-tab elements at the end of the scrollbox. // We have a container for non-tab elements at the end of the scrollbox.
@@ -205,7 +220,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
} }
node.before(tab); node.before(tab);
@@ -1271,7 +1302,7 @@ @@ -1271,7 +1306,7 @@
// There are separate "new tab" buttons for horizontal tabs toolbar, vertical tabs and // There are separate "new tab" buttons for horizontal tabs toolbar, vertical tabs and
// for when the tab strip is overflowed (which is shared by vertical and horizontal tabs); // for when the tab strip is overflowed (which is shared by vertical and horizontal tabs);
// Attach the long click popup to all of them. // Attach the long click popup to all of them.
@@ -214,7 +229,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
const newTab2 = this.newTabButton; const newTab2 = this.newTabButton;
const newTabVertical = document.getElementById( const newTabVertical = document.getElementById(
"vertical-tabs-newtab-button" "vertical-tabs-newtab-button"
@@ -1376,8 +1407,10 @@ @@ -1376,8 +1411,10 @@
*/ */
_handleTabSelect(aInstant) { _handleTabSelect(aInstant) {
let selectedTab = this.selectedItem; let selectedTab = this.selectedItem;
@@ -225,7 +240,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
selectedTab._notselectedsinceload = false; selectedTab._notselectedsinceload = false;
} }
@@ -1386,7 +1419,7 @@ @@ -1386,7 +1423,7 @@
* @param {boolean} [shouldScrollInstantly=false] * @param {boolean} [shouldScrollInstantly=false]
*/ */
#ensureTabIsVisible(tab, shouldScrollInstantly = false) { #ensureTabIsVisible(tab, shouldScrollInstantly = false) {
@@ -234,7 +249,7 @@ index 568f3a7cc7051ff8cb569f6bcb8018a5212f7072..3036768b8911b4fbc28df7528f7189d9
if (arrowScrollbox?.overflowing) { if (arrowScrollbox?.overflowing) {
arrowScrollbox.ensureElementIsVisible(tab, shouldScrollInstantly); arrowScrollbox.ensureElementIsVisible(tab, shouldScrollInstantly);
} }
@@ -1513,7 +1546,7 @@ @@ -1513,7 +1550,7 @@
} }
_notifyBackgroundTab(aTab) { _notifyBackgroundTab(aTab) {

View File

@@ -28,7 +28,7 @@ const SVG_ICONS = [
"ticket.svg", "time.svg", "trash.svg", "triangle.svg", "ticket.svg", "time.svg", "trash.svg", "triangle.svg",
"video.svg", "volume-high.svg", "wallet.svg", "warning.svg", "video.svg", "volume-high.svg", "wallet.svg", "warning.svg",
"water.svg", "weight.svg", "water.svg", "weight.svg",
]; ];
class nsZenEmojiPicker extends nsZenDOMOperatedFeature { class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
#panel; #panel;
@@ -47,6 +47,7 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
init() { init() {
this.#panel = document.getElementById("PanelUI-zen-emojis-picker"); this.#panel = document.getElementById("PanelUI-zen-emojis-picker");
this.#panel.addEventListener("popupshowing", this); this.#panel.addEventListener("popupshowing", this);
this.#panel.addEventListener("popupshown", this);
this.#panel.addEventListener("popuphidden", this); this.#panel.addEventListener("popuphidden", this);
this.#panel.addEventListener("command", this); this.#panel.addEventListener("command", this);
this.searchInput.addEventListener("input", this); this.searchInput.addEventListener("input", this);
@@ -57,6 +58,9 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
case "popupshowing": case "popupshowing":
this.#onPopupShowing(event); this.#onPopupShowing(event);
break; break;
case "popupshown":
this.#onPopupShown(event);
break;
case "popuphidden": case "popuphidden":
this.#onPopupHidden(event); this.#onPopupHidden(event);
break; break;
@@ -103,17 +107,20 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
return document.getElementById("PanelUI-zen-emojis-picker-search"); return document.getElementById("PanelUI-zen-emojis-picker-search");
} }
#changePage(toSvg = false) { #changePage(toSvg = false, { animate = true } = {}) {
const pages = document.getElementById("PanelUI-zen-emojis-picker-pages");
const itemToScroll = toSvg const itemToScroll = toSvg
? this.svgList ? this.svgList
: document : pages.querySelector('[emojis="true"]');
.getElementById("PanelUI-zen-emojis-picker-pages") if (animate) {
.querySelector('[emojis="true"]');
itemToScroll.scrollIntoView({ itemToScroll.scrollIntoView({
behavior: "smooth", behavior: "smooth",
block: "nearest", block: "nearest",
inline: "start", inline: "start",
}); });
} else {
pages.scrollLeft = toSvg ? itemToScroll.offsetLeft : 0;
}
const button = document.getElementById( const button = document.getElementById(
`PanelUI-zen-emojis-picker-change-${toSvg ? "svg" : "emojis"}` `PanelUI-zen-emojis-picker-change-${toSvg ? "svg" : "emojis"}`
); );
@@ -180,9 +187,6 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
}); });
emojiList.appendChild(item); emojiList.appendChild(item);
} }
setTimeout(() => {
this.searchInput.focus();
}, 500);
} }
const svgList = this.svgList; const svgList = this.svgList;
for (const icon of SVG_ICONS) { for (const icon of SVG_ICONS) {
@@ -199,14 +203,23 @@ class nsZenEmojiPicker extends nsZenDOMOperatedFeature {
} }
} }
#onPopupShown(event) {
if (event.target !== this.#panel) {
return;
}
const allowEmojis = !this.#panel.hasAttribute("only-svg-icons");
if (allowEmojis) {
this.searchInput.focus({ preventScroll: true });
}
this.#changePage(false, { animate: false });
}
#onPopupHidden(event) { #onPopupHidden(event) {
if (event.target !== this.#panel) { if (event.target !== this.#panel) {
return; return;
} }
this.#clearEmojis(); this.#clearEmojis();
this.#changePage(false);
const emojiList = this.emojiList; const emojiList = this.emojiList;
emojiList.innerHTML = ""; emojiList.innerHTML = "";

View File

@@ -723,8 +723,11 @@
const { isNearLeftEdge, isNearRightEdge } = const { isNearLeftEdge, isNearRightEdge } =
this.#shouldSwitchSpace(event); this.#shouldSwitchSpace(event);
if (isNearLeftEdge || isNearRightEdge) { if (isNearLeftEdge || isNearRightEdge) {
if (!this.#changeSpaceTimer) { if (!this.#changeSpaceTimer && !this.#isOutOfWindow) {
this.#changeSpaceTimer = setTimeout(() => { this.#changeSpaceTimer = setTimeout(() => {
if (this.#isOutOfWindow) {
return;
}
this.clearDragOverVisuals(); this.clearDragOverVisuals();
gZenWorkspaces gZenWorkspaces
.changeWorkspaceShortcut( .changeWorkspaceShortcut(
@@ -956,8 +959,10 @@
if (ownerGlobal?.gZenCompactModeManager) { if (ownerGlobal?.gZenCompactModeManager) {
// Sometimes, dragend doesn't always get called when dragging // Sometimes, dragend doesn't always get called when dragging
// to different windows, see gh-8643. // to different windows, see gh-8643.
requestAnimationFrame(() => {
delete ownerGlobal.gZenCompactModeManager._isTabBeingDragged; delete ownerGlobal.gZenCompactModeManager._isTabBeingDragged;
ownerGlobal.gZenCompactModeManager._clearAllHoverStates(); ownerGlobal.gZenCompactModeManager._clearAllHoverStates();
});
} }
this.clearSpaceSwitchTimer(); this.clearSpaceSwitchTimer();
gZenFolders.highlightGroupOnDragOver(null); gZenFolders.highlightGroupOnDragOver(null);

View File

@@ -53,6 +53,10 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
#setupEventListeners() { #setupEventListeners() {
window.addEventListener("TabClose", this.onTabClose.bind(this)); window.addEventListener("TabClose", this.onTabClose.bind(this));
window.addEventListener("TabSelect", this.onLocationChange.bind(this)); window.addEventListener("TabSelect", this.onLocationChange.bind(this));
window.addEventListener(
"MozDOMFullscreen:Entered",
this.onFullscreenEntered.bind(this)
);
document document
.getElementById("tabbrowser-tabpanels") .getElementById("tabbrowser-tabpanels")
@@ -1414,6 +1418,23 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
} }
} }
/**
* Handle DOM Fullscreen request while inside glance
*
* @param {Event} event - The MozDOMFullscreen:Entered event
*/
onFullscreenEntered(event) {
const browser = this.#currentBrowser;
if (!browser) {
return;
}
if (event.target === browser) {
this.fullyOpenGlance();
}
}
/** /**
* Manage tab close for glance tabs * Manage tab close for glance tabs
* *

View File

@@ -1506,19 +1506,27 @@ class nsZenWorkspaces {
continue; continue;
} }
const newtabPlacement = Services.prefs.getBoolPref(
"zen.view.show-newtab-button-top",
false
);
const insertElement = newtabPlacement
? container.firstChild
: container.lastChild;
if (container) { if (container) {
if (tab.group?.hasAttribute("split-view-group")) { if (tab.group?.hasAttribute("split-view-group")) {
gBrowser.zenHandleTabMove(tab.group, () => { gBrowser.zenHandleTabMove(tab.group, () => {
for (const subTab of tab.group.tabs) { for (const subTab of tab.group.tabs) {
subTab.setAttribute("zen-workspace-id", workspaceID); subTab.setAttribute("zen-workspace-id", workspaceID);
} }
container.insertBefore(tab.group, container.lastChild); container.insertBefore(tab.group, insertElement);
}); });
continue; continue;
} }
gBrowser.zenHandleTabMove(tab, () => { gBrowser.zenHandleTabMove(tab, () => {
tab.setAttribute("zen-workspace-id", workspaceID); tab.setAttribute("zen-workspace-id", workspaceID);
container.insertBefore(tab, container.lastChild); container.insertBefore(tab, insertElement);
}); });
} }
// also change glance tab if it's the same tab // also change glance tab if it's the same tab