Windows: Restore maximized/full screen widgets to correct screen.
[qt:qt.git] / src / gui / kernel / qwidget.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qapplication.h"
43 #include "qapplication_p.h"
44 #include "qbrush.h"
45 #include "qcursor.h"
46 #include "qdesktopwidget.h"
47 #include "qevent.h"
48 #include "qhash.h"
49 #include "qlayout.h"
50 #include "qmenu.h"
51 #include "qmetaobject.h"
52 #include "qpixmap.h"
53 #include "qpointer.h"
54 #include "qstack.h"
55 #include "qstyle.h"
56 #include "qstylefactory.h"
57 #include "qvariant.h"
58 #include "qwidget.h"
59 #include "qstyleoption.h"
60 #ifndef QT_NO_ACCESSIBILITY
61 # include "qaccessible.h"
62 #endif
63 #if defined(Q_WS_WIN)
64 # include "qt_windows.h"
65 #endif
66 #ifdef Q_WS_MAC
67 # include "qt_mac_p.h"
68 # include "qt_cocoa_helpers_mac_p.h"
69 # include "qmainwindow.h"
70 # include "qtoolbar.h"
71 # include <private/qmainwindowlayout_p.h>
72 #endif
73 #if defined(Q_WS_QWS)
74 # include "qwsdisplay_qws.h"
75 # include "qwsmanager_qws.h"
76 # include "qpaintengine.h" // for PorterDuff
77 # include "private/qwindowsurface_qws_p.h"
78 #endif
79 #if defined(Q_WS_QPA)
80 #include "qplatformwindow_qpa.h"
81 #endif
82 #include "qpainter.h"
83 #include "qtooltip.h"
84 #include "qwhatsthis.h"
85 #include "qdebug.h"
86 #include "private/qstylesheetstyle_p.h"
87 #include "private/qstyle_p.h"
88 #include "private/qinputcontext_p.h"
89 #include "qfileinfo.h"
90 #include "private/qsoftkeymanager_p.h"
91
92 #if defined (Q_WS_WIN)
93 # include <private/qwininputcontext_p.h>
94 #endif
95
96 #if defined(Q_WS_X11)
97 # include <private/qpaintengine_x11_p.h>
98 # include "qx11info_x11.h"
99 #endif
100
101 #include <private/qgraphicseffect_p.h>
102 #include <private/qwindowsurface_p.h>
103 #include <private/qbackingstore_p.h>
104 #ifdef Q_WS_MAC
105 # include <private/qpaintengine_mac_p.h>
106 #endif
107 #include <private/qpaintengine_raster_p.h>
108
109 #if defined(Q_OS_SYMBIAN)
110 #include "private/qt_s60_p.h"
111 #endif
112
113 #include "qwidget_p.h"
114 #include "qaction_p.h"
115 #include "qlayout_p.h"
116 #include "QtGui/qgraphicsproxywidget.h"
117 #include "QtGui/qgraphicsscene.h"
118 #include "private/qgraphicsproxywidget_p.h"
119 #include "QtGui/qabstractscrollarea.h"
120 #include "private/qabstractscrollarea_p.h"
121 #include "private/qevent_p.h"
122
123 #include "private/qgraphicssystem_p.h"
124 #include "private/qgesturemanager_p.h"
125
126 #ifdef QT_KEYPAD_NAVIGATION
127 #include "qtabwidget.h" // Needed in inTabWidget()
128 #endif // QT_KEYPAD_NAVIGATION
129
130 #ifdef Q_WS_S60
131 #include <aknappui.h>
132 #endif
133
134 #ifdef Q_OS_BLACKBERRY
135 #include <bps/navigator.h>
136 #endif
137
138 #ifdef Q_OS_BLACKBERRY_TABLET
139 #include <bps/orientation.h>
140 #endif
141
142 // widget/widget data creation count
143 //#define QWIDGET_EXTRA_DEBUG
144 //#define ALIEN_DEBUG
145
146 QT_BEGIN_NAMESPACE
147
148 #if !defined(Q_WS_QWS)
149 static bool qt_enable_backingstore = true;
150 #endif
151 #ifdef Q_WS_X11
152 // for compatibility with Qt 4.0
153 Q_GUI_EXPORT void qt_x11_set_global_double_buffer(bool enable)
154 {
155     qt_enable_backingstore = enable;
156 }
157 #endif
158
159 #if defined(QT_MAC_USE_COCOA)
160 bool qt_mac_clearDirtyOnWidgetInsideDrawWidget = false;
161 #endif
162
163 static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
164 {
165     return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) &&
166             qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()));
167 }
168
169 static inline bool hasBackingStoreSupport()
170 {
171 #ifdef Q_WS_MAC
172     return QApplicationPrivate::graphicsSystem() != 0;
173 #else
174     return true;
175 #endif
176 }
177
178 #ifdef Q_WS_MAC
179 #  define QT_NO_PAINT_DEBUG
180 #endif
181
182 extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
183 extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
184
185 /*!
186     \internal
187     \class QWidgetBackingStoreTracker
188     \brief Class which allows tracking of which widgets are using a given backing store
189
190     QWidgetBackingStoreTracker is a thin wrapper around a QWidgetBackingStore pointer,
191     which maintains a list of the QWidgets which are currently using the backing
192     store.  This list is modified via the registerWidget and unregisterWidget functions.
193  */
194
195 QWidgetBackingStoreTracker::QWidgetBackingStoreTracker()
196     :   m_ptr(0)
197 {
198
199 }
200
201 QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker()
202 {
203     delete m_ptr;
204 }
205
206 /*!
207     \internal
208     Destroy the contained QWidgetBackingStore, if not null, and clear the list of
209     widgets using the backing store, then create a new QWidgetBackingStore, providing
210     the QWidget.
211  */
212 void QWidgetBackingStoreTracker::create(QWidget *widget)
213 {
214     destroy();
215     m_ptr = new QWidgetBackingStore(widget);
216 }
217
218 /*!
219     \internal
220     Destroy the contained QWidgetBackingStore, if not null, and clear the list of
221     widgets using the backing store.
222  */
223 void QWidgetBackingStoreTracker::destroy()
224 {
225     delete m_ptr;
226     m_ptr = 0;
227     m_widgets.clear();
228 }
229
230 /*!
231     \internal
232     Add the widget to the list of widgets currently using the backing store.
233     If the widget was already in the list, this function is a no-op.
234  */
235 void QWidgetBackingStoreTracker::registerWidget(QWidget *w)
236 {
237     Q_ASSERT(m_ptr);
238     Q_ASSERT(w->internalWinId());
239     Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
240     m_widgets.insert(w);
241 }
242
243 /*!
244     \internal
245     Remove the widget from the list of widgets currently using the backing store.
246     If the widget was in the list, and removing it causes the list to be empty,
247     the backing store is deleted.
248     If the widget was not in the list, this function is a no-op.
249  */
250 void QWidgetBackingStoreTracker::unregisterWidget(QWidget *w)
251 {
252     if (m_widgets.remove(w) && m_widgets.isEmpty()) {
253         delete m_ptr;
254         m_ptr = 0;
255     }
256 }
257
258 /*!
259     \internal
260     Recursively remove widget and all of its descendents.
261  */
262 void QWidgetBackingStoreTracker::unregisterWidgetSubtree(QWidget *widget)
263 {
264     unregisterWidget(widget);
265     foreach (QObject *child, widget->children())
266         if (QWidget *childWidget = qobject_cast<QWidget *>(child))
267             unregisterWidgetSubtree(childWidget);
268 }
269
270 QWidgetPrivate::QWidgetPrivate(int version)
271     : QObjectPrivate(version)
272       , extra(0)
273       , focus_next(0)
274       , focus_prev(0)
275       , focus_child(0)
276       , layout(0)
277       , needsFlush(0)
278       , redirectDev(0)
279       , widgetItem(0)
280       , extraPaintEngine(0)
281       , polished(0)
282       , graphicsEffect(0)
283 #if !defined(QT_NO_IM)
284       , imHints(Qt::ImhNone)
285 #endif
286       , inheritedFontResolveMask(0)
287       , inheritedPaletteResolveMask(0)
288       , leftmargin(0)
289       , topmargin(0)
290       , rightmargin(0)
291       , bottommargin(0)
292       , leftLayoutItemMargin(0)
293       , topLayoutItemMargin(0)
294       , rightLayoutItemMargin(0)
295       , bottomLayoutItemMargin(0)
296       , hd(0)
297       , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred)
298       , fg_role(QPalette::NoRole)
299       , bg_role(QPalette::NoRole)
300       , dirtyOpaqueChildren(1)
301       , isOpaque(0)
302       , inDirtyList(0)
303       , isScrolled(0)
304       , isMoved(0)
305       , isGLWidget(0)
306       , usesDoubleBufferedGLContext(0)
307 #ifndef QT_NO_IM
308       , inheritsInputMethodHints(0)
309 #endif
310       , inSetParent(0)
311 #if defined(Q_WS_X11)
312       , picture(0)
313 #elif defined(Q_WS_WIN)
314       , noPaintOnScreen(0)
315   #ifndef QT_NO_GESTURES
316       , nativeGesturePanEnabled(0)
317   #endif
318 #elif defined(Q_WS_MAC)
319       , needWindowChange(0)
320       , window_event(0)
321       , qd_hd(0)
322 #elif defined(Q_OS_SYMBIAN)
323       , symbianScreenNumber(0)
324       , fixNativeOrientationCalled(false)
325       , isGLGlobalShareWidget(0)
326 #endif
327 {
328     if (!qApp) {
329         qFatal("QWidget: Must construct a QApplication before a QPaintDevice");
330         return;
331     }
332
333     if (version != QObjectPrivateVersion)
334         qFatal("Cannot mix incompatible Qt libraries");
335
336     isWidget = true;
337     memset(high_attributes, 0, sizeof(high_attributes));
338 #if QT_MAC_USE_COCOA
339     drawRectOriginalAdded = false;
340     originalDrawMethod = true;
341     changeMethods = false;
342     isInUnifiedToolbar = false;
343     unifiedSurface = 0;
344     toolbar_ancestor = 0;
345     flushRequested = false;
346     touchEventsEnabled = false;
347 #endif // QT_MAC_USE_COCOA
348 #ifdef QWIDGET_EXTRA_DEBUG
349     static int count = 0;
350     qDebug() << "widgets" << ++count;
351 #endif
352 }
353
354
355 QWidgetPrivate::~QWidgetPrivate()
356 {
357 #ifdef Q_OS_SYMBIAN
358     _q_cleanupWinIds();
359 #endif
360
361     if (widgetItem)
362         widgetItem->wid = 0;
363
364     if (extra)
365         deleteExtra();
366
367 #ifndef QT_NO_GRAPHICSEFFECT
368     delete graphicsEffect;
369 #endif //QT_NO_GRAPHICSEFFECT
370 }
371
372 class QDummyWindowSurface : public QWindowSurface
373 {
374 public:
375     QDummyWindowSurface(QWidget *window) : QWindowSurface(window) {}
376     QPaintDevice *paintDevice() { return window(); }
377     void flush(QWidget *, const QRegion &, const QPoint &) {}
378 };
379
380 QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
381 {
382     Q_Q(QWidget);
383
384     QWindowSurface *surface;
385 #ifndef QT_NO_PROPERTIES
386     if (q->property("_q_DummyWindowSurface").toBool()) {
387         surface = new QDummyWindowSurface(q);
388     } else
389 #endif
390     {
391         if (QApplicationPrivate::graphicsSystem())
392             surface = QApplicationPrivate::graphicsSystem()->createWindowSurface(q);
393         else
394             surface = createDefaultWindowSurface_sys();
395     }
396
397     return surface;
398 }
399
400 /*!
401     \internal
402 */
403 void QWidgetPrivate::scrollChildren(int dx, int dy)
404 {
405     Q_Q(QWidget);
406     if (q->children().size() > 0) {        // scroll children
407         QPoint pd(dx, dy);
408         QObjectList childObjects = q->children();
409         for (int i = 0; i < childObjects.size(); ++i) { // move all children
410             QWidget *w = qobject_cast<QWidget*>(childObjects.at(i));
411             if (w && !w->isWindow()) {
412                 QPoint oldp = w->pos();
413                 QRect  r(w->pos() + pd, w->size());
414                 w->data->crect = r;
415 #ifndef Q_WS_QWS
416                 if (w->testAttribute(Qt::WA_WState_Created))
417                     w->d_func()->setWSGeometry();
418 #endif
419                 w->d_func()->setDirtyOpaqueRegion();
420                 QMoveEvent e(r.topLeft(), oldp);
421                 QApplication::sendEvent(w, &e);
422             }
423         }
424     }
425 }
426
427 #ifndef QT_NO_IM
428 QInputContext *QWidgetPrivate::assignedInputContext() const
429 {
430     const QWidget *widget = q_func();
431     while (widget) {
432         if (QInputContext *qic = widget->d_func()->ic)
433             return qic;
434         widget = widget->parentWidget();
435     }
436     return 0;
437 }
438
439 QInputContext *QWidgetPrivate::inputContext() const
440 {
441     if (QInputContext *qic = assignedInputContext())
442         return qic;
443     return qApp->inputContext();
444 }
445
446 /*!
447     This function returns the QInputContext for this widget. By
448     default the input context is inherited from the widgets
449     parent. For toplevels it is inherited from QApplication.
450
451     You can override this and set a special input context for this
452     widget by using the setInputContext() method.
453
454     \sa setInputContext()
455 */
456 QInputContext *QWidget::inputContext()
457 {
458     Q_D(QWidget);
459     if (!testAttribute(Qt::WA_InputMethodEnabled))
460         return 0;
461
462     return d->inputContext();
463 }
464
465 /*!
466   This function sets the input context \a context
467   on this widget.
468
469   Qt takes ownership of the given input \a context.
470
471   \sa inputContext()
472 */
473 void QWidget::setInputContext(QInputContext *context)
474 {
475     Q_D(QWidget);
476     if (!testAttribute(Qt::WA_InputMethodEnabled))
477         return;
478
479     if (context == d->ic)
480         return;
481     if (d->ic)
482         delete d->ic;
483     d->ic = context;
484     if (d->ic)
485         d->ic->setParent(this);
486 }
487 #endif // QT_NO_IM
488
489 /*!
490     \obsolete
491
492     This function can be called on the widget that currently has focus
493     to reset the input method operating on it.
494
495     This function is providing for convenience, instead you should use
496     \l{QInputContext::}{reset()} on the input context that was
497     returned by inputContext().
498
499     \sa QInputContext, inputContext(), QInputContext::reset()
500 */
501 void QWidget::resetInputContext()
502 {
503     if (!hasFocus())
504         return;
505 #ifndef QT_NO_IM
506     QInputContext *qic = this->inputContext();
507     if(qic)
508         qic->reset();
509 #endif // QT_NO_IM
510 }
511
512 #ifdef QT_KEYPAD_NAVIGATION
513 QPointer<QWidget> QWidgetPrivate::editingWidget;
514
515 /*!
516     Returns true if this widget currently has edit focus; otherwise false.
517
518     This feature is only available in Qt for Embedded Linux.
519
520     \sa setEditFocus(), QApplication::keypadNavigationEnabled()
521 */
522 bool QWidget::hasEditFocus() const
523 {
524     const QWidget* w = this;
525     while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
526         w = w->d_func()->extra->focus_proxy;
527     return QWidgetPrivate::editingWidget == w;
528 }
529
530 /*!
531     \fn void QWidget::setEditFocus(bool enable)
532
533     If \a enable is true, make this widget have edit focus, in which
534     case Qt::Key_Up and Qt::Key_Down will be delivered to the widget
535     normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to
536     change focus.
537
538     This feature is only available in Qt for Embedded Linux and Qt
539     for Symbian.
540
541     \sa hasEditFocus(), QApplication::keypadNavigationEnabled()
542 */
543 void QWidget::setEditFocus(bool on)
544 {
545     QWidget *f = this;
546     while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
547         f = f->d_func()->extra->focus_proxy;
548
549     if (QWidgetPrivate::editingWidget && QWidgetPrivate::editingWidget != f)
550         QWidgetPrivate::editingWidget->setEditFocus(false);
551
552     if (on && !f->hasFocus())
553         f->setFocus();
554
555     if ((!on && !QWidgetPrivate::editingWidget)
556         || (on && QWidgetPrivate::editingWidget == f)) {
557         return;
558     }
559
560     if (!on && QWidgetPrivate::editingWidget == f) {
561         QWidgetPrivate::editingWidget = 0;
562         QEvent event(QEvent::LeaveEditFocus);
563         QApplication::sendEvent(f, &event);
564         QApplication::sendEvent(f->style(), &event);
565     } else if (on) {
566         QWidgetPrivate::editingWidget = f;
567         QEvent event(QEvent::EnterEditFocus);
568         QApplication::sendEvent(f, &event);
569         QApplication::sendEvent(f->style(), &event);
570     }
571 }
572 #endif
573
574 /*!
575     \property QWidget::autoFillBackground
576     \brief whether the widget background is filled automatically
577     \since 4.1
578
579     If enabled, this property will cause Qt to fill the background of the
580     widget before invoking the paint event. The color used is defined by the
581     QPalette::Window color role from the widget's \l{QPalette}{palette}.
582
583     In addition, Windows are always filled with QPalette::Window, unless the
584     WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
585
586     This property cannot be turned off (i.e., set to false) if a widget's
587     parent has a static gradient for its background.
588
589     \warning Use this property with caution in conjunction with
590     \l{Qt Style Sheets}. When a widget has a style sheet with a valid
591     background or a border-image, this property is automatically disabled.
592
593     By default, this property is false.
594
595     \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
596     {QWidget#Transparency and Double Buffering}{Transparency and Double Buffering}
597 */
598 bool QWidget::autoFillBackground() const
599 {
600     Q_D(const QWidget);
601     return d->extra && d->extra->autoFillBackground;
602 }
603
604 void QWidget::setAutoFillBackground(bool enabled)
605 {
606     Q_D(QWidget);
607     if (!d->extra)
608         d->createExtra();
609     if (d->extra->autoFillBackground == enabled)
610         return;
611
612     d->extra->autoFillBackground = enabled;
613     d->updateIsOpaque();
614     update();
615     d->updateIsOpaque();
616 }
617
618 /*!
619     \class QWidget
620     \brief The QWidget class is the base class of all user interface objects.
621
622     \ingroup basicwidgets
623
624     The widget is the atom of the user interface: it receives mouse, keyboard
625     and other events from the window system, and paints a representation of
626     itself on the screen. Every widget is rectangular, and they are sorted in a
627     Z-order. A widget is clipped by its parent and by the widgets in front of
628     it.
629
630     A widget that is not embedded in a parent widget is called a window.
631     Usually, windows have a frame and a title bar, although it is also possible
632     to create windows without such decoration using suitable
633     \l{Qt::WindowFlags}{window flags}). In Qt, QMainWindow and the various
634     subclasses of QDialog are the most common window types.
635
636     Every widget's constructor accepts one or two standard arguments:
637
638     \list 1
639         \i  \c{QWidget *parent = 0} is the parent of the new widget. If it is 0
640             (the default), the new widget will be a window. If not, it will be
641             a child of \e parent, and be constrained by \e parent's geometry
642             (unless you specify Qt::Window as window flag).
643         \i  \c{Qt::WindowFlags f = 0} (where available) sets the window flags;
644             the default is suitable for almost all widgets, but to get, for
645             example, a window without a window system frame, you must use
646             special flags.
647     \endlist
648
649     QWidget has many member functions, but some of them have little direct
650     functionality; for example, QWidget has a font property, but never uses
651     this itself. There are many subclasses which provide real functionality,
652     such as QLabel, QPushButton, QListWidget, and QTabWidget.
653
654
655     \section1 Top-Level and Child Widgets
656
657     A widget without a parent widget is always an independent window (top-level
658     widget). For these widgets, setWindowTitle() and setWindowIcon() set the
659     title bar and icon respectively.
660
661     Non-window widgets are child widgets, displayed within their parent
662     widgets. Most widgets in Qt are mainly useful as child widgets. For
663     example, it is possible to display a button as a top-level window, but most
664     people prefer to put their buttons inside other widgets, such as QDialog.
665
666     \image parent-child-widgets.png A parent widget containing various child widgets.
667
668     The diagram above shows a QGroupBox widget being used to hold various child
669     widgets in a layout provided by QGridLayout. The QLabel child widgets have
670     been outlined to indicate their full sizes.
671
672     If you want to use a QWidget to hold child widgets you will usually want to
673     add a layout to the parent QWidget. See \l{Layout Management} for more
674     information.
675
676
677     \section1 Composite Widgets
678
679     When a widget is used as a container to group a number of child widgets, it
680     is known as a composite widget. These can be created by constructing a
681     widget with the required visual properties - a QFrame, for example - and
682     adding child widgets to it, usually managed by a layout. The above diagram
683     shows such a composite widget that was created using \l{Qt Designer}.
684
685     Composite widgets can also be created by subclassing a standard widget,
686     such as QWidget or QFrame, and adding the necessary layout and child
687     widgets in the constructor of the subclass. Many of the \l{Qt Examples}
688     {examples provided with Qt} use this approach, and it is also covered in
689     the Qt \l{Tutorials}.
690
691
692     \section1 Custom Widgets and Painting
693
694     Since QWidget is a subclass of QPaintDevice, subclasses can be used to
695     display custom content that is composed using a series of painting
696     operations with an instance of the QPainter class. This approach contrasts
697     with the canvas-style approach used by the \l{Graphics View}
698     {Graphics View Framework} where items are added to a scene by the
699     application and are rendered by the framework itself.
700
701     Each widget performs all painting operations from within its paintEvent()
702     function. This is called whenever the widget needs to be redrawn, either
703     as a result of some external change or when requested by the application.
704
705     The \l{widgets/analogclock}{Analog Clock example} shows how a simple widget
706     can handle paint events.
707
708
709     \section1 Size Hints and Size Policies
710
711     When implementing a new widget, it is almost always useful to reimplement
712     sizeHint() to provide a reasonable default size for the widget and to set
713     the correct size policy with setSizePolicy().
714
715     By default, composite widgets which do not provide a size hint will be
716     sized according to the space requirements of their child widgets.
717
718     The size policy lets you supply good default behavior for the layout
719     management system, so that other widgets can contain and manage yours
720     easily. The default size policy indicates that the size hint represents
721     the preferred size of the widget, and this is often good enough for many
722     widgets.
723
724     \note The size of top-level widgets are constrained to 2/3 of the desktop's
725     height and width. You can resize() the widget manually if these bounds are
726     inadequate.
727
728
729     \section1 Events
730
731     Widgets respond to events that are typically caused by user actions. Qt
732     delivers events to widgets by calling specific event handler functions with
733     instances of QEvent subclasses containing information about each event.
734
735     If your widget only contains child widgets, you probably do not need to
736     implement any event handlers. If you want to detect a mouse click in a
737     child widget call the child's underMouse() function inside the widget's
738     mousePressEvent().
739
740     The \l{widgets/scribble}{Scribble example} implements a wider set of
741     events to handle mouse movement, button presses, and window resizing.
742
743     You will need to supply the behavior and content for your own widgets, but
744     here is a brief overview of the events that are relevant to QWidget,
745     starting with the most common ones:
746
747     \list
748         \i  paintEvent() is called whenever the widget needs to be repainted.
749             Every widget displaying custom content must implement it. Painting
750             using a QPainter can only take place in a paintEvent() or a
751             function called by a paintEvent().
752         \i  resizeEvent() is called when the widget has been resized.
753         \i  mousePressEvent() is called when a mouse button is pressed while
754             the mouse cursor is inside the widget, or when the widget has
755             grabbed the mouse using grabMouse(). Pressing the mouse without
756             releasing it is effectively the same as calling grabMouse().
757         \i  mouseReleaseEvent() is called when a mouse button is released. A
758             widget receives mouse release events when it has received the
759             corresponding mouse press event. This means that if the user
760             presses the mouse inside \e your widget, then drags the mouse
761             somewhere else before releasing the mouse button, \e your widget
762             receives the release event. There is one exception: if a popup menu
763             appears while the mouse button is held down, this popup immediately
764             steals the mouse events.
765         \i  mouseDoubleClickEvent() is called when the user double-clicks in
766             the widget. If the user double-clicks, the widget receives a mouse
767             press event, a mouse release event and finally this event instead
768             of a second mouse press event. (Some mouse move events may also be
769             received if the mouse is not held steady during this operation.) It
770             is \e{not possible} to distinguish a click from a double-click
771             until the second click arrives. (This is one reason why most GUI
772             books recommend that double-clicks be an extension of
773             single-clicks, rather than trigger a different action.)
774     \endlist
775
776     Widgets that accept keyboard input need to reimplement a few more event
777     handlers:
778
779     \list
780         \i  keyPressEvent() is called whenever a key is pressed, and again when
781             a key has been held down long enough for it to auto-repeat. The
782             \key Tab and \key Shift+Tab keys are only passed to the widget if
783             they are not used by the focus-change mechanisms. To force those
784             keys to be processed by your widget, you must reimplement
785             QWidget::event().
786         \i  focusInEvent() is called when the widget gains keyboard focus
787             (assuming you have called setFocusPolicy()). Well-behaved widgets
788             indicate that they own the keyboard focus in a clear but discreet
789             way.
790         \i  focusOutEvent() is called when the widget loses keyboard focus.
791     \endlist
792
793     You may be required to also reimplement some of the less common event
794     handlers:
795
796     \list
797         \i  mouseMoveEvent() is called whenever the mouse moves while a mouse
798             button is held down. This can be useful during drag and drop
799             operations. If you call \l{setMouseTracking()}{setMouseTracking}(true),
800             you get mouse move events even when no buttons are held down.
801             (See also the \l{Drag and Drop} guide.)
802         \i  keyReleaseEvent() is called whenever a key is released and while it
803             is held down (if the key is auto-repeating). In that case, the
804             widget will receive a pair of key release and key press event for
805             every repeat. The \key Tab and \key Shift+Tab keys are only passed
806             to the widget if they are not used by the focus-change mechanisms.
807             To force those keys to be processed by your widget, you must
808             reimplement QWidget::event().
809         \i  wheelEvent() is called whenever the user turns the mouse wheel
810             while the widget has the focus.
811         \i  enterEvent() is called when the mouse enters the widget's screen
812             space. (This excludes screen space owned by any of the widget's
813             children.)
814         \i  leaveEvent() is called when the mouse leaves the widget's screen
815             space. If the mouse enters a child widget it will not cause a
816             leaveEvent().
817         \i  moveEvent() is called when the widget has been moved relative to
818             its parent.
819         \i  closeEvent() is called when the user closes the widget (or when
820             close() is called).
821     \endlist
822
823     There are also some rather obscure events described in the documentation
824     for QEvent::Type. To handle these events, you need to reimplement event()
825     directly.
826
827     The default implementation of event() handles \key Tab and \key Shift+Tab
828     (to move the keyboard focus), and passes on most of the other events to
829     one of the more specialized handlers above.
830
831     Events and the mechanism used to deliver them are covered in 
832     \l{The Event System}.
833
834     \section1 Groups of Functions and Properties
835
836     \table
837     \header \i Context \i Functions and Properties
838
839     \row \i Window functions \i
840         show(),
841         hide(),
842         raise(),
843         lower(),
844         close().
845
846     \row \i Top-level windows \i
847         \l windowModified, \l windowTitle, \l windowIcon, \l windowIconText,
848         \l isActiveWindow, activateWindow(), \l minimized, showMinimized(),
849         \l maximized, showMaximized(), \l fullScreen, showFullScreen(),
850         showNormal().
851
852     \row \i Window contents \i
853         update(),
854         repaint(),
855         scroll().
856
857     \row \i Geometry \i
858         \l pos, x(), y(), \l rect, \l size, width(), height(), move(), resize(),
859         \l sizePolicy, sizeHint(), minimumSizeHint(),
860         updateGeometry(), layout(),
861         \l frameGeometry, \l geometry, \l childrenRect, \l childrenRegion,
862         adjustSize(),
863         mapFromGlobal(), mapToGlobal(),
864         mapFromParent(), mapToParent(),
865         \l maximumSize, \l minimumSize, \l sizeIncrement,
866         \l baseSize, setFixedSize()
867
868     \row \i Mode \i
869         \l visible, isVisibleTo(),
870         \l enabled, isEnabledTo(),
871         \l modal,
872         isWindow(),
873         \l mouseTracking,
874         \l updatesEnabled,
875         visibleRegion().
876
877     \row \i Look and feel \i
878         style(),
879         setStyle(),
880         \l styleSheet,
881         \l cursor,
882         \l font,
883         \l palette,
884         backgroundRole(), setBackgroundRole(),
885         fontInfo(), fontMetrics().
886
887     \row \i Keyboard focus functions \i
888         \l focus, \l focusPolicy,
889         setFocus(), clearFocus(), setTabOrder(), setFocusProxy(),
890         focusNextChild(), focusPreviousChild().
891
892     \row \i Mouse and keyboard grabbing \i
893         grabMouse(), releaseMouse(),
894         grabKeyboard(), releaseKeyboard(),
895         mouseGrabber(), keyboardGrabber().
896
897     \row \i Event handlers \i
898         event(),
899         mousePressEvent(),
900         mouseReleaseEvent(),
901         mouseDoubleClickEvent(),
902         mouseMoveEvent(),
903         keyPressEvent(),
904         keyReleaseEvent(),
905         focusInEvent(),
906         focusOutEvent(),
907         wheelEvent(),
908         enterEvent(),
909         leaveEvent(),
910         paintEvent(),
911         moveEvent(),
912         resizeEvent(),
913         closeEvent(),
914         dragEnterEvent(),
915         dragMoveEvent(),
916         dragLeaveEvent(),
917         dropEvent(),
918         childEvent(),
919         showEvent(),
920         hideEvent(),
921         customEvent().
922         changeEvent(),
923
924     \row \i System functions \i
925         parentWidget(), window(), setParent(), winId(),
926         find(), metric().
927
928     \row \i Interactive help \i
929         setToolTip(), setWhatsThis()
930
931     \endtable
932
933
934     \section1 Widget Style Sheets
935
936     In addition to the standard widget styles for each platform, widgets can
937     also be styled according to rules specified in a \l{styleSheet}
938     {style sheet}. This feature enables you to customize the appearance of
939     specific widgets to provide visual cues to users about their purpose. For
940     example, a button could be styled in a particular way to indicate that it
941     performs a destructive action.
942
943     The use of widget style sheets is described in more detail in the
944     \l{Qt Style Sheets} document.
945
946
947     \section1 Transparency and Double Buffering
948
949     Since Qt 4.0, QWidget automatically double-buffers its painting, so there
950     is no need to write double-buffering code in paintEvent() to avoid
951     flicker.
952
953     Since Qt 4.1, the Qt::WA_ContentsPropagated widget attribute has been
954     deprecated. Instead, the contents of parent widgets are propagated by
955     default to each of their children as long as Qt::WA_PaintOnScreen is not
956     set. Custom widgets can be written to take advantage of this feature by
957     updating irregular regions (to create non-rectangular child widgets), or
958     painting with colors that have less than full alpha component. The
959     following diagram shows how attributes and properties of a custom widget
960     can be fine-tuned to achieve different effects.
961
962     \image propagation-custom.png
963
964     In the above diagram, a semi-transparent rectangular child widget with an
965     area removed is constructed and added to a parent widget (a QLabel showing
966     a pixmap). Then, different properties and widget attributes are set to
967     achieve different effects:
968
969     \list
970         \i  The left widget has no additional properties or widget attributes
971             set. This default state suits most custom widgets using
972             transparency, are irregularly-shaped, or do not paint over their
973             entire area with an opaque brush.
974         \i  The center widget has the \l autoFillBackground property set. This
975             property is used with custom widgets that rely on the widget to
976             supply a default background, and do not paint over their entire
977             area with an opaque brush.
978         \i  The right widget has the Qt::WA_OpaquePaintEvent widget attribute
979             set. This indicates that the widget will paint over its entire area
980             with opaque colors. The widget's area will initially be
981             \e{uninitialized}, represented in the diagram with a red diagonal
982             grid pattern that shines through the overpainted area. The
983             Qt::WA_OpaquePaintArea attribute is useful for widgets that need to
984             paint their own specialized contents quickly and do not need a
985             default filled background.
986     \endlist
987
988     To rapidly update custom widgets with simple background colors, such as
989     real-time plotting or graphing widgets, it is better to define a suitable
990     background color (using setBackgroundRole() with the
991     QPalette::Window role), set the \l autoFillBackground property, and only
992     implement the necessary drawing functionality in the widget's paintEvent().
993
994     To rapidly update custom widgets that constantly paint over their entire
995     areas with opaque content, e.g., video streaming widgets, it is better to
996     set the widget's Qt::WA_OpaquePaintEvent, avoiding any unnecessary overhead
997     associated with repainting the widget's background.
998
999     If a widget has both the Qt::WA_OpaquePaintEvent widget attribute \e{and}
1000     the \l autoFillBackground property set, the Qt::WA_OpaquePaintEvent
1001     attribute takes precedence. Depending on your requirements, you should
1002     choose either one of them.
1003
1004     Since Qt 4.1, the contents of parent widgets are also propagated to
1005     standard Qt widgets. This can lead to some unexpected results if the
1006     parent widget is decorated in a non-standard way, as shown in the diagram
1007     below.
1008
1009     \image propagation-standard.png
1010
1011     The scope for customizing the painting behavior of standard Qt widgets,
1012     without resorting to subclassing, is slightly less than that possible for
1013     custom widgets. Usually, the desired appearance of a standard widget can be
1014     achieved by setting its \l autoFillBackground property.
1015
1016
1017     \section1 Creating Translucent Windows
1018
1019     Since Qt 4.5, it has been possible to create windows with translucent regions
1020     on window systems that support compositing.
1021
1022     To enable this feature in a top-level widget, set its Qt::WA_TranslucentBackground
1023     attribute with setAttribute() and ensure that its background is painted with
1024     non-opaque colors in the regions you want to be partially transparent.
1025
1026     Platform notes:
1027
1028     \list
1029     \o X11: This feature relies on the use of an X server that supports ARGB visuals
1030     and a compositing window manager.
1031     \o Windows: The widget needs to have the Qt::FramelessWindowHint window flag set
1032     for the translucency to work.
1033     \endlist
1034
1035
1036     \section1 Native Widgets vs Alien Widgets
1037
1038     Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
1039     system. They do not have a native window handle associated with them. This
1040     feature significantly speeds up widget painting, resizing, and removes flicker.
1041
1042     Should you require the old behavior with native windows, you can choose
1043     one of the following options:
1044
1045     \list 1
1046         \i  Use the \c{QT_USE_NATIVE_WINDOWS=1} in your environment.
1047         \i  Set the Qt::AA_NativeWindows attribute on your application. All
1048             widgets will be native widgets.
1049         \i  Set the Qt::WA_NativeWindow attribute on widgets: The widget itself
1050             and all of its ancestors will become native (unless
1051             Qt::WA_DontCreateNativeAncestors is set).
1052         \i  Call QWidget::winId to enforce a native window (this implies 3).
1053         \i  Set the Qt::WA_PaintOnScreen attribute to enforce a native window
1054             (this implies 3).
1055     \endlist
1056
1057     \sa QEvent, QPainter, QGridLayout, QBoxLayout
1058
1059     \section1 Softkeys
1060
1061     Since Qt 4.6, Softkeys are usually physical keys on a device that have a corresponding label or
1062     other visual representation on the screen that is generally located next to its
1063     physical counterpart. They are most often found on mobile phone platforms. In
1064     modern touch based user interfaces it is also possible to have softkeys that do
1065     not correspond to any physical keys. Softkeys differ from other onscreen labels
1066     in that they are contextual.
1067
1068     In Qt, contextual softkeys are added to a widget by calling addAction() and
1069     passing a \c QAction with a softkey role set on it. When the widget
1070     containing the softkey actions has focus, its softkeys should appear in
1071     the user interface. Softkeys are discovered by traversing the widget
1072     hierarchy so it is possible to define a single set of softkeys that are
1073     present at all times by calling addAction() for a given top level widget.
1074
1075     On some platforms, this concept overlaps with \c QMenuBar such that if no
1076     other softkeys are found and the top level widget is a QMainWindow containing
1077     a QMenuBar, the menubar actions may appear on one of the softkeys.
1078
1079     Note: Currently softkeys are only supported on the Symbian Platform.
1080
1081     \sa addAction(), QAction, QMenuBar
1082
1083 */
1084
1085 QWidgetMapper *QWidgetPrivate::mapper = 0;          // widget with wid
1086 QWidgetSet *QWidgetPrivate::allWidgets = 0;         // widgets with no wid
1087
1088
1089 /*****************************************************************************
1090   QWidget utility functions
1091  *****************************************************************************/
1092
1093 QRegion qt_dirtyRegion(QWidget *widget)
1094 {
1095     if (!widget)
1096         return QRegion();
1097
1098     QWidgetBackingStore *bs = qt_widget_private(widget)->maybeBackingStore();
1099     if (!bs)
1100         return QRegion();
1101
1102     return bs->dirtyRegion(widget);
1103 }
1104
1105 /*****************************************************************************
1106   QWidget member functions
1107  *****************************************************************************/
1108
1109 /*
1110     Widget state flags:
1111   \list
1112   \i Qt::WA_WState_Created The widget has a valid winId().
1113   \i Qt::WA_WState_Visible The widget is currently visible.
1114   \i Qt::WA_WState_Hidden The widget is hidden, i.e. it won't
1115   become visible unless you call show() on it. Qt::WA_WState_Hidden
1116   implies !Qt::WA_WState_Visible.
1117   \i Qt::WA_WState_CompressKeys Compress keyboard events.
1118   \i Qt::WA_WState_BlockUpdates Repaints and updates are disabled.
1119   \i Qt::WA_WState_InPaintEvent Currently processing a paint event.
1120   \i Qt::WA_WState_Reparented The widget has been reparented.
1121   \i Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending.
1122   \i Qt::WA_WState_DND (Deprecated) The widget supports drag and drop, see setAcceptDrops().
1123   \endlist
1124 */
1125
1126 struct QWidgetExceptionCleaner
1127 {
1128     /* this cleans up when the constructor throws an exception */
1129     static inline void cleanup(QWidget *that, QWidgetPrivate *d)
1130     {
1131 #ifdef QT_NO_EXCEPTIONS
1132         Q_UNUSED(that);
1133         Q_UNUSED(d);
1134 #else
1135         QWidgetPrivate::allWidgets->remove(that);
1136         if (d->focus_next != that) {
1137             if (d->focus_next)
1138                 d->focus_next->d_func()->focus_prev = d->focus_prev;
1139             if (d->focus_prev)
1140                 d->focus_prev->d_func()->focus_next = d->focus_next;
1141         }
1142 #endif
1143     }
1144 };
1145
1146 /*!
1147     Constructs a widget which is a child of \a parent, with  widget
1148     flags set to \a f.
1149
1150     If \a parent is 0, the new widget becomes a window. If
1151     \a parent is another widget, this widget becomes a child window
1152     inside \a parent. The new widget is deleted when its \a parent is
1153     deleted.
1154
1155     The widget flags argument, \a f, is normally 0, but it can be set
1156     to customize the frame of a window (i.e. \a
1157     parent must be 0). To customize the frame, use a value composed
1158     from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}.
1159
1160     If you add a child widget to an already visible widget you must
1161     explicitly show the child to make it visible.
1162
1163     Note that the X11 version of Qt may not be able to deliver all
1164     combinations of style flags on all systems. This is because on
1165     X11, Qt can only ask the window manager, and the window manager
1166     can override the application's settings. On Windows, Qt can set
1167     whatever flags you want.
1168
1169     \sa windowFlags
1170 */
1171 QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
1172     : QObject(*new QWidgetPrivate, 0), QPaintDevice()
1173 {
1174     QT_TRY {
1175         d_func()->init(parent, f);
1176     } QT_CATCH(...) {
1177         QWidgetExceptionCleaner::cleanup(this, d_func());
1178         QT_RETHROW;
1179     }
1180 }
1181
1182 #ifdef QT3_SUPPORT
1183 /*!
1184     \overload
1185     \obsolete
1186  */
1187 QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f)
1188     : QObject(*new QWidgetPrivate, 0), QPaintDevice()
1189 {
1190     QT_TRY {
1191         d_func()->init(parent , f);
1192         setObjectName(QString::fromAscii(name));
1193     } QT_CATCH(...) {
1194         QWidgetExceptionCleaner::cleanup(this, d_func());
1195         QT_RETHROW;
1196     }
1197 }
1198 #endif
1199
1200 /*! \internal
1201 */
1202 QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
1203     : QObject(dd, 0), QPaintDevice()
1204 {
1205     Q_D(QWidget);
1206     QT_TRY {
1207         d->init(parent, f);
1208     } QT_CATCH(...) {
1209         QWidgetExceptionCleaner::cleanup(this, d_func());
1210         QT_RETHROW;
1211     }
1212 }
1213
1214 /*!
1215     \internal
1216 */
1217 int QWidget::devType() const
1218 {
1219     return QInternal::Widget;
1220 }
1221
1222
1223 //### w is a "this" ptr, passed as a param because QWorkspace needs special logic
1224 void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
1225 {
1226     bool customize =  (flags & (Qt::CustomizeWindowHint
1227             | Qt::FramelessWindowHint
1228             | Qt::WindowTitleHint
1229             | Qt::WindowSystemMenuHint
1230             | Qt::WindowMinimizeButtonHint
1231             | Qt::WindowMaximizeButtonHint
1232             | Qt::WindowCloseButtonHint
1233             | Qt::WindowContextHelpButtonHint));
1234
1235     uint type = (flags & Qt::WindowType_Mask);
1236
1237     if ((type == Qt::Widget || type == Qt::SubWindow) && w && !w->parent()) {
1238         type = Qt::Window;
1239         flags |= Qt::Window;
1240     }
1241
1242     if (flags & Qt::CustomizeWindowHint) {
1243         // modify window flags to make them consistent.
1244         // Only enable this on non-Mac platforms. Since the old way of doing this would
1245         // interpret WindowSystemMenuHint as a close button and we can't change that behavior
1246         // we can't just add this in.
1247 #ifndef Q_WS_MAC
1248         if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint)) {
1249             flags |= Qt::WindowSystemMenuHint;
1250 #else
1251         if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint
1252                      | Qt::WindowSystemMenuHint)) {
1253 #endif
1254             flags |= Qt::WindowTitleHint;
1255             flags &= ~Qt::FramelessWindowHint;
1256         }
1257     } else if (customize && !(flags & Qt::FramelessWindowHint)) {
1258         // if any of the window hints that affect the titlebar are set
1259         // and the window is supposed to have frame, we add a titlebar
1260         // and system menu by default.
1261         flags |= Qt::WindowSystemMenuHint;
1262         flags |= Qt::WindowTitleHint;
1263     }
1264     if (customize)
1265         ; // don't modify window flags if the user explicitly set them.
1266     else if (type == Qt::Dialog || type == Qt::Sheet)
1267 #ifndef Q_WS_WINCE
1268         flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint | Qt::WindowCloseButtonHint;
1269 #else
1270         flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
1271 #endif
1272     else if (type == Qt::Tool)
1273         flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
1274     else
1275         flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint;
1276
1277
1278 }
1279
1280 void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
1281 {
1282     Q_Q(QWidget);
1283     if (QApplication::type() == QApplication::Tty)
1284         qFatal("QWidget: Cannot create a QWidget when no GUI is being used");
1285
1286     Q_ASSERT(allWidgets);
1287     if (allWidgets)
1288         allWidgets->insert(q);
1289
1290     QWidget *desktopWidget = 0;
1291     if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
1292         desktopWidget = parentWidget;
1293         parentWidget = 0;
1294     }
1295
1296     q->data = &data;
1297
1298 #ifndef QT_NO_THREAD
1299     if (!parent) {
1300         Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
1301                    "Widgets must be created in the GUI thread.");
1302     }
1303 #endif
1304
1305 #if defined(Q_WS_X11)
1306     if (desktopWidget) {
1307         // make sure the widget is created on the same screen as the
1308         // programmer specified desktop widget
1309         xinfo = desktopWidget->d_func()->xinfo;
1310     }
1311 #elif defined(Q_OS_SYMBIAN)
1312     if (desktopWidget) {
1313         symbianScreenNumber = qt_widget_private(desktopWidget)->symbianScreenNumber;
1314     }
1315 #elif defined(Q_WS_QPA)
1316     if (desktopWidget) {
1317         int screen = desktopWidget->d_func()->topData()->screenIndex;
1318         topData()->screenIndex = screen;
1319         QPlatformIntegration *platform = QApplicationPrivate::platformIntegration();
1320         platform->moveToScreen(q, screen);
1321     }
1322 #else
1323     Q_UNUSED(desktopWidget);
1324 #endif
1325
1326     data.fstrut_dirty = true;
1327
1328     data.winid = 0;
1329     data.widget_attributes = 0;
1330     data.window_flags = f;
1331     data.window_state = 0;
1332     data.focus_policy = 0;
1333     data.context_menu_policy = Qt::DefaultContextMenu;
1334     data.window_modality = Qt::NonModal;
1335
1336     data.sizehint_forced = 0;
1337     data.is_closing = 0;
1338     data.in_show = 0;
1339     data.in_set_window_state = 0;
1340     data.in_destructor = false;
1341
1342     // Widgets with Qt::MSWindowsOwnDC (typically QGLWidget) must have a window handle.
1343     if (f & Qt::MSWindowsOwnDC)
1344         q->setAttribute(Qt::WA_NativeWindow);
1345
1346 //#ifdef Q_WS_MAC
1347 //    q->setAttribute(Qt::WA_NativeWindow);
1348 //#endif
1349
1350     q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
1351     adjustQuitOnCloseAttribute();
1352
1353     q->setAttribute(Qt::WA_WState_Hidden);
1354
1355     //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
1356 #ifdef Q_OS_SYMBIAN
1357     if (isGLWidget) {
1358         // Don't waste GPU mem for unnecessary large egl surface until resized by application
1359         data.crect = QRect(0,0,1,1);
1360     } else {
1361         data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,360,640);
1362     }
1363 #else
1364     data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480);
1365 #endif
1366
1367     focus_next = focus_prev = q;
1368
1369     if ((f & Qt::WindowType_Mask) == Qt::Desktop)
1370         q->create();
1371     else if (parentWidget)
1372         q->setParent(parentWidget, data.window_flags);
1373     else {
1374         adjustFlags(data.window_flags, q);
1375         resolveLayoutDirection();
1376         // opaque system background?
1377         const QBrush &background = q->palette().brush(QPalette::Window);
1378         setOpaque(q->isWindow() && background.style() != Qt::NoBrush && background.isOpaque());
1379     }
1380     data.fnt = QFont(data.fnt, q);
1381 #if defined(Q_WS_X11)
1382     data.fnt.x11SetScreen(xinfo.screen());
1383 #endif // Q_WS_X11
1384
1385     q->setAttribute(Qt::WA_PendingMoveEvent);
1386     q->setAttribute(Qt::WA_PendingResizeEvent);
1387
1388     if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances)
1389         QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter;
1390
1391     if (QApplicationPrivate::app_compile_version < 0x040200
1392         || QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation))
1393         q->create();
1394
1395
1396     QEvent e(QEvent::Create);
1397     QApplication::sendEvent(q, &e);
1398     QApplication::postEvent(q, new QEvent(QEvent::PolishRequest));
1399
1400     extraPaintEngine = 0;
1401 }
1402
1403
1404
1405 void QWidgetPrivate::createRecursively()
1406 {
1407     Q_Q(QWidget);
1408     q->create(0, true, true);
1409     for (int i = 0; i < children.size(); ++i) {
1410         QWidget *child = qobject_cast<QWidget *>(children.at(i));
1411         if (child && !child->isHidden() && !child->isWindow() && !child->testAttribute(Qt::WA_WState_Created))
1412             child->d_func()->createRecursively();
1413     }
1414 }
1415
1416
1417
1418
1419 /*!
1420     Creates a new widget window if \a window is 0, otherwise sets the
1421     widget's window to \a window.
1422
1423     Initializes the window (sets the geometry etc.) if \a
1424     initializeWindow is true. If \a initializeWindow is false, no
1425     initialization is performed. This parameter only makes sense if \a
1426     window is a valid window.
1427
1428     Destroys the old window if \a destroyOldWindow is true. If \a
1429     destroyOldWindow is false, you are responsible for destroying the
1430     window yourself (using platform native code).
1431
1432     The QWidget constructor calls create(0,true,true) to create a
1433     window for this widget.
1434 */
1435
1436 void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
1437 {
1438     Q_D(QWidget);
1439     if (testAttribute(Qt::WA_WState_Created) && window == 0 && internalWinId())
1440         return;
1441
1442     if (d->data.in_destructor)
1443         return;
1444
1445     Qt::WindowType type = windowType();
1446     Qt::WindowFlags &flags = data->window_flags;
1447
1448     if ((type == Qt::Widget || type == Qt::SubWindow) && !parentWidget()) {
1449         type = Qt::Window;
1450         flags |= Qt::Window;
1451     }
1452
1453 #ifndef Q_WS_QPA
1454     if (QWidget *parent = parentWidget()) {
1455         if (type & Qt::Window) {
1456             if (!parent->testAttribute(Qt::WA_WState_Created))
1457                 parent->createWinId();
1458         } else if (testAttribute(Qt::WA_NativeWindow) && !parent->internalWinId()
1459                    && !testAttribute(Qt::WA_DontCreateNativeAncestors)) {
1460             // We're about to create a native child widget that doesn't have a native parent;
1461             // enforce a native handle for the parent unless the Qt::WA_DontCreateNativeAncestors
1462             // attribute is set.
1463             d->createWinId(window);
1464             // Nothing more to do.
1465             Q_ASSERT(testAttribute(Qt::WA_WState_Created));
1466             Q_ASSERT(internalWinId());
1467             return;
1468         }
1469     }
1470 #endif //Q_WS_QPA
1471
1472 #ifdef QT3_SUPPORT
1473     if (flags & Qt::WStaticContents)
1474         setAttribute(Qt::WA_StaticContents);
1475     if (flags & Qt::WDestructiveClose)
1476         setAttribute(Qt::WA_DeleteOnClose);
1477     if (flags & Qt::WShowModal)
1478         setWindowModality(Qt::ApplicationModal);
1479     if (flags & Qt::WMouseNoMask)
1480         setAttribute(Qt::WA_MouseNoMask);
1481     if (flags & Qt::WGroupLeader)
1482         setAttribute(Qt::WA_GroupLeader);
1483     if (flags & Qt::WNoMousePropagation)
1484         setAttribute(Qt::WA_NoMousePropagation);
1485 #endif
1486
1487     static int paintOnScreenEnv = -1;
1488     if (paintOnScreenEnv == -1)
1489         paintOnScreenEnv = qgetenv("QT_ONSCREEN_PAINT").toInt() > 0 ? 1 : 0;
1490     if (paintOnScreenEnv == 1)
1491         setAttribute(Qt::WA_PaintOnScreen);
1492
1493     if (QApplicationPrivate::testAttribute(Qt::AA_NativeWindows))
1494         setAttribute(Qt::WA_NativeWindow);
1495
1496 #ifdef ALIEN_DEBUG
1497     qDebug() << "QWidget::create:" << this << "parent:" << parentWidget()
1498              << "Alien?" << !testAttribute(Qt::WA_NativeWindow);
1499 #endif
1500
1501 #if defined (Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP)
1502     // Unregister the dropsite (if already registered) before we
1503     // re-create the widget with a native window.
1504     if (testAttribute(Qt::WA_WState_Created) && !internalWinId() && testAttribute(Qt::WA_NativeWindow)
1505             && d->extra && d->extra->dropTarget) {
1506         d->registerDropSite(false);
1507     }
1508 #endif // defined (Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP)
1509
1510     d->updateIsOpaque();
1511
1512     setAttribute(Qt::WA_WState_Created);                        // set created flag
1513     d->create_sys(window, initializeWindow, destroyOldWindow);
1514
1515     // a real toplevel window needs a backing store
1516     if (isWindow() && windowType() != Qt::Desktop) {
1517         d->topData()->backingStore.destroy();
1518         if (hasBackingStoreSupport())
1519             d->topData()->backingStore.create(this);
1520     }
1521
1522     d->setModal_sys();
1523
1524     if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))
1525         setAttribute(Qt::WA_DropSiteRegistered, true);
1526
1527 #ifdef QT_EVAL
1528     extern void qt_eval_init_widget(QWidget *w);
1529     qt_eval_init_widget(this);
1530 #endif
1531
1532     // need to force the resting of the icon after changing parents
1533     if (testAttribute(Qt::WA_SetWindowIcon))
1534         d->setWindowIcon_sys(true);
1535     if (isWindow() && !d->topData()->iconText.isEmpty())
1536         d->setWindowIconText_helper(d->topData()->iconText);
1537     if (isWindow() && !d->topData()->caption.isEmpty())
1538         d->setWindowTitle_helper(d->topData()->caption);
1539     if (windowType() != Qt::Desktop) {
1540         d->updateSystemBackground();
1541
1542         if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon))
1543             d->setWindowIcon_sys();
1544     }
1545 }
1546
1547 /*!
1548     Destroys the widget.
1549
1550     All this widget's children are deleted first. The application
1551     exits if this widget is the main widget.
1552 */
1553
1554 QWidget::~QWidget()
1555 {
1556     Q_D(QWidget);
1557     d->data.in_destructor = true;
1558
1559 #if defined (QT_CHECK_STATE)
1560     if (paintingActive())
1561         qWarning("QWidget: %s (%s) deleted while being painted", className(), name());
1562 #endif
1563
1564 #ifndef QT_NO_GESTURES
1565     foreach (Qt::GestureType type, d->gestureContext.keys())
1566         ungrabGesture(type);
1567 #endif
1568
1569     // force acceptDrops false before winId is destroyed.
1570     d->registerDropSite(false);
1571
1572 #ifndef QT_NO_ACTION
1573     // remove all actions from this widget
1574     for (int i = 0; i < d->actions.size(); ++i) {
1575         QActionPrivate *apriv = d->actions.at(i)->d_func();
1576         apriv->widgets.removeAll(this);
1577     }
1578     d->actions.clear();
1579 #endif
1580
1581 #ifndef QT_NO_SHORTCUT
1582     // Remove all shortcuts grabbed by this
1583     // widget, unless application is closing
1584     if (!QApplicationPrivate::is_app_closing && testAttribute(Qt::WA_GrabbedShortcut))
1585         qApp->d_func()->shortcutMap.removeShortcut(0, this, QKeySequence());
1586 #endif
1587
1588     // delete layout while we still are a valid widget
1589     delete d->layout;
1590     d->layout = 0;
1591     // Remove myself from focus list
1592
1593     Q_ASSERT(d->focus_next->d_func()->focus_prev == this);
1594     Q_ASSERT(d->focus_prev->d_func()->focus_next == this);
1595
1596     if (d->focus_next != this) {
1597         d->focus_next->d_func()->focus_prev = d->focus_prev;
1598         d->focus_prev->d_func()->focus_next = d->focus_next;
1599         d->focus_next = d->focus_prev = 0;
1600     }
1601
1602 #ifdef QT3_SUPPORT
1603     if (QApplicationPrivate::main_widget == this) {        // reset main widget
1604         QApplicationPrivate::main_widget = 0;
1605         QApplication::quit();
1606     }
1607 #endif
1608
1609     QT_TRY {
1610         clearFocus();
1611     } QT_CATCH(...) {
1612         // swallow this problem because we are in a destructor
1613     }
1614
1615     d->setDirtyOpaqueRegion();
1616
1617     if (isWindow() && isVisible() && internalWinId()) {
1618         QT_TRY {
1619             d->close_helper(QWidgetPrivate::CloseNoEvent);
1620         } QT_CATCH(...) {
1621             // if we're out of memory, at least hide the window.
1622             QT_TRY {
1623                 hide();
1624             } QT_CATCH(...) {
1625                 // and if that also doesn't work, then give up
1626             }
1627         }
1628     }
1629
1630 #if defined(Q_WS_WIN) || defined(Q_WS_X11)|| defined(Q_WS_MAC)
1631     else if (!internalWinId() && isVisible()) {
1632         qApp->d_func()->sendSyntheticEnterLeave(this);
1633     }
1634 #elif defined(Q_WS_QWS) || defined(Q_WS_QPA)
1635     else if (isVisible()) {
1636         qApp->d_func()->sendSyntheticEnterLeave(this);
1637     }
1638 #endif
1639
1640 #ifdef Q_OS_SYMBIAN
1641     if (d->extra && d->extra->topextra && d->extra->topextra->backingStore) {
1642         // Okay, we are about to destroy the top-level window that owns
1643         // the backing store. Make sure we delete the backing store right away
1644         // before the window handle is invalid. This is important because
1645         // the backing store will delete its window surface, which may or may
1646         // not have a reference to this widget that will be used later to
1647         // notify the window it no longer has a surface.
1648         d->extra->topextra->backingStore.destroy();
1649     }
1650 #endif
1651     if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
1652         bs->removeDirtyWidget(this);
1653         if (testAttribute(Qt::WA_StaticContents))
1654             bs->removeStaticWidget(this);
1655     }
1656
1657     delete d->needsFlush;
1658     d->needsFlush = 0;
1659
1660     // set all QPointers for this object to zero
1661     if (d->hasGuards)
1662         QObjectPrivate::clearGuards(this);
1663
1664     if (d->declarativeData) {
1665         QAbstractDeclarativeData::destroyed(d->declarativeData, this);
1666         d->declarativeData = 0;                 // don't activate again in ~QObject
1667     }
1668
1669 #ifdef QT_MAC_USE_COCOA
1670     // QCocoaView holds a pointer back to this widget. Clear it now
1671     // to make sure it's not followed later on. The lifetime of the
1672     // QCocoaView might exceed the lifetime of this widget in cases
1673     // where Cocoa itself holds references to it.
1674     extern void qt_mac_clearCocoaViewQWidgetPointers(QWidget *);
1675     qt_mac_clearCocoaViewQWidgetPointers(this);
1676 #endif
1677
1678     if (!d->children.isEmpty())
1679         d->deleteChildren();
1680
1681 #ifndef QT_NO_ACCESSIBILITY
1682     QAccessible::updateAccessibility(this, 0, QAccessible::ObjectDestroyed);
1683 #endif
1684
1685     QApplication::removePostedEvents(this);
1686
1687     QT_TRY {
1688         destroy();                                        // platform-dependent cleanup
1689     } QT_CATCH(...) {
1690         // if this fails we can't do anything about it but at least we are not allowed to throw.
1691     }
1692     --QWidgetPrivate::instanceCounter;
1693
1694     if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication
1695         QWidgetPrivate::allWidgets->remove(this);
1696
1697     QT_TRY {
1698         QEvent e(QEvent::Destroy);
1699         QCoreApplication::sendEvent(this, &e);
1700     } QT_CATCH(const std::exception&) {
1701         // if this fails we can't do anything about it but at least we are not allowed to throw.
1702     }
1703 }
1704
1705 int QWidgetPrivate::instanceCounter = 0;  // Current number of widget instances
1706 int QWidgetPrivate::maxInstances = 0;     // Maximum number of widget instances
1707
1708 void QWidgetPrivate::setWinId(WId id)                // set widget identifier
1709 {
1710     Q_Q(QWidget);
1711     // the user might create a widget with Qt::Desktop window
1712     // attribute (or create another QDesktopWidget instance), which
1713     // will have the same windowid (the root window id) as the
1714     // qt_desktopWidget. We should not add the second desktop widget
1715     // to the mapper.
1716     bool userDesktopWidget = qt_desktopWidget != 0 && qt_desktopWidget != q && q->windowType() == Qt::Desktop;
1717     if (mapper && data.winid && !userDesktopWidget) {
1718         mapper->remove(data.winid);
1719     }
1720
1721     const WId oldWinId = data.winid;
1722
1723     data.winid = id;
1724 #if defined(Q_WS_X11)
1725     hd = id; // X11: hd == ident
1726 #endif
1727     if (mapper && id && !userDesktopWidget) {
1728         mapper->insert(data.winid, q);
1729     }
1730
1731     if(oldWinId != id) {
1732         QEvent e(QEvent::WinIdChange);
1733         QCoreApplication::sendEvent(q, &e);
1734     }
1735 }
1736
1737 void QWidgetPrivate::createTLExtra()
1738 {
1739     if (!extra)
1740         createExtra();
1741     if (!extra->topextra) {
1742         QTLWExtra* x = extra->topextra = new QTLWExtra;
1743         x->icon = 0;
1744         x->iconPixmap = 0;
1745         x->windowSurface = 0;
1746         x->sharedPainter = 0;
1747         x->incw = x->inch = 0;
1748         x->basew = x->baseh = 0;
1749         x->frameStrut.setCoords(0, 0, 0, 0);
1750         x->normalGeometry = QRect(0,0,-1,-1);
1751         x->savedFlags = 0;
1752         x->opacity = 255;
1753         x->posFromMove = false;
1754         x->sizeAdjusted = false;
1755         x->inTopLevelResize = false;
1756         x->inRepaint = false;
1757         x->embedded = 0;
1758 #ifdef Q_WS_MAC
1759 #ifdef QT_MAC_USE_COCOA
1760         x->wasMaximized = false;
1761 #endif // QT_MAC_USE_COCOA
1762 #endif // Q_WS_MAC
1763         createTLSysExtra();
1764 #ifdef QWIDGET_EXTRA_DEBUG
1765         static int count = 0;
1766         qDebug() << "tlextra" << ++count;
1767 #endif
1768 #if defined(Q_WS_QPA)
1769         x->platformWindow = 0;
1770         x->platformWindowFormat = QPlatformWindowFormat::defaultFormat();
1771         x->screenIndex = 0;
1772 #endif
1773     }
1774 }
1775
1776 /*!
1777   \internal
1778   Creates the widget extra data.
1779 */
1780
1781 void QWidgetPrivate::createExtra()
1782 {
1783     if (!extra) {                                // if not exists
1784         extra = new QWExtra;
1785         extra->glContext = 0;
1786         extra->topextra = 0;
1787 #ifndef QT_NO_GRAPHICSVIEW
1788         extra->proxyWidget = 0;
1789 #endif
1790 #ifndef QT_NO_CURSOR
1791         extra->curs = 0;
1792 #endif
1793         extra->minw = 0;
1794         extra->minh = 0;
1795         extra->maxw = QWIDGETSIZE_MAX;
1796         extra->maxh = QWIDGETSIZE_MAX;
1797         extra->customDpiX = 0;
1798         extra->customDpiY = 0;
1799         extra->explicitMinSize = 0;
1800         extra->explicitMaxSize = 0;
1801         extra->autoFillBackground = 0;
1802         extra->nativeChildrenForced = 0;
1803         extra->inRenderWithPainter = 0;
1804         extra->hasMask = 0;
1805         createSysExtra();
1806 #ifdef QWIDGET_EXTRA_DEBUG
1807         static int count = 0;
1808         qDebug() << "extra" << ++count;
1809 #endif
1810     }
1811 }
1812
1813
1814 /*!
1815   \internal
1816   Deletes the widget extra data.
1817 */
1818
1819 void QWidgetPrivate::deleteExtra()
1820 {
1821     if (extra) {                                // if exists
1822 #ifndef QT_NO_CURSOR
1823         delete extra->curs;
1824 #endif
1825         deleteSysExtra();
1826 #ifndef QT_NO_STYLE_STYLESHEET
1827         // dereference the stylesheet style
1828         if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(extra->style))
1829             proxy->deref();
1830 #endif
1831         if (extra->topextra) {
1832             deleteTLSysExtra();
1833             extra->topextra->backingStore.destroy();
1834             delete extra->topextra->icon;
1835             delete extra->topextra->iconPixmap;
1836 #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
1837             delete extra->topextra->qwsManager;
1838 #endif
1839             delete extra->topextra->windowSurface;
1840             delete extra->topextra;
1841         }
1842         delete extra;
1843         // extra->xic destroyed in QWidget::destroy()
1844         extra = 0;
1845     }
1846 }
1847
1848 /*
1849   Returns true if there are widgets above this which overlap with
1850   \a rect, which is in parent's coordinate system (same as crect).
1851 */
1852
1853 bool QWidgetPrivate::isOverlapped(const QRect &rect) const
1854 {
1855     Q_Q(const QWidget);
1856
1857     const QWidget *w = q;
1858     QRect r = rect;
1859     while (w) {
1860         if (w->isWindow())
1861             return false;
1862         QWidgetPrivate *pd = w->parentWidget()->d_func();
1863         bool above = false;
1864         for (int i = 0; i < pd->children.size(); ++i) {
1865             QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
1866             if (!sibling || !sibling->isVisible() || sibling->isWindow())
1867                 continue;
1868             if (!above) {
1869                 above = (sibling == w);
1870                 continue;
1871             }
1872
1873             if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) {
1874                 const QWExtra *siblingExtra = sibling->d_func()->extra;
1875                 if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
1876                     && !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
1877                     continue;
1878                 }
1879                 return true;
1880             }
1881         }
1882         w = w->parentWidget();
1883         r.translate(pd->data.crect.topLeft());
1884     }
1885     return false;
1886 }
1887
1888 void QWidgetPrivate::syncBackingStore()
1889 {
1890     if (paintOnScreen()) {
1891         repaint_sys(dirty);
1892         dirty = QRegion();
1893     } else if (QWidgetBackingStore *bs = maybeBackingStore()) {
1894         bs->sync();
1895     }
1896 }
1897
1898 void QWidgetPrivate::syncBackingStore(const QRegion &region)
1899 {
1900     if (paintOnScreen())
1901         repaint_sys(region);
1902     else if (QWidgetBackingStore *bs = maybeBackingStore()) {
1903         bs->sync(q_func(), region);
1904     }
1905 }
1906
1907 void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
1908 {
1909     Q_Q(QWidget);
1910
1911     if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->updatesEnabled())
1912         return; // nothing we can do
1913
1914     if (enable != q->testAttribute(Qt::WA_UpdatesDisabled))
1915         return; // nothing to do
1916
1917     q->setAttribute(Qt::WA_UpdatesDisabled, !enable);
1918     if (enable)
1919         q->update();
1920
1921     Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled;
1922     for (int i = 0; i < children.size(); ++i) {
1923         QWidget *w = qobject_cast<QWidget *>(children.at(i));
1924         if (w && !w->isWindow() && !w->testAttribute(attribute))
1925             w->d_func()->setUpdatesEnabled_helper(enable);
1926     }
1927 }
1928
1929 /*!
1930     \internal
1931
1932     Propagate this widget's palette to all children, except style sheet
1933     widgets, and windows that don't enable window propagation (palettes don't
1934     normally propagate to windows).
1935 */
1936 void QWidgetPrivate::propagatePaletteChange()
1937 {
1938     Q_Q(QWidget);
1939     // Propagate a new inherited mask to all children.
1940 #ifndef QT_NO_GRAPHICSVIEW
1941     if (!q->parentWidget() && extra && extra->proxyWidget) {
1942         QGraphicsProxyWidget *p = extra->proxyWidget;
1943         inheritedPaletteResolveMask = p->d_func()->inheritedPaletteResolveMask | p->palette().resolve();
1944     } else
1945 #endif //QT_NO_GRAPHICSVIEW
1946         if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
1947         inheritedPaletteResolveMask = 0;
1948     }
1949     int mask = data.pal.resolve() | inheritedPaletteResolveMask;
1950
1951     QEvent pc(QEvent::PaletteChange);
1952     QApplication::sendEvent(q, &pc);
1953     for (int i = 0; i < children.size(); ++i) {
1954         QWidget *w = qobject_cast<QWidget*>(children.at(i));
1955         if (w && !w->testAttribute(Qt::WA_StyleSheet)
1956             && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
1957             QWidgetPrivate *wd = w->d_func();
1958             wd->inheritedPaletteResolveMask = mask;
1959             wd->resolvePalette();
1960         }
1961     }
1962 #if defined(QT3_SUPPORT)
1963     q->paletteChange(q->palette()); // compatibility
1964 #endif
1965 }
1966
1967 /*
1968   Returns the widget's clipping rectangle.
1969 */
1970 QRect QWidgetPrivate::clipRect() const
1971 {
1972     Q_Q(const QWidget);
1973     const QWidget * w = q;
1974     if (!w->isVisible())
1975         return QRect();
1976     QRect r = effectiveRectFor(q->rect());
1977     int ox = 0;
1978     int oy = 0;
1979     while (w
1980             && w->isVisible()
1981             && !w->isWindow()
1982             && w->parentWidget()) {
1983         ox -= w->x();
1984         oy -= w->y();
1985         w = w->parentWidget();
1986         r &= QRect(ox, oy, w->width(), w->height());
1987     }
1988     return r;
1989 }
1990
1991 /*
1992   Returns the widget's clipping region (without siblings).
1993 */
1994 QRegion QWidgetPrivate::clipRegion() const
1995 {
1996     Q_Q(const QWidget);
1997     if (!q->isVisible())
1998         return QRegion();
1999     QRegion r(q->rect());
2000     const QWidget * w = q;
2001     const QWidget *ignoreUpTo;
2002     int ox = 0;
2003     int oy = 0;
2004     while (w
2005            && w->isVisible()
2006            && !w->isWindow()
2007            && w->parentWidget()) {
2008         ox -= w->x();
2009         oy -= w->y();
2010         ignoreUpTo = w;
2011         w = w->parentWidget();
2012         r &= QRegion(ox, oy, w->width(), w->height());
2013
2014         int i = 0;
2015         while(w->d_func()->children.at(i++) != static_cast<const QObject *>(ignoreUpTo))
2016             ;
2017         for ( ; i < w->d_func()->children.size(); ++i) {
2018             if(QWidget *sibling = qobject_cast<QWidget *>(w->d_func()->children.at(i))) {
2019                 if(sibling->isVisible() && !sibling->isWindow()) {
2020                     QRect siblingRect(ox+sibling->x(), oy+sibling->y(),
2021                                       sibling->width(), sibling->height());
2022                     if (qRectIntersects(siblingRect, q->rect()))
2023                         r -= QRegion(siblingRect);
2024                 }
2025             }
2026         }
2027     }
2028     return r;
2029 }
2030
2031 #ifndef QT_NO_GRAPHICSEFFECT
2032 void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
2033 {
2034     Q_Q(QWidget);
2035     QWidget *w = q;
2036     do {
2037         if (w->graphicsEffect()) {
2038             QWidgetEffectSourcePrivate *sourced =
2039                 static_cast<QWidgetEffectSourcePrivate *>(w->graphicsEffect()->source()->d_func());
2040             if (!sourced->updateDueToGraphicsEffect)
2041                 w->graphicsEffect()->source()->d_func()->invalidateCache();
2042         }
2043         w = w->parentWidget();
2044     } while (w);
2045 }
2046 #endif //QT_NO_GRAPHICSEFFECT
2047
2048 void QWidgetPrivate::setDirtyOpaqueRegion()
2049 {
2050     Q_Q(QWidget);
2051
2052     dirtyOpaqueChildren = true;
2053
2054 #ifndef QT_NO_GRAPHICSEFFECT
2055     invalidateGraphicsEffectsRecursively();
2056 #endif //QT_NO_GRAPHICSEFFECT
2057
2058     if (q->isWindow())
2059         return;
2060
2061     QWidget *parent = q->parentWidget();
2062     if (!parent)
2063         return;
2064
2065     // TODO: instead of setting dirtyflag, manipulate the dirtyregion directly?
2066     QWidgetPrivate *pd = parent->d_func();
2067     if (!pd->dirtyOpaqueChildren)
2068         pd->setDirtyOpaqueRegion();
2069 }
2070
2071 const QRegion &QWidgetPrivate::getOpaqueChildren() const
2072 {
2073     if (!dirtyOpaqueChildren)
2074         return opaqueChildren;
2075
2076     QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this);
2077     that->opaqueChildren = QRegion();
2078
2079     for (int i = 0; i < children.size(); ++i) {
2080         QWidget *child = qobject_cast<QWidget *>(children.at(i));
2081         if (!child || !child->isVisible() || child->isWindow())
2082             continue;
2083
2084         const QPoint offset = child->geometry().topLeft();
2085         QWidgetPrivate *childd = child->d_func();
2086         QRegion r = childd->isOpaque ? child->rect() : childd->getOpaqueChildren();
2087         if (childd->extra && childd->extra->hasMask)
2088             r &= childd->extra->mask;
2089         if (r.isEmpty())
2090             continue;
2091         r.translate(offset);
2092         that->opaqueChildren += r;
2093     }
2094
2095     that->opaqueChildren &= q_func()->rect();
2096     that->dirtyOpaqueChildren = false;
2097
2098     return that->opaqueChildren;
2099 }
2100
2101 void QWidgetPrivate::subtractOpaqueChildren(QRegion &source, const QRect &clipRect) const
2102 {
2103     if (children.isEmpty() || clipRect.isEmpty())
2104         return;
2105
2106     const QRegion &r = getOpaqueChildren();
2107     if (!r.isEmpty())
2108         source -= (r & clipRect);
2109 }
2110
2111 //subtract any relatives that are higher up than me --- this is too expensive !!!
2112 void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirtySiblingsAbove,
2113                                             bool alsoNonOpaque) const
2114 {
2115     Q_Q(const QWidget);
2116     static int disableSubtractOpaqueSiblings = qgetenv("QT_NO_SUBTRACTOPAQUESIBLINGS").toInt();
2117     if (disableSubtractOpaqueSiblings || q->isWindow())
2118         return;
2119
2120 #ifdef QT_MAC_USE_COCOA
2121     if (q->d_func()->isInUnifiedToolbar)
2122         return;
2123 #endif // QT_MAC_USE_COCOA
2124
2125     QRect clipBoundingRect;
2126     bool dirtyClipBoundingRect = true;
2127
2128     QRegion parentClip;
2129     bool dirtyParentClip = true;
2130
2131     QPoint parentOffset = data.crect.topLeft();
2132
2133     const QWidget *w = q;
2134
2135     while (w) {
2136         if (w->isWindow())
2137             break;
2138         QWidgetPrivate *pd = w->parentWidget()->d_func();
2139         const int myIndex = pd->children.indexOf(const_cast<QWidget *>(w));
2140         const QRect widgetGeometry = w->d_func()->effectiveRectFor(w->data->crect);
2141         for (int i = myIndex + 1; i < pd->children.size(); ++i) {
2142             QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
2143             if (!sibling || !sibling->isVisible() || sibling->isWindow())
2144                 continue;
2145
2146             const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(sibling->data->crect);
2147             if (!qRectIntersects(siblingGeometry, widgetGeometry))
2148                 continue;
2149
2150             if (dirtyClipBoundingRect) {
2151                 clipBoundingRect = sourceRegion.boundingRect();
2152                 dirtyClipBoundingRect = false;
2153             }
2154
2155             if (!qRectIntersects(siblingGeometry, clipBoundingRect.translated(parentOffset)))
2156                 continue;
2157
2158             if (dirtyParentClip) {
2159                 parentClip = sourceRegion.translated(parentOffset);
2160                 dirtyParentClip = false;
2161             }
2162
2163             const QPoint siblingPos(sibling->data->crect.topLeft());
2164             const QRect siblingClipRect(sibling->d_func()->clipRect());
2165             QRegion siblingDirty(parentClip);
2166             siblingDirty &= (siblingClipRect.translated(siblingPos));
2167             const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask
2168                                  && !sibling->d_func()->graphicsEffect;
2169             if (hasMask)
2170                 siblingDirty &= sibling->d_func()->extra->mask.translated(siblingPos);
2171             if (siblingDirty.isEmpty())
2172                 continue;
2173
2174             if (sibling->d_func()->isOpaque || alsoNonOpaque) {
2175                 if (hasMask) {
2176                     siblingDirty.translate(-parentOffset);
2177                     sourceRegion -= siblingDirty;
2178                 } else {
2179                     sourceRegion -= siblingGeometry.translated(-parentOffset);
2180                 }
2181             } else {
2182                 if (hasDirtySiblingsAbove)
2183                     *hasDirtySiblingsAbove = true;
2184                 if (sibling->d_func()->children.isEmpty())
2185                     continue;
2186                 QRegion opaqueSiblingChildren(sibling->d_func()->getOpaqueChildren());
2187                 opaqueSiblingChildren.translate(-parentOffset + siblingPos);
2188                 sourceRegion -= opaqueSiblingChildren;
2189             }
2190             if (sourceRegion.isEmpty())
2191                 return;
2192
2193             dirtyClipBoundingRect = true;
2194             dirtyParentClip = true;
2195         }
2196
2197         w = w->parentWidget();
2198         parentOffset += pd->data.crect.topLeft();
2199         dirtyParentClip = true;
2200     }
2201 }
2202
2203 void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
2204 {
2205     Q_Q(const QWidget);
2206
2207     const QWidget *w = q;
2208     QPoint offset;
2209
2210 #ifndef QT_NO_GRAPHICSEFFECT
2211     if (graphicsEffect) {
2212         w = q->parentWidget();
2213         offset -= data.crect.topLeft();
2214     }
2215 #endif //QT_NO_GRAPHICSEFFECT
2216
2217     while (w) {
2218         const QWidgetPrivate *wd = w->d_func();
2219         if (wd->extra && wd->extra->hasMask)
2220             region &= (w != q) ? wd->extra->mask.translated(offset) : wd->extra->mask;
2221         if (w->isWindow())
2222             return;
2223         offset -= wd->data.crect.topLeft();
2224         w = w->parentWidget();
2225     }
2226 }
2227
2228 bool QWidgetPrivate::paintOnScreen() const
2229 {
2230 #if defined(Q_WS_QWS)
2231     return false;
2232 #elif  defined(QT_NO_BACKINGSTORE)
2233     return true;
2234 #else
2235     Q_Q(const QWidget);
2236     if (q->testAttribute(Qt::WA_PaintOnScreen)
2237             || (!q->isWindow() && q->window()->testAttribute(Qt::WA_PaintOnScreen))) {
2238         return true;
2239     }
2240
2241     return !qt_enable_backingstore;
2242 #endif
2243 }
2244
2245 void QWidgetPrivate::updateIsOpaque()
2246 {
2247     // hw: todo: only needed if opacity actually changed
2248     setDirtyOpaqueRegion();
2249
2250 #ifndef QT_NO_GRAPHICSEFFECT
2251     if (graphicsEffect) {
2252         // ### We should probably add QGraphicsEffect::isOpaque at some point.
2253         setOpaque(false);
2254         return;
2255     }
2256 #endif //QT_NO_GRAPHICSEFFECT
2257
2258     Q_Q(QWidget);
2259 #ifdef Q_WS_X11
2260     if (q->testAttribute(Qt::WA_X11OpenGLOverlay)) {
2261         setOpaque(false);
2262         return;
2263     }
2264 #endif
2265
2266 #ifdef Q_WS_S60
2267     if (q->testAttribute(Qt::WA_TranslucentBackground)) {
2268         if (q->windowType() & Qt::Dialog || q->windowType() & Qt::Popup) {
2269             if (S60->avkonComponentsSupportTransparency) {
2270                 setOpaque(false);
2271                 return;
2272             }
2273         } else {
2274             setOpaque(false);
2275             return;
2276         }
2277     }
2278 #endif
2279
2280     if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) {
2281         setOpaque(true);
2282         return;
2283     }
2284
2285     const QPalette &pal = q->palette();
2286
2287     if (q->autoFillBackground()) {
2288         const QBrush &autoFillBrush = pal.brush(q->backgroundRole());
2289         if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
2290             setOpaque(true);
2291             return;
2292         }
2293     }
2294
2295     if (q->isWindow() && !q->testAttribute(Qt::WA_NoSystemBackground)) {
2296 #ifdef Q_WS_S60
2297         setOpaque(true);
2298         return;
2299 #else
2300         const QBrush &windowBrush = q->palette().brush(QPalette::Window);
2301         if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
2302             setOpaque(true);
2303             return;
2304         }
2305 #endif
2306     }
2307     setOpaque(false);
2308 }
2309
2310 void QWidgetPrivate::setOpaque(bool opaque)
2311 {
2312     if (isOpaque == opaque)
2313         return;
2314     isOpaque = opaque;
2315 #ifdef Q_WS_MAC
2316     macUpdateIsOpaque();
2317 #endif
2318 #ifdef Q_WS_X11
2319     x11UpdateIsOpaque();
2320 #endif
2321 #ifdef Q_WS_WIN
2322     winUpdateIsOpaque();
2323 #endif
2324 #ifdef Q_OS_SYMBIAN
2325     s60UpdateIsOpaque();
2326 #endif
2327 }
2328
2329 void QWidgetPrivate::updateIsTranslucent()
2330 {
2331 #ifdef Q_WS_MAC
2332     macUpdateIsOpaque();
2333 #endif
2334 #ifdef Q_WS_X11
2335     x11UpdateIsOpaque();
2336 #endif
2337 #ifdef Q_WS_WIN
2338     winUpdateIsOpaque();
2339 #endif
2340 #ifdef Q_OS_SYMBIAN
2341     s60UpdateIsOpaque();
2342 #endif
2343 }
2344
2345 /*!
2346     \fn void QPixmap::fill(const QWidget *widget, const QPoint &offset)
2347
2348     Fills the pixmap with the \a widget's background color or pixmap
2349     according to the given offset.
2350
2351     The QPoint \a offset defines a point in widget coordinates to
2352     which the pixmap's top-left pixel will be mapped to. This is only
2353     significant if the widget has a background pixmap; otherwise the
2354     pixmap will simply be filled with the background color of the
2355     widget.
2356 */
2357
2358 void QPixmap::fill( const QWidget *widget, const QPoint &off )
2359 {
2360     QPainter p(this);
2361     p.translate(-off);
2362     widget->d_func()->paintBackground(&p, QRect(off, size()));
2363 }
2364
2365 static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush)
2366 {
2367     Q_ASSERT(painter);
2368
2369     if (brush.style() == Qt::TexturePattern) {
2370 #ifdef Q_WS_MAC
2371         // Optimize pattern filling on mac by using HITheme directly
2372         // when filling with the standard widget background.
2373         // Defined in qmacstyle_mac.cpp
2374         extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
2375         qt_mac_fill_background(painter, rgn, brush);
2376 #else
2377 #if !defined(QT_NO_STYLE_S60)
2378         // Defined in qs60style.cpp
2379         extern bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
2380         if (!qt_s60_fill_background(painter, rgn, brush))
2381 #endif // !defined(QT_NO_STYLE_S60)
2382         {
2383             const QRect rect(rgn.boundingRect());
2384             painter->setClipRegion(rgn);
2385             painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
2386         }
2387 #endif // Q_WS_MAC
2388
2389     } else if (brush.gradient()
2390                && brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
2391         painter->save();
2392         painter->setClipRegion(rgn);
2393         painter->fillRect(0, 0, painter->device()->width(), painter->device()->height(), brush);
2394         painter->restore();
2395     } else {
2396         const QVector<QRect> &rects = rgn.rects();
2397         for (int i = 0; i < rects.size(); ++i)
2398             painter->fillRect(rects.at(i), brush);
2399     }
2400 }
2401
2402 void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const
2403 {
2404     Q_Q(const QWidget);
2405
2406 #ifndef QT_NO_SCROLLAREA
2407     bool resetBrushOrigin = false;
2408     QPointF oldBrushOrigin;
2409     //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
2410     QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
2411     if (scrollArea && scrollArea->viewport() == q) {
2412         QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
2413         QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
2414         oldBrushOrigin = painter->brushOrigin();
2415         resetBrushOrigin = true;
2416         painter->setBrushOrigin(-priv->contentsOffset());
2417
2418     }
2419 #endif // QT_NO_SCROLLAREA
2420
2421     const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
2422
2423     if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
2424         const QBrush bg = q->palette().brush(QPalette::Window);
2425 #if defined(Q_WS_QWS) || defined(Q_WS_QPA)
2426         if (!(flags & DontSetCompositionMode)) {
2427             //copy alpha straight in
2428             QPainter::CompositionMode oldMode = painter->compositionMode();
2429             painter->setCompositionMode(QPainter::CompositionMode_Source);
2430             fillRegion(painter, rgn, bg);
2431             painter->setCompositionMode(oldMode);
2432         } else {
2433             fillRegion(painter, rgn, bg);
2434         }
2435 #else
2436         fillRegion(painter, rgn, bg);
2437 #endif
2438     }
2439
2440     if (q->autoFillBackground())
2441         fillRegion(painter, rgn, autoFillBrush);
2442
2443     if (q->testAttribute(Qt::WA_StyledBackground)) {
2444         painter->setClipRegion(rgn);
2445         QStyleOption opt;
2446         opt.initFrom(q);
2447         q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
2448     }
2449
2450 #ifndef QT_NO_SCROLLAREA
2451     if (resetBrushOrigin)
2452         painter->setBrushOrigin(oldBrushOrigin);
2453 #endif // QT_NO_SCROLLAREA
2454 }
2455
2456 /*
2457   \internal
2458   This function is called when a widget is hidden or destroyed.
2459   It resets some application global pointers that should only refer active,
2460   visible widgets.
2461 */
2462
2463 #ifdef Q_WS_MAC
2464     extern QPointer<QWidget> qt_button_down;
2465 #else
2466     extern QWidget *qt_button_down;
2467 #endif
2468
2469 void QWidgetPrivate::deactivateWidgetCleanup()
2470 {
2471     Q_Q(QWidget);
2472     // If this was the active application window, reset it
2473     if (QApplication::activeWindow() == q)
2474         QApplication::setActiveWindow(0);
2475     // If the is the active mouse press widget, reset it
2476     if (q == qt_button_down)
2477         qt_button_down = 0;
2478 }
2479
2480
2481 /*!
2482     Returns a pointer to the widget with window identifer/handle \a
2483     id.
2484
2485     The window identifier type depends on the underlying window
2486     system, see \c qwindowdefs.h for the actual definition. If there
2487     is no widget with this identifier, 0 is returned.
2488 */
2489
2490 QWidget *QWidget::find(WId id)
2491 {
2492     return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : 0;
2493 }
2494
2495
2496
2497 /*!
2498     \fn WId QWidget::internalWinId() const
2499     \internal
2500     Returns the window system identifier of the widget, or 0 if the widget is not created yet.
2501
2502 */
2503
2504 /*!
2505     \fn WId QWidget::winId() const
2506
2507     Returns the window system identifier of the widget.
2508
2509     Portable in principle, but if you use it you are probably about to
2510     do something non-portable. Be careful.
2511
2512     If a widget is non-native (alien) and winId() is invoked on it, that widget
2513     will be provided a native handle.
2514
2515     On Mac OS X, the type returned depends on which framework Qt was linked
2516     against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt
2517     is using Cocoa, {WId} is a pointer to an NSView.
2518
2519     This value may change at run-time. An event with type QEvent::WinIdChange
2520     will be sent to the widget following a change in window system identifier.
2521
2522     \sa find()
2523 */
2524 WId QWidget::winId() const
2525 {
2526     if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
2527 #ifdef ALIEN_DEBUG
2528         qDebug() << "QWidget::winId: creating native window for" << this;
2529 #endif
2530         QWidget *that = const_cast<QWidget*>(this);
2531 #ifndef Q_WS_QPA
2532         that->setAttribute(Qt::WA_NativeWindow);
2533 #endif
2534         that->d_func()->createWinId();
2535         return that->data->winid;
2536     }
2537     return data->winid;
2538 }
2539
2540
2541 void QWidgetPrivate::createWinId(WId winid)
2542 {
2543     Q_Q(QWidget);
2544
2545 #ifdef ALIEN_DEBUG
2546     qDebug() << "QWidgetPrivate::createWinId for" << q << winid;
2547 #endif
2548     const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow);
2549     if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) {
2550 #ifndef Q_WS_QPA
2551         if (!q->isWindow()) {
2552             QWidget *parent = q->parentWidget();
2553             QWidgetPrivate *pd = parent->d_func();
2554             if (forceNativeWindow && !q->testAttribute(Qt::WA_DontCreateNativeAncestors))
2555                 parent->setAttribute(Qt::WA_NativeWindow);
2556             if (!parent->internalWinId()) {
2557                 pd->createWinId();
2558             }
2559
2560             for (int i = 0; i < pd->children.size(); ++i) {
2561                 QWidget *w = qobject_cast<QWidget *>(pd->children.at(i));
2562                 if (w && !w->isWindow() && (!w->testAttribute(Qt::WA_WState_Created)
2563                                             || (!w->internalWinId() && w->testAttribute(Qt::WA_NativeWindow)))) {
2564                     if (w!=q) {
2565                         w->create();
2566                     } else {
2567                         w->create(winid);
2568                         // if the window has already been created, we
2569                         // need to raise it to its proper stacking position
2570                         if (winid)
2571                             w->raise();
2572                     }
2573                 }
2574             }
2575         } else {
2576             q->create();
2577         }
2578 #else
2579         Q_UNUSED(winid);
2580         q->create();
2581 #endif //Q_WS_QPA
2582
2583     }
2584 }
2585
2586
2587 /*!
2588 \internal
2589 Ensures that the widget has a window system identifier, i.e. that it is known to the windowing system.
2590
2591 */
2592
2593 void QWidget::createWinId()
2594 {
2595     Q_D(QWidget);
2596 #ifdef ALIEN_DEBUG
2597     qDebug()  << "QWidget::createWinId" << this;
2598 #endif
2599 //    qWarning("QWidget::createWinId is obsolete, please fix your code.");
2600     d->createWinId();
2601 }
2602
2603 /*!
2604     \since 4.4
2605
2606     Returns the effective window system identifier of the widget, i.e. the
2607     native parent's window system identifier.
2608
2609     If the widget is native, this function returns the native widget ID.
2610     Otherwise, the window ID of the first native parent widget, i.e., the
2611     top-level widget that contains this widget, is returned.
2612
2613     \note We recommend that you do not store this value as it is likely to
2614     change at run-time.
2615
2616     \sa nativeParentWidget()
2617 */
2618 WId QWidget::effectiveWinId() const
2619 {
2620     WId id = internalWinId();
2621     if (id || !testAttribute(Qt::WA_WState_Created))
2622         return id;
2623     QWidget *realParent = nativeParentWidget();
2624     if (!realParent && d_func()->inSetParent) {
2625         // In transitional state. This is really just a workaround. The real problem
2626         // is that QWidgetPrivate::setParent_sys (platform specific code) first sets
2627         // the window id to 0 (setWinId(0)) before it sets the Qt::WA_WState_Created
2628         // attribute to false. The correct way is to do it the other way around, and
2629         // in that case the Qt::WA_WState_Created logic above will kick in and
2630         // return 0 whenever the widget is in a transitional state. However, changing
2631         // the original logic for all platforms is far more intrusive and might
2632         // break existing applications.
2633         // Note: The widget can only be in a transitional state when changing its
2634         // parent -- everything else is an internal error -- hence explicitly checking
2635         // against 'inSetParent' rather than doing an unconditional return whenever
2636         // 'realParent' is 0 (which may cause strange artifacts and headache later).
2637         return 0;
2638     }
2639     // This widget *must* have a native parent widget.
2640     Q_ASSERT(realParent);
2641     Q_ASSERT(realParent->internalWinId());
2642     return realParent->internalWinId();
2643 }
2644
2645 #ifndef QT_NO_STYLE_STYLESHEET
2646
2647 /*!
2648     \property QWidget::styleSheet
2649     \brief the widget's style sheet
2650     \since 4.2
2651
2652     The style sheet contains a textual description of customizations to the
2653     widget's style, as described in the \l{Qt Style Sheets} document.
2654
2655     Since Qt 4.5, Qt style sheets fully supports Mac OS X.
2656
2657     \warning Qt style sheets are currently not supported for custom QStyle
2658     subclasses. We plan to address this in some future release.
2659
2660     \sa setStyle(), QApplication::styleSheet, {Qt Style Sheets}
2661 */
2662 QString QWidget::styleSheet() const
2663 {
2664     Q_D(const QWidget);
2665     if (!d->extra)
2666         return QString();
2667     return d->extra->styleSheet;
2668 }
2669
2670 void QWidget::setStyleSheet(const QString& styleSheet)
2671 {
2672     Q_D(QWidget);
2673     d->createExtra();
2674
2675     QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(d->extra->style);
2676     d->extra->styleSheet = styleSheet;
2677     if (styleSheet.isEmpty()) { // stylesheet removed
2678         if (!proxy)
2679             return;
2680
2681         d->inheritStyle();
2682         return;
2683     }
2684
2685     if (proxy) { // style sheet update
2686         proxy->repolish(this);
2687         return;
2688     }
2689
2690     if (testAttribute(Qt::WA_SetStyle)) {
2691         d->setStyle_helper(new QStyleSheetStyle(d->extra->style), true);
2692     } else {
2693         d->setStyle_helper(new QStyleSheetStyle(0), true);
2694     }
2695 }
2696
2697 #endif // QT_NO_STYLE_STYLESHEET
2698
2699 /*!
2700     \sa QWidget::setStyle(), QApplication::setStyle(), QApplication::style()
2701 */
2702
2703 QStyle *QWidget::style() const
2704 {
2705     Q_D(const QWidget);
2706
2707     if (d->extra && d->extra->style)
2708         return d->extra->style;
2709     return QApplication::style();
2710 }
2711
2712 /*!
2713     Sets the widget's GUI style to \a style. The ownership of the style
2714     object is not transferred.
2715
2716     If no style is set, the widget uses the application's style,
2717     QApplication::style() instead.
2718
2719     Setting a widget's style has no effect on existing or future child
2720     widgets.
2721
2722     \warning This function is particularly useful for demonstration
2723     purposes, where you want to show Qt's styling capabilities. Real
2724     applications should avoid it and use one consistent GUI style
2725     instead.
2726
2727     \warning Qt style sheets are currently not supported for custom QStyle
2728     subclasses. We plan to address this in some future release.
2729
2730     \sa style(), QStyle, QApplication::style(), QApplication::setStyle()
2731 */
2732
2733 void QWidget::setStyle(QStyle *style)
2734 {
2735     Q_D(QWidget);
2736     setAttribute(Qt::WA_SetStyle, style != 0);
2737     d->createExtra();
2738 #ifndef QT_NO_STYLE_STYLESHEET
2739     if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(style)) {
2740         //if for some reason someone try to set a QStyleSheetStyle, ref it
2741         //(this may happen for exemple in QButtonDialogBox which propagates its style)
2742         proxy->ref();
2743         d->setStyle_helper(style, false);
2744     } else if (qobject_cast<QStyleSheetStyle *>(d->extra->style) || !qApp->styleSheet().isEmpty()) {
2745         // if we have an application stylesheet or have a proxy already, propagate
2746         d->setStyle_helper(new QStyleSheetStyle(style), true);
2747     } else
2748 #endif
2749         d->setStyle_helper(style, false);
2750 }
2751
2752 void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
2753 #ifdef Q_WS_MAC
2754         metalHack
2755 #endif
2756         )
2757 {
2758     Q_Q(QWidget);
2759     QStyle *oldStyle  = q->style();
2760 #ifndef QT_NO_STYLE_STYLESHEET
2761     QWeakPointer<QStyle> origStyle;
2762 #endif
2763
2764 #ifdef Q_WS_MAC
2765     // the metalhack boolean allows Qt/Mac to do a proper re-polish depending
2766     // on how the Qt::WA_MacBrushedMetal attribute is set. It is only ever
2767     // set when changing that attribute and passes the widget's CURRENT style.
2768     // therefore no need to do a reassignment.
2769     if (!metalHack)
2770 #endif
2771     {
2772         createExtra();
2773
2774 #ifndef QT_NO_STYLE_STYLESHEET
2775         origStyle = extra->style.data();
2776 #endif
2777         extra->style = newStyle;
2778     }
2779
2780     // repolish
2781     if (q->windowType() != Qt::Desktop) {
2782         if (polished) {
2783             oldStyle->unpolish(q);
2784 #ifdef Q_WS_MAC
2785             if (metalHack)
2786                 macUpdateMetalAttribute();
2787 #endif
2788             q->style()->polish(q);
2789 #ifdef Q_WS_MAC
2790         } else if (metalHack) {
2791             macUpdateMetalAttribute();
2792 #endif
2793         }
2794     }
2795
2796     if (propagate) {
2797         for (int i = 0; i < children.size(); ++i) {
2798             QWidget *c = qobject_cast<QWidget*>(children.at(i));
2799             if (c)
2800                 c->d_func()->inheritStyle();
2801         }
2802     }
2803
2804 #ifndef QT_NO_STYLE_STYLESHEET
2805     if (!qobject_cast<QStyleSheetStyle*>(newStyle)) {
2806         if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) {
2807             cssStyle->clearWidgetFont(q);
2808         }
2809     }
2810 #endif
2811
2812     QEvent e(QEvent::StyleChange);
2813     QApplication::sendEvent(q, &e);
2814 #ifdef QT3_SUPPORT
2815     q->styleChange(*oldStyle);
2816 #endif
2817
2818 #ifndef QT_NO_STYLE_STYLESHEET
2819     // dereference the old stylesheet style
2820     if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data()))
2821         proxy->deref();
2822 #endif
2823 }
2824
2825 // Inherits style from the current parent and propagates it as necessary
2826 void QWidgetPrivate::inheritStyle()
2827 {
2828 #ifndef QT_NO_STYLE_STYLESHEET
2829     Q_Q(QWidget);
2830
2831     QStyleSheetStyle *proxy = extra ? qobject_cast<QStyleSheetStyle *>(extra->style) : 0;
2832
2833     if (!q->styleSheet().isEmpty()) {
2834         Q_ASSERT(proxy);
2835         proxy->repolish(q);
2836         return;
2837     }
2838
2839     QStyle *origStyle = proxy ? proxy->base : (extra ? (QStyle*)extra->style : 0);
2840     QWidget *parent = q->parentWidget();
2841     QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : 0;
2842     // If we have stylesheet on app or parent has stylesheet style, we need
2843     // to be running a proxy
2844     if (!qApp->styleSheet().isEmpty() || qobject_cast<QStyleSheetStyle *>(parentStyle)) {
2845         QStyle *newStyle = parentStyle;
2846         if (q->testAttribute(Qt::WA_SetStyle))
2847             newStyle = new QStyleSheetStyle(origStyle);
2848         else if (QStyleSheetStyle *newProxy = qobject_cast<QStyleSheetStyle *>(parentStyle))
2849             newProxy->ref();
2850
2851         setStyle_helper(newStyle, true);
2852         return;
2853     }
2854
2855     // So, we have no stylesheet on parent/app and we have an empty stylesheet
2856     // we just need our original style back
2857     if (origStyle == (extra ? (QStyle*)extra->style : 0)) // is it any different?
2858         return;
2859
2860     // We could have inherited the proxy from our parent (which has a custom style)
2861     // In such a case we need to start following the application style (i.e revert
2862     // the propagation behavior of QStyleSheetStyle)
2863     if (!q->testAttribute(Qt::WA_SetStyle))
2864         origStyle = 0;
2865
2866     setStyle_helper(origStyle, true);
2867 #endif // QT_NO_STYLE_STYLESHEET
2868 }
2869
2870 #ifdef QT3_SUPPORT
2871 /*!
2872     \overload
2873
2874     Sets the widget's GUI style to \a style using the QStyleFactory.
2875 */
2876 QStyle* QWidget::setStyle(const QString &style)
2877 {
2878     QStyle *s = QStyleFactory::create(style);
2879     setStyle(s);
2880     return s;
2881 }
2882 #endif
2883
2884 /*!
2885     \fn bool QWidget::isWindow() const
2886
2887     Returns true if the widget is an independent window, otherwise
2888     returns false.
2889
2890     A window is a widget that isn't visually the child of any other
2891     widget and that usually has a frame and a
2892     \l{QWidget::setWindowTitle()}{window title}.
2893
2894     A window can have a \l{QWidget::parentWidget()}{parent widget}.
2895     It will then be grouped with its parent and deleted when the
2896     parent is deleted, minimized when the parent is minimized etc. If
2897     supported by the window manager, it will also have a common
2898     taskbar entry with its parent.
2899
2900     QDialog and QMainWindow widgets are by default windows, even if a
2901     parent widget is specified in the constructor. This behavior is
2902     specified by the Qt::Window flag.
2903
2904     \sa window(), isModal(), parentWidget()
2905 */
2906
2907 /*!
2908     \property QWidget::modal
2909     \brief whether the widget is a modal widget
2910
2911     This property only makes sense for windows. A modal widget
2912     prevents widgets in all other windows from getting any input.
2913
2914     By default, this property is false.
2915
2916     \sa isWindow(), windowModality, QDialog
2917 */
2918
2919 /*!
2920     \property QWidget::windowModality
2921     \brief which windows are blocked by the modal widget
2922     \since 4.1
2923
2924     This property only makes sense for windows. A modal widget
2925     prevents widgets in other windows from getting input. The value of
2926     this property controls which windows are blocked when the widget
2927     is visible. Changing this property while the window is visible has
2928     no effect; you must hide() the widget first, then show() it again.
2929
2930     By default, this property is Qt::NonModal.
2931
2932     \sa isWindow(), QWidget::modal, QDialog
2933 */
2934
2935 Qt::WindowModality QWidget::windowModality() const
2936 {
2937     return static_cast<Qt::WindowModality>(data->window_modality);
2938 }
2939
2940 void QWidget::setWindowModality(Qt::WindowModality windowModality)
2941 {
2942     data->window_modality = windowModality;
2943     // setModal_sys() will be called by setAttribute()
2944     setAttribute(Qt::WA_ShowModal, (data->window_modality != Qt::NonModal));
2945     setAttribute(Qt::WA_SetWindowModality, true);
2946 }
2947
2948 /*!
2949     \fn bool QWidget::underMouse() const
2950
2951     Returns true if the widget is under the mouse cursor; otherwise
2952     returns false.
2953
2954     This value is not updated properly during drag and drop
2955     operations.
2956
2957     \sa enterEvent(), leaveEvent()
2958 */
2959
2960 /*!
2961     \property QWidget::minimized
2962     \brief whether this widget is minimized (iconified)
2963
2964     This property is only relevant for windows.
2965
2966     By default, this property is false.
2967
2968     \sa showMinimized(), visible, show(), hide(), showNormal(), maximized
2969 */
2970 bool QWidget::isMinimized() const
2971 { return data->window_state & Qt::WindowMinimized; }
2972
2973 /*!
2974     Shows the widget minimized, as an icon.
2975
2976     Calling this function only affects \l{isWindow()}{windows}.
2977
2978     \sa showNormal(), showMaximized(), show(), hide(), isVisible(),
2979         isMinimized()
2980 */
2981 void QWidget::showMinimized()
2982 {
2983     bool isMin = isMinimized();
2984     if (isMin && isVisible())
2985         return;
2986
2987     ensurePolished();
2988 #ifdef QT3_SUPPORT
2989     if (parent())
2990         QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
2991 #endif
2992
2993     if (!isMin)
2994         setWindowState((windowState() & ~Qt::WindowActive) | Qt::WindowMinimized);
2995     show();
2996 }
2997
2998 /*!
2999     \property QWidget::maximized
3000     \brief whether this widget is maximized
3001
3002     This property is only relevant for windows.
3003
3004     \note Due to limitations on some window systems, this does not always
3005     report the expected results (e.g., if the user on X11 maximizes the
3006     window via the window manager, Qt has no way of distinguishing this
3007     from any other resize). This is expected to improve as window manager
3008     protocols evolve.
3009
3010     By default, this property is false.
3011
3012     \sa windowState(), showMaximized(), visible, show(), hide(), showNormal(), minimized
3013 */
3014 bool QWidget::isMaximized() const
3015 { return data->window_state & Qt::WindowMaximized; }
3016
3017
3018
3019 /*!
3020     Returns the current window state. The window state is a OR'ed
3021     combination of Qt::WindowState: Qt::WindowMinimized,
3022     Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
3023
3024   \sa Qt::WindowState setWindowState()
3025  */
3026 Qt::WindowStates QWidget::windowState() const
3027 {
3028     return Qt::WindowStates(data->window_state);
3029 }
3030
3031 /*!\internal
3032
3033    The function sets the window state on child widgets similar to
3034    setWindowState(). The difference is that the window state changed
3035    event has the isOverride() flag set. It exists mainly to keep
3036    Q3Workspace working.
3037  */
3038 void QWidget::overrideWindowState(Qt::WindowStates newstate)
3039 {
3040     QWindowStateChangeEvent e(Qt::WindowStates(data->window_state), true);
3041     data->window_state  = newstate;
3042     QApplication::sendEvent(this, &e);
3043 }
3044
3045 /*!
3046     \fn void QWidget::setWindowState(Qt::WindowStates windowState)
3047
3048     Sets the window state to \a windowState. The window state is a OR'ed
3049     combination of Qt::WindowState: Qt::WindowMinimized,
3050     Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
3051
3052     If the window is not visible (i.e. isVisible() returns false), the
3053     window state will take effect when show() is called. For visible
3054     windows, the change is immediate. For example, to toggle between
3055     full-screen and normal mode, use the following code:
3056
3057     \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 0
3058
3059     In order to restore and activate a minimized window (while
3060     preserving its maximized and/or full-screen state), use the following:
3061
3062     \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 1
3063
3064     Calling this function will hide the widget. You must call show() to make
3065     the widget visible again.
3066
3067     \note On some window systems Qt::WindowActive is not immediate, and may be
3068     ignored in certain cases.
3069
3070     When the window state changes, the widget receives a changeEvent()
3071     of type QEvent::WindowStateChange.
3072
3073     \sa Qt::WindowState windowState()
3074 */
3075
3076 /*!
3077     \property QWidget::fullScreen
3078     \brief whether the widget is shown in full screen mode
3079
3080     A widget in full screen mode occupies the whole screen area and does not
3081     display window decorations, such as a title bar.
3082
3083     By default, this property is false.
3084
3085     \sa windowState(), minimized, maximized
3086 */
3087 bool QWidget::isFullScreen() const
3088 { return data->window_state & Qt::WindowFullScreen; }
3089
3090 /*!
3091     Shows the widget in full-screen mode.
3092
3093     Calling this function only affects \l{isWindow()}{windows}.
3094
3095     To return from full-screen mode, call showNormal().
3096
3097     Full-screen mode works fine under Windows, but has certain
3098     problems under X. These problems are due to limitations of the
3099     ICCCM protocol that specifies the communication between X11
3100     clients and the window manager. ICCCM simply does not understand
3101     the concept of non-decorated full-screen windows. Therefore, the
3102     best we can do is to request a borderless window and place and
3103     resize it to fill the entire screen. Depending on the window
3104     manager, this may or may not work. The borderless window is
3105     requested using MOTIF hints, which are at least partially
3106     supported by virtually all modern window managers.
3107
3108     An alternative would be to bypass the window manager entirely and
3109     create a window with the Qt::X11BypassWindowManagerHint flag. This
3110     has other severe problems though, like totally broken keyboard focus
3111     and very strange effects on desktop changes or when the user raises
3112     other windows.
3113
3114     X11 window managers that follow modern post-ICCCM specifications
3115     support full-screen mode properly.
3116
3117     \sa showNormal(), showMaximized(), show(), hide(), isVisible()
3118 */
3119 void QWidget::showFullScreen()
3120 {
3121 #ifdef Q_WS_MAC
3122     // If the unified toolbar is enabled, we have to disable it before going fullscreen.
3123     QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
3124     if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) {
3125         mainWindow->setUnifiedTitleAndToolBarOnMac(false);
3126         QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
3127         mainLayout->activateUnifiedToolbarAfterFullScreen = true;
3128     }
3129 #endif // Q_WS_MAC
3130     ensurePolished();
3131 #ifdef QT3_SUPPORT
3132     if (parent())
3133         QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
3134 #endif
3135
3136     setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized))
3137                    | Qt::WindowFullScreen);
3138     show();
3139     activateWindow();
3140 }
3141
3142 /*!
3143     Shows the widget maximized.
3144
3145     Calling this function only affects \l{isWindow()}{windows}.
3146
3147     On X11, this function may not work properly with certain window
3148     managers. See the \l{Window Geometry} documentation for an explanation.
3149
3150     \sa setWindowState(), showNormal(), showMinimized(), show(), hide(), isVisible()
3151 */
3152 void QWidget::showMaximized()
3153 {
3154     ensurePolished();
3155 #ifdef QT3_SUPPORT
3156     if (parent())
3157         QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
3158 #endif
3159
3160     setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen))
3161                    | Qt::WindowMaximized);
3162 #ifdef Q_WS_MAC
3163     // If the unified toolbar was enabled before going fullscreen, we have to enable it back.
3164     QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
3165     if (mainWindow)
3166     {
3167         QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
3168         if (mainLayout->activateUnifiedToolbarAfterFullScreen) {
3169             mainWindow->setUnifiedTitleAndToolBarOnMac(true);
3170             mainLayout->activateUnifiedToolbarAfterFullScreen = false;
3171         }
3172     }
3173 #endif // Q_WS_MAC
3174     show();
3175 }
3176
3177 /*!
3178     Restores the widget after it has been maximized or minimized.
3179
3180     Calling this function only affects \l{isWindow()}{windows}.
3181
3182     \sa setWindowState(), showMinimized(), showMaximized(), show(), hide(), isVisible()
3183 */
3184 void QWidget::showNormal()
3185 {
3186     ensurePolished();
3187 #ifdef QT3_SUPPORT
3188     if (parent())
3189         QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
3190 #endif
3191
3192     setWindowState(windowState() & ~(Qt::WindowMinimized
3193                                      | Qt::WindowMaximized
3194                                      | Qt::WindowFullScreen));
3195 #ifdef Q_WS_MAC
3196     // If the unified toolbar was enabled before going fullscreen, we have to enable it back.
3197     QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
3198     if (mainWindow)
3199     {
3200         QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
3201         if (mainLayout->activateUnifiedToolbarAfterFullScreen) {
3202             mainWindow->setUnifiedTitleAndToolBarOnMac(true);
3203             mainLayout->activateUnifiedToolbarAfterFullScreen = false;
3204         }
3205     }
3206 #endif // Q_WS_MAC
3207     show();
3208 }
3209
3210 /*!
3211     Returns true if this widget would become enabled if \a ancestor is
3212     enabled; otherwise returns false.
3213
3214
3215
3216     This is the case if neither the widget itself nor every parent up
3217     to but excluding \a ancestor has been explicitly disabled.
3218
3219     isEnabledTo(0) is equivalent to isEnabled().
3220
3221     \sa setEnabled() enabled
3222 */
3223
3224 bool QWidget::isEnabledTo(QWidget* ancestor) const
3225 {
3226     const QWidget * w = this;
3227     while (!w->testAttribute(Qt::WA_ForceDisabled)
3228             && !w->isWindow()
3229             && w->parentWidget()
3230             && w->parentWidget() != ancestor)
3231         w = w->parentWidget();
3232     return !w->testAttribute(Qt::WA_ForceDisabled);
3233 }
3234
3235 #ifndef QT_NO_ACTION
3236 /*!
3237     Appends the action \a action to this widget's list of actions.
3238
3239     All QWidgets have a list of \l{QAction}s, however they can be
3240     represented graphically in many different ways. The default use of
3241     the QAction list (as returned by actions()) is to create a context
3242     QMenu.
3243
3244     A QWidget should only have one of each action and adding an action
3245     it already has will not cause the same action to be in the widget twice.
3246
3247     The ownership of \a action is not transferred to this QWidget.
3248
3249     \sa removeAction(), insertAction(), actions(), QMenu
3250 */
3251 void QWidget::addAction(QAction *action)
3252 {
3253     insertAction(0, action);
3254 }
3255
3256 /*!
3257     Appends the actions \a actions to this widget's list of actions.
3258
3259     \sa removeAction(), QMenu, addAction()
3260 */
3261 void QWidget::addActions(QList<QAction*> actions)
3262 {
3263     for(int i = 0; i < actions.count(); i++)
3264         insertAction(0, actions.at(i));
3265 }
3266
3267 /*!
3268     Inserts the action \a action to this widget's list of actions,
3269     before the action \a before. It appends the action if \a before is 0 or
3270     \a before is not a valid action for this widget.
3271
3272     A QWidget should only have one of each action.
3273
3274     \sa removeAction(), addAction(), QMenu, contextMenuPolicy, actions()
3275 */
3276 void QWidget::insertAction(QAction *before, QAction *action)
3277 {
3278     if(!action) {
3279         qWarning("QWidget::insertAction: Attempt to insert null action");
3280         return;
3281     }
3282
3283     Q_D(QWidget);
3284     if(d->actions.contains(action))
3285         removeAction(action);
3286
3287     int pos = d->actions.indexOf(before);
3288     if (pos < 0) {
3289         before = 0;
3290         pos = d->actions.size();
3291     }
3292     d->actions.insert(pos, action);
3293
3294     QActionPrivate *apriv = action->d_func();
3295     apriv->widgets.append(this);
3296
3297     QActionEvent e(QEvent::ActionAdded, action, before);
3298     QApplication::sendEvent(this, &e);
3299 }
3300
3301 /*!
3302     Inserts the actions \a actions to this widget's list of actions,
3303     before the action \a before. It appends the action if \a before is 0 or
3304     \a before is not a valid action for this widget.
3305
3306     A QWidget can have at most one of each action.
3307
3308     \sa removeAction(), QMenu, insertAction(), contextMenuPolicy
3309 */
3310 void QWidget::insertActions(QAction *before, QList<QAction*> actions)
3311 {
3312     for(int i = 0; i < actions.count(); ++i)
3313         insertAction(before, actions.at(i));
3314 }
3315
3316 /*!
3317     Removes the action \a action from this widget's list of actions.
3318     \sa insertAction(), actions(), insertAction()
3319 */
3320 void QWidget::removeAction(QAction *action)
3321 {
3322     if (!action)
3323         return;
3324
3325     Q_D(QWidget);
3326
3327     QActionPrivate *apriv = action->d_func();
3328     apriv->widgets.removeAll(this);
3329
3330     if (d->actions.removeAll(action)) {
3331         QActionEvent e(QEvent::ActionRemoved, action);
3332         QApplication::sendEvent(this, &e);
3333     }
3334 }
3335
3336 /*!
3337     Returns the (possibly empty) list of this widget's actions.
3338
3339     \sa contextMenuPolicy, insertAction(), removeAction()
3340 */
3341 QList<QAction*> QWidget::actions() const
3342 {
3343     Q_D(const QWidget);
3344     return d->actions;
3345 }
3346 #endif // QT_NO_ACTION
3347
3348 /*!
3349   \fn bool QWidget::isEnabledToTLW() const
3350   \obsolete
3351
3352   This function is deprecated. It is equivalent to isEnabled()
3353 */
3354
3355 /*!
3356     \property QWidget::enabled
3357     \brief whether the widget is enabled
3358
3359     In general an enabled widget handles keyboard and mouse events; a disabled
3360     widget does not. An exception is made with \l{QAbstractButton}.
3361
3362     Some widgets display themselves differently when they are
3363     disabled. For example a button might draw its label grayed out. If
3364     your widget needs to know when it becomes enabled or disabled, you
3365     can use the changeEvent() with type QEvent::EnabledChange.
3366
3367     Disabling a widget implicitly disables all its children. Enabling
3368     respectively enables all child widgets unless they have been
3369     explicitly disabled.
3370
3371     By default, this property is true.
3372
3373     \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
3374 */
3375 void QWidget::setEnabled(bool enable)
3376 {
3377     Q_D(QWidget);
3378     setAttribute(Qt::WA_ForceDisabled, !enable);
3379     d->setEnabled_helper(enable);
3380 }
3381
3382 void QWidgetPrivate::setEnabled_helper(bool enable)
3383 {
3384     Q_Q(QWidget);
3385
3386     if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->isEnabled())
3387         return; // nothing we can do
3388
3389     if (enable != q->testAttribute(Qt::WA_Disabled))
3390         return; // nothing to do
3391
3392     q->setAttribute(Qt::WA_Disabled, !enable);
3393     updateSystemBackground();
3394
3395     if (!enable && q->window()->focusWidget() == q) {
3396         bool parentIsEnabled = (!q->parentWidget() || q->parentWidget()->isEnabled());
3397         if (!parentIsEnabled || !q->focusNextChild())
3398             q->clearFocus();
3399     }
3400
3401     Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceDisabled : Qt::WA_Disabled;
3402     for (int i = 0; i < children.size(); ++i) {
3403         QWidget *w = qobject_cast<QWidget *>(children.at(i));
3404         if (w && !w->testAttribute(attribute))
3405             w->d_func()->setEnabled_helper(enable);
3406     }
3407 #if defined(Q_WS_X11)
3408     if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
3409         // enforce the windows behavior of clearing the cursor on
3410         // disabled widgets
3411         qt_x11_enforce_cursor(q);
3412     }
3413 #endif
3414 #if defined(Q_WS_MAC)
3415     setEnabled_helper_sys(enable);
3416 #endif
3417 #ifndef QT_NO_IM
3418     if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) {
3419         QWidget *focusWidget = effectiveFocusWidget();
3420         QInputContext *qic = focusWidget->d_func()->inputContext();
3421         if (enable) {
3422             if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
3423                 qic->setFocusWidget(focusWidget);
3424         } else {
3425             qic->reset();
3426             qic->setFocusWidget(0);
3427         }
3428     }
3429 #endif //QT_NO_IM
3430     QEvent e(QEvent::EnabledChange);
3431     QApplication::sendEvent(q, &e);
3432 #ifdef QT3_SUPPORT
3433     q->enabledChange(!enable); // compatibility
3434 #endif
3435 }
3436
3437 /*!
3438     \property QWidget::acceptDrops
3439     \brief whether drop events are enabled for this widget
3440
3441     Setting this property to true announces to the system that this
3442     widget \e may be able to accept drop events.
3443
3444     If the widget is the desktop (windowType() == Qt::Desktop), this may
3445     fail if another application is using the desktop; you can call
3446     acceptDrops() to test if this occurs.
3447
3448     \warning Do not modify this property in a drag and drop event handler.
3449
3450     By default, this property is false.
3451
3452     \sa {Drag and Drop}
3453 */
3454 bool QWidget::acceptDrops() const
3455 {
3456     return testAttribute(Qt::WA_AcceptDrops);
3457 }
3458
3459 void QWidget::setAcceptDrops(bool on)
3460 {
3461     setAttribute(Qt::WA_AcceptDrops, on);
3462
3463 }
3464
3465 /*!
3466     \fn void QWidget::enabledChange(bool)
3467
3468     \internal
3469     \obsolete
3470 */
3471
3472 /*!
3473     \fn void QWidget::paletteChange(const QPalette &)
3474
3475     \internal
3476     \obsolete
3477 */
3478
3479 /*!
3480     \fn void QWidget::fontChange(const QFont &)
3481
3482     \internal
3483     \obsolete
3484 */
3485
3486 /*!
3487     \fn void QWidget::windowActivationChange(bool)
3488
3489     \internal
3490     \obsolete
3491 */
3492
3493 /*!
3494     \fn void QWidget::languageChange()
3495
3496     \obsolete
3497 */
3498
3499 /*!
3500     \fn void QWidget::styleChange(QStyle& style)
3501
3502     \internal
3503     \obsolete
3504 */
3505
3506 /*!
3507     Disables widget input events if \a disable is true; otherwise
3508     enables input events.
3509
3510     See the \l enabled documentation for more information.
3511
3512     \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
3513 */
3514 void QWidget::setDisabled(bool disable)
3515 {
3516     setEnabled(!disable);
3517 }
3518
3519 /*!
3520     \property QWidget::frameGeometry
3521     \brief geometry of the widget relative to its parent including any
3522     window frame
3523
3524     See the \l{Window Geometry} documentation for an overview of geometry
3525     issues with windows.
3526
3527     By default, this property contains a value that depends on the user's
3528     platform and screen geometry.
3529
3530     \sa geometry() x() y() pos()
3531 */
3532 QRect QWidget::frameGeometry() const
3533 {
3534     Q_D(const QWidget);
3535     if (isWindow() && ! (windowType() == Qt::Popup)) {
3536         QRect fs = d->frameStrut();
3537         return QRect(data->crect.x() - fs.left(),
3538                      data->crect.y() - fs.top(),
3539                      data->crect.width() + fs.left() + fs.right(),
3540                      data->crect.height() + fs.top() + fs.bottom());
3541     }
3542     return data->crect;
3543 }
3544
3545 /*!
3546     \property QWidget::x
3547
3548     \brief the x coordinate of the widget relative to its parent including
3549     any window frame
3550
3551     See the \l{Window Geometry} documentation for an overview of geometry
3552     issues with windows.
3553
3554     By default, this property has a value of 0.
3555
3556     \sa frameGeometry, y, pos
3557 */
3558 int QWidget::x() const
3559 {
3560     Q_D(const QWidget);
3561     if (isWindow() && ! (windowType() == Qt::Popup))
3562         return data->crect.x() - d->frameStrut().left();
3563     return data->crect.x();
3564 }
3565
3566 /*!
3567     \property QWidget::y
3568     \brief the y coordinate of the widget relative to its parent and
3569     including any window frame
3570
3571     See the \l{Window Geometry} documentation for an overview of geometry
3572     issues with windows.
3573
3574     By default, this property has a value of 0.
3575
3576     \sa frameGeometry, x, pos
3577 */
3578 int QWidget::y() const
3579 {
3580     Q_D(const QWidget);
3581     if (isWindow() && ! (windowType() == Qt::Popup))
3582         return data->crect.y() - d->frameStrut().top();
3583     return data->crect.y();
3584 }
3585
3586 /*!
3587     \property QWidget::pos
3588     \brief the position of the widget within its parent widget
3589
3590     If the widget is a window, the position is that of the widget on
3591     the desktop, including its frame.
3592
3593     When changing the position, the widget, if visible, receives a
3594     move event (moveEvent()) immediately. If the widget is not
3595     currently visible, it is guaranteed to receive an event before it
3596     is shown.
3597
3598     By default, this property contains a position that refers to the
3599     origin.
3600
3601     \warning Calling move() or setGeometry() inside moveEvent() can
3602     lead to infinite recursion.
3603
3604     See the \l{Window Geometry} documentation for an overview of geometry
3605     issues with windows.
3606
3607     \sa frameGeometry, size x(), y()
3608 */
3609 QPoint QWidget::pos() const
3610 {
3611     Q_D(const QWidget);
3612     if (isWindow() && ! (windowType() == Qt::Popup)) {
3613         QRect fs = d->frameStrut();
3614         return QPoint(data->crect.x() - fs.left(), data->crect.y() - fs.top());
3615     }
3616     return data->crect.topLeft();
3617 }
3618
3619 /*!
3620     \property QWidget::geometry
3621     \brief the geometry of the widget relative to its parent and
3622     excluding the window frame
3623
3624     When changing the geometry, the widget, if visible, receives a
3625     move event (moveEvent()) and/or a resize event (resizeEvent())
3626     immediately. If the widget is not currently visible, it is
3627     guaranteed to receive appropriate events before it is shown.
3628
3629     The size component is adjusted if it lies outside the range
3630     defined by minimumSize() and maximumSize().
3631
3632     \warning Calling setGeometry() inside resizeEvent() or moveEvent()
3633     can lead to infinite recursion.
3634
3635     See the \l{Window Geometry} documentation for an overview of geometry
3636     issues with windows.
3637
3638     By default, this property contains a value that depends on the user's
3639     platform and screen geometry.
3640
3641     \sa frameGeometry(), rect(), move(), resize(), moveEvent(),
3642         resizeEvent(), minimumSize(), maximumSize()
3643 */
3644
3645 /*!
3646     \property QWidget::normalGeometry
3647
3648     \brief the geometry of the widget as it will appear when shown as
3649     a normal (not maximized or full screen) top-level widget
3650
3651     For child widgets this property always holds an empty rectangle.
3652
3653     By default, this property contains an empty rectangle.
3654
3655     \sa QWidget::windowState(), QWidget::geometry
3656 */
3657
3658 /*!
3659     \property QWidget::size
3660     \brief the size of the widget excluding any window frame
3661
3662     If the widget is visible when it is being resized, it receives a resize event
3663     (resizeEvent()) immediately. If the widget is not currently
3664     visible, it is guaranteed to receive an event before it is shown.
3665
3666     The size is adjusted if it lies outside the range defined by
3667     minimumSize() and maximumSize().
3668
3669     By default, this property contains a value that depends on the user's
3670     platform and screen geometry.
3671
3672     \warning Calling resize() or setGeometry() inside resizeEvent() can
3673     lead to infinite recursion.
3674
3675     \note Setting the size to \c{QSize(0, 0)} will cause the widget to not
3676     appear on screen. This also applies to windows.
3677
3678     \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize()
3679 */
3680
3681 /*!
3682     \property QWidget::width
3683     \brief the width of the widget excluding any window frame
3684
3685     See the \l{Window Geometry} documentation for an overview of geometry
3686     issues with windows.
3687
3688     \note Do not use this function to find the width of a screen on
3689     a \l{QDesktopWidget}{multiple screen desktop}. Read
3690     \l{QDesktopWidget#Screen Geometry}{this note} for details.
3691
3692     By default, this property contains a value that depends on the user's
3693     platform and screen geometry.
3694
3695     \sa geometry, height, size
3696 */
3697
3698 /*!
3699     \property QWidget::height
3700     \brief the height of the widget excluding any window frame
3701
3702     See the \l{Window Geometry} documentation for an overview of geometry
3703     issues with windows.
3704
3705     \note Do not use this function to find the height of a screen
3706     on a \l{QDesktopWidget}{multiple screen desktop}. Read
3707     \l{QDesktopWidget#Screen Geometry}{this note} for details.
3708
3709     By default, this property contains a value that depends on the user's
3710     platform and screen geometry.