Line data Source code
1 : /**
2 : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #include "XLInputDispatcher.h"
25 : #include "XLInputListener.h"
26 :
27 : namespace STAPPLER_VERSIONIZED stappler::xenolith {
28 :
29 126 : InputListenerStorage::~InputListenerStorage() {
30 63 : clear();
31 126 : }
32 :
33 63 : InputListenerStorage::InputListenerStorage(PoolRef *p) : PoolRef(p) {
34 63 : perform([&, this] {
35 63 : _preSceneEvents = new (_pool) memory::vector<Rec>;
36 63 : _sceneEvents = new (_pool) memory::vector<Rec>;
37 63 : _postSceneEvents = new (_pool) memory::vector<Rec>;
38 :
39 63 : _sceneEvents->reserve(256);
40 63 : });
41 63 : }
42 :
43 9580 : void InputListenerStorage::clear() {
44 10399 : for (auto &it : *_preSceneEvents) {
45 819 : it.listener->release(0);
46 : }
47 32866 : for (auto &it : *_sceneEvents) {
48 23286 : it.listener->release(0);
49 : }
50 19181 : for (auto &it : *_postSceneEvents) {
51 9601 : it.listener->release(0);
52 : }
53 :
54 9580 : _preSceneEvents->clear();
55 9580 : _sceneEvents->clear();
56 9580 : _postSceneEvents->clear();
57 9580 : _maxFocusValue = 0;
58 9580 : }
59 :
60 9517 : void InputListenerStorage::reserve(const InputListenerStorage *st) {
61 9517 : _preSceneEvents->reserve(st->_preSceneEvents->size());
62 9517 : _sceneEvents->reserve(st->_sceneEvents->size());
63 9517 : _postSceneEvents->reserve(st->_postSceneEvents->size());
64 9517 : }
65 :
66 33706 : void InputListenerStorage::addListener(InputListener *input, uint32_t focus) {
67 33706 : input->retain();
68 33706 : auto p = input->getPriority();
69 33706 : if (p == 0) {
70 23286 : _sceneEvents->emplace_back(Rec{input, focus});
71 10420 : } else if (p < 0) {
72 9601 : auto lb = std::lower_bound(_postSceneEvents->begin(), _postSceneEvents->end(), Rec{input, focus},
73 63 : [] (const Rec &l, const Rec &r) {
74 63 : return l.listener->getPriority() < r.listener->getPriority();
75 9601 : });
76 :
77 9601 : if (lb == _postSceneEvents->end()) {
78 9559 : _postSceneEvents->emplace_back(Rec{input, focus});
79 : } else {
80 42 : _postSceneEvents->emplace(lb, Rec{input, focus});
81 : }
82 : } else {
83 819 : auto lb = std::lower_bound(_preSceneEvents->begin(), _preSceneEvents->end(), Rec{input, focus},
84 63 : [] (const Rec &l, const Rec &r) {
85 63 : return l.listener->getPriority() < r.listener->getPriority();
86 819 : });
87 :
88 819 : if (lb == _preSceneEvents->end()) {
89 798 : _preSceneEvents->emplace_back(Rec{input, focus});
90 : } else {
91 21 : _preSceneEvents->emplace(lb, Rec{input, focus});
92 : }
93 : }
94 33706 : }
95 :
96 42362 : void InputListenerStorage::updateFocus(uint32_t focusValue) {
97 42362 : _maxFocusValue = max(focusValue, _maxFocusValue);
98 42362 : }
99 :
100 42 : bool InputDispatcher::init(PoolRef *pool, TextInputViewInterface *view) {
101 42 : if (view) {
102 42 : _textInput = Rc<TextInputManager>::create(view);
103 : }
104 42 : _pool = pool;
105 42 : return true;
106 : }
107 :
108 9538 : void InputDispatcher::update(const UpdateTime &time) {
109 9538 : _currentTime = time.global;
110 9538 : }
111 :
112 9559 : Rc<InputListenerStorage> InputDispatcher::acquireNewStorage() {
113 9559 : Rc<InputListenerStorage> req;
114 9559 : if (_tmpEvents) {
115 9496 : req = move(_tmpEvents);
116 9496 : _tmpEvents = nullptr;
117 : } else {
118 63 : req = Rc<InputListenerStorage>::alloc(_pool);
119 : }
120 9559 : if (_events) {
121 9517 : req->reserve(_events);
122 : }
123 9559 : return req;
124 0 : }
125 :
126 9559 : void InputDispatcher::commitStorage(Rc<InputListenerStorage> &&storage) {
127 9559 : _tmpEvents = move(_events);
128 9559 : _events = move(storage);
129 9559 : if (_tmpEvents) {
130 9517 : _tmpEvents->clear();
131 : }
132 9559 : }
133 :
134 5816 : void InputDispatcher::handleInputEvent(const InputEventData &event) {
135 5816 : if (!_events) {
136 0 : return;
137 : }
138 :
139 5816 : switch (event.event) {
140 0 : case InputEventName::None:
141 : case InputEventName::Max:
142 0 : return;
143 : break;
144 913 : case InputEventName::Begin: {
145 913 : auto v = _activeEvents.find(event.id);
146 913 : if (v == _activeEvents.end()) {
147 892 : v = _activeEvents.emplace(event.id, EventHandlersInfo{getEventInfo(event), Vector<Rc<InputListener>>()}).first;
148 : } else {
149 21 : v->second.clear(true);
150 21 : v->second.event = getEventInfo(event);
151 : }
152 :
153 913 : _events->foreach([&] (const InputListenerStorage::Rec &l) {
154 6243 : if (l.listener->canHandleEvent(v->second.event)) {
155 1559 : v->second.listeners.emplace_back(l.listener);
156 : }
157 6243 : return true;
158 : }, true);
159 :
160 913 : v->second.handle(true);
161 913 : break;
162 : }
163 334 : case InputEventName::Move: {
164 334 : auto v = _activeEvents.find(event.id);
165 334 : if (v != _activeEvents.end()) {
166 334 : updateEventInfo(v->second.event, event);
167 334 : v->second.handle(true);
168 : }
169 334 : break;
170 : }
171 892 : case InputEventName::End:
172 : case InputEventName::Cancel: {
173 892 : auto v = _activeEvents.find(event.id);
174 892 : if (v != _activeEvents.end()) {
175 892 : updateEventInfo(v->second.event, event);
176 892 : v->second.handle(false);
177 892 : v->second.clear(false);
178 892 : _activeEvents.erase(v);
179 : }
180 892 : break;
181 : }
182 1279 : case InputEventName::MouseMove: {
183 1279 : _pointerLocation = Vec2(event.x, event.y);
184 :
185 1279 : EventHandlersInfo handlers{getEventInfo(event)};
186 1279 : _events->foreach([&] (const InputListenerStorage::Rec &l) {
187 4433 : if (l.listener->canHandleEvent(handlers.event)) {
188 1793 : handlers.listeners.emplace_back(l.listener);
189 : }
190 4433 : return true;
191 : }, false);
192 :
193 1279 : handlers.handle(false);
194 :
195 1321 : for (auto &it : _activeEvents) {
196 42 : if ((it.second.event.data.modifiers & InputModifier::Unmanaged) == InputModifier::None) {
197 42 : it.second.event.data.x = event.x;
198 42 : it.second.event.data.y = event.y;
199 42 : it.second.event.data.event = InputEventName::Move;
200 42 : it.second.event.data.modifiers = event.modifiers;
201 42 : handleInputEvent(it.second.event.data);
202 : }
203 : }
204 1279 : break;
205 1279 : }
206 26 : case InputEventName::Scroll: {
207 26 : EventHandlersInfo handlers{getEventInfo(event)};
208 26 : _events->foreach([&] (const InputListenerStorage::Rec &l) {
209 136 : if (l.listener->canHandleEvent(handlers.event)) {
210 0 : handlers.listeners.emplace_back(l.listener);
211 : }
212 136 : return true;
213 : }, false);
214 26 : handlers.handle(false);
215 26 : break;
216 26 : }
217 84 : case InputEventName::Background: {
218 84 : _inBackground = event.getValue();
219 :
220 84 : EventHandlersInfo handlers{getEventInfo(event)};
221 84 : _events->foreach([&] (const InputListenerStorage::Rec &l) {
222 420 : if (l.listener->canHandleEvent(handlers.event)) {
223 42 : handlers.listeners.emplace_back(l.listener);
224 : }
225 420 : return true;
226 : }, false);
227 84 : handlers.handle(false);
228 :
229 84 : if (handlers.event.data.getValue()) {
230 : // Mouse left window, cancel active mouse events
231 42 : cancelTouchEvents(event.x, event.y, event.modifiers);
232 : }
233 84 : break;
234 84 : }
235 88 : case InputEventName::FocusGain: {
236 88 : _hasFocus = event.getValue();
237 :
238 88 : EventHandlersInfo handlers{getEventInfo(event)};
239 88 : _events->foreach([&] (const InputListenerStorage::Rec &l) {
240 347 : if (l.listener->canHandleEvent(handlers.event)) {
241 43 : handlers.listeners.emplace_back(l.listener);
242 : }
243 347 : return true;
244 : }, false);
245 88 : handlers.handle(false);
246 :
247 88 : if (!handlers.event.data.getValue()) {
248 : // Mouse left window, cancel active mouse events
249 25 : cancelTouchEvents(event.x, event.y, event.modifiers);
250 : }
251 88 : break;
252 88 : }
253 100 : case InputEventName::PointerEnter: {
254 100 : _pointerInWindow = event.getValue();
255 :
256 100 : EventHandlersInfo handlers{getEventInfo(event)};
257 100 : _events->foreach([&] (const InputListenerStorage::Rec &l) {
258 471 : if (l.listener->canHandleEvent(handlers.event)) {
259 49 : handlers.listeners.emplace_back(l.listener);
260 : }
261 471 : return true;
262 : }, false);
263 :
264 100 : handlers.handle(false);
265 :
266 100 : if (!handlers.event.data.getValue()) {
267 : // Mouse left window, cancel active mouse events
268 48 : cancelTouchEvents(event.x, event.y, event.modifiers);
269 : }
270 100 : break;
271 100 : }
272 903 : case InputEventName::KeyPressed: {
273 903 : if (_textInput && _textInput->canHandleInputEvent(event)) {
274 : // forward to text input
275 777 : if (_textInput->handleInputEvent(event)) {
276 756 : clearKey(event);
277 756 : return;
278 : }
279 : }
280 :
281 147 : auto v = resetKey(event);
282 :
283 147 : _events->foreach([&] (const InputListenerStorage::Rec &l) {
284 903 : if (l.listener->canHandleEvent(v->event)) {
285 21 : v->listeners.emplace_back(l.listener);
286 : }
287 903 : return true;
288 : }, true);
289 147 : v->handle(true);
290 147 : break;
291 : }
292 315 : case InputEventName::KeyRepeated:
293 315 : if (_textInput && _textInput->canHandleInputEvent(event)) {
294 : // forward to text input
295 231 : if (_textInput->handleInputEvent(event)) {
296 231 : clearKey(event);
297 231 : return;
298 : }
299 : }
300 :
301 84 : handleKey(event, false);
302 84 : break;
303 :
304 882 : case InputEventName::KeyReleased:
305 : case InputEventName::KeyCanceled:
306 882 : if (_textInput && _textInput->canHandleInputEvent(event)) {
307 : // forward to text input
308 756 : if (_textInput->handleInputEvent(event)) {
309 21 : clearKey(event);
310 21 : return;
311 : }
312 : }
313 :
314 861 : handleKey(event, true);
315 861 : break;
316 : }
317 : }
318 :
319 21 : Vector<InputEventData> InputDispatcher::getActiveEvents() const {
320 21 : Vector<InputEventData> eventsTmp; eventsTmp.reserve(_activeEvents.size());
321 42 : for (auto &it : _activeEvents) {
322 21 : eventsTmp.emplace_back(it.second.event.data);
323 : }
324 21 : return eventsTmp;
325 0 : }
326 :
327 63 : void InputDispatcher::setListenerExclusive(const InputListener *l) {
328 105 : for (auto &it : _activeEvents) {
329 42 : setListenerExclusive(it.second, l);
330 : }
331 84 : for (auto &it : _activeKeys) {
332 21 : setListenerExclusive(it.second, l);
333 : }
334 63 : }
335 :
336 73 : void InputDispatcher::setListenerExclusiveForTouch(const InputListener *l, uint32_t id) {
337 73 : auto it = _activeEvents.find(id);
338 73 : if (it != _activeEvents.end()) {
339 73 : setListenerExclusive(it->second, l);
340 : }
341 73 : }
342 :
343 21 : void InputDispatcher::setListenerExclusiveForKey(const InputListener *l, InputKeyCode id) {
344 21 : auto it = _activeKeys.find(id);
345 21 : if (it != _activeKeys.end()) {
346 21 : setListenerExclusive(it->second, l);
347 : }
348 21 : }
349 :
350 21 : bool InputDispatcher::hasActiveInput() const {
351 21 : return !_activeEvents.empty() || !_activeKeys.empty();
352 : }
353 :
354 2637 : InputEvent InputDispatcher::getEventInfo(const InputEventData &event) const {
355 2637 : auto loc = Vec2(event.x, event.y);
356 2637 : return InputEvent{event, loc, loc, loc, _currentTime, _currentTime, _currentTime, event.modifiers, event.modifiers};
357 : }
358 :
359 1436 : void InputDispatcher::updateEventInfo(InputEvent &event, const InputEventData &data) const {
360 1436 : event.previousLocation = event.currentLocation;
361 1436 : event.currentLocation = Vec2(data.x, data.y);
362 :
363 1436 : event.previousTime = event.currentTime;
364 1436 : event.currentTime = _currentTime;
365 :
366 1436 : event.previousModifiers = event.data.modifiers;
367 :
368 1436 : event.data.event = data.event;
369 1436 : event.data.x = data.x;
370 1436 : event.data.y = data.y;
371 1436 : event.data.button = data.button;
372 1436 : event.data.modifiers = data.modifiers;
373 :
374 1436 : if (event.data.isPointEvent()) {
375 1226 : event.data.point.valueX = data.point.valueX;
376 1226 : event.data.point.valueY = data.point.valueY;
377 1226 : event.data.point.density = data.point.density;
378 210 : } else if (event.data.isKeyEvent()) {
379 189 : event.data.key.keychar = data.key.keychar;
380 189 : event.data.key.keycode = data.key.keycode;
381 189 : event.data.key.keysym = data.key.keysym;
382 : }
383 1436 : }
384 :
385 4115 : void InputDispatcher::EventHandlersInfo::handle(bool removeOnFail) {
386 4115 : processed.clear();
387 4115 : if (exclusive) {
388 277 : processed.emplace_back(exclusive.get());
389 277 : auto res = exclusive->handleEvent(event);
390 277 : if (res == InputEventState::Declined) {
391 0 : exclusive = nullptr;
392 : }
393 : } else {
394 3838 : Vector<Rc<InputListener>> listenerToRemove;
395 3838 : auto vec = listeners;
396 8692 : for (auto &it : vec) {
397 4927 : processed.emplace_back(it.get());
398 4927 : auto res = it->handleEvent(event);
399 4927 : if (res == InputEventState::Captured && !exclusive && it->shouldSwallowEvent(event)) {
400 6 : setExclusive(it);
401 : }
402 :
403 4927 : if (exclusive) {
404 73 : if (std::find(processed.begin(), processed.end(), exclusive.get()) == processed.end()) {
405 0 : auto res = exclusive->handleEvent(event);
406 0 : if (res == InputEventState::Declined) {
407 0 : exclusive = nullptr;
408 : }
409 : }
410 73 : break;
411 : }
412 :
413 4854 : if (removeOnFail && res == InputEventState::Declined) {
414 0 : listenerToRemove.emplace_back(it);
415 : }
416 : }
417 :
418 3838 : for (auto &it : listenerToRemove) {
419 0 : auto iit = std::find(listeners.begin(), listeners.end(), it);
420 0 : if (iit != listeners.end()) {
421 0 : listeners.erase(iit);
422 : }
423 : }
424 3838 : }
425 4115 : processed.clear();
426 4115 : }
427 :
428 1060 : void InputDispatcher::EventHandlersInfo::clear(bool cancel) {
429 1060 : if (cancel) {
430 42 : event.data.event = isKeyEvent ? InputEventName::KeyCanceled : InputEventName::Cancel;
431 42 : handle(false);
432 : }
433 :
434 1060 : listeners.clear();
435 1060 : exclusive = nullptr;
436 1060 : }
437 :
438 163 : void InputDispatcher::EventHandlersInfo::setExclusive(const InputListener *l) {
439 163 : if (exclusive) {
440 6 : return;
441 : }
442 :
443 157 : auto v = std::find(listeners.begin(), listeners.end(), l);
444 157 : if (v != listeners.end()) {
445 73 : exclusive = *v;
446 :
447 73 : auto event = this->event;
448 73 : event.data.event = isKeyEvent ? InputEventName::KeyCanceled : InputEventName::Cancel;
449 246 : for (auto &iit : listeners) {
450 173 : if (iit.get() != l) {
451 100 : iit->handleEvent(event);
452 : }
453 : }
454 73 : listeners.clear();
455 : }
456 : }
457 :
458 157 : void InputDispatcher::setListenerExclusive(EventHandlersInfo &info, const InputListener *l) const {
459 157 : info.setExclusive(l);
460 157 : }
461 :
462 1008 : void InputDispatcher::clearKey(const InputEventData &event) {
463 1008 : if (event.key.keycode == InputKeyCode::Unknown) {
464 0 : auto v = _activeKeySyms.find(event.key.keysym);
465 0 : if (v != _activeKeySyms.end()) {
466 0 : v->second.clear(true);
467 0 : _activeKeySyms.erase(v);
468 : }
469 : } else {
470 1008 : auto v = _activeKeys.find(event.key.keycode);
471 1008 : if (v != _activeKeys.end()) {
472 0 : v->second.clear(true);
473 0 : _activeKeys.erase(v);
474 : }
475 : }
476 1008 : }
477 :
478 147 : InputDispatcher::EventHandlersInfo *InputDispatcher::resetKey(const InputEventData &event) {
479 147 : if (event.key.keycode == InputKeyCode::Unknown) {
480 63 : auto v = _activeKeySyms.find(event.key.keysym);
481 63 : if (v == _activeKeySyms.end()) {
482 42 : v = _activeKeySyms.emplace(event.key.keysym, EventHandlersInfo{getEventInfo(event), Vector<Rc<InputListener>>()}).first;
483 : } else {
484 21 : v->second.clear(true);
485 21 : v->second.event = getEventInfo(event);
486 : }
487 63 : v->second.isKeyEvent = true;
488 63 : return &v->second;
489 : } else {
490 84 : auto v = _activeKeys.find(event.key.keycode);
491 84 : if (v == _activeKeys.end()) {
492 84 : v = _activeKeys.emplace(event.key.keycode, EventHandlersInfo{getEventInfo(event), Vector<Rc<InputListener>>()}).first;
493 : } else {
494 0 : v->second.clear(true);
495 0 : v->second.event = getEventInfo(event);
496 : }
497 84 : v->second.isKeyEvent = true;
498 84 : return &v->second;
499 : }
500 : }
501 :
502 945 : void InputDispatcher::handleKey(const InputEventData &event, bool clear) {
503 945 : if (event.key.keycode == InputKeyCode::Unknown) {
504 84 : auto v = _activeKeySyms.find(event.key.keysym);
505 84 : if (v != _activeKeySyms.end()) {
506 84 : updateEventInfo(v->second.event, event);
507 84 : v->second.handle(!clear);
508 84 : if (clear) {
509 42 : v->second.clear(false);
510 42 : _activeKeySyms.erase(v);
511 : }
512 : }
513 : } else {
514 861 : auto v = _activeKeys.find(event.key.keycode);
515 861 : if (v != _activeKeys.end()) {
516 126 : updateEventInfo(v->second.event, event);
517 126 : v->second.handle(!clear);
518 126 : if (clear) {
519 84 : v->second.clear(false);
520 84 : _activeKeys.erase(v);
521 : }
522 : }
523 : }
524 945 : }
525 :
526 115 : void InputDispatcher::cancelTouchEvents(float x, float y, InputModifier mods) {
527 115 : auto tmpEvents = _activeEvents;
528 136 : for (auto &it : tmpEvents) {
529 21 : it.second.event.data.x = x;
530 21 : it.second.event.data.y = y;
531 21 : it.second.event.data.event = InputEventName::Cancel;
532 21 : it.second.event.data.modifiers = mods;
533 21 : handleInputEvent(it.second.event.data);
534 : }
535 115 : _activeEvents.clear();
536 115 : }
537 :
538 : }
|