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")
60
61Q_DECLARE_JNI_CLASS(DisplayMode, "android/view/Display$Mode")
62
65{
66 m_availableGeometry = QAndroidPlatformIntegration::m_defaultAvailableGeometry;
67 m_size = QAndroidPlatformIntegration::m_defaultScreenSize;
68 m_physicalSize = QAndroidPlatformIntegration::m_defaultPhysicalSize;
69
70 // Raster only apps should set QT_ANDROID_RASTER_IMAGE_DEPTH to 16
71 // is way much faster than 32
72 if (qEnvironmentVariableIntValue("QT_ANDROID_RASTER_IMAGE_DEPTH") == 16) {
73 m_format = QImage::Format_RGB16;
74 m_depth = 16;
75 } else {
77 m_depth = 32;
78 }
79
81 &QAndroidPlatformScreen::applicationStateChanged);
82
83 if (!displayObject.isValid())
84 return;
85
86 m_name = displayObject.callObjectMethod<jstring>("getName").toString();
87 m_refreshRate = displayObject.callMethod<jfloat>("getRefreshRate");
88 m_displayId = displayObject.callMethod<jint>("getDisplayId");
89
90 const QJniObject context = QNativeInterface::QAndroidApplication::context();
91 const auto displayContext = context.callMethod<QtJniTypes::Context>("createDisplayContext",
92 displayObject.object<QtJniTypes::Display>());
93
94 const auto sizeObj = QtJniTypes::QtDisplayManager::callStaticMethod<QtJniTypes::Size>(
95 "getDisplaySize", displayContext,
96 displayObject.object<QtJniTypes::Display>());
97 m_size = QSize(sizeObj.callMethod<int>("getWidth"), sizeObj.callMethod<int>("getHeight"));
98
99 const auto resources = displayContext.callMethod<QtJniTypes::Resources>("getResources");
100 const auto metrics = resources.callMethod<QtJniTypes::DisplayMetrics>("getDisplayMetrics");
101 const float xdpi = metrics.getField<float>("xdpi");
102 const float ydpi = metrics.getField<float>("ydpi");
103
104 // Potentially densityDpi could be used instead of xpdi/ydpi to do the calculation,
105 // but the results are not consistent with devices specs.
106 // (https://issuetracker.google.com/issues/194120500)
107 m_physicalSize.setWidth(qRound(m_size.width() / xdpi * 25.4));
108 m_physicalSize.setHeight(qRound(m_size.height() / ydpi * 25.4));
109
110 if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) {
111 const QJniObject currentMode = displayObject.callObjectMethod<QtJniTypes::DisplayMode>("getMode");
112 m_currentMode = currentMode.callMethod<jint>("getModeId");
113
114 const QJniObject supportedModes = displayObject.callObjectMethod<QtJniTypes::DisplayMode[]>(
115 "getSupportedModes");
116 const auto modeArray = jobjectArray(supportedModes.object());
117
118 QJniEnvironment env;
119 const auto size = env->GetArrayLength(modeArray);
120 for (jsize i = 0; i < size; ++i) {
121 const auto mode = QJniObject::fromLocalRef(env->GetObjectArrayElement(modeArray, i));
122 m_modes << QPlatformScreen::Mode {
123 .size = QSize { mode.callMethod<jint>("getPhysicalWidth"),
124 mode.callMethod<jint>("getPhysicalHeight") },
125 .refreshRate = mode.callMethod<jfloat>("getRefreshRate")
126 };
127 }
128 }
129}
130
134
136{
138 Qt::WindowType type = w->window()->type();
139 if (w->window()->isVisible() &&
140 (type == Qt::Window || type == Qt::Popup || type == Qt::Dialog)) {
141 return w->window();
142 }
143 }
144 return nullptr;
145}
146
148{
150 if (w->geometry().contains(p, false) && w->window()->isVisible())
151 return w->window();
152 }
153 return 0;
154}
155
157{
158 if (window->parent() && window->isRaster())
159 return;
160
162 return;
163
165 QtAndroid::qtActivityDelegate().callMethod<void>("addTopLevelWindow", window->nativeWindow());
166
167 if (window->window()->isVisible())
169}
170
172{
174
176 qWarning() << "Failed to remove window";
177
178 QtAndroid::qtActivityDelegate().callMethod<void>("removeTopLevelWindow", window->nativeViewId());
179
181}
182
184{
186 if (index < 0)
187 return;
188 if (index > 0) {
190 QtAndroid::qtActivityDelegate().callMethod<void>("bringChildToFront", window->nativeViewId());
191 }
193}
194
196{
198 if (index == -1 || index == (m_windowStack.size() - 1))
199 return;
201 QtAndroid::qtActivityDelegate().callMethod<void>("bringChildToBack", window->nativeViewId());
202
204}
205
210
216
218 const QRect &availableGeometry)
219{
220 // The goal of this method is to set all geometry-related parameters
221 // at the same time and generate only one screen geometry change event.
223 m_size = size;
224 // If available geometry has changed, the event will be handled in
225 // setAvailableGeometry. Otherwise we need to explicitly handle it to
226 // retain the behavior, because setSize() does the handling unconditionally.
229 } else {
231 this->availableGeometry());
232 }
233}
234
236{
237 return m_displayId;
238}
239
247
252
254{
256 return;
257
258 QRect oldGeometry = m_availableGeometry;
259
263
264 if (oldGeometry.width() == 0 && oldGeometry.height() == 0 && rect.width() > 0 && rect.height() > 0) {
265 QList<QWindow *> windows = QGuiApplication::allWindows();
266 for (int i = 0; i < windows.size(); ++i) {
267 QWindow *w = windows.at(i);
268 if (w->handle()) {
269 QRect geometry = w->handle()->geometry();
270 if (geometry.width() > 0 && geometry.height() > 0)
272 }
273 }
274 }
275}
276
277void QAndroidPlatformScreen::applicationStateChanged(Qt::ApplicationState state)
278{
279 for (QAndroidPlatformWindow *w : std::as_const(m_windowStack))
280 w->applicationStateChanged(state);
281}
282
284{
288 if (w && w->handle()) {
289 QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
290 if (platformWindow)
291 platformWindow->updateSystemUiVisibility();
292 }
293}
294
295static const int androidLogicalDpi = 72;
296
298{
300 return QDpi(lDpi, lDpi);
301}
302
307
309{
310 return QAndroidPlatformIntegration::m_orientation;
311}
312
314{
315 return QAndroidPlatformIntegration::m_nativeOrientation;
316}
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)
QtJniTypes::QtActivityDelegateBase qtActivityDelegate()
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