Update spec to build Qt 5.0
[profile/ivi/qtbase.git] / src / widgets / kernel / qwidget_qpa.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
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.
16 **
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.
24 **
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.
28 **
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.
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 <qpa/qplatformintegration.h>
54 #include "QtGui/private/qwindow_p.h"
55
56 #include <qpa/qplatformcursor.h>
57 #include <QtGui/QGuiApplication>
58 #include <QtGui/QScreen>
59 #include <QtCore/QMargins>
60
61 QT_BEGIN_NAMESPACE
62
63 void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
64 {
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())
72                         childWidget->winId();
73                     if (childWidget->windowHandle()) {
74                         QWindow *parentWindow = childWidget->nativeParentWidget()->windowHandle();
75                         if (childWidget->isWindow())
76                             childWidget->windowHandle()->setTransientParent(parentWindow);
77                         else
78                             childWidget->windowHandle()->setParent(parentWindow);
79                     }
80                 } else {
81                     q_createNativeChildrenAndSetParent(childWidget);
82                 }
83             }
84         }
85     }
86
87 }
88
89 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
90 {
91     Q_Q(QWidget);
92
93     Q_UNUSED(window);
94     Q_UNUSED(initializeWindow);
95     Q_UNUSED(destroyOldWindow);
96
97     Qt::WindowFlags flags = data.window_flags;
98
99     if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
100         return; // we only care about real toplevels
101
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.
105     if (!win) {
106         createTLSysExtra();
107         win = topData()->window;
108     }
109
110     win->setFlags(data.window_flags);
111     fixPosIncludesFrame();
112     win->setGeometry(q->geometry());
113     win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0));
114
115     if (q->testAttribute(Qt::WA_TranslucentBackground)) {
116         QSurfaceFormat format;
117         format.setAlphaBufferSize(8);
118         win->setFormat(format);
119     }
120
121     if (QWidget *nativeParent = q->nativeParentWidget()) {
122         if (nativeParent->windowHandle()) {
123             if (flags & Qt::Window) {
124                 win->setTransientParent(nativeParent->windowHandle());
125                 win->setParent(0);
126             } else {
127                 win->setTransientParent(0);
128                 win->setParent(nativeParent->windowHandle());
129             }
130         }
131     }
132
133     qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ?
134         QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive;
135     win->create();
136
137     data.window_flags = win->flags();
138
139     QBackingStore *store = q->backingStore();
140
141     if (!store) {
142         if (win && q->windowType() != Qt::Desktop)
143             q->setBackingStore(new QBackingStore(win));
144         else
145             q->setAttribute(Qt::WA_PaintOnScreen, true);
146     }
147
148     setWindowModified_helper();
149     setWinId(win->winId());
150
151     // Check children and create windows for them if necessary
152     q_createNativeChildrenAndSetParent(q);
153
154     if (extra && !extra->mask.isEmpty())
155         setMask_sys(extra->mask);
156
157     // If widget is already shown, set window visible, too
158     if (q->isVisible())
159         win->setVisible(true);
160 }
161
162 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
163 {
164     Q_D(QWidget);
165
166     d->aboutToDestroy();
167     if (!isWindow() && parentWidget())
168         parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
169     d->deactivateWidgetCleanup();
170
171     if ((windowType() == Qt::Popup))
172         qApp->d_func()->closePopup(this);
173
174     if (this == QApplicationPrivate::active_window)
175         QApplication::setActiveWindow(0);
176     if (QWidget::mouseGrabber() == this)
177         releaseMouse();
178     if (QWidget::keyboardGrabber() == this)
179         releaseKeyboard();
180
181     setAttribute(Qt::WA_WState_Created, false);
182
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()) {
190                         widget->destroy();
191                     }
192                 }
193             }
194         }
195         if (destroyWindow) {
196             d->deleteTLSysExtra();
197         } else {
198             if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
199                 d->hide_sys();
200             }
201         }
202
203         d->setWinId(0);
204     }
205 }
206
207 void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
208 {
209     Q_Q(QWidget);
210
211     Qt::WindowFlags oldFlags = data.window_flags;
212     bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
213
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
219
220         // get the desktop's screen number
221         targetScreen = newparent->window()->d_func()->topData()->screenIndex;
222         newparent = 0;
223     }
224
225     setWinId(0);
226
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);
237                 } else {
238                     q->windowHandle()->setTransientParent(0);
239                     q->windowHandle()->setParent(parentWithWindow->windowHandle());
240                 }
241             } else {
242                 q->windowHandle()->setTransientParent(0);
243                 q->windowHandle()->setParent(0);
244             }
245         }
246     }
247
248     if (!newparent) {
249         f |= Qt::Window;
250         if (targetScreen == -1) {
251             if (parent)
252                 targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex;
253         }
254     }
255
256     bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
257
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";
261         q->destroy();
262     }
263
264     adjustFlags(f, q);
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);
269
270     if (newparent && wasCreated && (q->testAttribute(Qt::WA_NativeWindow) || (f & Qt::Window)))
271         q->createWinId();
272
273     if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
274         q->setAttribute(Qt::WA_WState_Hidden);
275     q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
276
277     // move the window to the selected screen
278     if (!newparent && targetScreen != -1) {
279         if (maybeTopData())
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));
284         }
285     }
286 }
287
288 QPoint QWidget::mapToGlobal(const QPoint &pos) const
289 {
290     int x = pos.x(), y = pos.y();
291     const QWidget *w = this;
292     while (w) {
293         QWindow *window = w->windowHandle();
294         if (window && window->handle())
295             return window->mapToGlobal(QPoint(x, y));
296
297         x += w->data->crect.x();
298         y += w->data->crect.y();
299         w = w->isWindow() ? 0 : w->parentWidget();
300     }
301     return QPoint(x, y);
302 }
303
304 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
305 {
306     int x = pos.x(), y = pos.y();
307     const QWidget *w = this;
308     while (w) {
309         QWindow *window = w->windowHandle();
310         if (window && window->handle())
311             return window->mapFromGlobal(QPoint(x, y));
312
313         x -= w->data->crect.x();
314         y -= w->data->crect.y();
315         w = w->isWindow() ? 0 : w->parentWidget();
316     }
317     return QPoint(x, y);
318 }
319
320 void QWidgetPrivate::updateSystemBackground() {}
321
322 #ifndef QT_NO_CURSOR
323 void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
324 {
325     Q_UNUSED(cursor);
326     Q_Q(QWidget);
327     qt_qpa_set_cursor(q, false);
328 }
329
330 void QWidgetPrivate::unsetCursor_sys()
331 {
332     Q_Q(QWidget);
333     qt_qpa_set_cursor(q, false);
334 }
335
336 #endif //QT_NO_CURSOR
337
338 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
339 {
340     Q_Q(QWidget);
341     if (!q->isWindow())
342         return;
343
344     if (QWindow *window = q->windowHandle())
345         window->setTitle(caption);
346
347 }
348
349 void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath)
350 {
351     Q_Q(QWidget);
352     if (!q->isWindow())
353         return;
354
355     if (QWindow *window = q->windowHandle())
356         window->setFilePath(filePath);
357 }
358
359 void QWidgetPrivate::setWindowIcon_sys()
360 {
361     Q_Q(QWidget);
362     if (QWindow *window = q->windowHandle())
363         window->setIcon(q->windowIcon());
364 }
365
366 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
367 {
368     Q_UNUSED(iconText);
369 }
370
371 QWidget *qt_pressGrab = 0;
372 QWidget *qt_mouseGrb = 0;
373 static QWidget *keyboardGrb = 0;
374
375 static inline QWindow *grabberWindow(const QWidget *w)
376 {
377     QWindow *window = w->windowHandle();
378     if (!window)
379         if (const QWidget *nativeParent = w->nativeParentWidget())
380             window = nativeParent->windowHandle();
381     return window;
382 }
383
384 void QWidget::grabMouse()
385 {
386     if (qt_mouseGrb)
387         qt_mouseGrb->releaseMouse();
388
389     if (QWindow *window = grabberWindow(this))
390         window->setMouseGrabEnabled(true);
391
392     qt_mouseGrb = this;
393     qt_pressGrab = 0;
394 }
395
396 #ifndef QT_NO_CURSOR
397 void QWidget::grabMouse(const QCursor &cursor)
398 {
399     Q_UNUSED(cursor);
400     grabMouse();
401 }
402 #endif
403
404 bool QWidgetPrivate::stealMouseGrab(bool grab)
405 {
406     // This is like a combination of grab/releaseMouse() but with error checking
407     // and it has no effect on the result of mouseGrabber().
408     Q_Q(QWidget);
409     QWindow *window = grabberWindow(q);
410     return window ? window->setMouseGrabEnabled(grab) : false;
411 }
412
413 void QWidget::releaseMouse()
414 {
415     if (qt_mouseGrb == this) {
416         if (QWindow *window = grabberWindow(this))
417             window->setMouseGrabEnabled(false);
418         qt_mouseGrb = 0;
419     }
420 }
421
422 void QWidget::grabKeyboard()
423 {
424     if (keyboardGrb)
425         keyboardGrb->releaseKeyboard();
426     if (QWindow *window = grabberWindow(this))
427         window->setKeyboardGrabEnabled(true);
428     keyboardGrb = this;
429 }
430
431 bool QWidgetPrivate::stealKeyboardGrab(bool grab)
432 {
433     // This is like a combination of grab/releaseKeyboard() but with error
434     // checking and it has no effect on the result of keyboardGrabber().
435     Q_Q(QWidget);
436     QWindow *window = grabberWindow(q);
437     return window ? window->setKeyboardGrabEnabled(grab) : false;
438 }
439
440 void QWidget::releaseKeyboard()
441 {
442     if (keyboardGrb == this) {
443         if (QWindow *window = grabberWindow(this))
444             window->setKeyboardGrabEnabled(false);
445         keyboardGrb = 0;
446     }
447 }
448
449 QWidget *QWidget::mouseGrabber()
450 {
451     if (qt_mouseGrb)
452         return qt_mouseGrb;
453     return qt_pressGrab;
454 }
455
456 QWidget *QWidget::keyboardGrabber()
457 {
458     return keyboardGrb;
459 }
460
461 void QWidget::activateWindow()
462 {
463     QWindow *const wnd = window()->windowHandle();
464
465     if (wnd)
466         wnd->requestActivate();
467 }
468
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)
472 {
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());
478     }
479     return geometry;
480 }
481
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()
486 {
487     Q_Q(QWidget);
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;
494             } else {
495                 if (q->windowHandle()) {
496                     updateFrameStrut();
497                     if (!q->data->fstrut_dirty) {
498                         data.crect.translate(te->frameStrut.x(), te->frameStrut.y());
499                         te->posIncludesFrame = 0;
500                     }
501                 } // windowHandle()
502             } // !WA_DontShowOnScreen
503         } // posIncludesFrame
504     } // QTLWExtra
505 }
506
507 void QWidgetPrivate::show_sys()
508 {
509     Q_Q(QWidget);
510
511     QWindow *window = q->windowHandle();
512
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);
519         }
520         return;
521     }
522
523     QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
524
525     if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
526         return;
527
528     if (window) {
529         if (q->isWindow())
530             fixPosIncludesFrame();
531         QRect geomRect = q->geometry();
532         if (q->isWindow()) {
533             if (!q->testAttribute(Qt::WA_Moved))
534                 geomRect = positionTopLevelWindow(geomRect, window->screen());
535         } else {
536             QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
537             geomRect.moveTopLeft(topLeftOfWindow);
538         }
539         const QRect windowRect = window->geometry();
540         if (windowRect != geomRect) {
541             window->setGeometry(geomRect);
542         }
543
544         if (QBackingStore *store = q->backingStore()) {
545             if (store->size() != geomRect.size()) {
546                 store->resize(geomRect.size());
547             }
548         }
549
550 #ifndef QT_NO_CURSOR
551         qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show
552 #endif
553         invalidateBuffer(q->rect());
554         window->setVisible(true);
555     }
556 }
557
558
559 void QWidgetPrivate::hide_sys()
560 {
561     Q_Q(QWidget);
562
563     QWindow *window = q->windowHandle();
564
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);
570         }
571         // do not return here, if window non-zero, we must hide it
572     }
573
574     deactivateWidgetCleanup();
575
576     if (!q->isWindow()) {
577         QWidget *p = q->parentWidget();
578         if (p &&p->isVisible()) {
579             invalidateBuffer(q->rect());
580         }
581     } else {
582         invalidateBuffer(q->rect());
583     }
584
585     if (window)
586         window->setVisible(false);
587 }
588
589 Qt::WindowState effectiveState(Qt::WindowStates state)
590  {
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;
598  }
599
600 void QWidget::setWindowState(Qt::WindowStates newstate)
601 {
602     Q_D(QWidget);
603     Qt::WindowStates oldstate = windowState();
604     if (oldstate == newstate)
605         return;
606     if (isWindow() && !testAttribute(Qt::WA_WState_Created))
607         create();
608
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())
616             adjustSize();
617
618         d->createTLExtra();
619         if (oldEffectiveState == Qt::WindowNoState)
620             d->topData()->normalGeometry = geometry();
621
622         Q_ASSERT(windowHandle());
623         windowHandle()->setWindowState(newEffectiveState);
624     }
625     data->in_set_window_state = 0;
626
627     if (newstate & Qt::WindowActive)
628         activateWindow();
629
630     QWindowStateChangeEvent e(oldstate);
631     QApplication::sendEvent(this, &e);
632 }
633
634 void QWidgetPrivate::setFocus_sys()
635 {
636     Q_Q(QWidget);
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();
644             }
645         }
646     }
647 }
648
649 void QWidgetPrivate::raise_sys()
650 {
651     Q_Q(QWidget);
652     if (q->isWindow() || q->testAttribute(Qt::WA_NativeWindow)) {
653         q->windowHandle()->raise();
654     }
655 }
656
657 void QWidgetPrivate::lower_sys()
658 {
659     Q_Q(QWidget);
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()));
666     }
667 }
668
669 void QWidgetPrivate::stackUnder_sys(QWidget*)
670 {
671     Q_Q(QWidget);
672     if (QWidget *p = q->parentWidget()) {
673         setDirtyOpaqueRegion();
674         p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
675     }
676 }
677
678 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
679 {
680     Q_Q(QWidget);
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);
686     }
687
688     QPoint oldp = q->geometry().topLeft();
689     QSize olds = q->size();
690     QRect r(x, y, w, h);
691
692     bool isResize = olds != r.size();
693     isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
694
695
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())
699         return;
700
701     if (!data.in_set_window_state) {
702         q->data->window_state &= ~Qt::WindowMaximized;
703         q->data->window_state &= ~Qt::WindowFullScreen;
704         if (q->isWindow())
705             topData()->normalGeometry = QRect(0, 0, -1, -1);
706     }
707
708     QPoint oldPos = q->pos();
709     data.crect = r;
710
711     bool needsShow = false;
712
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))
716             hide_sys();
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);
720         needsShow = true;
721     }
722
723     if (q->isVisible()) {
724         if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
725             if (q->windowHandle()) {
726                 if (q->isWindow()) {
727                     q->windowHandle()->setGeometry(q->geometry());
728                 } else {
729                     QPoint posInNativeParent =  q->mapTo(q->nativeParentWidget(),QPoint());
730                     q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
731                 }
732                 const QWidgetBackingStore *bs = maybeBackingStore();
733                 if (bs->store) {
734                     if (isResize)
735                         bs->store->resize(r.size());
736                 }
737
738                 if (needsShow)
739                     show_sys();
740             }
741
742             if (!q->isWindow()) {
743                 if (isMove && !isResize)
744                     moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
745                 else
746                     invalidateBuffer_resizeHelper(oldPos, olds);
747             }
748         }
749
750         if (isMove) {
751             QMoveEvent e(q->pos(), oldPos);
752             QApplication::sendEvent(q, &e);
753         }
754         if (isResize) {
755             QResizeEvent e(r.size(), olds);
756             QApplication::sendEvent(q, &e);
757             if (q->windowHandle())
758                 q->update();
759         }
760     } else { // not visible
761         if (isMove && q->pos() != oldPos)
762             q->setAttribute(Qt::WA_PendingMoveEvent, true);
763         if (isResize)
764             q->setAttribute(Qt::WA_PendingResizeEvent, true);
765     }
766
767 }
768
769 void QWidgetPrivate::setConstraints_sys()
770 {
771     Q_Q(QWidget);
772     if (extra && q->windowHandle()) {
773         QWindow *win = q->windowHandle();
774         QWindowPrivate *winp = qt_window_private(win);
775
776         winp->minimumSize = QSize(extra->minw, extra->minh);
777         winp->maximumSize = QSize(extra->maxw, extra->maxh);
778
779         if (extra->topextra) {
780             winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
781             winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
782         }
783
784         if (winp->platformWindow) {
785             fixPosIncludesFrame();
786             winp->platformWindow->propagateSizeHints();
787         }
788     }
789 }
790
791 void QWidgetPrivate::scroll_sys(int dx, int dy)
792 {
793     Q_Q(QWidget);
794     scrollChildren(dx, dy);
795     scrollRect(q->rect(), dx, dy);
796 }
797
798 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
799 {
800     scrollRect(r, dx, dy);
801 }
802
803 int QWidget::metric(PaintDeviceMetric m) const
804 {
805     Q_D(const QWidget);
806
807     QScreen *screen = 0;
808     if (QWidget *topLevel = window())
809         if (QWindow *topLevelWindow = topLevel->windowHandle()) {
810             QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
811             if (platformScreen)
812                 screen = platformScreen->screen();
813         }
814     if (!screen && QGuiApplication::primaryScreen())
815         screen = QGuiApplication::primaryScreen();
816
817     if (!screen) {
818         if (m == PdmDpiX || m == PdmDpiY)
819               return 72;
820         return QPaintDevice::metric(m);
821     }
822     int val;
823     if (m == PdmWidth) {
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;
836         else if (d->parent)
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;
842         else if (d->parent)
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());
849     } else {
850         val = QPaintDevice::metric(m);// XXX
851     }
852     return val;
853 }
854
855 /*!
856     \preliminary
857
858     Returns the QPlatformWindow this widget will be drawn into.
859 */
860 QWindow *QWidget::windowHandle() const
861 {
862     Q_D(const QWidget);
863     QTLWExtra *extra = d->maybeTopData();
864     if (extra)
865         return extra->window;
866
867     return 0;
868 }
869
870 void QWidgetPrivate::createSysExtra()
871 {
872 }
873
874 void QWidgetPrivate::deleteSysExtra()
875 {
876
877 }
878
879 void QWidgetPrivate::createTLSysExtra()
880 {
881     Q_Q(QWidget);
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));
890     }
891 }
892
893 void QWidgetPrivate::deleteTLSysExtra()
894 {
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();
902         }
903         setWinId(0);
904         delete extra->topextra->window;
905         extra->topextra->window = 0;
906
907         extra->topextra->backingStoreTracker.destroy();
908         delete extra->topextra->backingStore;
909         extra->topextra->backingStore = 0;
910
911     }
912 }
913
914 void QWidgetPrivate::registerDropSite(bool on)
915 {
916     Q_UNUSED(on);
917 }
918
919 void QWidgetPrivate::setMask_sys(const QRegion &region)
920 {
921     if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowMasks)) {
922         qWarning("%s: Not supported on %s.", Q_FUNC_INFO, qPrintable(QGuiApplication::platformName()));
923         return;
924     }
925     Q_Q(QWidget);
926     if (const QWindow *window = q->windowHandle())
927         if (QPlatformWindow *platformWindow = window->handle())
928             platformWindow->setMask(region);
929 }
930
931 void QWidgetPrivate::updateFrameStrut()
932 {
933     Q_Q(QWidget);
934     if (q->data->fstrut_dirty) {
935         if (QTLWExtra *te = maybeTopData()) {
936             if (te->window) {
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;
942                     }
943                 }
944             }
945         }
946     }
947 }
948
949 void QWidgetPrivate::setWindowOpacity_sys(qreal level)
950 {
951     Q_Q(QWidget);
952     if (q->windowHandle())
953         q->windowHandle()->setOpacity(level);
954 }
955
956 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
957 {
958     Q_UNUSED(dontShow);
959     Q_UNUSED(oldRect);
960     // XXX
961 }
962
963 QPaintEngine *QWidget::paintEngine() const
964 {
965     qWarning("QWidget::paintEngine: Should no longer be called");
966
967 #ifdef Q_OS_WIN
968     // We set this bit which is checked in setAttribute for
969     // Qt::WA_PaintOnScreen. We do this to allow these two scenarios:
970     //
971     // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to
972     // Windows which would mean suddenly their widgets stop working.
973     //
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.
977     //
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
981     // graphics stuff.
982     const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1;
983 #endif
984
985     return 0; //##### @@@
986 }
987
988 void QWidgetPrivate::setModal_sys()
989 {
990     Q_Q(QWidget);
991     if (q->windowHandle())
992         q->windowHandle()->setModality(q->windowModality());
993 }
994
995 #ifndef QT_NO_CURSOR
996 static inline void applyCursor(QWidget *w, QCursor c)
997 {
998     if (QWindow *window = w->windowHandle())
999         window->setCursor(c);
1000 }
1001
1002 void qt_qpa_set_cursor(QWidget *w, bool force)
1003 {
1004     if (!w->testAttribute(Qt::WA_WState_Created))
1005         return;
1006
1007     static QPointer<QWidget> lastUnderMouse = 0;
1008     if (force) {
1009         lastUnderMouse = w;
1010     } else if (lastUnderMouse) {
1011         const WId lastWinId = lastUnderMouse->effectiveWinId();
1012         const WId winId = w->effectiveWinId();
1013         if (lastWinId && lastWinId == winId)
1014             w = lastUnderMouse;
1015     } else if (!w->internalWinId()) {
1016         return; // The mouse is not under this widget, and it's not native, so don't change it.
1017     }
1018
1019     while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
1020            && !w->testAttribute(Qt::WA_SetCursor))
1021         w = w->parentWidget();
1022
1023     QWidget *nativeParent = w;
1024     if (!w->internalWinId())
1025         nativeParent = w->nativeParentWidget();
1026     if (!nativeParent || !nativeParent->internalWinId())
1027         return;
1028
1029     if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
1030         if (w->isEnabled())
1031             applyCursor(nativeParent, w->cursor());
1032         else
1033             // Enforce the windows behavior of clearing the cursor on
1034             // disabled widgets.
1035             applyCursor(nativeParent, Qt::ArrowCursor);
1036     } else {
1037         applyCursor(nativeParent, Qt::ArrowCursor);
1038     }
1039 }
1040 #endif //QT_NO_CURSOR 
1041
1042 QT_END_NAMESPACE