1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
42 #include "QtWidgets/qwidget.h"
43 #include "QtGui/qevent.h"
44 #include "QtWidgets/qapplication.h"
45 #include "private/qwidgetbackingstore_p.h"
46 #include "private/qwidget_p.h"
47 #include "private/qwidgetwindow_qpa_p.h"
48 #include "private/qapplication_p.h"
49 #include "QtWidgets/qdesktopwidget.h"
50 #include <qpa/qplatformwindow.h>
51 #include "QtGui/qsurfaceformat.h"
52 #include <qpa/qplatformopenglcontext.h>
53 #include <qpa/qplatformintegration.h>
54 #include "QtGui/private/qwindow_p.h"
56 #include <qpa/qplatformcursor.h>
57 #include <QtGui/QGuiApplication>
58 #include <QtGui/QScreen>
59 #include <QtCore/QMargins>
63 void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
65 QObjectList children = parentWidget->children();
66 for (int i = 0; i < children.size(); i++) {
67 if (children.at(i)->isWidgetType()) {
68 const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
69 if (childWidget) { // should not be necessary
70 if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
71 if (!childWidget->windowHandle())
73 if (childWidget->windowHandle()) {
74 QWindow *parentWindow = childWidget->nativeParentWidget()->windowHandle();
75 if (childWidget->isWindow())
76 childWidget->windowHandle()->setTransientParent(parentWindow);
78 childWidget->windowHandle()->setParent(parentWindow);
81 q_createNativeChildrenAndSetParent(childWidget);
89 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
94 Q_UNUSED(initializeWindow);
95 Q_UNUSED(destroyOldWindow);
97 Qt::WindowFlags flags = data.window_flags;
99 if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
100 return; // we only care about real toplevels
102 QWindow *win = topData()->window;
103 // topData() ensures the extra is created but does not ensure 'window' is non-null
104 // in case the extra was already valid.
107 win = topData()->window;
110 win->setFlags(data.window_flags);
111 fixPosIncludesFrame();
112 win->setGeometry(q->geometry());
113 win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0));
115 if (q->testAttribute(Qt::WA_TranslucentBackground)) {
116 QSurfaceFormat format;
117 format.setAlphaBufferSize(8);
118 win->setFormat(format);
121 if (QWidget *nativeParent = q->nativeParentWidget()) {
122 if (nativeParent->windowHandle()) {
123 if (flags & Qt::Window) {
124 win->setTransientParent(nativeParent->windowHandle());
127 win->setTransientParent(0);
128 win->setParent(nativeParent->windowHandle());
133 qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ?
134 QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive;
137 data.window_flags = win->flags();
139 QBackingStore *store = q->backingStore();
142 if (win && q->windowType() != Qt::Desktop)
143 q->setBackingStore(new QBackingStore(win));
145 q->setAttribute(Qt::WA_PaintOnScreen, true);
148 setWindowModified_helper();
149 setWinId(win->winId());
151 // Check children and create windows for them if necessary
152 q_createNativeChildrenAndSetParent(q);
154 if (extra && !extra->mask.isEmpty())
155 setMask_sys(extra->mask);
157 // If widget is already shown, set window visible, too
159 win->setVisible(true);
162 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
167 if (!isWindow() && parentWidget())
168 parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
169 d->deactivateWidgetCleanup();
171 if ((windowType() == Qt::Popup))
172 qApp->d_func()->closePopup(this);
174 if (this == QApplicationPrivate::active_window)
175 QApplication::setActiveWindow(0);
176 if (QWidget::mouseGrabber() == this)
178 if (QWidget::keyboardGrabber() == this)
181 setAttribute(Qt::WA_WState_Created, false);
183 if (windowType() != Qt::Desktop) {
184 if (destroySubWindows) {
185 QObjectList childList(children());
186 for (int i = 0; i < childList.size(); i++) {
187 QWidget *widget = qobject_cast<QWidget *>(childList.at(i));
188 if (widget && widget->testAttribute(Qt::WA_NativeWindow)) {
189 if (widget->windowHandle()) {
196 d->deleteTLSysExtra();
198 if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
207 void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
211 Qt::WindowFlags oldFlags = data.window_flags;
212 bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
214 int targetScreen = -1;
215 // Handle a request to move the widget to a particular screen
216 if (newparent && newparent->windowType() == Qt::Desktop) {
217 // make sure the widget is created on the same screen as the
218 // programmer specified desktop widget
220 // get the desktop's screen number
221 targetScreen = newparent->window()->d_func()->topData()->screenIndex;
227 if (parent != newparent) {
228 QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function???
229 if (q->windowHandle()) {
230 q->windowHandle()->setFlags(f);
231 QWidget *parentWithWindow =
232 newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0;
233 if (parentWithWindow) {
234 if (f & Qt::Window) {
235 q->windowHandle()->setTransientParent(parentWithWindow->windowHandle());
236 q->windowHandle()->setParent(0);
238 q->windowHandle()->setTransientParent(0);
239 q->windowHandle()->setParent(parentWithWindow->windowHandle());
242 q->windowHandle()->setTransientParent(0);
243 q->windowHandle()->setParent(0);
250 if (targetScreen == -1) {
252 targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex;
256 bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
258 // Reparenting toplevel to child
259 if (!(f&Qt::Window) && (oldFlags&Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) {
260 //qDebug() << "setParent_sys() change from toplevel";
265 data.window_flags = f;
266 q->setAttribute(Qt::WA_WState_Created, false);
267 q->setAttribute(Qt::WA_WState_Visible, false);
268 q->setAttribute(Qt::WA_WState_Hidden, false);
270 if (newparent && wasCreated && (q->testAttribute(Qt::WA_NativeWindow) || (f & Qt::Window)))
273 if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
274 q->setAttribute(Qt::WA_WState_Hidden);
275 q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
277 // move the window to the selected screen
278 if (!newparent && targetScreen != -1) {
280 maybeTopData()->screenIndex = targetScreen;
281 // only if it is already created
282 if (q->testAttribute(Qt::WA_WState_Created)) {
283 q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0));
288 QPoint QWidget::mapToGlobal(const QPoint &pos) const
290 int x = pos.x(), y = pos.y();
291 const QWidget *w = this;
293 QWindow *window = w->windowHandle();
294 if (window && window->handle())
295 return window->mapToGlobal(QPoint(x, y));
297 x += w->data->crect.x();
298 y += w->data->crect.y();
299 w = w->isWindow() ? 0 : w->parentWidget();
304 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
306 int x = pos.x(), y = pos.y();
307 const QWidget *w = this;
309 QWindow *window = w->windowHandle();
310 if (window && window->handle())
311 return window->mapFromGlobal(QPoint(x, y));
313 x -= w->data->crect.x();
314 y -= w->data->crect.y();
315 w = w->isWindow() ? 0 : w->parentWidget();
320 void QWidgetPrivate::updateSystemBackground() {}
323 void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
327 qt_qpa_set_cursor(q, false);
330 void QWidgetPrivate::unsetCursor_sys()
333 qt_qpa_set_cursor(q, false);
336 #endif //QT_NO_CURSOR
338 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
344 if (QWindow *window = q->windowHandle())
345 window->setTitle(caption);
349 void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath)
355 if (QWindow *window = q->windowHandle())
356 window->setFilePath(filePath);
359 void QWidgetPrivate::setWindowIcon_sys()
362 if (QWindow *window = q->windowHandle())
363 window->setIcon(q->windowIcon());
366 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
371 QWidget *qt_pressGrab = 0;
372 QWidget *qt_mouseGrb = 0;
373 static QWidget *keyboardGrb = 0;
375 static inline QWindow *grabberWindow(const QWidget *w)
377 QWindow *window = w->windowHandle();
379 if (const QWidget *nativeParent = w->nativeParentWidget())
380 window = nativeParent->windowHandle();
384 void QWidget::grabMouse()
387 qt_mouseGrb->releaseMouse();
389 if (QWindow *window = grabberWindow(this))
390 window->setMouseGrabEnabled(true);
397 void QWidget::grabMouse(const QCursor &cursor)
404 bool QWidgetPrivate::stealMouseGrab(bool grab)
406 // This is like a combination of grab/releaseMouse() but with error checking
407 // and it has no effect on the result of mouseGrabber().
409 QWindow *window = grabberWindow(q);
410 return window ? window->setMouseGrabEnabled(grab) : false;
413 void QWidget::releaseMouse()
415 if (qt_mouseGrb == this) {
416 if (QWindow *window = grabberWindow(this))
417 window->setMouseGrabEnabled(false);
422 void QWidget::grabKeyboard()
425 keyboardGrb->releaseKeyboard();
426 if (QWindow *window = grabberWindow(this))
427 window->setKeyboardGrabEnabled(true);
431 bool QWidgetPrivate::stealKeyboardGrab(bool grab)
433 // This is like a combination of grab/releaseKeyboard() but with error
434 // checking and it has no effect on the result of keyboardGrabber().
436 QWindow *window = grabberWindow(q);
437 return window ? window->setKeyboardGrabEnabled(grab) : false;
440 void QWidget::releaseKeyboard()
442 if (keyboardGrb == this) {
443 if (QWindow *window = grabberWindow(this))
444 window->setKeyboardGrabEnabled(false);
449 QWidget *QWidget::mouseGrabber()
456 QWidget *QWidget::keyboardGrabber()
461 void QWidget::activateWindow()
463 QWindow *const wnd = window()->windowHandle();
466 wnd->requestActivate();
469 // Position top level windows at the center, avoid showing
470 // Windows at the default 0,0 position excluding the frame.
471 static inline QRect positionTopLevelWindow(QRect geometry, const QScreen *screen)
473 if (screen && geometry.x() == 0 && geometry.y() == 0) {
474 const QRect availableGeometry = screen->availableGeometry();
475 if (availableGeometry.width() > geometry.width()
476 && availableGeometry.height() > geometry.height())
477 geometry.moveCenter(availableGeometry.center());
482 // move() was invoked with Qt::WA_WState_Created not set (frame geometry
483 // unknown), that is, crect has a position including the frame.
484 // If we can determine the frame strut, fix that and clear the flag.
485 void QWidgetPrivate::fixPosIncludesFrame()
488 if (QTLWExtra *te = maybeTopData()) {
489 if (te->posIncludesFrame) {
490 // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for
491 // example, in QGraphicsProxyWidget).
492 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
493 te->posIncludesFrame = 0;
495 if (q->windowHandle()) {
497 if (!q->data->fstrut_dirty) {
498 data.crect.translate(te->frameStrut.x(), te->frameStrut.y());
499 te->posIncludesFrame = 0;
502 } // !WA_DontShowOnScreen
503 } // posIncludesFrame
507 void QWidgetPrivate::show_sys()
511 QWindow *window = q->windowHandle();
513 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
514 invalidateBuffer(q->rect());
515 q->setAttribute(Qt::WA_Mapped);
516 if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
517 // add our window to the modal window list
518 QGuiApplicationPrivate::showModalWindow(window);
523 QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
525 if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
530 fixPosIncludesFrame();
531 QRect geomRect = q->geometry();
533 if (!q->testAttribute(Qt::WA_Moved))
534 geomRect = positionTopLevelWindow(geomRect, window->screen());
536 QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
537 geomRect.moveTopLeft(topLeftOfWindow);
539 const QRect windowRect = window->geometry();
540 if (windowRect != geomRect) {
541 window->setGeometry(geomRect);
544 if (QBackingStore *store = q->backingStore()) {
545 if (store->size() != geomRect.size()) {
546 store->resize(geomRect.size());
551 qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show
553 invalidateBuffer(q->rect());
554 window->setVisible(true);
559 void QWidgetPrivate::hide_sys()
563 QWindow *window = q->windowHandle();
565 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
566 q->setAttribute(Qt::WA_Mapped, false);
567 if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
568 // remove our window from the modal window list
569 QGuiApplicationPrivate::hideModalWindow(window);
571 // do not return here, if window non-zero, we must hide it
574 deactivateWidgetCleanup();
576 if (!q->isWindow()) {
577 QWidget *p = q->parentWidget();
578 if (p &&p->isVisible()) {
579 invalidateBuffer(q->rect());
582 invalidateBuffer(q->rect());
586 window->setVisible(false);
589 Qt::WindowState effectiveState(Qt::WindowStates state)
591 if (state & Qt::WindowMinimized)
592 return Qt::WindowMinimized;
593 else if (state & Qt::WindowFullScreen)
594 return Qt::WindowFullScreen;
595 else if (state & Qt::WindowMaximized)
596 return Qt::WindowMaximized;
597 return Qt::WindowNoState;
600 void QWidget::setWindowState(Qt::WindowStates newstate)
603 Qt::WindowStates oldstate = windowState();
604 if (oldstate == newstate)
606 if (isWindow() && !testAttribute(Qt::WA_WState_Created))
609 data->window_state = newstate;
610 data->in_set_window_state = 1;
611 Qt::WindowState newEffectiveState = effectiveState(newstate);
612 Qt::WindowState oldEffectiveState = effectiveState(oldstate);
613 if (isWindow() && newEffectiveState != oldEffectiveState) {
614 // Ensure the initial size is valid, since we store it as normalGeometry below.
615 if (!testAttribute(Qt::WA_Resized) && !isVisible())
619 if (oldEffectiveState == Qt::WindowNoState)
620 d->topData()->normalGeometry = geometry();
622 Q_ASSERT(windowHandle());
623 windowHandle()->setWindowState(newEffectiveState);
625 data->in_set_window_state = 0;
627 if (newstate & Qt::WindowActive)
630 QWindowStateChangeEvent e(oldstate);
631 QApplication::sendEvent(this, &e);
634 void QWidgetPrivate::setFocus_sys()
637 // Embedded native widget may have taken the focus; get it back to toplevel if that is the case
638 const QWidget *topLevel = q->window();
639 if (topLevel->windowType() != Qt::Popup) {
640 if (QWindow *nativeWindow = q->window()->windowHandle()) {
641 if (nativeWindow != QGuiApplication::focusWindow()
642 && q->testAttribute(Qt::WA_WState_Created)) {
643 nativeWindow->requestActivate();
649 void QWidgetPrivate::raise_sys()
652 if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) {
653 q->windowHandle()->raise();
657 void QWidgetPrivate::lower_sys()
660 if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) {
661 Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
662 q->windowHandle()->lower();
663 } else if (QWidget *p = q->parentWidget()) {
664 setDirtyOpaqueRegion();
665 p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
669 void QWidgetPrivate::stackUnder_sys(QWidget*)
672 if (QWidget *p = q->parentWidget()) {
673 setDirtyOpaqueRegion();
674 p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
678 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
681 if (extra) { // any size restrictions?
682 w = qMin(w,extra->maxw);
683 h = qMin(h,extra->maxh);
684 w = qMax(w,extra->minw);
685 h = qMax(h,extra->minh);
688 QPoint oldp = q->geometry().topLeft();
689 QSize olds = q->size();
692 bool isResize = olds != r.size();
693 isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
696 // We only care about stuff that changes the geometry, or may
697 // cause the window manager to change its state
698 if (r.size() == olds && oldp == r.topLeft())
701 if (!data.in_set_window_state) {
702 q->data->window_state &= ~Qt::WindowMaximized;
703 q->data->window_state &= ~Qt::WindowFullScreen;
705 topData()->normalGeometry = QRect(0, 0, -1, -1);
708 QPoint oldPos = q->pos();
711 bool needsShow = false;
713 if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) {
714 q->setAttribute(Qt::WA_OutsideWSRange, true);
715 if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
717 data.crect = QRect(x, y, w, h);
718 } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
719 q->setAttribute(Qt::WA_OutsideWSRange, false);
723 if (q->isVisible()) {
724 if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
725 if (q->windowHandle()) {
727 q->windowHandle()->setGeometry(q->geometry());
729 QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
730 q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
732 const QWidgetBackingStore *bs = maybeBackingStore();
735 bs->store->resize(r.size());
742 if (!q->isWindow()) {
743 if (isMove && !isResize)
744 moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
746 invalidateBuffer_resizeHelper(oldPos, olds);
751 QMoveEvent e(q->pos(), oldPos);
752 QApplication::sendEvent(q, &e);
755 QResizeEvent e(r.size(), olds);
756 QApplication::sendEvent(q, &e);
757 if (q->windowHandle())
760 } else { // not visible
761 if (isMove && q->pos() != oldPos)
762 q->setAttribute(Qt::WA_PendingMoveEvent, true);
764 q->setAttribute(Qt::WA_PendingResizeEvent, true);
769 void QWidgetPrivate::setConstraints_sys()
772 if (extra && q->windowHandle()) {
773 QWindow *win = q->windowHandle();
774 QWindowPrivate *winp = qt_window_private(win);
776 winp->minimumSize = QSize(extra->minw, extra->minh);
777 winp->maximumSize = QSize(extra->maxw, extra->maxh);
779 if (extra->topextra) {
780 winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
781 winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
784 if (winp->platformWindow) {
785 fixPosIncludesFrame();
786 winp->platformWindow->propagateSizeHints();
791 void QWidgetPrivate::scroll_sys(int dx, int dy)
794 scrollChildren(dx, dy);
795 scrollRect(q->rect(), dx, dy);
798 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
800 scrollRect(r, dx, dy);
803 int QWidget::metric(PaintDeviceMetric m) const
808 if (QWidget *topLevel = window())
809 if (QWindow *topLevelWindow = topLevel->windowHandle()) {
810 QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
812 screen = platformScreen->screen();
814 if (!screen && QGuiApplication::primaryScreen())
815 screen = QGuiApplication::primaryScreen();
818 if (m == PdmDpiX || m == PdmDpiY)
820 return QPaintDevice::metric(m);
824 val = data->crect.width();
825 } else if (m == PdmWidthMM) {
826 val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
827 } else if (m == PdmHeight) {
828 val = data->crect.height();
829 } else if (m == PdmHeightMM) {
830 val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
831 } else if (m == PdmDepth) {
832 return screen->depth();
833 } else if (m == PdmDpiX) {
834 if (d->extra && d->extra->customDpiX)
835 return d->extra->customDpiX;
837 return static_cast<QWidget *>(d->parent)->metric(m);
838 return qRound(screen->logicalDotsPerInchX());
839 } else if (m == PdmDpiY) {
840 if (d->extra && d->extra->customDpiY)
841 return d->extra->customDpiY;
843 return static_cast<QWidget *>(d->parent)->metric(m);
844 return qRound(screen->logicalDotsPerInchY());
845 } else if (m == PdmPhysicalDpiX) {
846 return qRound(screen->physicalDotsPerInchX());
847 } else if (m == PdmPhysicalDpiY) {
848 return qRound(screen->physicalDotsPerInchY());
850 val = QPaintDevice::metric(m);// XXX
858 Returns the QPlatformWindow this widget will be drawn into.
860 QWindow *QWidget::windowHandle() const
863 QTLWExtra *extra = d->maybeTopData();
865 return extra->window;
870 void QWidgetPrivate::createSysExtra()
874 void QWidgetPrivate::deleteSysExtra()
879 void QWidgetPrivate::createTLSysExtra()
882 extra->topextra->screenIndex = 0;
883 extra->topextra->window = 0;
884 if (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow()) {
885 extra->topextra->window = new QWidgetWindow(q);
886 if (extra->minw || extra->minh)
887 extra->topextra->window->setMinimumSize(QSize(extra->minw, extra->minh));
888 if (extra->maxw != QWIDGETSIZE_MAX || extra->maxh != QWIDGETSIZE_MAX)
889 extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh));
893 void QWidgetPrivate::deleteTLSysExtra()
895 if (extra && extra->topextra) {
896 //the toplevel might have a context with a "qglcontext associated with it. We need to
897 //delete the qglcontext before we delete the qplatformopenglcontext.
898 //One unfortunate thing about this is that we potentially create a glContext just to
899 //delete it straight afterwards.
900 if (extra->topextra->window) {
901 extra->topextra->window->destroy();
904 delete extra->topextra->window;
905 extra->topextra->window = 0;
907 extra->topextra->backingStoreTracker.destroy();
908 delete extra->topextra->backingStore;
909 extra->topextra->backingStore = 0;
914 void QWidgetPrivate::registerDropSite(bool on)
919 void QWidgetPrivate::setMask_sys(const QRegion ®ion)
921 if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowMasks)) {
922 qWarning("%s: Not supported on %s.", Q_FUNC_INFO, qPrintable(QGuiApplication::platformName()));
926 if (const QWindow *window = q->windowHandle())
927 if (QPlatformWindow *platformWindow = window->handle())
928 platformWindow->setMask(region);
931 void QWidgetPrivate::updateFrameStrut()
934 if (q->data->fstrut_dirty) {
935 if (QTLWExtra *te = maybeTopData()) {
937 if (const QPlatformWindow *pw = te->window->handle()) {
938 const QMargins margins = pw->frameMargins();
939 if (!margins.isNull()) {
940 te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
941 q->data->fstrut_dirty = false;
949 void QWidgetPrivate::setWindowOpacity_sys(qreal level)
952 if (q->windowHandle())
953 q->windowHandle()->setOpacity(level);
956 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
963 QPaintEngine *QWidget::paintEngine() const
965 qWarning("QWidget::paintEngine: Should no longer be called");
968 // We set this bit which is checked in setAttribute for
969 // Qt::WA_PaintOnScreen. We do this to allow these two scenarios:
971 // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to
972 // Windows which would mean suddenly their widgets stop working.
974 // 2. Users set paint on screen and subclass paintEngine() to
975 // return 0, in which case we have a "hole" in the backingstore
976 // allowing use of GDI or DirectX directly.
978 // 1 is WRONG, but to minimize silent failures, we have set this
979 // bit to ignore the setAttribute call. 2. needs to be
980 // supported because its our only means of embedding native
982 const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1;
985 return 0; //##### @@@
988 void QWidgetPrivate::setModal_sys()
991 if (q->windowHandle())
992 q->windowHandle()->setModality(q->windowModality());
996 static inline void applyCursor(QWidget *w, QCursor c)
998 if (QWindow *window = w->windowHandle())
999 window->setCursor(c);
1002 void qt_qpa_set_cursor(QWidget *w, bool force)
1004 if (!w->testAttribute(Qt::WA_WState_Created))
1007 static QPointer<QWidget> lastUnderMouse = 0;
1010 } else if (lastUnderMouse) {
1011 const WId lastWinId = lastUnderMouse->effectiveWinId();
1012 const WId winId = w->effectiveWinId();
1013 if (lastWinId && lastWinId == winId)
1015 } else if (!w->internalWinId()) {
1016 return; // The mouse is not under this widget, and it's not native, so don't change it.
1019 while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
1020 && !w->testAttribute(Qt::WA_SetCursor))
1021 w = w->parentWidget();
1023 QWidget *nativeParent = w;
1024 if (!w->internalWinId())
1025 nativeParent = w->nativeParentWidget();
1026 if (!nativeParent || !nativeParent->internalWinId())
1029 if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
1031 applyCursor(nativeParent, w->cursor());
1033 // Enforce the windows behavior of clearing the cursor on
1034 // disabled widgets.
1035 applyCursor(nativeParent, Qt::ArrowCursor);
1037 applyCursor(nativeParent, Qt::ArrowCursor);
1040 #endif //QT_NO_CURSOR