Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
QtInputDelegate.java
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4package org.qtproject.qt.android;
5
6import android.app.Activity;
7import android.content.Context;
8import android.graphics.Rect;
9import android.os.Build;
10import android.os.Bundle;
11import android.os.Handler;
12import android.os.Looper;
13import android.os.ResultReceiver;
14import android.text.method.MetaKeyKeyListener;
15import android.util.DisplayMetrics;
16import android.util.Log;
17import android.view.InputDevice;
18import android.view.KeyCharacterMap;
19import android.view.KeyEvent;
20import android.view.MotionEvent;
21import android.view.WindowInsets;
22import android.view.WindowInsets.Type;
23import android.view.WindowInsetsAnimationController;
24import android.view.WindowInsetsAnimationControlListener;
25import android.view.WindowManager;
26import android.view.View;
27import android.view.ViewTreeObserver;
28import android.view.inputmethod.InputMethodManager;
29
30class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, QtInputInterface
31{
32
33 private static final String TAG = "QtInputDelegate";
34 // keyboard methods
35 static native void keyDown(int key, int unicode, int modifier, boolean autoRepeat);
36 static native void keyUp(int key, int unicode, int modifier, boolean autoRepeat);
37 static native void keyboardVisibilityChanged(boolean visibility);
38 static native void keyboardGeometryChanged(int x, int y, int width, int height);
39 // keyboard methods
40
41 // dispatch events methods
42 static native boolean dispatchGenericMotionEvent(MotionEvent event);
43 static native boolean dispatchKeyEvent(KeyEvent event);
44 // dispatch events methods
45
46 // handle methods
47 static native void handleLocationChanged(int id, int x, int y);
48 // handle methods
49
50 private QtEditText m_currentEditText = null;
51 private InputMethodManager m_imm;
52
53 // We can't rely on a hardcoded value, because screens have different resolutions.
54 // That is why we assume that the keyboard should be higher than 0.15 of the screen.
55 private static final float KEYBOARD_TO_SCREEN_RATIO = 0.15f;
56
57 private boolean m_keyboardTransitionInProgress = false;
58 private boolean m_keyboardIsVisible = false;
59 private boolean m_isKeyboardHidingAnimationOngoing = false;
60 private long m_showHideTimeStamp = System.nanoTime();
61 private int m_portraitKeyboardHeight = 0;
62 private int m_landscapeKeyboardHeight = 0;
63 private int m_probeKeyboardHeightDelayMs = 50;
64
65 private int m_softInputMode = 0;
66
67 private static Boolean m_tabletEventSupported = null;
68
69 private static int m_oldX, m_oldY;
70
71
72 private long m_metaState;
73 private int m_lastChar = 0;
74 private boolean m_backKeyPressedSent = false;
75
76 // Note: because of the circular call to updateFullScreen() from the delegate, we need
77 // a listener to be able to do that call from the delegate, because that's where that
78 // logic lives
82
83 private final KeyboardVisibilityListener m_keyboardVisibilityListener;
84
85 QtInputDelegate(KeyboardVisibilityListener listener)
86 {
87 m_keyboardVisibilityListener = listener;
88 }
89
90 void initInputMethodManager(Activity activity)
91 {
92 m_imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
93 if (m_imm == null)
94 Log.w(TAG, "getSystemService() returned a null InputMethodManager instance");
95
96 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
97 View rootView = activity.getWindow().getDecorView();
98 rootView.setOnApplyWindowInsetsListener((view, insets) -> {
99 WindowInsets windowInsets = view.onApplyWindowInsets(insets);
100 if (m_keyboardIsVisible != windowInsets.isVisible(WindowInsets.Type.ime()))
101 setKeyboardVisibility_internal(!m_keyboardIsVisible, System.nanoTime());
102 return windowInsets;
103 });
104 }
105 }
106
107 private final ViewTreeObserver.OnGlobalLayoutListener keyboardListener =
108 new ViewTreeObserver.OnGlobalLayoutListener() {
109 @Override
110 public void onGlobalLayout() {
111 if (!isKeyboardHidden())
112 setKeyboardTransitionInProgress(false);
113 }
114 };
115
116 private void setKeyboardTransitionInProgress(boolean state)
117 {
118 if (m_keyboardTransitionInProgress == state || m_currentEditText == null)
119 return;
120
121 m_keyboardTransitionInProgress = state;
122 ViewTreeObserver observer = m_currentEditText.getViewTreeObserver();
123 if (state)
124 observer.addOnGlobalLayoutListener(keyboardListener);
125 else
126 observer.removeOnGlobalLayoutListener(keyboardListener);
127 }
128
129 // QtInputInterface implementation begin
130 @Override
131 public void updateSelection(final int selStart, final int selEnd,
132 final int candidatesStart, final int candidatesEnd)
133 {
134 if (m_imm != null) {
135 QtNative.runAction(() -> {
136 if (m_imm != null) {
137 m_imm.updateSelection(m_currentEditText, selStart, selEnd,
138 candidatesStart, candidatesEnd);
139 }
140 });
141 }
142 }
143
144 private void showKeyboard(Activity activity,
145 final int x, final int y, final int width, final int height,
146 final int inputHints, final int enterKeyType)
147 {
148 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
149 activity.getWindow().getInsetsController().controlWindowInsetsAnimation(
150 WindowInsets.Type.ime(), -1, null, null,
151 new WindowInsetsAnimationControlListener() {
152 @Override
153 public void onCancelled(WindowInsetsAnimationController controller) { }
154
155 @Override
156 public void onReady(WindowInsetsAnimationController controller, int types) { }
157
158 @Override
159 public void onFinished(WindowInsetsAnimationController controller) {
160 QtNativeInputConnection.updateCursorPosition();
161 if (m_softInputMode == 0)
162 probeForKeyboardHeight(activity, x, y, width, height,
163 inputHints, enterKeyType);
164 }
165 });
166 activity.getWindow().getInsetsController().show(Type.ime());
167 } else {
168 if (m_imm == null)
169 return;
170 m_imm.showSoftInput(m_currentEditText, 0, new ResultReceiver(new Handler(Looper.getMainLooper())) {
171 @Override
172 @SuppressWarnings("fallthrough")
173 protected void onReceiveResult(int resultCode, Bundle resultData) {
174 switch (resultCode) {
175 case InputMethodManager.RESULT_SHOWN:
176 QtNativeInputConnection.updateCursorPosition();
177 //FALLTHROUGH
178 case InputMethodManager.RESULT_UNCHANGED_SHOWN:
179 setKeyboardVisibility(true, System.nanoTime());
180 if (m_softInputMode == 0) {
181 probeForKeyboardHeight(activity,
182 x, y, width, height, inputHints, enterKeyType);
183 }
184 break;
185 case InputMethodManager.RESULT_HIDDEN:
186 case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
187 setKeyboardVisibility(false, System.nanoTime());
188 break;
189 }
190 }
191 });
192 }
193 }
194
195 @Override
196 public void showSoftwareKeyboard(Activity activity,
197 final int x, final int y, final int width, final int height,
198 final int inputHints, final int enterKeyType)
199 {
200 if (m_imm == null)
201 return;
202
203 QtNative.runAction(() -> {
204 if (m_imm == null || m_currentEditText == null)
205 return;
206
207 if (updateSoftInputMode(activity, height))
208 return;
209
210 m_currentEditText.setEditTextOptions(enterKeyType, inputHints);
211 m_currentEditText.setLayoutParams(new QtLayout.LayoutParams(width, height, x, y));
212 m_currentEditText.requestFocus();
213 m_currentEditText.postDelayed(() -> {
214 showKeyboard(activity, x, y, width, height, inputHints, enterKeyType);
215 if (m_currentEditText.m_optionsChanged) {
216 m_imm.restartInput(m_currentEditText);
217 m_currentEditText.m_optionsChanged = false;
218 }
219 }, 15);
220 });
221 }
222
223 @Override
224 public int getSelectionHandleWidth()
225 {
226 return m_currentEditText == null ? 0 : m_currentEditText.getSelectionHandleWidth();
227 }
228
229 /* called from the C++ code when the position of the cursor or selection handles needs to
230 be adjusted.
231 mode is one of QAndroidInputContext::CursorHandleShowMode
232 */
233 @Override
234 public void updateHandles(int mode, int editX, int editY, int editButtons,
235 int x1, int y1, int x2, int y2, boolean rtl)
236 {
237 QtNative.runAction(() -> {
238 if (m_currentEditText != null)
239 m_currentEditText.updateHandles(mode, editX, editY, editButtons, x1, y1, x2, y2, rtl);
240 });
241 }
242
243 @Override
244 public QtInputConnection.QtInputConnectionListener getInputConnectionListener()
245 {
246 return this;
247 }
248
249 @Override
250 public void resetSoftwareKeyboard()
251 {
252 if (m_imm == null || m_currentEditText == null)
253 return;
254 m_currentEditText.postDelayed(() -> {
255 if (m_imm == null || m_currentEditText == null)
256 return;
257 m_imm.restartInput(m_currentEditText);
258 m_currentEditText.m_optionsChanged = false;
259 }, 5);
260 }
261
262 @Override
263 public void hideSoftwareKeyboard()
264 {
265 if (m_imm == null || m_currentEditText == null)
266 return;
267
268 m_isKeyboardHidingAnimationOngoing = true;
269 QtNative.runAction(() -> {
270 if (m_imm == null || m_currentEditText == null)
271 return;
272
273 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
274 Activity activity = QtNative.activity();
275 if (activity == null) {
276 Log.w(TAG, "hideSoftwareKeyboard: The activity reference is null");
277 return;
278 }
279 activity.getWindow().getInsetsController().hide(Type.ime());
280 } else {
281 m_imm.hideSoftInputFromWindow(m_currentEditText.getWindowToken(), 0,
282 new ResultReceiver(new Handler(Looper.getMainLooper())) {
283 @Override
284 protected void onReceiveResult(int resultCode, Bundle resultData) {
285 switch (resultCode) {
286 case InputMethodManager.RESULT_SHOWN:
287 case InputMethodManager.RESULT_UNCHANGED_SHOWN:
288 setKeyboardVisibility(true, System.nanoTime());
289 break;
290 case InputMethodManager.RESULT_HIDDEN:
291 case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
292 setKeyboardVisibility(false, System.nanoTime());
293 break;
294 }
295 }
296 });
297 }
298 });
299 }
300
301 // Is the keyboard fully visible i.e. visible and no ongoing animation
302 @Override
303 public boolean isSoftwareKeyboardVisible()
304 {
305 return isKeyboardVisible() && !m_isKeyboardHidingAnimationOngoing;
306 }
307 // QtInputInterface implementation end
308
309 // QtInputConnectionListener methods
310 @Override
311 public boolean keyboardTransitionInProgress() {
312 return m_keyboardTransitionInProgress;
313 }
314
315 @Override
316 public boolean isKeyboardHidden() {
317 Activity activity = QtNative.activity();
318 if (activity == null) {
319 Log.w(TAG, "isKeyboardHidden: The activity reference is null");
320 return true;
321 }
322
323 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
324 Rect r = new Rect();
325 activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
326 DisplayMetrics metrics = new DisplayMetrics();
327 QtDisplayManager.getDisplay(activity).getMetrics(metrics);
328 int screenHeight = metrics.heightPixels;
329 final int kbHeight = screenHeight - r.bottom;
330 return kbHeight < screenHeight * KEYBOARD_TO_SCREEN_RATIO;
331 }
332
333 return !m_keyboardIsVisible;
334 }
335
336 @Override
337 public void onSetClosing(boolean closing) {
338 if (!closing)
339 setKeyboardVisibility(true, System.nanoTime());
340 }
341
342 @Override
343 public void onHideKeyboardRunnableDone(boolean visibility, long hideTimeStamp) {
344 setKeyboardVisibility(visibility, hideTimeStamp);
345 }
346
347 @Override
348 public void onSendKeyEventDefaultCase() {
350 }
351
352 @Override
353 public void onEditTextChanged(QtEditText editText) {
354 setFocusedView(editText);
355 }
356 // QtInputConnectionListener methods
357
358 boolean isKeyboardVisible()
359 {
360 return m_keyboardIsVisible;
361 }
362
363 void setSoftInputMode(int inputMode)
364 {
365 m_softInputMode = inputMode;
366 }
367
368 QtEditText getCurrentQtEditText()
369 {
370 return m_currentEditText;
371 }
372
373 private void keyboardVisibilityUpdated(boolean visibility)
374 {
375 m_isKeyboardHidingAnimationOngoing = false;
376 QtInputDelegate.keyboardVisibilityChanged(visibility);
377 }
378
379 void setKeyboardVisibility(boolean visibility, long timeStamp)
380 {
381 // Since API 30 keyboard visibility changes are tracked by OnApplyWindowInsetsListener.
382 // There are no manual changes anymore
383 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
384 setKeyboardVisibility_internal(visibility, timeStamp);
385 }
386
387 private void setKeyboardVisibility_internal(boolean visibility, long timeStamp)
388 {
389 if (m_showHideTimeStamp > timeStamp)
390 return;
391 m_showHideTimeStamp = timeStamp;
392
393 if (m_keyboardIsVisible == visibility)
394 return;
395 m_keyboardIsVisible = visibility;
396 keyboardVisibilityUpdated(m_keyboardIsVisible);
397 setKeyboardTransitionInProgress(visibility);
398
399 if (!visibility) {
400 // Hiding the keyboard clears the immersive mode, so we need to set it again.
401 m_keyboardVisibilityListener.onKeyboardVisibilityChange();
402 if (m_currentEditText != null)
403 m_currentEditText.clearFocus();
404 }
405 }
406
407 void setFocusedView(QtEditText currentEditText)
408 {
409 setKeyboardTransitionInProgress(false);
410 m_currentEditText = currentEditText;
411 }
412
413 private boolean updateSoftInputMode(Activity activity, int height)
414 {
415 DisplayMetrics metrics = new DisplayMetrics();
416 QtDisplayManager.getDisplay(activity).getMetrics(metrics);
417
418 // If the screen is in portrait mode than we estimate that keyboard height
419 // will not be higher than 2/5 of the screen. Otherwise we estimate that keyboard height
420 // will not be higher than 2/3 of the screen
421 final int visibleHeight;
422 if (metrics.widthPixels < metrics.heightPixels) {
423 visibleHeight = m_portraitKeyboardHeight != 0 ?
424 m_portraitKeyboardHeight : metrics.heightPixels * 3 / 5;
425 } else {
426 visibleHeight = m_landscapeKeyboardHeight != 0 ?
427 m_landscapeKeyboardHeight : metrics.heightPixels / 3;
428 }
429
430 if (m_softInputMode != 0) {
431 activity.getWindow().setSoftInputMode(m_softInputMode);
432 int stateHidden = WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
433 return (m_softInputMode & stateHidden) != 0;
434 } else {
435 int stateUnchanged = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
436 if (height > visibleHeight) {
437 int adjustResize = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
438 activity.getWindow().setSoftInputMode(stateUnchanged | adjustResize);
439 } else {
440 int adjustPan = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
441 activity.getWindow().setSoftInputMode(stateUnchanged | adjustPan);
442 }
443 }
444 return false;
445 }
446
447 private void probeForKeyboardHeight(Activity activity, int x, int y,
448 int width, int height, int inputHints, int enterKeyType)
449 {
450 if (m_currentEditText == null) {
451 Log.w(TAG, "probeForKeyboardHeight: null QtEditText");
452 return;
453 }
454 m_currentEditText.postDelayed(() -> {
455 if (!m_keyboardIsVisible)
456 return;
457 DisplayMetrics metrics = new DisplayMetrics();
458 QtDisplayManager.getDisplay(activity).getMetrics(metrics);
459 Rect r = new Rect();
460 activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
461 if (metrics.heightPixels != r.bottom) {
462 if (metrics.widthPixels > metrics.heightPixels) { // landscape
463 if (m_landscapeKeyboardHeight != r.bottom) {
464 m_landscapeKeyboardHeight = r.bottom;
465 showSoftwareKeyboard(activity, x, y, width, height,
466 inputHints, enterKeyType);
467 }
468 } else {
469 if (m_portraitKeyboardHeight != r.bottom) {
470 m_portraitKeyboardHeight = r.bottom;
471 showSoftwareKeyboard(activity, x, y, width, height,
472 inputHints, enterKeyType);
473 }
474 }
475 } else {
476 // no luck ?
477 // maybe the delay was too short, so let's make it longer
478 if (m_probeKeyboardHeightDelayMs < 1000)
479 m_probeKeyboardHeightDelayMs *= 2;
480 }
481 }, m_probeKeyboardHeightDelayMs);
482 }
483
484 boolean onKeyDown(int keyCode, KeyEvent event)
485 {
486 m_metaState = MetaKeyKeyListener.handleKeyDown(m_metaState, keyCode, event);
487 int metaState = MetaKeyKeyListener.getMetaState(m_metaState) | event.getMetaState();
488 int c = event.getUnicodeChar(metaState);
489 int lc = c;
490 m_metaState = MetaKeyKeyListener.adjustMetaAfterKeypress(m_metaState);
491
492 if ((c & KeyCharacterMap.COMBINING_ACCENT) != 0) {
493 c = c & KeyCharacterMap.COMBINING_ACCENT_MASK;
494 c = KeyEvent.getDeadChar(m_lastChar, c);
495 }
496
497 if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP
498 || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
499 || keyCode == KeyEvent.KEYCODE_MUTE)
500 && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) {
501 return false;
502 }
503
504 m_lastChar = lc;
505 if (keyCode == KeyEvent.KEYCODE_BACK) {
506 m_backKeyPressedSent = !isKeyboardVisible();
507 if (!m_backKeyPressedSent)
508 return true;
509 }
510
511 QtInputDelegate.keyDown(keyCode, c, event.getMetaState(), event.getRepeatCount() > 0);
512
513 return true;
514 }
515
516 boolean onKeyUp(int keyCode, KeyEvent event)
517 {
518 if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP
519 || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
520 || keyCode == KeyEvent.KEYCODE_MUTE)
521 && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) {
522 return false;
523 }
524
525 if (keyCode == KeyEvent.KEYCODE_BACK && !m_backKeyPressedSent) {
527 setKeyboardVisibility(false, System.nanoTime());
528 return true;
529 }
530
531 m_metaState = MetaKeyKeyListener.handleKeyUp(m_metaState, keyCode, event);
532 boolean autoRepeat = event.getRepeatCount() > 0;
533 QtInputDelegate.keyUp(keyCode, event.getUnicodeChar(), event.getMetaState(), autoRepeat);
534
535 return true;
536 }
537
538 boolean handleDispatchKeyEvent(KeyEvent event)
539 {
540 if (event.getAction() == KeyEvent.ACTION_MULTIPLE
541 && event.getCharacters() != null
542 && event.getCharacters().length() == 1
543 && event.getKeyCode() == 0) {
544 keyDown(0, event.getCharacters().charAt(0), event.getMetaState(),
545 event.getRepeatCount() > 0);
546 keyUp(0, event.getCharacters().charAt(0), event.getMetaState(),
547 event.getRepeatCount() > 0);
548 }
549
550 return dispatchKeyEvent(event);
551 }
552
553 boolean handleDispatchGenericMotionEvent(MotionEvent event)
554 {
556 }
557
559 // Mouse and Touch Input //
561
562 // tablet methods
563 static native boolean isTabletEventSupported();
564 static native void tabletEvent(int winId, int deviceId, long time, int action,
565 int pointerType, int buttonState, float x, float y,
566 float pressure);
567 // tablet methods
568
569 // pointer methods
570 static native void mouseDown(int winId, int x, int y, int mouseButtonState);
571 static native void mouseUp(int winId, int x, int y, int mouseButtonState);
572 static native void mouseMove(int winId, int x, int y, int mouseButtonState);
573 static native void mouseWheel(int winId, int x, int y, float hDelta, float vDelta);
574 static native void touchBegin(int winId);
575 static native void touchAdd(int winId, int pointerId, int action, boolean primary,
576 int x, int y, float major, float minor, float rotation,
577 float pressure);
578 static native void touchEnd(int winId, int action);
579 static native void touchCancel(int winId);
580 static native void longPress(int winId, int x, int y);
581 // pointer methods
582
583 static private int getAction(int index, MotionEvent event)
584 {
585 int action = event.getActionMasked();
586 if (action == MotionEvent.ACTION_MOVE) {
587 int hsz = event.getHistorySize();
588 if (hsz > 0) {
589 float x = event.getX(index);
590 float y = event.getY(index);
591 for (int h = 0; h < hsz; ++h) {
592 if ( event.getHistoricalX(index, h) != x ||
593 event.getHistoricalY(index, h) != y )
594 return 1;
595 }
596 return 2;
597 }
598 return 1;
599 }
600 if (action == MotionEvent.ACTION_DOWN
601 || action == MotionEvent.ACTION_POINTER_DOWN && index == event.getActionIndex()) {
602 return 0;
603 } else if (action == MotionEvent.ACTION_UP
604 || action == MotionEvent.ACTION_POINTER_UP && index == event.getActionIndex()) {
605 return 3;
606 }
607 return 2;
608 }
609
610 static void sendTouchEvent(MotionEvent event, int id)
611 {
612 int pointerType = 0;
613
614 if (m_tabletEventSupported == null)
615 m_tabletEventSupported = isTabletEventSupported();
616
617 switch (event.getToolType(0)) {
618 case MotionEvent.TOOL_TYPE_STYLUS:
619 pointerType = 1; // QTabletEvent::Pen
620 break;
621 case MotionEvent.TOOL_TYPE_ERASER:
622 pointerType = 3; // QTabletEvent::Eraser
623 break;
624 }
625
626 if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
627 sendMouseEvent(event, id);
628 } else if (m_tabletEventSupported && pointerType != 0) {
629 tabletEvent(id, event.getDeviceId(), event.getEventTime(), event.getActionMasked(),
630 pointerType, event.getButtonState(),
631 event.getX(), event.getY(), event.getPressure());
632 } else {
633 touchBegin(id);
634 for (int i = 0; i < event.getPointerCount(); ++i) {
635 touchAdd(id,
636 event.getPointerId(i),
637 getAction(i, event),
638 i == 0,
639 (int)event.getX(i),
640 (int)event.getY(i),
641 event.getTouchMajor(i),
642 event.getTouchMinor(i),
643 event.getOrientation(i),
644 event.getPressure(i));
645 }
646
647 switch (event.getAction()) {
648 case MotionEvent.ACTION_DOWN:
649 touchEnd(id, 0);
650 break;
651
652 case MotionEvent.ACTION_UP:
653 touchEnd(id, 2);
654 break;
655
656 case MotionEvent.ACTION_CANCEL:
657 touchCancel(id);
658 break;
659
660 default:
661 touchEnd(id, 1);
662 }
663 }
664 }
665
666 static void sendTrackballEvent(MotionEvent event, int id)
667 {
668 sendMouseEvent(event,id);
669 }
670
671 static boolean sendGenericMotionEvent(MotionEvent event, int id)
672 {
673 int scrollOrHoverMove = MotionEvent.ACTION_SCROLL | MotionEvent.ACTION_HOVER_MOVE;
674 int pointerDeviceModifier = (event.getSource() & InputDevice.SOURCE_CLASS_POINTER);
675 boolean isPointerDevice = pointerDeviceModifier == InputDevice.SOURCE_CLASS_POINTER;
676
677 if ((event.getAction() & scrollOrHoverMove) == 0 || !isPointerDevice )
678 return false;
679
680 return sendMouseEvent(event, id);
681 }
682
683 static boolean sendMouseEvent(MotionEvent event, int id)
684 {
685 switch (event.getActionMasked()) {
686 case MotionEvent.ACTION_UP:
687 mouseUp(id, (int) event.getX(), (int) event.getY(), event.getButtonState());
688 break;
689
690 case MotionEvent.ACTION_DOWN:
691 mouseDown(id, (int) event.getX(), (int) event.getY(), event.getButtonState());
692 m_oldX = (int) event.getX();
693 m_oldY = (int) event.getY();
694 break;
695 case MotionEvent.ACTION_HOVER_MOVE:
696 case MotionEvent.ACTION_MOVE:
697 if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
698 mouseMove(id, (int) event.getX(), (int) event.getY(), event.getButtonState());
699 } else {
700 int dx = (int) (event.getX() - m_oldX);
701 int dy = (int) (event.getY() - m_oldY);
702 if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
703 mouseMove(id, (int) event.getX(), (int) event.getY(), event.getButtonState());
704 m_oldX = (int) event.getX();
705 m_oldY = (int) event.getY();
706 }
707 }
708 break;
709 case MotionEvent.ACTION_SCROLL:
710 mouseWheel(id, (int) event.getX(), (int) event.getY(),
711 event.getAxisValue(MotionEvent.AXIS_HSCROLL),
712 event.getAxisValue(MotionEvent.AXIS_VSCROLL));
713 break;
714 default:
715 return false;
716 }
717 return true;
718 }
719}
PeripheralState state
QPainter Context
void mouseMove(QWindow *window, QPoint pos=QPoint(), int delay=-1)
Definition qtestmouse.h:147
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
bool isSoftwareKeyboardVisible()
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
Q_CORE_EXPORT QtJniTypes::Activity activity()
#define TAG(x)
static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, QtJniTypes::MotionEvent event)
static jboolean dispatchKeyEvent(JNIEnv *, jclass, QtJniTypes::KeyEvent event)
GLint GLint GLint GLint GLint x
GLenum mode
GLsizei GLenum GLenum * types
GLuint64 key
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLboolean r
GLuint GLfloat GLfloat GLfloat x1
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLuint index
GLint GLsizei width
GLint y
GLfloat GLfloat GLfloat GLfloat h
struct _cl_event * event
const GLubyte * c
GLfixed GLfixed GLfixed y2
GLfixed GLfixed x2
@ Handler
Type
[0]
static QPointingDevice::PointerType pointerType(unsigned currentCursor)
QQuickView * view
[0]