Cocoa: Fix qmlscene flicker on startup.
[profile/ivi/qtbase.git] / src / plugins / platforms / windows / qwindowswindow.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (info@qt.nokia.com)
6 **
7 ** This file is part of the plugins of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qwindowswindow.h"
43 #include "qwindowsnativeimage.h"
44 #include "qwindowscontext.h"
45 #include "qwindowsdrag.h"
46 #include "qwindowsscreen.h"
47 #include "qwindowscursor.h"
48
49 #include <QtGui/QGuiApplication>
50 #include <QtGui/QScreen>
51 #include <QtGui/QWindow>
52 #include <QtGui/QWindowSystemInterface>
53
54 #include <QtCore/QDebug>
55
56 QT_BEGIN_NAMESPACE
57
58 static QByteArray debugWinStyle(DWORD style)
59 {
60
61     QByteArray rc = "0x";
62     rc += QByteArray::number(qulonglong(style), 16);
63     if (style & WS_POPUP)
64         rc += " WS_POPUP";
65     if (style & WS_CHILD)
66         rc += " WS_CHILD";
67     if (style & WS_OVERLAPPED)
68         rc += " WS_OVERLAPPED";
69     if (style & WS_CLIPSIBLINGS)
70         rc += " WS_CLIPSIBLINGS";
71     if (style & WS_CLIPCHILDREN)
72         rc += " WS_CLIPCHILDREN";
73     if (style & WS_THICKFRAME)
74         rc += " WS_THICKFRAME";
75     if (style & WS_DLGFRAME)
76         rc += " WS_DLGFRAME";
77     if (style & WS_SYSMENU)
78         rc += " WS_SYSMENU";
79     if (style & WS_MINIMIZEBOX)
80         rc += " WS_MINIMIZEBOX";
81     if (style & WS_MAXIMIZEBOX)
82         rc += " WS_MAXIMIZEBOX";
83     return rc;
84 }
85
86 static QByteArray debugWindowStates(Qt::WindowStates s)
87 {
88
89     QByteArray rc = "0x";
90     rc += QByteArray::number(int(s), 16);
91     if (s & Qt::WindowMinimized)
92         rc += " WindowMinimized";
93     if (s & Qt::WindowMaximized)
94         rc += " WindowMaximized";
95     if (s & Qt::WindowFullScreen)
96         rc += " WindowFullScreen";
97     if (s & Qt::WindowActive)
98         rc += " WindowActive";
99     return rc;
100 }
101
102 QDebug operator<<(QDebug d, const MINMAXINFO &i)
103 {
104     d.nospace() << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ','
105                 << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x
106                  << ',' << i.ptMaxPosition.y << " mintrack="
107                  << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y
108                  << " maxtrack=" << i.ptMaxTrackSize.x << ','
109                  << i.ptMaxTrackSize.y;
110     return d;
111 }
112
113 static inline QSize qSizeOfRect(const RECT &rect)
114 {
115     return QSize(rect.right -rect.left, rect.bottom - rect.top);
116 }
117
118 static inline QRect qrectFromRECT(const RECT &rect)
119 {
120     return QRect(QPoint(rect.left, rect.top), qSizeOfRect(rect));
121 }
122
123 QDebug operator<<(QDebug d, const RECT &r)
124 {
125     d.nospace() << "RECT: left/top=" << r.left << ',' << r.top
126                 << " right/bottom=" << r.right << ',' << r.bottom;
127     return d;
128 }
129
130 QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
131 {
132     qDebug().nospace() << "NCCALCSIZE_PARAMS "
133         << qrectFromRECT(p.rgrc[0])
134         << ' ' << qrectFromRECT(p.rgrc[1]) << ' '
135         << qrectFromRECT(p.rgrc[2]);
136     return d;
137 }
138
139 static inline QRect frameGeometry(HWND hwnd)
140 {
141     RECT rect = { 0, 0, 0, 0 };
142     GetWindowRect(hwnd, &rect);
143     return qrectFromRECT(rect);
144 }
145
146 QSize clientSize(HWND hwnd)
147 {
148     RECT rect = { 0, 0, 0, 0 };
149     GetClientRect(hwnd, &rect); // Always returns point 0,0, thus unusable for geometry.
150     return qSizeOfRect(rect);
151 }
152
153 // from qwidget_win.cpp/maximum layout size check removed.
154 static bool shouldShowMaximizeButton(Qt::WindowFlags flags)
155 {
156     if (flags & Qt::MSWindowsFixedSizeDialogHint)
157         return false;
158     // if the user explicitly asked for the maximize button, we try to add
159     // it even if the window has fixed size.
160     if (flags & Qt::CustomizeWindowHint &&
161         flags & Qt::WindowMaximizeButtonHint)
162         return true;
163     return flags & Qt::WindowMaximizeButtonHint;
164 }
165
166 /*!
167     \class WindowCreationData
168     \brief Window creation code.
169
170     This struct gathers all information required to create a window.
171     Window creation is split in 3 steps:
172
173     \list
174     \o fromWindow() Gather all required information
175     \o create() Create the system handle.
176     \o initialize() Post creation initialization steps.
177     \endlist
178
179     The reason for this split is to also enable changing the QWindowFlags
180     by calling:
181
182     \list
183     \o fromWindow() Gather information and determine new system styles
184     \o applyWindowFlags() to apply the new window system styles.
185     \o initialize() Post creation initialization steps.
186     \endlist
187
188     Contains the window creation code formerly in qwidget_win.cpp.
189
190     \sa QWindowCreationContext
191     \ingroup qt-lighthouse-win
192 */
193
194 struct WindowCreationData
195 {
196     typedef QWindowsWindow::WindowData WindowData;
197
198     WindowCreationData() : parentHandle(0), type(Qt::Widget), style(0), exStyle(0),
199         topLevel(false), popup(false), dialog(false), desktop(false),
200         tool(false) {}
201
202     void fromWindow(const QWindow *w, const Qt::WindowFlags flags, bool isGL);
203     inline WindowData create(const QWindow *w, const QRect &geometry, QString title) const;
204     inline void applyWindowFlags(HWND hwnd) const;
205     void initialize(HWND h, bool frameChange) const;
206
207     Qt::WindowFlags flags;
208     HWND parentHandle;
209     Qt::WindowType type;
210     unsigned style;
211     unsigned exStyle;
212     bool isGL;
213     bool topLevel;
214     bool popup;
215     bool dialog;
216     bool desktop;
217     bool tool;
218 };
219
220 QDebug operator<<(QDebug debug, const WindowCreationData &d)
221 {
222     debug.nospace() << QWindowsWindow::debugWindowFlags(d.flags)
223         << " gs=" << d.isGL << " topLevel=" << d.topLevel << " popup="
224         << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop
225         << " tool=" << d.tool << " style=" << debugWinStyle(d.style)
226         << " exStyle=0x" << QString::number(d.exStyle, 16)
227         << " parent=" << d.parentHandle;
228     return debug;
229 }
230
231 void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flagsIn,
232                                     bool isGLin)
233 {
234     isGL = isGLin;
235     flags = flagsIn;
236     topLevel = w->isTopLevel();
237
238     if (topLevel && flags == 1) {
239         qWarning("Remove me: fixing toplevel window flags");
240         flags |= Qt::WindowTitleHint|Qt::WindowSystemMenuHint|Qt::WindowMinimizeButtonHint
241                 |Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint;
242     }
243
244     type = static_cast<Qt::WindowType>(int(flags) & Qt::WindowType_Mask);
245     switch (type) {
246     case Qt::Dialog:
247     case Qt::Sheet:
248         dialog = true;
249         break;
250     case Qt::Drawer:
251     case Qt::Tool:
252         tool = true;
253         break;
254     case Qt::Popup:
255         popup = true;
256         break;
257     case Qt::Desktop:
258         desktop = true;
259         break;
260     default:
261         break;
262     }
263     if ((flags & Qt::MSWindowsFixedSizeDialogHint))
264         dialog = true;
265
266     // Parent: Use transient parent for top levels.
267     if (popup) {
268         flags |= Qt::WindowStaysOnTopHint; // a popup stays on top, no parent.
269     } else {
270         if (const QWindow *parentWindow = topLevel ? w->transientParent() : w->parent())
271             parentHandle = QWindowsWindow::handleOf(parentWindow);
272     }
273
274     if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
275         style = WS_POPUP;
276     } else if (topLevel && !desktop) {
277         if (flags & Qt::FramelessWindowHint)
278             style = WS_POPUP;                // no border
279         else if (flags & Qt::WindowTitleHint)
280             style = WS_OVERLAPPED;
281         else
282             style = 0;
283     } else {
284         style = WS_CHILD;
285     }
286
287     if (!desktop) {
288         // if (!testAttribute(Qt::WA_PaintUnclipped))
289         // ### Commented out for now as it causes some problems, but
290         // this should be correct anyway, so dig some more into this
291 #ifdef Q_FLATTEN_EXPOSE
292         if (isGL)
293             style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // see SetPixelFormat
294 #else
295         style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
296 #endif
297         if (topLevel) {
298             if ((type == Qt::Window || dialog || tool)) {
299                 if (!(flags & Qt::FramelessWindowHint)) {
300                     style |= WS_POPUP;
301                     if (flags & Qt::MSWindowsFixedSizeDialogHint) {
302                         style |= WS_DLGFRAME;
303                     } else {
304                         style |= WS_THICKFRAME;
305                     }
306                 }
307                 if (flags & Qt::WindowTitleHint)
308                     style |= WS_CAPTION;
309                 if (flags & Qt::WindowSystemMenuHint)
310                     style |= WS_SYSMENU;
311                 if (flags & Qt::WindowMinimizeButtonHint)
312                     style |= WS_MINIMIZEBOX;
313                 if (shouldShowMaximizeButton(flags))
314                     style |= WS_MAXIMIZEBOX;
315                 if (tool)
316                     exStyle |= WS_EX_TOOLWINDOW;
317                 if (flags & Qt::WindowContextHelpButtonHint)
318                     exStyle |= WS_EX_CONTEXTHELP;
319             } else {
320                  exStyle |= WS_EX_TOOLWINDOW;
321             }
322         }
323     }
324 }
325
326 QWindowsWindow::WindowData
327     WindowCreationData::create(const QWindow *w, const QRect &geometry, QString title) const
328 {
329     typedef QSharedPointer<QWindowCreationContext> QWindowCreationContextPtr;
330
331     WindowData result;
332     result.flags = flags;
333
334     if (desktop) {                        // desktop widget. No frame, hopefully?
335         result.hwnd = GetDesktopWindow();
336         result.geometry = frameGeometry(result.hwnd);
337         if (QWindowsContext::verboseWindows)
338             qDebug().nospace() << "Created desktop window " << w << result.hwnd;
339         return result;
340     }
341
342     const HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
343
344     const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w, isGL);
345
346     if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
347         title = topLevel ? qAppName() : w->objectName();
348
349     const wchar_t *titleUtf16 = reinterpret_cast<const wchar_t *>(title.utf16());
350     const wchar_t *classNameUtf16 = reinterpret_cast<const wchar_t *>(windowClassName.utf16());
351
352     // Capture events before CreateWindowEx() returns.
353     const QWindowCreationContextPtr context(new QWindowCreationContext(w, geometry, style, exStyle));
354     QWindowsContext::instance()->setWindowCreationContext(context);
355
356     if (QWindowsContext::verboseWindows)
357         qDebug().nospace()
358                 << "CreateWindowEx: " << w << *this
359                 << " class=" <<windowClassName << " title=" << title
360                 << "\nrequested: " << geometry << ": "
361                 << context->frameWidth << 'x' <<  context->frameHeight
362                 << '+' << context->frameX << '+' << context->frameY;
363
364     result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
365                                  style,
366                                  context->frameX, context->frameY,
367                                  context->frameWidth, context->frameHeight,
368                                  parentHandle, NULL, appinst, NULL);
369     QWindowsContext::instance()->setWindowCreationContext(QWindowCreationContextPtr());
370     if (QWindowsContext::verboseWindows)
371         qDebug().nospace()
372                 << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
373                 << context->obtainedGeometry << context->margins;
374
375     if (!result.hwnd) {
376         qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__);
377         return result;
378     }
379
380     result.geometry = context->obtainedGeometry;
381     result.frame = context->margins;
382     return result;
383 }
384
385 void WindowCreationData::applyWindowFlags(HWND hwnd) const
386 {
387     // Keep enabled and visible from the current style.
388     const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
389     const LONG_PTR oldExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
390
391     const LONG_PTR newStyle = style | (oldStyle & (WS_DISABLED|WS_VISIBLE));
392     if (oldStyle != newStyle)
393         SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
394     const LONG_PTR newExStyle = exStyle;
395     if (newExStyle != oldExStyle)
396         SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
397     if (QWindowsContext::verboseWindows)
398         qDebug().nospace() << __FUNCTION__ << hwnd << *this
399         << "\n    Style from " << debugWinStyle(oldStyle) << "\n    to "
400         << debugWinStyle(newStyle) << "\n    ExStyle from 0x"
401         << QByteArray::number(qulonglong(oldExStyle), 16) << " to 0x"
402         << QByteArray::number(qulonglong(newExStyle), 16);
403 }
404
405 void WindowCreationData::initialize(HWND hwnd, bool frameChange) const
406 {
407     if (desktop || !hwnd)
408         return;
409     UINT flags = SWP_NOMOVE | SWP_NOSIZE;
410     if (frameChange)
411         flags |= SWP_FRAMECHANGED;
412     if (topLevel) {
413         flags |= SWP_NOACTIVATE;
414         if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
415             SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, flags);
416             if (flags & Qt::WindowStaysOnBottomHint)
417                 qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
418         } else if (flags & Qt::WindowStaysOnBottomHint) {
419             SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, flags);
420         }
421         if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) {
422             HMENU systemMenu = GetSystemMenu(hwnd, FALSE);
423             if (flags & Qt::WindowCloseButtonHint)
424                 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
425             else
426                 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
427         }
428     } else { // child.
429         SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
430     }
431 }
432
433 /*!
434     \class QWindowsGeometryHint
435     \brief Stores geometry constraints and provides utility functions.
436
437     Geometry constraints ready to apply to a MINMAXINFO taking frame
438     into account.
439
440     \ingroup qt-lighthouse-win
441 */
442
443 #define QWINDOWSIZE_MAX ((1<<24)-1)
444
445 QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w) :
446      minimumSize(w->minimumSize()),
447      maximumSize(w->maximumSize())
448 {
449 }
450
451 bool QWindowsGeometryHint::validSize(const QSize &s) const
452 {
453     const int width = s.width();
454     const int height = s.height();
455     return width >= minimumSize.width() && width <= maximumSize.width()
456            && height >= minimumSize.height() && height <= maximumSize.height();
457 }
458
459 QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle)
460 {
461     RECT rect = {0,0,0,0};
462     style &= ~(WS_OVERLAPPED); // Not permitted, see docs.
463     if (!AdjustWindowRectEx(&rect, style, FALSE, exStyle))
464         qErrnoWarning("%s: AdjustWindowRectEx failed", __FUNCTION__);
465     const QMargins result(qAbs(rect.left), qAbs(rect.top),
466                           qAbs(rect.right), qAbs(rect.bottom));
467     if (QWindowsContext::verboseWindows)
468         qDebug().nospace() << __FUNCTION__ << " style= 0x"
469                  << QString::number(style, 16)
470                  << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result;
471
472     return result;
473 }
474
475 void QWindowsGeometryHint::applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const
476 {
477     return applyToMinMaxInfo(GetWindowLong(hwnd, GWL_STYLE),
478                              GetWindowLong(hwnd, GWL_EXSTYLE), mmi);
479 }
480
481 void QWindowsGeometryHint::applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXINFO *mmi) const
482 {
483     if (QWindowsContext::verboseWindows)
484         qDebug().nospace() << '>' << __FUNCTION__ << '<' << " min="
485                            << minimumSize.width() << ',' << minimumSize.height()
486                            << " max=" << maximumSize.width() << ',' << maximumSize.height()
487                            << " in " << *mmi;
488
489     const QMargins margins = QWindowsGeometryHint::frame(style, exStyle);
490     const int frameWidth = margins.left() + margins.right();
491     const int frameHeight = margins.top() + margins.bottom();
492     if (minimumSize.width() > 0)
493         mmi->ptMinTrackSize.x = minimumSize.width() + frameWidth;
494     if (minimumSize.height() > 0)
495         mmi->ptMinTrackSize.y = minimumSize.height() + frameHeight;
496
497     const int maximumWidth = qMax(maximumSize.width(), minimumSize.width());
498     const int maximumHeight = qMax(maximumSize.height(), minimumSize.height());
499     if (maximumWidth < QWINDOWSIZE_MAX)
500         mmi->ptMaxTrackSize.x = maximumWidth + frameWidth;
501     // windows with title bar have an implicit size limit of 112 pixels
502     if (maximumHeight < QWINDOWSIZE_MAX)
503         mmi->ptMaxTrackSize.y = qMax(maximumHeight + frameHeight, 112);
504     if (QWindowsContext::verboseWindows)
505         qDebug().nospace() << '<' << __FUNCTION__
506                            << " frame=" << margins << ' ' << frameWidth << ',' << frameHeight
507                            << " out " << *mmi;
508 }
509
510 /*!
511     \class QWindowCreationContext
512     \brief Active Context for creating windows.
513
514     There is a phase in window creation (WindowCreationData::create())
515     in which events are sent before the system API CreateWindowEx() returns
516     the handle. These cannot be handled by the platform window as the association
517     of the unknown handle value to the window does not exist yet and as not
518     to trigger recursive handle creation, etc.
519
520     In that phase, an instance of  QWindowCreationContext is set on
521     QWindowsContext.
522
523     QWindowCreationContext stores the information to answer the initial
524     WM_GETMINMAXINFO and obtains the corrected size/position.
525
526     \sa WindowCreationData, QWindowsContext
527     \ingroup qt-lighthouse-win
528 */
529
530 QWindowCreationContext::QWindowCreationContext(const QWindow *w,
531                                                const QRect &geometry,
532                                                DWORD style_, DWORD exStyle_) :
533     geometryHint(w), style(style_), exStyle(exStyle_),
534     requestedGeometry(geometry), obtainedGeometry(geometry),
535     margins(QWindowsGeometryHint::frame(style, exStyle)),
536     frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT),
537     frameWidth(CW_USEDEFAULT), frameHeight(CW_USEDEFAULT)
538 {
539     // Geometry of toplevels does not consider window frames.
540     // TODO: No concept of WA_wasMoved yet that would indicate a
541     // CW_USEDEFAULT unless set. For now, assume that 0,0 means 'default'
542     // for toplevels.
543     if (geometry.isValid()) {
544         if (!w->isTopLevel() || geometry.y() >= margins.top()) {
545             frameX = geometry.x() - margins.left();
546             frameY = geometry.y() - margins.top();
547         }
548         frameWidth = geometry.width() + margins.left() + margins.right();
549         frameHeight = geometry.height() + margins.top() + margins.bottom();
550     }
551     if (QWindowsContext::verboseWindows)
552         qDebug().nospace()
553                 << __FUNCTION__ << ' ' << w << " min" << geometryHint.minimumSize
554                 << " min" << geometryHint.maximumSize;
555 }
556
557 /*!
558     \class QWindowsBaseWindow
559     \brief Raster or OpenGL Window.
560
561     \list
562     \o Raster type: handleWmPaint() is implemented to
563        to bitblt the image. The DC can be accessed
564        via getDC/Relase DC, which has a special handling
565        when within a paint event (in that case, the DC obtained
566        from BeginPaint() is returned).
567
568     \o Open GL: The first time QWindowsGLContext accesses
569        the handle, it sets up the pixelformat on the DC
570        which in turn sets it on the window (see flag
571        PixelFormatInitialized).
572        handleWmPaint() is empty (although required).
573     \endlist
574
575     \ingroup qt-lighthouse-win
576 */
577
578 QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
579     QPlatformWindow(aWindow),
580     m_data(data),
581     m_flags(0),
582     m_hdc(0),
583     m_windowState(aWindow->windowState()),
584     m_opacity(1.0),
585     m_mouseGrab(false),
586     m_cursor(QWindowsScreen::screenOf(aWindow)->cursor().standardWindowCursor()),
587     m_dropTarget(0)
588 {
589     if (aWindow->surfaceType() == QWindow::OpenGLSurface)
590         setFlag(OpenGL_Surface);
591     QWindowsContext::instance()->addWindow(m_data.hwnd, this);
592     if (aWindow->isTopLevel()) {
593         switch (aWindow->windowType()) {
594         case Qt::Window:
595         case Qt::Dialog:
596         case Qt::Sheet:
597         case Qt::Drawer:
598         case Qt::Popup:
599         case Qt::Tool:
600             registerDropSite();
601             break;
602         default:
603             break;
604         }
605     }
606 }
607
608 QWindowsWindow::~QWindowsWindow()
609 {
610     destroyWindow();
611 }
612
613 void QWindowsWindow::destroyWindow()
614 {
615     if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
616         qDebug() << __FUNCTION__ << this << window() << m_data.hwnd;
617     if (m_data.hwnd) {
618         unregisterDropSite();
619         if (m_data.hwnd != GetDesktopWindow())
620             DestroyWindow(m_data.hwnd);
621         QWindowsContext::instance()->removeWindow(m_data.hwnd);
622         m_data.hwnd = 0;
623     }
624 }
625
626 void QWindowsWindow::registerDropSite()
627 {
628     if (m_data.hwnd && !m_dropTarget) {
629         m_dropTarget = new QWindowsOleDropTarget(window());
630         RegisterDragDrop(m_data.hwnd, m_dropTarget);
631         CoLockObjectExternal(m_dropTarget, true, true);
632     }
633 }
634
635 void QWindowsWindow::unregisterDropSite()
636 {
637     if (m_data.hwnd && m_dropTarget) {
638         m_dropTarget->Release();
639         CoLockObjectExternal(m_dropTarget, false, true);
640         RevokeDragDrop(m_data.hwnd);
641         m_dropTarget = 0;
642     }
643 }
644
645 QWindow *QWindowsWindow::topLevelOf(QWindow *w)
646 {
647     while (QWindow *parent = w->parent())
648         w = parent;
649     return w;
650 }
651
652 QWindowsWindow::WindowData
653     QWindowsWindow::WindowData::create(const QWindow *w,
654                                            const WindowData &parameters,
655                                            const QString &title,
656                                            bool isGL)
657 {
658     WindowCreationData creationData;
659     creationData.fromWindow(w, parameters.flags, isGL);
660     WindowData result = creationData.create(w, parameters.geometry, title);
661     creationData.initialize(result.hwnd, false);
662     return result;
663 }
664
665 void QWindowsWindow::setVisible(bool visible)
666 {
667     if (QWindowsContext::verboseWindows)
668         qDebug() << __FUNCTION__ << this << window() << m_data.hwnd << visible;
669     if (m_data.hwnd) {
670         if (visible) {
671             show_sys();
672         } else {
673             hide_sys();
674         }
675     }
676 }
677
678 bool QWindowsWindow::isVisible() const
679 {
680     return m_data.hwnd && IsWindowVisible(m_data.hwnd);
681 }
682
683 // partially from QWidgetPrivate::show_sys()
684 void QWindowsWindow::show_sys() const
685 {
686     int sm = SW_SHOWNORMAL;
687     bool fakedMaximize = false;
688     const QWindow *w = window();
689     const Qt::WindowFlags flags = w->windowFlags();
690     const Qt::WindowType type = w->windowType();
691     if (w->isTopLevel()) {
692         const Qt::WindowState state = w->windowState();
693         if (state & Qt::WindowMinimized) {
694             sm = SW_SHOWMINIMIZED;
695             if (!isVisible())
696                 sm = SW_SHOWMINNOACTIVE;
697         } else if (state & Qt::WindowMaximized) {
698             sm = SW_SHOWMAXIMIZED;
699             // Windows will not behave correctly when we try to maximize a window which does not
700             // have minimize nor maximize buttons in the window frame. Windows would then ignore
701             // non-available geometry, and rather maximize the widget to the full screen, minus the
702             // window frame (caption). So, we do a trick here, by adding a maximize button before
703             // maximizing the widget, and then remove the maximize button afterwards.
704             if (flags & Qt::WindowTitleHint &&
705                 !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
706                 fakedMaximize = TRUE;
707                 setStyle(style() | WS_MAXIMIZEBOX);
708             }
709         }
710     }
711     if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::Tool)
712         sm = SW_SHOWNOACTIVATE;
713
714     ShowWindow(m_data.hwnd, sm);
715
716     if (fakedMaximize) {
717         setStyle(style() & ~WS_MAXIMIZEBOX);
718         SetWindowPos(m_data.hwnd, 0, 0, 0, 0, 0,
719                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
720                      | SWP_FRAMECHANGED);
721     }
722 }
723
724 // partially from QWidgetPrivate::hide_sys()
725 void QWindowsWindow::hide_sys() const
726 {
727     const Qt::WindowFlags flags = window()->windowFlags();
728     if (flags != Qt::Desktop) {
729         if (flags & Qt::Popup)
730             ShowWindow(m_data.hwnd, SW_HIDE);
731         else
732             SetWindowPos(m_data.hwnd,0, 0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
733     }
734 }
735
736 void QWindowsWindow::setParent(const QPlatformWindow *newParent)
737 {
738     if (QWindowsContext::verboseWindows)
739         qDebug() << __FUNCTION__ << window() << newParent;
740
741     if (newParent != parent() && m_data.hwnd)
742         setParent_sys(newParent);
743 }
744
745 void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
746 {
747     HWND parentHWND = 0;
748     if (parent) {
749         const QWindowsWindow *parentW = static_cast<const QWindowsWindow *>(parent);
750         parentHWND = parentW->handle();
751     }
752     SetParent(m_data.hwnd, parentHWND);
753 }
754
755 void QWindowsWindow::handleShown()
756 {
757     QWindowSystemInterface::handleMapEvent(window());
758 }
759
760 void QWindowsWindow::handleHidden()
761 {
762     QWindowSystemInterface::handleUnmapEvent(window());
763 }
764
765 void QWindowsWindow::setGeometry(const QRect &rect)
766 {
767     const QSize oldSize = m_data.geometry.size();
768     m_data.geometry = rect;
769     const QSize newSize = rect.size();
770     // Check on hint.
771     if (newSize != oldSize) {
772         const QWindowsGeometryHint hint(window());
773         if (!hint.validSize(newSize)) {
774             qWarning("%s: Attempt to set a size (%dx%d) violating the constraints"
775                      "(%dx%d - %dx%d) on window '%s'.", __FUNCTION__,
776                      newSize.width(), newSize.height(),
777                      hint.minimumSize.width(), hint.minimumSize.height(),
778                      hint.maximumSize.width(), hint.maximumSize.height(),
779                      qPrintable(window()->objectName()));
780         }
781     }
782     if (m_data.hwnd) {
783         // A ResizeEvent with resulting geometry will be sent. If we cannot
784         // achieve that size (for example, window title minimal constraint),
785         // notify and warn.
786         setGeometry_sys(rect);
787         if (m_data.geometry != rect) {
788             qWarning("%s: Unable to set geometry %dx%d+%d+%d on '%s'."
789                      " Resulting geometry:  %dx%d+%d+%d.",
790                      __FUNCTION__,
791                      rect.width(), rect.height(), rect.x(), rect.y(),
792                      qPrintable(window()->objectName()),
793                      m_data.geometry.width(), m_data.geometry.height(),
794                      m_data.geometry.x(), m_data.geometry.y());
795         }
796     } else {
797         QPlatformWindow::setGeometry(rect);
798     }
799 }
800
801 void QWindowsWindow::handleMoved()
802 {
803     if (!IsIconic(m_data.hwnd)) // Minimize can send nonsensical move events.
804         handleGeometryChange();
805 }
806
807 void QWindowsWindow::handleResized(int wParam)
808 {
809     switch (wParam) {
810     case SIZE_MAXHIDE: // Some other window affected.
811     case SIZE_MAXSHOW:
812         return;
813     case SIZE_MINIMIZED:
814         handleWindowStateChange(Qt::WindowMinimized);
815         return;
816     case SIZE_MAXIMIZED:
817         handleWindowStateChange(Qt::WindowMaximized);
818         handleGeometryChange();
819         break;
820     case SIZE_RESTORED:
821         if (m_windowState != Qt::WindowNoState)
822             handleWindowStateChange(Qt::WindowNoState);
823         handleGeometryChange();
824         break;
825     }
826 }
827
828 void QWindowsWindow::handleGeometryChange()
829 {
830     m_data.geometry = geometry_sys();
831     QPlatformWindow::setGeometry(m_data.geometry);
832     QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
833
834     if (QWindowsContext::verboseEvents || QWindowsContext::verboseWindows)
835         qDebug() << __FUNCTION__ << this << window() << m_data.geometry;
836 }
837
838 void QWindowsWindow::setGeometry_sys(const QRect &rect) const
839 {
840     const QRect frameGeometry = rect + frameMargins();
841
842     if (QWindowsContext::verboseWindows)
843         qDebug() << '>' << __FUNCTION__ << this << window()
844                  << "    \n from " << geometry_sys() << " to " <<rect
845                  << " new frame: " << frameGeometry;
846
847     const bool rc = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(),
848                                frameGeometry.width(), frameGeometry.height(), true);
849     if (QWindowsContext::verboseWindows)
850         qDebug() << '<' << __FUNCTION__ << this << window()
851                  << "    \n resulting " << rc << geometry_sys();
852 }
853
854 QRect QWindowsWindow::geometry_sys() const
855 {
856     // Warning: Returns bogus values when minimized.
857     return frameGeometry(m_data.hwnd) - frameMargins();
858 }
859
860 /*!
861     Allocates a HDC for the window or returns the temporary one
862     obtained from WinAPI BeginPaint within a WM_PAINT event.
863
864     \sa releaseDC()
865 */
866
867 HDC QWindowsWindow::getDC()
868 {
869     if (!m_hdc)
870         m_hdc = GetDC(handle());
871     return m_hdc;
872 }
873
874 /*!
875     Relases the HDC for the window or does nothing in
876     case it was obtained from WinAPI BeginPaint within a WM_PAINT event.
877
878     \sa getDC()
879 */
880
881 void QWindowsWindow::releaseDC()
882 {
883     if (m_hdc && !testFlag(WithinWmPaint)) {
884         ReleaseDC(handle(), m_hdc);
885         m_hdc = 0;
886     }
887 }
888
889 void QWindowsWindow::handleWmPaint(HWND hwnd, UINT,
890                                          WPARAM, LPARAM)
891 {
892     PAINTSTRUCT ps;
893     if (testFlag(OpenGL_Surface)) {
894         BeginPaint(hwnd, &ps); // WM_ERASEBKGND needs to be handled.
895         EndPaint(hwnd, &ps);
896     } else {
897         releaseDC();
898         m_hdc = BeginPaint(hwnd, &ps);
899         setFlag(WithinWmPaint);
900
901         const QRect updateRect = qrectFromRECT(ps.rcPaint);
902         if (QWindowsContext::verboseIntegration)
903             qDebug() << __FUNCTION__ << this << window() << updateRect;
904
905         QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRegion(updateRect));
906         clearFlag(WithinWmPaint);
907         m_hdc = 0;
908         EndPaint(hwnd, &ps);
909     }
910 }
911
912 void QWindowsWindow::setWindowTitle(const QString &title)
913 {
914     if (QWindowsContext::verboseWindows)
915         qDebug() << __FUNCTION__ << this << window() <<title;
916     if (m_data.hwnd)
917         SetWindowText(m_data.hwnd, (const wchar_t*)title.utf16());
918 }
919
920 Qt::WindowFlags QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
921 {
922     if (QWindowsContext::verboseWindows)
923         qDebug() << '>' << __FUNCTION__ << this << window() << "\n    from: "
924                  << QWindowsWindow::debugWindowFlags(m_data.flags)
925                  << "\n    to: " << QWindowsWindow::debugWindowFlags(flags);
926     if (m_data.flags != flags) {
927         m_data.flags = flags;
928         if (m_data.hwnd)
929             m_data = setWindowFlags_sys(flags);
930     }
931     if (QWindowsContext::verboseWindows)
932         qDebug() << '<' << __FUNCTION__ << "\n    returns: "
933                  << QWindowsWindow::debugWindowFlags(m_data.flags);
934     return m_data.flags;
935 }
936
937 QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt) const
938 {
939     // Geometry changes have not been observed here. Frames change, though.
940     WindowCreationData creationData;
941     creationData.fromWindow(window(), wt, window()->surfaceType() == QWindow::OpenGLSurface);
942     creationData.applyWindowFlags(m_data.hwnd);
943     creationData.initialize(m_data.hwnd, true);
944     WindowData result = m_data;
945     result.flags = creationData.flags;
946     setFlag(FrameDirty);
947     return result;
948 }
949
950 void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
951 {
952     if (QWindowsContext::verboseWindows)
953         qDebug() << __FUNCTION__ << this << window()
954                  << "\n    from " << debugWindowStates(m_windowState)
955                  << " to " << debugWindowStates(state);
956     setFlag(FrameDirty);
957     m_windowState = state;
958     QWindowSystemInterface::handleWindowStateChanged(window(), state);
959 }
960
961 Qt::WindowState QWindowsWindow::setWindowState(Qt::WindowState state)
962 {
963     if (m_data.hwnd) {
964         setWindowState_sys(state);
965         m_windowState = state;
966     }
967     return state;
968 }
969
970 Qt::WindowState QWindowsWindow::windowState_sys() const
971 {
972     if (IsIconic(m_data.hwnd))
973         return Qt::WindowMinimized;
974     if (IsZoomed(m_data.hwnd))
975         return Qt::WindowMaximized;
976     if (geometry_sys() == window()->screen()->geometry())
977         return Qt::WindowFullScreen;
978     return Qt::WindowNoState;
979 }
980
981 Qt::WindowStates QWindowsWindow::windowStates_sys() const
982 {
983     Qt::WindowStates result = windowState_sys();
984     if (GetActiveWindow() == m_data.hwnd)
985         result |= Qt::WindowActive;
986     return result;
987 }
988
989 /*!
990     \brief Change the window state.
991
992     \note Window frames change when maximized;
993     the top margin shrinks somewhat but that cannot be obtained using
994     AdjustWindowRectEx().
995
996     \note Some calls to SetWindowLong require a subsequent call
997     to ShowWindow.
998 */
999
1000 void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
1001 {
1002     const Qt::WindowStates oldStates = windowStates_sys();
1003     // Maintain the active flag as the platform window API does not
1004     // use it.
1005     Qt::WindowStates newStates = newState;
1006     if (oldStates & Qt::WindowActive)
1007         newStates |=  Qt::WindowActive;
1008     if (oldStates == newStates)
1009         return;
1010     if (QWindowsContext::verboseWindows)
1011         qDebug() << '>' << __FUNCTION__ << this << window()
1012                  << " from " << debugWindowStates(oldStates)
1013                  << " to " << debugWindowStates(newStates);
1014
1015     const bool isActive = newStates & Qt::WindowActive;
1016     const int max    = isActive ? SW_SHOWMAXIMIZED : SW_MAXIMIZE;
1017     const int normal = isActive ? SW_SHOWNORMAL    : SW_SHOWNOACTIVATE;
1018     const int min    = isActive ? SW_SHOWMINIMIZED : SW_MINIMIZE;
1019     const bool visible = isVisible();
1020
1021     setFlag(FrameDirty);
1022
1023     if ((oldStates & Qt::WindowMaximized) != (newStates & Qt::WindowMaximized)) {
1024         if (visible && !(newStates & Qt::WindowMinimized))
1025             ShowWindow(m_data.hwnd, (newStates & Qt::WindowMaximized) ? max : normal);
1026     }
1027
1028     if ((oldStates & Qt::WindowFullScreen) != (newStates & Qt::WindowFullScreen)) {
1029         if (newStates & Qt::WindowFullScreen) {
1030 #ifndef Q_FLATTEN_EXPOSE
1031             UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
1032 #else
1033             UINT newStyle = WS_POPUP;
1034 #endif
1035             if (style() & WS_SYSMENU)
1036                 newStyle |= WS_SYSMENU;
1037             if (visible)
1038                 newStyle |= WS_VISIBLE;
1039             setStyle(newStyle);
1040
1041             const QRect r = window()->screen()->geometry();
1042             UINT swpf = SWP_FRAMECHANGED;
1043             if (newStates & Qt::WindowActive)
1044                 swpf |= SWP_NOACTIVATE;
1045
1046             SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf);
1047         } else {
1048             if (visible)
1049                 setStyle(style() | WS_VISIBLE);
1050             UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE;
1051             if (newStates & Qt::WindowActive)
1052                 swpf |= SWP_NOACTIVATE;
1053             SetWindowPos(m_data.hwnd, 0, 0, 0, 0, 0, swpf);
1054
1055             // preserve maximized state
1056             if (visible)
1057                 ShowWindow(m_data.hwnd, (newStates & Qt::WindowMaximized) ? max : normal);
1058         }
1059     }
1060
1061     if ((oldStates & Qt::WindowMinimized) != (newStates & Qt::WindowMinimized)) {
1062         if (visible)
1063             ShowWindow(m_data.hwnd, (newStates & Qt::WindowMinimized) ? min :
1064                        (newStates & Qt::WindowMaximized) ? max : normal);
1065     }
1066     if (QWindowsContext::verboseWindows)
1067         qDebug() << '<' << __FUNCTION__ << this << window()
1068                  << debugWindowStates(newStates);
1069 }
1070
1071 void QWindowsWindow::setStyle(unsigned s) const
1072 {
1073     if (QWindowsContext::verboseWindows)
1074         qDebug() << __FUNCTION__ << this << window() << debugWinStyle(s);
1075     setFlag(FrameDirty);
1076     SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
1077 }
1078
1079 void QWindowsWindow::setExStyle(unsigned s) const
1080 {
1081     if (QWindowsContext::verboseWindows)
1082         qDebug().nospace() << __FUNCTION__ << ' ' << this << ' ' << window()
1083         << " 0x" << QByteArray::number(s, 16);
1084     setFlag(FrameDirty);
1085     SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
1086 }
1087
1088 void QWindowsWindow::raise()
1089 {
1090     if (QWindowsContext::verboseWindows)
1091         qDebug() << __FUNCTION__ << this << window();
1092     SetWindowPos(m_data.hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1093 }
1094
1095 void QWindowsWindow::lower()
1096 {
1097     if (QWindowsContext::verboseWindows)
1098         qDebug() << __FUNCTION__ << this << window();
1099     if (m_data.hwnd)
1100         SetWindowPos(m_data.hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1101 }
1102
1103 void QWindowsWindow::propagateSizeHints()
1104 {
1105     if (QWindowsContext::verboseWindows)
1106         qDebug() << __FUNCTION__ << this << window();
1107 }
1108
1109 QMargins QWindowsWindow::frameMargins() const
1110 {
1111     // Frames are invalidated by style changes (window state, flags).
1112     // As they are also required for geometry calculations in resize
1113     // event sequences, introduce a dirty flag mechanism to be able
1114     // to cache results.
1115     if (testFlag(FrameDirty)) {
1116         m_data.frame = QWindowsGeometryHint::frame(style(), exStyle());
1117         clearFlag(FrameDirty);
1118     }
1119     return m_data.frame;
1120 }
1121
1122 void QWindowsWindow::setOpacity(qreal level)
1123 {
1124     if (QWindowsContext::verboseWindows)
1125         qDebug() << __FUNCTION__ << level;
1126     if (m_opacity != level) {
1127         m_opacity = level;
1128         if (m_data.hwnd)
1129             setOpacity_sys(level);
1130     }
1131 }
1132
1133 void QWindowsWindow::setOpacity_sys(qreal level) const
1134 {
1135     const long wl = GetWindowLong(m_data.hwnd, GWL_EXSTYLE);
1136     const bool isOpaque = level == 1.0;
1137
1138     if (isOpaque) {
1139         if (wl & WS_EX_LAYERED)
1140             SetWindowLong(m_data.hwnd, GWL_EXSTYLE, wl & ~WS_EX_LAYERED);
1141     } else {
1142         if ((wl & WS_EX_LAYERED) == 0)
1143             SetWindowLong(m_data.hwnd, GWL_EXSTYLE, wl | WS_EX_LAYERED);
1144         if (m_data.flags & Qt::FramelessWindowHint) {
1145             BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * level), AC_SRC_ALPHA};
1146             QWindowsContext::user32dll.updateLayeredWindow(m_data.hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA);
1147         } else {
1148             QWindowsContext::user32dll.setLayeredWindowAttributes(m_data.hwnd, 0, (int)(level * 255), LWA_ALPHA);
1149         }
1150     }
1151 }
1152
1153 void QWindowsWindow::requestActivateWindow()
1154 {
1155     if (QWindowsContext::verboseWindows)
1156         qDebug() << __FUNCTION__ << this << window();
1157     if (m_data.hwnd)
1158         SetForegroundWindow(m_data.hwnd);
1159 }
1160
1161 bool QWindowsWindow::setKeyboardGrabEnabled(bool grab)
1162 {
1163     if (!m_data.hwnd) {
1164         qWarning("%s: No handle", __FUNCTION__);
1165         return false;
1166     }
1167     if (QWindowsContext::verboseWindows)
1168         qDebug() << __FUNCTION__ << this << window() << grab;
1169
1170     QWindowsContext *context = QWindowsContext::instance();
1171     if (grab) {
1172         context->setKeyGrabber(window());
1173     } else {
1174         if (context->keyGrabber() == window())
1175             context->setKeyGrabber(0);
1176     }
1177     return true;
1178 }
1179
1180 bool QWindowsWindow::setMouseGrabEnabled(bool grab)
1181 {
1182     bool result = false;
1183     if (!m_data.hwnd) {
1184         qWarning("%s: No handle", __FUNCTION__);
1185         return result;
1186     }
1187     if (QWindowsContext::verboseWindows)
1188         qDebug() << __FUNCTION__ << window() << grab;
1189
1190     if (m_mouseGrab != grab) {
1191         m_mouseGrab = grab;
1192         if (isVisible())
1193             setMouseGrabEnabled_sys(grab);
1194     }
1195     return grab;
1196 }
1197
1198 void QWindowsWindow::setMouseGrabEnabled_sys(bool grab)
1199 {
1200     if (grab) {
1201         SetCapture(m_data.hwnd);
1202     } else {
1203         ReleaseCapture();
1204     }
1205 }
1206
1207 void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
1208 {
1209     const QWindowsGeometryHint hint(window());
1210     hint.applyToMinMaxInfo(m_data.hwnd, mmi);
1211     if (QWindowsContext::verboseWindows)
1212         qDebug() << __FUNCTION__ << window() << *mmi;
1213 }
1214
1215 /*!
1216     \brief Applies to cursor property set on the window to the global cursor
1217     unless there is an override cursor.
1218
1219     \sa QWindowsCursor
1220 */
1221
1222 void QWindowsWindow::applyCursor()
1223 {
1224     if (!QGuiApplication::overrideCursor())
1225         SetCursor(m_cursor.handle());
1226 }
1227
1228 void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
1229 {
1230     if (c.handle() != m_cursor.handle()) {
1231         const bool underMouse = QWindowsContext::instance()->windowUnderMouse() == window();
1232         if (QWindowsContext::verboseWindows)
1233             qDebug() << window() << __FUNCTION__ << "Shape=" << c.cursor().shape()
1234                      << " isWUM=" << underMouse;
1235         m_cursor = c;
1236         if (underMouse)
1237             applyCursor();
1238     }
1239 }
1240
1241 /*!
1242     \brief Find a child window using flags from  ChildWindowFromPointEx.
1243 */
1244
1245 QWindowsWindow *QWindowsWindow::childAtScreenPoint(const QPoint &screenPoint,
1246                                                            unsigned cwexflags) const
1247 {
1248     if (m_data.hwnd)
1249         return QWindowsContext::instance()->findPlatformWindowAt(m_data.hwnd, screenPoint, cwexflags);
1250     return 0;
1251 }
1252
1253 QWindowsWindow *QWindowsWindow::childAt(const QPoint &clientPoint, unsigned cwexflags) const
1254 {
1255     if (m_data.hwnd)
1256         return childAtScreenPoint(QWindowsGeometryHint::mapToGlobal(m_data.hwnd, clientPoint),
1257                                   cwexflags);
1258     return 0;
1259 }
1260
1261 QByteArray QWindowsWindow::debugWindowFlags(Qt::WindowFlags wf)
1262 {
1263     const int iwf = int(wf);
1264     QByteArray rc = "0x";
1265     rc += QByteArray::number(iwf, 16);
1266     rc += " [";
1267
1268     switch ((iwf & Qt::WindowType_Mask)) {
1269     case Qt::Widget:
1270         rc += " Widget";
1271         break;
1272     case Qt::Window:
1273         rc += " Window";
1274         break;
1275     case Qt::Dialog:
1276         rc += " Dialog";
1277         break;
1278     case Qt::Sheet:
1279         rc += " Sheet";
1280         break;
1281     case Qt::Popup:
1282         rc += " Popup";
1283         break;
1284     case Qt::Tool:
1285         rc += " Tool";
1286         break;
1287     case Qt::ToolTip:
1288         rc += " ToolTip";
1289         break;
1290     case Qt::SplashScreen:
1291         rc += " SplashScreen";
1292         break;
1293     case Qt::Desktop:
1294         rc += " Desktop";
1295         break;
1296     case Qt::SubWindow:
1297         rc += " SubWindow";
1298         break;
1299     }
1300     if (iwf & Qt::MSWindowsFixedSizeDialogHint) rc += " MSWindowsFixedSizeDialogHint";
1301     if (iwf & Qt::MSWindowsOwnDC) rc += " MSWindowsOwnDC";
1302     if (iwf & Qt::FramelessWindowHint) rc += " FramelessWindowHint";
1303     if (iwf & Qt::WindowTitleHint) rc += " WindowTitleHint";
1304     if (iwf & Qt::WindowSystemMenuHint) rc += " WindowSystemMenuHint";
1305     if (iwf & Qt::WindowMinimizeButtonHint) rc += " WindowMinimizeButtonHint";
1306     if (iwf & Qt::WindowMaximizeButtonHint) rc += " WindowMaximizeButtonHint";
1307     if (iwf & Qt::WindowContextHelpButtonHint) rc += " WindowContextHelpButtonHint";
1308     if (iwf & Qt::WindowShadeButtonHint) rc += " WindowShadeButtonHint";
1309     if (iwf & Qt::WindowStaysOnTopHint) rc += " WindowStaysOnTopHint";
1310     if (iwf & Qt::CustomizeWindowHint) rc += " CustomizeWindowHint";
1311     if (iwf & Qt::WindowStaysOnBottomHint) rc += " WindowStaysOnBottomHint";
1312     if (iwf & Qt::WindowCloseButtonHint) rc += " WindowCloseButtonHint";
1313     rc += ']';
1314     return rc;
1315 }
1316
1317 QT_END_NAMESPACE