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 if (window->type() == Qt::Desktop)
153 QVariant type = window->property(
"_q_platform_qnxWindowType");
154 if (type.isValid() && type.canConvert<
int>()) {
156 screen_create_window_type(&m_window, m_screenContext, type.value<
int>()),
157 "Could not create window");
158 }
else if (m_isTopLevel) {
160 "Could not create top level window");
161 if (window->type() != Qt::CoverWindow) {
167 screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW),
168 "Could not create child window");
176 QVariant windowId = window->property(
"qnxWindowId");
177 if (!windowId.isValid())
178 windowId = window->property(
"_q_platform_qnxWindowId");
179 if (windowId.isValid() && windowId.canConvert<QByteArray>()) {
180 QByteArray id = windowId.toByteArray();
182 id.size(), id),
"Failed to set id");
187 if (windowGroup.isValid() && windowGroup.canConvert<QByteArray>())
188 joinWindowGroup(windowGroup.toByteArray());
190 QVariant pipelineValue = window->property(
"_q_platform_qnxPipeline");
191 if (pipelineValue.isValid()) {
193 int pipeline = pipelineValue.toInt(&ok);
195 qCDebug(lcQpaWindow) <<
"Set pipeline value to" << pipeline;
198 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_PIPELINE, &pipeline),
199 "Failed to set window pipeline");
201 qCDebug(lcQpaWindow) <<
"Invalid pipeline value:" << pipelineValue;
208 switch (window->type()) {
211 m_desktopNotify = DesktopNotifyPosition | DesktopNotifyVisible;
215 m_desktopNotify = DesktopNotifyTitle | DesktopNotifyVisible;
221 screen_manage_window(m_window,
222 (m_desktopNotify & DesktopNotifyTitle) ?
"Frame=Y" :
"Frame=N");
226 if (Q_UNLIKELY(debug_fps())) {
227 debug |= SCREEN_DEBUG_GRAPH_FPS;
229 if (Q_UNLIKELY(debug_posts())) {
230 debug |= SCREEN_DEBUG_GRAPH_POSTS;
232 if (Q_UNLIKELY(debug_blits())) {
233 debug |= SCREEN_DEBUG_GRAPH_BLITS;
235 if (Q_UNLIKELY(debug_updates())) {
236 debug |= SCREEN_DEBUG_GRAPH_UPDATES;
238 if (Q_UNLIKELY(debug_cpu_time())) {
239 debug |= SCREEN_DEBUG_GRAPH_CPU_TIME;
241 if (Q_UNLIKELY(debug_gpu_time())) {
242 debug |= SCREEN_DEBUG_GRAPH_GPU_TIME;
244 if (Q_UNLIKELY(debug_statistics())) {
245 debug = SCREEN_DEBUG_STATISTICS;
249 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_DEBUG, &debug),
250 "Could not set SCREEN_PROPERTY_DEBUG");
251 qCDebug(lcQpaWindow) <<
"window SCREEN_PROPERTY_DEBUG= " << debug;
266 , m_isTopLevel(
false)
268 qCDebug(lcQpaWindow) <<
"window =" << window <<
", size =" << window->size();
270 collectWindowGroup();
272 screen_get_window_property_cv(m_window,
273 SCREEN_PROPERTY_PARENT,
274 m_parentGroupName.size(),
275 m_parentGroupName.data());
276 m_parentGroupName.resize(strlen(m_parentGroupName.constData()));
280 QVariant parentGroup = window->property(
"qnxInitialWindowGroup");
281 if (!parentGroup.isValid())
282 parentGroup = window->property(
"_q_platform_qnxParentGroup");
283 if (parentGroup.isValid() && parentGroup.canConvert<QByteArray>())
284 joinWindowGroup(parentGroup.toByteArray());
289 qCDebug(lcQpaWindow) <<
"window =" << window();
292 Q_ASSERT(m_childWindows.size() == 0);
295 QQnxIntegration::instance()->removeWindow(m_window);
305 removeContextPermission();
307 screen_destroy_window(m_window);
312 QRect newGeometry = rect;
313 if (shouldMakeFullScreen())
314 newGeometry = screen()->geometry();
316 if (window()->type() != Qt::Desktop)
317 setGeometryHelper(newGeometry);
320 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size()));
323void QQnxWindow::setGeometryHelper(
const QRect &rect)
325 qCDebug(lcQpaWindow) <<
"window =" << window()
326 <<
", (" << rect.x() <<
"," << rect.y()
327 <<
"," << rect.width() <<
"," << rect.height() <<
")";
330 QPlatformWindow::setGeometry(rect);
335 if (m_desktopNotify & DesktopNotifyPosition) {
336 notifyManager(QString::asprintf(
"Pos=%d,%d", rect.x(), rect.y()));
340 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
341 "Failed to set window position");
344 val[0] = rect.width();
345 val[1] = rect.height();
347 "Failed to set window size");
350 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val),
351 "Failed to set window source size");
353 screen_flush_context(m_screenContext, 0);
355 QWindowSystemInterface::handleGeometryChange(window(), rect);
360 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"visible =" << visible;
362 if (m_visible == visible || window()->type() == Qt::Desktop)
366 if (m_parentGroupName.isNull() && !m_isTopLevel) {
367 joinWindowGroup(parent() ?
static_cast<QQnxWindow*>(parent())->groupName()
368 : QByteArray(m_screen->windowGroupName()));
374 while (root->m_parentWindow)
375 root = root->m_parentWindow;
377 root->updateVisibility(root->m_visible);
379 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), window()->geometry().size()));
384 if (showWithoutActivating() && focusable() && m_firstActivateHandled) {
385 m_firstActivateHandled =
false;
386 int val = SCREEN_SENSITIVITY_NO_FOCUS;
388 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
389 "Failed to set window sensitivity");
393 screen_flush_context(m_screenContext, 0);
397void QQnxWindow::updateVisibility(
bool parentVisible)
399 qCDebug(lcQpaWindow) <<
"parentVisible =" << parentVisible <<
"window =" << window();
401 int val = (m_visible && parentVisible) ? 1 : 0;
402 if (m_desktopNotify & DesktopNotifyVisible) {
403 notifyManager(QString(
"Visible=") + (val ?
"Y" :
"N"));
405 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val),
406 "Failed to set window visibility");
409 Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
410 childWindow->updateVisibility(m_visible && parentVisible);
415 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"opacity =" << level;
417 int val = (
int)(level * 255);
418 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val),
419 "Failed to set global alpha");
421 screen_flush_context(m_screenContext, 0);
426 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"expose =" << exposed;
428 if (m_exposed != exposed) {
430 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), window()->geometry().size()));
436 return m_visible && m_exposed;
441 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"size =" << size;
444 const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size;
447 if (nonEmptySize == m_bufferSize || format == -1)
451 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, &format),
452 "Failed to set window format");
454 int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
455 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
456 "Failed to set window buffer size");
458 if (m_bufferSize.isValid()) {
459 m_bufferSize = nonEmptySize;
465 "Failed to create window buffers");
470 screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
471 "Failed to query render buffer count");
474 qFatal(
"QQnxWindow: invalid buffer count. Expected = %d, got = %d.",
481 if (size.isEmpty()) {
485 val[0] = SCREEN_TRANSPARENCY_DISCARD;
486 }
else if (window()->requestedFormat().alphaBufferSize() == 0) {
489 val[0] = SCREEN_TRANSPARENCY_NONE;
495 val[0] = SCREEN_TRANSPARENCY_SOURCE_OVER;
498 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val),
499 "Failed to set window transparency");
502 m_bufferSize = nonEmptySize;
508 qCDebug(lcQpaWindow) <<
"window =" << window() <<
"platformScreen =" << platformScreen;
510 if (platformScreen == 0) {
512 Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
513 childWindow->setScreen(0);
518 if (m_screen == platformScreen)
522 qCDebug(lcQpaWindow) <<
"Moving window to different screen";
526 screen_leave_window_group(m_window);
530 m_screen = platformScreen;
531 if (!m_parentWindow) {
536 screen_display_t display = platformScreen->nativeDisplay();
538 screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (
void **)&display),
539 "Failed to set window display");
541 Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
543 if (window()->type() == Qt::SubWindow || window()->type() == Qt::ToolTip)
544 childWindow->setScreen(platformScreen);
553 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"window =" << window();
555 if (m_parentWindow) {
556 if (Q_UNLIKELY(!m_parentWindow->m_childWindows.removeAll(
this)))
557 qFatal(
"QQnxWindow: Window Hierarchy broken; window has parent, but parent hasn't got child.");
559 m_parentWindow =
nullptr;
560 }
else if (m_screen) {
567 qCDebug(lcQpaWindow) <<
"window =" <<
this->window() <<
"platformWindow =" << window;
571 if (newParent == m_parentWindow)
574 if (
static_cast<QQnxScreen *>(screen())->rootWindow() ==
this) {
575 qWarning(
"Application window cannot be reparented");
580 m_parentWindow = newParent;
583 if (m_parentWindow) {
584 if (m_parentWindow->m_screen != m_screen)
587 m_parentWindow->m_childWindows.push_back(
this);
588 joinWindowGroup(m_parentWindow->groupName());
591 joinWindowGroup(QByteArray());
599 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"window =" << window();
601 if (m_parentWindow) {
602 m_parentWindow->m_childWindows.removeAll(
this);
603 m_parentWindow->m_childWindows.push_back(
this);
613 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"window =" << window();
615 if (m_parentWindow) {
616 m_parentWindow->m_childWindows.removeAll(
this);
617 m_parentWindow->m_childWindows.push_front(
this);
628 if (QGuiApplication::focusWindow())
629 focusWindow =
static_cast<QQnxWindow*>(QGuiApplication::focusWindow()->handle());
631 if (focusWindow ==
this)
634 if (
static_cast<QQnxScreen *>(screen())->rootWindow() ==
this ||
635 (focusWindow && findWindow(focusWindow->nativeHandle()))) {
638 setFocus(nativeHandle());
643 QList<QQnxWindow*> windowList;
644 while (currentWindow) {
645 auto platformScreen =
static_cast<QQnxScreen *>(screen());
646 windowList.prepend(currentWindow);
648 if (currentWindow == focusWindow)
651 if (currentWindow->parent()){
652 currentWindow =
static_cast<
QQnxWindow*>(currentWindow->parent());
653 }
else if (platformScreen->rootWindow() &&
654 platformScreen->rootWindow()->m_windowGroupName == currentWindow->m_parentGroupName) {
655 currentWindow = platformScreen->rootWindow();
657 currentWindow =
nullptr;
662 for (
int i = 1; i < windowList.size(); ++i)
663 windowList.at(i-1)->setFocus(windowList.at(i)->nativeHandle());
665 windowList.last()->setFocus(windowList.constLast()->nativeHandle());
668 screen_flush_context(m_screenContext, 0);
671void QQnxWindow::setFocus(screen_window_t newFocusWindow)
673 screen_window_t temporaryFocusWindow =
nullptr;
675 screen_group_t screenGroup = 0;
677 reinterpret_cast<
void **>(&screenGroup)),
678 "Failed to retrieve window group");
680 if (showWithoutActivating() && focusable() && !m_firstActivateHandled) {
681 m_firstActivateHandled =
true;
682 int val = SCREEN_SENSITIVITY_TEST;
684 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
685 "Failed to set window sensitivity");
692 screen_window_t oldFocusWindow =
nullptr;
694 screen_get_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS,
695 reinterpret_cast<
void **>(&oldFocusWindow)),
696 "Failed to retrieve group focus");
697 if (newFocusWindow == oldFocusWindow) {
699 memset(groupName, 0,
sizeof(groupName));
701 sizeof(groupName) - 1, groupName),
702 "Failed to retrieve group name");
705 m_screenContext, SCREEN_CHILD_WINDOW),
706 "Failed to create temporary focus window");
708 "Temporary focus window failed to join window group");
710 screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS,
711 reinterpret_cast<
void **>(&temporaryFocusWindow)),
712 "Temporary focus window failed to take focus");
713 screen_flush_context(m_screenContext, 0);
719 reinterpret_cast<
void **>(&newFocusWindow)),
720 "Failed to set group focus");
722 screen_destroy_window(temporaryFocusWindow);
727 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"state =" << state;
730 if (m_windowState == state)
733 m_windowState = state;
752 if (m_window == windowHandle)
755 Q_FOREACH (QQnxWindow *window, m_childWindows) {
756 QQnxWindow *
const result = window->findWindow(windowHandle);
766 qWarning(
"Qt::WindowMinimized is not supported by this OS version");
771 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"angle =" << rotation;
773 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation),
774 "Failed to set window rotation");
779 if (window()->type() == Qt::Desktop)
783 int val = SCREEN_PRE_MULTIPLIED_ALPHA;
784 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val),
785 "Failed to set alpha mode");
790 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val),
791 "Failed to set swap interval");
793 if (showWithoutActivating() || !focusable()) {
798 val = SCREEN_SENSITIVITY_NO_FOCUS;
800 screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
801 "Failed to set window sensitivity");
807 if (window()->type() == Qt::CoverWindow)
811 QQnxIntegration::instance()->addWindow(m_window, window());
814 setWindowState(window()->windowState());
815 setOpacity(window()->opacity());
817 if (window()->parent() && window()->parent()->handle())
818 setParent(window()->parent()->handle());
820 setGeometryHelper(shouldMakeFullScreen() ? screen()->geometry() : window()->geometry());
825 QByteArray groupName(256, 0);
827 SCREEN_PROPERTY_GROUP,
830 "Failed to retrieve window group");
831 groupName.resize(strlen(groupName.constData()));
832 m_windowGroupName = groupName;
838 "Failed to create window group");
840 collectWindowGroup();
845 bool changed =
false;
847 qCDebug(lcQpaWindow) << Q_FUNC_INFO <<
"group:" << groupName;
857 if (m_foreign && !m_parentGroupName.isEmpty())
858 addContextPermission();
860 if (!groupName.isEmpty()) {
861 if (groupName != m_parentGroupName) {
862 screen_join_window_group(m_window, groupName);
863 m_parentGroupName = groupName;
867 if (!m_parentGroupName.isEmpty()) {
868 screen_leave_window_group(m_window);
875 m_parentGroupName =
"";
878 if (m_foreign && !groupName.isEmpty())
879 removeContextPermission();
882 screen_flush_context(m_screenContext, 0);
887 updateZorder(m_window, topZorder);
889 Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
890 childWindow->updateZorder(topZorder);
893void QQnxWindow::updateZorder(screen_window_t window,
int &topZorder)
895 Q_SCREEN_CHECKERROR(screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder),
896 "Failed to set window z-order");
902 if (m_windowState & Qt::WindowMinimized) {
905 if (m_unmaximizedGeometry.isValid())
906 setGeometry(m_unmaximizedGeometry);
908 setGeometry(m_screen->geometry());
909 }
else if (m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen)) {
910 m_unmaximizedGeometry = geometry();
911 setGeometry(m_windowState & Qt::WindowFullScreen ? m_screen->geometry()
912 : m_screen->availableGeometry());
913 }
else if (m_unmaximizedGeometry.isValid()) {
914 setGeometry(m_unmaximizedGeometry);
921 m_cover->updateCover();
930 return ((
static_cast<QQnxScreen *>(screen())->rootWindow() ==
this)
931 && (QQnxIntegration::instance()->options() & QQnxIntegration::FullScreenApplication));
937 if (showWithoutActivating() && focusable() && !m_firstActivateHandled)
943 return (window()->flags() & Qt::Popup) == Qt::Popup
944 || window()->property(
"_q_showWithoutActivating").toBool();
949 return (window()->flags() & Qt::WindowDoesNotAcceptFocus) != Qt::WindowDoesNotAcceptFocus;
954 QByteArray grantString(
"context:");
956 grantString.append(
":rw-");
957 screen_set_window_property_cv(m_window,
958 SCREEN_PROPERTY_PERMISSIONS,
959 grantString.length(),
965 if (m_desktopNotify & DesktopNotifyTitle) {
966 QString titleStr =
"Title=" + title;
967 notifyManager(titleStr);
971void QQnxWindow::notifyManager(
const QString &msg)
974 screen_create_event(&ev);
976 std::string str = msg.toStdString();
977 screen_set_event_property_iv(ev, SCREEN_PROPERTY_TYPE,
978 (
const int[]){ SCREEN_EVENT_MANAGER });
979 screen_set_event_property_cv(ev, SCREEN_PROPERTY_USER_DATA, str.length(),
981 screen_set_event_property_pv(ev, SCREEN_PROPERTY_WINDOW,
982 reinterpret_cast<
void **>(&m_window));
983 screen_set_event_property_pv(ev, SCREEN_PROPERTY_CONTEXT,
984 reinterpret_cast<
void **>(&m_screenContext));
987 "Failed to send a message to the window manager");
992 QByteArray revokeString(
"context:");
994 revokeString.append(
":---");
995 screen_set_window_property_cv(m_window,
996 SCREEN_PROPERTY_PERMISSIONS,
997 revokeString.length(),
998 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)