Android: don't call delegates outside of the Activity
The delegate classes shouldn't be used outside of the Activity/Service classes, since they're practically private implementation, so don't use them anywhere outside Activity/Service. Since Qt Android apps still mainly support having one QtActivity/ QtService, QtNative heavily uses those objects to do various operations. For that reason, we still need to use the delegate there. The aim is to change that in future patches and do the operations where they make more sense for example directly under QtActivityBase/QtActivityDelegate or Service counterpart. The QtServiceDelegate is used no where and have no special implementation, so it's removed here. Task-number: QTBUG-118077 Change-Id: I5e106318169be19fec8163e8e500ee573af0e1bc Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
19baa077d9
commit
f5e2302851
@ -12,7 +12,6 @@ set(java_sources
|
||||
src/org/qtproject/qt/android/QtActivityBase.java
|
||||
src/org/qtproject/qt/android/QtServiceBase.java
|
||||
src/org/qtproject/qt/android/QtActivityDelegate.java
|
||||
src/org/qtproject/qt/android/QtServiceDelegate.java
|
||||
src/org/qtproject/qt/android/QtInputDelegate.java
|
||||
src/org/qtproject/qt/android/QtLoader.java
|
||||
src/org/qtproject/qt/android/QtActivityLoader.java
|
||||
|
@ -173,7 +173,7 @@ public class QtActivityBase extends Activity
|
||||
super.onDestroy();
|
||||
if (m_delegate.isQuitApp()) {
|
||||
QtNative.terminateQt();
|
||||
QtNative.setActivity(null, null);
|
||||
QtNative.setActivity(null);
|
||||
QtNative.m_qtThread.exit();
|
||||
System.exit(0);
|
||||
}
|
||||
@ -325,6 +325,11 @@ public class QtActivityBase extends Activity
|
||||
QtNative.sendRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
public void hideSplashScreen(final int duration)
|
||||
{
|
||||
m_delegate.hideSplashScreen(duration);
|
||||
}
|
||||
|
||||
QtActivityDelegate getActivityDelegate()
|
||||
{
|
||||
return m_delegate;
|
||||
|
@ -6,7 +6,6 @@
|
||||
package org.qtproject.qt.android;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
@ -27,7 +26,6 @@ import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowInsetsController;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
@ -56,34 +54,36 @@ public class QtActivityDelegate
|
||||
private QtAccessibilityDelegate m_accessibilityDelegate = null;
|
||||
private final QtDisplayManager m_displayManager = new QtDisplayManager();
|
||||
|
||||
private QtInputDelegate.KeyboardVisibilityListener m_keyboardVisibilityListener =
|
||||
new QtInputDelegate.KeyboardVisibilityListener() {
|
||||
@Override
|
||||
public void onKeyboardVisibilityChange() {
|
||||
m_displayManager.updateFullScreen(m_activity);
|
||||
}
|
||||
};
|
||||
private final QtInputDelegate m_inputDelegate = new QtInputDelegate(m_keyboardVisibilityListener);
|
||||
private QtInputDelegate m_inputDelegate = null;
|
||||
|
||||
QtActivityDelegate(Activity activity)
|
||||
{
|
||||
m_activity = activity;
|
||||
QtNative.setActivity(m_activity, this);
|
||||
QtNative.setActivity(m_activity);
|
||||
|
||||
setActionBarVisibility(false);
|
||||
|
||||
m_displayManager.registerDisplayListener(m_activity, m_layout);
|
||||
|
||||
QtInputDelegate.KeyboardVisibilityListener keyboardVisibilityListener =
|
||||
new QtInputDelegate.KeyboardVisibilityListener() {
|
||||
@Override
|
||||
public void onKeyboardVisibilityChange() {
|
||||
m_displayManager.updateFullScreen(m_activity);
|
||||
}
|
||||
};
|
||||
m_inputDelegate = new QtInputDelegate(m_activity, keyboardVisibilityListener);
|
||||
|
||||
try {
|
||||
m_inputDelegate.setSoftInputMode(m_activity.getPackageManager()
|
||||
.getActivityInfo(m_activity.getComponentName(), 0).softInputMode);
|
||||
PackageManager pm = m_activity.getPackageManager();
|
||||
ActivityInfo activityInfo = pm.getActivityInfo(m_activity.getComponentName(), 0);
|
||||
m_inputDelegate.setSoftInputMode(activityInfo.softInputMode);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
m_displayManager.registerDisplayListener(m_activity, m_layout);
|
||||
}
|
||||
|
||||
QtDisplayManager displayManager()
|
||||
{
|
||||
QtDisplayManager displayManager() {
|
||||
return m_displayManager;
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ public class QtActivityDelegate
|
||||
try {
|
||||
// set new activity
|
||||
m_activity = activity;
|
||||
QtNative.setActivity(m_activity, this);
|
||||
QtNative.setActivity(m_activity);
|
||||
|
||||
// update the new activity content view to old layout
|
||||
ViewGroup layoutParent = (ViewGroup) m_layout.getParent();
|
||||
@ -220,8 +220,6 @@ public class QtActivityDelegate
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
m_inputDelegate.setEditText(new QtEditText(m_activity));
|
||||
m_inputDelegate.setInputMethodManager((InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE));
|
||||
m_surfaces = new HashMap<Integer, QtSurface>();
|
||||
m_nativeViews = new HashMap<Integer, View>();
|
||||
m_activity.registerForContextMenu(m_layout);
|
||||
@ -273,31 +271,40 @@ public class QtActivityDelegate
|
||||
|
||||
public void hideSplashScreen(final int duration)
|
||||
{
|
||||
if (m_splashScreen == null)
|
||||
return;
|
||||
|
||||
if (duration <= 0) {
|
||||
m_layout.removeView(m_splashScreen);
|
||||
m_splashScreen = null;
|
||||
return;
|
||||
}
|
||||
|
||||
final Animation fadeOut = new AlphaAnimation(1, 0);
|
||||
fadeOut.setInterpolator(new AccelerateInterpolator());
|
||||
fadeOut.setDuration(duration);
|
||||
|
||||
fadeOut.setAnimationListener(new Animation.AnimationListener() {
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) { hideSplashScreen(0); }
|
||||
public void run() {
|
||||
if (m_splashScreen == null)
|
||||
return;
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animation animation) {}
|
||||
if (duration <= 0) {
|
||||
m_layout.removeView(m_splashScreen);
|
||||
m_splashScreen = null;
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animation animation) {}
|
||||
final Animation fadeOut = new AlphaAnimation(1, 0);
|
||||
fadeOut.setInterpolator(new AccelerateInterpolator());
|
||||
fadeOut.setDuration(duration);
|
||||
|
||||
fadeOut.setAnimationListener(new Animation.AnimationListener() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
hideSplashScreen(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animation animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animation animation) {
|
||||
}
|
||||
});
|
||||
|
||||
m_splashScreen.startAnimation(fadeOut);
|
||||
}
|
||||
});
|
||||
|
||||
m_splashScreen.startAnimation(fadeOut);
|
||||
}
|
||||
|
||||
public void notifyLocationChange(int viewId)
|
||||
@ -381,7 +388,22 @@ public class QtActivityDelegate
|
||||
|
||||
public void resetOptionsMenu()
|
||||
{
|
||||
m_activity.invalidateOptionsMenu();
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
m_activity.invalidateOptionsMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void openOptionsMenu()
|
||||
{
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
m_activity.openOptionsMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean m_contextMenuVisible = false;
|
||||
@ -395,31 +417,36 @@ public class QtActivityDelegate
|
||||
public void openContextMenu(final int x, final int y, final int w, final int h)
|
||||
{
|
||||
m_layout.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
m_layout.setLayoutParams(m_inputDelegate.getQtEditText(), new QtLayout.LayoutParams(w, h, x, y), false);
|
||||
PopupMenu popup = new PopupMenu(m_activity, m_inputDelegate.getQtEditText());
|
||||
QtActivityDelegate.this.onCreatePopupMenu(popup.getMenu());
|
||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem menuItem) {
|
||||
return m_activity.onContextItemSelected(menuItem);
|
||||
}
|
||||
});
|
||||
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(PopupMenu popupMenu) {
|
||||
m_activity.onContextMenuClosed(popupMenu.getMenu());
|
||||
}
|
||||
});
|
||||
popup.show();
|
||||
}
|
||||
}, 100);
|
||||
@Override
|
||||
public void run() {
|
||||
m_layout.setLayoutParams(m_inputDelegate.getQtEditText(), new QtLayout.LayoutParams(w, h, x, y), false);
|
||||
PopupMenu popup = new PopupMenu(m_activity, m_inputDelegate.getQtEditText());
|
||||
QtActivityDelegate.this.onCreatePopupMenu(popup.getMenu());
|
||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem menuItem) {
|
||||
return m_activity.onContextItemSelected(menuItem);
|
||||
}
|
||||
});
|
||||
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(PopupMenu popupMenu) {
|
||||
m_activity.onContextMenuClosed(popupMenu.getMenu());
|
||||
}
|
||||
});
|
||||
popup.show();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
public void closeContextMenu()
|
||||
{
|
||||
m_activity.closeContextMenu();
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
m_activity.closeContextMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void setActionBarVisibility(boolean visible)
|
||||
@ -433,96 +460,116 @@ public class QtActivityDelegate
|
||||
}
|
||||
|
||||
public void insertNativeView(int id, View view, int x, int y, int w, int h) {
|
||||
if (m_dummyView != null) {
|
||||
m_layout.removeView(m_dummyView);
|
||||
m_dummyView = null;
|
||||
}
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_dummyView != null) {
|
||||
m_layout.removeView(m_dummyView);
|
||||
m_dummyView = null;
|
||||
}
|
||||
|
||||
if (m_nativeViews.containsKey(id))
|
||||
m_layout.removeView(m_nativeViews.remove(id));
|
||||
if (m_nativeViews.containsKey(id))
|
||||
m_layout.removeView(m_nativeViews.remove(id));
|
||||
|
||||
if (w < 0 || h < 0) {
|
||||
view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
} else {
|
||||
view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
|
||||
}
|
||||
if (w < 0 || h < 0) {
|
||||
view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
} else {
|
||||
view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
|
||||
}
|
||||
|
||||
view.setId(id);
|
||||
m_layout.addView(view);
|
||||
m_nativeViews.put(id, view);
|
||||
view.setId(id);
|
||||
m_layout.addView(view);
|
||||
m_nativeViews.put(id, view);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void createSurface(int id, boolean onTop, int x, int y, int w, int h, int imageDepth) {
|
||||
if (m_surfaces.size() == 0) {
|
||||
TypedValue attr = new TypedValue();
|
||||
m_activity.getTheme().resolveAttribute(android.R.attr.windowBackground, attr, true);
|
||||
if (attr.type >= TypedValue.TYPE_FIRST_COLOR_INT && attr.type <= TypedValue.TYPE_LAST_COLOR_INT) {
|
||||
m_activity.getWindow().setBackgroundDrawable(new ColorDrawable(attr.data));
|
||||
} else {
|
||||
m_activity.getWindow().setBackgroundDrawable(m_activity.getResources().getDrawable(attr.resourceId, m_activity.getTheme()));
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_surfaces.size() == 0) {
|
||||
TypedValue attr = new TypedValue();
|
||||
m_activity.getTheme().resolveAttribute(android.R.attr.windowBackground, attr, true);
|
||||
if (attr.type >= TypedValue.TYPE_FIRST_COLOR_INT && attr.type <= TypedValue.TYPE_LAST_COLOR_INT) {
|
||||
m_activity.getWindow().setBackgroundDrawable(new ColorDrawable(attr.data));
|
||||
} else {
|
||||
m_activity.getWindow().setBackgroundDrawable(m_activity.getResources().getDrawable(attr.resourceId, m_activity.getTheme()));
|
||||
}
|
||||
if (m_dummyView != null) {
|
||||
m_layout.removeView(m_dummyView);
|
||||
m_dummyView = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_surfaces.containsKey(id))
|
||||
m_layout.removeView(m_surfaces.remove(id));
|
||||
|
||||
QtSurface surface = new QtSurface(m_activity, id, onTop, imageDepth);
|
||||
if (w < 0 || h < 0) {
|
||||
surface.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
} else {
|
||||
surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
|
||||
}
|
||||
|
||||
// Native views are always inserted in the end of the stack (i.e., on top).
|
||||
// All other views are stacked based on the order they are created.
|
||||
final int surfaceCount = getSurfaceCount();
|
||||
m_layout.addView(surface, surfaceCount);
|
||||
|
||||
m_surfaces.put(id, surface);
|
||||
if (!m_splashScreenSticky)
|
||||
hideSplashScreen();
|
||||
}
|
||||
if (m_dummyView != null) {
|
||||
m_layout.removeView(m_dummyView);
|
||||
m_dummyView = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_surfaces.containsKey(id))
|
||||
m_layout.removeView(m_surfaces.remove(id));
|
||||
|
||||
QtSurface surface = new QtSurface(m_activity, id, onTop, imageDepth);
|
||||
if (w < 0 || h < 0) {
|
||||
surface.setLayoutParams( new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
} else {
|
||||
surface.setLayoutParams( new QtLayout.LayoutParams(w, h, x, y));
|
||||
}
|
||||
|
||||
// Native views are always inserted in the end of the stack (i.e., on top).
|
||||
// All other views are stacked based on the order they are created.
|
||||
final int surfaceCount = getSurfaceCount();
|
||||
m_layout.addView(surface, surfaceCount);
|
||||
|
||||
m_surfaces.put(id, surface);
|
||||
if (!m_splashScreenSticky)
|
||||
hideSplashScreen();
|
||||
});
|
||||
}
|
||||
|
||||
public void setSurfaceGeometry(int id, int x, int y, int w, int h) {
|
||||
if (m_surfaces.containsKey(id)) {
|
||||
QtSurface surface = m_surfaces.get(id);
|
||||
surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
|
||||
} else if (m_nativeViews.containsKey(id)) {
|
||||
View view = m_nativeViews.get(id);
|
||||
view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
|
||||
} else {
|
||||
Log.e(QtNative.QtTAG, "Surface " + id +" not found!");
|
||||
return;
|
||||
}
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_surfaces.containsKey(id)) {
|
||||
QtSurface surface = m_surfaces.get(id);
|
||||
surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
|
||||
} else if (m_nativeViews.containsKey(id)) {
|
||||
View view = m_nativeViews.get(id);
|
||||
view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
|
||||
} else {
|
||||
Log.e(QtNative.QtTAG, "Surface " + id + " not found!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void destroySurface(int id) {
|
||||
View view = null;
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
View view = null;
|
||||
|
||||
if (m_surfaces.containsKey(id)) {
|
||||
view = m_surfaces.remove(id);
|
||||
} else if (m_nativeViews.containsKey(id)) {
|
||||
view = m_nativeViews.remove(id);
|
||||
} else {
|
||||
Log.e(QtNative.QtTAG, "Surface " + id +" not found!");
|
||||
}
|
||||
if (m_surfaces.containsKey(id)) {
|
||||
view = m_surfaces.remove(id);
|
||||
} else if (m_nativeViews.containsKey(id)) {
|
||||
view = m_nativeViews.remove(id);
|
||||
} else {
|
||||
Log.e(QtNative.QtTAG, "Surface " + id + " not found!");
|
||||
}
|
||||
|
||||
if (view == null)
|
||||
return;
|
||||
if (view == null)
|
||||
return;
|
||||
|
||||
// Keep last frame in stack until it is replaced to get correct
|
||||
// shutdown transition
|
||||
if (m_surfaces.size() == 0 && m_nativeViews.size() == 0) {
|
||||
m_dummyView = view;
|
||||
} else {
|
||||
m_layout.removeView(view);
|
||||
}
|
||||
// Keep last frame in stack until it is replaced to get correct
|
||||
// shutdown transition
|
||||
if (m_surfaces.size() == 0 && m_nativeViews.size() == 0) {
|
||||
m_dummyView = view;
|
||||
} else {
|
||||
m_layout.removeView(view);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getSurfaceCount()
|
||||
@ -532,31 +579,41 @@ public class QtActivityDelegate
|
||||
|
||||
public void bringChildToFront(int id)
|
||||
{
|
||||
View view = m_surfaces.get(id);
|
||||
if (view != null) {
|
||||
final int surfaceCount = getSurfaceCount();
|
||||
if (surfaceCount > 0)
|
||||
m_layout.moveChild(view, surfaceCount - 1);
|
||||
return;
|
||||
}
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
View view = m_surfaces.get(id);
|
||||
if (view != null) {
|
||||
final int surfaceCount = getSurfaceCount();
|
||||
if (surfaceCount > 0)
|
||||
m_layout.moveChild(view, surfaceCount - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
view = m_nativeViews.get(id);
|
||||
if (view != null)
|
||||
m_layout.moveChild(view, -1);
|
||||
view = m_nativeViews.get(id);
|
||||
if (view != null)
|
||||
m_layout.moveChild(view, -1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void bringChildToBack(int id)
|
||||
{
|
||||
View view = m_surfaces.get(id);
|
||||
if (view != null) {
|
||||
m_layout.moveChild(view, 0);
|
||||
return;
|
||||
}
|
||||
QtNative.runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
View view = m_surfaces.get(id);
|
||||
if (view != null) {
|
||||
m_layout.moveChild(view, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
view = m_nativeViews.get(id);
|
||||
if (view != null) {
|
||||
final int index = getSurfaceCount();
|
||||
m_layout.moveChild(view, index);
|
||||
}
|
||||
view = m_nativeViews.get(id);
|
||||
if (view != null) {
|
||||
final int index = getSurfaceCount();
|
||||
m_layout.moveChild(view, index);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
|
||||
import org.qtproject.qt.android.QtInputConnection.QtInputConnectionListener;
|
||||
|
||||
public class QtEditText extends View
|
||||
{
|
||||
int m_initialCapsMode = 0;
|
||||
@ -17,6 +19,13 @@ public class QtEditText extends View
|
||||
int m_inputType = InputType.TYPE_CLASS_TEXT;
|
||||
boolean m_optionsChanged = false;
|
||||
|
||||
private QtInputConnectionListener m_qtInputConnectionListener;
|
||||
|
||||
public void setQtInputConnectionListener(QtInputConnectionListener listener)
|
||||
{
|
||||
m_qtInputConnectionListener = listener;
|
||||
}
|
||||
|
||||
public void setImeOptions(int m_imeOptions)
|
||||
{
|
||||
if (m_imeOptions == this.m_imeOptions)
|
||||
@ -56,7 +65,7 @@ public class QtEditText extends View
|
||||
outAttrs.imeOptions = m_imeOptions;
|
||||
outAttrs.initialCapsMode = m_initialCapsMode;
|
||||
outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI;
|
||||
return new QtInputConnection(this);
|
||||
return new QtInputConnection(this, m_qtInputConnectionListener);
|
||||
}
|
||||
|
||||
// // DEBUG CODE
|
||||
|
@ -51,31 +51,6 @@ class QtNativeInputConnection
|
||||
static native boolean updateCursorPosition();
|
||||
}
|
||||
|
||||
class HideKeyboardRunnable implements Runnable {
|
||||
private long m_hideTimeStamp = System.nanoTime();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Check that the keyboard is really no longer there.
|
||||
Activity activity = QtNative.activity();
|
||||
Rect r = new Rect();
|
||||
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
|
||||
|
||||
int screenHeight = 0;
|
||||
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
screenHeight = metrics.heightPixels;
|
||||
} else {
|
||||
final WindowMetrics maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics();
|
||||
screenHeight = maximumWindowMetrics.getBounds().height();
|
||||
}
|
||||
final int kbHeight = screenHeight - r.bottom;
|
||||
if (kbHeight < 100)
|
||||
QtNative.activityDelegate().getInputDelegate().setKeyboardVisibility(false, m_hideTimeStamp);
|
||||
}
|
||||
}
|
||||
|
||||
public class QtInputConnection extends BaseInputConnection
|
||||
{
|
||||
private static final int ID_SELECT_ALL = android.R.id.selectAll;
|
||||
@ -86,21 +61,52 @@ public class QtInputConnection extends BaseInputConnection
|
||||
private static final int ID_SWITCH_INPUT_METHOD = android.R.id.switchInputMethod;
|
||||
private static final int ID_ADD_TO_DICTIONARY = android.R.id.addToDictionary;
|
||||
|
||||
private final QtInputConnectionListener m_qtInputConnectionListener;
|
||||
|
||||
class HideKeyboardRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
// Check that the keyboard is really no longer there.
|
||||
Activity activity = QtNative.activity();
|
||||
Rect r = new Rect();
|
||||
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
|
||||
|
||||
int screenHeight = 0;
|
||||
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
screenHeight = metrics.heightPixels;
|
||||
} else {
|
||||
final WindowMetrics maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics();
|
||||
screenHeight = maximumWindowMetrics.getBounds().height();
|
||||
}
|
||||
final int kbHeight = screenHeight - r.bottom;
|
||||
if (kbHeight < 100)
|
||||
m_qtInputConnectionListener.onHideKeyboardRunnableDone(false, System.nanoTime());
|
||||
}
|
||||
}
|
||||
|
||||
public interface QtInputConnectionListener {
|
||||
void onSetClosing(boolean closing);
|
||||
void onHideKeyboardRunnableDone(boolean visibility, long hideTimeStamp);
|
||||
void onSendKeyEventDefaultCase();
|
||||
}
|
||||
|
||||
private QtEditText m_view = null;
|
||||
|
||||
private void setClosing(boolean closing)
|
||||
{
|
||||
if (closing) {
|
||||
if (closing)
|
||||
m_view.postDelayed(new HideKeyboardRunnable(), 100);
|
||||
} else {
|
||||
QtNative.activityDelegate().getInputDelegate().setKeyboardVisibility(true, System.nanoTime());
|
||||
}
|
||||
else
|
||||
m_qtInputConnectionListener.onSetClosing(false);
|
||||
}
|
||||
|
||||
public QtInputConnection(QtEditText targetView)
|
||||
public QtInputConnection(QtEditText targetView, QtInputConnectionListener listener)
|
||||
{
|
||||
super(targetView, true);
|
||||
m_view = targetView;
|
||||
m_qtInputConnectionListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -256,7 +262,7 @@ public class QtInputConnection extends BaseInputConnection
|
||||
break;
|
||||
|
||||
default:
|
||||
QtNative.activityDelegate().getInputDelegate().hideSoftwareKeyboard();
|
||||
m_qtInputConnectionListener.onSendKeyEventDefaultCase();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
package org.qtproject.qt.android;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@ -17,6 +18,8 @@ import android.view.MotionEvent;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import org.qtproject.qt.android.QtInputConnection.QtInputConnectionListener;
|
||||
|
||||
public class QtInputDelegate {
|
||||
|
||||
// keyboard methods
|
||||
@ -96,7 +99,7 @@ public class QtInputDelegate {
|
||||
private int m_lastChar = 0;
|
||||
private boolean m_backKeyPressedSent = false;
|
||||
|
||||
// Note: because of the circular call to updateFullScreen() from QtActivityDelegate, we need
|
||||
// Note: because of the circular call to updateFullScreen() from the delegate, we need
|
||||
// a listener to be able to do that call from the delegate, because that's where that
|
||||
// logic lives
|
||||
public interface KeyboardVisibilityListener {
|
||||
@ -105,9 +108,29 @@ public class QtInputDelegate {
|
||||
|
||||
private final KeyboardVisibilityListener m_keyboardVisibilityListener;
|
||||
|
||||
QtInputDelegate(KeyboardVisibilityListener listener)
|
||||
QtInputDelegate(Activity activity, KeyboardVisibilityListener listener)
|
||||
{
|
||||
this.m_keyboardVisibilityListener = listener;
|
||||
m_editText = new QtEditText(activity);
|
||||
m_imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
QtInputConnectionListener inputConnectionListener = new QtInputConnectionListener() {
|
||||
@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();
|
||||
}
|
||||
};
|
||||
m_editText.setQtInputConnectionListener(inputConnectionListener);
|
||||
}
|
||||
|
||||
public boolean isKeyboardVisible()
|
||||
@ -131,16 +154,6 @@ public class QtInputDelegate {
|
||||
return m_editText;
|
||||
}
|
||||
|
||||
void setEditText(QtEditText editText)
|
||||
{
|
||||
m_editText = editText;
|
||||
}
|
||||
|
||||
void setInputMethodManager(InputMethodManager inputMethodManager)
|
||||
{
|
||||
m_imm = inputMethodManager;
|
||||
}
|
||||
|
||||
void setEditPopupMenu(EditPopupMenu editPopupMenu)
|
||||
{
|
||||
m_editPopupMenu = editPopupMenu;
|
||||
|
@ -54,11 +54,10 @@ import android.graphics.Rect;
|
||||
|
||||
public class QtNative
|
||||
{
|
||||
// TODO get rid of the delegation from QtNative, call directly the Activity in c++
|
||||
private static Activity m_activity = null;
|
||||
private static boolean m_activityPaused = false;
|
||||
private static Service m_service = null;
|
||||
private static QtActivityDelegate m_activityDelegate = null;
|
||||
private static QtServiceDelegate m_serviceDelegate = null;
|
||||
public static Object m_mainActivityMutex = new Object(); // mutex used to synchronize runnable operations
|
||||
|
||||
public static final String QtTAG = "Qt JAVA"; // string used for Log.x
|
||||
@ -81,8 +80,8 @@ public class QtNative
|
||||
|
||||
public static boolean isStarted()
|
||||
{
|
||||
boolean hasActivity = m_activity != null && m_activityDelegate != null;
|
||||
boolean hasService = m_service != null && m_serviceDelegate != null;
|
||||
boolean hasActivity = m_activity != null;
|
||||
boolean hasService = m_service != null;
|
||||
return m_started && (hasActivity || hasService);
|
||||
}
|
||||
|
||||
@ -111,21 +110,6 @@ public class QtNative
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static QtActivityDelegate activityDelegate()
|
||||
{
|
||||
synchronized (m_mainActivityMutex) {
|
||||
return m_activityDelegate;
|
||||
}
|
||||
}
|
||||
|
||||
public static QtServiceDelegate serviceDelegate()
|
||||
{
|
||||
synchronized (m_mainActivityMutex) {
|
||||
return m_serviceDelegate;
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getStringArray(String joinedString)
|
||||
{
|
||||
return joinedString.split(",");
|
||||
@ -204,19 +188,17 @@ public class QtNative
|
||||
return m_qtThread;
|
||||
}
|
||||
|
||||
public static void setActivity(Activity qtMainActivity, QtActivityDelegate qtActivityDelegate)
|
||||
public static void setActivity(Activity qtMainActivity)
|
||||
{
|
||||
synchronized (m_mainActivityMutex) {
|
||||
m_activity = qtMainActivity;
|
||||
m_activityDelegate = qtActivityDelegate;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setService(Service qtMainService, QtServiceDelegate qtServiceDelegate)
|
||||
public static void setService(Service qtMainService)
|
||||
{
|
||||
synchronized (m_mainActivityMutex) {
|
||||
m_service = qtMainService;
|
||||
m_serviceDelegate = qtServiceDelegate;
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,72 +331,6 @@ public class QtNative
|
||||
return perm;
|
||||
}
|
||||
|
||||
// TODO get rid of the delegation from QtNative, call directly the Activity in c++
|
||||
private static void setSystemUiVisibility(final int systemUiVisibility)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null) {
|
||||
m_activityDelegate.setSystemUiVisibility(systemUiVisibility);
|
||||
}
|
||||
updateWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void notifyQtAndroidPluginRunning(final boolean running)
|
||||
{
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.notifyQtAndroidPluginRunning(running);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void openContextMenu(final int x, final int y, final int w, final int h)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.openContextMenu(x, y, w, h);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void closeContextMenu()
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.closeContextMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void resetOptionsMenu()
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.resetOptionsMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void openOptionsMenu()
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activity != null)
|
||||
m_activity.openOptionsMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static byte[][] getSSLCertificates()
|
||||
{
|
||||
ArrayList<byte[]> certificateList = new ArrayList<byte[]>();
|
||||
@ -442,83 +358,6 @@ public class QtNative
|
||||
return certificateArray;
|
||||
}
|
||||
|
||||
private static void createSurface(final int id, final boolean onTop, final int x, final int y, final int w, final int h, final int imageDepth)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.createSurface(id, onTop, x, y, w, h, imageDepth);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void insertNativeView(final int id, final View view, final int x, final int y, final int w, final int h)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.insertNativeView(id, view, x, y, w, h);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void setSurfaceGeometry(final int id, final int x, final int y, final int w, final int h)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.setSurfaceGeometry(id, x, y, w, h);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void bringChildToFront(final int id)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.bringChildToFront(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void bringChildToBack(final int id)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.bringChildToBack(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void destroySurface(final int id)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.destroySurface(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void hideSplashScreen(final int duration)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (m_activityDelegate != null)
|
||||
m_activityDelegate.hideSplashScreen(duration);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static String[] listAssetContent(android.content.res.AssetManager asset, String path) {
|
||||
String [] list;
|
||||
ArrayList<String> res = new ArrayList<String>();
|
||||
|
@ -9,15 +9,11 @@ import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
public class QtServiceBase extends Service {
|
||||
private QtServiceDelegate m_delegate;
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
|
||||
m_delegate = new QtServiceDelegate(this);
|
||||
|
||||
// the application has already started, do not reload everything again
|
||||
if (QtNative.isStarted()) {
|
||||
Log.w(QtNative.QtTAG,
|
||||
@ -38,7 +34,7 @@ public class QtServiceBase extends Service {
|
||||
super.onDestroy();
|
||||
QtNative.quitQtCoreApplication();
|
||||
QtNative.terminateQt();
|
||||
QtNative.setService(null, null);
|
||||
QtNative.setService(null);
|
||||
QtNative.m_qtThread.exit();
|
||||
System.exit(0);
|
||||
}
|
||||
@ -49,9 +45,4 @@ public class QtServiceBase extends Service {
|
||||
return QtNative.onBind(intent);
|
||||
}
|
||||
}
|
||||
|
||||
QtServiceDelegate getServiceDelegate()
|
||||
{
|
||||
return m_delegate;
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
// Copyright (C) 2016 BogDan Vatra <bogdan@kde.org>
|
||||
// Copyright (C) 2023 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.Service;
|
||||
|
||||
public class QtServiceDelegate
|
||||
{
|
||||
private Service m_service = null;
|
||||
|
||||
QtServiceDelegate(Service service)
|
||||
{
|
||||
m_service = service;
|
||||
|
||||
// Set native context
|
||||
QtNative.setService(m_service, this);
|
||||
}
|
||||
}
|
@ -94,8 +94,7 @@ int QNativeInterface::QAndroidApplication::sdkVersion()
|
||||
*/
|
||||
void QNativeInterface::QAndroidApplication::hideSplashScreen(int duration)
|
||||
{
|
||||
QJniObject::callStaticMethod<void>("org/qtproject/qt/android/QtNative",
|
||||
"hideSplashScreen", "(I)V", duration);
|
||||
QtAndroidPrivate::activity().callMethod<void>("hideSplashScreen", duration);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -45,9 +45,6 @@ static jmethodID m_loadClassMethodID = nullptr;
|
||||
static AAssetManager *m_assetManager = nullptr;
|
||||
static jobject m_assets = nullptr;
|
||||
static jobject m_resourcesObj = nullptr;
|
||||
static jmethodID m_createSurfaceMethodID = nullptr;
|
||||
static jmethodID m_setSurfaceGeometryMethodID = nullptr;
|
||||
static jmethodID m_destroySurfaceMethodID = nullptr;
|
||||
|
||||
static QtJniTypes::QtActivityDelegate m_activityDelegate = nullptr;
|
||||
static QtJniTypes::QtInputDelegate m_inputDelegate = nullptr;
|
||||
@ -165,7 +162,7 @@ namespace QtAndroid
|
||||
// TODO move calls from here to where they logically belong
|
||||
void setSystemUiVisibility(SystemUiVisibility uiVisibility)
|
||||
{
|
||||
QJniObject::callStaticMethod<void>(m_applicationClass, "setSystemUiVisibility", "(I)V", jint(uiVisibility));
|
||||
qtActivityDelegate().callMethod<void>("setSystemUiVisibility", jint(uiVisibility));
|
||||
}
|
||||
|
||||
// FIXME: avoid direct access to QtActivityDelegate
|
||||
@ -218,7 +215,7 @@ namespace QtAndroid
|
||||
|
||||
void notifyQtAndroidPluginRunning(bool running)
|
||||
{
|
||||
QJniObject::callStaticMethod<void>(m_applicationClass, "notifyQtAndroidPluginRunning","(Z)V", running);
|
||||
qtActivityDelegate().callMethod<void>("notifyQtAndroidPluginRunning", running);
|
||||
}
|
||||
|
||||
jobject createBitmap(QImage img, JNIEnv *env)
|
||||
@ -338,12 +335,8 @@ namespace QtAndroid
|
||||
w = std::max(geometry.width(), 1);
|
||||
h = std::max(geometry.height(), 1);
|
||||
}
|
||||
env->CallStaticVoidMethod(m_applicationClass,
|
||||
m_createSurfaceMethodID,
|
||||
surfaceId,
|
||||
jboolean(onTop),
|
||||
x, y, w, h,
|
||||
imageDepth);
|
||||
qtActivityDelegate().callMethod<void>("createSurface", surfaceId, jboolean(onTop),
|
||||
x, y, w, h, imageDepth);
|
||||
return surfaceId;
|
||||
}
|
||||
|
||||
@ -358,9 +351,7 @@ namespace QtAndroid
|
||||
if (!geometry.isNull())
|
||||
geometry.getRect(&x, &y, &w, &h);
|
||||
|
||||
QJniObject::callStaticMethod<void>(m_applicationClass,
|
||||
"insertNativeView",
|
||||
"(ILandroid/view/View;IIII)V",
|
||||
qtActivityDelegate().callMethod<void>("insertNativeView",
|
||||
surfaceId,
|
||||
view,
|
||||
x,
|
||||
@ -395,10 +386,7 @@ namespace QtAndroid
|
||||
w = geometry.width();
|
||||
h = geometry.height();
|
||||
}
|
||||
env->CallStaticVoidMethod(m_applicationClass,
|
||||
m_setSurfaceGeometryMethodID,
|
||||
surfaceId,
|
||||
x, y, w, h);
|
||||
qtActivityDelegate().callMethod<void>("setSurfaceGeometry", surfaceId, x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
@ -414,11 +402,7 @@ namespace QtAndroid
|
||||
m_surfaces.erase(it);
|
||||
}
|
||||
|
||||
QJniEnvironment env;
|
||||
if (env.jniEnv())
|
||||
env->CallStaticVoidMethod(m_applicationClass,
|
||||
m_destroySurfaceMethodID,
|
||||
surfaceId);
|
||||
qtActivityDelegate().callMethod<void>("destroySurface", surfaceId);
|
||||
}
|
||||
|
||||
void bringChildToFront(int surfaceId)
|
||||
@ -426,10 +410,7 @@ namespace QtAndroid
|
||||
if (surfaceId == -1)
|
||||
return;
|
||||
|
||||
QJniObject::callStaticMethod<void>(m_applicationClass,
|
||||
"bringChildToFront",
|
||||
"(I)V",
|
||||
surfaceId);
|
||||
qtActivityDelegate().callMethod<void>("bringChildToFront", surfaceId);
|
||||
}
|
||||
|
||||
void bringChildToBack(int surfaceId)
|
||||
@ -437,10 +418,7 @@ namespace QtAndroid
|
||||
if (surfaceId == -1)
|
||||
return;
|
||||
|
||||
QJniObject::callStaticMethod<void>(m_applicationClass,
|
||||
"bringChildToBack",
|
||||
"(I)V",
|
||||
surfaceId);
|
||||
qtActivityDelegate().callMethod<void>("bringChildToBack", surfaceId);
|
||||
}
|
||||
|
||||
bool blockEventLoopsWhenSuspended()
|
||||
@ -893,10 +871,6 @@ static bool registerNatives(QJniEnvironment &env)
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
GET_AND_CHECK_STATIC_METHOD(m_createSurfaceMethodID, m_applicationClass, "createSurface", "(IZIIIII)V");
|
||||
GET_AND_CHECK_STATIC_METHOD(m_setSurfaceGeometryMethodID, m_applicationClass, "setSurfaceGeometry", "(IIIII)V");
|
||||
GET_AND_CHECK_STATIC_METHOD(m_destroySurfaceMethodID, m_applicationClass, "destroySurface", "(I)V");
|
||||
|
||||
jmethodID methodID;
|
||||
GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;");
|
||||
jobject contextObject = env->CallStaticObjectMethod(m_applicationClass, methodID);
|
||||
|
@ -31,8 +31,6 @@ namespace QtAndroidMenu
|
||||
static QWindow *activeTopLevelWindow = nullptr;
|
||||
Q_CONSTINIT static QRecursiveMutex menuBarMutex;
|
||||
|
||||
static jmethodID openContextMenuMethodID = 0;
|
||||
|
||||
static jmethodID clearMenuMethodID = 0;
|
||||
static jmethodID addMenuItemMethodID = 0;
|
||||
static int menuNoneValue = 0;
|
||||
@ -46,29 +44,31 @@ namespace QtAndroidMenu
|
||||
|
||||
void resetMenuBar()
|
||||
{
|
||||
QJniObject::callStaticMethod<void>(applicationClass(), "resetOptionsMenu");
|
||||
qtActivityDelegate().callMethod<void>("resetOptionsMenu");
|
||||
}
|
||||
|
||||
void openOptionsMenu()
|
||||
{
|
||||
QJniObject::callStaticMethod<void>(applicationClass(), "openOptionsMenu");
|
||||
qtActivityDelegate().callMethod<void>("openOptionsMenu");
|
||||
}
|
||||
|
||||
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env)
|
||||
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect)
|
||||
{
|
||||
QMutexLocker lock(&visibleMenuMutex);
|
||||
if (visibleMenu)
|
||||
pendingContextMenus.append(visibleMenu);
|
||||
visibleMenu = menu;
|
||||
menu->aboutToShow();
|
||||
env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
|
||||
qtActivityDelegate().callMethod<void>("openContextMenu",
|
||||
anchorRect.x(), anchorRect.y(),
|
||||
anchorRect.width(), anchorRect.height());
|
||||
}
|
||||
|
||||
void hideContextMenu(QAndroidPlatformMenu *menu)
|
||||
{
|
||||
QMutexLocker lock(&visibleMenuMutex);
|
||||
if (visibleMenu == menu) {
|
||||
QJniObject::callStaticMethod<void>(applicationClass(), "closeContextMenu");
|
||||
qtActivityDelegate().callMethod<void>("closeContextMenu");
|
||||
pendingContextMenus.clear();
|
||||
} else {
|
||||
pendingContextMenus.removeOne(menu);
|
||||
@ -211,8 +211,10 @@ namespace QtAndroidMenu
|
||||
return order;
|
||||
}
|
||||
|
||||
static jboolean onPrepareOptionsMenu(JNIEnv *env, jobject /*thiz*/, jobject menu)
|
||||
static jboolean onPrepareOptionsMenu(JNIEnv *env, jobject thiz, jobject menu)
|
||||
{
|
||||
Q_UNUSED(thiz)
|
||||
|
||||
env->CallVoidMethod(menu, clearMenuMethodID);
|
||||
QMutexLocker lock(&menuBarMutex);
|
||||
if (!visibleMenuBar)
|
||||
@ -249,8 +251,11 @@ namespace QtAndroidMenu
|
||||
return order ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
static jboolean onOptionsItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked)
|
||||
static jboolean onOptionsItemSelected(JNIEnv *env, jobject thiz, jint menuId, jboolean checked)
|
||||
{
|
||||
Q_UNUSED(env)
|
||||
Q_UNUSED(thiz)
|
||||
|
||||
QMutexLocker lock(&menuBarMutex);
|
||||
if (!visibleMenuBar)
|
||||
return JNI_FALSE;
|
||||
@ -260,7 +265,7 @@ namespace QtAndroidMenu
|
||||
QAndroidPlatformMenuItem *item = static_cast<QAndroidPlatformMenuItem *>(menus.front()->menuItemForId(menuId));
|
||||
if (item) {
|
||||
if (item->menu()) {
|
||||
showContextMenu(item->menu(), QRect(), env);
|
||||
showContextMenu(item->menu(), QRect());
|
||||
} else {
|
||||
if (item->isCheckable())
|
||||
item->setChecked(checked);
|
||||
@ -270,18 +275,23 @@ namespace QtAndroidMenu
|
||||
} else {
|
||||
QAndroidPlatformMenu *menu = static_cast<QAndroidPlatformMenu *>(visibleMenuBar->menuForId(menuId));
|
||||
if (menu)
|
||||
showContextMenu(menu, QRect(), env);
|
||||
showContextMenu(menu, QRect());
|
||||
}
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
static void onOptionsMenuClosed(JNIEnv */*env*/, jobject /*thiz*/, jobject /*menu*/)
|
||||
static void onOptionsMenuClosed(JNIEnv *env, jobject thiz, jobject menu)
|
||||
{
|
||||
Q_UNUSED(env)
|
||||
Q_UNUSED(thiz)
|
||||
Q_UNUSED(menu)
|
||||
}
|
||||
|
||||
static void onCreateContextMenu(JNIEnv *env, jobject /*thiz*/, jobject menu)
|
||||
static void onCreateContextMenu(JNIEnv *env, jobject thiz, jobject menu)
|
||||
{
|
||||
Q_UNUSED(thiz)
|
||||
|
||||
env->CallVoidMethod(menu, clearMenuMethodID);
|
||||
QMutexLocker lock(&visibleMenuMutex);
|
||||
if (!visibleMenu)
|
||||
@ -295,8 +305,9 @@ namespace QtAndroidMenu
|
||||
addAllMenuItemsToMenu(env, menu, visibleMenu);
|
||||
}
|
||||
|
||||
static void fillContextMenu(JNIEnv *env, jobject /*thiz*/, jobject menu)
|
||||
static void fillContextMenu(JNIEnv *env, jobject thiz, jobject menu)
|
||||
{
|
||||
Q_UNUSED(thiz)
|
||||
env->CallVoidMethod(menu, clearMenuMethodID);
|
||||
QMutexLocker lock(&visibleMenuMutex);
|
||||
if (!visibleMenu)
|
||||
@ -305,13 +316,16 @@ namespace QtAndroidMenu
|
||||
addAllMenuItemsToMenu(env, menu, visibleMenu);
|
||||
}
|
||||
|
||||
static jboolean onContextItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked)
|
||||
static jboolean onContextItemSelected(JNIEnv *env, jobject thiz, jint menuId, jboolean checked)
|
||||
{
|
||||
Q_UNUSED(env)
|
||||
Q_UNUSED(thiz)
|
||||
|
||||
QMutexLocker lock(&visibleMenuMutex);
|
||||
QAndroidPlatformMenuItem * item = static_cast<QAndroidPlatformMenuItem *>(visibleMenu->menuItemForId(menuId));
|
||||
if (item) {
|
||||
if (item->menu()) {
|
||||
showContextMenu(item->menu(), QRect(), env);
|
||||
showContextMenu(item->menu(), QRect());
|
||||
} else {
|
||||
if (item->isCheckable())
|
||||
item->setChecked(checked);
|
||||
@ -328,8 +342,12 @@ namespace QtAndroidMenu
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
static void onContextMenuClosed(JNIEnv *env, jobject /*thiz*/, jobject /*menu*/)
|
||||
static void onContextMenuClosed(JNIEnv *env, jobject thiz, jobject menu)
|
||||
{
|
||||
Q_UNUSED(env)
|
||||
Q_UNUSED(thiz)
|
||||
Q_UNUSED(menu)
|
||||
|
||||
QMutexLocker lock(&visibleMenuMutex);
|
||||
if (!visibleMenu)
|
||||
return;
|
||||
@ -337,7 +355,7 @@ namespace QtAndroidMenu
|
||||
visibleMenu->aboutToHide();
|
||||
visibleMenu = 0;
|
||||
if (!pendingContextMenus.empty())
|
||||
showContextMenu(pendingContextMenus.takeLast(), QRect(), env);
|
||||
showContextMenu(pendingContextMenus.takeLast(), QRect());
|
||||
}
|
||||
|
||||
static JNINativeMethod methods[] = {
|
||||
@ -387,8 +405,6 @@ namespace QtAndroidMenu
|
||||
return false;
|
||||
}
|
||||
|
||||
GET_AND_CHECK_STATIC_METHOD(openContextMenuMethodID, appClass, "openContextMenu", "(IIII)V");
|
||||
|
||||
jclass clazz;
|
||||
FIND_AND_CHECK_CLASS("android/view/Menu");
|
||||
GET_AND_CHECK_METHOD(clearMenuMethodID, clazz, "clear", "()V");
|
||||
|
@ -21,7 +21,7 @@ namespace QtAndroidMenu
|
||||
{
|
||||
// Menu support
|
||||
void openOptionsMenu();
|
||||
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env);
|
||||
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect);
|
||||
void hideContextMenu(QAndroidPlatformMenu *menu);
|
||||
void syncMenu(QAndroidPlatformMenu *menu);
|
||||
void androidPlatformMenuDestroyed(QAndroidPlatformMenu *menu);
|
||||
|
@ -119,7 +119,7 @@ void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &t
|
||||
Q_UNUSED(parentWindow);
|
||||
Q_UNUSED(item);
|
||||
setVisible(true);
|
||||
QtAndroidMenu::showContextMenu(this, targetRect, QJniEnvironment().jniEnv());
|
||||
QtAndroidMenu::showContextMenu(this, targetRect);
|
||||
}
|
||||
|
||||
QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const
|
||||
|
@ -199,11 +199,14 @@ void tst_Android::testRunOnAndroidMainThread()
|
||||
}
|
||||
}
|
||||
|
||||
Q_DECLARE_JNI_CLASS(QtActivityDelegate, "org/qtproject/qt/android/QtActivityDelegate")
|
||||
|
||||
void setSystemUiVisibility(int visibility)
|
||||
{
|
||||
QNativeInterface::QAndroidApplication::runOnAndroidMainThread([visibility] {
|
||||
QJniObject::callStaticMethod<void>("org/qtproject/qt/android/QtNative",
|
||||
"setSystemUiVisibility", "(I)V", visibility);
|
||||
auto context = QNativeInterface::QAndroidApplication::context();
|
||||
auto activityDelegate = context.callMethod<QtJniTypes::QtActivityDelegate>("getActivityDelegate");
|
||||
activityDelegate.callMethod<void>("setSystemUiVisibility", jint(visibility));
|
||||
}).waitForFinished();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user