1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
4 ** Copyright (C) 2016 The Qt Company Ltd.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the plugins of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include "qandroidplatformwindow.h"
42 #include "qandroidplatformopenglcontext.h"
43 #include "qandroidplatformscreen.h"
44 
45 #include "androidjnimain.h"
46 
47 #include <qguiapplication.h>
48 #include <qpa/qwindowsysteminterface.h>
49 #include <private/qhighdpiscaling_p.h>
50 
51 QT_BEGIN_NAMESPACE
52 
53 static QBasicAtomicInt winIdGenerator = Q_BASIC_ATOMIC_INITIALIZER(0);
54 
QAndroidPlatformWindow(QWindow * window)55 QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
56     : QPlatformWindow(window)
57 {
58     m_windowFlags = Qt::Widget;
59     m_windowState = Qt::WindowNoState;
60     m_windowId = winIdGenerator.fetchAndAddRelaxed(1) + 1;
61     setWindowState(window->windowStates());
62 
63     const bool forceMaximize = m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen);
64     const QRect requestedGeometry = forceMaximize ? QRect() : window->geometry();
65     const QRect availableGeometry = (window->parent()) ? window->parent()->geometry() : platformScreen()->availableGeometry();
66     const QRect finalGeometry = QPlatformWindow::initialGeometry(window, requestedGeometry,
67                                                                  availableGeometry.width(), availableGeometry.height());
68 
69    if (requestedGeometry != finalGeometry)
70        setGeometry(QHighDpi::toNativePixels(finalGeometry, window));
71 }
72 
lower()73 void QAndroidPlatformWindow::lower()
74 {
75     platformScreen()->lower(this);
76 }
77 
raise()78 void QAndroidPlatformWindow::raise()
79 {
80     updateStatusBarVisibility();
81     platformScreen()->raise(this);
82 }
83 
setGeometry(const QRect & rect)84 void QAndroidPlatformWindow::setGeometry(const QRect &rect)
85 {
86     QPlatformWindow::setGeometry(rect);
87     QWindowSystemInterface::handleGeometryChange(window(), rect);
88 }
89 
setVisible(bool visible)90 void QAndroidPlatformWindow::setVisible(bool visible)
91 {
92     if (visible)
93         updateStatusBarVisibility();
94 
95     if (visible) {
96         if (m_windowState & Qt::WindowFullScreen)
97             setGeometry(platformScreen()->geometry());
98         else if (m_windowState & Qt::WindowMaximized)
99             setGeometry(platformScreen()->availableGeometry());
100     }
101 
102     if (visible)
103         platformScreen()->addWindow(this);
104     else
105         platformScreen()->removeWindow(this);
106 
107     QRect availableGeometry = screen()->availableGeometry();
108     if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
109         QPlatformWindow::setVisible(visible);
110 }
111 
setWindowState(Qt::WindowStates state)112 void QAndroidPlatformWindow::setWindowState(Qt::WindowStates state)
113 {
114     if (m_windowState == state)
115         return;
116 
117     QPlatformWindow::setWindowState(state);
118     m_windowState = state;
119 
120     if (window()->isVisible())
121         updateStatusBarVisibility();
122 }
123 
setWindowFlags(Qt::WindowFlags flags)124 void QAndroidPlatformWindow::setWindowFlags(Qt::WindowFlags flags)
125 {
126     if (m_windowFlags == flags)
127         return;
128 
129     m_windowFlags = flags;
130 }
131 
windowFlags() const132 Qt::WindowFlags QAndroidPlatformWindow::windowFlags() const
133 {
134     return m_windowFlags;
135 }
136 
setParent(const QPlatformWindow * window)137 void QAndroidPlatformWindow::setParent(const QPlatformWindow *window)
138 {
139     Q_UNUSED(window);
140 }
141 
platformScreen() const142 QAndroidPlatformScreen *QAndroidPlatformWindow::platformScreen() const
143 {
144     return static_cast<QAndroidPlatformScreen *>(window()->screen()->handle());
145 }
146 
propagateSizeHints()147 void QAndroidPlatformWindow::propagateSizeHints()
148 {
149     //shut up warning from default implementation
150 }
151 
requestActivateWindow()152 void QAndroidPlatformWindow::requestActivateWindow()
153 {
154     platformScreen()->topWindowChanged(window());
155 }
156 
updateStatusBarVisibility()157 void QAndroidPlatformWindow::updateStatusBarVisibility()
158 {
159     Qt::WindowFlags flags = window()->flags();
160     bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
161     if (!isNonRegularWindow) {
162         if (m_windowState & Qt::WindowFullScreen)
163             QtAndroid::hideStatusBar();
164         else
165             QtAndroid::showStatusBar();
166     }
167 }
168 
isExposed() const169 bool QAndroidPlatformWindow::isExposed() const
170 {
171     return qApp->applicationState() > Qt::ApplicationHidden
172             && window()->isVisible()
173             && !window()->geometry().isEmpty();
174 }
175 
applicationStateChanged(Qt::ApplicationState)176 void QAndroidPlatformWindow::applicationStateChanged(Qt::ApplicationState)
177 {
178     QRegion region;
179     if (isExposed())
180         region = QRect(QPoint(), geometry().size());
181 
182     QWindowSystemInterface::handleExposeEvent(window(), region);
183     QWindowSystemInterface::flushWindowSystemEvents();
184 }
185 
186 QT_END_NAMESPACE
187