mirror of
https://github.com/zen-browser/desktop.git
synced 2026-01-24 21:56:10 +00:00
fix: Fixed drag and drop not using the actual pointer location, b=no-bug, c=folders, tabs, workspaces
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
!element ||
|
||||
element.closest(".zen-current-workspace-indicator") ||
|
||||
element.hasAttribute("split-view-group") ||
|
||||
element.classList.contains("zen-drop-target") ||
|
||||
isEssentialsPromo(element)
|
||||
) {
|
||||
return element;
|
||||
@@ -52,6 +53,9 @@
|
||||
if (isTabGroupLabel(element)) {
|
||||
return element.closest(".tab-group-label-container");
|
||||
}
|
||||
if (gBrowser.isTabGroup(element)) {
|
||||
return element.labelContainerElement;
|
||||
}
|
||||
throw new Error(`Element "${element.tagName}" is not expected to move`);
|
||||
};
|
||||
|
||||
@@ -111,7 +115,7 @@
|
||||
const { offsetX, offsetY } = this.#getDragImageOffset(event, tab, draggingTabs);
|
||||
const dragImage = this.#createDragImageForTabs(draggingTabs);
|
||||
this.originalDragImageArgs = [dragImage, offsetX, offsetY];
|
||||
dt.updateDragImage(...this.originalDragImageArgs);
|
||||
dt.setDragImage(...this.originalDragImageArgs);
|
||||
if (tab.hasAttribute("zen-essential")) {
|
||||
setTimeout(() => {
|
||||
tab.style.visibility = "hidden";
|
||||
@@ -137,6 +141,9 @@
|
||||
const rect = tab.getBoundingClientRect();
|
||||
tabClone.style.minWidth = tabClone.style.maxWidth = `${rect.width}px`;
|
||||
tabClone.style.minHeight = tabClone.style.maxHeight = `${rect.height}px`;
|
||||
if (tabClone.hasAttribute("visuallyselected")) {
|
||||
tabClone.style.transform = "translate(-50%, -50%)";
|
||||
}
|
||||
}
|
||||
if (i > 0) {
|
||||
tabClone.style.transform = `translate(${i * 4}px, -${i * (tabRect.height - 4)}px)`;
|
||||
@@ -521,7 +528,7 @@
|
||||
|
||||
[dropBefore, dropElement] = this.#applyDragoverIndicator(
|
||||
event,
|
||||
tabs,
|
||||
dropElement,
|
||||
movingTabs,
|
||||
draggedTab
|
||||
) ?? [dropBefore, dropElement];
|
||||
@@ -646,7 +653,7 @@
|
||||
clientX < 0 || clientX > innerWidth || clientY < 0 || clientY > innerHeight;
|
||||
if (isOutOfWindow && !this.#isOutOfWindow) {
|
||||
this.#isOutOfWindow = true;
|
||||
this.#maybeClearVerticalPinnedGridDragOver();
|
||||
this.maybeClearVerticalPinnedGridDragOver();
|
||||
this.clearSpaceSwitchTimer();
|
||||
this.clearDragOverVisuals();
|
||||
const dt = event.dataTransfer;
|
||||
@@ -678,8 +685,8 @@
|
||||
|
||||
handle_drop(event) {
|
||||
this.clearSpaceSwitchTimer();
|
||||
gZenFolders.highlightGroupOnDragOver(null);
|
||||
super.handle_drop(event);
|
||||
this.#maybeClearVerticalPinnedGridDragOver();
|
||||
const dt = event.dataTransfer;
|
||||
const activeWorkspace = gZenWorkspaces.activeWorkspace;
|
||||
let draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
|
||||
@@ -817,11 +824,14 @@
|
||||
if (currentEssenialContainer?.essentialsPromo) {
|
||||
currentEssenialContainer.essentialsPromo.remove();
|
||||
}
|
||||
// We also call it here to ensure we clear any highlight if the drop happened
|
||||
// outside of a valid drop target.
|
||||
gZenFolders.highlightGroupOnDragOver(null);
|
||||
this.ZenDragAndDropService.onDragEnd();
|
||||
super.handle_dragend(event);
|
||||
this.#removeDragOverBackground();
|
||||
gZenPinnedTabManager.removeTabContainersDragoverClass();
|
||||
this.#maybeClearVerticalPinnedGridDragOver();
|
||||
this.maybeClearVerticalPinnedGridDragOver();
|
||||
this.originalDragImageArgs = [];
|
||||
window.removeEventListener("dragover", this.handle_windowDragEnter, { capture: true });
|
||||
this.#isOutOfWindow = false;
|
||||
@@ -872,53 +882,43 @@
|
||||
}
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
#applyDragoverIndicator(event, tabs, movingTabs, draggedTab) {
|
||||
#applyDragoverIndicator(event, dropElement, movingTabs, draggedTab) {
|
||||
const separation = 4;
|
||||
const dropZoneSelector =
|
||||
":is(.tabbrowser-tab, .zen-drop-target, .tab-group-label, tab-group[split-view-group])";
|
||||
":is(.tabbrowser-tab, .zen-drop-target, .tab-group-label-container, tab-group[split-view-group])";
|
||||
let shouldPlayHapticFeedback = false;
|
||||
let showIndicatorUnderNewTabButton = false;
|
||||
let dropBefore = false;
|
||||
let dropElement = event.target.closest(dropZoneSelector);
|
||||
if (!dropElement) {
|
||||
let dropElementFromEvent = event.target.closest(dropZoneSelector);
|
||||
if (!dropElementFromEvent) {
|
||||
if (event.target.classList.contains("zen-workspace-empty-space")) {
|
||||
dropElement = this._tabbrowserTabs.ariaFocusableItems.at(-1);
|
||||
// Only if there are no normal tabs to drop after
|
||||
showIndicatorUnderNewTabButton =
|
||||
gBrowser.tabs[gBrowser.tabs.length - 1].hasAttribute("zen-empty-tab");
|
||||
} else {
|
||||
const numEssentials = gBrowser._numZenEssentials;
|
||||
const numPinned = gBrowser.pinnedTabCount - numEssentials;
|
||||
const tabToUse =
|
||||
event.target.closest(dropZoneSelector) || draggedTab._dragData?.dropElement;
|
||||
if (!tabToUse) {
|
||||
return null;
|
||||
}
|
||||
const isPinned = tabToUse.pinned;
|
||||
const relativeTabs = tabs.slice(
|
||||
isPinned ? 0 : numPinned,
|
||||
isPinned ? numPinned : undefined
|
||||
);
|
||||
const draggedTabRect = elementToMove(tabToUse).getBoundingClientRect();
|
||||
dropElement = event.clientY > draggedTabRect.top ? relativeTabs.at(-1) : relativeTabs[0];
|
||||
}
|
||||
}
|
||||
dropElement = elementToMove(dropElement);
|
||||
this.#maybeClearVerticalPinnedGridDragOver();
|
||||
this.maybeClearVerticalPinnedGridDragOver();
|
||||
if (this.#lastDropTarget !== dropElement) {
|
||||
shouldPlayHapticFeedback = this.#lastDropTarget !== null;
|
||||
this.#removeDragOverBackground();
|
||||
}
|
||||
let isZenFolder = dropElement.parentElement?.isZenFolder;
|
||||
let possibleFolderElement = dropElement.parentElement;
|
||||
let isZenFolder = possibleFolderElement?.isZenFolder;
|
||||
let canHightlightGroup =
|
||||
gZenFolders.highlightGroupOnDragOver(dropElement.parentElement, movingTabs) || !isZenFolder;
|
||||
gZenFolders.highlightGroupOnDragOver(possibleFolderElement, movingTabs) || !isZenFolder;
|
||||
let rect = window.windowUtils.getBoundsWithoutFlushing(dropElement);
|
||||
const overlapPercent = (event.clientY - rect.top) / rect.height;
|
||||
// We wan't to leave a small threshold (20% for example) so we can drag tabs below and above
|
||||
// a folder label without dragging into the folder.
|
||||
let threshold = Services.prefs.getIntPref("zen.tabs.folder-dragover-threshold-percent") / 100;
|
||||
let dropIntoFolder =
|
||||
isZenFolder && (overlapPercent < threshold || overlapPercent > 1 - threshold);
|
||||
isZenFolder &&
|
||||
(overlapPercent < threshold ||
|
||||
(overlapPercent > 1 - threshold &&
|
||||
(possibleFolderElement.collapsed ||
|
||||
possibleFolderElement.childGroupsAndTabs.length < 2)));
|
||||
if (
|
||||
isTabGroupLabel(draggedTab) &&
|
||||
draggedTab.group?.isZenFolder &&
|
||||
@@ -1234,7 +1234,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#maybeClearVerticalPinnedGridDragOver() {
|
||||
maybeClearVerticalPinnedGridDragOver() {
|
||||
if (this._fakeEssentialTab) {
|
||||
this._fakeEssentialTab.remove();
|
||||
delete this._fakeEssentialTab;
|
||||
|
||||
@@ -1134,11 +1134,10 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
* @param {MozTabbrowserTabGroup|undefined|null} folder The folder to highlight, or null to clear highlight.
|
||||
* @param {Array<MozTabbrowserTab>|null} movingTabs The tabs being moved.
|
||||
*/
|
||||
highlightGroupOnDragOver(folder, movingTabs) {
|
||||
highlightGroupOnDragOver(folder, movingTabs = null) {
|
||||
if (folder === this.#lastHighlightedGroup) {
|
||||
return true;
|
||||
}
|
||||
const tab = movingTabs ? movingTabs[0] : null;
|
||||
if (this.#lastHighlightedGroup && this.#lastHighlightedGroup !== folder) {
|
||||
if (this.#lastHighlightedGroup.collapsed) {
|
||||
this.updateFolderIcon(this.#lastHighlightedGroup, "close");
|
||||
@@ -1148,7 +1147,6 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
if (
|
||||
folder?.isZenFolder &&
|
||||
(!folder.hasAttribute("split-view-group") || !folder.hasAttribute("selected")) &&
|
||||
folder !== tab?.group &&
|
||||
!(
|
||||
folder.level >= this.#ZEN_MAX_SUBFOLDERS &&
|
||||
movingTabs?.some((t) => gBrowser.isTabGroupLabel(t))
|
||||
|
||||
@@ -123,11 +123,11 @@ zen-folder {
|
||||
}
|
||||
|
||||
&[state="open"] .back {
|
||||
transform: skewX(16deg) translate(-2px, 3.4px) scale(0.85);
|
||||
transform: skewX(16deg) translate(-4px, 2px) scale(0.85);
|
||||
}
|
||||
|
||||
&[state="open"] :is(.front, .dots, .icon) {
|
||||
transform: skewX(-16deg) translate(11.1px, 3.4px) scale(0.85);
|
||||
transform: skewX(-16deg) translate(8px, 2px) scale(0.85);
|
||||
}
|
||||
|
||||
& .icon {
|
||||
|
||||
@@ -560,6 +560,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
);
|
||||
const essentialTabsTarget = event.target.closest(".zen-essentials-container");
|
||||
const tabsTarget = !pinnedTabsTarget;
|
||||
gBrowser.tabContainer.tabDragAndDrop.maybeClearVerticalPinnedGridDragOver();
|
||||
|
||||
// TODO: Solve the issue of adding a tab between two groups
|
||||
// Remove group labels from the moving tabs and replace it
|
||||
@@ -651,7 +652,6 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return moved;
|
||||
} catch (ex) {
|
||||
console.error("Error moving tabs:", ex);
|
||||
|
||||
@@ -497,7 +497,7 @@
|
||||
}
|
||||
|
||||
#tabbrowser-tabs {
|
||||
--toolbarbutton-inner-padding: 6px !important;
|
||||
--toolbarbutton-inner-padding: 10px !important;
|
||||
--tab-icon-end-margin: var(--toolbarbutton-inner-padding) !important;
|
||||
}
|
||||
|
||||
@@ -670,7 +670,7 @@
|
||||
.tab-sharing-icon-overlay,
|
||||
.tab-icon-overlay {
|
||||
margin-inline-end: var(--toolbarbutton-inner-padding) !important;
|
||||
margin-inline-start: calc(var(--toolbarbutton-inner-padding) / 4) !important;
|
||||
margin-inline-start: calc(var(--toolbarbutton-inner-padding) / 3) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -934,7 +934,7 @@
|
||||
height: calc(100% - var(--tab-block-margin) * 2);
|
||||
margin-left: calc(-1 * var(--tab-inline-padding) + var(--tab-block-margin));
|
||||
margin-right: 8px;
|
||||
padding: 0 calc(var(--toolbarbutton-inner-padding) - 2px) 0 calc(var(--toolbarbutton-inner-padding) / 4 + var(--tab-inline-padding) - 2px);
|
||||
padding: 0 calc(var(--toolbarbutton-inner-padding) - 2px) 0 calc(var(--toolbarbutton-inner-padding) / 3 + var(--tab-inline-padding) - 2px);
|
||||
border-radius: 0;
|
||||
border-top-left-radius: var(--border-radius-medium);
|
||||
width: unset;
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
/* Mark workspaces indicator */
|
||||
.zen-current-workspace-indicator {
|
||||
--indicator-gap: var(--toolbarbutton-inner-padding);
|
||||
padding: calc(2px + var(--tab-inline-padding) + var(--zen-toolbox-padding));
|
||||
padding: calc(3px + var(--tab-inline-padding) + var(--zen-toolbox-padding));
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
max-height: var(--zen-workspace-indicator-height);
|
||||
|
||||
Reference in New Issue
Block a user