Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qplatformwindow.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
8
9#include <private/qguiapplication_p.h>
10#include <qpa/qwindowsysteminterface.h>
11#include <QtGui/qwindow.h>
12#include <QtGui/qscreen.h>
13#include <private/qhighdpiscaling_p.h>
14#include <private/qwindow_p.h>
15#include <qpa/qplatformintegration.h>
16
18
19/*!
20 Constructs a platform window with the given top level window.
21*/
22
23QPlatformWindow::QPlatformWindow(QWindow *window)
24 : QPlatformSurface(window)
25 , d_ptr(new QPlatformWindowPrivate)
26{
27 Q_D(QPlatformWindow);
28 d->rect = QHighDpi::toNativePixels(window->geometry(), window);
29}
30
31/*!
32 Virtual destructor does not delete its top level window.
33*/
34QPlatformWindow::~QPlatformWindow()
35{
36}
37
38/*!
39 Called as part of QWindow::create(), after constructing
40 the window. Platforms should prefer to do initialization
41 here instead of in the constructor, as the platform window
42 object will be fully constructed, and associated to the
43 corresponding QWindow, allowing synchronous event delivery.
44*/
45void QPlatformWindow::initialize()
46{
47}
48
49/*!
50 Returns the window which belongs to the QPlatformWindow
51*/
52QWindow *QPlatformWindow::window() const
53{
54 return static_cast<QWindow *>(m_surface);
55}
56
57/*!
58 Returns the parent platform window (or \nullptr if orphan).
59*/
60QPlatformWindow *QPlatformWindow::parent() const
61{
62 return window()->parent() ? window()->parent()->handle() : nullptr;
63}
64
65/*!
66 Returns the platform screen handle corresponding to this platform window,
67 or null if the window is not associated with a screen.
68*/
69QPlatformScreen *QPlatformWindow::screen() const
70{
71 QScreen *scr = window()->screen();
72 return scr ? scr->handle() : nullptr;
73}
74
75/*!
76 Returns the actual surface format of the window.
77*/
78QSurfaceFormat QPlatformWindow::format() const
79{
80 return QSurfaceFormat();
81}
82
83/*!
84 This function is called by Qt whenever a window is moved or resized using the QWindow API.
85
86 Unless you also override QPlatformWindow::geometry(), you need to call the baseclass
87 implementation of this function in any override of QPlatformWindow::setGeometry(), as
88 QWindow::geometry() is expected to report back the set geometry until a confirmation
89 (or rejection) of the new geometry comes back from the window manager and is reported
90 via QWindowSystemInterface::handleGeometryChange().
91
92 Window move/resizes can also be triggered spontaneously by the window manager, or as a
93 response to an earlier requested move/resize via the Qt APIs. There is no need to call
94 this function from the window manager callback, instead call
95 QWindowSystemInterface::handleGeometryChange().
96
97 The position(x, y) part of the rect might be inclusive or exclusive of the window frame
98 as returned by frameMargins(). You can detect this in the plugin by checking
99 qt_window_private(window())->positionPolicy.
100*/
101void QPlatformWindow::setGeometry(const QRect &rect)
102{
103 Q_D(QPlatformWindow);
104 d->rect = rect;
105}
106
107/*!
108 Returns the current geometry of a window
109*/
110QRect QPlatformWindow::geometry() const
111{
112 Q_D(const QPlatformWindow);
113 return d->rect;
114}
115
116/*!
117 Returns the geometry of a window in 'normal' state
118 (neither maximized, fullscreen nor minimized) for saving geometries to
119 application settings.
120
121 \since 5.3
122*/
123QRect QPlatformWindow::normalGeometry() const
124{
125 return QRect();
126}
127
128QMargins QPlatformWindow::frameMargins() const
129{
130 return QMargins();
131}
132
133/*!
134 The safe area margins of a window represent the area that is safe to
135 place content within, without intersecting areas of the screen where
136 system UI is placed, or where a screen bezel may cover the content.
138QMargins QPlatformWindow::safeAreaMargins() const
139{
140 return QMargins();
141}
142
143/*!
144 Reimplemented in subclasses to show the surface
145 if \a visible is \c true, and hide it if \a visible is \c false.
146
147 The default implementation sends a synchronous expose event.
148*/
149void QPlatformWindow::setVisible(bool visible)
150{
151 Q_UNUSED(visible);
152 QRect rect(QPoint(), geometry().size());
153 QWindowSystemInterface::handleExposeEvent(window(), rect);
154 QWindowSystemInterface::flushWindowSystemEvents();
155}
156
157/*!
158 Requests setting the window flags of this surface
159 to \a flags.
160*/
161void QPlatformWindow::setWindowFlags(Qt::WindowFlags flags)
162{
163 Q_UNUSED(flags);
164}
165
166/*!
167 Returns if this window is exposed in the windowing system.
168
169 An exposeEvent() is sent every time this value changes.
170 */
171
172bool QPlatformWindow::isExposed() const
173{
174 return window()->isVisible();
175}
176
177/*!
178 Returns \c true if the window should appear active from a style perspective.
179
180 This function can make platform-specific isActive checks, such as checking
181 if the QWindow is embedded in an active native window.
182*/
183bool QPlatformWindow::isActive() const
184{
185 return false;
186}
187
188/*!
189 Returns \c true if the window is an ancestor of the given \a child.
190
191 Platform overrides should iterate the native window hierarchy of the child,
192 to ensure that ancestary is reflected even with native windows in the window
193 hierarchy.
194*/
195bool QPlatformWindow::isAncestorOf(const QPlatformWindow *child) const
196{
197 for (const QPlatformWindow *parent = child->parent(); parent; parent = parent->parent()) {
198 if (parent == this)
199 return true;
200 }
201
202 return false;
203}
204
205/*!
206 Returns \c true if the window is a child of a non-Qt window.
207
208 A embedded window has no parent platform window as reflected
209 though parent(), but will have a native parent window.
210*/
211bool QPlatformWindow::isEmbedded() const
212{
213 return false;
214}
215
216/*!
217 Translates the window coordinate \a pos to global screen
218 coordinates using native methods. This is required for embedded windows,
219 where the topmost QWindow coordinates are not global screen coordinates.
220
221 Returns \a pos if there is no platform specific implementation.
222*/
223QPoint QPlatformWindow::mapToGlobal(const QPoint &pos) const
224{
225 const QPlatformWindow *p = this;
226 QPoint result = pos;
227 while (p) {
228 result += p->geometry().topLeft();
229 p = p->parent();
230 }
231 return result;
232}
233
234QPointF QPlatformWindow::mapToGlobalF(const QPointF &pos) const
235{
236 const QPoint posPt = pos.toPoint();
237 const QPointF delta = pos - posPt;
238 return mapToGlobal(posPt) + delta;
239}
240
241QPointF QPlatformWindow::mapFromGlobalF(const QPointF &pos) const
242{
243 const QPoint posPt = pos.toPoint();
244 const QPointF delta = pos - posPt;
245 return mapFromGlobal(posPt) + delta;
246}
247
248/*!
249 Translates the global screen coordinate \a pos to window
250 coordinates using native methods. This is required for embedded windows,
251 where the topmost QWindow coordinates are not global screen coordinates.
252
253 Returns \a pos if there is no platform specific implementation.
254*/
255QPoint QPlatformWindow::mapFromGlobal(const QPoint &pos) const
256{
257 const QPlatformWindow *p = this;
258 QPoint result = pos;
259 while (p) {
260 result -= p->geometry().topLeft();
261 p = p->parent();
262 }
263 return result;
264}
265
266/*!
267 Requests setting the window state of this surface
268 to \a type.
269
270 Qt::WindowActive can be ignored.
271*/
272void QPlatformWindow::setWindowState(Qt::WindowStates)
273{
274}
275
276/*!
277 Reimplement in subclasses to return a handle to the native window
278*/
279WId QPlatformWindow::winId() const
280{
281 // Return anything but 0. Returning 0 would cause havoc with QWidgets on
282 // very basic platform plugins that do not reimplement this function,
283 // because the top-level widget's internalWinId() would always be 0 which
284 // would mean top-levels are never treated as native.
285 return WId(1);
286}
287
288/*!
289 This function is called to enable native child window in QPA. It is common not to support this
290 feature in Window systems, but can be faked. When this function is called all geometry of this
291 platform window will be relative to the parent.
292
293 Platforms that override this function should return \c true
294 for QPlatformIntegration::Capability::ChildWindows.
295*/
296void QPlatformWindow::setParent(const QPlatformWindow *parent)
297{
298 Q_UNUSED(parent);
299 Q_ASSERT(!QGuiApplicationPrivate::platformIntegration()->hasCapability(
300 QPlatformIntegration::Capability::ChildWindows));
301 qWarning("This plugin does not support setParent!");
302}
303
304/*!
305 Reimplement to set the window title to \a title.
306
307 The implementation might want to append the application display name to
308 the window title, like Windows and Linux do.
309
310 \l QPlatformWindow::windowTitle() can be used to retrieve the
311 actual window title.
312
313 \sa QGuiApplication::applicationDisplayName()
314 \sa QPlatformWindow::windowTitle()
315*/
316void QPlatformWindow::setWindowTitle(const QString &title) { Q_UNUSED(title); }
317
318/*!
319 Reimplement to return the actual window title used in the underlying
320 windowing system unless the title set for the QWindow which
321 belongs to this QPlatformWindow (i.e. the window returned by
322 \l QPlatformWindow::window) is always used without modification.
323
324 \sa QPlatformWindow::setWindowTitle()
325
326 \since 6.9
327*/
328QString QPlatformWindow::windowTitle() const
329{
330 return window()->title();
331}
332
333/*!
334 Reimplement to set the window file path to \a filePath
335*/
336void QPlatformWindow::setWindowFilePath(const QString &filePath) { Q_UNUSED(filePath); }
337
338/*!
339 Reimplement to set the window icon to \a icon
340*/
341void QPlatformWindow::setWindowIcon(const QIcon &icon) { Q_UNUSED(icon); }
342
343/*!
344 Reimplement to let the platform handle non-spontaneous window close.
345
346 When reimplementing make sure to call the base class implementation
347 or QWindowSystemInterface::handleCloseEvent(), which will prompt the
348 user to accept the window close (if needed) and then close the QWindow.
349*/
350bool QPlatformWindow::close()
351{
352 return QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(window());
353}
354
355/*!
356 Reimplement to be able to let Qt raise windows to the top of the desktop
357*/
358void QPlatformWindow::raise() { qWarning("This plugin does not support raise()"); }
359
360/*!
361 Reimplement to be able to let Qt lower windows to the bottom of the desktop
362*/
363void QPlatformWindow::lower() { qWarning("This plugin does not support lower()"); }
364
365/*!
366 Reimplement to propagate the size hints of the QWindow.
367
368 The size hints include QWindow::minimumSize(), QWindow::maximumSize(),
369 QWindow::sizeIncrement(), and QWindow::baseSize().
370*/
371void QPlatformWindow::propagateSizeHints() {qWarning("This plugin does not support propagateSizeHints()"); }
372
373/*!
374 Reimplement to be able to let Qt set the opacity level of a window
375*/
376void QPlatformWindow::setOpacity(qreal level)
377{
378 Q_UNUSED(level);
379 qWarning("This plugin does not support setting window opacity");
380}
381
382/*!
383 Reimplement to be able to let Qt set the mask of a window
384*/
385
386void QPlatformWindow::setMask(const QRegion &region)
387{
388 Q_UNUSED(region);
389 qWarning("This plugin does not support setting window masks");
390}
391
392/*!
393 Reimplement to let Qt be able to request activation/focus for a window
394
395 Some window systems will probably not have callbacks for this functionality,
396 and then calling QWindowSystemInterface::handleFocusWindowChanged(QWindow *w)
397 would be sufficient.
398
399 If the window system has some event handling/callbacks then call
400 QWindowSystemInterface::handleFocusWindowChanged(QWindow *w) when the window system
401 gives the notification.
402
403 Default implementation calls QWindowSystem::handleFocusWindowChanged(QWindow *w)
404*/
405void QPlatformWindow::requestActivateWindow()
406{
407 QWindowSystemInterface::handleFocusWindowChanged(window());
408}
409
410/*!
411 Handle changes to the orientation of the platform window's contents.
412
413 This is a hint to the window manager in case it needs to display
414 additional content like popups, dialogs, status bars, or similar
415 in relation to the window.
416
417 \sa QWindow::reportContentOrientationChange()
418*/
419void QPlatformWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
420{
421 Q_UNUSED(orientation);
422}
423
424/*!
425 Reimplement this function in subclass to return the device pixel ratio
426 for the window. This is the ratio between physical pixels
427 and device-independent pixels.
428
429 \sa QPlatformWindow::devicePixelRatio();
430*/
431qreal QPlatformWindow::devicePixelRatio() const
432{
433 return 1.0;
434}
435
436bool QPlatformWindow::setKeyboardGrabEnabled(bool grab)
437{
438 Q_UNUSED(grab);
439 qWarning("This plugin does not support grabbing the keyboard");
440 return false;
441}
442
443bool QPlatformWindow::setMouseGrabEnabled(bool grab)
444{
445 Q_UNUSED(grab);
446 qWarning("This plugin does not support grabbing the mouse");
447 return false;
448}
449
450/*!
451 Reimplement to be able to let Qt indicate that the window has been
452 modified. Return true if the native window supports setting the modified
453 flag, false otherwise.
454*/
455bool QPlatformWindow::setWindowModified(bool modified)
456{
457 Q_UNUSED(modified);
458 return false;
459}
460
461/*!
462 Reimplement this method to be able to do any platform specific event
463 handling. All non-synthetic events for window() are passed to this
464 function before being sent to QWindow::event().
465
466 Return true if the event should not be passed on to the QWindow.
467
468 Subclasses should always call the base class implementation.
469*/
470bool QPlatformWindow::windowEvent(QEvent *event)
471{
472 Q_D(QPlatformWindow);
473
474 if (event->type() == QEvent::Timer) {
475 if (static_cast<QTimerEvent *>(event)->timerId() == d->updateTimer.timerId()) {
476 deliverUpdateRequest();
477 // Delivery of the update request may be circumvented temporarily by the
478 // platform window, or the user may request another update during the
479 // delivery, so wait to stop the timer until we know we don't need it
480 // anymore.
481 if (!hasPendingUpdateRequest())
482 d->updateTimer.stop();
483 return true;
484 }
485 }
486
487 return false;
488}
489
490/*!
491 Reimplement this method to start a system resize operation if
492 the system supports it and return true to indicate success.
493
494 The default implementation is empty and does nothing with \a edges.
495
496 \since 5.15
497*/
498
499bool QPlatformWindow::startSystemResize(Qt::Edges edges)
500{
501 Q_UNUSED(edges);
502 return false;
503}
504
505/*!
506 Reimplement this method to start a system move operation if
507 the system supports it and return true to indicate success.
508
509 The default implementation is empty and does nothing.
510
511 \since 5.15
512*/
513
514bool QPlatformWindow::startSystemMove()
515{
516 return false;
517}
518
519/*!
520 Reimplement this method to set whether frame strut events
521 should be sent to \a enabled.
522
523 \sa frameStrutEventsEnabled
524*/
525
526void QPlatformWindow::setFrameStrutEventsEnabled(bool enabled)
527{
528 Q_UNUSED(enabled); // Do not warn as widgets enable it by default causing warnings with XCB.
529}
530
531/*!
532 Reimplement this method to return whether
533 frame strut events are enabled.
534*/
535
536bool QPlatformWindow::frameStrutEventsEnabled() const
537{
538 return false;
539}
540
541/*!
542 Call this method to put together a window title composed of
543 \a title
544 \a separator
545 the application display name
546
547 If the display name isn't set, and the title is empty, the raw app name is used.
548*/
549QString QPlatformWindow::formatWindowTitle(const QString &title, const QString &separator)
550{
551 QString fullTitle = title;
552 if (QGuiApplicationPrivate::displayName && !title.endsWith(*QGuiApplicationPrivate::displayName)) {
553 // Append display name, if set.
554 if (!fullTitle.isEmpty())
555 fullTitle += separator;
556 fullTitle += *QGuiApplicationPrivate::displayName;
557 } else if (fullTitle.isEmpty()) {
558 // Don't let the window title be completely empty, use the app name as fallback.
559 fullTitle = QCoreApplication::applicationName();
560 }
561 return fullTitle;
562}
563
564/*!
565 Helper function for finding the new screen for \a newGeometry in response to
566 a geometry changed event. Returns the new screen if the window was moved to
567 another virtual sibling. If the screen changes, the platform plugin should call
568 QWindowSystemInterface::handleWindowScreenChanged().
569 \note: The current screen will always be returned for child windows since
570 they should never signal screen changes.
571
572 \since 5.4
573 \sa QWindowSystemInterface::handleWindowScreenChanged()
574*/
575QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const
576{
577 QPlatformScreen *currentScreen = screen();
578 QPlatformScreen *fallback = currentScreen;
579 // QRect::center can return a value outside the rectangle if it's empty.
580 // Apply mapToGlobal() in case it is a foreign/embedded window.
581 QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center();
582 if (isForeignWindow())
583 center = mapToGlobal(center - newGeometry.topLeft());
584
585 if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) {
586 const auto screens = currentScreen->virtualSiblings();
587 for (QPlatformScreen *screen : screens) {
588 const QRect screenGeometry = screen->geometry();
589 if (screenGeometry.contains(center))
590 return screen;
591 if (screenGeometry.intersects(newGeometry))
592 fallback = screen;
593 }
594 }
595 return fallback;
596}
597
598/*!
599 Returns a size with both dimensions bounded to [0, QWINDOWSIZE_MAX]
600*/
601QSize QPlatformWindow::constrainWindowSize(const QSize &size)
602{
603 return size.expandedTo(QSize(0, 0)).boundedTo(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
604}
605
606/*!
607 Reimplement this method to set whether the window demands attention
608 (for example, by flashing the taskbar icon) depending on \a enabled.
609
610 \sa isAlertState()
611 \since 5.1
612*/
613
614void QPlatformWindow::setAlertState(bool enable)
615{
616 Q_UNUSED(enable);
617}
618
619/*!
620 Reimplement this method return whether the window is in
621 an alert state.
622
623 \sa setAlertState()
624 \since 5.1
625*/
626
627bool QPlatformWindow::isAlertState() const
628{
629 return false;
630}
631
632// Return the effective screen for the initial geometry of a window. In a
633// multimonitor-setup, try to find the right screen by checking the transient
634// parent or the mouse cursor for parentless windows (cf QTBUG-34204,
635// QDialog::adjustPosition()), unless a non-primary screen has been set,
636// in which case we try to respect that.
637static inline const QScreen *effectiveScreen(const QWindow *window)
638{
639 if (!window)
640 return QGuiApplication::primaryScreen();
641 const QScreen *screen = window->screen();
642 if (!screen)
643 return QGuiApplication::primaryScreen();
644 if (screen != QGuiApplication::primaryScreen())
645 return screen;
646#ifndef QT_NO_CURSOR
647 const QList<QScreen *> siblings = screen->virtualSiblings();
648 if (siblings.size() > 1) {
649 const QPoint referencePoint = window->transientParent() ? window->transientParent()->geometry().center() : QCursor::pos();
650 for (const QScreen *sibling : siblings) {
651 if (sibling->geometry().contains(referencePoint))
652 return sibling;
653 }
654 }
655#endif
656 return screen;
657}
658
659/*!
660 Invalidates the window's surface by releasing its surface buffers.
661
662 Many platforms do not support releasing the surface memory,
663 and the default implementation does nothing.
664
665 The platform window is expected to recreate the surface again if
666 it is needed. For instance, if an OpenGL context is made current
667 on this window.
668 */
669void QPlatformWindow::invalidateSurface()
670{
671}
672
673static QSize fixInitialSize(QSize size, const QWindow *w, int deviceIndependentDefaultWidth,
674 int deviceIndependentDefaultHeight)
675{
676 if (size.width() == 0) {
677 const int minWidth = w->minimumWidth();
678 size.setWidth(minWidth > 0 ? minWidth : deviceIndependentDefaultWidth);
679 }
680 if (size.height() == 0) {
681 const int minHeight = w->minimumHeight();
682 size.setHeight(minHeight > 0 ? minHeight : deviceIndependentDefaultHeight);
683 }
684 return size;
685}
686
687/*!
688 Helper function to get initial geometry on windowing systems which do not
689 do smart positioning and also do not provide a means of centering a
690 transient window w.r.t. its parent. For example this is useful on Windows
691 and MacOS but not X11, because an X11 window manager typically tries to
692 layout new windows to optimize usage of the available desktop space.
693 However if the given window already has geometry which the application has
694 initialized, it takes priority.
695
696 \a initialGeometry has to be provided in native pixels.
697 \a defaultWidth has to be provided in device independent pixels
698 \a defaultHeight has to be provided in device independent pixels
699*/
700QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeometry,
701 int defaultWidth, int defaultHeight,
702 const QScreen **resultingScreenReturn)
703{
704 if (resultingScreenReturn)
705 *resultingScreenReturn = w->screen();
706
707 // FIXME: Should QWindow::isTopLevel() reflect Qt::SubWindow directly?
708 const bool isTopLevel = w->isTopLevel() && !isSubWindow(w);
709 if (!isTopLevel) {
710 const qreal factor = QHighDpiScaling::factor(w);
711 const QSize deviceIndependentSize =
712 fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor), w,
713 defaultWidth, defaultHeight);
714 return QRect(initialGeometry.topLeft(), QHighDpi::toNative(deviceIndependentSize, factor));
715 }
716 const auto *wp = qt_window_private(const_cast<QWindow*>(w));
717 const bool positionAutomatic = wp->positionAutomatic && w->type() != Qt::Popup;
718 if (!positionAutomatic && !wp->resizeAutomatic)
719 return initialGeometry;
720 const QScreen *screen = positionAutomatic
721 ? effectiveScreen(w)
722 : QGuiApplication::screenAt(initialGeometry.center());
723 if (!screen)
724 return initialGeometry;
725 if (resultingScreenReturn)
726 *resultingScreenReturn = screen;
727 // initialGeometry refers to window's screen
728 QRect deviceIndependentRect(QHighDpi::fromNativePixels(initialGeometry, w));
729 if (wp->resizeAutomatic)
730 deviceIndependentRect.setSize(
731 fixInitialSize(deviceIndependentRect.size(), w, defaultWidth, defaultHeight));
732 if (positionAutomatic) {
733 const QRect availableDeviceIndependentGeometry = screen->availableGeometry();
734 // Center unless the geometry ( + unknown window frame) is too large for the screen).
735 if (deviceIndependentRect.height() < (availableDeviceIndependentGeometry.height() * 8) / 9
736 && deviceIndependentRect.width()
737 < (availableDeviceIndependentGeometry.width() * 8) / 9) {
738 const QWindow *tp = w->transientParent();
739 if (tp) {
740 // A transient window should be centered w.r.t. its transient parent.
741 deviceIndependentRect.moveCenter(tp->geometry().center());
742 } else {
743 // Center the window on the screen. (Only applicable on platforms
744 // which do not provide a better way.)
745 deviceIndependentRect.moveCenter(availableDeviceIndependentGeometry.center());
746 }
747 }
748 }
749 return QHighDpi::toNativePixels(deviceIndependentRect, screen);
750}
751
752
753/*!
754 Checks whether the window has the Qt::SubWindow flag.
755
756 A sub-window is a window without a QWindow::parent(),
757 that should still not be treated as a top level.
758*/
759bool QPlatformWindow::isSubWindow(const QWindow *window)
760{
761 // Explicitly check for the SubWindow bits rather than an exact type match,
762 // because Qt::SubWindow (unlike other Qt::WindowTypes) does not include
763 // the Qt::Window flag, so exact type match will fail when clients call
764 // QWindow::setFlag(Qt::SubWindow) on an existing window.
765 return window->flags().testFlag(Qt::SubWindow);
766}
767
768/*!
769 Requests an QEvent::UpdateRequest event. The event will be
770 delivered to the QWindow.
771
772 QPlatformWindow subclasses can re-implement this function to
773 provide display refresh synchronized updates. The event
774 should be delivered using QPlatformWindow::deliverUpdateRequest()
775 to not get out of sync with the internal state of QWindow.
776
777 The default implementation posts an UpdateRequest event to the window after
778 an interval that is at most 5 ms. If the window's associated screen reports
779 a \l{QPlatformScreen::refreshRate()}{refresh rate} higher than 60 Hz, the
780 interval is scaled down to a valid smaller than 5. The additional time is
781 there to give the event loop a bit of idle time to gather system events.
782
783*/
784void QPlatformWindow::requestUpdate()
785{
786 Q_D(QPlatformWindow);
787
788 static bool customUpdateIntervalValid = false;
789 static int customUpdateInterval = qEnvironmentVariableIntValue("QT_QPA_UPDATE_IDLE_TIME",
790 &customUpdateIntervalValid);
791 int updateInterval = customUpdateInterval;
792 if (!customUpdateIntervalValid) {
793 updateInterval = 5;
794 if (QPlatformScreen *currentScreen = screen()) {
795 const qreal refreshRate = currentScreen->refreshRate();
796 if (refreshRate > 60.0)
797 updateInterval /= refreshRate / 60.0;
798 }
799 }
800
801 // Start or restart the timer (in case we're called during update
802 // request delivery).
803 d->updateTimer.start(updateInterval, Qt::PreciseTimer, window());
804}
805
806/*!
807 Returns true if the window has a pending update request.
808
809 \sa requestUpdate(), deliverUpdateRequest()
810*/
811bool QPlatformWindow::hasPendingUpdateRequest() const
812{
813 return qt_window_private(window())->updateRequestPending;
814}
815
816/*!
817 Returns whether applications can render new frames from any thread
818 without co-ordination with the main thread.
819
820 Platform windows may set this to true during resize events for
821 more control over submitted frames.
822
823 This function may be called from any thread.
824*/
825bool QPlatformWindow::allowsIndependentThreadedRendering() const
826{
827 return true;
828}
829
830/*!
831 Delivers an QEvent::UpdateRequest event to the window.
832
833 QPlatformWindow subclasses can re-implement this function to
834 provide e.g. logging or tracing of the delivery, but should
835 always call the base class function.
836*/
837void QPlatformWindow::deliverUpdateRequest()
838{
839 Q_ASSERT(hasPendingUpdateRequest());
840
841 QWindow *w = window();
842 QWindowPrivate *wp = qt_window_private(w);
843
844 // We expect that the platform plugins send DevicePixelRatioChange events.
845 // As a fail-safe make a final check here to make sure the cached DPR value is
846 // always up to date before delivering the update request.
847 if (wp->updateDevicePixelRatio()) {
848 qWarning() << "The cached device pixel ratio value was stale on window update. "
849 << "Please file a QTBUG which explains how to reproduce.";
850 }
851
852 wp->updateRequestPending = false;
853 QEvent request(QEvent::UpdateRequest);
854 QCoreApplication::sendEvent(w, &request);
855}
856
857/*!
858 Returns the QWindow minimum size.
859*/
860QSize QPlatformWindow::windowMinimumSize() const
861{
862 return constrainWindowSize(QHighDpi::toNativePixels(window()->minimumSize(), window()));
863}
864
865/*!
866 Returns the QWindow maximum size.
867*/
868QSize QPlatformWindow::windowMaximumSize() const
869{
870 return constrainWindowSize(QHighDpi::toNativePixels(window()->maximumSize(), window()));
871}
872
873/*!
874 Returns the QWindow base size.
875*/
876QSize QPlatformWindow::windowBaseSize() const
877{
878 return QHighDpi::toNativePixels(window()->baseSize(), window());
879}
880
881/*!
882 Returns the QWindow size increment.
883*/
884QSize QPlatformWindow::windowSizeIncrement() const
885{
886 QSize increment = window()->sizeIncrement();
887 if (!QHighDpiScaling::isActive())
888 return increment;
889
890 // Normalize the increment. If not set the increment can be
891 // (-1, -1) or (0, 0). Make that (1, 1) which is scalable.
892 if (increment.isEmpty())
893 increment = QSize(1, 1);
894
895 return QHighDpi::toNativePixels(increment, window());
896}
897
898/*!
899 Returns the QWindow geometry.
900*/
901QRect QPlatformWindow::windowGeometry() const
902{
903 return QHighDpi::toNativeWindowGeometry(window()->geometry(), window());
904}
905
906/*!
907 Returns the QWindow frame geometry.
908*/
909QRect QPlatformWindow::windowFrameGeometry() const
910{
911 return QHighDpi::toNativeWindowGeometry(window()->frameGeometry(), window());
912}
913
914/*!
915 Returns the closest acceptable geometry for a given geometry before
916 a resize/move event for platforms that support it, for example to
917 implement heightForWidth().
918*/
919
920QRectF QPlatformWindow::closestAcceptableGeometry(const QWindow *qWindow, const QRectF &nativeRect)
921{
922 const QRectF rectF = QHighDpi::fromNativeWindowGeometry(nativeRect, qWindow);
923 const QRectF correctedGeometryF = qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(rectF);
924 return !correctedGeometryF.isEmpty() && rectF != correctedGeometryF
925 ? QHighDpi::toNativeWindowGeometry(correctedGeometryF, qWindow) : nativeRect;
926}
927
928QRectF QPlatformWindow::windowClosestAcceptableGeometry(const QRectF &nativeRect) const
929{
930 return QPlatformWindow::closestAcceptableGeometry(window(), nativeRect);
931}
932
933/*!
934 \class QPlatformWindow
935 \since 4.8
936 \internal
937 \preliminary
938 \ingroup qpa
939
940 \brief The QPlatformWindow class provides an abstraction for top-level windows.
941
942 The QPlatformWindow abstraction is used by QWindow for all its top level windows. It is being
943 created by calling the createPlatformWindow function in the loaded QPlatformIntegration
944 instance.
945
946 QPlatformWindow is used to signal to the windowing system, how Qt perceives its frame.
947 However, it is not concerned with how Qt renders into the window it represents.
948
949 Visible QWindows will always have a QPlatformWindow. However, it is not necessary for
950 all windows to have a QBackingStore. This is the case for QOpenGLWindow. And could be the case for
951 windows where some third party renders into it.
952
953 The platform specific window handle can be retrieved by the winId function.
954
955 QPlatformWindow is also the way QPA defines how native child windows should be supported
956 through the setParent function.
957
958 \section1 Implementation Aspects
959
960 \list 1
961 \li Mouse grab: Qt expects windows to automatically grab the mouse if the user presses
962 a button until the button is released.
963 Automatic grab should be released if some window is explicitly grabbed.
964 \li Enter/Leave events: If there is a window explicitly grabbing mouse events
965 (\c{setMouseGrabEnabled()}), enter and leave events should only be sent to the
966 grabbing window when mouse cursor passes over the grabbing window boundary.
967 Other windows will not receive enter or leave events while the grab is active.
968 While an automatic mouse grab caused by a mouse button press is active, no window
969 will receive enter or leave events. When the last mouse button is released, the
970 autograbbing window will receive leave event if mouse cursor is no longer within
971 the window boundary.
972 When any grab starts, the window under cursor will receive a leave event unless
973 it is the grabbing window.
974 When any grab ends, the window under cursor will receive an enter event unless it
975 was the grabbing window.
976 \li Window positioning: When calling \c{QWindow::setFramePosition()}, the flag
977 \c{QWindowPrivate::positionPolicy} is set to \c{QWindowPrivate::WindowFrameInclusive}.
978 This means the position includes the window frame, whose size is at this point
979 unknown and the geometry's topleft point is the position of the window frame.
980 \endlist
981
982 Apart from the auto-tests (\c{tests/auto/gui/kernel/qwindow},
983 \c{tests/auto/gui/kernel/qguiapplication} and \c{tests/auto/widgets/kernel/qwidget}),
984 there are a number of manual tests and examples that can help testing a platform plugin:
985
986 \list 1
987 \li \c{examples/qpa/windows}: Basic \c{QWindow} creation.
988 \li \c{examples/opengl/hellowindow}: Basic Open GL windows.
989 \li \c{tests/manual/windowflags}: Tests setting the window flags.
990 \li \c{tests/manual/windowgeometry} Tests setting the window geometry.
991 \li \c{tests/manual/windowmodality} Tests setting the window modality.
992 \li \c{tests/manual/widgetgrab} Tests mouse grab and dialogs.
993 \endlist
994
995 \sa QBackingStore, QWindow
996*/
997
998QT_END_NAMESPACE
Combined button and popup list for selecting options.
static QSize fixInitialSize(QSize size, const QWindow *w, int deviceIndependentDefaultWidth, int deviceIndependentDefaultHeight)
static const QScreen * effectiveScreen(const QWindow *window)
#define QWINDOWSIZE_MAX