From 417cf3fc535ef18e7895cb863235cc33e36669f9 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 6 Nov 2013 15:42:16 +0200 Subject: Android: Fix menu on API-11+ On API-11+ if there is no hardware menu button show the action bar. Fix menu when using the opengl android plugin. Task-number: QTBUG-32002 Change-Id: I45bd49107621e4cab85eb6411897229e20bb8281 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: BogDan Vatra --- .../qtproject/qt5/android/QtActivityDelegate.java | 64 ++++++++++++++++++++-- .../qtproject/qt5/android/bindings/QtActivity.java | 15 ++++- .../platforms/android/src/androidjnimenu.cpp | 26 +++++---- .../src/opengl/qandroidopenglplatformscreen.cpp | 2 + .../android/src/qandroidplatformmenubar.cpp | 2 + 5 files changed, 92 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 82533dc9cb..da2f6163ea 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -63,6 +63,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.Surface; import android.view.View; +import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; @@ -406,6 +407,7 @@ public class QtActivityDelegate m_applicationParameters = loaderParams.getString(APPLICATION_PARAMETERS_KEY); else m_applicationParameters = ""; + setActionBarVisibility(false); return true; } @@ -615,7 +617,7 @@ public class QtActivityDelegate m_surface = new QtSurface(m_activity, 0); m_editText = new QtEditText(m_activity, this); m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE); - m_layout.addView(m_surface,0); + m_layout.addView(m_surface, 0); m_activity.setContentView(m_layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); @@ -808,7 +810,10 @@ public class QtActivityDelegate public boolean onPrepareOptionsMenu(Menu menu) { m_opionsMenuIsVisible = true; - return QtNative.onPrepareOptionsMenu(menu); + boolean res = QtNative.onPrepareOptionsMenu(menu); + if (!res || menu.size() == 0) + setActionBarVisibility(false); + return res; } public boolean onOptionsItemSelected(MenuItem item) @@ -824,8 +829,17 @@ public class QtActivityDelegate public void resetOptionsMenu() { - if (m_opionsMenuIsVisible) - m_activity.closeOptionsMenu(); + setActionBarVisibility(true); + if (Build.VERSION.SDK_INT > 10) { + try { + Activity.class.getMethod("invalidateOptionsMenu").invoke(m_activity); + } catch (Exception e) { + e.printStackTrace(); + } + } + else + if (m_opionsMenuIsVisible) + m_activity.closeOptionsMenu(); } private boolean m_contextMenuVisible = false; public void onCreateContextMenu(ContextMenu menu, @@ -866,4 +880,46 @@ public class QtActivityDelegate { m_activity.closeContextMenu(); } + + private boolean hasPermanentMenuKey() + { + try { + return Build.VERSION.SDK_INT < 11 || (Build.VERSION.SDK_INT >= 14 && + (Boolean)ViewConfiguration.class.getMethod("hasPermanentMenuKey").invoke(ViewConfiguration.get(m_activity))); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + private Object getActionBar() + { + try { + return Activity.class.getMethod("getActionBar").invoke(m_activity); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + private void setActionBarVisibility(boolean visible) + { + if (hasPermanentMenuKey() || !visible) { + if (Build.VERSION.SDK_INT > 10 && getActionBar() != null) { + try { + Class.forName("android.app.ActionBar").getMethod("hide").invoke(getActionBar()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } else { + if (Build.VERSION.SDK_INT > 10 && getActionBar() != null) + try { + Class.forName("android.app.ActionBar").getMethod("show").invoke(getActionBar()); + } catch (Exception e) { + e.printStackTrace(); + } + } + } } diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java index 4c5d479800..089cf5aa60 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java @@ -80,6 +80,7 @@ import android.view.ActionMode; import android.view.ActionMode.Callback; //@ANDROID-11 + public class QtActivity extends Activity { private final static int MINISTRO_INSTALL_REQUEST_CODE = 0xf3ee; // request code used to know when Ministro instalation is finished @@ -714,13 +715,25 @@ public class QtActivity extends Activity } catch (Exception e) { e.printStackTrace(); } + + if (Build.VERSION.SDK_INT > 10) { + try { + requestWindowFeature(Window.class.getField("FEATURE_ACTION_BAR").getInt(null)); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + requestWindowFeature(Window.FEATURE_NO_TITLE); + } + if (QtApplication.m_delegateObject != null && QtApplication.onCreate != null) { QtApplication.invokeDelegateMethod(QtApplication.onCreate, savedInstanceState); return; } + ENVIRONMENT_VARIABLES += "\tQT_ANDROID_THEME=" + QT_ANDROID_DEFAULT_THEME + "/\tQT_ANDROID_THEME_DISPLAY_DPI=" + getResources().getDisplayMetrics().densityDpi + "\t"; - requestWindowFeature(Window.FEATURE_NO_TITLE); + try { m_activityInfo = getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA); } catch (NameNotFoundException e) { diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/src/androidjnimenu.cpp index 8964995832..866acd3c7e 100644 --- a/src/plugins/platforms/android/src/androidjnimenu.cpp +++ b/src/plugins/platforms/android/src/androidjnimenu.cpp @@ -41,13 +41,14 @@ #include "androidjnimenu.h" #include "androidjnimain.h" -#include -#include -#include -#include #include "qandroidplatformmenubar.h" #include "qandroidplatformmenu.h" -#include +#include "qandroidplatformmenuitem.h" + +#include +#include +#include +#include using namespace QtAndroid; @@ -141,18 +142,17 @@ namespace QtAndroidMenu void setActiveTopLevelWindow(QWindow *window) { + Qt::WindowFlags flags = window->flags(); + bool isNonRegularWindow = flags & (Qt::Desktop | Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window; + if (isNonRegularWindow) + return; + QMutexLocker lock(&menuBarMutex); if (activeTopLevelWindow == window) return; visibleMenuBar = 0; activeTopLevelWindow = window; -#ifdef ANDROID_PLUGIN_OPENGL - //only one toplevel window, so the menu bar always belongs to us - if (menuBars.size() == 1) { - visibleMenuBar = *menuBars.constBegin(); //since QSet doesn't have first() - } else -#endif foreach (QAndroidPlatformMenuBar *menuBar, menuBars) { if (menuBar->parentWindow() == window) { visibleMenuBar = menuBar; @@ -173,8 +173,10 @@ namespace QtAndroidMenu { QMutexLocker lock(&menuBarMutex); menuBars.remove(menuBar); - if (visibleMenuBar == menuBar) + if (visibleMenuBar == menuBar) { + visibleMenuBar = 0; resetMenuBar(); + } } static QString removeAmpersandEscapes(QString s) diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp index 821fd954df..de4075feff 100644 --- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp @@ -41,6 +41,7 @@ #include "qandroidopenglplatformscreen.h" #include "qandroidopenglplatformwindow.h" +#include "androidjnimenu.h" QT_BEGIN_NAMESPACE @@ -51,6 +52,7 @@ QAndroidOpenGLPlatformScreen::QAndroidOpenGLPlatformScreen(EGLDisplay display) void QAndroidOpenGLPlatformScreen::topWindowChanged(QPlatformWindow *window) { + QtAndroidMenu::setActiveTopLevelWindow(window->window()); QAndroidOpenGLPlatformWindow *platformWindow = static_cast(window); if (platformWindow != 0) platformWindow->updateStatusBarVisibility(); diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp index ef1ac61356..134062fb32 100644 --- a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp @@ -79,6 +79,8 @@ void QAndroidPlatformMenuBar::syncMenu(QPlatformMenu *menu) void QAndroidPlatformMenuBar::handleReparent(QWindow *newParentWindow) { + if (m_parentWindow == newParentWindow) + return; m_parentWindow = newParentWindow; QtAndroidMenu::setMenuBar(this, newParentWindow); } -- cgit v1.2.3