conditional middle-btn tab close

This commit is contained in:
mathuo 2025-02-08 11:30:19 +00:00
parent 8ed0fb5586
commit d8da2f29c3
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
3 changed files with 44 additions and 15 deletions

View File

@ -49,8 +49,8 @@ export class Tab extends CompositeDisposable {
private readonly dropTarget: Droptarget; private readonly dropTarget: Droptarget;
private content: ITabRenderer | undefined = undefined; private content: ITabRenderer | undefined = undefined;
private readonly _onChanged = new Emitter<MouseEvent>(); private readonly _onPointDown = new Emitter<MouseEvent>();
readonly onChanged: Event<MouseEvent> = this._onChanged.event; readonly onPointerDown: Event<MouseEvent> = this._onPointDown.event;
private readonly _onDropped = new Emitter<DroptargetEvent>(); private readonly _onDropped = new Emitter<DroptargetEvent>();
readonly onDrop: Event<DroptargetEvent> = this._onDropped.event; readonly onDrop: Event<DroptargetEvent> = this._onDropped.event;
@ -117,7 +117,7 @@ export class Tab extends CompositeDisposable {
this.onWillShowOverlay = this.dropTarget.onWillShowOverlay; this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
this.addDisposables( this.addDisposables(
this._onChanged, this._onPointDown,
this._onDropped, this._onDropped,
this._onDragStart, this._onDragStart,
dragHandler.onDragStart((event) => { dragHandler.onDragStart((event) => {
@ -125,11 +125,7 @@ export class Tab extends CompositeDisposable {
}), }),
dragHandler, dragHandler,
addDisposableListener(this._element, 'pointerdown', (event) => { addDisposableListener(this._element, 'pointerdown', (event) => {
if (event.defaultPrevented) { this._onPointDown.fire(event);
return;
}
this._onChanged.fire(event);
}), }),
this.dropTarget.onDrop((event) => { this.dropTarget.onDrop((event) => {
this._onDropped.fire(event); this._onDropped.fire(event);

View File

@ -317,7 +317,7 @@ export class TabsContainer
tab.onDragStart((event) => { tab.onDragStart((event) => {
this._onTabDragStart.fire({ nativeEvent: event, panel }); this._onTabDragStart.fire({ nativeEvent: event, panel });
}), }),
tab.onChanged((event) => { tab.onPointerDown((event) => {
if (event.defaultPrevented) { if (event.defaultPrevented) {
return; return;
} }
@ -356,9 +356,6 @@ export class TabsContainer
this.group.model.openPanel(panel); this.group.model.openPanel(panel);
} }
break; break;
case 1: // middle click
panel.api.close();
break;
} }
}), }),
tab.onDrop((event) => { tab.onDrop((event) => {

View File

@ -32,10 +32,15 @@ export const DockviewDefaultTab: React.FunctionComponent<
params: _params, params: _params,
hideClose, hideClose,
closeActionOverride, closeActionOverride,
onPointerDown,
onPointerUp,
onPointerLeave,
...rest ...rest
}) => { }) => {
const title = useTitle(api); const title = useTitle(api);
const isMiddleMouseButton = React.useRef<boolean>(false);
const onClose = React.useCallback( const onClose = React.useCallback(
(event: React.MouseEvent<HTMLSpanElement>) => { (event: React.MouseEvent<HTMLSpanElement>) => {
event.preventDefault(); event.preventDefault();
@ -49,21 +54,52 @@ export const DockviewDefaultTab: React.FunctionComponent<
[api, closeActionOverride] [api, closeActionOverride]
); );
const onPointerDown = React.useCallback((e: React.MouseEvent) => { const onBtnPointerDown = React.useCallback((event: React.MouseEvent) => {
e.preventDefault(); event.preventDefault();
}, []); }, []);
const _onPointerDown = React.useCallback(
(event: React.PointerEvent<HTMLDivElement>) => {
isMiddleMouseButton.current = event.button === 1;
onPointerDown?.(event);
},
[onPointerDown]
);
const _onPointerUp = React.useCallback(
(event: React.PointerEvent<HTMLDivElement>) => {
if (isMiddleMouseButton && event.button === 1 && !hideClose) {
isMiddleMouseButton.current = false;
onClose(event);
}
onPointerUp?.(event);
},
[onPointerUp, onClose, hideClose]
);
const _onPointerLeave = React.useCallback(
(event: React.PointerEvent<HTMLDivElement>) => {
isMiddleMouseButton.current = false;
onPointerLeave?.(event);
},
[onPointerLeave]
);
return ( return (
<div <div
data-testid="dockview-dv-default-tab" data-testid="dockview-dv-default-tab"
{...rest} {...rest}
onPointerDown={_onPointerDown}
onPointerUp={_onPointerUp}
onPointerLeave={_onPointerLeave}
className="dv-default-tab" className="dv-default-tab"
> >
<span className="dv-default-tab-content">{title}</span> <span className="dv-default-tab-content">{title}</span>
{!hideClose && ( {!hideClose && (
<div <div
className="dv-default-tab-action" className="dv-default-tab-action"
onPointerDown={onPointerDown} onPointerDown={onBtnPointerDown}
onClick={onClose} onClick={onClose}
> >
<CloseButton /> <CloseButton />