Implement QWidgetPrivate::setWindowIcon_sys()
[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()
332 {
333     Q_Q(QWidget);
334     if (QWindow *window = q->windowHandle())
335         window->setWindowIcon(q->windowIcon());
336 }
337
338 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
339 {
340     Q_UNUSED(iconText);
341 }
342
343 QWidget *qt_pressGrab = 0;
344 QWidget *qt_mouseGrb = 0;
345 static QWidget *keyboardGrb = 0;
346
347 void QWidget::grabMouse()
348 {
349     if (qt_mouseGrb)
350         qt_mouseGrb->releaseMouse();
351
352     if (windowHandle())
353         windowHandle()->setMouseGrabEnabled(true);
354
355     qt_mouseGrb = this;
356     qt_pressGrab = 0;
357 }
358
359 #ifndef QT_NO_CURSOR
360 void QWidget::grabMouse(const QCursor &cursor)
361 {
362     Q_UNUSED(cursor);
363
364     if (qt_mouseGrb)
365         qt_mouseGrb->releaseMouse();
366
367     if (windowHandle())
368         windowHandle()->setMouseGrabEnabled(true);
369
370     qt_mouseGrb = this;
371     qt_pressGrab = 0;
372 }
373 #endif
374
375 bool QWidgetPrivate::stealMouseGrab(bool grab)
376 {
377     // This is like a combination of grab/releaseMouse() but with error checking
378     // and it has no effect on the result of mouseGrabber().
379     Q_Q(QWidget);
380     return q->windowHandle() ? q->windowHandle()->setMouseGrabEnabled(grab) : false;
381 }
382
383 void QWidget::releaseMouse()
384 {
385     if (qt_mouseGrb == this) {
386         if (windowHandle())
387             windowHandle()->setMouseGrabEnabled(false);
388         qt_mouseGrb = 0;
389     }
390 }
391
392 void QWidget::grabKeyboard()
393 {
394     if (keyboardGrb)
395         keyboardGrb->releaseKeyboard();
396     if (windowHandle())
397         windowHandle()->setKeyboardGrabEnabled(true);
398     keyboardGrb = this;
399 }
400
401 bool QWidgetPrivate::stealKeyboardGrab(bool grab)
402 {
403     // This is like a combination of grab/releaseKeyboard() but with error
404     // checking and it has no effect on the result of keyboardGrabber().
405     Q_Q(QWidget);
406     return q->windowHandle() ? q->windowHandle()->setKeyboardGrabEnabled(grab) : false;
407 }
408
409 void QWidget::releaseKeyboard()
410 {
411     if (keyboardGrb == this) {
412         if (windowHandle())
413             windowHandle()->setKeyboardGrabEnabled(false);
414         keyboardGrb = 0;
415     }
416 }
417
418 QWidget *QWidget::mouseGrabber()
419 {
420     if (qt_mouseGrb)
421         return qt_mouseGrb;
422     return qt_pressGrab;
423 }
424
425 QWidget *QWidget::keyboardGrabber()
426 {
427     return keyboardGrb;
428 }
429
430 void QWidget::activateWindow()
431 {
432     if (windowHandle())
433         windowHandle()->requestActivateWindow();
434 }
435
436 // Position top level windows at the center, avoid showing
437 // Windows at the default 0,0 position excluding the frame.
438 static inline QRect positionTopLevelWindow(QRect geometry, const QScreen *screen)
439 {
440     if (screen && geometry.x() == 0 && geometry.y() == 0) {
441        const QRect availableGeometry = screen->availableGeometry();
442         if (availableGeometry.width() > geometry.width()
443             && availableGeometry.height() > geometry.height())
444             geometry.moveCenter(availableGeometry.center());
445     }
446     return geometry;
447 }
448
449 // move() was invoked with Qt::WA_WState_Created not set (frame geometry
450 // unknown), that is, crect has a position including the frame.
451 // If we can determine the frame strut, fix that and clear the flag.
452 void QWidgetPrivate::fixPosIncludesFrame()
453 {
454     Q_Q(QWidget);
455     if (QTLWExtra *te = maybeTopData()) {
456         if (te->posIncludesFrame) {
457             // For Qt::WA_DontShowOnScreen, assume a frame of 0 (for
458             // example, in QGraphicsProxyWidget).
459             if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
460                 te->posIncludesFrame = 0;
461             } else {
462                 if (q->windowHandle()) {
463                     updateFrameStrut();
464                     if (!q->data->fstrut_dirty) {
465                         data.crect.translate(te->frameStrut.x(), te->frameStrut.y());
466                         te->posIncludesFrame = 0;
467                     }
468                 } // windowHandle()
469             } // !WA_DontShowOnScreen
470         } // posIncludesFrame
471     } // QTLWExtra
472 }
473
474 void QWidgetPrivate::show_sys()
475 {
476     Q_Q(QWidget);
477
478     QWindow *window = q->windowHandle();
479
480     if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
481         invalidateBuffer(q->rect());
482         q->setAttribute(Qt::WA_Mapped);
483         if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
484             // add our window to the modal window list
485             QGuiApplicationPrivate::showModalWindow(window);
486         }
487         return;
488     }
489
490     QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
491
492     if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
493         return;
494
495     if (window) {
496         if (q->isWindow())
497             fixPosIncludesFrame();
498         QRect geomRect = q->geometry();
499         if (q->isWindow()) {
500             if (!q->testAttribute(Qt::WA_Moved))
501                 geomRect = positionTopLevelWindow(geomRect, window->screen());
502         } else {
503             QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
504             geomRect.moveTopLeft(topLeftOfWindow);
505         }
506         const QRect windowRect = window->geometry();
507         if (windowRect != geomRect) {
508             window->setGeometry(geomRect);
509         }
510
511         if (QBackingStore *store = q->backingStore()) {
512             if (store->size() != geomRect.size()) {
513                 store->resize(geomRect.size());
514             }
515         }
516
517         invalidateBuffer(q->rect());
518         window->setVisible(true);
519     }
520 }
521
522
523 void QWidgetPrivate::hide_sys()
524 {
525     Q_Q(QWidget);
526
527     QWindow *window = q->windowHandle();
528
529     if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
530         q->setAttribute(Qt::WA_Mapped, false);
531         if (q->isWindow() && q->windowModality() != Qt::NonModal && window) {
532             // remove our window from the modal window list
533             QGuiApplicationPrivate::hideModalWindow(window);
534         }
535         // do not return here, if window non-zero, we must hide it
536     }
537
538     deactivateWidgetCleanup();
539
540     if (!q->isWindow()) {
541         QWidget *p = q->parentWidget();
542         if (p &&p->isVisible()) {
543             invalidateBuffer(q->rect());
544         }
545         return;
546     }
547
548     invalidateBuffer(q->rect());
549
550     if (window)
551         window->setVisible(false);
552 }
553
554 void QWidgetPrivate::setMaxWindowState_helper()
555 {
556     Q_Q(QWidget);
557
558     const uint old_state = data.in_set_window_state;
559     data.in_set_window_state = 1;
560
561     const QRect desktop = qApp->desktop()->availableGeometry(qApp->desktop()->screenNumber(q));
562     q->setGeometry(desktop);
563
564     data.in_set_window_state = old_state;
565 }
566
567 void QWidgetPrivate::setFullScreenSize_helper()
568 {
569     Q_Q(QWidget);
570
571     const uint old_state = data.in_set_window_state;
572     data.in_set_window_state = 1;
573
574     const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
575     q->move(screen.topLeft());
576     q->resize(screen.size());
577
578     data.in_set_window_state = old_state;
579 }
580
581 Qt::WindowState effectiveState(Qt::WindowStates state)
582  {
583      if (state & Qt::WindowMinimized)
584          return Qt::WindowMinimized;
585      else if (state & Qt::WindowFullScreen)
586          return Qt::WindowFullScreen;
587      else if (state & Qt::WindowMaximized)
588          return Qt::WindowMaximized;
589      return Qt::WindowNoState;
590  }
591
592 void QWidget::setWindowState(Qt::WindowStates newstate)
593 {
594     Q_D(QWidget);
595     Qt::WindowStates oldstate = windowState();
596     if (oldstate == newstate)
597         return;
598     if (isWindow() && !testAttribute(Qt::WA_WState_Created))
599         create();
600
601     data->window_state = newstate;
602     data->in_set_window_state = 1;
603     bool needShow = false;
604     Qt::WindowState newEffectiveState = effectiveState(newstate);
605     Qt::WindowState oldEffectiveState = effectiveState(oldstate);
606     if (isWindow() && newEffectiveState != oldEffectiveState) {
607         d->createTLExtra();
608         if (oldEffectiveState == Qt::WindowNoState)
609             d->topData()->normalGeometry = geometry();
610
611         Q_ASSERT(windowHandle());
612         windowHandle()->setWindowState(newEffectiveState);
613         bool supported = windowHandle()->windowState() == newEffectiveState;
614
615         if (!supported) {
616             // undo the effects of the old emulated state
617             if (oldEffectiveState == Qt::WindowFullScreen) {
618                 setParent(0, d->topData()->savedFlags);
619                 needShow = true;
620             } else if (oldEffectiveState == Qt::WindowMinimized) {
621                 needShow = true;
622             }
623
624             // emulate the new window state
625             if (newEffectiveState == Qt::WindowMinimized) {
626                 //### not ideal...
627                 hide();
628                 needShow = false;
629             } else if (newEffectiveState == Qt::WindowFullScreen) {
630                 d->topData()->savedFlags = windowFlags();
631                 setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
632                 d->setFullScreenSize_helper();
633                 raise();
634                 needShow = true;
635             } else if (newEffectiveState == Qt::WindowMaximized) {
636                 createWinId();
637                 d->setMaxWindowState_helper();
638             } else if (newEffectiveState == Qt::WindowNoState) {
639                 // reset old geometry
640                 QRect r = d->topData()->normalGeometry;
641                 if (r.width() >= 0) {
642                     d->topData()->normalGeometry = QRect(0,0,-1,-1);
643                     setGeometry(r);
644                 }
645             }
646         }
647     }
648     data->in_set_window_state = 0;
649
650     if (needShow)
651         show();
652
653     if (newstate & Qt::WindowActive)
654         activateWindow();
655
656     QWindowStateChangeEvent e(oldstate);
657     QApplication::sendEvent(this, &e);
658 }
659
660 void QWidgetPrivate::setFocus_sys()
661 {
662
663 }
664
665 void QWidgetPrivate::raise_sys()
666 {
667     Q_Q(QWidget);
668     if (q->isWindow()) {
669         q->windowHandle()->raise();
670     }
671 }
672
673 void QWidgetPrivate::lower_sys()
674 {
675     Q_Q(QWidget);
676     if (q->isWindow()) {
677         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
678         q->windowHandle()->lower();
679     } else if (QWidget *p = q->parentWidget()) {
680         setDirtyOpaqueRegion();
681         p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
682     }
683 }
684
685 void QWidgetPrivate::stackUnder_sys(QWidget*)
686 {
687     Q_Q(QWidget);
688     if (QWidget *p = q->parentWidget()) {
689         setDirtyOpaqueRegion();
690         p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
691     }
692 }
693
694 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
695 {
696     Q_Q(QWidget);
697     if (extra) {                                // any size restrictions?
698         w = qMin(w,extra->maxw);
699         h = qMin(h,extra->maxh);
700         w = qMax(w,extra->minw);
701         h = qMax(h,extra->minh);
702     }
703
704     QPoint oldp = q->geometry().topLeft();
705     QSize olds = q->size();
706     QRect r(x, y, w, h);
707
708     bool isResize = olds != r.size();
709     isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
710
711
712     // We only care about stuff that changes the geometry, or may
713     // cause the window manager to change its state
714     if (r.size() == olds && oldp == r.topLeft())
715         return;
716
717     if (!data.in_set_window_state) {
718         q->data->window_state &= ~Qt::WindowMaximized;
719         q->data->window_state &= ~Qt::WindowFullScreen;
720         if (q->isWindow())
721             topData()->normalGeometry = QRect(0, 0, -1, -1);
722     }
723
724     QPoint oldPos = q->pos();
725     data.crect = r;
726
727     bool needsShow = false;
728
729     if (w == 0 || h == 0) {
730         q->setAttribute(Qt::WA_OutsideWSRange, true);
731         if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
732             hide_sys();
733         data.crect = QRect(x, y, w, h);
734     } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
735         q->setAttribute(Qt::WA_OutsideWSRange, false);
736         needsShow = true;
737     }
738
739     if (q->isVisible()) {
740         if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
741             if (q->windowHandle()) {
742                 if (q->isWindow()) {
743                     q->windowHandle()->setGeometry(q->geometry());
744                 } else {
745                     QPoint posInNativeParent =  q->mapTo(q->nativeParentWidget(),QPoint());
746                     q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
747                 }
748                 const QWidgetBackingStore *bs = maybeBackingStore();
749                 if (bs->store) {
750                     if (isResize)
751                         bs->store->resize(r.size());
752                 }
753
754                 if (needsShow)
755                     show_sys();
756             } else {
757                 if (isMove && !isResize)
758                     moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
759                 else
760                     invalidateBuffer_resizeHelper(oldPos, olds);
761             }
762         }
763
764         if (isMove) {
765             QMoveEvent e(q->pos(), oldPos);
766             QApplication::sendEvent(q, &e);
767         }
768         if (isResize) {
769             QResizeEvent e(r.size(), olds);
770             QApplication::sendEvent(q, &e);
771             if (q->windowHandle())
772                 q->update();
773         }
774     } else { // not visible
775         if (isMove && q->pos() != oldPos)
776             q->setAttribute(Qt::WA_PendingMoveEvent, true);
777         if (isResize)
778             q->setAttribute(Qt::WA_PendingResizeEvent, true);
779     }
780
781 }
782
783 void QWidgetPrivate::setConstraints_sys()
784 {
785     Q_Q(QWidget);
786     if (extra && q->windowHandle()) {
787         QWindow *win = q->windowHandle();
788         QWindowPrivate *winp = qt_window_private(win);
789
790         winp->minimumSize = QSize(extra->minw, extra->minh);
791         winp->maximumSize = QSize(extra->maxw, extra->maxh);
792
793         if (extra->topextra) {
794             winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
795             winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
796         }
797
798         if (winp->platformWindow) {
799             fixPosIncludesFrame();
800             winp->platformWindow->propagateSizeHints();
801         }
802     }
803 }
804
805 void QWidgetPrivate::scroll_sys(int dx, int dy)
806 {
807     Q_Q(QWidget);
808     scrollChildren(dx, dy);
809     scrollRect(q->rect(), dx, dy);
810 }
811
812 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
813 {
814     scrollRect(r, dx, dy);
815 }
816
817 int QWidget::metric(PaintDeviceMetric m) const
818 {
819     Q_D(const QWidget);
820
821     QScreen *screen = 0;
822     if (QWidget *topLevel = window())
823         if (QWindow *topLevelWindow = topLevel->windowHandle()) {
824             QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
825             if (platformScreen)
826                 screen = platformScreen->screen();
827         }
828     if (!screen && QGuiApplication::primaryScreen())
829         screen = QGuiApplication::primaryScreen();
830
831     if (!screen) {
832         if (m == PdmDpiX || m == PdmDpiY)
833               return 72;
834         return QPaintDevice::metric(m);
835     }
836     int val;
837     if (m == PdmWidth) {
838         val = data->crect.width();
839     } else if (m == PdmWidthMM) {
840         val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
841     } else if (m == PdmHeight) {
842         val = data->crect.height();
843     } else if (m == PdmHeightMM) {
844         val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
845     } else if (m == PdmDepth) {
846         return screen->depth();
847     } else if (m == PdmDpiX) {
848         if (d->extra && d->extra->customDpiX)
849             return d->extra->customDpiX;
850         else if (d->parent)
851             return static_cast<QWidget *>(d->parent)->metric(m);
852         return qRound(screen->logicalDotsPerInchX());
853     } else if (m == PdmDpiY) {
854         if (d->extra && d->extra->customDpiY)
855             return d->extra->customDpiY;
856         else if (d->parent)
857             return static_cast<QWidget *>(d->parent)->metric(m);
858         return qRound(screen->logicalDotsPerInchY());
859     } else if (m == PdmPhysicalDpiX) {
860         return qRound(screen->physicalDotsPerInchX());
861     } else if (m == PdmPhysicalDpiY) {
862         return qRound(screen->physicalDotsPerInchY());
863     } else {
864         val = QPaintDevice::metric(m);// XXX
865     }
866     return val;
867 }
868
869 /*!
870     \preliminary
871
872     Returns the QPlatformWindow this widget will be drawn into.
873 */
874 QWindow *QWidget::windowHandle() const
875 {
876     Q_D(const QWidget);
877     QTLWExtra *extra = d->maybeTopData();
878     if (extra)
879         return extra->window;
880
881     return 0;
882 }
883
884 void QWidgetPrivate::createSysExtra()
885 {
886 }
887
888 void QWidgetPrivate::deleteSysExtra()
889 {
890
891 }
892
893 void QWidgetPrivate::createTLSysExtra()
894 {
895     Q_Q(QWidget);
896     extra->topextra->screenIndex = 0;
897     extra->topextra->window = 0;
898     if (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())
899         extra->topextra->window = new QWidgetWindow(q);
900 }
901
902 void QWidgetPrivate::deleteTLSysExtra()
903 {
904     if (extra && extra->topextra) {
905         //the toplevel might have a context with a "qglcontext associated with it. We need to
906         //delete the qglcontext before we delete the qplatformopenglcontext.
907         //One unfortunate thing about this is that we potentially create a glContext just to
908         //delete it straight afterwards.
909         if (extra->topextra->window) {
910             extra->topextra->window->destroy();
911         }
912         setWinId(0);
913         //hmmm. should we delete window..
914         delete extra->topextra->window;
915         extra->topextra->window = 0;
916     }
917 }
918
919 void QWidgetPrivate::registerDropSite(bool on)
920 {
921     Q_UNUSED(on);
922 }
923
924 void QWidgetPrivate::setMask_sys(const QRegion &region)
925 {
926     Q_UNUSED(region);
927     // XXX
928 }
929
930 void QWidgetPrivate::updateFrameStrut()
931 {
932     Q_Q(QWidget);
933     if (q->data->fstrut_dirty) {
934         if (QTLWExtra *te = maybeTopData()) {
935             if (te->window) {
936                 if (const QPlatformWindow *pw = te->window->handle()) {
937                     const QMargins margins = pw->frameMargins();
938                     if (!margins.isNull()) {
939                         te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
940                         q->data->fstrut_dirty = false;
941                     }
942                 }
943             }
944         }
945     }
946 }
947
948 void QWidgetPrivate::setWindowOpacity_sys(qreal level)
949 {
950     Q_Q(QWidget);
951     if (q->windowHandle())
952         q->windowHandle()->setOpacity(level);
953 }
954
955 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
956 {
957     Q_UNUSED(dontShow);
958     Q_UNUSED(oldRect);
959     // XXX
960 }
961
962 QPaintEngine *QWidget::paintEngine() const
963 {
964     qWarning("QWidget::paintEngine: Should no longer be called");
965     return 0; //##### @@@
966 }
967
968 void QWidgetPrivate::setModal_sys()
969 {
970     Q_Q(QWidget);
971     if (q->windowHandle())
972         q->windowHandle()->setWindowModality(q->windowModality());
973 }
974
975 #ifndef QT_NO_CURSOR
976 static inline void applyCursor(QWidget *w, QCursor c)
977 {
978     if (QWindow *window = w->windowHandle())
979         if (const QScreen *screen = window->screen())
980             if (QPlatformCursor *cursor = screen->handle()->cursor())
981                 cursor->changeCursor(&c, window);
982 }
983
984 void qt_qpa_set_cursor(QWidget *w, bool force)
985 {
986     if (!w->testAttribute(Qt::WA_WState_Created))
987         return;
988
989     static QPointer<QWidget> lastUnderMouse = 0;
990     if (force) {
991         lastUnderMouse = w;
992     } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
993         w = lastUnderMouse;
994     } else if (!w->internalWinId()) {
995         return; // The mouse is not under this widget, and it's not native, so don't change it.
996     }
997
998     while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
999            && !w->testAttribute(Qt::WA_SetCursor))
1000         w = w->parentWidget();
1001
1002     QWidget *nativeParent = w;
1003     if (!w->internalWinId())
1004         nativeParent = w->nativeParentWidget();
1005     if (!nativeParent || !nativeParent->internalWinId())
1006         return;
1007
1008     if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
1009         QCursor *oc = QApplication::overrideCursor();
1010         if (oc)
1011             applyCursor(nativeParent, *oc);
1012         else if (w->isEnabled())
1013             applyCursor(nativeParent, w->cursor());
1014         else
1015             // Enforce the windows behavior of clearing the cursor on
1016             // disabled widgets.
1017             applyCursor(nativeParent, Qt::ArrowCursor);
1018     } else {
1019         applyCursor(nativeParent, Qt::ArrowCursor);
1020     }
1021 }
1022 #endif //QT_NO_CURSOR 
1023
1024 QT_END_NAMESPACE