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