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