Skip to content

Commit 7c40da4

Browse files
committed
fix(renderwindowinteractor): observe KeyPress events on RW container instead of document
Observing on document produces many false positives. For example, a key press event was for an <input> element but RWI was also processing it. BREAKING CHANGE: This may break key press event current behavior. Use tabIndex=0 on RW containers to fix it. fix #1856
1 parent d15d50f commit 7c40da4

File tree

4 files changed

+127
-8
lines changed

4 files changed

+127
-8
lines changed

BREAKING_CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## From 32.x to 33
2+
3+
- **vtkRenderWindowInteractor**: KeyPress, KeyDown and KeyUp events are now observed on the container and no longer on the document. You may have to add "tabIndex" on your containers to give focus on your render windows and catch
4+
key events. Check the RenderWindowInteractor example.
5+
16
## From 31.x to 32
27

38
- **vtkMapper**: remove `mapScalarsToTexture` from the public API. The function becomes protected and its API changes. This shouldn't cause any issue in most cases.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<style>
2+
#view-1:focus {
3+
outline: none; /* remove default */
4+
box-shadow: 0 0 20px 10px rgba(0, 255, 0, 0.6); /* red glow */
5+
}
6+
#view-2:focus, #view-2:focus-visible {
7+
outline: none; /* remove default */
8+
}
9+
10+
input:focus {
11+
outline: none;
12+
border: 2px solid teal;
13+
box-shadow: 0 0 4px teal;
14+
}
15+
16+
/* Optional: Use focus-visible for keyboard-only styling */
17+
select:focus-visible {
18+
outline: 3px dashed orange;
19+
}
20+
</style>
21+
<h3>Click or press tab until you "focus" a render window, then type keys (e.g. r, w, s)</h3>
22+
<table>
23+
<tr>
24+
<td>Click with mouse then press space key:</td>
25+
<td>
26+
<input type="checkbox" id="checkboxTranslation" checked>
27+
</td>
28+
</tr>
29+
<tr>
30+
<td>Click then key up and down :</td>
31+
<td><input id='slider' type="range" min="0" max="255" step="1" value="255" style="width: 100px;"/></td>
32+
</tr>
33+
<tr>
34+
<td>Use key up and down to browse through:</td>
35+
<td>
36+
<select id="select">
37+
<option>One</option>
38+
<option>Two</option>
39+
<option selected="selected">Three</option>
40+
<option>Four</option>
41+
</select>
42+
</td>
43+
</tr>
44+
<tr>
45+
<td>
46+
<button id="buttonReset">Click and press space key</button>
47+
</td>
48+
</tr>
49+
</table>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import '@kitware/vtk.js/favicon';
2+
3+
// Load the rendering pieces we want to use (for both WebGL and WebGPU)
4+
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
5+
6+
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
7+
import vtkConeSource from '@kitware/vtk.js/Filters/Sources/ConeSource';
8+
import vtkGenericRenderWindow from '@kitware/vtk.js/Rendering/Misc/GenericRenderWindow';
9+
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
10+
11+
import controlPanel from './controlPanel.html';
12+
13+
// ----------------------------------------------------------------------------
14+
// Standard rendering code setup
15+
// ----------------------------------------------------------------------------
16+
17+
const container = document.querySelector('body');
18+
const controlContainer = document.createElement('div');
19+
controlContainer.innerHTML = controlPanel;
20+
container.appendChild(controlContainer);
21+
22+
global.RWIs = [];
23+
24+
const logs = document.createElement('pre');
25+
26+
const cone = vtkConeSource.newInstance();
27+
28+
for (let i = 0; i < 3; ++i) {
29+
const elementParent = document.createElement('div');
30+
elementParent.style.width = '33%';
31+
elementParent.style.height = '300px';
32+
elementParent.style.display = 'inline-block';
33+
34+
const element = document.createElement('div');
35+
element.setAttribute('id', `view-${i}`);
36+
element.style.width = '100%';
37+
element.style.height = '100%';
38+
element.tabIndex = 0;
39+
elementParent.appendChild(element);
40+
41+
container.appendChild(elementParent);
42+
43+
const grw = vtkGenericRenderWindow.newInstance();
44+
45+
const color = [0, 0, 0];
46+
color[i % 3] = 1;
47+
grw.getRenderer().setBackground(color);
48+
49+
const mapper = vtkMapper.newInstance();
50+
mapper.setInputConnection(cone.getOutputPort());
51+
const actor = vtkActor.newInstance();
52+
actor.setMapper(mapper);
53+
grw.getRenderer().addActor(actor);
54+
grw.getRenderer().resetCamera();
55+
56+
grw.setContainer(element);
57+
grw.resize();
58+
59+
global.RWIs.push(grw.getInteractor());
60+
// Pick on mouse right click
61+
grw.getInteractor().onKeyDown((callData) => {
62+
logs.textContent += `Pressed ${callData.key} on RWI #${i}\n`;
63+
});
64+
}
65+
container.appendChild(logs);

Sources/Rendering/Core/RenderWindowInteractor/index.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,11 @@ function vtkRenderWindowInteractor(publicAPI, model) {
237237
});
238238
container.addEventListener('pointerup', publicAPI.handlePointerUp);
239239
container.addEventListener('pointercancel', publicAPI.handlePointerCancel);
240-
document.addEventListener('keypress', publicAPI.handleKeyPress);
241-
document.addEventListener('keydown', publicAPI.handleKeyDown);
242-
document.addEventListener('keyup', publicAPI.handleKeyUp);
240+
container.addEventListener('keypress', publicAPI.handleKeyPress);
241+
container.addEventListener('keydown', publicAPI.handleKeyDown);
242+
container.addEventListener('keyup', publicAPI.handleKeyUp);
243243

244-
document.addEventListener(
244+
container.addEventListener(
245245
'pointerlockchange',
246246
publicAPI.handlePointerLockChange
247247
);
@@ -307,10 +307,10 @@ function vtkRenderWindowInteractor(publicAPI, model) {
307307
publicAPI.handlePointerCancel
308308
);
309309
}
310-
document.removeEventListener('keypress', publicAPI.handleKeyPress);
311-
document.removeEventListener('keydown', publicAPI.handleKeyDown);
312-
document.removeEventListener('keyup', publicAPI.handleKeyUp);
313-
document.removeEventListener(
310+
container.removeEventListener('keypress', publicAPI.handleKeyPress);
311+
container.removeEventListener('keydown', publicAPI.handleKeyDown);
312+
container.removeEventListener('keyup', publicAPI.handleKeyUp);
313+
container.removeEventListener(
314314
'pointerlockchange',
315315
publicAPI.handlePointerLockChange
316316
);

0 commit comments

Comments
 (0)