feat: Polished split view creation and fixed minor details, b=no-bug, c=tabs, common, compact-mode, folders, glance, split-view, workspaces

This commit is contained in:
mr. m
2025-09-16 17:10:31 +02:00
parent ef09a30239
commit b0c53ed068
13 changed files with 69 additions and 55 deletions

View File

@@ -9,7 +9,7 @@
value: 8 value: 8
- name: zen.theme.dark-mode-bias - name: zen.theme.dark-mode-bias
value: 0.25 value: 0.3
- name: zen.theme.gradient - name: zen.theme.gradient
value: true value: true

View File

@@ -1,5 +1,5 @@
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 c7557dad38db9ef02b981c46de9595df77cb67db..c2001aac234d1575498df82db21da2374efe9697 100644 index c7557dad38db9ef02b981c46de9595df77cb67db..510cf06c69253ef25d1d411ad424d892fc91a208 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
@@ -44,6 +44,9 @@ @@ -44,6 +44,9 @@
@@ -415,7 +415,7 @@ index c7557dad38db9ef02b981c46de9595df77cb67db..c2001aac234d1575498df82db21da237
- (lastMovingTabScreenX + tabWidth); - (lastMovingTabScreenX + tabWidth);
- let lastBoundY = periphery.screenY - (lastMovingTabScreenY + tabHeight); - let lastBoundY = periphery.screenY - (lastMovingTabScreenY + tabHeight);
+ (lastMovingTabScreenX + tabWidth) + 4; + (lastMovingTabScreenX + tabWidth) + 4;
+ let lastBoundY = 0; + let lastBoundY = lastTab.screenY - lastMovingTabScreenY;
translateX = Math.min(Math.max(translateX, firstBoundX), lastBoundX); translateX = Math.min(Math.max(translateX, firstBoundX), lastBoundX);
translateY = Math.min(Math.max(translateY, firstBoundY), lastBoundY); translateY = Math.min(Math.max(translateY, firstBoundY), lastBoundY);

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/urlbar/UrlbarInput.sys.mjs b/browser/components/urlbar/UrlbarInput.sys.mjs diff --git a/browser/components/urlbar/UrlbarInput.sys.mjs b/browser/components/urlbar/UrlbarInput.sys.mjs
index 1c447bd31de854d1522dbcfb5d7ad557c84f1388..ff09a4c158b0f4a37dc3b01a5de9cb1062e526fe 100644 index 1c447bd31de854d1522dbcfb5d7ad557c84f1388..bb0934cf5f170e82de9876642833dc6e9910668c 100644
--- a/browser/components/urlbar/UrlbarInput.sys.mjs --- a/browser/components/urlbar/UrlbarInput.sys.mjs
+++ b/browser/components/urlbar/UrlbarInput.sys.mjs +++ b/browser/components/urlbar/UrlbarInput.sys.mjs
@@ -74,6 +74,13 @@ ChromeUtils.defineLazyGetter(lazy, "logger", () => @@ -74,6 +74,13 @@ ChromeUtils.defineLazyGetter(lazy, "logger", () =>
@@ -70,7 +70,7 @@ index 1c447bd31de854d1522dbcfb5d7ad557c84f1388..ff09a4c158b0f4a37dc3b01a5de9cb10
+ if (this._zenHandleUrlbarClose) { + if (this._zenHandleUrlbarClose) {
+ this._zenHandleUrlbarClose(true, true); + this._zenHandleUrlbarClose(true, true);
+ } else { + } else {
+ this.view.close({ elementPicked: true }); + this.window.setTimeout(() => this.view.close({ elementPicked: true }), 0);
+ } + }
} }

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/urlbar/UrlbarView.sys.mjs b/browser/components/urlbar/UrlbarView.sys.mjs diff --git a/browser/components/urlbar/UrlbarView.sys.mjs b/browser/components/urlbar/UrlbarView.sys.mjs
index fdbab8806fd320f4aacec46a42c8ef953580d00c..2a6f22178aa42e8f1a7d0b58e02db85f712b01dc 100644 index fdbab8806fd320f4aacec46a42c8ef953580d00c..e23fae0d7e0b71d74899c11c229359864cd7e427 100644
--- a/browser/components/urlbar/UrlbarView.sys.mjs --- a/browser/components/urlbar/UrlbarView.sys.mjs
+++ b/browser/components/urlbar/UrlbarView.sys.mjs +++ b/browser/components/urlbar/UrlbarView.sys.mjs
@@ -613,7 +613,7 @@ export class UrlbarView { @@ -613,7 +613,7 @@ export class UrlbarView {
@@ -11,11 +11,16 @@ index fdbab8806fd320f4aacec46a42c8ef953580d00c..2a6f22178aa42e8f1a7d0b58e02db85f
// Try to reuse the cached top-sites context. If it's not cached, then // Try to reuse the cached top-sites context. If it's not cached, then
// there will be a gap of time between when the input is focused and // there will be a gap of time between when the input is focused and
// when the view opens that can be perceived as flicker. // when the view opens that can be perceived as flicker.
@@ -824,6 +824,26 @@ export class UrlbarView { @@ -824,6 +824,31 @@ export class UrlbarView {
// still associated with the first result. // still associated with the first result.
this.input.setResultForCurrentValue(firstResult); this.input.setResultForCurrentValue(firstResult);
} }
+ if (queryContext.results[0].payload.zenAction) { + if (queryContext.results[0].payload.zenAction) {
+ this.#selectElement(this.getFirstSelectableElement(), {
+ updateInput: false,
+ setAccessibleFocus:
+ this.controller._userSelectionBehavior == "arrow",
+ });
+ this.window.setTimeout(() => { + this.window.setTimeout(() => {
+ this.window.setTimeout(() => { + this.window.setTimeout(() => {
+ this.#selectElement(this.getFirstSelectableElement(), { + this.#selectElement(this.getFirstSelectableElement(), {
@@ -38,7 +43,7 @@ index fdbab8806fd320f4aacec46a42c8ef953580d00c..2a6f22178aa42e8f1a7d0b58e02db85f
} }
// Announce tab-to-search results to screen readers as the user types. // Announce tab-to-search results to screen readers as the user types.
@@ -2706,6 +2726,8 @@ export class UrlbarView { @@ -2706,6 +2731,8 @@ export class UrlbarView {
if (row?.hasAttribute("row-selectable")) { if (row?.hasAttribute("row-selectable")) {
row?.toggleAttribute("selected", true); row?.toggleAttribute("selected", true);
} }
@@ -47,7 +52,7 @@ index fdbab8806fd320f4aacec46a42c8ef953580d00c..2a6f22178aa42e8f1a7d0b58e02db85f
if (element != row) { if (element != row) {
row?.toggleAttribute("descendant-selected", true); row?.toggleAttribute("descendant-selected", true);
} }
@@ -3189,7 +3211,7 @@ export class UrlbarView { @@ -3189,7 +3216,7 @@ export class UrlbarView {
} }
#enableOrDisableRowWrap() { #enableOrDisableRowWrap() {

View File

@@ -145,7 +145,10 @@ var gZenUIManager = {
'--zen-urlbar-top', '--zen-urlbar-top',
`${window.innerHeight / 2 - Math.max(kUrlbarHeight, gURLBar.textbox.getBoundingClientRect().height) / 2}px` `${window.innerHeight / 2 - Math.max(kUrlbarHeight, gURLBar.textbox.getBoundingClientRect().height) / 2}px`
); );
gURLBar.textbox.style.setProperty('--zen-urlbar-width', `${window.innerWidth / 2}px`); gURLBar.textbox.style.setProperty(
'--zen-urlbar-width',
`${Math.min(window.innerWidth / 2, 800)}px`
);
gZenVerticalTabsManager.actualWindowButtons.removeAttribute('zen-has-hover'); gZenVerticalTabsManager.actualWindowButtons.removeAttribute('zen-has-hover');
gZenVerticalTabsManager.recalculateURLBarHeight(); gZenVerticalTabsManager.recalculateURLBarHeight();
if (!this._preventToolbarRebuild) { if (!this._preventToolbarRebuild) {
@@ -328,8 +331,8 @@ var gZenUIManager = {
// Open location command // Open location command
try { try {
document.getElementById('Browser:OpenLocation').doCommand();
gURLBar.search(this._lastSearch || ''); gURLBar.search(this._lastSearch || '');
document.getElementById('Browser:OpenLocation').doCommand();
} catch (e) { } catch (e) {
console.error('Error opening location in new tab:', e); console.error('Error opening location in new tab:', e);
this.handleUrlbarClose(false); this.handleUrlbarClose(false);
@@ -699,12 +702,18 @@ var gZenVerticalTabsManager = {
animateTabClose(aTab) { animateTabClose(aTab) {
const height = aTab.getBoundingClientRect().height; const height = aTab.getBoundingClientRect().height;
const visibleItems = gBrowser.tabContainer.ariaFocusableItems;
const isLastItem = visibleItems[visibleItems.length - 1] === aTab;
return gZenUIManager.motion.animate( return gZenUIManager.motion.animate(
aTab, aTab,
{ {
opacity: [1, 0], opacity: [1, 0],
transform: ['scale(1)', 'scale(0.95)'], transform: ['scale(1)', 'scale(0.95)'],
...(isLastItem
? {}
: {
marginBottom: [`0px`, `-${height}px`], marginBottom: [`0px`, `-${height}px`],
}),
}, },
{ {
duration: 0.075, duration: 0.075,

View File

@@ -32,7 +32,7 @@
} }
&[zen-floating-urlbar='true'] { &[zen-floating-urlbar='true'] {
--urlbar-container-padding: 2px; --urlbar-container-padding: 3px;
} }
} }
@@ -179,7 +179,7 @@
& .urlbar-background { & .urlbar-background {
--zen-urlbar-background-base: light-dark( --zen-urlbar-background-base: light-dark(
white, white,
color-mix(in srgb, hsl(0, 0%, 5%), var(--zen-colors-primary) 20%) color-mix(in srgb, hsl(0, 0%, 1%), var(--zen-colors-primary) 25%)
); );
@media -moz-pref('zen.theme.acrylic-elements') { @media -moz-pref('zen.theme.acrylic-elements') {
--zen-urlbar-background-transparent: color-mix( --zen-urlbar-background-transparent: color-mix(
@@ -502,6 +502,7 @@
padding: 6px 8px; padding: 6px 8px;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
font-size: 10px; font-size: 10px;
margin-right: 2px;
&:empty { &:empty {
display: none !important; display: none !important;
@@ -646,7 +647,7 @@
} }
#urlbar-results { #urlbar-results {
max-height: 262px; max-height: 260px;
overflow-y: auto; overflow-y: auto;
scrollbar-width: none; scrollbar-width: none;
margin-block-start: var(--urlbarView-results-padding); margin-block-start: var(--urlbarView-results-padding);

View File

@@ -148,10 +148,11 @@
& #zen-toolbar-background { & #zen-toolbar-background {
display: flex; display: flex;
overflow: clip; overflow: clip;
background: transparent;
z-index: -1; z-index: -1;
background: var(--zen-dialog-background);
box-shadow: var(--zen-big-shadow); box-shadow: var(--zen-big-shadow);
@media -moz-pref('zen.theme.acrylic-elements') { @media -moz-pref('zen.theme.acrylic-elements') {
background: transparent;
backdrop-filter: blur(42px) saturate(110%) brightness(0.25) contrast(100%) !important; backdrop-filter: blur(42px) saturate(110%) brightness(0.25) contrast(100%) !important;
} }

View File

@@ -625,7 +625,7 @@
openTabsPopup(event) { openTabsPopup(event) {
event.stopPropagation(); event.stopPropagation();
if (document.documentElement.getAttribute('zen-renaming-tab')) { if (document.documentElement.getAttribute('zen-renaming-tab') || gURLBar.focused) {
return; return;
} }

View File

@@ -148,7 +148,6 @@
const initialHeight = data.height; const initialHeight = data.height;
this.browserWrapper?.removeAttribute('animate'); this.browserWrapper?.removeAttribute('animate');
this.browserWrapper?.removeAttribute('animate-end');
this.browserWrapper?.removeAttribute('has-finished-animation'); this.browserWrapper?.removeAttribute('has-finished-animation');
this.overlay?.removeAttribute('post-fade-out'); this.overlay?.removeAttribute('post-fade-out');
@@ -160,7 +159,6 @@
this.overlay.classList.add('zen-glance-overlay'); this.overlay.classList.add('zen-glance-overlay');
this.browserWrapper.removeAttribute('animate-end');
return new Promise((resolve) => { return new Promise((resolve) => {
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
this.quickOpenGlance(); this.quickOpenGlance();
@@ -184,7 +182,6 @@
bounce: 0.2, bounce: 0.2,
} }
); );
this.#currentBrowser.setAttribute('animate-glance-open', true);
this.overlay.removeAttribute('fade-out'); this.overlay.removeAttribute('fade-out');
this.browserWrapper.setAttribute('animate', true); this.browserWrapper.setAttribute('animate', true);
const top = initialY + initialHeight / 2; const top = initialY + initialHeight / 2;
@@ -220,10 +217,8 @@
) )
.then(() => { .then(() => {
gBrowser.tabContainer._invalidateCachedTabs(); gBrowser.tabContainer._invalidateCachedTabs();
this.#currentBrowser.removeAttribute('animate-glance-open');
this.overlay.style.removeProperty('overflow'); this.overlay.style.removeProperty('overflow');
this.browserWrapper.removeAttribute('animate'); this.browserWrapper.removeAttribute('animate');
this.browserWrapper.setAttribute('animate-end', true);
this.browserWrapper.setAttribute('has-finished-animation', true); this.browserWrapper.setAttribute('has-finished-animation', true);
this._animating = false; this._animating = false;
this.animatingOpen = false; this.animatingOpen = false;
@@ -351,7 +346,6 @@
) )
.then(() => { .then(() => {
this.browserWrapper.removeAttribute('animate'); this.browserWrapper.removeAttribute('animate');
this.browserWrapper.removeAttribute('animate-end');
if (!this.#currentParentTab) { if (!this.#currentParentTab) {
return; return;
} }
@@ -669,7 +663,7 @@
height: ['100%', '100%'], height: ['100%', '100%'],
}, },
{ {
duration: 0.4, duration: 0.3,
type: 'spring', type: 'spring',
bounce: 0, bounce: 0,
} }

View File

@@ -153,13 +153,8 @@
&[fade-out='true'] { &[fade-out='true'] {
& browser { & browser {
transition: opacity 0.1s ease; transition: opacity 0.2s ease;
opacity: 0; opacity: 0;
} }
} }
& browser[animate-glance-open='true'] {
transition: opacity 0.2s ease-in-out;
opacity: 0;
}
} }

View File

@@ -148,7 +148,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
if (groupIndex < 0) { if (groupIndex < 0) {
return; return;
} }
this.removeTabFromGroup(tab, groupIndex, true); this.removeTabFromGroup(tab, groupIndex, { forUnsplit: true });
} }
/** /**
@@ -185,9 +185,10 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
* *
* @param {Tab} tab - The tab to remove. * @param {Tab} tab - The tab to remove.
* @param {number} groupIndex - The index of the group. * @param {number} groupIndex - The index of the group.
* @param {boolean} forUnsplit - Indicates if the tab is being removed for unsplitting. * @param {boolean} [forUnsplit=false] - Whether the removal is for unsplitting.
* @param {boolean} [dontRebuildGrid=false] - Whether to skip rebuilding the grid layout.
*/ */
removeTabFromGroup(tab, groupIndex, forUnsplit) { removeTabFromGroup(tab, groupIndex, { forUnsplit = false, dontRebuildGrid = false } = {}) {
const group = this._data[groupIndex]; const group = this._data[groupIndex];
const tabIndex = group.tabs.indexOf(tab); const tabIndex = group.tabs.indexOf(tab);
group.tabs.splice(tabIndex, 1); group.tabs.splice(tabIndex, 1);
@@ -199,9 +200,11 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
if (group.tabs.length < 2) { if (group.tabs.length < 2) {
// We need to remove all remaining tabs from the group when unsplitting // We need to remove all remaining tabs from the group when unsplitting
let remainingTabs = [...group.tabs]; // Copy array since we'll modify it let remainingTabs = [...group.tabs]; // Copy array since we'll modify it
if (!dontRebuildGrid) {
for (let remainingTab of remainingTabs) { for (let remainingTab of remainingTabs) {
this.resetTabState(remainingTab, forUnsplit); this.resetTabState(remainingTab, forUnsplit);
} }
}
this.removeGroup(groupIndex); this.removeGroup(groupIndex);
gBrowser.selectedTab = remainingTabs[remainingTabs.length - 1]; gBrowser.selectedTab = remainingTabs[remainingTabs.length - 1];
} else { } else {
@@ -1602,7 +1605,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
const groupIndex = this._data.findIndex((group) => group.tabs.includes(tab)); const groupIndex = this._data.findIndex((group) => group.tabs.includes(tab));
this.deactivateCurrentSplitView(); this.deactivateCurrentSplitView();
if (groupIndex >= 0) { if (groupIndex >= 0) {
this.removeTabFromGroup(tab, groupIndex, true); this.removeTabFromGroup(tab, groupIndex, { forUnsplit: true });
} }
gBrowser.selectedTab = tab; gBrowser.selectedTab = tab;
tab._selected = true; tab._selected = true;
@@ -1940,17 +1943,21 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
const { onElementPicked } = event.detail; const { onElementPicked } = event.detail;
const groupIndex = this._data.findIndex((group) => group.tabs.includes(emptyTab)); const groupIndex = this._data.findIndex((group) => group.tabs.includes(emptyTab));
const newSelectedTab = gBrowser.selectedTab; const newSelectedTab = gBrowser.selectedTab;
requestAnimationFrame(() => { const cleanup = () => {
this.removeTabFromGroup(emptyTab, groupIndex); this.removeTabFromGroup(emptyTab, groupIndex);
};
if (onElementPicked) { if (onElementPicked) {
if (newSelectedTab === emptyTab || newSelectedTab === selectedTab) { if (newSelectedTab === emptyTab || newSelectedTab === selectedTab) {
cleanup();
return; return;
} }
gBrowser.selectedTab = selectedTab;
this.removeTabFromGroup(emptyTab, groupIndex, { forUnsplit: true });
this.splitTabs([selectedTab, newSelectedTab], 'grid', 1); this.splitTabs([selectedTab, newSelectedTab], 'grid', 1);
} else { } else {
gBrowser.selectedTab = selectedTab; gBrowser.selectedTab = selectedTab;
cleanup();
} }
});
}, },
{ once: true } { once: true }
); );

View File

@@ -35,6 +35,11 @@ XPCOMUtils.defineLazyPreferenceGetter(
* A provider that lets the user view all available global actions for a query. * A provider that lets the user view all available global actions for a query.
*/ */
export class ZenUrlbarProviderGlobalActions extends UrlbarProvider { export class ZenUrlbarProviderGlobalActions extends UrlbarProvider {
constructor() {
super();
lazy.UrlbarResult.addDynamicResultType(DYNAMIC_TYPE_NAME);
}
get name() { get name() {
return 'ZenUrlbarProviderGlobalActions'; return 'ZenUrlbarProviderGlobalActions';
} }
@@ -211,7 +216,7 @@ export class ZenUrlbarProviderGlobalActions extends UrlbarProvider {
} }
async startQuery(queryContext, addCallback) { async startQuery(queryContext, addCallback) {
const query = queryContext.searchString.trim().toLowerCase(); const query = queryContext.trimmedLowerCaseSearchString;
if (!query) { if (!query) {
return; return;
} }

View File

@@ -126,7 +126,7 @@
darkModeChange darkModeChange
); );
XPCOMUtils.defineLazyPreferenceGetter(this, 'darkModeBias', 'zen.theme.dark-mode-bias', 0.25); XPCOMUtils.defineLazyPreferenceGetter(this, 'darkModeBias', 'zen.theme.dark-mode-bias', 0.5);
} }
handleDarkModeChange() { handleDarkModeChange() {
@@ -1182,15 +1182,12 @@
let color1 = this.getSingleRGBColor(themedColors[2], forToolbar); let color1 = this.getSingleRGBColor(themedColors[2], forToolbar);
let color2 = this.getSingleRGBColor(themedColors[0], forToolbar); let color2 = this.getSingleRGBColor(themedColors[0], forToolbar);
let color3 = this.getSingleRGBColor(themedColors[1], forToolbar); let color3 = this.getSingleRGBColor(themedColors[1], forToolbar);
if (!forToolbar) {
return [ return [
`radial-gradient(circle at 0% 0%, ${color2}, transparent 100%)`, `linear-gradient(to top, ${color1} -50%, transparent 110%)`,
`radial-gradient(circle at 100% 0%, ${color3}, transparent 100%)`, `radial-gradient(circle at 0% 0%, ${color2} 10%, transparent 80%)`,
`linear-gradient(to top, ${color1} 0%, transparent 60%)`, `radial-gradient(circle at 100% -100%, ${color3} -100%, transparent 400%)`,
].join(', '); ].join(', ');
} }
return [`linear-gradient(-45deg, ${color1} 15%, ${color2})`].join(', ');
}
} }
} }