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