Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qandroidplatformscreen.cpp
Go to the documentation of this file.
1// Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
2// Copyright (C) 2016 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include <QDebug>
6#include <QTime>
7
8#include <qpa/qwindowsysteminterface.h>
9
13#include "androidjnimain.h"
14#include "androidjnimenu.h"
16
17#include <android/bitmap.h>
18#include <android/native_window_jni.h>
19#include <qguiapplication.h>
20
21#include <QtCore/QJniObject>
22#include <QtCore/QJniEnvironment>
23#include <QtGui/QGuiApplication>
24#include <QtGui/QWindow>
25#include <QtGui/private/qwindow_p.h>
26#include <vector>
27
29
30#ifdef QANDROIDPLATFORMSCREEN_DEBUG
31class ScopedProfiler
32{
33public:
34 ScopedProfiler(const QString &msg)
35 {
36 m_msg = msg;
37 m_timer.start();
38 }
39 ~ScopedProfiler()
40 {
41 qDebug() << m_msg << m_timer.elapsed();
42 }
43
44private:
45 QTime m_timer;
46 QString m_msg;
47};
48
49# define PROFILE_SCOPE ScopedProfiler ___sp___(__func__)
50#else
51# define PROFILE_SCOPE
52#endif
53
54Q_DECLARE_JNI_CLASS(Display, "android/view/Display")
55Q_DECLARE_JNI_CLASS(DisplayMetrics, "android/util/DisplayMetrics")
56Q_DECLARE_JNI_CLASS(Resources, "android/content/res/Resources")
57Q_DECLARE_JNI_CLASS(Size, "android/util/Size")
58Q_DECLARE_JNI_CLASS(QtNative, "org/qtproject/qt/android/QtNative")
59Q_DECLARE_JNI_CLASS(QtDisplayManager, "org/qtproject/qt/android/QtDisplayManager")
60Q_DECLARE_JNI_CLASS(QtWindowInterface, "org/qtproject/qt/android/QtWindowInterface")
61
62Q_DECLARE_JNI_CLASS(DisplayMode, "android/view/Display$Mode")
63
66{
67 m_availableGeometry = QAndroidPlatformIntegration::m_defaultAvailableGeometry;
68 m_size = QAndroidPlatformIntegration::m_defaultScreenSize;
69 m_physicalSize = QAndroidPlatformIntegration::m_defaultPhysicalSize;
70
71 // Raster only apps should set QT_ANDROID_RASTER_IMAGE_DEPTH to 16
72 // is way much faster than 32
73 if (qEnvironmentVariableIntValue("QT_ANDROID_RASTER_IMAGE_DEPTH") == 16) {
74 m_format = QImage::Format_RGB16;
75 m_depth = 16;
76 } else {
78 m_depth = 32;
79 }
80
82 &QAndroidPlatformScreen::applicationStateChanged);
83
84 if (!displayObject.isValid())
85 return;
86
87 m_name = displayObject.callObjectMethod<jstring>("getName").toString();
88 m_refreshRate = displayObject.callMethod<jfloat>("getRefreshRate");
89 m_displayId = displayObject.callMethod<jint>("getDisplayId");
90
91 const QJniObject context = QNativeInterface::QAndroidApplication::context();
92 const auto displayContext = context.callMethod<QtJniTypes::Context>("createDisplayContext",
93 displayObject.object<QtJniTypes::Display>());
94
95 const auto sizeObj = QtJniTypes::QtDisplayManager::callStaticMethod<QtJniTypes::Size>(
96 "getDisplaySize", displayContext,
97 displayObject.object<QtJniTypes::Display>());
98 m_size = QSize(sizeObj.callMethod<int>("getWidth"), sizeObj.callMethod<int>("getHeight"));
99
100 const auto resources = displayContext.callMethod<QtJniTypes::Resources>("getResources");
101 const auto metrics = resources.callMethod<QtJniTypes::DisplayMetrics>("getDisplayMetrics");
102 const float xdpi = metrics.getField<float>("xdpi");
103 const float ydpi = metrics.getField<float>("ydpi");
104
105 // Potentially densityDpi could be used instead of xpdi/ydpi to do the calculation,
106 // but the results are not consistent with devices specs.
107 // (https://issuetracker.google.com/issues/194120500)
108 m_physicalSize.setWidth(qRound(m_size.width() / xdpi * 25.4));
109 m_physicalSize.setHeight(qRound(m_size.height() / ydpi * 25.4));
110
111 if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) {
112 const QJniObject currentMode = displayObject.callObjectMethod<QtJniTypes::DisplayMode>("getMode");
113 m_currentMode = currentMode.callMethod<jint>("getModeId");
114
115 const QJniObject supportedModes = displayObject.callObjectMethod<QtJniTypes::DisplayMode[]>(
116 "getSupportedModes");
117 const auto modeArray = jobjectArray(supportedModes.object());
118
119 QJniEnvironment env;
120 const auto size = env->GetArrayLength(modeArray);
121 for (jsize i = 0; i < size; ++i) {
122 const auto mode = QJniObject::fromLocalRef(env->GetObjectArrayElement(modeArray, i));
123 m_modes << QPlatformScreen::Mode {
124 .size = QSize { mode.callMethod<jint>("getPhysicalWidth"),
125 mode.callMethod<jint>("getPhysicalHeight") },
126 .refreshRate = mode.callMethod<jfloat>("getRefreshRate")
127 };
128 }
129 }
130}
131
135
137{
139 Qt::WindowType type = w->window()->type();
140 if (w->window()->isVisible() &&
141 (type == Qt::Window || type == Qt::Popup || type == Qt::Dialog)) {
142 return w->window();
143 }
144 }
145 return nullptr;
146}
147
149{
151 if (w->geometry().contains(p, false) && w->window()->isVisible())
152 return w->window();
153 }
154 return 0;
155}
156
158{
159 if (window->parent() && window->isRaster())
160 return;
161
163 return;
164
166
168 reg->callInterface<QtJniTypes::QtWindowInterface, void>("addTopLevelWindow",
169 window->nativeWindow());
170
171 if (window->window()->isVisible())
173}
174
176{
178
180 qWarning() << "Failed to remove window";
181
183 reg->callInterface<QtJniTypes::QtWindowInterface, void>("removeTopLevelWindow",
184 window->nativeViewId());
185
187}
188
190{
192 if (index < 0)
193 return;
194 if (index > 0) {
196
198 reg->callInterface<QtJniTypes::QtWindowInterface, void>("bringChildToFront",
199 window->nativeViewId());
200 }
202}
203
205{
207 if (index == -1 || index == (m_windowStack.size() - 1))
208 return;
210
212 reg->callInterface<QtJniTypes::QtWindowInterface, void>("bringChildToBack",
213 window->nativeViewId());
214
216}
217
222
228
230 const QRect &availableGeometry)
231{
232 // The goal of this method is to set all geometry-related parameters
233 // at the same time and generate only one screen geometry change event.
235 m_size = size;
236 // If available geometry has changed, the event will be handled in
237 // setAvailableGeometry. Otherwise we need to explicitly handle it to
238 // retain the behavior, because setSize() does the handling unconditionally.
241 } else {
243 this->availableGeometry());
244 }
245}
246
248{
249 return m_displayId;
250}
251
259
264
266{
268 return;
269
270 QRect oldGeometry = m_availableGeometry;
271
275
276 if (oldGeometry.width() == 0 && oldGeometry.height() == 0 && rect.width() > 0 && rect.height() > 0) {
277 QList<QWindow *> windows = QGuiApplication::allWindows();
278 for (int i = 0; i < windows.size(); ++i) {
279 QWindow *w = windows.at(i);
280 if (w->handle()) {
281 QRect geometry = w->handle()->geometry();
282 if (geometry.width() > 0 && geometry.height() > 0)
284 }
285 }
286 }
287}
288
289void QAndroidPlatformScreen::applicationStateChanged(Qt::ApplicationState state)
290{
291 for (QAndroidPlatformWindow *w : std::as_const(m_windowStack))
292 w->applicationStateChanged(state);
293}
294
296{
300 if (w && w->handle()) {
301 QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
302 if (platformWindow)
303 platformWindow->updateSystemUiVisibility();
304 }
305}
306
307static const int androidLogicalDpi = 72;
308
310{
312 return QDpi(lDpi, lDpi);
313}
314
319
321{
322 return QAndroidPlatformIntegration::m_orientation;
323}
324
326{
327 return QAndroidPlatformIntegration::m_nativeOrientation;
328}
Qt::ScreenOrientation orientation() const override
Reimplement this function in subclass to return the current orientation of the screen,...
QSizeF physicalSize() const override
Reimplement this function in subclass to return the physical size of the screen, in millimeters.
void lower(QAndroidPlatformWindow *window)
QWindow * topLevelAt(const QPoint &p) const override
Return the given top level window for a given position.
void setSizeParameters(const QSize &physicalSize, const QSize &size, const QRect &availableGeometry)
QDpi logicalBaseDpi() const override
Reimplement to return the base logical DPI for the platform.
QDpi logicalDpi() const override
Reimplement this function in subclass to return the logical horizontal and vertical dots per inch met...
QRect geometry() const override
Reimplement in subclass to return the pixel geometry of the screen.
void raise(QAndroidPlatformWindow *window)
void setPhysicalSize(const QSize &size)
void setAvailableGeometry(const QRect &rect)
void setOrientation(Qt::ScreenOrientation orientation)
QRect availableGeometry() const override
Reimplement in subclass to return the pixel geometry of the available space This normally is the desk...
void removeWindow(QAndroidPlatformWindow *window)
Qt::ScreenOrientation nativeOrientation() const override
Reimplement this function in subclass to return the native orientation of the screen,...
void setSize(const QSize &size)
void setRefreshRate(qreal refreshRate)
qreal refreshRate() const override
Reimplement this function in subclass to return the vertical refresh rate of the screen,...
void addWindow(QAndroidPlatformWindow *window)
static QWindowList allWindows()
Returns a list of all the windows in the application.
void applicationStateChanged(Qt::ApplicationState state)
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
@ Format_RGB16
Definition qimage.h:49
\inmodule QtCore
\inmodule QtCore
qsizetype size() const noexcept
Definition qlist.h:397
bool removeOne(const AT &t)
Definition qlist.h:598
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
void move(qsizetype from, qsizetype to)
Definition qlist.h:610
void prepend(rvalue_ref t)
Definition qlist.h:473
\inmodule QtCore
Definition qobject.h:103
The QPlatformScreen class provides an abstraction for visual displays.
QScreen * screen() const
void resizeMaximizedWindows()
Convenience method to resize all the maximized and fullscreen windows of this platform screen.
QWindowList windows() const
Return all windows residing on this screen.
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore \reentrant
Definition qdatetime.h:215
static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry, const QRect &newAvailableGeometry)
static void handleFocusWindowChanged(QWindow *window, Qt::FocusReason r=Qt::OtherFocusReason)
static bool handleExposeEvent(QWindow *window, const QRegion &region)
static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation)
static void handleScreenRefreshRateChange(QScreen *screen, qreal newRefreshRate)
\inmodule QtGui
Definition qwindow.h:63
rect
[4]
else opt state
[0]
Combined button and popup list for selecting options.
void setActiveTopLevelWindow(QWindow *window)
AndroidBackendRegister * backendRegister()
double pixelDensity()
ScreenOrientation
Definition qnamespace.h:271
ApplicationState
Definition qnamespace.h:262
WindowType
Definition qnamespace.h:205
@ Popup
Definition qnamespace.h:211
@ Window
Definition qnamespace.h:207
@ Dialog
Definition qnamespace.h:208
@ ActiveWindowFocusReason
static void * context
static const int androidLogicalDpi
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
#define qGuiApp
QPair< qreal, qreal > QDpi
#define qDebug
[1]
Definition qlogging.h:164
#define qWarning
Definition qlogging.h:166
GLenum mode
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLenum type
GLuint res
GLfloat GLfloat p
[1]
QT_BEGIN_NAMESPACE Q_DECLARE_JNI_CLASS(Environment, "android/os/Environment")
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
struct _XDisplay Display
double qreal
Definition qtypes.h:187
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
aWidget window() -> setWindowTitle("New Window Title")
[2]
QQuickView * view
[0]
char * toString(const MyType &t)
[31]
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:962
bool contains(const AT &t) const noexcept
Definition qlist.h:45