Android: Differ between ShowMaximized and ShowFullScreen

The default is now ShowMaximized which behaves as it did before,
i.e. each window will fill the screen but the status bar will be
visible. Calling showFullScreen() explicitly will now hide the
status bar to maximize the amount of screen real estate occupied
by the application.

Task-number: QTBUG-33135
Change-Id: If0d0a2ab72f8026e76818290e2b953dbc0dec156
Reviewed-by: BogDan Vatra <bogdan@kde.org>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2013-10-31 16:14:54 +01:00 committed by The Qt Project
parent 45b10ee02a
commit 59569fd020
20 changed files with 287 additions and 11 deletions

View File

@ -343,6 +343,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
return QPlatformTheme::defaultThemeHint(QPlatformTheme::StartDragTime);
case ShowIsFullScreen:
return false;
case ShowIsMaximized:
return false;
case PasswordMaskDelay:
return QPlatformTheme::defaultThemeHint(QPlatformTheme::PasswordMaskDelay);
case PasswordMaskCharacter:

View File

@ -147,7 +147,8 @@ public:
UseRtlExtensions,
SynthesizeMouseFromTouchEvents,
PasswordMaskCharacter,
SetFocusOnTouchRelease
SetFocusOnTouchRelease,
ShowIsMaximized
};
virtual QVariant styleHint(StyleHint hint) const;

View File

@ -1657,6 +1657,8 @@ void QWindow::show()
bool isPopup = d_func()->windowFlags & Qt::Popup & ~Qt::Window;
if (!isPopup && qApp->styleHints()->showIsFullScreen())
showFullScreen();
else if (!isPopup && QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ShowIsMaximized).toBool())
showMaximized();
else
showNormal();
}

View File

@ -20,11 +20,13 @@ INCLUDEPATH += $$PWD/../src/opengl/
HEADERS += \
$$PWD/../src/opengl/qandroidopenglcontext.h \
$$PWD/../src/opengl/qandroidopenglplatformwindow.h
$$PWD/../src/opengl/qandroidopenglplatformwindow.h \
$$PWD/../src/opengl/qandroidopenglplatformscreen.h
SOURCES += \
$$PWD/../src/opengl/qandroidopenglcontext.cpp \
$$PWD/../src/opengl/qandroidopenglplatformwindow.cpp
$$PWD/../src/opengl/qandroidopenglplatformwindow.cpp \
$$PWD/../src/opengl/qandroidopenglplatformscreen.cpp
include($$PWD/../../eglfs/eglfs.pri)
include($$PWD/../src/src.pri)

View File

@ -97,6 +97,9 @@ static jmethodID m_createBitmapMethodID = 0;
static jobject m_ARGB_8888_BitmapConfigValue = 0;
static jobject m_RGB_565_BitmapConfigValue = 0;
jmethodID m_setFullScreenMethodID = 0;
static bool m_statusBarShowing = true;
static jclass m_bitmapDrawableClass = 0;
static jmethodID m_bitmapDrawableConstructorMethodID = 0;
@ -310,6 +313,36 @@ namespace QtAndroid
return m_activityObject;
}
void showStatusBar()
{
if (m_statusBarShowing)
return;
QtAndroid::AttachedJNIEnv env;
if (env.jniEnv == 0) {
qWarning("Failed to get JNI Environment.");
return;
}
env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, false);
m_statusBarShowing = true;
}
void hideStatusBar()
{
if (!m_statusBarShowing)
return;
QtAndroid::AttachedJNIEnv env;
if (env.jniEnv == 0) {
qWarning("Failed to get JNI Environment.");
return;
}
env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, true);
m_statusBarShowing = false;
}
void setApplicationActive()
{
if (m_activityActive)
@ -753,6 +786,7 @@ static int registerNatives(JNIEnv *env)
jclass clazz;
FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative");
m_applicationClass = static_cast<jclass>(env->NewGlobalRef(clazz));
GET_AND_CHECK_STATIC_METHOD(m_setFullScreenMethodID, m_applicationClass, "setFullScreen", "(Z)V");
if (env->RegisterNatives(m_applicationClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
__android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");

View File

@ -69,8 +69,6 @@ namespace QtAndroid
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration);
void setQtThread(QThread *thread);
void setFullScreen(QWidget *widget);
#ifndef ANDROID_PLUGIN_OPENGL
void flushImage(const QPoint &pos, const QImage &image, const QRect &rect);
#else
@ -89,6 +87,9 @@ namespace QtAndroid
void setApplicationActive();
void showStatusBar();
void hideStatusBar();
jobject createBitmap(QImage img, JNIEnv *env = 0);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);

View File

@ -0,0 +1,59 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qandroidopenglplatformscreen.h"
#include "qandroidopenglplatformwindow.h"
QT_BEGIN_NAMESPACE
QAndroidOpenGLPlatformScreen::QAndroidOpenGLPlatformScreen(EGLDisplay display)
: QEglFSScreen(display)
{
}
void QAndroidOpenGLPlatformScreen::topWindowChanged(QPlatformWindow *window)
{
QAndroidOpenGLPlatformWindow *platformWindow = static_cast<QAndroidOpenGLPlatformWindow *>(window);
if (platformWindow != 0)
platformWindow->updateStatusBarVisibility();
}
QT_END_NAMESPACE

View File

@ -0,0 +1,60 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QANDROIDOPENGLPLATFORMSCREEN_H
#define QANDROIDOPENGLPLATFORMSCREEN_H
#include "qeglfsscreen.h"
QT_BEGIN_NAMESPACE
class QAndroidOpenGLPlatformScreen : public QEglFSScreen
{
public:
QAndroidOpenGLPlatformScreen(EGLDisplay display);
protected:
void topWindowChanged(QPlatformWindow *window);
};
QT_END_NAMESPACE
#endif // QANDROIDOPENGLPLATFORMSCREEN_H

View File

@ -53,6 +53,7 @@ QBasicAtomicInt QAndroidOpenGLPlatformWindow::m_referenceCount = Q_BASIC_ATOMIC_
QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window)
: QEglFSWindow(window)
, m_state(Qt::WindowNoState)
{
}
@ -131,12 +132,38 @@ void QAndroidOpenGLPlatformWindow::destroy()
}
}
void QAndroidOpenGLPlatformWindow::updateStatusBarVisibility()
{
Qt::WindowFlags flags = window()->flags();
bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
if (!isNonRegularWindow) {
if (m_state & Qt::WindowFullScreen)
QtAndroid::hideStatusBar();
else if (m_state & Qt::WindowMaximized)
QtAndroid::showStatusBar();
}
}
void QAndroidOpenGLPlatformWindow::raise()
{
updateStatusBarVisibility();
}
void QAndroidOpenGLPlatformWindow::setWindowState(Qt::WindowState state)
{
if (m_state == state)
return;
m_state = state;
if (window()->isVisible())
updateStatusBarVisibility();
}
void QAndroidOpenGLPlatformWindow::setVisible(bool visible)
{
if (visible)
updateStatusBarVisibility();
QEglFSWindow::setVisible(visible);
// The Android Activity is activated before Qt is initialized, causing the application state to

View File

@ -66,16 +66,19 @@ public:
void invalidateSurface();
void resetSurface();
void setWindowState(Qt::WindowState state);
void setVisible(bool visible);
void destroy();
static void updateStaticNativeWindow();
void updateStatusBarVisibility();
private:
QSize m_scheduledResize;
QMutex m_lock;
Qt::WindowState m_state;
static QReadWriteLock m_staticSurfaceLock;
static EGLSurface m_staticSurface;

View File

@ -61,6 +61,7 @@
# include "androidjnimenu.h"
# include "qandroidopenglcontext.h"
# include "qandroidopenglplatformwindow.h"
# include "qandroidopenglplatformscreen.h"
# include "qeglfshooks.h"
# include <QtGui/qopenglcontext.h>
#endif
@ -141,7 +142,10 @@ QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(Q
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
{
return new QAndroidPlatformWindow(window);
QAndroidPlatformWindow *platformWindow = new QAndroidPlatformWindow(window);
platformWindow->setWindowState(window->windowState());
return platformWindow;
}
QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const
@ -154,6 +158,7 @@ QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *wind
QAndroidOpenGLPlatformWindow *platformWindow = new QAndroidOpenGLPlatformWindow(window);
platformWindow->create();
platformWindow->requestActivateWindow();
platformWindow->setWindowState(window->windowState());
QtAndroidMenu::setActiveTopLevelWindow(window);
return platformWindow;
@ -230,7 +235,7 @@ QPlatformServices *QAndroidPlatformIntegration::services() const
QVariant QAndroidPlatformIntegration::styleHint(StyleHint hint) const
{
switch (hint) {
case ShowIsFullScreen:
case ShowIsMaximized:
return true;
default:
return QPlatformIntegration::styleHint(hint);
@ -307,6 +312,11 @@ void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
m_defaultPhysicalSizeHeight = height;
}
QEglFSScreen *QAndroidPlatformIntegration::createScreen() const
{
return new QAndroidOpenGLPlatformScreen(display());
}
#endif
void QAndroidPlatformIntegration::pauseApp()

View File

@ -140,6 +140,10 @@ public:
QTouchDevice *touchDevice() const { return m_touchDevice; }
void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; }
#ifdef ANDROID_PLUGIN_OPENGL
QEglFSScreen *createScreen() const;
#endif
private:
friend class QEglFSAndroidHooks;

View File

@ -43,6 +43,7 @@
#include "qandroidplatformintegration.h"
#include "androidjnimain.h"
#include "androidjnimenu.h"
#include "qandroidplatformwindow.h"
QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen()
{
@ -57,6 +58,12 @@ QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen()
void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
{
QtAndroidMenu::setActiveTopLevelWindow(w);
if (w != 0) {
QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
if (platformWindow != 0)
platformWindow->updateStatusBarVisibility();
}
}
QRegion QAndroidPlatformScreen::doRedraw()

View File

@ -44,7 +44,9 @@
#include "androidjnimain.h"
#include <qpa/qwindowsysteminterface.h>
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window)
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
: QFbWindow(window)
, m_state(Qt::WindowNoState)
{
}
@ -58,8 +60,41 @@ void QAndroidPlatformWindow::propagateSizeHints()
//shut up warning from default implementation
}
void QAndroidPlatformWindow::updateStatusBarVisibility()
{
Qt::WindowFlags flags = window()->flags();
bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
if (!isNonRegularWindow) {
if (m_state & Qt::WindowFullScreen)
QtAndroid::hideStatusBar();
else if (m_state & Qt::WindowMaximized)
QtAndroid::showStatusBar();
}
}
void QAndroidPlatformWindow::raise()
{
updateStatusBarVisibility();
QFbWindow::raise();
}
void QAndroidPlatformWindow::setWindowState(Qt::WindowState state)
{
if (m_state == state)
return;
m_state = state;
if (window()->isVisible())
updateStatusBarVisibility();
QFbWindow::setWindowState(state);
}
void QAndroidPlatformWindow::setVisible(bool visible)
{
if (visible)
updateStatusBarVisibility();
QFbWindow::setVisible(visible);
// The Android Activity is activated before Qt is initialized, causing the application state to

View File

@ -52,11 +52,16 @@ public:
void propagateSizeHints();
void raise();
void setWindowState(Qt::WindowState state);
void setVisible(bool visible);
void updateStatusBarVisibility();
public slots:
void setGeometry(const QRect &rect);
private:
Qt::WindowState m_state;
};
#endif // ANDROIDPLATFORMWINDOW_H

View File

@ -165,7 +165,7 @@ void QEglFSIntegration::initialize()
qFatal("EGL error");
}
mScreen = new QEglFSScreen(mDisplay);
mScreen = createScreen();
screenAdded(mScreen);
mInputContext = QPlatformInputContextFactory::create();
@ -173,6 +173,11 @@ void QEglFSIntegration::initialize()
createInputHandlers();
}
QEglFSScreen *QEglFSIntegration::createScreen() const
{
return new QEglFSScreen(mDisplay);
}
QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
switch (hint)

View File

@ -86,6 +86,9 @@ public:
QPlatformInputContext *inputContext() const { return mInputContext; }
protected:
virtual QEglFSScreen *createScreen() const;
private:
void createInputHandlers();

View File

@ -126,26 +126,34 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface)
void QEglFSScreen::addWindow(QEglFSWindow *window)
{
if (!m_windows.contains(window))
if (!m_windows.contains(window)) {
m_windows.append(window);
topWindowChanged(window);
}
}
void QEglFSScreen::removeWindow(QEglFSWindow *window)
{
m_windows.removeOne(window);
if (!m_windows.isEmpty())
topWindowChanged(m_windows.last());
}
void QEglFSScreen::moveToTop(QEglFSWindow *window)
{
m_windows.removeOne(window);
m_windows.append(window);
topWindowChanged(window);
}
void QEglFSScreen::changeWindowIndex(QEglFSWindow *window, int newIdx)
{
int idx = m_windows.indexOf(window);
if (idx != -1 && idx != newIdx)
if (idx != -1 && idx != newIdx) {
m_windows.move(idx, newIdx);
if (newIdx == m_windows.size() - 1)
topWindowChanged(m_windows.last());
}
}
QEglFSWindow *QEglFSScreen::rootWindow()
@ -157,4 +165,9 @@ QEglFSWindow *QEglFSScreen::rootWindow()
return 0;
}
void QEglFSScreen::topWindowChanged(QPlatformWindow *window)
{
Q_UNUSED(window);
}
QT_END_NAMESPACE

View File

@ -85,6 +85,7 @@ public:
protected:
void setPrimarySurface(EGLSurface surface);
virtual void topWindowChanged(QPlatformWindow *window);
private:
friend class QEglFSWindow;

View File

@ -7012,6 +7012,8 @@ void QWidget::show()
bool isPopup = data->window_flags & Qt::Popup & ~Qt::Window;
if (isWindow() && !isPopup && qApp->styleHints()->showIsFullScreen())
showFullScreen();
else if (isWindow() && !isPopup && QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ShowIsMaximized).toBool())
showMaximized();
else
setVisible(true);
}