15#include <QtGui/QWindow>
16#include <qpa/qwindowsysteminterface.h>
18#include "private/qguiapplication_p.h"
20#include <QtCore/QDebug>
28#define DECLARE_DEBUG_VAR(variable)
29 static bool debug_ ## variable()
30 { static bool value = qgetenv("QNX_SCREEN_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
38#undef DECLARE_DEBUG_VAR
41
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
122 m_firstActivateHandled(
false),
125 qCDebug(lcQpaWindow) <<
"window =" << window <<
", size =" << window->size();
131 QVariant windowGroup = window->property(
"qnxInitialWindowGroup");
132 if (!windowGroup.isValid())
133 windowGroup = window->property(
"_q_platform_qnxParentGroup");
135 if (window->type() == Qt::CoverWindow) {
140 }
else if (parent() || windowGroup.isValid()) {
143 m_isTopLevel =
false;
150 QVariant type = window->property(
"_q_platform_qnxWindowType");
151 if (type.isValid() && type.canConvert<
int>()) {
153 screen_create_window_type(&m_window, m_screenContext, type.value<
int>()),
154 "Could not create window");
155 }
else if (m_isTopLevel) {
157 "Could not create top level window");
158 if (window->type() != Qt::CoverWindow) {
164 screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW),
165 "Could not create child window");
173 QVariant windowId = window->property(
"qnxWindowId");
174 if (!windowId.isValid())
175 windowId = window->property(
"_q_platform_qnxWindowId");
176 if (windowId.isValid() && windowId.canConvert<QByteArray>()) {
177 QByteArray id = windowId.toByteArray();
179 id.size(), id),
"Failed to set id");
184 if (windowGroup.isValid() && windowGroup.canConvert<QByteArray>())
185 joinWindowGroup(windowGroup.toByteArray());
187 QVariant pipelineValue = window->property(
"_q_platform_qnxPipeline");
188 if (pipelineValue.isValid()) {
190 int pipeline = pipelineValue.toInt(&ok);
192 qCDebug(lcQpaWindow) <<
"Set pipeline value to" << pipeline;
195 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_PIPELINE, &pipeline),
196 "Failed to set window pipeline");
198 qCDebug(lcQpaWindow) <<
"Invalid pipeline value:" << pipelineValue;
205 switch (window->type()) {
208 m_desktopNotify = DesktopNotifyPosition | DesktopNotifyVisible;
212 m_desktopNotify = DesktopNotifyTitle | DesktopNotifyVisible;
218 screen_manage_window(m_window,
219 (m_desktopNotify & DesktopNotifyTitle) ?
"Frame=Y" :
"Frame=N");
223 if (Q_UNLIKELY(debug_fps())) {
224 debug |= SCREEN_DEBUG_GRAPH_FPS;
226 if (Q_UNLIKELY(debug_posts())) {
227 debug |= SCREEN_DEBUG_GRAPH_POSTS;
229 if (Q_UNLIKELY(debug_blits())) {
230 debug |= SCREEN_DEBUG_GRAPH_BLITS;
232 if (Q_UNLIKELY(debug_updates())) {
233 debug |= SCREEN_DEBUG_GRAPH_UPDATES;
235 if (Q_UNLIKELY(debug_cpu_time())) {
236 debug |= SCREEN_DEBUG_GRAPH_CPU_TIME;
238 if (Q_UNLIKELY(debug_gpu_time())) {
239 debug |= SCREEN_DEBUG_GRAPH_GPU_TIME;
241 if (Q_UNLIKELY(debug_statistics())) {
242 debug = SCREEN_DEBUG_STATISTICS;
246 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_DEBUG, &debug),
247 "Could not set SCREEN_PROPERTY_DEBUG");
248 qCDebug(lcQpaWindow) <<
"window SCREEN_PROPERTY_DEBUG= " << debug;
263 , m_isTopLevel(
false)
265 qCDebug(lcQpaWindow) <<
"window =" << window <<
", size =" << window->size();
267 collectWindowGroup();
269 screen_get_window_property_cv(m_window,
270 SCREEN_PROPERTY_PARENT,
271 m_parentGroupName.size(),
272 m_parentGroupName.data());
273 m_parentGroupName.resize(strlen(m_parentGroupName.constData()));
277 QVariant parentGroup = window->property(
"qnxInitialWindowGroup");
278 if (!parentGroup.isValid())
279 parentGroup = window->property(
"_q_platform_qnxParentGroup");
280 if (parentGroup.isValid() && parentGroup.canConvert<QByteArray>())
281 joinWindowGroup(parentGroup.toByteArray());
286 qCDebug(lcQpaWindow) <<
"window =" << window();
289 Q_ASSERT(m_childWindows.size() == 0);
292 QQnxIntegration::instance()->removeWindow(m_window);
302 removeContextPermission();
304 screen_destroy_window(m_window);
309 QRect newGeometry = rect;
310 if (shouldMakeFullScreen())
311 newGeometry = screen()->geometry();
313 setGeometryHelper(newGeometry);
316 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
319void QQnxWindow::setGeometryHelper(
const QRect &rect)
321 qCDebug(lcQpaWindow) <<
"window =" << window()
322 <<
", (" << rect.x() <<
"," << rect.y()
323 <<
"," << rect.width() <<
"," << rect.height() <<
")";
326 QPlatformWindow::setGeometry(rect);
331 if (m_desktopNotify & DesktopNotifyPosition) {
332 notifyManager(QString::asprintf(
"Pos=%d,%d", rect.x(), rect.y()));
336 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
337 "Failed to set window position");
340 val[0] = rect.width();
341 val[1] = rect.height();
343 "Failed to set window size");
346 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val),
347 "Failed to set window source size");
349 screen_flush_context(m_screenContext, 0);
351 QWindowSystemInterface::handleGeometryChange(window(), rect);
356 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"visible =" << visible;
358 if (m_visible == visible)
362 if (m_parentGroupName.isNull() && !m_isTopLevel) {
363 joinWindowGroup(parent() ?
static_cast<QQnxWindow*>(parent())->groupName()
364 : QByteArray(m_screen->windowGroupName()));
370 while (root->m_parentWindow)
371 root = root->m_parentWindow;
373 root->updateVisibility(root->m_visible);
375 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), window()->geometry().size()));
380 if (showWithoutActivating() && focusable() && m_firstActivateHandled) {
381 m_firstActivateHandled =
false;
382 int val = SCREEN_SENSITIVITY_NO_FOCUS;
384 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
385 "Failed to set window sensitivity");
389 screen_flush_context(m_screenContext, 0);
393void QQnxWindow::updateVisibility(
bool parentVisible)
395 qCDebug(lcQpaWindow) <<
"parentVisible =" << parentVisible <<
"window =" << window();
397 int val = (m_visible && parentVisible) ? 1 : 0;
398 if (m_desktopNotify & DesktopNotifyVisible) {
399 notifyManager(QString(
"Visible=") + (val ?
"Y" :
"N"));
401 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val),
402 "Failed to set window visibility");
405 Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
406 childWindow->updateVisibility(m_visible && parentVisible);
411 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"opacity =" << level;
413 int val = (
int)(level * 255);
414 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val),
415 "Failed to set global alpha");
417 screen_flush_context(m_screenContext, 0);
422 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"expose =" << exposed;
424 if (m_exposed != exposed) {
426 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), window()->geometry().size()));
432 return m_visible && m_exposed;
437 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"size =" << size;
440 const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size;
443 if (nonEmptySize == m_bufferSize || format == -1)
447 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, &format),
448 "Failed to set window format");
450 int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
451 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
452 "Failed to set window buffer size");
454 if (m_bufferSize.isValid()) {
455 m_bufferSize = nonEmptySize;
461 "Failed to create window buffers");
466 screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
467 "Failed to query render buffer count");
470 qFatal(
"QQnxWindow: invalid buffer count. Expected = %d, got = %d.",
477 if (size.isEmpty()) {
481 val[0] = SCREEN_TRANSPARENCY_DISCARD;
482 }
else if (window()->requestedFormat().alphaBufferSize() == 0) {
485 val[0] = SCREEN_TRANSPARENCY_NONE;
491 val[0] = SCREEN_TRANSPARENCY_SOURCE_OVER;
494 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val),
495 "Failed to set window transparency");
498 m_bufferSize = nonEmptySize;
504 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"platformScreen =" << platformScreen;
506 if (platformScreen == 0) {
508 Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
509 childWindow->setScreen(0);
514 if (m_screen == platformScreen)
518 qCDebug(lcQpaWindow) <<
"Moving window to different screen";
522 screen_leave_window_group(m_window);
526 m_screen = platformScreen;
527 if (!m_parentWindow) {
532 screen_display_t display = platformScreen->nativeDisplay();
534 screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (
void **)&display),
535 "Failed to set window display");
537 Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
539 if (window()->type() == Qt::SubWindow || window()->type() == Qt::ToolTip)
540 childWindow->setScreen(platformScreen);
549 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"window =" << window();
551 if (m_parentWindow) {
552 if (Q_UNLIKELY(!m_parentWindow->m_childWindows.removeAll(
this)))
553 qFatal(
"QQnxWindow: Window Hierarchy broken; window has parent, but parent hasn't got child.");
555 m_parentWindow =
nullptr;
556 }
else if (m_screen) {
563 qCDebug(lcQpaWindow) <<
"window =" <<
this->window() <<
"platformWindow =" << window;
567 if (newParent == m_parentWindow)
570 if (
static_cast<QQnxScreen *>(screen())->rootWindow() ==
this) {
571 qWarning(
"Application window cannot be reparented");
576 m_parentWindow = newParent;
579 if (m_parentWindow) {
580 if (m_parentWindow->m_screen != m_screen)
583 m_parentWindow->m_childWindows.push_back(
this);
584 joinWindowGroup(m_parentWindow->groupName());
587 joinWindowGroup(QByteArray());
595 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"window =" << window();
597 if (m_parentWindow) {
598 m_parentWindow->m_childWindows.removeAll(
this);
599 m_parentWindow->m_childWindows.push_back(
this);
609 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"window =" << window();
611 if (m_parentWindow) {
612 m_parentWindow->m_childWindows.removeAll(
this);
613 m_parentWindow->m_childWindows.push_front(
this);
624 if (QGuiApplication::focusWindow())
625 focusWindow =
static_cast<QQnxWindow*>(QGuiApplication::focusWindow()->handle());
627 if (focusWindow ==
this)
630 if (
static_cast<QQnxScreen *>(screen())->rootWindow() ==
this ||
631 (focusWindow && findWindow(focusWindow->nativeHandle()))) {
634 setFocus(nativeHandle());
639 QList<QQnxWindow*> windowList;
640 while (currentWindow) {
641 auto platformScreen =
static_cast<QQnxScreen *>(screen());
642 windowList.prepend(currentWindow);
644 if (currentWindow == focusWindow)
647 if (currentWindow->parent()){
648 currentWindow =
static_cast<
QQnxWindow*>(currentWindow->parent());
649 }
else if (platformScreen->rootWindow() &&
650 platformScreen->rootWindow()->m_windowGroupName == currentWindow->m_parentGroupName) {
651 currentWindow = platformScreen->rootWindow();
653 currentWindow =
nullptr;
658 for (
int i = 1; i < windowList.size(); ++i)
659 windowList.at(i-1)->setFocus(windowList.at(i)->nativeHandle());
661 windowList.last()->setFocus(windowList.constLast()->nativeHandle());
664 screen_flush_context(m_screenContext, 0);
667void QQnxWindow::setFocus(screen_window_t newFocusWindow)
669 screen_window_t temporaryFocusWindow =
nullptr;
671 screen_group_t screenGroup = 0;
673 reinterpret_cast<
void **>(&screenGroup)),
674 "Failed to retrieve window group");
676 if (showWithoutActivating() && focusable() && !m_firstActivateHandled) {
677 m_firstActivateHandled =
true;
678 int val = SCREEN_SENSITIVITY_TEST;
680 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
681 "Failed to set window sensitivity");
688 screen_window_t oldFocusWindow =
nullptr;
690 screen_get_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS,
691 reinterpret_cast<
void **>(&oldFocusWindow)),
692 "Failed to retrieve group focus");
693 if (newFocusWindow == oldFocusWindow) {
695 memset(groupName, 0,
sizeof(groupName));
697 sizeof(groupName) - 1, groupName),
698 "Failed to retrieve group name");
701 m_screenContext, SCREEN_CHILD_WINDOW),
702 "Failed to create temporary focus window");
704 "Temporary focus window failed to join window group");
706 screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS,
707 reinterpret_cast<
void **>(&temporaryFocusWindow)),
708 "Temporary focus window failed to take focus");
709 screen_flush_context(m_screenContext, 0);
715 reinterpret_cast<
void **>(&newFocusWindow)),
716 "Failed to set group focus");
718 screen_destroy_window(temporaryFocusWindow);
723 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"state =" << state;
726 if (m_windowState == state)
729 m_windowState = state;
748 if (m_window == windowHandle)
751 Q_FOREACH (QQnxWindow *window, m_childWindows) {
752 QQnxWindow *
const result = window->findWindow(windowHandle);
762 qWarning(
"Qt::WindowMinimized is not supported by this OS version");
767 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"angle =" << rotation;
769 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation),
770 "Failed to set window rotation");
776 int val = SCREEN_PRE_MULTIPLIED_ALPHA;
777 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val),
778 "Failed to set alpha mode");
783 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val),
784 "Failed to set swap interval");
786 if (showWithoutActivating() || !focusable()) {
791 val = SCREEN_SENSITIVITY_NO_FOCUS;
793 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
794 "Failed to set window sensitivity");
800 if (window()->type() == Qt::CoverWindow)
804 QQnxIntegration::instance()->addWindow(m_window, window());
807 setWindowState(window()->windowState());
808 setOpacity(window()->opacity());
810 if (window()->parent() && window()->parent()->handle())
811 setParent(window()->parent()->handle());
813 setGeometryHelper(shouldMakeFullScreen() ? screen()->geometry() : window()->geometry());
818 QByteArray groupName(256, 0);
820 SCREEN_PROPERTY_GROUP,
823 "Failed to retrieve window group");
824 groupName.resize(strlen(groupName.constData()));
825 m_windowGroupName = groupName;
831 "Failed to create window group");
833 collectWindowGroup();
838 bool changed =
false;
840 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"group:" << groupName;
850 if (m_foreign && !m_parentGroupName.isEmpty())
851 addContextPermission();
853 if (!groupName.isEmpty()) {
854 if (groupName != m_parentGroupName) {
855 screen_join_window_group(m_window, groupName);
856 m_parentGroupName = groupName;
860 if (!m_parentGroupName.isEmpty()) {
861 screen_leave_window_group(m_window);
868 m_parentGroupName =
"";
871 if (m_foreign && !groupName.isEmpty())
872 removeContextPermission();
875 screen_flush_context(m_screenContext, 0);
880 updateZorder(m_window, topZorder);
882 Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
883 childWindow->updateZorder(topZorder);
886void QQnxWindow::updateZorder(screen_window_t window,
int &topZorder)
888 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder),
889 "Failed to set window z-order");
895 if (m_windowState & Qt::WindowMinimized) {
898 if (m_unmaximizedGeometry.isValid())
899 setGeometry(m_unmaximizedGeometry);
901 setGeometry(m_screen->geometry());
902 }
else if (m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen)) {
903 m_unmaximizedGeometry = geometry();
904 setGeometry(m_windowState & Qt::WindowFullScreen ? m_screen->geometry()
905 : m_screen->availableGeometry());
906 }
else if (m_unmaximizedGeometry.isValid()) {
907 setGeometry(m_unmaximizedGeometry);
914 m_cover->updateCover();
923 return ((
static_cast<QQnxScreen *>(screen())->rootWindow() ==
this)
924 && (QQnxIntegration::instance()->options() & QQnxIntegration::FullScreenApplication));
930 if (showWithoutActivating() && focusable() && !m_firstActivateHandled)
936 return (window()->flags() & Qt::Popup) == Qt::Popup
937 || window()->property(
"_q_showWithoutActivating").toBool();
942 return (window()->flags() & Qt::WindowDoesNotAcceptFocus) != Qt::WindowDoesNotAcceptFocus;
947 QByteArray grantString(
"context:");
949 grantString.append(
":rw-");
950 screen_set_window_property_cv(m_window,
951 SCREEN_PROPERTY_PERMISSIONS,
952 grantString.length(),
958 if (m_desktopNotify & DesktopNotifyTitle) {
959 QString titleStr =
"Title=" + title;
960 notifyManager(titleStr);
964void QQnxWindow::notifyManager(
const QString &msg)
967 screen_create_event(&ev);
969 std::string str = msg.toStdString();
970 screen_set_event_property_iv(ev, SCREEN_PROPERTY_TYPE,
971 (
const int[]){ SCREEN_EVENT_MANAGER });
972 screen_set_event_property_cv(ev, SCREEN_PROPERTY_USER_DATA, str.length(),
974 screen_set_event_property_pv(ev, SCREEN_PROPERTY_WINDOW,
975 reinterpret_cast<
void **>(&m_window));
976 screen_set_event_property_pv(ev, SCREEN_PROPERTY_CONTEXT,
977 reinterpret_cast<
void **>(&m_screenContext));
980 "Failed to send a message to the window manager");
985 QByteArray revokeString(
"context:");
987 revokeString.append(
":---");
988 screen_set_window_property_cv(m_window,
989 SCREEN_PROPERTY_PERMISSIONS,
990 revokeString.length(),
991 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)
#define _SCREEN_MAKE_VERSION(major, minor, patch)
#define DECLARE_DEBUG_VAR(variable)