15#include <QtGui/QWindow>
16#include <qpa/qwindowsysteminterface.h>
18#include "private/qguiapplication_p.h"
19#include "private/qhighdpiscaling_p.h"
21#include <QtCore/QDebug>
29#define DECLARE_DEBUG_VAR(variable)
30 static bool debug_ ## variable()
31 { static bool value = qgetenv("QNX_SCREEN_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
39#undef DECLARE_DEBUG_VAR
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
123 m_firstActivateHandled(
false),
126 qCDebug(lcQpaWindow) <<
"window =" << window <<
", size =" << window->size();
132 QVariant windowGroup = window->property(
"qnxInitialWindowGroup");
133 if (!windowGroup.isValid())
134 windowGroup = window->property(
"_q_platform_qnxParentGroup");
136 if (window->type() == Qt::CoverWindow) {
141 }
else if (parent() || windowGroup.isValid()) {
144 m_isTopLevel =
false;
151 QVariant type = window->property(
"_q_platform_qnxWindowType");
152 if (type.isValid() && type.canConvert<
int>()) {
154 screen_create_window_type(&m_window, m_screenContext, type.value<
int>()),
155 "Could not create window");
156 }
else if (m_isTopLevel) {
158 "Could not create top level window");
159 if (window->type() != Qt::CoverWindow) {
165 screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW),
166 "Could not create child window");
174 QVariant windowId = window->property(
"qnxWindowId");
175 if (!windowId.isValid())
176 windowId = window->property(
"_q_platform_qnxWindowId");
177 if (windowId.isValid() && windowId.canConvert<QByteArray>()) {
178 QByteArray id = windowId.toByteArray();
180 id.size(), id),
"Failed to set id");
185 if (windowGroup.isValid() && windowGroup.canConvert<QByteArray>())
186 joinWindowGroup(windowGroup.toByteArray());
188 QVariant pipelineValue = window->property(
"_q_platform_qnxPipeline");
189 if (pipelineValue.isValid()) {
191 int pipeline = pipelineValue.toInt(&ok);
193 qCDebug(lcQpaWindow) <<
"Set pipeline value to" << pipeline;
196 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_PIPELINE, &pipeline),
197 "Failed to set window pipeline");
199 qCDebug(lcQpaWindow) <<
"Invalid pipeline value:" << pipelineValue;
206 switch (window->type()) {
209 m_desktopNotify = DesktopNotifyPosition | DesktopNotifyVisible;
213 m_desktopNotify = DesktopNotifyTitle | DesktopNotifyVisible;
219 screen_manage_window(m_window,
220 (m_desktopNotify & DesktopNotifyTitle) ?
"Frame=Y" :
"Frame=N");
224 if (Q_UNLIKELY(debug_fps())) {
225 debug |= SCREEN_DEBUG_GRAPH_FPS;
227 if (Q_UNLIKELY(debug_posts())) {
228 debug |= SCREEN_DEBUG_GRAPH_POSTS;
230 if (Q_UNLIKELY(debug_blits())) {
231 debug |= SCREEN_DEBUG_GRAPH_BLITS;
233 if (Q_UNLIKELY(debug_updates())) {
234 debug |= SCREEN_DEBUG_GRAPH_UPDATES;
236 if (Q_UNLIKELY(debug_cpu_time())) {
237 debug |= SCREEN_DEBUG_GRAPH_CPU_TIME;
239 if (Q_UNLIKELY(debug_gpu_time())) {
240 debug |= SCREEN_DEBUG_GRAPH_GPU_TIME;
242 if (Q_UNLIKELY(debug_statistics())) {
243 debug = SCREEN_DEBUG_STATISTICS;
247 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_DEBUG, &debug),
248 "Could not set SCREEN_PROPERTY_DEBUG");
249 qCDebug(lcQpaWindow) <<
"window SCREEN_PROPERTY_DEBUG= " << debug;
264 , m_isTopLevel(
false)
266 qCDebug(lcQpaWindow) <<
"window =" << window <<
", size =" << window->size();
268 collectWindowGroup();
270 screen_get_window_property_cv(m_window,
271 SCREEN_PROPERTY_PARENT,
272 m_parentGroupName.size(),
273 m_parentGroupName.data());
274 m_parentGroupName.resize(strlen(m_parentGroupName.constData()));
278 QVariant parentGroup = window->property(
"qnxInitialWindowGroup");
279 if (!parentGroup.isValid())
280 parentGroup = window->property(
"_q_platform_qnxParentGroup");
281 if (parentGroup.isValid() && parentGroup.canConvert<QByteArray>())
282 joinWindowGroup(parentGroup.toByteArray());
287 qCDebug(lcQpaWindow) <<
"window =" << window();
290 Q_ASSERT(m_childWindows.size() == 0);
303 removeContextPermission();
305 screen_destroy_window(m_window);
310 QRect newGeometry = rect;
311 if (shouldMakeFullScreen())
312 newGeometry = screen()->geometry();
314 setGeometryHelper(newGeometry);
317 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
320void QQnxWindow::setGeometryHelper(
const QRect &rect)
322 qCDebug(lcQpaWindow) <<
"window =" << window()
323 <<
", (" << rect.x() <<
"," << rect.y()
324 <<
"," << rect.width() <<
"," << rect.height() <<
")";
327 QPlatformWindow::setGeometry(rect);
332 if (m_desktopNotify & DesktopNotifyPosition) {
333 notifyManager(QString::asprintf(
"Pos=%d,%d", rect.x(), rect.y()));
337 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
338 "Failed to set window position");
341 val[0] = rect.width();
342 val[1] = rect.height();
344 "Failed to set window size");
347 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val),
348 "Failed to set window source size");
350 screen_flush_context(m_screenContext, 0);
352 QWindowSystemInterface::handleGeometryChange(window(), rect);
357 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"visible =" << visible;
359 if (m_visible == visible)
363 if (m_parentGroupName.isNull() && !m_isTopLevel) {
364 joinWindowGroup(parent() ?
static_cast<QQnxWindow*>(parent())->groupName()
365 : QByteArray(m_screen->windowGroupName()));
371 while (root->m_parentWindow)
372 root = root->m_parentWindow;
374 root->updateVisibility(root->m_visible);
376 const QSize windowSize = QHighDpi::toNativePixels(window()->geometry().size(), window());
377 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), windowSize));
382 if (showWithoutActivating() && focusable() && m_firstActivateHandled) {
383 m_firstActivateHandled =
false;
384 int val = SCREEN_SENSITIVITY_NO_FOCUS;
386 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
387 "Failed to set window sensitivity");
391 screen_flush_context(m_screenContext, 0);
395void QQnxWindow::updateVisibility(
bool parentVisible)
397 qCDebug(lcQpaWindow) <<
"parentVisible =" << parentVisible <<
"window =" << window();
399 int val = (m_visible && parentVisible) ? 1 : 0;
400 if (m_desktopNotify & DesktopNotifyVisible) {
401 notifyManager(QString(
"Visible=") + (val ?
"Y" :
"N"));
403 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val),
404 "Failed to set window visibility");
407 Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
408 childWindow->updateVisibility(m_visible && parentVisible);
413 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"opacity =" << level;
415 int val = (
int)(level * 255);
416 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val),
417 "Failed to set global alpha");
419 screen_flush_context(m_screenContext, 0);
424 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"expose =" << exposed;
426 if (m_exposed != exposed) {
428 const QSize windowSize = QHighDpi::toNativePixels(window()->geometry().size(), window());
429 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), windowSize));
435 return m_visible && m_exposed;
440 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"size =" << size;
443 const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size;
446 if (nonEmptySize == m_bufferSize || format == -1)
450 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, &format),
451 "Failed to set window format");
453 int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
454 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
455 "Failed to set window buffer size");
457 if (m_bufferSize.isValid()) {
458 m_bufferSize = nonEmptySize;
464 "Failed to create window buffers");
469 screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
470 "Failed to query render buffer count");
473 qFatal(
"QQnxWindow: invalid buffer count. Expected = %d, got = %d.",
480 if (size.isEmpty()) {
484 val[0] = SCREEN_TRANSPARENCY_DISCARD;
485 }
else if (window()->requestedFormat().alphaBufferSize() == 0) {
488 val[0] = SCREEN_TRANSPARENCY_NONE;
494 val[0] = SCREEN_TRANSPARENCY_SOURCE_OVER;
497 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val),
498 "Failed to set window transparency");
501 m_bufferSize = nonEmptySize;
507 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"platformScreen =" << platformScreen;
509 if (platformScreen == 0) {
511 Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
512 childWindow->setScreen(0);
517 if (m_screen == platformScreen)
521 qCDebug(lcQpaWindow) <<
"Moving window to different screen";
525 screen_leave_window_group(m_window);
529 m_screen = platformScreen;
530 if (!m_parentWindow) {
535 screen_display_t display = platformScreen->nativeDisplay();
537 screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (
void **)&display),
538 "Failed to set window display");
540 Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
542 if (window()->type() == Qt::SubWindow || window()->type() == Qt::ToolTip)
543 childWindow->setScreen(platformScreen);
552 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"window =" << window();
554 if (m_parentWindow) {
555 if (Q_UNLIKELY(!m_parentWindow->m_childWindows.removeAll(
this)))
556 qFatal(
"QQnxWindow: Window Hierarchy broken; window has parent, but parent hasn't got child.");
558 m_parentWindow =
nullptr;
559 }
else if (m_screen) {
566 qCDebug(lcQpaWindow) <<
"window =" <<
this->window() <<
"platformWindow =" << window;
570 if (newParent == m_parentWindow)
573 if (
static_cast<QQnxScreen *>(screen())->rootWindow() ==
this) {
574 qWarning(
"Application window cannot be reparented");
579 m_parentWindow = newParent;
582 if (m_parentWindow) {
583 if (m_parentWindow->m_screen != m_screen)
586 m_parentWindow->m_childWindows.push_back(
this);
587 joinWindowGroup(m_parentWindow->groupName());
590 joinWindowGroup(QByteArray());
598 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"window =" << window();
600 if (m_parentWindow) {
601 m_parentWindow->m_childWindows.removeAll(
this);
602 m_parentWindow->m_childWindows.push_back(
this);
612 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"window =" << window();
614 if (m_parentWindow) {
615 m_parentWindow->m_childWindows.removeAll(
this);
616 m_parentWindow->m_childWindows.push_front(
this);
627 if (QGuiApplication::focusWindow())
628 focusWindow =
static_cast<QQnxWindow*>(QGuiApplication::focusWindow()->handle());
630 if (focusWindow ==
this)
633 if (
static_cast<QQnxScreen *>(screen())->rootWindow() ==
this ||
634 (focusWindow && findWindow(focusWindow->nativeHandle()))) {
637 setFocus(nativeHandle());
642 QList<QQnxWindow*> windowList;
643 while (currentWindow) {
644 auto platformScreen =
static_cast<QQnxScreen *>(screen());
645 windowList.prepend(currentWindow);
647 if (currentWindow == focusWindow)
650 if (currentWindow->parent()){
651 currentWindow =
static_cast<
QQnxWindow*>(currentWindow->parent());
652 }
else if (platformScreen->rootWindow() &&
653 platformScreen->rootWindow()->m_windowGroupName == currentWindow->m_parentGroupName) {
654 currentWindow = platformScreen->rootWindow();
656 currentWindow =
nullptr;
661 for (
int i = 1; i < windowList.size(); ++i)
662 windowList.at(i-1)->setFocus(windowList.at(i)->nativeHandle());
664 windowList.last()->setFocus(windowList.constLast()->nativeHandle());
667 screen_flush_context(m_screenContext, 0);
670void QQnxWindow::setFocus(screen_window_t newFocusWindow)
672 screen_window_t temporaryFocusWindow =
nullptr;
674 screen_group_t screenGroup = 0;
676 reinterpret_cast<
void **>(&screenGroup)),
677 "Failed to retrieve window group");
679 if (showWithoutActivating() && focusable() && !m_firstActivateHandled) {
680 m_firstActivateHandled =
true;
681 int val = SCREEN_SENSITIVITY_TEST;
683 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
684 "Failed to set window sensitivity");
691 screen_window_t oldFocusWindow =
nullptr;
694 reinterpret_cast<
void **>(&oldFocusWindow)),
695 "Failed to retrieve group focus");
696 if (newFocusWindow == oldFocusWindow) {
698 memset(groupName, 0,
sizeof(groupName));
700 sizeof(groupName) - 1, groupName),
701 "Failed to retrieve group name");
704 m_screenContext, SCREEN_CHILD_WINDOW),
705 "Failed to create temporary focus window");
707 "Temporary focus window failed to join window group");
710 reinterpret_cast<
void **>(&temporaryFocusWindow)),
711 "Temporary focus window failed to take focus");
712 screen_flush_context(m_screenContext, 0);
718 reinterpret_cast<
void **>(&newFocusWindow)),
719 "Failed to set group focus");
721 screen_destroy_window(temporaryFocusWindow);
726 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"state =" << state;
729 if (m_windowState == state)
732 m_windowState = state;
751 if (m_window == windowHandle)
754 Q_FOREACH (QQnxWindow *window, m_childWindows) {
755 QQnxWindow *
const result = window->findWindow(windowHandle);
765 qWarning(
"Qt::WindowMinimized is not supported by this OS version");
770 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"angle =" << rotation;
772 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation),
773 "Failed to set window rotation");
779 int val = SCREEN_PRE_MULTIPLIED_ALPHA;
780 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val),
781 "Failed to set alpha mode");
786 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val),
787 "Failed to set swap interval");
789 if (showWithoutActivating() || !focusable()) {
794 val = SCREEN_SENSITIVITY_NO_FOCUS;
796 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
797 "Failed to set window sensitivity");
803 if (window()->type() == Qt::CoverWindow)
810 setWindowState(window()->windowState());
811 setOpacity(window()->opacity());
813 if (window()->parent() && window()->parent()->handle())
814 setParent(window()->parent()->handle());
816 setGeometryHelper(shouldMakeFullScreen()
817 ? screen()->geometry()
818 : QHighDpi::toNativePixels(window()->geometry(), window()));
823 QByteArray groupName(256, 0);
825 SCREEN_PROPERTY_GROUP,
828 "Failed to retrieve window group");
829 groupName.resize(strlen(groupName.constData()));
830 m_windowGroupName = groupName;
836 "Failed to create window group");
838 collectWindowGroup();
843 bool changed =
false;
845 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"group:" << groupName;
855 if (m_foreign && !m_parentGroupName.isEmpty())
856 addContextPermission();
858 if (!groupName.isEmpty()) {
859 if (groupName != m_parentGroupName) {
860 screen_join_window_group(m_window, groupName);
861 m_parentGroupName = groupName;
865 if (!m_parentGroupName.isEmpty()) {
866 screen_leave_window_group(m_window);
873 m_parentGroupName =
"";
876 if (m_foreign && !groupName.isEmpty())
877 removeContextPermission();
880 screen_flush_context(m_screenContext, 0);
885 updateZorder(m_window, topZorder);
887 Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
888 childWindow->updateZorder(topZorder);
891void QQnxWindow::updateZorder(screen_window_t window,
int &topZorder)
893 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder),
894 "Failed to set window z-order");
900 if (m_windowState & Qt::WindowMinimized) {
903 if (m_unmaximizedGeometry.isValid())
904 setGeometry(m_unmaximizedGeometry);
906 setGeometry(m_screen->geometry());
907 }
else if (m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen)) {
908 m_unmaximizedGeometry = geometry();
909 setGeometry(m_windowState & Qt::WindowFullScreen ? m_screen->geometry()
910 : m_screen->availableGeometry());
911 }
else if (m_unmaximizedGeometry.isValid()) {
912 setGeometry(m_unmaximizedGeometry);
919 m_cover->updateCover();
928 return ((
static_cast<QQnxScreen *>(screen())->rootWindow() ==
this)
929 && (QQnxIntegration::instance()->options() & QQnxIntegration::FullScreenApplication));
935 if (showWithoutActivating() && focusable() && !m_firstActivateHandled)
941 return (window()->flags() & Qt::Popup) == Qt::Popup
942 || window()->property(
"_q_showWithoutActivating").toBool();
947 return (window()->flags() & Qt::WindowDoesNotAcceptFocus) != Qt::WindowDoesNotAcceptFocus;
952 QByteArray grantString(
"context:");
954 grantString.append(
":rw-");
955 screen_set_window_property_cv(m_window,
956 SCREEN_PROPERTY_PERMISSIONS,
957 grantString.length(),
963 if (m_desktopNotify & DesktopNotifyTitle) {
964 QString titleStr =
"Title=" + title;
965 notifyManager(titleStr);
969void QQnxWindow::notifyManager(
const QString &msg)
972 screen_create_event(&ev);
974 std::string str = msg.toStdString();
975 screen_set_event_property_iv(ev, SCREEN_PROPERTY_TYPE,
976 (
const int[]){ SCREEN_EVENT_MANAGER });
977 screen_set_event_property_cv(ev, SCREEN_PROPERTY_USER_DATA, str.length(),
979 screen_set_event_property_pv(ev, SCREEN_PROPERTY_WINDOW,
980 reinterpret_cast<
void **>(&m_window));
981 screen_set_event_property_pv(ev, SCREEN_PROPERTY_CONTEXT,
982 reinterpret_cast<
void **>(&m_screenContext));
985 "Failed to send a message to the window manager");
990 QByteArray revokeString(
"context:");
992 revokeString.append(
":---");
993 screen_set_window_property_cv(m_window,
994 SCREEN_PROPERTY_PERMISSIONS,
995 revokeString.length(),
996 revokeString.data());
static QQnxIntegration * instance()
void lowerWindow(QQnxWindow *window)
void raiseWindow(QQnxWindow *window)
void removeWindow(QQnxWindow *child)
void addWindow(QQnxWindow *child)
void setRootWindow(QQnxWindow *)
QQnxWindow * rootWindow() const
The QQnxWindow is the base class of the various classes used as instances of QPlatformWindow in the Q...
void setExposed(bool exposed)
void requestActivateWindow() override
Reimplement to let Qt be able to request activation/focus for a window.
virtual int pixelFormat() const =0
QQnxWindow(QWindow *window, screen_context_t context, screen_window_t screenWindow)
QQnxWindow * findWindow(screen_window_t windowHandle)
void setParent(const QPlatformWindow *window) override
This function is called to enable native child window in QPA.
bool shouldMakeFullScreen() const
void setVisible(bool visible) override
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false.
virtual void resetBuffers()=0
bool isExposed() const override
Returns if this window is exposed in the windowing system.
void raise() override
Reimplement to be able to let Qt raise windows to the top of the desktop.
QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow)
void joinWindowGroup(const QByteArray &groupName)
void propagateSizeHints() override
Reimplement to propagate the size hints of the QWindow.
void setWindowTitle(const QString &title)
Reimplement to set the window title to title.
void setScreen(QQnxScreen *platformScreen)
void setBufferSize(const QSize &size)
void setWindowState(Qt::WindowStates state) override
Requests setting the window state of this surface to type.
QPlatformScreen * screen() const override
Returns the platform screen handle corresponding to this platform window, or null if the window is no...
void setRotation(int rotation)
void handleActivationEvent()
void lower() override
Reimplement to be able to let Qt lower windows to the bottom of the desktop.
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
void setOpacity(qreal level) override
Reimplement to be able to let Qt set the opacity level of a window.
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
#define Q_SCREEN_CRITICALERROR(x, message)
#define Q_SCREEN_CHECKERROR(x, message)
void qqnxLgmonFramePosted(bool)
const int SCREEN_PROPERTY_FOCUS
#define _SCREEN_MAKE_VERSION(major, minor, patch)
#define DECLARE_DEBUG_VAR(variable)