Skip to content

Commit 8697452

Browse files
committed
fix unhandled edge cases for keyboard shortcuts (fixes #927, fixes #932, fixes #1063)
1 parent 508f113 commit 8697452

File tree

3 files changed

+59
-10
lines changed

3 files changed

+59
-10
lines changed

‎src/components/scene/keyboard-shortcuts.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var registerComponent = require('../../core/component').registerComponent;
2+
var shouldCaptureKeyEvent = require('../../utils/').shouldCaptureKeyEvent;
23
var THREE = require('../../lib/three');
34

45
var controls = new THREE.VRControls(new THREE.Object3D());
@@ -14,6 +15,7 @@ module.exports.Component = registerComponent('keyboard-shortcuts', {
1415
var scene = this.el;
1516

1617
this.listener = window.addEventListener('keyup', function (event) {
18+
if (!shouldCaptureKeyEvent(event)) { return; }
1719
if (self.enterVREnabled && event.keyCode === 70) { // f.
1820
scene.enterVR();
1921
}

‎src/components/wasd-controls.js‎

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var registerComponent = require('../core/component').registerComponent;
2+
var shouldCaptureKeyEvent = require('../utils/').shouldCaptureKeyEvent;
23
var THREE = require('../lib/three');
34

45
var MAX_DELTA = 0.2;
@@ -24,8 +25,12 @@ module.exports.Component = registerComponent('wasd-controls', {
2425
this.velocity = new THREE.Vector3();
2526
// To keep track of the pressed keys
2627
this.keys = {};
28+
this.onBlur = this.onBlur.bind(this);
29+
this.onFocus = this.onFocus.bind(this);
30+
this.onVisibilityChange = this.onVisibilityChange.bind(this);
2731
this.onKeyDown = this.onKeyDown.bind(this);
2832
this.onKeyUp = this.onKeyUp.bind(this);
33+
this.attachVisibilityEventListeners();
2934
},
3035

3136
update: function (previousData) {
@@ -81,11 +86,12 @@ module.exports.Component = registerComponent('wasd-controls', {
8186
},
8287

8388
play: function () {
84-
this.attachEventListeners();
89+
this.attachKeyEventListeners();
8590
},
8691

8792
pause: function () {
88-
this.removeEventListeners();
93+
this.keys = {};
94+
this.removeKeyEventListeners();
8995
},
9096

9197
tick: function (t) {
@@ -94,25 +100,54 @@ module.exports.Component = registerComponent('wasd-controls', {
94100

95101
remove: function () {
96102
this.pause();
103+
this.removeVisibilityEventListeners();
104+
},
105+
106+
attachVisibilityEventListeners: function () {
107+
window.addEventListener('blur', this.onBlur);
108+
window.addEventListener('focus', this.onFocus);
109+
document.addEventListener('visibilitychange', this.onVisibilityChange);
97110
},
98111

99-
attachEventListeners: function () {
100-
// Keyboard events
101-
window.addEventListener('keydown', this.onKeyDown, false);
102-
window.addEventListener('keyup', this.onKeyUp, false);
112+
removeVisibilityEventListeners: function () {
113+
window.removeEventListener('blur', this.onBlur);
114+
window.removeEventListener('focus', this.onFocus);
115+
document.removeEventListener('visibilitychange', this.onVisibilityChange);
103116
},
104117

105-
removeEventListeners: function () {
106-
// Keyboard events
118+
attachKeyEventListeners: function () {
119+
window.addEventListener('keydown', this.onKeyDown);
120+
window.addEventListener('keyup', this.onKeyUp);
121+
},
122+
123+
removeKeyEventListeners: function () {
107124
window.removeEventListener('keydown', this.onKeyDown);
108125
window.removeEventListener('keyup', this.onKeyUp);
109126
},
110127

128+
onBlur: function () {
129+
this.pause();
130+
},
131+
132+
onFocus: function () {
133+
this.play();
134+
},
135+
136+
onVisibilityChange: function () {
137+
if (document.hidden) {
138+
this.onBlur();
139+
} else {
140+
this.onFocus();
141+
}
142+
},
143+
111144
onKeyDown: function (event) {
145+
if (!shouldCaptureKeyEvent(event)) { return; }
112146
this.keys[event.keyCode] = true;
113147
},
114148

115149
onKeyUp: function (event) {
150+
if (!shouldCaptureKeyEvent(event)) { return; }
116151
this.keys[event.keyCode] = false;
117152
},
118153

‎src/utils/index.js‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,25 @@ var isIOS = module.exports.isIOS = function () {
131131
};
132132

133133
/**
134-
* Checks mobile device orientation
135-
* @return {Boolean} True if landscape orientation
134+
* Checks mobile device orientation.
135+
* @return {Boolean} True if landscape orientation.
136136
*/
137137
module.exports.isLandscape = function () {
138138
return window.orientation === 90 || window.orientation === -90;
139139
};
140140

141+
/**
142+
* Returns whether we should capture this keyboard event for keyboard shortcuts.
143+
* @param {Event} event Event object.
144+
* @returns {Boolean} Whether the key event should be captured.
145+
*/
146+
module.exports.shouldCaptureKeyEvent = function (event) {
147+
if (event.shiftKey || event.metaKey || event.altKey || event.ctrlKey) {
148+
return false;
149+
}
150+
return document.activeElement === document.body;
151+
};
152+
141153
/**
142154
* Splits a string into an array based on a delimiter.
143155
*

0 commit comments

Comments
 (0)