Skip to content

Commit

Permalink
Clean it up and document it at least
Browse files Browse the repository at this point in the history
  • Loading branch information
bhollis committed Jan 15, 2025
1 parent 163d621 commit 2802279
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 51 deletions.
19 changes: 0 additions & 19 deletions src/app/inventory-page/StoreBucket.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,5 @@
min-height: 0;
padding: 0;
}

&::before {
content: '';

opacity: 0;

width: 100%;
height: 100%;

position: absolute;

z-index: 9;

display: none;

.drag-perf-show & {
display: block;
}
}
}
}
7 changes: 2 additions & 5 deletions src/app/inventory-page/StoreBucketDropTarget.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { hideDragFixOverlay } from 'app/inventory/DragPerformanceFix';
import { InventoryBucket } from 'app/inventory/inventory-buckets';
import { DimItem } from 'app/inventory/item-types';
import { dropItem } from 'app/inventory/move-item';
Expand All @@ -20,10 +21,6 @@ interface Props {
grouped: boolean;
}

const onClick = () => {
document.body.classList.remove('drag-perf-show');
};

export default function StoreBucketDropTarget({
storeId,
children,
Expand Down Expand Up @@ -68,7 +65,7 @@ export default function StoreBucketDropTarget({
[styles.canDrop]: canDrop,
[styles.grouped]: grouped,
})}
onClick={onClick}
onClick={hideDragFixOverlay}
aria-label={bucket.name}
>
{children}
Expand Down
44 changes: 44 additions & 0 deletions src/app/inventory/DragPerformanceFix.m.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// A div that overlays the whole inventory to block hit-testing during drag.
// Note the z-index which should be above all other elements. Except for the
// sub-bucket overlays.
.dragPerfFix {
// to test, set a nonzero opacity and a background color
opacity: 0;

position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;

z-index: 8;

display: none;

.dragPerfShow & {
display: block;
}
}

// Each sub-bucket (inventory drag target) gets its own overlay as well, with a
// z-index one higher than the global overlay. This allows them to still receive
// drag events.
:global(.sub-bucket) {
&::before {
content: '';

// to test, set a nonzero opacity and a background color
opacity: 0;
width: 100%;
height: 100%;
position: absolute;

z-index: 9;

display: none;

.dragPerfShow & {
display: block;
}
}
}
8 changes: 8 additions & 0 deletions src/app/inventory/DragPerformanceFix.m.scss.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 0 additions & 17 deletions src/app/inventory/DragPerformanceFix.scss

This file was deleted.

29 changes: 22 additions & 7 deletions src/app/inventory/DragPerformanceFix.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import './DragPerformanceFix.scss';
import styles from './DragPerformanceFix.m.scss';

function hideOverlay() {
/**
* This is a workaround for sluggish dragging in Chrome on Windows. It may or
* may not be related to Logitech mouse drivers or high-DPI mice, but in Chrome
* on Windows only, some users experience a problem where they can drag items,
* but the drag targets do not get events very quickly, so it may take a second
* or two of hovering over a drop target to make it light up. This was still a
* problem as of January 2025.
*
* This workaround is to put a full-screen invisible div over the entire app,
* and then put separate invisible divs over each drop target. That simplifies
* the hit-testing Chrome has to do, and makes dragging feel normal.
*/
export default function DragPerformanceFix() {
// Rarely (possibly never in typical usage), a browser will forget to dispatch the dragEnd event
// So we try not to trap the user here.
document.body.classList.remove('drag-perf-show');
// So we try not to trap the user here by allowing them to click away the overlay.
return <div className={styles.dragPerfFix} onClick={hideDragFixOverlay} />;
}

/** This is a workaround for sluggish dragging in Chrome (and possibly other browsers) */
export default function DragPerformanceFix() {
return <div className="drag-perf-fix" onClick={hideOverlay} />;
export function showDragFixOverlay() {
document.body.classList.add(styles.dragPerfShow);
}

export function hideDragFixOverlay() {
document.body.classList.remove(styles.dragPerfShow);
}
6 changes: 3 additions & 3 deletions src/app/inventory/DraggableInventoryItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { hideItemPopup } from 'app/item-popup/item-popup';
import clsx from 'clsx';
import React from 'react';
import { useDrag } from 'react-dnd';
import { hideDragFixOverlay, showDragFixOverlay } from './DragPerformanceFix';
import styles from './DraggableInventoryItem.m.scss';
import { isDragging$ } from './drag-events';
import { DimItem } from './item-types';
Expand Down Expand Up @@ -30,10 +31,9 @@ export default function DraggableInventoryItem({ children, item, anyBucket = fal
: item.bucket.hash.toString(),
item: () => {
hideItemPopup();

dragTimeout = requestAnimationFrame(() => {
dragTimeout = null;
document.body.classList.add('drag-perf-show');
showDragFixOverlay();
});
isDragging$.next(true);
return item;
Expand All @@ -42,7 +42,7 @@ export default function DraggableInventoryItem({ children, item, anyBucket = fal
if (dragTimeout !== null) {
cancelAnimationFrame(dragTimeout);
}
document.body.classList.remove('drag-perf-show');
hideDragFixOverlay();
isDragging$.next(false);
},
canDrag,
Expand Down

0 comments on commit 2802279

Please sign in to comment.