Android: Implement input backend interface
Interface for input-related actions, based off of QtInputDelegate. Implements all the QtInputDelegate functions called from native code plus an extra function that allows the native side to get a QtInputConnectionListener object for QtWindow creation. Removed some unused functions and unmarked @UsedFromNativeCode in some that are no longer called from native, but still used from java. Added QtInputConnectionListener null checks in QtInputConnection, due to the possibility of a non-existent InputInterface returning a null QtInputConnectionListener for the QtInputConnection constructor. Task-number: QTBUG-118874 Change-Id: I8d4cde3e0c735471d0fa30d16db20eb13542cdaa Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io>
This commit is contained in:
parent
ad649b583d
commit
6bee03629f
@ -45,6 +45,7 @@ set(java_sources
|
|||||||
src/org/qtproject/qt/android/QtAccessibilityInterface.java
|
src/org/qtproject/qt/android/QtAccessibilityInterface.java
|
||||||
src/org/qtproject/qt/android/QtMenuInterface.java
|
src/org/qtproject/qt/android/QtMenuInterface.java
|
||||||
src/org/qtproject/qt/android/QtLayoutInterface.java
|
src/org/qtproject/qt/android/QtLayoutInterface.java
|
||||||
|
src/org/qtproject/qt/android/QtInputInterface.java
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_internal_add_jar(Qt${QtBase_VERSION_MAJOR}Android
|
qt_internal_add_jar(Qt${QtBase_VERSION_MAJOR}Android
|
||||||
|
@ -65,6 +65,8 @@ class QtActivityDelegate extends QtActivityDelegateBase
|
|||||||
(QtMenuInterface)QtActivityDelegate.this);
|
(QtMenuInterface)QtActivityDelegate.this);
|
||||||
BackendRegister.registerBackend(QtLayoutInterface.class,
|
BackendRegister.registerBackend(QtLayoutInterface.class,
|
||||||
(QtLayoutInterface)QtActivityDelegate.this);
|
(QtLayoutInterface)QtActivityDelegate.this);
|
||||||
|
BackendRegister.registerBackend(QtInputInterface.class,
|
||||||
|
(QtInputInterface)m_inputDelegate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +78,7 @@ class QtActivityDelegate extends QtActivityDelegateBase
|
|||||||
BackendRegister.unregisterBackend(QtAccessibilityInterface.class);
|
BackendRegister.unregisterBackend(QtAccessibilityInterface.class);
|
||||||
BackendRegister.unregisterBackend(QtMenuInterface.class);
|
BackendRegister.unregisterBackend(QtMenuInterface.class);
|
||||||
BackendRegister.unregisterBackend(QtLayoutInterface.class);
|
BackendRegister.unregisterBackend(QtLayoutInterface.class);
|
||||||
|
BackendRegister.unregisterBackend(QtInputInterface.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,6 @@ abstract class QtActivityDelegateBase
|
|||||||
return m_displayManager;
|
return m_displayManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedFromNativeCode
|
|
||||||
QtInputDelegate getInputDelegate() {
|
QtInputDelegate getInputDelegate() {
|
||||||
return m_inputDelegate;
|
return m_inputDelegate;
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,10 @@ class QtInputConnection extends BaseInputConnection
|
|||||||
Log.w(QtTAG, "HideKeyboardRunnable: The activity reference is null");
|
Log.w(QtTAG, "HideKeyboardRunnable: The activity reference is null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (m_qtInputConnectionListener == null) {
|
||||||
|
Log.w(QtTAG, "HideKeyboardRunnable: QtInputConnectionListener is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Rect r = new Rect();
|
Rect r = new Rect();
|
||||||
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
|
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
|
||||||
@ -109,7 +113,7 @@ class QtInputConnection extends BaseInputConnection
|
|||||||
{
|
{
|
||||||
if (closing)
|
if (closing)
|
||||||
m_view.postDelayed(new HideKeyboardRunnable(), 100);
|
m_view.postDelayed(new HideKeyboardRunnable(), 100);
|
||||||
else
|
else if (m_qtInputConnectionListener != null)
|
||||||
m_qtInputConnectionListener.onSetClosing(false);
|
m_qtInputConnectionListener.onSetClosing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +301,8 @@ class QtInputConnection extends BaseInputConnection
|
|||||||
restartImmInput();
|
restartImmInput();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_qtInputConnectionListener.onSendKeyEventDefaultCase();
|
if (m_qtInputConnectionListener != null)
|
||||||
|
m_qtInputConnectionListener.onSendKeyEventDefaultCase();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,8 @@ import android.view.inputmethod.InputMethodManager;
|
|||||||
import org.qtproject.qt.android.QtInputConnection.QtInputConnectionListener;
|
import org.qtproject.qt.android.QtInputConnection.QtInputConnectionListener;
|
||||||
|
|
||||||
/** @noinspection FieldCanBeLocal*/
|
/** @noinspection FieldCanBeLocal*/
|
||||||
class QtInputDelegate implements QtInputConnection.QtInputConnectionListener {
|
class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, QtInputInterface
|
||||||
|
{
|
||||||
|
|
||||||
// keyboard methods
|
// keyboard methods
|
||||||
public static native void keyDown(int key, int unicode, int modifier, boolean autoRepeat);
|
public static native void keyDown(int key, int unicode, int modifier, boolean autoRepeat);
|
||||||
@ -90,90 +91,20 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener {
|
|||||||
m_imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
m_imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// QtInputConnectionListener methods
|
// QtInputInterface implementation begin
|
||||||
@Override
|
@Override
|
||||||
public void onSetClosing(boolean closing) {
|
public void updateSelection(final int selStart, final int selEnd,
|
||||||
if (!closing)
|
final int candidatesStart, final int candidatesEnd)
|
||||||
setKeyboardVisibility(true, System.nanoTime());
|
{
|
||||||
|
QtNative.runAction(() -> {
|
||||||
|
if (m_imm == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_imm.updateSelection(m_currentEditText, selStart, selEnd, candidatesStart, candidatesEnd);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHideKeyboardRunnableDone(boolean visibility, long hideTimeStamp) {
|
|
||||||
setKeyboardVisibility(visibility, hideTimeStamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSendKeyEventDefaultCase() {
|
|
||||||
hideSoftwareKeyboard();
|
|
||||||
}
|
|
||||||
// QtInputConnectionListener methods
|
|
||||||
|
|
||||||
public boolean isKeyboardVisible()
|
|
||||||
{
|
|
||||||
return m_keyboardIsVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the keyboard fully visible i.e. visible and no ongoing animation
|
|
||||||
@UsedFromNativeCode
|
|
||||||
public boolean isSoftwareKeyboardVisible()
|
|
||||||
{
|
|
||||||
return isKeyboardVisible() && !m_isKeyboardHidingAnimationOngoing;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSoftInputMode(int inputMode)
|
|
||||||
{
|
|
||||||
m_softInputMode = inputMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
QtEditText getCurrentQtEditText()
|
|
||||||
{
|
|
||||||
return m_currentEditText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setEditPopupMenu(EditPopupMenu editPopupMenu)
|
|
||||||
{
|
|
||||||
m_editPopupMenu = editPopupMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void keyboardVisibilityUpdated(boolean visibility)
|
|
||||||
{
|
|
||||||
m_isKeyboardHidingAnimationOngoing = false;
|
|
||||||
QtInputDelegate.keyboardVisibilityChanged(visibility);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeyboardVisibility(boolean visibility, long timeStamp)
|
|
||||||
{
|
|
||||||
if (m_showHideTimeStamp > timeStamp)
|
|
||||||
return;
|
|
||||||
m_showHideTimeStamp = timeStamp;
|
|
||||||
|
|
||||||
if (m_keyboardIsVisible == visibility)
|
|
||||||
return;
|
|
||||||
m_keyboardIsVisible = visibility;
|
|
||||||
keyboardVisibilityUpdated(m_keyboardIsVisible);
|
|
||||||
|
|
||||||
// Hiding the keyboard clears the immersive mode, so we need to set it again.
|
|
||||||
if (!visibility)
|
|
||||||
m_keyboardVisibilityListener.onKeyboardVisibilityChange();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@UsedFromNativeCode
|
|
||||||
public void resetSoftwareKeyboard()
|
|
||||||
{
|
|
||||||
if (m_imm == null || m_currentEditText == null)
|
|
||||||
return;
|
|
||||||
m_currentEditText.postDelayed(() -> {
|
|
||||||
m_imm.restartInput(m_currentEditText);
|
|
||||||
m_currentEditText.m_optionsChanged = false;
|
|
||||||
}, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFocusedView(QtEditText currentEditText)
|
|
||||||
{
|
|
||||||
m_currentEditText = currentEditText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showSoftwareKeyboard(Activity activity, QtLayout layout,
|
public void showSoftwareKeyboard(Activity activity, QtLayout layout,
|
||||||
final int x, final int y, final int width, final int height,
|
final int x, final int y, final int width, final int height,
|
||||||
final int inputHints, final int enterKeyType)
|
final int inputHints, final int enterKeyType)
|
||||||
@ -217,6 +148,149 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSelectHandleWidth()
|
||||||
|
{
|
||||||
|
int width = 0;
|
||||||
|
if (m_leftSelectionHandle != null && m_rightSelectionHandle != null) {
|
||||||
|
width = Math.max(m_leftSelectionHandle.width(), m_rightSelectionHandle.width());
|
||||||
|
} else if (m_cursorHandle != null) {
|
||||||
|
width = m_cursorHandle.width();
|
||||||
|
}
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called from the C++ code when the position of the cursor or selection handles needs to
|
||||||
|
be adjusted.
|
||||||
|
mode is one of QAndroidInputContext::CursorHandleShowMode
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void updateHandles(Activity activity, QtLayout layout, int mode,
|
||||||
|
int editX, int editY, int editButtons,
|
||||||
|
int x1, int y1, int x2, int y2, boolean rtl)
|
||||||
|
{
|
||||||
|
QtNative.runAction(() -> updateHandleImpl(activity, layout, mode, editX, editY, editButtons,
|
||||||
|
x1, y1, x2, y2, rtl));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QtInputConnection.QtInputConnectionListener getInputConnectionListener()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetSoftwareKeyboard()
|
||||||
|
{
|
||||||
|
if (m_imm == null || m_currentEditText == null)
|
||||||
|
return;
|
||||||
|
m_currentEditText.postDelayed(() -> {
|
||||||
|
m_imm.restartInput(m_currentEditText);
|
||||||
|
m_currentEditText.m_optionsChanged = false;
|
||||||
|
}, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hideSoftwareKeyboard()
|
||||||
|
{
|
||||||
|
m_isKeyboardHidingAnimationOngoing = true;
|
||||||
|
QtNative.runAction(() -> {
|
||||||
|
if (m_imm == null || m_currentEditText == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_imm.hideSoftInputFromWindow(m_currentEditText.getWindowToken(), 0,
|
||||||
|
new ResultReceiver(new Handler()) {
|
||||||
|
@Override
|
||||||
|
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||||
|
switch (resultCode) {
|
||||||
|
case InputMethodManager.RESULT_SHOWN:
|
||||||
|
case InputMethodManager.RESULT_UNCHANGED_SHOWN:
|
||||||
|
setKeyboardVisibility(true, System.nanoTime());
|
||||||
|
break;
|
||||||
|
case InputMethodManager.RESULT_HIDDEN:
|
||||||
|
case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
|
||||||
|
setKeyboardVisibility(false, System.nanoTime());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the keyboard fully visible i.e. visible and no ongoing animation
|
||||||
|
@Override
|
||||||
|
public boolean isSoftwareKeyboardVisible()
|
||||||
|
{
|
||||||
|
return isKeyboardVisible() && !m_isKeyboardHidingAnimationOngoing;
|
||||||
|
}
|
||||||
|
// QtInputInterface implementation end
|
||||||
|
|
||||||
|
// QtInputConnectionListener methods
|
||||||
|
@Override
|
||||||
|
public void onSetClosing(boolean closing) {
|
||||||
|
if (!closing)
|
||||||
|
setKeyboardVisibility(true, System.nanoTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onHideKeyboardRunnableDone(boolean visibility, long hideTimeStamp) {
|
||||||
|
setKeyboardVisibility(visibility, hideTimeStamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSendKeyEventDefaultCase() {
|
||||||
|
hideSoftwareKeyboard();
|
||||||
|
}
|
||||||
|
// QtInputConnectionListener methods
|
||||||
|
|
||||||
|
public boolean isKeyboardVisible()
|
||||||
|
{
|
||||||
|
return m_keyboardIsVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSoftInputMode(int inputMode)
|
||||||
|
{
|
||||||
|
m_softInputMode = inputMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtEditText getCurrentQtEditText()
|
||||||
|
{
|
||||||
|
return m_currentEditText;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEditPopupMenu(EditPopupMenu editPopupMenu)
|
||||||
|
{
|
||||||
|
m_editPopupMenu = editPopupMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void keyboardVisibilityUpdated(boolean visibility)
|
||||||
|
{
|
||||||
|
m_isKeyboardHidingAnimationOngoing = false;
|
||||||
|
QtInputDelegate.keyboardVisibilityChanged(visibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyboardVisibility(boolean visibility, long timeStamp)
|
||||||
|
{
|
||||||
|
if (m_showHideTimeStamp > timeStamp)
|
||||||
|
return;
|
||||||
|
m_showHideTimeStamp = timeStamp;
|
||||||
|
|
||||||
|
if (m_keyboardIsVisible == visibility)
|
||||||
|
return;
|
||||||
|
m_keyboardIsVisible = visibility;
|
||||||
|
keyboardVisibilityUpdated(m_keyboardIsVisible);
|
||||||
|
|
||||||
|
// Hiding the keyboard clears the immersive mode, so we need to set it again.
|
||||||
|
if (!visibility)
|
||||||
|
m_keyboardVisibilityListener.onKeyboardVisibilityChange();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFocusedView(QtEditText currentEditText)
|
||||||
|
{
|
||||||
|
m_currentEditText = currentEditText;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean updateSoftInputMode(Activity activity, int height)
|
private boolean updateSoftInputMode(Activity activity, int height)
|
||||||
{
|
{
|
||||||
DisplayMetrics metrics = new DisplayMetrics();
|
DisplayMetrics metrics = new DisplayMetrics();
|
||||||
@ -284,69 +358,6 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener {
|
|||||||
}, m_probeKeyboardHeightDelayMs);
|
}, m_probeKeyboardHeightDelayMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideSoftwareKeyboard()
|
|
||||||
{
|
|
||||||
m_isKeyboardHidingAnimationOngoing = true;
|
|
||||||
QtNative.runAction(() -> {
|
|
||||||
if (m_imm == null || m_currentEditText == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_imm.hideSoftInputFromWindow(m_currentEditText.getWindowToken(), 0,
|
|
||||||
new ResultReceiver(new Handler()) {
|
|
||||||
@Override
|
|
||||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
|
||||||
switch (resultCode) {
|
|
||||||
case InputMethodManager.RESULT_SHOWN:
|
|
||||||
case InputMethodManager.RESULT_UNCHANGED_SHOWN:
|
|
||||||
setKeyboardVisibility(true, System.nanoTime());
|
|
||||||
break;
|
|
||||||
case InputMethodManager.RESULT_HIDDEN:
|
|
||||||
case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
|
|
||||||
setKeyboardVisibility(false, System.nanoTime());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@UsedFromNativeCode
|
|
||||||
public void updateSelection(final int selStart, final int selEnd,
|
|
||||||
final int candidatesStart, final int candidatesEnd)
|
|
||||||
{
|
|
||||||
QtNative.runAction(() -> {
|
|
||||||
if (m_imm == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_imm.updateSelection(m_currentEditText, selStart, selEnd, candidatesStart, candidatesEnd);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@UsedFromNativeCode
|
|
||||||
public int getSelectHandleWidth()
|
|
||||||
{
|
|
||||||
int width = 0;
|
|
||||||
if (m_leftSelectionHandle != null && m_rightSelectionHandle != null) {
|
|
||||||
width = Math.max(m_leftSelectionHandle.width(), m_rightSelectionHandle.width());
|
|
||||||
} else if (m_cursorHandle != null) {
|
|
||||||
width = m_cursorHandle.width();
|
|
||||||
}
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* called from the C++ code when the position of the cursor or selection handles needs to
|
|
||||||
be adjusted.
|
|
||||||
mode is one of QAndroidInputContext::CursorHandleShowMode
|
|
||||||
*/
|
|
||||||
@UsedFromNativeCode
|
|
||||||
public void updateHandles(Activity activity, QtLayout layout, int mode,
|
|
||||||
int editX, int editY, int editButtons,
|
|
||||||
int x1, int y1, int x2, int y2, boolean rtl)
|
|
||||||
{
|
|
||||||
QtNative.runAction(() -> updateHandleImpl(activity, layout, mode, editX, editY, editButtons,
|
|
||||||
x1, y1, x2, y2, rtl));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateHandleImpl(Activity activity, QtLayout layout, int mode,
|
private void updateHandleImpl(Activity activity, QtLayout layout, int mode,
|
||||||
int editX, int editY, int editButtons,
|
int editX, int editY, int editButtons,
|
||||||
int x1, int y1, int x2, int y2, boolean rtl)
|
int x1, int y1, int x2, int y2, boolean rtl)
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||||
|
package org.qtproject.qt.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
@UsedFromNativeCode
|
||||||
|
interface QtInputInterface {
|
||||||
|
void updateSelection(final int selStart, final int selEnd, final int candidatesStart,
|
||||||
|
final int candidatesEnd);
|
||||||
|
void showSoftwareKeyboard(Activity activity, QtLayout layout, final int x, final int y,
|
||||||
|
final int width, final int height, final int inputHints,
|
||||||
|
final int enterKeyType);
|
||||||
|
void resetSoftwareKeyboard();
|
||||||
|
void hideSoftwareKeyboard();
|
||||||
|
boolean isSoftwareKeyboardVisible();
|
||||||
|
int getSelectHandleWidth();
|
||||||
|
void updateHandles(Activity activity, QtLayout layout, int mode, int editX, int editY,
|
||||||
|
int editButtons, int x1, int y1, int x2, int y2, boolean rtl);
|
||||||
|
QtInputConnection.QtInputConnectionListener getInputConnectionListener();
|
||||||
|
}
|
@ -29,13 +29,7 @@ class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.App
|
|||||||
QtNative.registerAppStateListener(this);
|
QtNative.registerAppStateListener(this);
|
||||||
QtNative.setService(service);
|
QtNative.setService(service);
|
||||||
// QTBUG-122920 TODO Implement accessibility for service UIs
|
// QTBUG-122920 TODO Implement accessibility for service UIs
|
||||||
}
|
// QTBUG-122552 TODO Implement text input
|
||||||
|
|
||||||
@UsedFromNativeCode
|
|
||||||
QtInputDelegate getInputDelegate()
|
|
||||||
{
|
|
||||||
// TODO Implement text input (QTBUG-122552)
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,11 +26,12 @@ class QtWindow extends QtLayout implements QtSurfaceInterface {
|
|||||||
private static native void setSurface(int windowId, Surface surface);
|
private static native void setSurface(int windowId, Surface surface);
|
||||||
static native void windowFocusChanged(boolean hasFocus, int id);
|
static native void windowFocusChanged(boolean hasFocus, int id);
|
||||||
|
|
||||||
public QtWindow(Context context, QtWindow parentWindow, QtInputDelegate delegate)
|
public QtWindow(Context context, QtWindow parentWindow,
|
||||||
|
QtInputConnection.QtInputConnectionListener listener)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
setId(View.generateViewId());
|
setId(View.generateViewId());
|
||||||
m_editText = new QtEditText(context, delegate);
|
m_editText = new QtEditText(context, listener);
|
||||||
setParent(parentWindow);
|
setParent(parentWindow);
|
||||||
setFocusableInTouchMode(true);
|
setFocusableInTouchMode(true);
|
||||||
addView(m_editText, new QtLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
addView(m_editText, new QtLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
@ -25,6 +25,7 @@ using namespace QtAndroid;
|
|||||||
|
|
||||||
Q_DECLARE_JNI_CLASS(QtLayout, "org/qtproject/qt/android/QtLayout")
|
Q_DECLARE_JNI_CLASS(QtLayout, "org/qtproject/qt/android/QtLayout")
|
||||||
Q_DECLARE_JNI_CLASS(QtLayoutInterface, "org/qtproject/qt/android/QtLayoutInterface")
|
Q_DECLARE_JNI_CLASS(QtLayoutInterface, "org/qtproject/qt/android/QtLayoutInterface")
|
||||||
|
Q_DECLARE_JNI_CLASS(QtInputInterface, "org/qtproject/qt/android/QtInputInterface")
|
||||||
|
|
||||||
namespace QtAndroidInput
|
namespace QtAndroidInput
|
||||||
{
|
{
|
||||||
@ -107,42 +108,40 @@ namespace QtAndroidInput
|
|||||||
void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
|
void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
|
||||||
{
|
{
|
||||||
qCDebug(lcQpaInputMethods) << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
|
qCDebug(lcQpaInputMethods) << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
|
||||||
qtInputDelegate().callMethod<void>("updateSelection",
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
selStart,
|
reg->callInterface<QtJniTypes::QtInputInterface, void>("updateSelection", selStart, selEnd,
|
||||||
selEnd,
|
candidatesStart, candidatesEnd);
|
||||||
candidatesStart,
|
|
||||||
candidatesEnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
|
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
|
||||||
{
|
{
|
||||||
qtInputDelegate().callMethod<void>("showSoftwareKeyboard",
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
QtAndroidPrivate::activity(),
|
reg->callInterface<QtJniTypes::QtInputInterface, void>(
|
||||||
qtLayout().object<QtJniTypes::QtLayout>(),
|
"showSoftwareKeyboard", QtAndroidPrivate::activity(),
|
||||||
left,
|
qtLayout().object<QtJniTypes::QtLayout>(), left, top, width, height, inputHints,
|
||||||
top,
|
enterKeyType);
|
||||||
width,
|
|
||||||
height,
|
|
||||||
inputHints,
|
|
||||||
enterKeyType);
|
|
||||||
qCDebug(lcQpaInputMethods) << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints << enterKeyType;
|
qCDebug(lcQpaInputMethods) << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints << enterKeyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetSoftwareKeyboard()
|
void resetSoftwareKeyboard()
|
||||||
{
|
{
|
||||||
qtInputDelegate().callMethod<void>("resetSoftwareKeyboard");
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
|
reg->callInterface<QtJniTypes::QtInputInterface, void>("resetSoftwareKeyboard");
|
||||||
qCDebug(lcQpaInputMethods) << "@@@ RESETSOFTWAREKEYBOARD";
|
qCDebug(lcQpaInputMethods) << "@@@ RESETSOFTWAREKEYBOARD";
|
||||||
}
|
}
|
||||||
|
|
||||||
void hideSoftwareKeyboard()
|
void hideSoftwareKeyboard()
|
||||||
{
|
{
|
||||||
qtInputDelegate().callMethod<void>("hideSoftwareKeyboard");
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
|
reg->callInterface<QtJniTypes::QtInputInterface, void>("hideSoftwareKeyboard");
|
||||||
qCDebug(lcQpaInputMethods) << "@@@ HIDESOFTWAREKEYBOARD";
|
qCDebug(lcQpaInputMethods) << "@@@ HIDESOFTWAREKEYBOARD";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSoftwareKeyboardVisible()
|
bool isSoftwareKeyboardVisible()
|
||||||
{
|
{
|
||||||
return qtInputDelegate().callMethod<jboolean>("isSoftwareKeyboardVisible");
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
|
return reg->callInterface<QtJniTypes::QtInputInterface, jboolean>(
|
||||||
|
"isSoftwareKeyboardVisible");
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect softwareKeyboardRect()
|
QRect softwareKeyboardRect()
|
||||||
@ -152,17 +151,17 @@ namespace QtAndroidInput
|
|||||||
|
|
||||||
int getSelectHandleWidth()
|
int getSelectHandleWidth()
|
||||||
{
|
{
|
||||||
return qtInputDelegate().callMethod<jint>("getSelectHandleWidth");
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
|
return reg->callInterface<QtJniTypes::QtInputInterface, jint>("getSelectHandleWidth");
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
|
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
|
||||||
{
|
{
|
||||||
qtInputDelegate().callMethod<void>("updateHandles",
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
QtAndroidPrivate::activity(),
|
reg->callInterface<QtJniTypes::QtInputInterface, void>(
|
||||||
qtLayout().object<QtJniTypes::QtLayout>(),
|
"updateHandles", QtAndroidPrivate::activity(),
|
||||||
mode, editMenuPos.x(), editMenuPos.y(), editButtons,
|
qtLayout().object<QtJniTypes::QtLayout>(), mode, editMenuPos.x(), editMenuPos.y(),
|
||||||
cursor.x(), cursor.y(),
|
editButtons, cursor.x(), cursor.y(), anchor.x(), anchor.y(), rtl);
|
||||||
anchor.x(), anchor.y(), rtl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// from https://developer.android.com/reference/android/view/MotionEvent#getButtonState()
|
// from https://developer.android.com/reference/android/view/MotionEvent#getButtonState()
|
||||||
|
@ -55,7 +55,6 @@ static jclass m_qtActivityClass = nullptr;
|
|||||||
static jclass m_qtServiceClass = nullptr;
|
static jclass m_qtServiceClass = nullptr;
|
||||||
|
|
||||||
static QtJniTypes::QtActivityDelegateBase m_activityDelegate = nullptr;
|
static QtJniTypes::QtActivityDelegateBase m_activityDelegate = nullptr;
|
||||||
static QtJniTypes::QtInputDelegate m_inputDelegate = nullptr;
|
|
||||||
|
|
||||||
static int m_pendingApplicationState = -1;
|
static int m_pendingApplicationState = -1;
|
||||||
static QBasicMutex m_platformMutex;
|
static QBasicMutex m_platformMutex;
|
||||||
@ -210,16 +209,6 @@ namespace QtAndroid
|
|||||||
return m_activityDelegate;
|
return m_activityDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
QtJniTypes::QtInputDelegate qtInputDelegate()
|
|
||||||
{
|
|
||||||
if (!m_inputDelegate.isValid()) {
|
|
||||||
m_inputDelegate = qtActivityDelegate().callMethod<QtJniTypes::QtInputDelegate>(
|
|
||||||
"getInputDelegate");
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_inputDelegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isQtApplication()
|
bool isQtApplication()
|
||||||
{
|
{
|
||||||
// Returns true if the app is a Qt app, i.e. Qt controls the whole app and
|
// Returns true if the app is a Qt app, i.e. Qt controls the whole app and
|
||||||
|
@ -51,7 +51,6 @@ namespace QtAndroid
|
|||||||
jclass applicationClass();
|
jclass applicationClass();
|
||||||
|
|
||||||
QtJniTypes::QtActivityDelegateBase qtActivityDelegate();
|
QtJniTypes::QtActivityDelegateBase qtActivityDelegate();
|
||||||
QtJniTypes::QtInputDelegate qtInputDelegate();
|
|
||||||
|
|
||||||
// Keep synchronized with flags in ActivityDelegate.java
|
// Keep synchronized with flags in ActivityDelegate.java
|
||||||
enum SystemUiVisibility {
|
enum SystemUiVisibility {
|
||||||
|
@ -16,6 +16,10 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window")
|
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window")
|
||||||
|
|
||||||
|
Q_DECLARE_JNI_CLASS(QtInputInterface, "org/qtproject/qt/android/QtInputInterface")
|
||||||
|
Q_DECLARE_JNI_CLASS(QtInputConnectionListener,
|
||||||
|
"org/qtproject/qt/android/QtInputConnection$QtInputConnectionListener")
|
||||||
|
|
||||||
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
|
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
|
||||||
: QPlatformWindow(window), m_nativeQtWindow(nullptr),
|
: QPlatformWindow(window), m_nativeQtWindow(nullptr),
|
||||||
m_surfaceContainerType(SurfaceContainer::TextureView), m_nativeParentQtWindow(nullptr),
|
m_surfaceContainerType(SurfaceContainer::TextureView), m_nativeParentQtWindow(nullptr),
|
||||||
@ -55,10 +59,13 @@ QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
|
|||||||
m_nativeParentQtWindow = androidParent->nativeWindow();
|
m_nativeParentQtWindow = androidParent->nativeWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
|
QtJniTypes::QtInputConnectionListener listener =
|
||||||
|
reg->callInterface<QtJniTypes::QtInputInterface, QtJniTypes::QtInputConnectionListener>(
|
||||||
|
"getInputConnectionListener");
|
||||||
|
|
||||||
m_nativeQtWindow = QJniObject::construct<QtJniTypes::QtWindow>(
|
m_nativeQtWindow = QJniObject::construct<QtJniTypes::QtWindow>(
|
||||||
QNativeInterface::QAndroidApplication::context(),
|
QNativeInterface::QAndroidApplication::context(), m_nativeParentQtWindow, listener);
|
||||||
m_nativeParentQtWindow,
|
|
||||||
QtAndroid::qtInputDelegate());
|
|
||||||
m_nativeViewId = m_nativeQtWindow.callMethod<jint>("getId");
|
m_nativeViewId = m_nativeQtWindow.callMethod<jint>("getId");
|
||||||
|
|
||||||
if (window->isTopLevel())
|
if (window->isTopLevel())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user