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