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