1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
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->setWindowFlags(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->windowFlags();
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 widget is already shown, set window visible, too
156 win->setVisible(true);
159 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
164 if (!isWindow() && parentWidget())
165 parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
166 d->deactivateWidgetCleanup();
168 if ((windowType() == Qt::Popup))
169 qApp->d_func()->closePopup(this);
171 if (this == QApplicationPrivate::active_window)
172 QApplication::setActiveWindow(0);
173 if (QWidget::mouseGrabber() == this)
175 if (QWidget::keyboardGrabber() == this)
178 setAttribute(Qt::WA_WState_Created, false);
180 if (windowType() != Qt::Desktop) {
181 if (destroySubWindows) {
182 QObjectList childList(children());
183 for (int i = 0; i < childList.size(); i++) {
184 QWidget *widget = qobject_cast<QWidget *>(childList.at(i));
185 if (widget && widget->testAttribute(Qt::WA_NativeWindow)) {
186 if (widget->windowHandle()) {
193 d->deleteTLSysExtra();
195 if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
204 void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
208 Qt::WindowFlags oldFlags = data.window_flags;
209 bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
211 int targetScreen = -1;
212 // Handle a request to move the widget to a particular screen
213 if (newparent && newparent->windowType() == Qt::Desktop) {
214 // make sure the widget is created on the same screen as the
215 // programmer specified desktop widget
217 // get the desktop's screen number
218 targetScreen = newparent->window()->d_func()->topData()->screenIndex;
224 if (parent != newparent) {
225 QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function???
226 if (q->windowHandle()) {
227 q->windowHandle()->setWindowFlags(f);
228 QWidget *parentWithWindow =
229 newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0;
230 if (parentWithWindow) {
231 if (f & Qt::Window) {
232 q->windowHandle()->setTransientParent(parentWithWindow->windowHandle());
233 q->windowHandle()->setParent(0);
235 q->windowHandle()->setTransientParent(0);
236 q->windowHandle()->setParent(parentWithWindow->windowHandle());
239 q->windowHandle()->setTransientParent(0);
240 q->windowHandle()->setParent(0);
247 if (targetScreen == -1) {
249 targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex;
253 bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
255 // Reparenting toplevel to child
256 if (!(f&Qt::Window) && (oldFlags&Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) {
257 //qDebug() << "setParent_sys() change from toplevel";
259 } else if (newparent && wasCreated) {
264 data.window_flags = f;
265 q->setAttribute(Qt::WA_WState_Created, false);
266 q->setAttribute(Qt::WA_WState_Visible, false);
267 q->setAttribute(Qt::WA_WState_Hidden, false);
269 if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
270 q->setAttribute(Qt::WA_WState_Hidden);
271 q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
273 // move the window to the selected screen
274 if (!newparent && targetScreen != -1) {
276 maybeTopData()->screenIndex = targetScreen;
277 // only if it is already created
278 if (q->testAttribute(Qt::WA_WState_Created)) {
279 q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0));
284 QPoint QWidget::mapToGlobal(const QPoint &pos) const
286 int x = pos.x(), y = pos.y();
287 const QWidget *w = this;
289 x += w->data->crect.x();
290 y += w->data->crect.y();
291 w = w->isWindow() ? 0 : w->parentWidget();
296 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
298 int x = pos.x(), y = pos.y();
299 const QWidget *w = this;
301 x -= w->data->crect.x();
302 y -= w->data->crect.y();
303 w = w->isWindow() ? 0 : w->parentWidget();
308 void QWidgetPrivate::updateSystemBackground() {}
311 void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
315 qt_qpa_set_cursor(q, false);
318 void QWidgetPrivate::unsetCursor_sys()
321 qt_qpa_set_cursor(q, false);
324 #endif //QT_NO_CURSOR
326 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
332 if (QWindow *window = q->windowHandle())
333 window->setWindowTitle(caption);
337 void QWidgetPrivate::setWindowIcon_sys()
340 if (QWindow *window = q->windowHandle())
341 window->setWindowIcon(q->windowIcon());
344 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
349 QWidget *qt_pressGrab = 0;
350 QWidget *qt_mouseGrb = 0;
351 static QWidget *keyboardGrb = 0;
353 void QWidget::grabMouse()
356 qt_mouseGrb->releaseMouse();
359 windowHandle()->setMouseGrabEnabled(true);
366 void QWidget::grabMouse(const QCursor &cursor)
371 qt_mouseGrb->releaseMouse();
374 windowHandle()->setMouseGrabEnabled(true);
381 bool QWidgetPrivate::stealMouseGrab(bool grab)
383 // This is like a combination of grab/releaseMouse() but with error checking
384 // and it has no effect on the result of mouseGrabber().
386 return q->windowHandle() ? q->windowHandle()->setMouseGrabEnabled(grab) : false;
389 void QWidget::releaseMouse()
391 if (qt_mouseGrb == this) {
393 windowHandle()->setMouseGrabEnabled(false);
398 void QWidget::grabKeyboard()
401 keyboardGrb->releaseKeyboard();
403 windowHandle()->setKeyboardGrabEnabled(true);
407 bool QWidgetPrivate::stealKeyboardGrab(bool grab)
409 // This is like a combination of grab/releaseKeyboard() but with error
410 // checking and it has no effect on the result of keyboardGrabber().
412 return q->windowHandle() ? q->windowHandle()->setKeyboardGrabEnabled(grab) : false;
415 void QWidget::releaseKeyboard()
417 if (keyboardGrb == this) {
419 windowHandle()->setKeyboardGrabEnabled(false);
424 QWidget *QWidget::mouseGrabber()
431 QWidget *QWidget::keyboardGrabber()
436 void QWidget::activateWindow()
439 windowHandle()->requestActivateWindow();
442 // Position top level windows at the center, avoid showing
443 // Windows at the default 0,0 position excluding the frame.
444 static inline QRect positionTopLevelWindow(QRect geometry, const QScreen *screen)
446 if (screen && geometry.x() == 0 && geometry.y() == 0) {
447 const QRect availableGeometry = screen->availableGeometry();
448 if (availableGeometry.width() > geometry.width()
449 && availableGeometry.height() > geometry.height())
450 geometry.moveCenter(availableGeometry.center());
455 // move() was invoked with Qt::WA_WState_Created not set (frame geometry
456 // unknown), that is, crect has a position including the frame.
457 // If we can determine the frame strut, fix that and clear the flag.
458 void QWidgetPrivate::fixPosIncludesFrame()
461 if (QTLWExtra *te = maybeTopData()) {
462 if (te->posIncludesFrame) {
463 // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for
464 // example, in QGraphicsProxyWidget).
465 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
466 te->posIncludesFrame = 0;
468 if (q->windowHandle()) {
470 if (!q->data->fstrut_dirty) {
471 data.crect.translate(te->frameStrut.x(), te->frameStrut.y());
472 te->posIncludesFrame = 0;
475 } // !WA_DontShowOnScreen
476 } // posIncludesFrame
480 void QWidgetPrivate::show_sys()
484 QWindow *window = q->windowHandle();
486 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
487 invalidateBuffer(q->rect());
488 q->setAttribute(Qt::WA_Mapped);
489 if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
490 // add our window to the modal window list
491 QGuiApplicationPrivate::showModalWindow(window);
496 QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
498 if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
503 fixPosIncludesFrame();
504 QRect geomRect = q->geometry();
506 if (!q->testAttribute(Qt::WA_Moved))
507 geomRect = positionTopLevelWindow(geomRect, window->screen());
509 QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
510 geomRect.moveTopLeft(topLeftOfWindow);
512 const QRect windowRect = window->geometry();
513 if (windowRect != geomRect) {
514 window->setGeometry(geomRect);
517 if (QBackingStore *store = q->backingStore()) {
518 if (store->size() != geomRect.size()) {
519 store->resize(geomRect.size());
523 invalidateBuffer(q->rect());
524 window->setVisible(true);
529 void QWidgetPrivate::hide_sys()
533 QWindow *window = q->windowHandle();
535 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
536 q->setAttribute(Qt::WA_Mapped, false);
537 if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
538 // remove our window from the modal window list
539 QGuiApplicationPrivate::hideModalWindow(window);
541 // do not return here, if window non-zero, we must hide it
544 deactivateWidgetCleanup();
546 if (!q->isWindow()) {
547 QWidget *p = q->parentWidget();
548 if (p &&p->isVisible()) {
549 invalidateBuffer(q->rect());
552 invalidateBuffer(q->rect());
556 window->setVisible(false);
559 void QWidgetPrivate::setMaxWindowState_helper()
563 const uint old_state = data.in_set_window_state;
564 data.in_set_window_state = 1;
566 const QRect desktop = qApp->desktop()->availableGeometry(qApp->desktop()->screenNumber(q));
567 q->setGeometry(desktop);
569 data.in_set_window_state = old_state;
572 void QWidgetPrivate::setFullScreenSize_helper()
576 const uint old_state = data.in_set_window_state;
577 data.in_set_window_state = 1;
579 const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
580 q->move(screen.topLeft());
581 q->resize(screen.size());
583 data.in_set_window_state = old_state;
586 Qt::WindowState effectiveState(Qt::WindowStates state)
588 if (state & Qt::WindowMinimized)
589 return Qt::WindowMinimized;
590 else if (state & Qt::WindowFullScreen)
591 return Qt::WindowFullScreen;
592 else if (state & Qt::WindowMaximized)
593 return Qt::WindowMaximized;
594 return Qt::WindowNoState;
597 void QWidget::setWindowState(Qt::WindowStates newstate)
600 Qt::WindowStates oldstate = windowState();
601 if (oldstate == newstate)
603 if (isWindow() && !testAttribute(Qt::WA_WState_Created))
606 data->window_state = newstate;
607 data->in_set_window_state = 1;
608 bool needShow = false;
609 Qt::WindowState newEffectiveState = effectiveState(newstate);
610 Qt::WindowState oldEffectiveState = effectiveState(oldstate);
611 if (isWindow() && newEffectiveState != oldEffectiveState) {
613 if (oldEffectiveState == Qt::WindowNoState)
614 d->topData()->normalGeometry = geometry();
616 Q_ASSERT(windowHandle());
617 windowHandle()->setWindowState(newEffectiveState);
618 bool supported = windowHandle()->windowState() == newEffectiveState;
621 // undo the effects of the old emulated state
622 if (oldEffectiveState == Qt::WindowFullScreen) {
623 setParent(0, d->topData()->savedFlags);
625 } else if (oldEffectiveState == Qt::WindowMinimized) {
629 // emulate the new window state
630 if (newEffectiveState == Qt::WindowMinimized) {
634 } else if (newEffectiveState == Qt::WindowFullScreen) {
635 d->topData()->savedFlags = windowFlags();
636 setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
637 d->setFullScreenSize_helper();
640 } else if (newEffectiveState == Qt::WindowMaximized) {
642 d->setMaxWindowState_helper();
643 } else if (newEffectiveState == Qt::WindowNoState) {
644 // reset old geometry
645 QRect r = d->topData()->normalGeometry;
646 if (r.width() >= 0) {
647 d->topData()->normalGeometry = QRect(0,0,-1,-1);
653 data->in_set_window_state = 0;
658 if (newstate & Qt::WindowActive)
661 QWindowStateChangeEvent e(oldstate);
662 QApplication::sendEvent(this, &e);
665 void QWidgetPrivate::setFocus_sys()
670 void QWidgetPrivate::raise_sys()
674 q->windowHandle()->raise();
678 void QWidgetPrivate::lower_sys()
682 Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
683 q->windowHandle()->lower();
684 } else if (QWidget *p = q->parentWidget()) {
685 setDirtyOpaqueRegion();
686 p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
690 void QWidgetPrivate::stackUnder_sys(QWidget*)
693 if (QWidget *p = q->parentWidget()) {
694 setDirtyOpaqueRegion();
695 p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
699 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
702 if (extra) { // any size restrictions?
703 w = qMin(w,extra->maxw);
704 h = qMin(h,extra->maxh);
705 w = qMax(w,extra->minw);
706 h = qMax(h,extra->minh);
709 QPoint oldp = q->geometry().topLeft();
710 QSize olds = q->size();
713 bool isResize = olds != r.size();
714 isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
717 // We only care about stuff that changes the geometry, or may
718 // cause the window manager to change its state
719 if (r.size() == olds && oldp == r.topLeft())
722 if (!data.in_set_window_state) {
723 q->data->window_state &= ~Qt::WindowMaximized;
724 q->data->window_state &= ~Qt::WindowFullScreen;
726 topData()->normalGeometry = QRect(0, 0, -1, -1);
729 QPoint oldPos = q->pos();
732 bool needsShow = false;
734 if (w == 0 || h == 0) {
735 q->setAttribute(Qt::WA_OutsideWSRange, true);
736 if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
738 data.crect = QRect(x, y, w, h);
739 } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
740 q->setAttribute(Qt::WA_OutsideWSRange, false);
744 if (q->isVisible()) {
745 if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
746 if (q->windowHandle()) {
748 q->windowHandle()->setGeometry(q->geometry());
750 QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
751 q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
753 const QWidgetBackingStore *bs = maybeBackingStore();
756 bs->store->resize(r.size());
762 if (isMove && !isResize)
763 moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
765 invalidateBuffer_resizeHelper(oldPos, olds);
770 QMoveEvent e(q->pos(), oldPos);
771 QApplication::sendEvent(q, &e);
774 QResizeEvent e(r.size(), olds);
775 QApplication::sendEvent(q, &e);
776 if (q->windowHandle())
779 } else { // not visible
780 if (isMove && q->pos() != oldPos)
781 q->setAttribute(Qt::WA_PendingMoveEvent, true);
783 q->setAttribute(Qt::WA_PendingResizeEvent, true);
788 void QWidgetPrivate::setConstraints_sys()
791 if (extra && q->windowHandle()) {
792 QWindow *win = q->windowHandle();
793 QWindowPrivate *winp = qt_window_private(win);
795 winp->minimumSize = QSize(extra->minw, extra->minh);
796 winp->maximumSize = QSize(extra->maxw, extra->maxh);
798 if (extra->topextra) {
799 winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
800 winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
803 if (winp->platformWindow) {
804 fixPosIncludesFrame();
805 winp->platformWindow->propagateSizeHints();
810 void QWidgetPrivate::scroll_sys(int dx, int dy)
813 scrollChildren(dx, dy);
814 scrollRect(q->rect(), dx, dy);
817 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
819 scrollRect(r, dx, dy);
822 int QWidget::metric(PaintDeviceMetric m) const
827 if (QWidget *topLevel = window())
828 if (QWindow *topLevelWindow = topLevel->windowHandle()) {
829 QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
831 screen = platformScreen->screen();
833 if (!screen && QGuiApplication::primaryScreen())
834 screen = QGuiApplication::primaryScreen();
837 if (m == PdmDpiX || m == PdmDpiY)
839 return QPaintDevice::metric(m);
843 val = data->crect.width();
844 } else if (m == PdmWidthMM) {
845 val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
846 } else if (m == PdmHeight) {
847 val = data->crect.height();
848 } else if (m == PdmHeightMM) {
849 val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
850 } else if (m == PdmDepth) {
851 return screen->depth();
852 } else if (m == PdmDpiX) {
853 if (d->extra && d->extra->customDpiX)
854 return d->extra->customDpiX;
856 return static_cast<QWidget *>(d->parent)->metric(m);
857 return qRound(screen->logicalDotsPerInchX());
858 } else if (m == PdmDpiY) {
859 if (d->extra && d->extra->customDpiY)
860 return d->extra->customDpiY;
862 return static_cast<QWidget *>(d->parent)->metric(m);
863 return qRound(screen->logicalDotsPerInchY());
864 } else if (m == PdmPhysicalDpiX) {
865 return qRound(screen->physicalDotsPerInchX());
866 } else if (m == PdmPhysicalDpiY) {
867 return qRound(screen->physicalDotsPerInchY());
869 val = QPaintDevice::metric(m);// XXX
877 Returns the QPlatformWindow this widget will be drawn into.
879 QWindow *QWidget::windowHandle() const
882 QTLWExtra *extra = d->maybeTopData();
884 return extra->window;
889 void QWidgetPrivate::createSysExtra()
893 void QWidgetPrivate::deleteSysExtra()
898 void QWidgetPrivate::createTLSysExtra()
901 extra->topextra->screenIndex = 0;
902 extra->topextra->window = 0;
903 if (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())
904 extra->topextra->window = new QWidgetWindow(q);
907 void QWidgetPrivate::deleteTLSysExtra()
909 if (extra && extra->topextra) {
910 //the toplevel might have a context with a "qglcontext associated with it. We need to
911 //delete the qglcontext before we delete the qplatformopenglcontext.
912 //One unfortunate thing about this is that we potentially create a glContext just to
913 //delete it straight afterwards.
914 if (extra->topextra->window) {
915 extra->topextra->window->destroy();
918 delete extra->topextra->window;
919 extra->topextra->window = 0;
921 extra->topextra->backingStoreTracker.destroy();
922 delete extra->topextra->backingStore;
923 extra->topextra->backingStore = 0;
928 void QWidgetPrivate::registerDropSite(bool on)
933 void QWidgetPrivate::setMask_sys(const QRegion ®ionIn)
935 if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowMasks)) {
936 qWarning("%s: Not supported on %s.", Q_FUNC_INFO, qPrintable(QGuiApplication::platformName()));
940 QRegion region = regionIn;
941 QWindow *window = q->windowHandle();
943 if (QWidget *nativeParent = q->nativeParentWidget()) {
944 window = nativeParent->windowHandle();
945 region.translate(q->mapTo(nativeParent, QPoint(0, 0)));
949 if (QPlatformWindow *platformWindow = window->handle())
950 platformWindow->setMask(region);
953 void QWidgetPrivate::updateFrameStrut()
956 if (q->data->fstrut_dirty) {
957 if (QTLWExtra *te = maybeTopData()) {
959 if (const QPlatformWindow *pw = te->window->handle()) {
960 const QMargins margins = pw->frameMargins();
961 if (!margins.isNull()) {
962 te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
963 q->data->fstrut_dirty = false;
971 void QWidgetPrivate::setWindowOpacity_sys(qreal level)
974 if (q->windowHandle())
975 q->windowHandle()->setOpacity(level);
978 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
985 QPaintEngine *QWidget::paintEngine() const
987 qWarning("QWidget::paintEngine: Should no longer be called");
988 return 0; //##### @@@
991 void QWidgetPrivate::setModal_sys()
994 if (q->windowHandle())
995 q->windowHandle()->setWindowModality(q->windowModality());
999 static inline void applyCursor(QWidget *w, QCursor c)
1001 if (QWindow *window = w->windowHandle())
1002 if (const QScreen *screen = window->screen())
1003 if (QPlatformCursor *cursor = screen->handle()->cursor())
1004 cursor->changeCursor(&c, window);
1007 void qt_qpa_set_cursor(QWidget *w, bool force)
1009 if (!w->testAttribute(Qt::WA_WState_Created))
1012 static QPointer<QWidget> lastUnderMouse = 0;
1015 } else if (lastUnderMouse) {
1016 const WId lastWinId = lastUnderMouse->effectiveWinId();
1017 const WId winId = w->effectiveWinId();
1018 if (lastWinId && lastWinId == winId)
1020 } else if (!w->internalWinId()) {
1021 return; // The mouse is not under this widget, and it's not native, so don't change it.
1024 while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
1025 && !w->testAttribute(Qt::WA_SetCursor))
1026 w = w->parentWidget();
1028 QWidget *nativeParent = w;
1029 if (!w->internalWinId())
1030 nativeParent = w->nativeParentWidget();
1031 if (!nativeParent || !nativeParent->internalWinId())
1034 if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
1035 QCursor *oc = QApplication::overrideCursor();
1037 applyCursor(nativeParent, *oc);
1038 else if (w->isEnabled())
1039 applyCursor(nativeParent, w->cursor());
1041 // Enforce the windows behavior of clearing the cursor on
1042 // disabled widgets.
1043 applyCursor(nativeParent, Qt::ArrowCursor);
1045 applyCursor(nativeParent, Qt::ArrowCursor);
1048 #endif //QT_NO_CURSOR