9d444fee8ffe59191531baf00efc09c2e1899aaf
[profile/ivi/qtbase.git] / src / widgets / kernel / qwidget_qpa.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
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 "QtGui/private/qwindow_p.h"
54
55 #include <qpa/qplatformcursor.h>
56 #include <QtGui/QGuiApplication>
57 #include <QtGui/QScreen>
58 #include <QtCore/QMargins>
59
60 QT_BEGIN_NAMESPACE
61
62 void q_createNativeChildrenAndSetParent(QWindow *parentWindow, const QWidget *parentWidget)
63 {
64     QObjectList children = parentWidget->children();
65     for (int i = 0; i < children.size(); i++) {
66         if (children.at(i)->isWidgetType()) {
67             const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
68             if (childWidget) { // should not be necessary
69                 if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
70                     if (!childWidget->windowHandle())
71                         childWidget->winId();
72                     if (childWidget->windowHandle()) {
73                         if (childWidget->isTopLevel())
74                             childWidget->windowHandle()->setTransientParent(parentWindow);
75                         else
76                             childWidget->windowHandle()->setParent(parentWindow);
77                     }
78                 } else {
79                     q_createNativeChildrenAndSetParent(parentWindow,childWidget);
80                 }
81             }
82         }
83     }
84
85 }
86
87 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
88 {
89     Q_Q(QWidget);
90
91     Q_UNUSED(window);
92     Q_UNUSED(initializeWindow);
93     Q_UNUSED(destroyOldWindow);
94
95     Qt::WindowFlags flags = data.window_flags;
96
97     if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
98         return; // we only care about real toplevels
99
100     QWindow *win = topData()->window;
101     // topData() ensures the extra is created but does not ensure 'window' is non-null
102     // in case the extra was already valid.
103     if (!win) {
104         createTLSysExtra();
105         win = topData()->window;
106     }
107
108     win->setWindowFlags(data.window_flags);
109     fixPosIncludesFrame();
110     win->setGeometry(q->geometry());
111     win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0));
112
113     if (q->testAttribute(Qt::WA_TranslucentBackground)) {
114         QSurfaceFormat format;
115         format.setAlphaBufferSize(8);
116         win->setFormat(format);
117     }
118
119     if (QWidget *nativeParent = q->nativeParentWidget()) {
120         if (nativeParent->windowHandle()) {
121             if (flags & Qt::Window) {
122                 win->setTransientParent(nativeParent->windowHandle());
123                 win->setParent(0);
124             } else {
125                 win->setTransientParent(0);
126                 win->setParent(nativeParent->windowHandle());
127             }
128         }
129     }
130
131     qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ?
132         QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive;
133     win->create();
134
135     data.window_flags = win->windowFlags();
136
137     QBackingStore *store = q->backingStore();
138
139     if (!store) {
140         if (win && q->windowType() != Qt::Desktop)
141             q->setBackingStore(new QBackingStore(win));
142         else
143             q->setAttribute(Qt::WA_PaintOnScreen, true);
144     }
145
146     setWindowModified_helper();
147     setWinId(win->winId());
148
149     // Check children and create windows for them if necessary
150     q_createNativeChildrenAndSetParent(q->windowHandle(), q);
151
152     // If widget is already shown, set window visible, too
153     if (q->isVisible())
154         win->setVisible(true);
155 }
156
157 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
158 {
159     Q_D(QWidget);
160
161     d->aboutToDestroy();
162     if (!isWindow() && parentWidget())
163         parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
164     d->deactivateWidgetCleanup();
165
166     if ((windowType() == Qt::Popup))
167         qApp->d_func()->closePopup(this);
168
169     if (this == QApplicationPrivate::active_window)
170         QApplication::setActiveWindow(0);
171
172     setAttribute(Qt::WA_WState_Created, false);
173
174     if (windowType() != Qt::Desktop) {
175         if (destroySubWindows) {
176             QObjectList childList(children());
177             for (int i = 0; i < childList.size(); i++) {
178                 QWidget *widget = qobject_cast<QWidget *>(childList.at(i));
179                 if (widget && widget->testAttribute(Qt::WA_NativeWindow)) {
180                     if (widget->windowHandle()) {
181                         widget->destroy();
182                     }
183                 }
184             }
185         }
186         if (destroyWindow) {
187             d->deleteTLSysExtra();
188         } else {
189             if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
190                 d->hide_sys();
191             }
192         }
193
194         d->setWinId(0);
195     }
196 }
197
198 void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
199 {
200     Q_Q(QWidget);
201
202     Qt::WindowFlags oldFlags = data.window_flags;
203     bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
204
205     int targetScreen = -1;
206     // Handle a request to move the widget to a particular screen
207     if (newparent && newparent->windowType() == Qt::Desktop) {
208         // make sure the widget is created on the same screen as the
209         // programmer specified desktop widget
210
211         // get the desktop's screen number
212         targetScreen = newparent->window()->d_func()->topData()->screenIndex;
213         newparent = 0;
214     }
215
216     setWinId(0);
217
218     if (parent != newparent) {
219         QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function???
220         if (q->windowHandle()) {
221             q->windowHandle()->setWindowFlags(f);
222             QWidget *parentWithWindow =
223                 newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0;
224             if (parentWithWindow) {
225                 if (f & Qt::Window) {
226                     q->windowHandle()->setTransientParent(parentWithWindow->windowHandle());
227                     q->windowHandle()->setParent(0);
228                 } else {
229                     q->windowHandle()->setTransientParent(0);
230                     q->windowHandle()->setParent(parentWithWindow->windowHandle());
231                 }
232             } else {
233                 q->windowHandle()->setTransientParent(0);
234                 q->windowHandle()->setParent(0);
235             }
236         }
237     }
238
239     if (!newparent) {
240         f |= Qt::Window;
241         if (targetScreen == -1) {
242             if (parent)
243                 targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex;
244         }
245     }
246
247     bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
248
249     // Reparenting toplevel to child
250     if (!(f&Qt::Window) && (oldFlags&Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) {
251         //qDebug() << "setParent_sys() change from toplevel";
252         q->destroy();
253     } else if (newparent && wasCreated) {
254         q->createWinId();
255     }
256
257     adjustFlags(f, q);
258     data.window_flags = f;
259     q->setAttribute(Qt::WA_WState_Created, false);
260     q->setAttribute(Qt::WA_WState_Visible, false);
261     q->setAttribute(Qt::WA_WState_Hidden, false);
262
263     if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
264         q->setAttribute(Qt::WA_WState_Hidden);
265     q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
266
267     // move the window to the selected screen
268     if (!newparent && targetScreen != -1) {
269         if (maybeTopData())
270             maybeTopData()->screenIndex = targetScreen;
271         // only if it is already created
272         if (q->testAttribute(Qt::WA_WState_Created)) {
273             q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0));
274         }
275     }
276 }
277
278 QPoint QWidget::mapToGlobal(const QPoint &pos) const
279 {
280     int x = pos.x(), y = pos.y();
281     const QWidget *w = this;
282     while (w) {
283         x += w->data->crect.x();
284         y += w->data->crect.y();
285         w = w->isWindow() ? 0 : w->parentWidget();
286     }
287     return QPoint(x, y);
288 }
289
290 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
291 {
292     int x = pos.x(), y = pos.y();
293     const QWidget *w = this;
294     while (w) {
295         x -= w->data->crect.x();
296         y -= w->data->crect.y();
297         w = w->isWindow() ? 0 : w->parentWidget();
298     }
299     return QPoint(x, y);
300 }
301
302 void QWidgetPrivate::updateSystemBackground() {}
303
304 #ifndef QT_NO_CURSOR
305 void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
306 {
307     Q_UNUSED(cursor);
308     Q_Q(QWidget);
309     qt_qpa_set_cursor(q, false);
310 }
311
312 void QWidgetPrivate::unsetCursor_sys()
313 {
314     Q_Q(QWidget);
315     qt_qpa_set_cursor(q, false);
316 }
317
318 #endif //QT_NO_CURSOR
319
320 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
321 {
322     Q_Q(QWidget);
323     if (!q->isWindow())
324         return;
325
326     if (QWindow *window = q->windowHandle())
327         window->setWindowTitle(caption);
328
329 }
330
331 void QWidgetPrivate::setWindowIcon_sys(bool /*forceReset*/)
332 {
333 }
334
335 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
336 {
337     Q_UNUSED(iconText);
338 }
339
340 QWidget *qt_pressGrab = 0;
341 QWidget *qt_mouseGrb = 0;
342 static QWidget *keyboardGrb = 0;
343
344 void QWidget::grabMouse()
345 {
346     if (qt_mouseGrb)
347         qt_mouseGrb->releaseMouse();
348
349     if (windowHandle())
350         windowHandle()->setMouseGrabEnabled(true);
351
352     qt_mouseGrb = this;
353     qt_pressGrab = 0;
354 }
355
356 #ifndef QT_NO_CURSOR
357 void QWidget::grabMouse(const QCursor &cursor)
358 {
359     Q_UNUSED(cursor);
360
361     if (qt_mouseGrb)
362         qt_mouseGrb->releaseMouse();
363
364     if (windowHandle())
365         windowHandle()->setMouseGrabEnabled(true);
366
367     qt_mouseGrb = this;
368     qt_pressGrab = 0;
369 }
370 #endif
371
372 bool QWidgetPrivate::stealMouseGrab(bool grab)
373 {
374     // This is like a combination of grab/releaseMouse() but with error checking
375     // and it has no effect on the result of mouseGrabber().
376     Q_Q(QWidget);
377     return q->windowHandle() ? q->windowHandle()->setMouseGrabEnabled(grab) : false;
378 }
379
380 void QWidget::releaseMouse()
381 {
382     if (qt_mouseGrb == this) {
383         if (windowHandle())
384             windowHandle()->setMouseGrabEnabled(false);
385         qt_mouseGrb = 0;
386     }
387 }
388
389 void QWidget::grabKeyboard()
390 {
391     if (keyboardGrb)
392         keyboardGrb->releaseKeyboard();
393     if (windowHandle())
394         windowHandle()->setKeyboardGrabEnabled(true);
395     keyboardGrb = this;
396 }
397
398 bool QWidgetPrivate::stealKeyboardGrab(bool grab)
399 {
400     // This is like a combination of grab/releaseKeyboard() but with error
401     // checking and it has no effect on the result of keyboardGrabber().
402     Q_Q(QWidget);
403     return q->windowHandle() ? q->windowHandle()->setKeyboardGrabEnabled(grab) : false;
404 }
405
406 void QWidget::releaseKeyboard()
407 {
408     if (keyboardGrb == this) {
409         if (windowHandle())
410             windowHandle()->setKeyboardGrabEnabled(false);
411         keyboardGrb = 0;
412     }
413 }
414
415 QWidget *QWidget::mouseGrabber()
416 {
417     if (qt_mouseGrb)
418         return qt_mouseGrb;
419     return qt_pressGrab;
420 }
421
422 QWidget *QWidget::keyboardGrabber()
423 {
424     return keyboardGrb;
425 }
426
427 void QWidget::activateWindow()
428 {
429     if (windowHandle())
430         windowHandle()->requestActivateWindow();
431 }
432
433 // Position top level windows at the center, avoid showing
434 // Windows at the default 0,0 position excluding the frame.
435 static inline QRect positionTopLevelWindow(QRect geometry, const QScreen *screen)
436 {
437     if (screen && geometry.x() == 0 && geometry.y() == 0) {
438        const QRect availableGeometry = screen->availableGeometry();
439         if (availableGeometry.width() > geometry.width()
440             && availableGeometry.height() > geometry.height())
441             geometry.moveCenter(availableGeometry.center());
442     }
443     return geometry;
444 }
445
446 // move() was invoked with Qt::WA_WState_Created not set (frame geometry
447 // unknown), that is, crect has a position including the frame.
448 // If we can determine the frame strut, fix that and clear the flag.
449 void QWidgetPrivate::fixPosIncludesFrame()
450 {
451     Q_Q(QWidget);
452     if (QTLWExtra *te = maybeTopData()) {
453         if (te->posIncludesFrame) {
454             // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for
455             // example, in QGraphicsProxyWidget).
456             if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
457                 te->posIncludesFrame = 0;
458             } else {
459                 if (q->windowHandle()) {
460                     updateFrameStrut();
461                     if (!q->data->fstrut_dirty) {
462                         data.crect.translate(te->frameStrut.x(), te->frameStrut.y());
463                         te->posIncludesFrame = 0;
464                     }
465                 } // windowHandle()
466             } // !WA_DontShowOnScreen
467         } // posIncludesFrame
468     } // QTLWExtra
469 }
470
471 void QWidgetPrivate::show_sys()
472 {
473     Q_Q(QWidget);
474
475     QWindow *window = q->windowHandle();
476
477     if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
478         invalidateBuffer(q->rect());
479         q->setAttribute(Qt::WA_Mapped);
480         if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
481             // add our window to the modal window list
482             QGuiApplicationPrivate::showModalWindow(window);
483         }
484         return;
485     }
486
487     QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
488
489     if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
490         return;
491
492     if (window) {
493         if (q->isWindow())
494             fixPosIncludesFrame();
495         QRect geomRect = q->geometry();
496         if (q->isWindow()) {
497             if (!q->testAttribute(Qt::WA_Moved))
498                 geomRect = positionTopLevelWindow(geomRect, window->screen());
499         } else {
500             QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
501             geomRect.moveTopLeft(topLeftOfWindow);
502         }
503         const QRect windowRect = window->geometry();
504         if (windowRect != geomRect) {
505             window->setGeometry(geomRect);
506         }
507
508         if (QBackingStore *store = q->backingStore()) {
509             if (store->size() != geomRect.size()) {
510                 store->resize(geomRect.size());
511             }
512         }
513
514         invalidateBuffer(q->rect());
515         window->setVisible(true);
516     }
517 }
518
519
520 void QWidgetPrivate::hide_sys()
521 {
522     Q_Q(QWidget);
523
524     QWindow *window = q->windowHandle();
525
526     if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
527         q->setAttribute(Qt::WA_Mapped, false);
528         if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
529             // remove our window from the modal window list
530             QGuiApplicationPrivate::hideModalWindow(window);
531         }
532         // do not return here, if window non-zero, we must hide it
533     }
534
535     deactivateWidgetCleanup();
536
537     if (!q->isWindow()) {
538         QWidget *p = q->parentWidget();
539         if (p &&p->isVisible()) {
540             invalidateBuffer(q->rect());
541         }
542         return;
543     }
544
545     invalidateBuffer(q->rect());
546
547     if (window)
548         window->setVisible(false);
549 }
550
551 void QWidgetPrivate::setMaxWindowState_helper()
552 {
553     Q_Q(QWidget);
554
555     const uint old_state = data.in_set_window_state;
556     data.in_set_window_state = 1;
557
558     const QRect desktop = qApp->desktop()->availableGeometry(qApp->desktop()->screenNumber(q));
559     q->setGeometry(desktop);
560
561     data.in_set_window_state = old_state;
562 }
563
564 void QWidgetPrivate::setFullScreenSize_helper()
565 {
566     Q_Q(QWidget);
567
568     const uint old_state = data.in_set_window_state;
569     data.in_set_window_state = 1;
570
571     const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
572     q->move(screen.topLeft());
573     q->resize(screen.size());
574
575     data.in_set_window_state = old_state;
576 }
577
578 Qt::WindowState effectiveState(Qt::WindowStates state)
579  {
580      if (state & Qt::WindowMinimized)
581          return Qt::WindowMinimized;
582      else if (state & Qt::WindowFullScreen)
583          return Qt::WindowFullScreen;
584      else if (state & Qt::WindowMaximized)
585          return Qt::WindowMaximized;
586      return Qt::WindowNoState;
587  }
588
589 void QWidget::setWindowState(Qt::WindowStates newstate)
590 {
591     Q_D(QWidget);
592     Qt::WindowStates oldstate = windowState();
593     if (oldstate == newstate)
594         return;
595     if (isWindow() && !testAttribute(Qt::WA_WState_Created))
596         create();
597
598     data->window_state = newstate;
599     data->in_set_window_state = 1;
600     bool needShow = false;
601     Qt::WindowState newEffectiveState = effectiveState(newstate);
602     Qt::WindowState oldEffectiveState = effectiveState(oldstate);
603     if (isWindow() && newEffectiveState != oldEffectiveState) {
604         d->createTLExtra();
605         if (oldEffectiveState == Qt::WindowNoState)
606             d->topData()->normalGeometry = geometry();
607
608         Q_ASSERT(windowHandle());
609         windowHandle()->setWindowState(newEffectiveState);
610         bool supported = windowHandle()->windowState() == newEffectiveState;
611
612         if (!supported) {
613             // undo the effects of the old emulated state
614             if (oldEffectiveState == Qt::WindowFullScreen) {
615                 setParent(0, d->topData()->savedFlags);
616                 needShow = true;
617             } else if (oldEffectiveState == Qt::WindowMinimized) {
618                 needShow = true;
619             }
620
621             // emulate the new window state
622             if (newEffectiveState == Qt::WindowMinimized) {
623                 //### not ideal...
624                 hide();
625                 needShow = false;
626             } else if (newEffectiveState == Qt::WindowFullScreen) {
627                 d->topData()->savedFlags = windowFlags();
628                 setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
629                 d->setFullScreenSize_helper();
630                 raise();
631                 needShow = true;
632             } else if (newEffectiveState == Qt::WindowMaximized) {
633                 createWinId();
634                 d->setMaxWindowState_helper();
635             } else if (newEffectiveState == Qt::WindowNoState) {
636                 // reset old geometry
637                 QRect r = d->topData()->normalGeometry;
638                 if (r.width() >= 0) {
639                     d->topData()->normalGeometry = QRect(0,0,-1,-1);
640                     setGeometry(r);
641                 }
642             }
643         }
644     }
645     data->in_set_window_state = 0;
646
647     if (needShow)
648         show();
649
650     if (newstate & Qt::WindowActive)
651         activateWindow();
652
653     QWindowStateChangeEvent e(oldstate);
654     QApplication::sendEvent(this, &e);
655 }
656
657 void QWidgetPrivate::setFocus_sys()
658 {
659
660 }
661
662 void QWidgetPrivate::raise_sys()
663 {
664     Q_Q(QWidget);
665     if (q->isWindow()) {
666         q->windowHandle()->raise();
667     }
668 }
669
670 void QWidgetPrivate::lower_sys()
671 {
672     Q_Q(QWidget);
673     if (q->isWindow()) {
674         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
675         q->windowHandle()->lower();
676     } else if (QWidget *p = q->parentWidget()) {
677         setDirtyOpaqueRegion();
678         p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
679     }
680 }
681
682 void QWidgetPrivate::stackUnder_sys(QWidget*)
683 {
684     Q_Q(QWidget);
685     if (QWidget *p = q->parentWidget()) {
686         setDirtyOpaqueRegion();
687         p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
688     }
689 }
690
691 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
692 {
693     Q_Q(QWidget);
694     if (extra) {                                // any size restrictions?
695         w = qMin(w,extra->maxw);
696         h = qMin(h,extra->maxh);
697         w = qMax(w,extra->minw);
698         h = qMax(h,extra->minh);
699     }
700
701     QPoint oldp = q->geometry().topLeft();
702     QSize olds = q->size();
703     QRect r(x, y, w, h);
704
705     bool isResize = olds != r.size();
706     isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
707
708
709     // We only care about stuff that changes the geometry, or may
710     // cause the window manager to change its state
711     if (r.size() == olds && oldp == r.topLeft())
712         return;
713
714     if (!data.in_set_window_state) {
715         q->data->window_state &= ~Qt::WindowMaximized;
716         q->data->window_state &= ~Qt::WindowFullScreen;
717         if (q->isWindow())
718             topData()->normalGeometry = QRect(0, 0, -1, -1);
719     }
720
721     QPoint oldPos = q->pos();
722     data.crect = r;
723
724     bool needsShow = false;
725
726     if (w == 0 || h == 0) {
727         q->setAttribute(Qt::WA_OutsideWSRange, true);
728         if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
729             hide_sys();
730         data.crect = QRect(x, y, w, h);
731     } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
732         q->setAttribute(Qt::WA_OutsideWSRange, false);
733         needsShow = true;
734     }
735
736     if (q->isVisible()) {
737         if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
738             if (q->windowHandle()) {
739                 if (q->isWindow()) {
740                     q->windowHandle()->setGeometry(q->geometry());
741                 } else {
742                     QPoint posInNativeParent =  q->mapTo(q->nativeParentWidget(),QPoint());
743                     q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
744                 }
745                 const QWidgetBackingStore *bs = maybeBackingStore();
746                 if (bs->store) {
747                     if (isResize)
748                         bs->store->resize(r.size());
749                 }
750
751                 if (needsShow)
752                     show_sys();
753             } else {
754                 if (isMove && !isResize)
755                     moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
756                 else
757                     invalidateBuffer_resizeHelper(oldPos, olds);
758             }
759         }
760
761         if (isMove) {
762             QMoveEvent e(q->pos(), oldPos);
763             QApplication::sendEvent(q, &e);
764         }
765         if (isResize) {
766             QResizeEvent e(r.size(), olds);
767             QApplication::sendEvent(q, &e);
768             if (q->windowHandle())
769                 q->update();
770         }
771     } else { // not visible
772         if (isMove && q->pos() != oldPos)
773             q->setAttribute(Qt::WA_PendingMoveEvent, true);
774         if (isResize)
775             q->setAttribute(Qt::WA_PendingResizeEvent, true);
776     }
777
778 }
779
780 void QWidgetPrivate::setConstraints_sys()
781 {
782     Q_Q(QWidget);
783     if (extra && q->windowHandle()) {
784         QWindow *win = q->windowHandle();
785         QWindowPrivate *winp = qt_window_private(win);
786
787         winp->minimumSize = QSize(extra->minw, extra->minh);
788         winp->maximumSize = QSize(extra->maxw, extra->maxh);
789
790         if (extra->topextra) {
791             winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
792             winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
793         }
794
795         if (winp->platformWindow) {
796             fixPosIncludesFrame();
797             winp->platformWindow->propagateSizeHints();
798         }
799     }
800 }
801
802 void QWidgetPrivate::scroll_sys(int dx, int dy)
803 {
804     Q_Q(QWidget);
805     scrollChildren(dx, dy);
806     scrollRect(q->rect(), dx, dy);
807 }
808
809 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
810 {
811     scrollRect(r, dx, dy);
812 }
813
814 int QWidget::metric(PaintDeviceMetric m) const
815 {
816     Q_D(const QWidget);
817
818     QScreen *screen = 0;
819     if (QWidget *topLevel = window())
820         if (QWindow *topLevelWindow = topLevel->windowHandle()) {
821             QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
822             if (platformScreen)
823                 screen = platformScreen->screen();
824         }
825     if (!screen && QGuiApplication::primaryScreen())
826         screen = QGuiApplication::primaryScreen();
827
828     if (!screen) {
829         if (m == PdmDpiX || m == PdmDpiY)
830               return 72;
831         return QPaintDevice::metric(m);
832     }
833     int val;
834     if (m == PdmWidth) {
835         val = data->crect.width();
836     } else if (m == PdmWidthMM) {
837         val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
838     } else if (m == PdmHeight) {
839         val = data->crect.height();
840     } else if (m == PdmHeightMM) {
841         val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
842     } else if (m == PdmDepth) {
843         return screen->depth();
844     } else if (m == PdmDpiX) {
845         if (d->extra && d->extra->customDpiX)
846             return d->extra->customDpiX;
847         else if (d->parent)
848             return static_cast<QWidget *>(d->parent)->metric(m);
849         return qRound(screen->logicalDotsPerInchX());
850     } else if (m == PdmDpiY) {
851         if (d->extra && d->extra->customDpiY)
852             return d->extra->customDpiY;
853         else if (d->parent)
854             return static_cast<QWidget *>(d->parent)->metric(m);
855         return qRound(screen->logicalDotsPerInchY());
856     } else if (m == PdmPhysicalDpiX) {
857         return qRound(screen->physicalDotsPerInchX());
858     } else if (m == PdmPhysicalDpiY) {
859         return qRound(screen->physicalDotsPerInchY());
860     } else {
861         val = QPaintDevice::metric(m);// XXX
862     }
863     return val;
864 }
865
866 /*!
867     \preliminary
868
869     Returns the QPlatformWindow this widget will be drawn into.
870 */
871 QWindow *QWidget::windowHandle() const
872 {
873     Q_D(const QWidget);
874     QTLWExtra *extra = d->maybeTopData();
875     if (extra)
876         return extra->window;
877
878     return 0;
879 }
880
881 void QWidgetPrivate::createSysExtra()
882 {
883 }
884
885 void QWidgetPrivate::deleteSysExtra()
886 {
887
888 }
889
890 void QWidgetPrivate::createTLSysExtra()
891 {
892     Q_Q(QWidget);
893     extra->topextra->screenIndex = 0;
894     extra->topextra->window = 0;
895     if (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())
896         extra->topextra->window = new QWidgetWindow(q);
897 }
898
899 void QWidgetPrivate::deleteTLSysExtra()
900 {
901     if (extra && extra->topextra) {
902         //the toplevel might have a context with a "qglcontext associated with it. We need to
903         //delete the qglcontext before we delete the qplatformopenglcontext.
904         //One unfortunate thing about this is that we potentially create a glContext just to
905         //delete it straight afterwards.
906         if (extra->topextra->window) {
907             extra->topextra->window->destroy();
908         }
909         setWinId(0);
910         //hmmm. should we delete window..
911         delete extra->topextra->window;
912         extra->topextra->window = 0;
913     }
914 }
915
916 void QWidgetPrivate::registerDropSite(bool on)
917 {
918     Q_UNUSED(on);
919 }
920
921 void QWidgetPrivate::setMask_sys(const QRegion &region)
922 {
923     Q_UNUSED(region);
924     // XXX
925 }
926
927 void QWidgetPrivate::updateFrameStrut()
928 {
929     Q_Q(QWidget);
930     if (q->data->fstrut_dirty) {
931         if (QTLWExtra *te = maybeTopData()) {
932             if (te->window) {
933                 if (const QPlatformWindow *pw = te->window->handle()) {
934                     const QMargins margins = pw->frameMargins();
935                     if (!margins.isNull()) {
936                         te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
937                         q->data->fstrut_dirty = false;
938                     }
939                 }
940             }
941         }
942     }
943 }
944
945 void QWidgetPrivate::setWindowOpacity_sys(qreal level)
946 {
947     Q_Q(QWidget);
948     if (q->windowHandle())
949         q->windowHandle()->setOpacity(level);
950 }
951
952 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
953 {
954     Q_UNUSED(dontShow);
955     Q_UNUSED(oldRect);
956     // XXX
957 }
958
959 QPaintEngine *QWidget::paintEngine() const
960 {
961     qWarning("QWidget::paintEngine: Should no longer be called");
962     return 0; //##### @@@
963 }
964
965 void QWidgetPrivate::setModal_sys()
966 {
967     Q_Q(QWidget);
968     if (q->windowHandle())
969         q->windowHandle()->setWindowModality(q->windowModality());
970 }
971
972 #ifndef QT_NO_CURSOR
973 static inline void applyCursor(QWidget *w, QCursor c)
974 {
975     if (QWindow *window = w->windowHandle())
976         if (const QScreen *screen = window->screen())
977             if (QPlatformCursor *cursor = screen->handle()->cursor())
978                 cursor->changeCursor(&c, window);
979 }
980
981 void qt_qpa_set_cursor(QWidget *w, bool force)
982 {
983     if (!w->testAttribute(Qt::WA_WState_Created))
984         return;
985
986     static QPointer<QWidget> lastUnderMouse = 0;
987     if (force) {
988         lastUnderMouse = w;
989     } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
990         w = lastUnderMouse;
991     } else if (!w->internalWinId()) {
992         return; // The mouse is not under this widget, and it's not native, so don't change it.
993     }
994
995     while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
996            && !w->testAttribute(Qt::WA_SetCursor))
997         w = w->parentWidget();
998
999     QWidget *nativeParent = w;
1000     if (!w->internalWinId())
1001         nativeParent = w->nativeParentWidget();
1002     if (!nativeParent || !nativeParent->internalWinId())
1003         return;
1004
1005     if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
1006         QCursor *oc = QApplication::overrideCursor();
1007         if (oc)
1008             applyCursor(nativeParent, *oc);
1009         else if (w->isEnabled())
1010             applyCursor(nativeParent, w->cursor());
1011         else
1012             // Enforce the windows behavior of clearing the cursor on
1013             // disabled widgets.
1014             applyCursor(nativeParent, Qt::ArrowCursor);
1015     } else {
1016         applyCursor(nativeParent, Qt::ArrowCursor);
1017     }
1018 }
1019 #endif //QT_NO_CURSOR 
1020
1021 QT_END_NAMESPACE