Skip to content

Commit

Permalink
fix(handleWheel): mouse scrolling behavior for out-of-focus windows
Browse files Browse the repository at this point in the history
When rebinding events with a different container,
make sure all timeouts and state variables from
previous containter are cleared.
  • Loading branch information
jadh4v committed Jan 24, 2024
1 parent 4945167 commit 16deccc
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 16 deletions.
7 changes: 7 additions & 0 deletions Sources/Rendering/Core/RenderWindowInteractor/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,13 @@ export interface vtkRenderWindowInteractor extends vtkObject {
*/
rotateEvent(args: any): any;

/**
* Add an HTMLElement as the new container for the interactor.
* All events will be bound to this new container.
* Any old container will be removed along with its listeners.
*/
setContainer(container: HTMLElement | null): boolean;

/**
* Turn on/off the automatic repositioning of lights as the camera moves.
* @param lightFollowCamera
Expand Down
65 changes: 49 additions & 16 deletions Sources/Rendering/Core/RenderWindowInteractor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ function vtkRenderWindowInteractor(publicAPI, model) {
}

publicAPI.bindEvents = (container) => {
if (model.container === container || container === null) {
return false;
}
publicAPI.unbindEvents();
model.container = container;
container.addEventListener('contextmenu', preventDefault);
container.addEventListener('wheel', publicAPI.handleWheel);
Expand Down Expand Up @@ -245,26 +249,50 @@ function vtkRenderWindowInteractor(publicAPI, model) {
container.style.userSelect = 'none';
// disables tap highlight for when cursor is pointer
container.style.webkitTapHighlightColor = 'rgba(0,0,0,0)';
return true;
};

publicAPI.unbindEvents = () => {
// Clear any previous timeouts and state variables that control mouse / touchpad behavior.
clearTimeout(model.moveTimeoutID);
clearTimeout(model.wheelTimeoutID);
model.moveTimeoutID = 0;
model.wheelTimeoutID = 0;
wheelCoefficient = 1.0;

const { container } = model;
container.removeEventListener('contextmenu', preventDefault);
container.removeEventListener('wheel', publicAPI.handleWheel);
container.removeEventListener('DOMMouseScroll', publicAPI.handleWheel);
container.removeEventListener('pointerenter', publicAPI.handlePointerEnter);
container.removeEventListener('pointerleave', publicAPI.handlePointerLeave);
container.removeEventListener('pointermove', publicAPI.handlePointerMove, {
passive: false,
});
container.removeEventListener('pointerdown', publicAPI.handlePointerDown, {
passive: false,
});
container.removeEventListener('pointerup', publicAPI.handlePointerUp);
container.removeEventListener(
'pointercancel',
publicAPI.handlePointerCancel
);
if (container) {
container.removeEventListener('contextmenu', preventDefault);
container.removeEventListener('wheel', publicAPI.handleWheel);
container.removeEventListener('DOMMouseScroll', publicAPI.handleWheel);
container.removeEventListener(
'pointerenter',
publicAPI.handlePointerEnter
);
container.removeEventListener(
'pointerleave',
publicAPI.handlePointerLeave
);
container.removeEventListener(
'pointermove',
publicAPI.handlePointerMove,
{
passive: false,
}
);
container.removeEventListener(
'pointerdown',
publicAPI.handlePointerDown,
{
passive: false,
}
);
container.removeEventListener('pointerup', publicAPI.handlePointerUp);
container.removeEventListener(
'pointercancel',
publicAPI.handlePointerCancel
);
}
document.removeEventListener('keypress', publicAPI.handleKeyPress);
document.removeEventListener('keydown', publicAPI.handleKeyDown);
document.removeEventListener('keyup', publicAPI.handleKeyUp);
Expand Down Expand Up @@ -1126,6 +1154,11 @@ function vtkRenderWindowInteractor(publicAPI, model) {
model.currentRenderer = r;
};

publicAPI.setContainer = (container) => {
publicAPI.unbindEvents();
return publicAPI.bindEvents(container);
};

// Stop animating if the renderWindowInteractor is deleted.
const superDelete = publicAPI.delete;
publicAPI.delete = () => {
Expand Down

0 comments on commit 16deccc

Please sign in to comment.