Fixed crash in GL 2 paint engine on Intel Atom.
[profile/ivi/qtbase.git] / src / widgets / platforms / mac / qwidget_mac.mm
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 /****************************************************************************
43 **
44 ** Copyright (c) 2007-2008, Apple, Inc.
45 **
46 ** All rights reserved.
47 **
48 ** Redistribution and use in source and binary forms, with or without
49 ** modification, are permitted provided that the following conditions are met:
50 **
51 **   * Redistributions of source code must retain the above copyright notice,
52 **     this list of conditions and the following disclaimer.
53 **
54 **   * Redistributions in binary form must reproduce the above copyright notice,
55 **     this list of conditions and the following disclaimer in the documentation
56 **     and/or other materials provided with the distribution.
57 **
58 **   * Neither the name of Apple, Inc. nor the names of its contributors
59 **     may be used to endorse or promote products derived from this software
60 **     without specific prior written permission.
61 **
62 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
63 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
64 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
65 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
66 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
67 ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
68 ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
69 ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
70 ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
71 ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 **
74 ****************************************************************************/
75
76 #include <private/qt_mac_p.h>
77 #include <private/qeventdispatcher_mac_p.h>
78
79 #include "qapplication.h"
80 #include "qapplication_p.h"
81 #include "qbitmap.h"
82 #include "qcursor.h"
83 #include "qdesktopwidget.h"
84 #include "qevent.h"
85 #include "qfileinfo.h"
86 #include "qimage.h"
87 #include "qlayout.h"
88 #include "qmenubar.h"
89 #include <private/qbackingstore_p.h>
90 #include <private/qwindowsurface_mac_p.h>
91 #include <private/qpaintengine_mac_p.h>
92 #include "qpainter.h"
93 #include "qstyle.h"
94 #include "qtimer.h"
95 #include "qfocusframe.h"
96 #include "qdebug.h"
97 #include <private/qmainwindowlayout_p.h>
98
99 #include <private/qabstractscrollarea_p.h>
100 #include <qabstractscrollarea.h>
101 #include <ApplicationServices/ApplicationServices.h>
102 #include <limits.h>
103 #include <private/qt_cocoa_helpers_mac_p.h>
104 #include <private/qcocoaview_mac_p.h>
105 #include <private/qcocoawindow_mac_p.h>
106 #include <private/qcocoawindowdelegate_mac_p.h>
107 #include <private/qcocoapanel_mac_p.h>
108
109 #include "qwidget_p.h"
110 #include "qevent_p.h"
111 #include "qdnd_p.h"
112 #include <QtGui/qgraphicsproxywidget.h>
113 #include "qmainwindow.h"
114
115 QT_BEGIN_NAMESPACE
116
117 // qmainwindow.cpp
118 extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
119
120 #define XCOORD_MAX 16383
121 #define WRECT_MAX 8191
122
123
124
125 /*****************************************************************************
126   QWidget debug facilities
127  *****************************************************************************/
128 //#define DEBUG_WINDOW_RGNS
129 //#define DEBUG_WINDOW_CREATE
130 //#define DEBUG_WINDOW_STATE
131 //#define DEBUG_WIDGET_PAINT
132
133 /*****************************************************************************
134   QWidget globals
135  *****************************************************************************/
136
137 static bool qt_mac_raise_process = true;
138 static OSWindowRef qt_root_win = 0;
139 QWidget *mac_mouse_grabber = 0;
140 QWidget *mac_keyboard_grabber = 0;
141
142
143 /*****************************************************************************
144   Externals
145  *****************************************************************************/
146 extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
147 extern QWidget *qt_mac_modal_blocked(QWidget *); //qapplication_mac.mm
148 extern void qt_event_request_activate(QWidget *); //qapplication_mac.mm
149 extern bool qt_event_remove_activate(); //qapplication_mac.mm
150 extern void qt_mac_event_release(QWidget *w); //qapplication_mac.mm
151 extern void qt_event_request_showsheet(QWidget *); //qapplication_mac.mm
152 extern void qt_event_request_window_change(QWidget *); //qapplication_mac.mm
153 extern QPointer<QWidget> qt_last_mouse_receiver; //qapplication_mac.mm
154 extern QPointer<QWidget> qt_last_native_mouse_receiver; //qt_cocoa_helpers_mac.mm
155 extern IconRef qt_mac_create_iconref(const QPixmap &); //qpixmap_mac.cpp
156 extern void qt_mac_set_cursor(const QCursor *, const QPoint &); //qcursor_mac.mm
157 extern void qt_mac_update_cursor(); //qcursor_mac.mm
158 extern bool qt_nograb();
159 extern CGImageRef qt_mac_create_cgimage(const QPixmap &, bool); //qpixmap_mac.cpp
160 extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
161 extern QRegion qt_mac_convert_mac_region(RgnHandle rgn); //qregion_mac.cpp
162 extern void qt_mac_setMouseGrabCursor(bool set, QCursor *cursor = 0); // qcursor_mac.mm
163 extern QPointer<QWidget> topLevelAt_cache; // qapplication_mac.mm
164 /*****************************************************************************
165   QWidget utility functions
166  *****************************************************************************/
167 void Q_GUI_EXPORT qt_mac_set_raise_process(bool b) { qt_mac_raise_process = b; }
168 static QSize qt_mac_desktopSize()
169 {
170     int w = 0, h = 0;
171     CGDisplayCount cg_count;
172     CGGetActiveDisplayList(0, 0, &cg_count);
173     QVector<CGDirectDisplayID> displays(cg_count);
174     CGGetActiveDisplayList(cg_count, displays.data(), &cg_count);
175     Q_ASSERT(cg_count == (CGDisplayCount)displays.size());
176     for(int i = 0; i < (int)cg_count; ++i) {
177         CGRect r = CGDisplayBounds(displays.at(i));
178         w = qMax<int>(w, qRound(r.origin.x + r.size.width));
179         h = qMax<int>(h, qRound(r.origin.y + r.size.height));
180     }
181     return QSize(w, h);
182 }
183
184 static NSDrawer *qt_mac_drawer_for(const QWidget *widget)
185 {
186     NSView *widgetView = reinterpret_cast<NSView *>(widget->window()->effectiveWinId());
187     NSArray *windows = [NSApp windows];
188     for (NSWindow *window in windows) {
189         NSArray *drawers = [window drawers];
190         for (NSDrawer *drawer in drawers) {
191             if ([drawer contentView] == widgetView)
192                 return drawer;
193         }
194     }
195     return 0;
196 }
197
198 static void qt_mac_destructView(OSViewRef view)
199 {
200     NSWindow *window = [view window];
201     if ([window contentView] == view)
202         [window setContentView:[[NSView alloc] initWithFrame:[view bounds]]];
203     [view removeFromSuperview];
204     [view release];
205 }
206
207 static void qt_mac_destructWindow(OSWindowRef window)
208 {
209     if ([window isVisible] && [window isSheet]){
210         [NSApp endSheet:window];
211         [window orderOut:window];
212     }
213
214     [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] resignDelegateForWindow:window];
215     [window release];
216 }
217
218 static void qt_mac_destructDrawer(NSDrawer *drawer)
219 {
220     [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] resignDelegateForDrawer:drawer];
221     [drawer release];
222 }
223
224 bool qt_mac_can_clickThrough(const QWidget *w)
225 {
226     static int qt_mac_carbon_clickthrough = -1;
227     if (qt_mac_carbon_clickthrough < 0)
228         qt_mac_carbon_clickthrough = !qgetenv("QT_MAC_NO_COCOA_CLICKTHROUGH").isEmpty();
229     bool ret = !qt_mac_carbon_clickthrough;
230     for ( ; w; w = w->parentWidget()) {
231         if (w->testAttribute(Qt::WA_MacNoClickThrough)) {
232             ret = false;
233             break;
234         }
235     }
236     return ret;
237 }
238
239 bool qt_mac_is_macsheet(const QWidget *w)
240 {
241     if (!w)
242         return false;
243
244     Qt::WindowModality modality = w->windowModality();
245     if (modality == Qt::ApplicationModal)
246         return false;
247     return w->parentWidget() && (modality == Qt::WindowModal || w->windowType() == Qt::Sheet);
248 }
249
250 bool qt_mac_is_macdrawer(const QWidget *w)
251 {
252     return (w && w->parentWidget() && w->windowType() == Qt::Drawer);
253 }
254
255 bool qt_mac_insideKeyWindow(const QWidget *w)
256 {
257     return [[reinterpret_cast<NSView *>(w->effectiveWinId()) window] isKeyWindow];
258     return false;
259 }
260
261 bool qt_mac_set_drawer_preferred_edge(QWidget *w, Qt::DockWidgetArea where) //users of Qt for Mac OS X can use this..
262 {
263     if(!qt_mac_is_macdrawer(w))
264         return false;
265
266     NSDrawer *drawer = qt_mac_drawer_for(w);
267     if (!drawer)
268         return false;
269         NSRectEdge      edge;
270     if (where & Qt::LeftDockWidgetArea)
271         edge = NSMinXEdge;
272     else if (where & Qt::RightDockWidgetArea)
273         edge = NSMaxXEdge;
274     else if (where & Qt::TopDockWidgetArea)
275                 edge = NSMaxYEdge;
276     else if (where & Qt::BottomDockWidgetArea)
277         edge = NSMinYEdge;
278     else
279         return false;
280
281     if (edge == [drawer preferredEdge]) //no-op
282         return false;
283
284     if (w->isVisible()) {
285             [drawer close];
286             [drawer openOnEdge:edge];
287         }
288         [drawer setPreferredEdge:edge];
289     return true;
290 }
291
292 QPoint qt_mac_posInWindow(const QWidget *w)
293 {
294     QPoint ret = w->data->wrect.topLeft();
295     while(w && !w->isWindow()) {
296         ret += w->pos();
297         w =  w->parentWidget();
298     }
299     return ret;
300 }
301
302 //find a QWidget from a OSWindowRef
303 QWidget *qt_mac_find_window(OSWindowRef window)
304 {
305     return [window QT_MANGLE_NAMESPACE(qt_qwidget)];
306 }
307
308 inline static void qt_mac_set_fullscreen_mode(bool b)
309 {
310     extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
311     if(qt_mac_app_fullscreen == b)
312         return;
313     qt_mac_app_fullscreen = b;
314     if (b) {
315         SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
316     } else {
317         SetSystemUIMode(kUIModeNormal, 0);
318     }
319 }
320
321 Q_GUI_EXPORT OSViewRef qt_mac_nativeview_for(const QWidget *w)
322 {
323     return reinterpret_cast<OSViewRef>(w->internalWinId());
324 }
325
326 Q_GUI_EXPORT OSViewRef qt_mac_effectiveview_for(const QWidget *w)
327 {
328     // Get the first non-alien (parent) widget for
329     // w, and return its NSView (if it has one):
330     return reinterpret_cast<OSViewRef>(w->effectiveWinId());
331 }
332
333 Q_GUI_EXPORT OSViewRef qt_mac_get_contentview_for(OSWindowRef w)
334 {
335     return [w contentView];
336 }
337
338 bool qt_mac_sendMacEventToWidget(QWidget *widget, EventRef ref)
339 {
340     return widget->macEvent(0, ref);
341 }
342
343 Q_GUI_EXPORT OSWindowRef qt_mac_window_for(OSViewRef view)
344 {
345     if (view)
346         return [view window];
347     return 0;
348 }
349
350 static bool qt_isGenuineQWidget(OSViewRef ref)
351 {
352     return [ref isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]];
353 }
354
355 bool qt_isGenuineQWidget(const QWidget *window)
356 {
357     if (!window)
358         return false;
359
360     if (!window->internalWinId())
361         return true;  //alien
362
363     return qt_isGenuineQWidget(OSViewRef(window->internalWinId()));
364 }
365
366 Q_GUI_EXPORT OSWindowRef qt_mac_window_for(const QWidget *w)
367 {
368     if (OSViewRef hiview = qt_mac_effectiveview_for(w)) {
369         OSWindowRef window = qt_mac_window_for(hiview);
370         if (window)
371             return window;
372
373         if (qt_isGenuineQWidget(hiview)) {
374             // This is a workaround for NSToolbar. When a widget is hidden
375             // by clicking the toolbar button, Cocoa reparents the widgets
376             // to another window (but Qt doesn't know about it).
377             // When we start showing them, it reparents back,
378             // but at this point it's window is nil, but the window it's being brought
379             // into (the Qt one) is for sure created.
380             // This stops the hierarchy moving under our feet.
381             QWidget *toplevel = w->window();
382             if (toplevel != w) {
383                 hiview = qt_mac_nativeview_for(toplevel);
384                 if (OSWindowRef w = qt_mac_window_for(hiview))
385                     return w;
386             }
387
388             toplevel->d_func()->createWindow_sys();
389             // Reget the hiview since "create window" could potentially move the view (I guess).
390             hiview = qt_mac_nativeview_for(toplevel);
391             return qt_mac_window_for(hiview);
392         }
393     }
394     return 0;
395 }
396
397
398
399 inline static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRect &rect)
400 {
401     if (!widget)
402         return false;
403
404 #ifndef QT_NO_GRAPHICSVIEW
405     QWidget *tlw = widget->window();
406     QWExtra *extra = qt_widget_private(tlw)->extra;
407     if (extra && extra->proxyWidget) {
408         extra->proxyWidget->update(rect.translated(widget->mapTo(tlw, QPoint())));
409         return true;
410     }
411 #endif
412
413     return false;
414 }
415
416 inline static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRegion &rgn)
417 {
418     if (!widget)
419         return false;
420
421 #ifndef QT_NO_GRAPHICSVIEW
422     QWidget *tlw = widget->window();
423     QWExtra *extra = qt_widget_private(tlw)->extra;
424     if (extra && extra->proxyWidget) {
425         const QPoint offset(widget->mapTo(tlw, QPoint()));
426         const QVector<QRect> rects = rgn.rects();
427         for (int i = 0; i < rects.size(); ++i)
428             extra->proxyWidget->update(rects.at(i).translated(offset));
429         return true;
430     }
431 #endif
432
433     return false;
434 }
435
436 void QWidgetPrivate::macSetNeedsDisplay(QRegion region)
437 {
438     Q_Q(QWidget);
439     if (NSView *nativeView = qt_mac_nativeview_for(q)) {
440         // INVARIANT: q is _not_ alien. So we can optimize a little:
441         if (region.isEmpty()) {
442             [nativeView setNeedsDisplay:YES];
443         } else {
444             QVector<QRect> rects = region.rects();
445             for (int i = 0; i<rects.count(); ++i) {
446                 const QRect &rect = rects.at(i);
447                 NSRect nsrect = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
448                 [nativeView setNeedsDisplayInRect:nsrect];
449             }
450         }
451     } else if (QWidget *effectiveWidget = q->nativeParentWidget()) {
452         // INVARIANT: q is alien, and effectiveWidget is native.
453         if (NSView *effectiveView = qt_mac_nativeview_for(effectiveWidget)) {
454             if (region.isEmpty()) {
455                 const QRect &rect = q->rect();
456                 QPoint p = q->mapTo(effectiveWidget, rect.topLeft());
457                 NSRect nsrect = NSMakeRect(p.x(), p.y(), rect.width(), rect.height());
458                 [effectiveView setNeedsDisplayInRect:nsrect];
459             } else {
460                 QVector<QRect> rects = region.rects();
461                 for (int i = 0; i<rects.count(); ++i) {
462                     const QRect &rect = rects.at(i);
463                     QPoint p = q->mapTo(effectiveWidget, rect.topLeft());
464                     NSRect nsrect = NSMakeRect(p.x(), p.y(), rect.width(), rect.height());
465                     [effectiveView setNeedsDisplayInRect:nsrect];
466                 }
467             }
468         }
469     }
470 }
471
472 void QWidgetPrivate::macUpdateIsOpaque()
473 {
474     Q_Q(QWidget);
475     if (!q->testAttribute(Qt::WA_WState_Created))
476         return;
477     if (isRealWindow() && !q->testAttribute(Qt::WA_MacBrushedMetal)) {
478         bool opaque = isOpaque;
479         if (extra && extra->imageMask)
480             opaque = false; // we are never opaque when we have a mask.
481         [qt_mac_window_for(q) setOpaque:opaque];
482     }
483 }
484 static OSWindowRef qt_mac_create_window(QWidget *widget, WindowClass wclass,
485                                         NSUInteger wattr, const QRect &crect)
486 {
487     // Determine if we need to add in our "custom window" attribute. Cocoa is rather clever
488     // in deciding if we need the maximize button or not (i.e., it's resizeable, so you
489     // must need a maximize button). So, the only buttons we have control over are the
490     // close and minimize buttons. If someone wants to customize and NOT have the maximize
491     // button, then we have to do our hack. We only do it for these cases because otherwise
492     // the window looks different when activated. This "QtMacCustomizeWindow" attribute is
493     // intruding on a public space and WILL BREAK in the future.
494     // One can hope that there is a more public API available by that time.
495     Qt::WindowFlags flags = widget ? widget->windowFlags() : Qt::WindowFlags(0);
496     if ((flags & Qt::CustomizeWindowHint)) {
497         if ((flags & (Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint
498                       | Qt::WindowMinimizeButtonHint | Qt::WindowTitleHint))
499             && !(flags & Qt::WindowMaximizeButtonHint))
500             wattr |= QtMacCustomizeWindow;
501     }
502
503     // If we haven't created the desktop widget, you have to pass the rectangle
504     // in "cocoa coordinates" (i.e., top points to the lower left coordinate).
505     // Otherwise, we do the conversion for you. Since we are the only ones that
506     // create the desktop widget, this is OK (but confusing).
507     NSRect geo = NSMakeRect(crect.left(),
508                             (qt_root_win != 0) ? flipYCoordinate(crect.bottom() + 1) : crect.top(),
509                             crect.width(), crect.height());
510     QMacCocoaAutoReleasePool pool;
511     OSWindowRef window;
512     switch (wclass) {
513     case kMovableModalWindowClass:
514     case kModalWindowClass:
515     case kSheetWindowClass:
516     case kFloatingWindowClass:
517     case kOverlayWindowClass:
518     case kHelpWindowClass: {
519         NSPanel *panel;
520         BOOL needFloating = NO;
521         BOOL worksWhenModal = widget && (widget->windowType() == Qt::Popup);
522         // Add in the extra flags if necessary.
523         switch (wclass) {
524         case kSheetWindowClass:
525             wattr |= NSDocModalWindowMask;
526             break;
527         case kFloatingWindowClass:
528         case kHelpWindowClass:
529             needFloating = YES;
530             wattr |= NSUtilityWindowMask;
531             break;
532         default:
533             break;
534         }
535         panel = [[QT_MANGLE_NAMESPACE(QCocoaPanel) alloc] QT_MANGLE_NAMESPACE(qt_initWithQWidget):widget contentRect:geo styleMask:wattr];
536         [panel setFloatingPanel:needFloating];
537         [panel setWorksWhenModal:worksWhenModal];
538         window = panel;
539         break;
540     }
541     case kDrawerWindowClass: {
542         NSDrawer *drawer = [[NSDrawer alloc] initWithContentSize:geo.size preferredEdge:NSMinXEdge];
543         [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] becomeDelegateForDrawer:drawer widget:widget];
544         QWidget *parentWidget = widget->parentWidget();
545         if (parentWidget)
546             [drawer setParentWindow:qt_mac_window_for(parentWidget)];
547         [drawer setLeadingOffset:0.0];
548         [drawer setTrailingOffset:25.0];
549         window = [[drawer contentView] window];  // Just to make sure we actually return a window
550         break;
551     }
552     default:
553         window = [[QT_MANGLE_NAMESPACE(QCocoaWindow) alloc] QT_MANGLE_NAMESPACE(qt_initWithQWidget):widget contentRect:geo styleMask:wattr];
554         break;
555     }
556     qt_syncCocoaTitleBarButtons(window, widget);
557     return window;
558 }
559
560 OSViewRef qt_mac_create_widget(QWidget *widget, QWidgetPrivate *widgetPrivate, OSViewRef parent)
561 {
562     QMacCocoaAutoReleasePool pool;
563     QT_MANGLE_NAMESPACE(QCocoaView) *view = [[QT_MANGLE_NAMESPACE(QCocoaView) alloc] initWithQWidget:widget widgetPrivate:widgetPrivate];
564
565 #ifdef ALIEN_DEBUG
566     qDebug() << "Creating NSView for" << widget;
567 #endif
568
569     if (view && parent)
570         [parent addSubview:view];
571     return view;
572 }
573
574 void qt_mac_unregister_widget()
575 {
576 }
577
578 void QWidgetPrivate::toggleDrawers(bool visible)
579 {
580     for (int i = 0; i < children.size(); ++i) {
581         register QObject *object = children.at(i);
582         if (!object->isWidgetType())
583             continue;
584         QWidget *widget = static_cast<QWidget*>(object);
585         if(qt_mac_is_macdrawer(widget)) {
586             bool oldState = widget->testAttribute(Qt::WA_WState_ExplicitShowHide);
587             if(visible) {
588                 if (!widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
589                     widget->show();
590             } else {
591                 widget->hide();
592                 if(!oldState)
593                     widget->setAttribute(Qt::WA_WState_ExplicitShowHide, false);
594             }
595         }
596     }
597 }
598
599 /*****************************************************************************
600   QWidgetPrivate member functions
601  *****************************************************************************/
602 bool QWidgetPrivate::qt_mac_update_sizer(QWidget *w, int up)
603 {
604     // I'm not sure what "up" is
605     if(!w || !w->isWindow())
606         return false;
607
608     QTLWExtra *topData = w->d_func()->topData();
609     QWExtra *extraData = w->d_func()->extraData();
610     // topData->resizer is only 4 bits, so subtracting -1 from zero causes bad stuff
611     // to happen, prevent that here (you really want the thing hidden).
612     if (up >= 0 || topData->resizer != 0)
613         topData->resizer += up;
614     OSWindowRef windowRef = qt_mac_window_for(OSViewRef(w->effectiveWinId()));
615     {
616     }
617     bool remove_grip = (topData->resizer || (w->windowFlags() & Qt::FramelessWindowHint)
618                         || (extraData->maxw && extraData->maxh &&
619                             extraData->maxw == extraData->minw && extraData->maxh == extraData->minh));
620     [windowRef setShowsResizeIndicator:!remove_grip];
621     return true;
622 }
623
624 void QWidgetPrivate::qt_clean_root_win()
625 {
626     QMacCocoaAutoReleasePool pool;
627     [qt_root_win release];
628     qt_root_win = 0;
629 }
630
631 bool QWidgetPrivate::qt_create_root_win()
632 {
633     if(qt_root_win)
634         return false;
635     const QSize desktopSize = qt_mac_desktopSize();
636     QRect desktopRect(QPoint(0, 0), desktopSize);
637     qt_root_win = qt_mac_create_window(0, kOverlayWindowClass, NSBorderlessWindowMask, desktopRect);
638     if(!qt_root_win)
639         return false;
640     qAddPostRoutine(qt_clean_root_win);
641     return true;
642 }
643
644 bool QWidgetPrivate::qt_widget_rgn(QWidget *widget, short wcode, RgnHandle rgn, bool force = false)
645 {
646     bool ret = false;
647     Q_UNUSED(widget);
648     Q_UNUSED(wcode);
649     Q_UNUSED(rgn);
650     Q_UNUSED(force);
651     return ret;
652 }
653
654 /*****************************************************************************
655   QWidget member functions
656  *****************************************************************************/
657 void QWidgetPrivate::determineWindowClass()
658 {
659     Q_Q(QWidget);
660 #if !defined(QT_NO_MAINWINDOW) && !defined(QT_NO_TOOLBAR)
661     // Make sure that QMainWindow has the MacWindowToolBarButtonHint when the
662     // unifiedTitleAndToolBarOnMac property is ON. This is to avoid reentry of
663     // setParent() triggered by the QToolBar::event(QEvent::ParentChange).
664     QMainWindow *mainWindow = qobject_cast<QMainWindow *>(q);
665     if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) {
666         data.window_flags |= Qt::MacWindowToolBarButtonHint;
667     }
668 #endif
669
670     const Qt::WindowType type = q->windowType();
671     Qt::WindowFlags &flags = data.window_flags;
672     const bool popup = (type == Qt::Popup);
673     if (type == Qt::ToolTip || type == Qt::SplashScreen || popup)
674         flags |= Qt::FramelessWindowHint;
675
676     WindowClass wclass = kSheetWindowClass;
677     if(qt_mac_is_macdrawer(q))
678         wclass = kDrawerWindowClass;
679     else if (q->testAttribute(Qt::WA_ShowModal) && flags & Qt::CustomizeWindowHint)
680         wclass = kDocumentWindowClass;
681     else if(popup || (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && type == Qt::SplashScreen))
682         wclass = kModalWindowClass;
683     else if(type == Qt::Dialog)
684         wclass = kMovableModalWindowClass;
685     else if(type == Qt::ToolTip)
686         wclass = kHelpWindowClass;
687     else if(type == Qt::Tool || (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5
688                                  && type == Qt::SplashScreen))
689         wclass = kFloatingWindowClass;
690     else if(q->testAttribute(Qt::WA_ShowModal))
691         wclass = kMovableModalWindowClass;
692     else
693         wclass = kDocumentWindowClass;
694
695     WindowAttributes wattr = NSBorderlessWindowMask;
696     if(qt_mac_is_macsheet(q)) {
697         //grp = GetWindowGroupOfClass(kMovableModalWindowClass);
698         wclass = kSheetWindowClass;
699         wattr = NSTitledWindowMask | NSResizableWindowMask;
700     } else {
701         // Shift things around a bit to get the correct window class based on the presence
702         // (or lack) of the border.
703         bool customize = flags & Qt::CustomizeWindowHint;
704         bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint)));
705         if (framelessWindow) {
706             if (wclass == kDocumentWindowClass) {
707                 wclass = kSimpleWindowClass;
708             } else if (wclass == kFloatingWindowClass) {
709                 wclass = kToolbarWindowClass;
710             } else if (wclass  == kMovableModalWindowClass) {
711                 wclass  = kModalWindowClass;
712             }
713         } else {
714             wattr |= NSTitledWindowMask;
715             if (wclass != kModalWindowClass)
716                 wattr |= NSResizableWindowMask;
717         }
718         // Only add extra decorations (well, buttons) for widgets that can have them
719         // and have an actual border we can put them on.
720         if (wclass != kModalWindowClass
721                 && wclass != kSheetWindowClass && wclass != kPlainWindowClass
722                 && !framelessWindow && wclass != kDrawerWindowClass
723                 && wclass != kHelpWindowClass) {
724             if (flags & Qt::WindowMinimizeButtonHint)
725                 wattr |= NSMiniaturizableWindowMask;
726             if (flags & Qt::WindowSystemMenuHint || flags & Qt::WindowCloseButtonHint)
727                 wattr |= NSClosableWindowMask;
728         } else {
729             // Clear these hints so that we aren't call them on invalid windows
730             flags &= ~(Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint
731                        | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint);
732         }
733     }
734     if (q->testAttribute(Qt::WA_MacBrushedMetal))
735         wattr |= NSTexturedBackgroundWindowMask;
736
737 #ifdef DEBUG_WINDOW_CREATE
738 #define ADD_DEBUG_WINDOW_NAME(x) { x, #x }
739     struct {
740         UInt32 tag;
741         const char *name;
742     } known_attribs[] = {
743         ADD_DEBUG_WINDOW_NAME(kWindowCompositingAttribute),
744         ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
745         ADD_DEBUG_WINDOW_NAME(kWindowMetalAttribute),
746         ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
747         ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
748         ADD_DEBUG_WINDOW_NAME(kWindowCollapseBoxAttribute),
749         ADD_DEBUG_WINDOW_NAME(kWindowHorizontalZoomAttribute),
750         ADD_DEBUG_WINDOW_NAME(kWindowVerticalZoomAttribute),
751         ADD_DEBUG_WINDOW_NAME(kWindowResizableAttribute),
752         ADD_DEBUG_WINDOW_NAME(kWindowNoActivatesAttribute),
753         ADD_DEBUG_WINDOW_NAME(kWindowNoUpdatesAttribute),
754         ADD_DEBUG_WINDOW_NAME(kWindowOpaqueForEventsAttribute),
755         ADD_DEBUG_WINDOW_NAME(kWindowLiveResizeAttribute),
756         ADD_DEBUG_WINDOW_NAME(kWindowCloseBoxAttribute),
757         ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
758         { 0, 0 }
759     }, known_classes[] = {
760         ADD_DEBUG_WINDOW_NAME(kHelpWindowClass),
761         ADD_DEBUG_WINDOW_NAME(kPlainWindowClass),
762         ADD_DEBUG_WINDOW_NAME(kDrawerWindowClass),
763         ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
764         ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
765         ADD_DEBUG_WINDOW_NAME(kSheetWindowClass),
766         ADD_DEBUG_WINDOW_NAME(kFloatingWindowClass),
767         ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
768         ADD_DEBUG_WINDOW_NAME(kDocumentWindowClass),
769         ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
770         ADD_DEBUG_WINDOW_NAME(kMovableModalWindowClass),
771         ADD_DEBUG_WINDOW_NAME(kModalWindowClass),
772         { 0, 0 }
773     };
774     qDebug("Qt: internal: ************* Creating new window %p (%s::%s)", q, q->metaObject()->className(),
775             q->objectName().toLocal8Bit().constData());
776     bool found_class = false;
777     for(int i = 0; known_classes[i].name; i++) {
778         if(wclass == known_classes[i].tag) {
779             found_class = true;
780             qDebug("Qt: internal: ** Class: %s", known_classes[i].name);
781             break;
782         }
783     }
784     if(!found_class)
785         qDebug("Qt: internal: !! Class: Unknown! (%d)", (int)wclass);
786     if(wattr) {
787         WindowAttributes tmp_wattr = wattr;
788         qDebug("Qt: internal: ** Attributes:");
789         for(int i = 0; tmp_wattr && known_attribs[i].name; i++) {
790             if((tmp_wattr & known_attribs[i].tag) == known_attribs[i].tag) {
791                 tmp_wattr ^= known_attribs[i].tag;
792             }
793         }
794         if(tmp_wattr)
795             qDebug("Qt: internal: !! Attributes: Unknown (%d)", (int)tmp_wattr);
796     }
797 #endif
798
799     topData()->wclass = wclass;
800     topData()->wattr = wattr;
801 }
802
803 #undef ADD_DEBUG_WINDOW_NAME
804
805 void QWidgetPrivate::setWindowLevel()
806 {
807     Q_Q(QWidget);
808     const QWidget * const windowParent = q->window()->parentWidget();
809     const QWidget * const primaryWindow = windowParent ? windowParent->window() : 0;
810     NSInteger winLevel = -1;
811
812     if (q->windowType() == Qt::Popup) {
813         winLevel = NSPopUpMenuWindowLevel;
814         // Popup should be in at least the same level as its parent.
815         if (primaryWindow) {
816             OSWindowRef parentRef = qt_mac_window_for(primaryWindow);
817             winLevel = qMax([parentRef level], winLevel);
818         }
819     } else if (q->windowType() == Qt::Tool) {
820         winLevel = NSFloatingWindowLevel;
821     } else if (q->windowType() == Qt::Dialog) {
822         // Correct modality level (NSModalPanelWindowLevel) will be
823         // set by cocoa when creating a modal session later.
824         winLevel = NSNormalWindowLevel;
825     }
826
827     // StayOnTop window should appear above Tool windows.
828     if (data.window_flags & Qt::WindowStaysOnTopHint)
829         winLevel = NSPopUpMenuWindowLevel;
830     // Tooltips should appear above StayOnTop windows.
831     if (q->windowType() == Qt::ToolTip)
832         winLevel = NSScreenSaverWindowLevel;
833     // All other types are Normal level.
834     if (winLevel == -1)
835         winLevel = NSNormalWindowLevel;
836     [qt_mac_window_for(q) setLevel:winLevel];
837 }
838
839 void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWindowRef)
840 {
841     Q_Q(QWidget);
842     QMacCocoaAutoReleasePool pool;
843     NSWindow *windowRef = static_cast<NSWindow *>(voidWindowRef);
844     const Qt::WindowType type = q->windowType();
845     Qt::WindowFlags &flags = data.window_flags;
846     QWidget *parentWidget = q->parentWidget();
847
848     const bool popup = (type == Qt::Popup);
849     const bool dialog = (type == Qt::Dialog
850                          || type == Qt::Sheet
851                          || type == Qt::Drawer
852                          || (flags & Qt::MSWindowsFixedSizeDialogHint));
853     QTLWExtra *topExtra = topData();
854
855     if ((popup || type == Qt::Tool || type == Qt::ToolTip) && !q->isModal()) {
856         [windowRef setHidesOnDeactivate:YES];
857     } else {
858         [windowRef setHidesOnDeactivate:NO];
859     }
860     if (q->testAttribute(Qt::WA_MacNoShadow))
861         [windowRef setHasShadow:NO];
862     else
863         [windowRef setHasShadow:YES];
864     Q_UNUSED(parentWidget);
865     Q_UNUSED(dialog);
866
867     data.fstrut_dirty = true; // when we create a toplevel widget, the frame strut should be dirty
868
869     OSViewRef nsview = (OSViewRef)data.winid;
870     if (!nsview) {
871         nsview = qt_mac_create_widget(q, this, 0);
872         setWinId(WId(nsview));
873     }
874     [windowRef setContentView:nsview];
875     [nsview setHidden:NO];
876     transferChildren();
877
878     // Tell Cocoa explicit that we wan't the view to receive key events
879     // (regardless of focus policy) because this is how it works on other
880     // platforms (and in the carbon port):
881     [windowRef makeFirstResponder:nsview];
882
883     if (topExtra->posFromMove) {
884         updateFrameStrut();
885
886         const QRect &fStrut = frameStrut();
887         const QRect &crect = data.crect;
888         const QRect frameRect(QPoint(crect.left(), crect.top()),
889                               QSize(fStrut.left() + fStrut.right() + crect.width(),
890                                     fStrut.top() + fStrut.bottom() + crect.height()));
891         NSRect cocoaFrameRect = NSMakeRect(frameRect.x(), flipYCoordinate(frameRect.bottom() + 1),
892                                            frameRect.width(), frameRect.height());
893         [windowRef setFrame:cocoaFrameRect display:NO];
894         topExtra->posFromMove = false;
895     }
896
897     if (q->testAttribute(Qt::WA_WState_WindowOpacitySet)){
898         q->setWindowOpacity(topExtra->opacity / 255.0f);
899     } else if (qt_mac_is_macsheet(q)){
900         CGFloat alpha = [qt_mac_window_for(q) alphaValue];
901         if (alpha >= 1.0) {
902             q->setWindowOpacity(0.95f);
903             q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
904         }
905     } else{
906         // If the window has been recreated after beeing e.g. a sheet,
907         // make sure that we don't report a faulty opacity:
908         q->setWindowOpacity(1.0f);
909         q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
910     }
911
912     // Its more performant to handle the mouse cursor
913     // ourselves, expecially when using alien widgets:
914     [windowRef disableCursorRects];
915
916     setWindowLevel();
917     macUpdateHideOnSuspend();
918     macUpdateOpaqueSizeGrip();
919     macUpdateIgnoreMouseEvents();
920     setWindowTitle_helper(extra->topextra->caption);
921     setWindowIconText_helper(extra->topextra->iconText);
922     setWindowModified_sys(q->isWindowModified());
923     updateFrameStrut();
924     syncCocoaMask();
925     macUpdateIsOpaque();
926     qt_mac_update_sizer(q);
927     applyMaxAndMinSizeOnWindow();
928 }
929
930
931 /*
932  Recreates widget window. Useful if immutable
933  properties for it has changed.
934  */
935 void QWidgetPrivate::recreateMacWindow()
936 {
937     Q_Q(QWidget);
938     OSViewRef myView = qt_mac_nativeview_for(q);
939     OSWindowRef oldWindow = qt_mac_window_for(myView);
940     QMacCocoaAutoReleasePool pool;
941     [myView removeFromSuperview];
942     determineWindowClass();
943     createWindow_sys();
944     if (NSToolbar *toolbar = [oldWindow toolbar]) {
945         OSWindowRef newWindow = qt_mac_window_for(myView);
946         [newWindow setToolbar:toolbar];
947         [toolbar setVisible:[toolbar isVisible]];
948     }
949     if ([oldWindow isVisible]){
950         if ([oldWindow isSheet])
951             [NSApp endSheet:oldWindow];
952         [oldWindow orderOut:oldWindow];
953         show_sys();
954     }
955
956     // Release the window after creating the new window, because releasing it early
957     // may cause the app to quit ("close on last window closed attribute")
958     qt_mac_destructWindow(oldWindow);
959 }
960
961 void QWidgetPrivate::createWindow_sys()
962 {
963     Q_Q(QWidget);
964     Qt::WindowFlags &flags = data.window_flags;
965     QWidget *parentWidget = q->parentWidget();
966
967     QTLWExtra *topExtra = topData();
968     if (topExtra->embedded)
969         return;  // Simply return because this view "is" the top window.
970     quint32 wattr = topExtra->wattr;
971
972     if(parentWidget && (parentWidget->window()->windowFlags() & Qt::WindowStaysOnTopHint)) // If our parent has Qt::WStyle_StaysOnTop, so must we
973         flags |= Qt::WindowStaysOnTopHint;
974
975     data.fstrut_dirty = true;
976
977     OSWindowRef windowRef = qt_mac_create_window(q, topExtra->wclass, wattr, data.crect);
978     if (windowRef == 0)
979         qWarning("QWidget: Internal error: %s:%d: If you reach this error please contact Qt Support and include the\n"
980                 "      WidgetFlags used in creating the widget.", __FILE__, __LINE__);
981     finishCreateWindow_sys_Cocoa(windowRef);
982 }
983
984 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
985 {
986     Q_Q(QWidget);
987     QMacCocoaAutoReleasePool pool;
988
989     OSViewRef destroyid = 0;
990
991     Qt::WindowType type = q->windowType();
992     Qt::WindowFlags flags = data.window_flags;
993     QWidget *parentWidget = q->parentWidget();
994
995     bool topLevel = (flags & Qt::Window);
996     bool popup = (type == Qt::Popup);
997     bool dialog = (type == Qt::Dialog
998                    || type == Qt::Sheet
999                    || type == Qt::Drawer
1000                    || (flags & Qt::MSWindowsFixedSizeDialogHint));
1001     bool desktop = (type == Qt::Desktop);
1002
1003     // Determine this early for top-levels so, we can use it later.
1004     if (topLevel)
1005         determineWindowClass();
1006
1007     if (desktop) {
1008         QSize desktopSize = qt_mac_desktopSize();
1009         q->setAttribute(Qt::WA_WState_Visible);
1010         data.crect.setRect(0, 0, desktopSize.width(), desktopSize.height());
1011         dialog = popup = false;                  // force these flags off
1012     } else {
1013         if (topLevel && (type != Qt::Drawer)) {
1014             if (QDesktopWidget *dsk = QApplication::desktop()) { // calc pos/size from screen
1015                 const bool wasResized = q->testAttribute(Qt::WA_Resized);
1016                 const bool wasMoved = q->testAttribute(Qt::WA_Moved);
1017                 int deskn = dsk->primaryScreen();
1018                 if (parentWidget && parentWidget->windowType() != Qt::Desktop)
1019                     deskn = dsk->screenNumber(parentWidget);
1020                 QRect screenGeo = dsk->screenGeometry(deskn);
1021                 if (!wasResized) {
1022                     NSRect newRect = [NSWindow frameRectForContentRect:NSMakeRect(0, 0,
1023                                                                   screenGeo.width() / 2.,
1024                                                                   4 * screenGeo.height() / 10.)
1025                                         styleMask:topData()->wattr];
1026                     data.crect.setSize(QSize(newRect.size.width, newRect.size.height));
1027                     // Constrain to minimums and maximums we've set
1028                     if (extra->minw > 0)
1029                         data.crect.setWidth(qMax(extra->minw, data.crect.width()));
1030                     if (extra->minh > 0)
1031                         data.crect.setHeight(qMax(extra->minh, data.crect.height()));
1032                     if (extra->maxw > 0)
1033                         data.crect.setWidth(qMin(extra->maxw, data.crect.width()));
1034                     if (extra->maxh > 0)
1035                         data.crect.setHeight(qMin(extra->maxh, data.crect.height()));
1036                 }
1037                 if (!wasMoved && !q->testAttribute(Qt::WA_DontShowOnScreen))
1038                     data.crect.moveTopLeft(QPoint(screenGeo.width()/4,
1039                                                   3 * screenGeo.height() / 10));
1040             }
1041         }
1042     }
1043
1044
1045     if(!window)                              // always initialize
1046         initializeWindow=true;
1047
1048     hd = 0;
1049     if(window) {                                // override the old window (with a new NSView)
1050         OSViewRef nativeView = OSViewRef(window);
1051         OSViewRef parent = 0;
1052         [nativeView retain];
1053         if (destroyOldWindow)
1054             destroyid = qt_mac_nativeview_for(q);
1055         bool transfer = false;
1056         setWinId((WId)nativeView);
1057         if(topLevel) {
1058             for(int i = 0; i < 2; ++i) {
1059                 if(i == 1) {
1060                     if(!initializeWindow)
1061                         break;
1062                     createWindow_sys();
1063                 }
1064                 if(OSWindowRef windowref = qt_mac_window_for(nativeView)) {
1065                     [windowref retain];
1066                     if (initializeWindow) {
1067                         parent = qt_mac_get_contentview_for(windowref);
1068                     } else {
1069                         parent = [nativeView superview];
1070                     }
1071                     break;
1072                 }
1073             }
1074             if(!parent)
1075                 transfer = true;
1076         } else if (parentWidget) {
1077             // I need to be added to my parent, therefore my parent needs an NSView
1078             // Alien note: a 'window' was supplied as argument, meaning this widget
1079             // is not alien. So therefore the parent cannot be alien either.
1080             parentWidget->createWinId();
1081             parent = qt_mac_nativeview_for(parentWidget);
1082         }
1083         if(parent != nativeView && parent) {
1084             [parent addSubview:nativeView];
1085         }
1086         if(transfer)
1087             transferChildren();
1088         data.fstrut_dirty = true; // we'll re calculate this later
1089         q->setAttribute(Qt::WA_WState_Visible,
1090                         ![nativeView isHidden]
1091                         );
1092         if(initializeWindow) {
1093             NSRect bounds = NSMakeRect(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
1094             [nativeView setFrame:bounds];
1095             q->setAttribute(Qt::WA_WState_Visible, [nativeView isHidden]);
1096         }
1097     } else if (desktop) {                        // desktop widget
1098         if (!qt_root_win)
1099             QWidgetPrivate::qt_create_root_win();
1100         Q_ASSERT(qt_root_win);
1101         WId rootWinID = 0;
1102         [qt_root_win retain];
1103         if (OSViewRef rootContentView = [qt_root_win contentView]) {
1104             rootWinID = (WId)rootContentView;
1105             [rootContentView retain];
1106         }
1107         setWinId(rootWinID);
1108     } else if (topLevel) {
1109         determineWindowClass();
1110         if(OSViewRef osview = qt_mac_create_widget(q, this, 0)) {
1111             NSRect bounds = NSMakeRect(data.crect.x(), flipYCoordinate(data.crect.y()),
1112                                        data.crect.width(), data.crect.height());
1113             [osview setFrame:bounds];
1114             setWinId((WId)osview);
1115         }
1116     } else {
1117         data.fstrut_dirty = false; // non-toplevel widgets don't have a frame, so no need to update the strut
1118
1119         if (q->testAttribute(Qt::WA_NativeWindow) == false || q->internalWinId() != 0) {
1120             // INVARIANT: q is Alien, and we should not create an NSView to back it up.
1121         } else
1122         if (OSViewRef osview = qt_mac_create_widget(q, this, qt_mac_nativeview_for(parentWidget))) {
1123             NSRect bounds = NSMakeRect(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
1124             [osview setFrame:bounds];
1125             setWinId((WId)osview);
1126             if (q->isVisible()) {
1127                 // If q were Alien before, but now became native (e.g. if a call to
1128                 // winId was done from somewhere), we need to show the view immidiatly:
1129                 QMacCocoaAutoReleasePool pool;
1130                 [osview setHidden:NO];
1131             }
1132         }
1133     }
1134
1135     updateIsOpaque();
1136
1137     if (q->testAttribute(Qt::WA_DropSiteRegistered))
1138         registerDropSite(true);
1139     if (q->hasFocus())
1140         setFocus_sys();
1141     if (!topLevel && initializeWindow)
1142         setWSGeometry();
1143     if (destroyid)
1144         qt_mac_destructView(destroyid);
1145 }
1146
1147 /*!
1148     Returns the QuickDraw handle of the widget. Use of this function is not
1149     portable. This function will return 0 if QuickDraw is not supported, or
1150     if the handle could not be created.
1151
1152     \warning This function is only available on Mac OS X.
1153 */
1154
1155 Qt::HANDLE
1156 QWidget::macQDHandle() const
1157 {
1158     return 0;
1159 }
1160
1161 /*!
1162   Returns the CoreGraphics handle of the widget. Use of this function is
1163   not portable. This function will return 0 if no painter context can be
1164   established, or if the handle could not be created.
1165
1166   \warning This function is only available on Mac OS X.
1167 */
1168 Qt::HANDLE
1169 QWidget::macCGHandle() const
1170 {
1171     return handle();
1172 }
1173
1174 void qt_mac_updateParentUnderAlienWidget(QWidget *alienWidget)
1175 {
1176     QWidget *nativeParent = alienWidget->nativeParentWidget();
1177     if (!nativeParent)
1178         return;
1179
1180     QPoint globalPos = alienWidget->mapToGlobal(QPoint(0, 0));
1181     QRect dirtyRect = QRect(nativeParent->mapFromGlobal(globalPos), alienWidget->size());
1182     nativeParent->update(dirtyRect);
1183 }
1184
1185 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
1186 {
1187     Q_D(QWidget);
1188     QMacCocoaAutoReleasePool pool;
1189     d->aboutToDestroy();
1190     if (!isWindow() && parentWidget())
1191         parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
1192     if (!internalWinId())
1193         qt_mac_updateParentUnderAlienWidget(this);
1194     d->deactivateWidgetCleanup();
1195     qt_mac_event_release(this);
1196     if(testAttribute(Qt::WA_WState_Created)) {
1197         setAttribute(Qt::WA_WState_Created, false);
1198         QObjectList chldrn = children();
1199         for(int i = 0; i < chldrn.size(); i++) {  // destroy all widget children
1200             QObject *obj = chldrn.at(i);
1201             if(obj->isWidgetType())
1202                 static_cast<QWidget*>(obj)->destroy(destroySubWindows, destroySubWindows);
1203         }
1204         if(mac_mouse_grabber == this)
1205             releaseMouse();
1206         if(mac_keyboard_grabber == this)
1207             releaseKeyboard();
1208
1209         if(testAttribute(Qt::WA_ShowModal))          // just be sure we leave modal
1210             QApplicationPrivate::leaveModal(this);
1211         else if((windowType() == Qt::Popup))
1212             qApp->d_func()->closePopup(this);
1213         if (destroyWindow) {
1214             if(OSViewRef hiview = qt_mac_nativeview_for(this)) {
1215                 OSWindowRef window = 0;
1216                 NSDrawer *drawer = nil;
1217                 if (qt_mac_is_macdrawer(this)) {
1218                     drawer = qt_mac_drawer_for(this);
1219                 } else
1220                 if (isWindow())
1221                     window = qt_mac_window_for(hiview);
1222
1223                 // Because of how "destruct" works, we have to do just a normal release for the root_win.
1224                 if (window && window == qt_root_win) {
1225                     [hiview release];
1226                 } else {
1227                     qt_mac_destructView(hiview);
1228                 }
1229                 if (drawer)
1230                     qt_mac_destructDrawer(drawer);
1231                 if (window)
1232                     qt_mac_destructWindow(window);
1233             }
1234         }
1235         QT_TRY {
1236             d->setWinId(0);
1237         } QT_CATCH (const std::bad_alloc &) {
1238             // swallow - destructors must not throw
1239         }
1240     }
1241 }
1242
1243 void QWidgetPrivate::transferChildren()
1244 {
1245     Q_Q(QWidget);
1246     if (!q->internalWinId())
1247         return;  // Can't add any views anyway
1248
1249     QObjectList chlist = q->children();
1250     for (int i = 0; i < chlist.size(); ++i) {
1251         QObject *obj = chlist.at(i);
1252         if (obj->isWidgetType()) {
1253             QWidget *w = (QWidget *)obj;
1254             if (!w->isWindow()) {
1255                 // This seems weird, no need to call it in a loop right?
1256                 if (!topData()->caption.isEmpty())
1257                     setWindowTitle_helper(extra->topextra->caption);
1258                 if (w->internalWinId()) {
1259                     // New NSWindows get an extra reference when drops are
1260                     // registered (at least in 10.5) which means that we may
1261                     // access the window later and get a crash (becasue our
1262                     // widget is dead). Work around this be having the drop
1263                     // site disabled until it is part of the new hierarchy.
1264                     bool oldRegistered = w->testAttribute(Qt::WA_DropSiteRegistered);
1265                     w->setAttribute(Qt::WA_DropSiteRegistered, false);
1266                     [qt_mac_nativeview_for(w) retain];
1267                     [qt_mac_nativeview_for(w) removeFromSuperview];
1268                     [qt_mac_nativeview_for(q) addSubview:qt_mac_nativeview_for(w)];
1269                     [qt_mac_nativeview_for(w) release];
1270                     w->setAttribute(Qt::WA_DropSiteRegistered, oldRegistered);
1271                 }
1272             }
1273         }
1274     }
1275 }
1276
1277 void QWidgetPrivate::setSubWindowStacking(bool set)
1278 {
1279     // After hitting too many unforeseen bugs trying to put Qt on top of the cocoa child
1280     // window API, we have decided to revert this behaviour as much as we can. We
1281     // therefore now only allow child windows to exist for children of modal dialogs.
1282     static bool use_behaviour_qt473 = !qgetenv("QT_MAC_USE_CHILDWINDOWS").isEmpty();
1283
1284     // This will set/remove a visual relationship between parent and child on screen.
1285     // The reason for doing this is to ensure that a child always stacks infront of
1286     // its parent. Unfortunatly is turns out that [NSWindow addChildWindow] has
1287     // several unwanted side-effects, one of them being the moving of a child when
1288     // moving the parent, which we choose to accept. A way tougher side-effect is
1289     // that Cocoa will hide the parent if you hide the child. And in the case of
1290     // a tool window, since it will normally hide when you deactivate the
1291     // application, Cocoa will hide the parent upon deactivate as well. The result often
1292     // being no more visible windows on screen. So, to make a long story short, we only
1293     // allow parent-child relationships between windows that both are either a plain window
1294     // or a dialog.
1295
1296     Q_Q(QWidget);
1297     if (!q->isWindow())
1298         return;
1299     NSWindow *qwin = [qt_mac_nativeview_for(q) window];
1300     if (!qwin)
1301         return;
1302     Qt::WindowType qtype = q->windowType();
1303     if (set && !(qtype == Qt::Window || qtype == Qt::Dialog))
1304         return;
1305     if (set && ![qwin isVisible])
1306         return;
1307
1308     if (QWidget *parent = q->parentWidget()) {
1309         if (NSWindow *pwin = [qt_mac_nativeview_for(parent) window]) {
1310             if (set) {
1311                 Qt::WindowType ptype = parent->window()->windowType();
1312                 if ([pwin isVisible]
1313                     && (ptype == Qt::Window || ptype == Qt::Dialog)
1314                     && ![qwin parentWindow]
1315                     && (use_behaviour_qt473 || parent->windowModality() == Qt::ApplicationModal)) {
1316                     NSInteger level = [qwin level];
1317                     [pwin addChildWindow:qwin ordered:NSWindowAbove];
1318                     if ([qwin level] < level)
1319                         [qwin setLevel:level];
1320                 }
1321             } else {
1322                 [pwin removeChildWindow:qwin];
1323             }
1324         }
1325     }
1326
1327     // Only set-up child windows for q if q is modal:
1328     if (set && !use_behaviour_qt473 && q->windowModality() != Qt::ApplicationModal)
1329         return;
1330
1331     QObjectList widgets = q->children();
1332     for (int i=0; i<widgets.size(); ++i) {
1333         QWidget *child = qobject_cast<QWidget *>(widgets.at(i));
1334         if (child && child->isWindow()) {
1335             if (NSWindow *cwin = [qt_mac_nativeview_for(child) window]) {
1336                 if (set) {
1337                     Qt::WindowType ctype = child->window()->windowType();
1338                     if ([cwin isVisible] && (ctype == Qt::Window || ctype == Qt::Dialog) && ![cwin parentWindow]) {
1339                         NSInteger level = [cwin level];
1340                         [qwin addChildWindow:cwin ordered:NSWindowAbove];
1341                         if ([cwin level] < level)
1342                             [cwin setLevel:level];
1343                     }
1344                 } else {
1345                     [qwin removeChildWindow:qt_mac_window_for(child)];
1346                 }
1347             }
1348         }
1349     }
1350 }
1351
1352 void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
1353 {
1354     Q_Q(QWidget);
1355     QMacCocoaAutoReleasePool pool;
1356     QTLWExtra *topData = maybeTopData();
1357     bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
1358     bool wasWindow = q->isWindow();
1359     OSViewRef old_id = 0;
1360
1361     if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
1362         q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
1363
1364     // Maintain the glWidgets list on parent change: remove "our" gl widgets
1365     // from the list on the old parent and grandparents.
1366     if (glWidgets.isEmpty() == false) {
1367         QWidget *current = q->parentWidget();
1368         while (current) {
1369             for (QList<QWidgetPrivate::GlWidgetInfo>::const_iterator it = glWidgets.constBegin();
1370                  it != glWidgets.constEnd(); ++it)
1371                 current->d_func()->glWidgets.removeAll(*it);
1372
1373             if (current->isWindow())
1374                 break;
1375             current = current->parentWidget();
1376         }
1377     }
1378
1379     bool oldToolbarVisible = false;
1380     NSDrawer *oldDrawer = nil;
1381     NSToolbar *oldToolbar = 0;
1382     if (wasCreated && !(q->windowType() == Qt::Desktop)) {
1383         old_id = qt_mac_nativeview_for(q);
1384         if (qt_mac_is_macdrawer(q)) {
1385             oldDrawer = qt_mac_drawer_for(q);
1386         }
1387         if (wasWindow) {
1388             OSWindowRef oldWindow = qt_mac_window_for(old_id);
1389             oldToolbar = [oldWindow toolbar];
1390             if (oldToolbar) {
1391                 [oldToolbar retain];
1392                 oldToolbarVisible = [oldToolbar isVisible];
1393                 [oldWindow setToolbar:nil];
1394             }
1395         }
1396     }
1397     QWidget* oldtlw = q->window();
1398
1399     if (q->testAttribute(Qt::WA_DropSiteRegistered))
1400         q->setAttribute(Qt::WA_DropSiteRegistered, false);
1401
1402     //recreate and setup flags
1403     QObjectPrivate::setParent_helper(parent);
1404     bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
1405     if (wasCreated && !qt_isGenuineQWidget(q))
1406         return;
1407
1408     if (!q->testAttribute(Qt::WA_WState_WindowOpacitySet)) {
1409         q->setWindowOpacity(1.0f);
1410         q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
1411     }
1412
1413     setWinId(0); //do after the above because they may want the id
1414
1415     data.window_flags = f;
1416     q->setAttribute(Qt::WA_WState_Created, false);
1417     q->setAttribute(Qt::WA_WState_Visible, false);
1418     q->setAttribute(Qt::WA_WState_Hidden, false);
1419     adjustFlags(data.window_flags, q);
1420     // keep compatibility with previous versions, we need to preserve the created state.
1421     // (but we recreate the winId for the widget being reparented, again for compatibility,
1422     // unless this is an alien widget. )
1423     const bool nonWindowWithCreatedParent = !q->isWindow() && parent->testAttribute(Qt::WA_WState_Created);
1424     const bool nativeWidget = q->internalWinId() != 0;
1425     if (wasCreated || (nativeWidget && nonWindowWithCreatedParent)) {
1426         createWinId();
1427         if (q->isWindow()) {
1428             // Simply transfer our toolbar over. Everything should stay put, unlike in Carbon.
1429             if (oldToolbar && !(f & Qt::FramelessWindowHint)) {
1430                 OSWindowRef newWindow = qt_mac_window_for(q);
1431                 [newWindow setToolbar:oldToolbar];
1432                 [oldToolbar release];
1433                 [oldToolbar setVisible:oldToolbarVisible];
1434             }
1435         }
1436     }
1437     if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
1438         q->setAttribute(Qt::WA_WState_Hidden);
1439     q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
1440
1441     if (wasCreated) {
1442         transferChildren();
1443
1444         if (topData &&
1445                 (!topData->caption.isEmpty() || !topData->filePath.isEmpty()))
1446             setWindowTitle_helper(q->windowTitle());
1447     }
1448
1449     if (q->testAttribute(Qt::WA_AcceptDrops)
1450         || (!q->isWindow() && q->parentWidget()
1451             && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)))
1452         q->setAttribute(Qt::WA_DropSiteRegistered, true);
1453
1454     //cleanup
1455     if (old_id) { //don't need old window anymore
1456         OSWindowRef window = (oldtlw == q) ? qt_mac_window_for(old_id) : 0;
1457         qt_mac_destructView(old_id);
1458
1459         if (oldDrawer) {
1460             qt_mac_destructDrawer(oldDrawer);
1461         } else
1462         if (window)
1463             qt_mac_destructWindow(window);
1464     }
1465
1466     // Maintain the glWidgets list on parent change: add "our" gl widgets
1467     // to the list on the new parent and grandparents.
1468     if (glWidgets.isEmpty() == false) {
1469         QWidget *current = q->parentWidget();
1470         while (current) {
1471             current->d_func()->glWidgets += glWidgets;
1472             if (current->isWindow())
1473                 break;
1474             current = current->parentWidget();
1475         }
1476     }
1477     invalidateBuffer(q->rect());
1478     qt_event_request_window_change(q);
1479 }
1480
1481 QPoint QWidget::mapToGlobal(const QPoint &pos) const
1482 {
1483     Q_D(const QWidget);
1484     if (!internalWinId()) {
1485         QPoint p = pos + data->crect.topLeft();
1486         return isWindow() ?  p : parentWidget()->mapToGlobal(p);
1487     }
1488     QPoint tmp = d->mapToWS(pos);
1489     NSPoint hi_pos = NSMakePoint(tmp.x(), tmp.y());
1490     hi_pos = [qt_mac_nativeview_for(this) convertPoint:hi_pos toView:nil];
1491     NSRect win_rect = [qt_mac_window_for(this) frame];
1492     hi_pos.x += win_rect.origin.x;
1493     hi_pos.y += win_rect.origin.y;
1494     // If we aren't the desktop we need to flip, if you flip the desktop on itself, you get the other problem.
1495     return ((window()->windowFlags() & Qt::Desktop) == Qt::Desktop) ? QPointF(hi_pos.x, hi_pos.y).toPoint()
1496                                                                     : flipPoint(hi_pos).toPoint();
1497 }
1498
1499 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
1500 {
1501     Q_D(const QWidget);
1502     if (!internalWinId()) {
1503         QPoint p = isWindow() ?  pos : parentWidget()->mapFromGlobal(pos);
1504         return p - data->crect.topLeft();
1505     }
1506     NSRect win_rect = [qt_mac_window_for(this) frame];
1507     // The Window point is in "Cocoa coordinates," but the view is in "Qt coordinates"
1508     // so make sure to keep them in sync.
1509     NSPoint hi_pos = NSMakePoint(pos.x()-win_rect.origin.x,
1510                                  flipYCoordinate(pos.y())-win_rect.origin.y);
1511     hi_pos = [qt_mac_nativeview_for(this) convertPoint:hi_pos fromView:0];
1512     return d->mapFromWS(QPoint(qRound(hi_pos.x), qRound(hi_pos.y)));
1513 }
1514
1515 void QWidgetPrivate::updateSystemBackground()
1516 {
1517 }
1518
1519 void QWidgetPrivate::setCursor_sys(const QCursor &)
1520 {
1521     qt_mac_update_cursor();
1522 }
1523
1524 void QWidgetPrivate::unsetCursor_sys()
1525 {
1526     qt_mac_update_cursor();
1527 }
1528
1529 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
1530 {
1531     Q_Q(QWidget);
1532     if (q->isWindow()) {
1533         QMacCocoaAutoReleasePool pool;
1534         [qt_mac_window_for(q) setTitle:qt_mac_QStringToNSString(caption)];
1535     }
1536 }
1537
1538 void QWidgetPrivate::setWindowModified_sys(bool mod)
1539 {
1540     Q_Q(QWidget);
1541     if (q->isWindow() && q->testAttribute(Qt::WA_WState_Created)) {
1542         [qt_mac_window_for(q) setDocumentEdited:mod];
1543     }
1544 }
1545
1546 void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath)
1547 {
1548     Q_Q(QWidget);
1549     QMacCocoaAutoReleasePool pool;
1550     QFileInfo fi(filePath);
1551     [qt_mac_window_for(q) setRepresentedFilename:fi.exists() ? qt_mac_QStringToNSString(filePath) : @""];
1552 }
1553
1554 void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
1555 {
1556     Q_Q(QWidget);
1557
1558     if (!q->testAttribute(Qt::WA_WState_Created))
1559         return;
1560
1561     QTLWExtra *topData = this->topData();
1562     if (topData->iconPixmap && !forceReset) // already set
1563         return;
1564
1565     QIcon icon = q->windowIcon();
1566     QPixmap *pm = 0;
1567     if (!icon.isNull()) {
1568         // now create the extra
1569         if (!topData->iconPixmap) {
1570             pm = new QPixmap(icon.pixmap(QSize(22, 22)));
1571             topData->iconPixmap = pm;
1572         } else {
1573             pm = topData->iconPixmap;
1574         }
1575     }
1576     if (q->isWindow()) {
1577         QMacCocoaAutoReleasePool pool;
1578         if (icon.isNull())
1579             return;
1580         NSButton *iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
1581         if (iconButton == nil) {
1582             QCFString string(q->windowTitle());
1583             const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
1584             [qt_mac_window_for(q) setRepresentedURL:[NSURL fileURLWithPath:const_cast<NSString *>(tmpString)]];
1585             iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
1586         }
1587         if (icon.isNull()) {
1588             [iconButton setImage:nil];
1589         } else {
1590             QPixmap scaled = pm->scaled(QSize(16,16), Qt::KeepAspectRatio, Qt::SmoothTransformation);
1591             NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(scaled));
1592             [iconButton setImage:image];
1593             [image release];
1594         }
1595     }
1596 }
1597
1598 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
1599 {
1600     Q_Q(QWidget);
1601     if(q->isWindow() && !iconText.isEmpty()) {
1602         QMacCocoaAutoReleasePool pool;
1603         [qt_mac_window_for(q) setMiniwindowTitle:qt_mac_QStringToNSString(iconText)];
1604     }
1605 }
1606
1607 void QWidget::grabMouse()
1608 {
1609     if(isVisible() && !qt_nograb()) {
1610         if(mac_mouse_grabber)
1611             mac_mouse_grabber->releaseMouse();
1612         mac_mouse_grabber=this;
1613         qt_mac_setMouseGrabCursor(true);
1614     }
1615 }
1616
1617 #ifndef QT_NO_CURSOR
1618 void QWidget::grabMouse(const QCursor &cursor)
1619 {
1620     if(isVisible() && !qt_nograb()) {
1621         if(mac_mouse_grabber)
1622             mac_mouse_grabber->releaseMouse();
1623         mac_mouse_grabber=this;
1624         qt_mac_setMouseGrabCursor(true, const_cast<QCursor *>(&cursor));
1625     }
1626 }
1627 #endif
1628
1629 void QWidget::releaseMouse()
1630 {
1631     if(!qt_nograb() && mac_mouse_grabber == this) {
1632         mac_mouse_grabber = 0;
1633         qt_mac_setMouseGrabCursor(false);
1634     }
1635 }
1636
1637 void QWidget::grabKeyboard()
1638 {
1639     if(!qt_nograb()) {
1640         if(mac_keyboard_grabber)
1641             mac_keyboard_grabber->releaseKeyboard();
1642         mac_keyboard_grabber = this;
1643     }
1644 }
1645
1646 void QWidget::releaseKeyboard()
1647 {
1648     if(!qt_nograb() && mac_keyboard_grabber == this)
1649         mac_keyboard_grabber = 0;
1650 }
1651
1652 QWidget *QWidget::mouseGrabber()
1653 {
1654     return mac_mouse_grabber;
1655 }
1656
1657 QWidget *QWidget::keyboardGrabber()
1658 {
1659     return mac_keyboard_grabber;
1660 }
1661
1662 void QWidget::activateWindow()
1663 {
1664     QWidget *tlw = window();
1665     if(!tlw->isVisible() || !tlw->isWindow() || (tlw->windowType() == Qt::Desktop))
1666         return;
1667     qt_event_remove_activate();
1668
1669     QWidget *fullScreenWidget = tlw;
1670     QWidget *parentW = tlw;
1671     // Find the oldest parent or the parent with fullscreen, whichever comes first.
1672     while (parentW) {
1673         fullScreenWidget = parentW->window();
1674         if (fullScreenWidget->windowState() & Qt::WindowFullScreen)
1675             break;
1676         parentW = fullScreenWidget->parentWidget();
1677     }
1678
1679     if (fullScreenWidget->windowType() != Qt::ToolTip) {
1680         qt_mac_set_fullscreen_mode((fullScreenWidget->windowState() & Qt::WindowFullScreen) &&
1681                                                qApp->desktop()->screenNumber(this) == 0);
1682     }
1683
1684     bool windowActive;
1685     OSWindowRef win = qt_mac_window_for(tlw);
1686     QMacCocoaAutoReleasePool pool;
1687     windowActive = [win isKeyWindow];
1688     if ((tlw->windowType() == Qt::Popup)
1689             || (tlw->windowType() == Qt::Tool)
1690             || qt_mac_is_macdrawer(tlw)
1691             || windowActive) {
1692         [win makeKeyWindow];
1693     } else if(!isMinimized()) {
1694         [win makeKeyAndOrderFront:win];
1695     }
1696 }
1697
1698 QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
1699 {
1700     return new QMacWindowSurface(q_func());
1701 }
1702
1703 void QWidgetPrivate::update_sys(const QRect &r)
1704 {
1705     Q_Q(QWidget);
1706     if (updateRedirectedToGraphicsProxyWidget(q, r))
1707         return;
1708     dirtyOnWidget += r;
1709     macSetNeedsDisplay(r != q->rect() ? r : QRegion());
1710 }
1711
1712 void QWidgetPrivate::update_sys(const QRegion &rgn)
1713 {
1714     Q_Q(QWidget);
1715     if (updateRedirectedToGraphicsProxyWidget(q, rgn))
1716         return;
1717     dirtyOnWidget += rgn;
1718     macSetNeedsDisplay(rgn);
1719 }
1720
1721 bool QWidgetPrivate::isRealWindow() const
1722 {
1723     return q_func()->isWindow() && !topData()->embedded;
1724 }
1725
1726 void QWidgetPrivate::show_sys()
1727 {
1728     Q_Q(QWidget);
1729     if ((q->windowType() == Qt::Desktop)) //desktop is always visible
1730         return;
1731
1732     invalidateBuffer(q->rect());
1733     if (q->testAttribute(Qt::WA_OutsideWSRange))
1734         return;
1735     QMacCocoaAutoReleasePool pool;
1736     q->setAttribute(Qt::WA_Mapped);
1737     if (q->testAttribute(Qt::WA_DontShowOnScreen))
1738         return;
1739
1740     bool realWindow = isRealWindow();
1741
1742     data.fstrut_dirty = true;
1743     if (realWindow) {
1744         bool isCurrentlyMinimized = (q->windowState() & Qt::WindowMinimized);
1745         setModal_sys();
1746         OSWindowRef window = qt_mac_window_for(q);
1747
1748         // Make sure that we end up sending a repaint event to
1749         // the widget if the window has been visible one before:
1750         [qt_mac_get_contentview_for(window) setNeedsDisplay:YES];
1751         if(qt_mac_is_macsheet(q)) {
1752             qt_event_request_showsheet(q);
1753         } else if(qt_mac_is_macdrawer(q)) {
1754             NSDrawer *drawer = qt_mac_drawer_for(q);
1755             [drawer openOnEdge:[drawer preferredEdge]];
1756         } else {
1757             // sync the opacity value back (in case of a fade).
1758             [window setAlphaValue:q->windowOpacity()];
1759
1760             QWidget *top = 0;
1761             if (QApplicationPrivate::tryModalHelper(q, &top)) {
1762                 [window makeKeyAndOrderFront:window];
1763                 // If this window is app modal, we need to start spinning
1764                 // a modal session for it. Interrupting
1765                 // the event dispatcher will make this happend:
1766                 if (data.window_modality == Qt::ApplicationModal)
1767                     QEventDispatcherMac::instance()->interrupt();
1768             } else {
1769                 // The window is modally shaddowed, so we need to make
1770                 // sure that we don't pop in front of the modal window:
1771                 [window orderFront:window];
1772                 if (!top->testAttribute(Qt::WA_DontShowOnScreen)) {
1773                     if (NSWindow *modalWin = qt_mac_window_for(top))
1774                         [modalWin orderFront:window];
1775                 }
1776             }
1777             setSubWindowStacking(true);
1778             qt_mac_update_cursor();
1779             if (q->windowType() == Qt::Popup) {
1780                 qt_button_down = 0;
1781                 if (q->focusWidget())
1782                                     q->focusWidget()->d_func()->setFocus_sys();
1783                                 else
1784                     setFocus_sys();
1785                         }
1786             toggleDrawers(true);
1787         }
1788         if (isCurrentlyMinimized) { //show in collapsed state
1789             [window miniaturize:window];
1790         } else if (!q->testAttribute(Qt::WA_ShowWithoutActivating)) {
1791         }
1792     } else if(topData()->embedded || !q->parentWidget() || q->parentWidget()->isVisible()) {
1793         if (NSView *view = qt_mac_nativeview_for(q)) {
1794             // INVARIANT: q is native. Just show the view:
1795             [view setHidden:NO];
1796         } else {
1797             // INVARIANT: q is alien. Update q instead:
1798             q->update();
1799         }
1800     }
1801
1802     if ([NSApp isActive] && !qt_button_down && !QWidget::mouseGrabber()){
1803         // Update enter/leave immidiatly, don't wait for a move event. But only
1804         // if no grab exists (even if the grab points to this widget, it seems, ref X11)
1805         QPoint qlocal, qglobal;
1806         QWidget *widgetUnderMouse = 0;
1807         qt_mac_getTargetForMouseEvent(0, QEvent::Enter, qlocal, qglobal, 0, &widgetUnderMouse);
1808         QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, qt_last_mouse_receiver);
1809         qt_last_mouse_receiver = widgetUnderMouse;
1810         qt_last_native_mouse_receiver = widgetUnderMouse ?
1811             (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0;
1812     }
1813
1814     topLevelAt_cache = 0;
1815     qt_event_request_window_change(q);
1816 }
1817
1818 QPoint qt_mac_nativeMapFromParent(const QWidget *child, const QPoint &pt)
1819 {
1820     NSPoint nativePoint = [qt_mac_nativeview_for(child) convertPoint:NSMakePoint(pt.x(), pt.y()) fromView:qt_mac_nativeview_for(child->parentWidget())];
1821     return QPoint(nativePoint.x, nativePoint.y);
1822 }
1823
1824
1825 void QWidgetPrivate::hide_sys()
1826 {
1827     Q_Q(QWidget);
1828     if((q->windowType() == Qt::Desktop)) //you can't hide the desktop!
1829         return;
1830     QMacCocoaAutoReleasePool pool;
1831     if(q->isWindow()) {
1832         setSubWindowStacking(false);
1833         OSWindowRef window = qt_mac_window_for(q);
1834         if(qt_mac_is_macsheet(q)) {
1835             [NSApp endSheet:window];
1836             [window orderOut:window];
1837         } else if(qt_mac_is_macdrawer(q)) {
1838             [qt_mac_drawer_for(q) close];
1839         } else {
1840             [window orderOut:window];
1841             // Unfortunately it is not as easy as just hiding the window, we need
1842             // to find out if we were in full screen mode. If we were and this is
1843             // the last window in full screen mode then we need to unset the full screen
1844             // mode. If this is not the last visible window in full screen mode then we
1845             // don't change the full screen mode.
1846             if(q->isFullScreen())
1847             {
1848                 bool keepFullScreen = false;
1849                 QWidgetList windowList = qApp->topLevelWidgets();
1850                 int windowCount = windowList.count();
1851                 for(int i = 0; i < windowCount; i++)
1852                 {
1853                     QWidget *w = windowList[i];
1854                     // If it is the same window, we don't need to check :-)
1855                     if(q == w)
1856                         continue;
1857                     // If they are not visible or if they are minimized then
1858                     // we just ignore them.
1859                     if(!w->isVisible() || w->isMinimized())
1860                         continue;
1861                     // Is it full screen?
1862                     // Notice that if there is one window in full screen mode then we
1863                     // cannot switch the full screen mode off, therefore we just abort.
1864                     if(w->isFullScreen()) {
1865                         keepFullScreen = true;
1866                         break;
1867                     }
1868                 }
1869                 // No windows in full screen mode, so let just unset that flag.
1870                 if(!keepFullScreen)
1871                     qt_mac_set_fullscreen_mode(false);
1872             }
1873             toggleDrawers(false);
1874             qt_mac_update_cursor();
1875         }
1876     } else {
1877          invalidateBuffer(q->rect());
1878         if (NSView *view = qt_mac_nativeview_for(q)) {
1879             // INVARIANT: q is native. Just hide the view:
1880             [view setHidden:YES];
1881         } else {
1882             // INVARIANT: q is alien. Repaint where q is placed instead:
1883             qt_mac_updateParentUnderAlienWidget(q);
1884         }
1885     }
1886
1887     if ([NSApp isActive] && !qt_button_down && !QWidget::mouseGrabber()){
1888         // Update enter/leave immidiatly, don't wait for a move event. But only
1889         // if no grab exists (even if the grab points to this widget, it seems, ref X11)
1890         QPoint qlocal, qglobal;
1891         QWidget *widgetUnderMouse = 0;
1892         qt_mac_getTargetForMouseEvent(0, QEvent::Leave, qlocal, qglobal, 0, &widgetUnderMouse);
1893         QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, qt_last_native_mouse_receiver);
1894         qt_last_mouse_receiver = widgetUnderMouse;
1895         qt_last_native_mouse_receiver = widgetUnderMouse ?
1896             (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0;
1897      }
1898
1899     topLevelAt_cache = 0;
1900     qt_event_request_window_change(q);
1901     deactivateWidgetCleanup();
1902     qt_mac_event_release(q);
1903 }
1904
1905 void QWidget::setWindowState(Qt::WindowStates newstate)
1906 {
1907     Q_D(QWidget);
1908     bool needShow = false;
1909     Qt::WindowStates oldstate = windowState();
1910     if (oldstate == newstate)
1911         return;
1912
1913     QMacCocoaAutoReleasePool pool;
1914     bool needSendStateChange = true;
1915     if(isWindow()) {
1916         if((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
1917             if(newstate & Qt::WindowFullScreen) {
1918                 if(QTLWExtra *tlextra = d->topData()) {
1919                     if(tlextra->normalGeometry.width() < 0) {
1920                         if(!testAttribute(Qt::WA_Resized))
1921                             adjustSize();
1922                         tlextra->normalGeometry = geometry();
1923                     }
1924                     tlextra->savedFlags = windowFlags();
1925                 }
1926                 needShow = isVisible();
1927                 const QRect fullscreen(qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(this)));
1928                 setParent(parentWidget(), Qt::Window | Qt::FramelessWindowHint | (windowFlags() & 0xffff0000)); //save
1929                 setGeometry(fullscreen);
1930                 if(!qApp->desktop()->screenNumber(this))
1931                     qt_mac_set_fullscreen_mode(true);
1932             } else {
1933                 needShow = isVisible();
1934                 if(!qApp->desktop()->screenNumber(this))
1935                     qt_mac_set_fullscreen_mode(false);
1936                 setParent(parentWidget(), d->topData()->savedFlags);
1937                 setGeometry(d->topData()->normalGeometry);
1938                 d->topData()->normalGeometry.setRect(0, 0, -1, -1);
1939             }
1940         }
1941
1942         d->createWinId();
1943
1944         OSWindowRef window = qt_mac_window_for(this);
1945         if((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
1946             if (newstate & Qt::WindowMinimized) {
1947                 [window miniaturize:window];
1948             } else {
1949                 [window deminiaturize:window];
1950             }
1951             needSendStateChange = oldstate == windowState(); // Collapse didn't change our flags.
1952         }
1953
1954         if((newstate & Qt::WindowMaximized) && !((newstate & Qt::WindowFullScreen))) {
1955             if(QTLWExtra *tlextra = d->topData()) {
1956                 if(tlextra->normalGeometry.width() < 0) {
1957                     if(!testAttribute(Qt::WA_Resized))
1958                         adjustSize();
1959                     tlextra->normalGeometry = geometry();
1960                 }
1961             }
1962         } else if(!(newstate & Qt::WindowFullScreen)) {
1963 //            d->topData()->normalGeometry = QRect(0, 0, -1, -1);
1964         }
1965
1966 #ifdef DEBUG_WINDOW_STATE
1967 #define WSTATE(x) qDebug("%s -- %s --> %s", #x, (oldstate & x) ? "true" : "false", (newstate & x) ? "true" : "false")
1968         WSTATE(Qt::WindowMinimized);
1969         WSTATE(Qt::WindowMaximized);
1970         WSTATE(Qt::WindowFullScreen);
1971 #undef WSTATE
1972 #endif
1973         if(!(newstate & (Qt::WindowMinimized|Qt::WindowFullScreen)) &&
1974            ((oldstate & Qt::WindowFullScreen) || (oldstate & Qt::WindowMinimized) ||
1975             (oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized))) {
1976             if(newstate & Qt::WindowMaximized) {
1977                 data->fstrut_dirty = true;
1978                 NSToolbar *toolbarRef = [window toolbar];
1979                 if (toolbarRef && !isVisible() && ![toolbarRef isVisible]) {
1980                     // HIToolbar, needs to be shown so that it's in the structure window
1981                     // Typically this is part of a main window and will get shown
1982                     // during the show, but it's will make the maximize all wrong.
1983                     // ### Not sure this is right for NSToolbar...
1984                     [toolbarRef setVisible:true];
1985 //                    ShowHideWindowToolbar(window, true, false);
1986                     d->updateFrameStrut();  // In theory the dirty would work, but it's optimized out if the window is not visible :(
1987                 }
1988                 // Everything should be handled by Cocoa.
1989                 [window zoom:window];
1990                 needSendStateChange = oldstate == windowState(); // Zoom didn't change flags.
1991             } else if(oldstate & Qt::WindowMaximized && !(oldstate & Qt::WindowFullScreen)) {
1992                 [window zoom:window];
1993                 if(QTLWExtra *tlextra = d->topData()) {
1994                     setGeometry(tlextra->normalGeometry);
1995                     tlextra->normalGeometry.setRect(0, 0, -1, -1);
1996                 }
1997             }
1998         }
1999     }
2000
2001     data->window_state = newstate;
2002
2003     if(needShow)
2004         show();
2005
2006     if(newstate & Qt::WindowActive)
2007         activateWindow();
2008
2009     qt_event_request_window_change(this);
2010     if (needSendStateChange) {
2011         QWindowStateChangeEvent e(oldstate);
2012         QApplication::sendEvent(this, &e);
2013     }
2014 }
2015
2016 void QWidgetPrivate::setFocus_sys()
2017 {
2018     Q_Q(QWidget);
2019     if (q->testAttribute(Qt::WA_WState_Created)) {
2020         QMacCocoaAutoReleasePool pool;
2021         NSView *view = qt_mac_nativeview_for(q);
2022         [[view window] makeFirstResponder:view];
2023     }
2024 }
2025
2026 NSComparisonResult compareViews2Raise(id view1, id view2, void *context)
2027 {
2028     id topView = reinterpret_cast<id>(context);
2029     if (view1 == topView)
2030         return NSOrderedDescending;
2031     if (view2 == topView)
2032         return NSOrderedAscending;
2033     return NSOrderedSame;
2034 }
2035
2036 void QWidgetPrivate::raise_sys()
2037 {
2038     Q_Q(QWidget);
2039     if((q->windowType() == Qt::Desktop))
2040         return;
2041
2042     QMacCocoaAutoReleasePool pool;
2043     if (isRealWindow()) {
2044         // With the introduction of spaces it is not as simple as just raising the window.
2045         // First we need to check if we are in the right space. If we are, then we just continue
2046         // as usual. The problem comes when we are not in the active space. There are two main cases:
2047         // 1. Our parent was moved to a new space. In this case we want the window to be raised
2048         // in the same space as its parent.
2049         // 2. We don't have a parent. For this case we will just raise the window and let Cocoa
2050         // switch to the corresponding space.
2051         // NOTICE: There are a lot of corner cases here. We are keeping this simple for now, if
2052         // required we will introduce special handling for some of them.
2053         if (!q->testAttribute(Qt::WA_DontShowOnScreen) && q->isVisible()) {
2054             OSWindowRef window = qt_mac_window_for(q);
2055             // isOnActiveSpace is available only from 10.6 onwards, so we need to check if it is
2056             // available before calling it.
2057             if([window respondsToSelector:@selector(isOnActiveSpace)]) {
2058                 if(![window performSelector:@selector(isOnActiveSpace)]) {
2059                     QWidget *parentWidget = q->parentWidget();
2060                     if(parentWidget) {
2061                         OSWindowRef parentWindow = qt_mac_window_for(parentWidget);
2062                         if(parentWindow && [parentWindow respondsToSelector:@selector(isOnActiveSpace)]) {
2063                             if ([parentWindow performSelector:@selector(isOnActiveSpace)]) {
2064                                 // The window was created in a different space. Therefore if we want
2065                                 // to show it in the current space we need to recreate it in the new
2066                                 // space.
2067                                 recreateMacWindow();
2068                                 window = qt_mac_window_for(q);
2069                             }
2070                         }
2071                     }
2072                 }
2073             }
2074             [window orderFront:window];
2075         }
2076         if (qt_mac_raise_process) { //we get to be the active process now
2077             ProcessSerialNumber psn;
2078             GetCurrentProcess(&psn);
2079             SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
2080         }
2081     } else {
2082         NSView *view = qt_mac_nativeview_for(q);
2083         NSView *parentView = [view superview];
2084         [parentView sortSubviewsUsingFunction:compareViews2Raise context:reinterpret_cast<void *>(view)];
2085     }
2086     topLevelAt_cache = 0;
2087 }
2088
2089 NSComparisonResult compareViews2Lower(id view1, id view2, void *context)
2090 {
2091     id topView = reinterpret_cast<id>(context);
2092     if (view1 == topView)
2093         return NSOrderedAscending;
2094     if (view2 == topView)
2095         return NSOrderedDescending;
2096     return NSOrderedSame;
2097 }
2098
2099 void QWidgetPrivate::lower_sys()
2100 {
2101     Q_Q(QWidget);
2102     if((q->windowType() == Qt::Desktop))
2103         return;
2104     if (isRealWindow()) {
2105         OSWindowRef window = qt_mac_window_for(q);
2106         [window orderBack:window];
2107     } else {
2108         NSView *view = qt_mac_nativeview_for(q);
2109         NSView *parentView = [view superview];
2110         [parentView sortSubviewsUsingFunction:compareViews2Lower context:reinterpret_cast<void *>(view)];
2111     }
2112     topLevelAt_cache = 0;
2113 }
2114
2115 NSComparisonResult compareViews2StackUnder(id view1, id view2, void *context)
2116 {
2117     const QHash<NSView *, int> &viewOrder = *reinterpret_cast<QHash<NSView *, int> *>(context);
2118     if (viewOrder[view1] < viewOrder[view2])
2119         return NSOrderedAscending;
2120     if (viewOrder[view1] > viewOrder[view2])
2121         return NSOrderedDescending;
2122     return NSOrderedSame;
2123 }
2124
2125 void QWidgetPrivate::stackUnder_sys(QWidget *w)
2126 {
2127     // stackUnder
2128     Q_Q(QWidget);
2129     if(!w || q->isWindow() || (q->windowType() == Qt::Desktop))
2130         return;
2131     // Do the same trick as lower_sys() and put this widget before the widget passed in.
2132     NSView *myView = qt_mac_nativeview_for(q);
2133     NSView *wView = qt_mac_nativeview_for(w);
2134
2135     QHash<NSView *, int> viewOrder;
2136     NSView *parentView = [myView superview];
2137     NSArray *subviews = [parentView subviews];
2138     NSUInteger index = 1;
2139     // make a hash of view->zorderindex and make sure z-value is always odd,
2140     // so that when we modify the order we create a new (even) z-value which
2141     // will not interfere with others.
2142     for (NSView *subview in subviews) {
2143         viewOrder.insert(subview, index * 2);
2144         ++index;
2145     }
2146     viewOrder[myView] = viewOrder[wView] - 1;
2147
2148     [parentView sortSubviewsUsingFunction:compareViews2StackUnder context:reinterpret_cast<void *>(&viewOrder)];
2149 }
2150
2151
2152 /*
2153   Helper function for non-toplevel widgets. Helps to map Qt's 32bit
2154   coordinate system to OS X's 16bit coordinate system.
2155
2156   Sets the geometry of the widget to data.crect, but clipped to sizes
2157   that OS X can handle. Unmaps widgets that are completely outside the
2158   valid range.
2159
2160   Maintains data.wrect, which is the geometry of the OS X widget,
2161   measured in this widget's coordinate system.
2162
2163   if the parent is not clipped, parentWRect is empty, otherwise
2164   parentWRect is the geometry of the parent's OS X rect, measured in
2165   parent's coord sys
2166 */
2167 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
2168 {
2169     Q_Q(QWidget);
2170     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
2171
2172     if (!q->internalWinId() && QApplicationPrivate::graphicsSystem() != 0) {
2173         // We have no view to move, and no paint engine that
2174         // we can update dirty regions on. So just return:
2175         return;
2176     }
2177
2178     QMacCocoaAutoReleasePool pool;
2179
2180     /*
2181       There are up to four different coordinate systems here:
2182       Qt coordinate system for this widget.
2183       X coordinate system for this widget (relative to wrect).
2184       Qt coordinate system for parent
2185       X coordinate system for parent (relative to parent's wrect).
2186     */
2187
2188     // wrect is the same as crect, except that it is
2189     // clipped to fit inside parent (and screen):
2190     QRect wrect;
2191
2192     // wrectInParentCoordSys will be the same as wrect, except that it is
2193     // originated in q's parent rather than q itself. It starts out in
2194     // parent's Qt coord system, and ends up in parent's coordinate system:
2195     QRect wrectInParentCoordSys = data.crect;
2196
2197     // If q's parent has been clipped, parentWRect will
2198     // be filled with the parents clipped crect:
2199     QRect parentWRect;
2200
2201     // Embedded have different meaning on each platform, and on
2202     // Mac, it means that q is a QMacNativeWidget.
2203     bool isEmbeddedWindow = (q->isWindow() && topData()->embedded);
2204     NSView *nsview = qt_mac_nativeview_for(q);
2205     if (!isEmbeddedWindow) {
2206         parentWRect = q->parentWidget()->data->wrect;
2207     } else {
2208         // INVARIANT: q's parent view is not owned by Qt. So we need to
2209         // do some extra calls to get the clipped rect of the parent view:
2210         NSView *parentView = [qt_mac_nativeview_for(q) superview];
2211         if (parentView) {
2212             NSRect tmpRect = [parentView frame];
2213             parentWRect = QRect(tmpRect.origin.x, tmpRect.origin.y,
2214                                 tmpRect.size.width, tmpRect.size.height);
2215         } else {
2216             const QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
2217             parentWRect = wrectRange;
2218         }
2219     }
2220
2221     if (parentWRect.isValid()) {
2222         // INVARIANT: q's parent has been clipped.
2223         // So we fit our own wrects inside it:
2224         if (!parentWRect.contains(wrectInParentCoordSys) && !isEmbeddedWindow) {
2225             wrectInParentCoordSys &= parentWRect;
2226             wrect = wrectInParentCoordSys;
2227             // Make sure wrect is originated in q's coordinate system:
2228             wrect.translate(-data.crect.topLeft());
2229         }
2230         // // Make sure wrectInParentCoordSys originated in q's parent coordinate system:
2231         wrectInParentCoordSys.translate(-parentWRect.topLeft());
2232     } else {
2233         // INVARIANT: we dont know yet the clipping rect of q's parent.
2234         // So we may or may not have to adjust our wrects:
2235
2236         if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
2237             // This is where the main optimization is: we have an old wrect from an earlier
2238             // setGeometry call, and the new crect is smaller than it. If the final wrect is
2239             // also inside the old wrect, we can just move q and its children to the new
2240             // location without any clipping:
2241
2242              // vrect will be the part of q that's will be visible inside
2243              // q's parent. If it inside the old wrect, then we can just move:
2244             QRect vrect = wrectInParentCoordSys & q->parentWidget()->rect();
2245             vrect.translate(-data.crect.topLeft());
2246
2247             if (data.wrect.contains(vrect)) {
2248                 wrectInParentCoordSys = data.wrect;
2249                 wrectInParentCoordSys.translate(data.crect.topLeft());
2250                 if (nsview) {
2251                     // INVARIANT: q is native. Set view frame:
2252                     NSRect bounds = NSMakeRect(wrectInParentCoordSys.x(), wrectInParentCoordSys.y(),
2253                         wrectInParentCoordSys.width(), wrectInParentCoordSys.height());
2254                         [nsview setFrame:bounds];
2255                 } else {
2256                     // INVARIANT: q is alien. Repaint wrect instead (includes old and new wrect):
2257                     QWidget *parent = q->parentWidget();
2258                     QPoint globalPosWRect = parent->mapToGlobal(data.wrect.topLeft());
2259
2260                     QWidget *nativeParent = q->nativeParentWidget();
2261                     QRect dirtyWRect = QRect(nativeParent->mapFromGlobal(globalPosWRect), data.wrect.size());
2262
2263                     nativeParent->update(dirtyWRect);
2264                 }
2265                 if (q->testAttribute(Qt::WA_OutsideWSRange)) {
2266                     q->setAttribute(Qt::WA_OutsideWSRange, false);
2267                     if (!dontShow) {
2268                         q->setAttribute(Qt::WA_Mapped);
2269                         // If q is Alien, the following call does nothing:
2270                         [nsview setHidden:NO];
2271                     }
2272                 }
2273                 return;
2274             }
2275         }
2276
2277     }
2278
2279     // unmap if we are outside the valid window system coord system
2280     bool outsideRange = !wrectInParentCoordSys.isValid();
2281     bool mapWindow = false;
2282     if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
2283         q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
2284         if (outsideRange) {
2285             // If q is Alien, the following call does nothing:
2286             [nsview setHidden:YES];
2287             q->setAttribute(Qt::WA_Mapped, false);
2288         } else if (!q->isHidden()) {
2289             mapWindow = true;
2290         }
2291     }
2292
2293     if (outsideRange)
2294         return;
2295
2296     // Store the new clipped rect:
2297     bool jump = (data.wrect != wrect);
2298     data.wrect = wrect;
2299
2300     // and now recursively for all children...
2301     // ### can be optimized
2302     for (int i = 0; i < children.size(); ++i) {
2303         QObject *object = children.at(i);
2304         if (object->isWidgetType()) {
2305             QWidget *w = static_cast<QWidget *>(object);
2306             if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
2307                 w->d_func()->setWSGeometry();
2308         }
2309     }
2310
2311     if (nsview) {
2312         // INVARIANT: q is native. Move the actual NSView:
2313         NSRect bounds = NSMakeRect(
2314             wrectInParentCoordSys.x(), wrectInParentCoordSys.y(),
2315             wrectInParentCoordSys.width(), wrectInParentCoordSys.height());
2316         [nsview setFrame:bounds];
2317         if (jump)
2318             q->update();
2319     } else if (QApplicationPrivate::graphicsSystem() == 0){
2320         // INVARIANT: q is alien and we use native paint engine.
2321         // Schedule updates where q is moved from and to:
2322         const QWidget *parent = q->parentWidget();
2323         const QPoint globalPosOldWRect = parent->mapToGlobal(oldRect.topLeft());
2324         const QPoint globalPosNewWRect = parent->mapToGlobal(wrectInParentCoordSys.topLeft());
2325
2326         QWidget *nativeParent = q->nativeParentWidget();
2327         const QRegion dirtyOldWRect = QRect(nativeParent->mapFromGlobal(globalPosOldWRect), oldRect.size());
2328         const QRegion dirtyNewWRect = QRect(nativeParent->mapFromGlobal(globalPosNewWRect), wrectInParentCoordSys.size());
2329
2330         const bool sizeUnchanged = oldRect.size() == wrectInParentCoordSys.size();
2331         const bool posUnchanged = oldRect.topLeft() == wrectInParentCoordSys.topLeft();
2332
2333         // Resolve/minimize the region that needs to update:
2334         if (sizeUnchanged && q->testAttribute(Qt::WA_OpaquePaintEvent)) {
2335             // INVARIANT: q is opaque, and is only moved (not resized). So in theory we only
2336             // need to blit pixels, and skip a repaint. But we can only make this work if we
2337             // had access to the backbuffer, so we need to update all:
2338             nativeParent->update(dirtyOldWRect | dirtyNewWRect);
2339         } else if (posUnchanged && q->testAttribute(Qt::WA_StaticContents)) {
2340             // We only need to redraw exposed areas:
2341             nativeParent->update(dirtyNewWRect - dirtyOldWRect);
2342         } else {
2343             nativeParent->update(dirtyOldWRect | dirtyNewWRect);
2344         }
2345     }
2346
2347     if (mapWindow && !dontShow) {
2348         q->setAttribute(Qt::WA_Mapped);
2349         // If q is Alien, the following call does nothing:
2350         [nsview setHidden:NO];
2351     }
2352 }
2353
2354 void QWidgetPrivate::adjustWithinMaxAndMinSize(int &w, int &h)
2355 {
2356     if (QWExtra *extra = extraData()) {
2357         w = qMin(w, extra->maxw);
2358         h = qMin(h, extra->maxh);
2359         w = qMax(w, extra->minw);
2360         h = qMax(h, extra->minh);
2361
2362         // Deal with size increment
2363         if (QTLWExtra *top = topData()) {
2364             if(top->incw) {
2365                 w = w/top->incw;
2366                 w *= top->incw;
2367             }
2368             if(top->inch) {
2369                 h = h/top->inch;
2370                 h *= top->inch;
2371             }
2372         }
2373     }
2374
2375     if (isRealWindow()) {
2376         w = qMax(0, w);
2377         h = qMax(0, h);
2378     }
2379 }
2380
2381 void QWidgetPrivate::applyMaxAndMinSizeOnWindow()
2382 {
2383     Q_Q(QWidget);
2384     QMacCocoaAutoReleasePool pool;
2385
2386     const float max_f(20000);
2387 #define SF(x) ((x > max_f) ? max_f : x)
2388     NSSize max = NSMakeSize(SF(extra->maxw), SF(extra->maxh));
2389     NSSize min = NSMakeSize(SF(extra->minw), SF(extra->minh));
2390 #undef SF
2391     [qt_mac_window_for(q) setContentMinSize:min];
2392     [qt_mac_window_for(q) setContentMaxSize:max];
2393 }
2394
2395 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
2396 {
2397     Q_Q(QWidget);
2398     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
2399
2400     if(q->windowType() == Qt::Desktop)
2401         return;
2402
2403     QMacCocoaAutoReleasePool pool;
2404     bool realWindow = isRealWindow();
2405
2406     if (realWindow && !q->testAttribute(Qt::WA_DontShowOnScreen)){
2407         adjustWithinMaxAndMinSize(w, h);
2408         if (!isMove && !q->testAttribute(Qt::WA_Moved) && !q->isVisible()) {
2409             // INVARIANT: The location of the window has not yet been set. The default will
2410             // instead be to center it on the desktop, or over the parent, if any. Since we now
2411             // resize the window, we need to adjust the top left position to keep the window
2412             // centeralized. And we need to to this now (and before show) in case the positioning
2413             // of other windows (e.g. sub-windows) depend on this position:
2414             if (QWidget *p = q->parentWidget()) {
2415                 x = p->geometry().center().x() - (w / 2);
2416                 y = p->geometry().center().y() - (h / 2);
2417             } else {
2418                 QRect availGeo = QApplication::desktop()->availableGeometry(q);
2419                 x = availGeo.center().x() - (w / 2);
2420                 y = availGeo.center().y() - (h / 2);
2421             }
2422         }
2423
2424         QSize  olds = q->size();
2425         const bool isResize = (olds != QSize(w, h));
2426         NSWindow *window = qt_mac_window_for(q);
2427         const QRect &fStrut = frameStrut();
2428         const QRect frameRect(QPoint(x - fStrut.left(), y - fStrut.top()),
2429                               QSize(fStrut.left() + fStrut.right() + w,
2430                                     fStrut.top() + fStrut.bottom() + h));
2431         NSRect cocoaFrameRect = NSMakeRect(frameRect.x(), flipYCoordinate(frameRect.bottom() + 1),
2432                                            frameRect.width(), frameRect.height());
2433         // The setFrame call will trigger a 'windowDidResize' notification for the corresponding
2434         // NSWindow. The pending flag is set, so that the resize event can be send as non-spontaneous.
2435         if (isResize)
2436             q->setAttribute(Qt::WA_PendingResizeEvent);
2437         QPoint currTopLeft = data.crect.topLeft();
2438         if (currTopLeft.x() == x && currTopLeft.y() == y
2439                 && cocoaFrameRect.size.width != 0
2440                 && cocoaFrameRect.size.height != 0) {
2441             [window setFrame:cocoaFrameRect display:realWindow];
2442         } else {
2443             // The window is moved and resized (or resized to zero).
2444             // Since Cocoa usually only sends us a resize callback after
2445             // setting a window frame, we issue an explicit move as
2446             // well. To stop Cocoa from optimize away the move (since the move
2447             // would have the same origin as the setFrame call) we shift the
2448             // window back and forth inbetween.
2449             cocoaFrameRect.origin.y += 1;
2450             [window setFrame:cocoaFrameRect display:realWindow];
2451             cocoaFrameRect.origin.y -= 1;
2452             [window setFrameOrigin:cocoaFrameRect.origin];
2453         }
2454     } else {
2455         setGeometry_sys_helper(x, y, w, h, isMove);
2456     }
2457
2458     topLevelAt_cache = 0;
2459 }
2460
2461 void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isMove)
2462 {
2463     Q_Q(QWidget);
2464     bool realWindow = isRealWindow();
2465
2466     QPoint oldp = q->pos();
2467     QSize  olds = q->size();
2468     // Apply size restrictions, applicable for Windows & Widgets.
2469     if (QWExtra *extra = extraData()) {
2470         w = qBound(extra->minw, w, extra->maxw);
2471         h = qBound(extra->minh, h, extra->maxh);
2472     }
2473     const bool isResize = (olds != QSize(w, h));
2474
2475     if (!realWindow && !isResize && QPoint(x, y) == oldp)
2476         return;
2477
2478     if (isResize)
2479         data.window_state = data.window_state & ~Qt::WindowMaximized;
2480
2481     const bool visible = q->isVisible();
2482     data.crect = QRect(x, y, w, h);
2483
2484     if (realWindow) {
2485         adjustWithinMaxAndMinSize(w, h);
2486         qt_mac_update_sizer(q);
2487
2488         [qt_mac_nativeview_for(q) setFrame:NSMakeRect(0, 0, w, h)];
2489     } else {
2490         const QRect oldRect(oldp, olds);
2491         if (!isResize && QApplicationPrivate::graphicsSystem())
2492             moveRect(oldRect, x - oldp.x(), y - oldp.y());
2493
2494         setWSGeometry(false, oldRect);
2495
2496         if (isResize && QApplicationPrivate::graphicsSystem())
2497             invalidateBuffer_resizeHelper(oldp, olds);
2498     }
2499
2500     if(isMove || isResize) {
2501         if(!visible) {
2502             if(isMove && q->pos() != oldp)
2503                 q->setAttribute(Qt::WA_PendingMoveEvent, true);
2504             if(isResize)
2505                 q->setAttribute(Qt::WA_PendingResizeEvent, true);
2506         } else {
2507             if(isResize) { //send the resize event..
2508                 QResizeEvent e(q->size(), olds);
2509                 QApplication::sendEvent(q, &e);
2510             }
2511             if(isMove && q->pos() != oldp) { //send the move event..
2512                 QMoveEvent e(q->pos(), oldp);
2513                 QApplication::sendEvent(q, &e);
2514             }
2515         }
2516     }
2517     qt_event_request_window_change(q);
2518 }
2519
2520 void QWidgetPrivate::setConstraints_sys()
2521 {
2522     updateMaximizeButton_sys();
2523     applyMaxAndMinSizeOnWindow();
2524 }
2525
2526 void QWidgetPrivate::updateMaximizeButton_sys()
2527 {
2528     Q_Q(QWidget);
2529     if (q->data->window_flags & Qt::CustomizeWindowHint)
2530         return;
2531
2532     OSWindowRef window = qt_mac_window_for(q);
2533     QTLWExtra * tlwExtra = topData();
2534     QMacCocoaAutoReleasePool pool;
2535     NSButton *maximizeButton = [window standardWindowButton:NSWindowZoomButton];
2536     if (extra->maxw && extra->maxh
2537         && extra->maxw == extra->minw
2538         && extra->maxh == extra->minh) {
2539         // The window has a fixed size, so gray out the maximize button:
2540         if (!tlwExtra->savedWindowAttributesFromMaximized) {
2541             tlwExtra->savedWindowAttributesFromMaximized = (![maximizeButton isHidden] && [maximizeButton isEnabled]);
2542         }
2543        [maximizeButton setEnabled:NO];
2544
2545
2546     } else {
2547         if (tlwExtra->savedWindowAttributesFromMaximized) {
2548             [maximizeButton setEnabled:YES];
2549             tlwExtra->savedWindowAttributesFromMaximized = 0;
2550         }
2551     }
2552
2553
2554 }
2555
2556 void QWidgetPrivate::scroll_sys(int dx, int dy)
2557 {
2558     if (QApplicationPrivate::graphicsSystem() && !paintOnScreen()) {
2559         // INVARIANT: Alien paint engine
2560         scrollChildren(dx, dy);
2561         scrollRect(q_func()->rect(), dx, dy);
2562     } else {
2563         scroll_sys(dx, dy, QRect());
2564     }
2565 }
2566
2567 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &qscrollRect)
2568 {
2569     if (QMacScrollOptimization::delayScroll(this, dx, dy, qscrollRect))
2570         return;
2571
2572     Q_Q(QWidget);
2573     if (QApplicationPrivate::graphicsSystem() && !paintOnScreen()) {
2574         // INVARIANT: Alien paint engine
2575         scrollRect(qscrollRect, dx, dy);
2576         return;
2577     }
2578
2579     static int accelEnv = -1;
2580     if (accelEnv == -1) {
2581         accelEnv = qgetenv("QT_NO_FAST_SCROLL").toInt() == 0;
2582     }
2583
2584     // Scroll the whole widget if qscrollRect is not valid:
2585     QRect validScrollRect = qscrollRect.isValid() ? qscrollRect : q->rect();
2586     validScrollRect &= clipRect();
2587
2588     // If q is overlapped by other widgets, we cannot just blit pixels since
2589     // this will move overlapping widgets as well. In case we just update:
2590     const bool overlapped = isOverlapped(validScrollRect.translated(data.crect.topLeft()));
2591     const bool accelerateScroll = accelEnv && isOpaque && !overlapped;
2592     const bool isAlien = (q->internalWinId() == 0);
2593     const QPoint scrollDelta(dx, dy);
2594
2595     // If qscrollRect is valid, we are _not_ supposed to scroll q's children (as documented).
2596     // But we do scroll children (and the whole of q) if qscrollRect is invalid. This case is
2597     // documented as undefined, but we exploit it to help factor our code into one function.
2598     const bool scrollChildren = !qscrollRect.isValid();
2599
2600     if (!q->updatesEnabled()) {
2601         // We are told not to update anything on q at this point. So unless
2602         // we are supposed to scroll children, we bail out early:
2603         if (!scrollChildren || q->children().isEmpty())
2604             return;
2605     }
2606
2607     if (!accelerateScroll) {
2608         if (overlapped) {
2609             QRegion region(validScrollRect);
2610             subtractOpaqueSiblings(region);
2611             update_sys(region);
2612         }else {
2613             update_sys(qscrollRect);
2614         }
2615         return;
2616     }
2617
2618     QMacCocoaAutoReleasePool pool;
2619
2620     // First move all native children. Alien children will indirectly be
2621     // moved when the parent is scrolled. All directly or indirectly moved
2622     // children will receive a move event before the function call returns.
2623     QWidgetList movedChildren;
2624     if (scrollChildren) {
2625         QObjectList children = q->children();
2626
2627         for (int i=0; i<children.size(); i++) {
2628             QObject *obj = children.at(i);
2629             if (QWidget *w = qobject_cast<QWidget*>(obj)) {
2630                 if (!w->isWindow()) {
2631                     w->data->crect = QRect(w->pos() + scrollDelta, w->size());
2632                     if (NSView *view = qt_mac_nativeview_for(w)) {
2633                         // INVARIANT: w is not alien
2634                         [view setFrame:NSMakeRect(
2635                             w->data->crect.x(), w->data->crect.y(),
2636                             w->data->crect.width(), w->data->crect.height())];
2637                     }
2638                     movedChildren.append(w);
2639                 }
2640             }
2641         }
2642     }
2643
2644     if (q->testAttribute(Qt::WA_WState_Created) && q->isVisible()) {
2645         // Scroll q itself according to the qscrollRect, and
2646         // call update on any exposed areas so that they get redrawn:
2647
2648
2649         QWidget *nativeWidget = isAlien ? q->nativeParentWidget() : q;
2650         if (!nativeWidget)
2651             return;
2652         OSViewRef view = qt_mac_nativeview_for(nativeWidget);
2653         if (!view)
2654             return;
2655
2656         // Calculate the rectangles that needs to be redrawn
2657         // after the scroll. This will be source rect minus destination rect:
2658         QRect deltaXRect;
2659         if (dx != 0) {
2660             deltaXRect.setY(validScrollRect.y());
2661             deltaXRect.setHeight(validScrollRect.height());
2662             if (dx > 0) {
2663                 deltaXRect.setX(validScrollRect.x());
2664                 deltaXRect.setWidth(dx);
2665             } else {
2666                 deltaXRect.setX(validScrollRect.x() + validScrollRect.width() + dx);
2667                 deltaXRect.setWidth(-dx);
2668             }
2669         }
2670
2671         QRect deltaYRect;
2672         if (dy != 0) {
2673             deltaYRect.setX(validScrollRect.x());
2674             deltaYRect.setWidth(validScrollRect.width());
2675             if (dy > 0) {
2676                 deltaYRect.setY(validScrollRect.y());
2677                 deltaYRect.setHeight(dy);
2678            } else {
2679                 deltaYRect.setY(validScrollRect.y() + validScrollRect.height() + dy);
2680                 deltaYRect.setHeight(-dy);
2681             }
2682         }
2683
2684         if (isAlien) {
2685             // Adjust the scroll rect to the location as seen from the native parent:
2686             QPoint scrollTopLeftInsideNative = nativeWidget->mapFromGlobal(q->mapToGlobal(validScrollRect.topLeft()));
2687             validScrollRect.moveTo(scrollTopLeftInsideNative);
2688         }
2689
2690         // Make the pixel copy rect within the validScrollRect bounds:
2691         NSRect nsscrollRect = NSMakeRect(
2692             validScrollRect.x() + (dx < 0 ? -dx : 0),
2693             validScrollRect.y() + (dy < 0 ? -dy : 0),
2694             validScrollRect.width() + (dx > 0 ? -dx : 0),
2695             validScrollRect.height() + (dy > 0 ? -dy : 0));
2696
2697         NSSize deltaSize = NSMakeSize(dx, dy);
2698         [view scrollRect:nsscrollRect by:deltaSize];
2699
2700         // Some areas inside the scroll rect might have been marked as dirty from before, which
2701         // means that they are scheduled to be redrawn. But as we now scroll, those dirty rects
2702         // should also move along to ensure that q receives repaints on the correct places.
2703         // Since some of the dirty rects might lay outside, or only intersect with, the scroll
2704         // rect, the old calls to setNeedsDisplay still makes sense.
2705         // NB: Using [view translateRectsNeedingDisplayInRect:nsscrollRect by:deltaSize] have
2706         // so far not been proven fruitful to solve this problem.
2707         const QVector<QRect> &dirtyRectsToScroll = dirtyOnWidget.rects();
2708         for (int i=0; i<dirtyRectsToScroll.size(); ++i) {
2709             QRect qdirtyRect = dirtyRectsToScroll[i];
2710             qdirtyRect.translate(dx, dy);
2711             update_sys(qdirtyRect);
2712         }
2713
2714         // Update newly exposed areas. This will generate new dirty areas on
2715         // q, and therefore, we do it after updating the old dirty rects above:
2716         if (dx != 0)
2717             update_sys(deltaXRect);
2718         if (dy != 0)
2719             update_sys(deltaYRect);
2720
2721     }
2722
2723     for (int i=0; i<movedChildren.size(); i++) {
2724         QWidget *w = movedChildren.at(i);
2725         QMoveEvent e(w->pos(), w->pos() - scrollDelta);
2726         QApplication::sendEvent(w, &e);
2727     }
2728 }
2729
2730 int QWidget::metric(PaintDeviceMetric m) const
2731 {
2732     switch(m) {
2733     case PdmHeightMM:
2734         return qRound(metric(PdmHeight) * 25.4 / qreal(metric(PdmDpiY)));
2735     case PdmWidthMM:
2736         return qRound(metric(PdmWidth) * 25.4 / qreal(metric(PdmDpiX)));
2737     case PdmHeight:
2738     case PdmWidth:
2739         if (m == PdmWidth)
2740             return data->crect.width();
2741         else
2742             return data->crect.height();
2743     case PdmDepth:
2744         return 32;
2745     case PdmNumColors:
2746         return INT_MAX;
2747     case PdmDpiX:
2748     case PdmPhysicalDpiX: {
2749         Q_D(const QWidget);
2750         if (d->extra && d->extra->customDpiX)
2751             return d->extra->customDpiX;
2752         else if (d->parent)
2753             return static_cast<QWidget *>(d->parent)->metric(m);
2754         extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
2755         return int(qt_mac_defaultDpi_x()); }
2756     case PdmDpiY:
2757     case PdmPhysicalDpiY: {
2758         Q_D(const QWidget);
2759         if (d->extra && d->extra->customDpiY)
2760             return d->extra->customDpiY;
2761         else if (d->parent)
2762             return static_cast<QWidget *>(d->parent)->metric(m);
2763         extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp
2764         return int(qt_mac_defaultDpi_y()); }
2765     default: //leave this so the compiler complains when new ones are added
2766         qWarning("QWidget::metric: Unhandled parameter %d", m);
2767         return QPaintDevice::metric(m);
2768     }
2769     return 0;
2770 }
2771
2772 void QWidgetPrivate::createSysExtra()
2773 {
2774     extra->imageMask = 0;
2775 }
2776
2777 void QWidgetPrivate::deleteSysExtra()
2778 {
2779     if (extra->imageMask)
2780         CFRelease(extra->imageMask);
2781 }
2782
2783 void QWidgetPrivate::createTLSysExtra()
2784 {
2785     extra->topextra->resizer = 0;
2786     extra->topextra->isSetGeometry = 0;
2787     extra->topextra->isMove = 0;
2788     extra->topextra->wattr = 0;
2789     extra->topextra->wclass = 0;
2790     extra->topextra->group = 0;
2791     extra->topextra->windowIcon = 0;
2792     extra->topextra->savedWindowAttributesFromMaximized = 0;
2793 }
2794
2795 void QWidgetPrivate::deleteTLSysExtra()
2796 {
2797 }
2798
2799 void QWidgetPrivate::updateFrameStrut()
2800 {
2801     Q_Q(QWidget);
2802
2803     QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this);
2804
2805     that->data.fstrut_dirty = false;
2806     QTLWExtra *top = that->topData();
2807
2808     // 1 Get the window frame
2809     OSWindowRef oswnd = qt_mac_window_for(q);
2810     NSRect frameW = [oswnd frame];
2811     // 2 Get the content frame - so now
2812     NSRect frameC = [oswnd contentRectForFrameRect:frameW];
2813     top->frameStrut.setCoords(frameC.origin.x - frameW.origin.x,
2814                               (frameW.origin.y + frameW.size.height) - (frameC.origin.y + frameC.size.height),
2815                               (frameW.origin.x + frameW.size.width) - (frameC.origin.x + frameC.size.width),
2816                               frameC.origin.y - frameW.origin.y);
2817 }
2818
2819 void QWidgetPrivate::registerDropSite(bool on)
2820 {
2821     Q_Q(QWidget);
2822     if (!q->testAttribute(Qt::WA_WState_Created))
2823         return;
2824     NSWindow *win = qt_mac_window_for(q);
2825     if (on) {
2826         if ([win isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaWindow) class]])
2827             [static_cast<QT_MANGLE_NAMESPACE(QCocoaWindow) *>(win) registerDragTypes];
2828         else if ([win isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaPanel) class]])
2829             [static_cast<QT_MANGLE_NAMESPACE(QCocoaPanel) *>(win) registerDragTypes];
2830     }
2831 }
2832
2833 void QWidgetPrivate::registerTouchWindow(bool enable)
2834 {
2835     Q_UNUSED(enable);
2836 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
2837     if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_6)
2838         return;
2839
2840     Q_Q(QWidget);
2841     if (enable == touchEventsEnabled)
2842         return;
2843
2844     QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_effectiveview_for(q));
2845     if (!view)
2846         return;
2847
2848     if (enable) {
2849         ++view->alienTouchCount;
2850         if (view->alienTouchCount == 1) {
2851             touchEventsEnabled = true;
2852             [view setAcceptsTouchEvents:YES];
2853         }
2854     } else {
2855         --view->alienTouchCount;
2856         if (view->alienTouchCount == 0) {
2857             touchEventsEnabled = false;
2858             [view setAcceptsTouchEvents:NO];
2859         }
2860     }
2861 #endif
2862 }
2863
2864 void QWidgetPrivate::setMask_sys(const QRegion &region)
2865 {
2866     Q_UNUSED(region);
2867     Q_Q(QWidget);
2868
2869     if (!q->internalWinId())
2870         return;
2871
2872     if (extra->mask.isEmpty()) {
2873         extra->maskBits = QImage();
2874         finishCocoaMaskSetup();
2875     } else {
2876         syncCocoaMask();
2877     }
2878
2879     topLevelAt_cache = 0;
2880 }
2881
2882 void QWidgetPrivate::setWindowOpacity_sys(qreal level)
2883 {
2884     Q_Q(QWidget);
2885
2886     if (!q->isWindow())
2887         return;
2888
2889     level = qBound(0.0, level, 1.0);
2890     topData()->opacity = (uchar)(level * 255);
2891     if (!q->testAttribute(Qt::WA_WState_Created))
2892         return;
2893
2894     OSWindowRef oswindow = qt_mac_window_for(q);
2895     [oswindow setAlphaValue:level];
2896 }
2897
2898 void QWidgetPrivate::syncCocoaMask()
2899 {
2900     Q_Q(QWidget);
2901     if (!q->testAttribute(Qt::WA_WState_Created) || !extra)
2902         return;
2903
2904     if (extra->hasMask) {
2905         if(extra->maskBits.size() != q->size()) {
2906             extra->maskBits = QImage(q->size(), QImage::Format_Mono);
2907         }
2908         extra->maskBits.fill(QColor(Qt::color1).rgba());
2909         extra->maskBits.setNumColors(2);
2910         extra->maskBits.setColor(0, QColor(Qt::color0).rgba());
2911         extra->maskBits.setColor(1, QColor(Qt::color1).rgba());
2912         QPainter painter(&extra->maskBits);
2913         painter.setBrush(Qt::color1);
2914         painter.setPen(Qt::NoPen);
2915         painter.drawRects(extra->mask.rects());
2916         painter.end();
2917         finishCocoaMaskSetup();
2918     }
2919 }
2920
2921 void QWidgetPrivate::finishCocoaMaskSetup()
2922 {
2923     Q_Q(QWidget);
2924
2925     if (!q->testAttribute(Qt::WA_WState_Created) || !extra)
2926         return;
2927
2928     // Technically this is too late to release, because the data behind the image
2929     // has already been released. But it's more tidy to do it here.
2930     // If you are seeing a crash, consider doing a CFRelease before changing extra->maskBits.
2931     if (extra->imageMask) {
2932         CFRelease(extra->imageMask);
2933         extra->imageMask = 0;
2934     }
2935
2936     if (!extra->maskBits.isNull()) {
2937         QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(0,
2938                                                                        extra->maskBits.bits(),
2939                                                                        extra->maskBits.numBytes(),
2940                                                                        0); // shouldn't need to release.
2941         CGFloat decode[2] = {1, 0};
2942         extra->imageMask = CGImageMaskCreate(extra->maskBits.width(), extra->maskBits.height(),
2943                                              1, 1, extra->maskBits.bytesPerLine(), dataProvider,
2944                                              decode, false);
2945     }
2946     if (q->isWindow()) {
2947         NSWindow *window = qt_mac_window_for(q);
2948         [window setOpaque:(extra->imageMask == 0)];
2949         [window invalidateShadow];
2950     }
2951     macSetNeedsDisplay(QRegion());
2952 }
2953
2954 struct QPaintEngineCleanupHandler
2955 {
2956     inline QPaintEngineCleanupHandler() : engine(0) {}
2957     inline ~QPaintEngineCleanupHandler() { delete engine; }
2958     QPaintEngine *engine;
2959 };
2960
2961 Q_GLOBAL_STATIC(QPaintEngineCleanupHandler, engineHandler)
2962
2963 QPaintEngine *QWidget::paintEngine() const
2964 {
2965     QPaintEngine *&pe = engineHandler()->engine;
2966     if (!pe)
2967         pe = new QCoreGraphicsPaintEngine();
2968     if (pe->isActive()) {
2969         QPaintEngine *engine = new QCoreGraphicsPaintEngine();
2970         engine->setAutoDestruct(true);
2971         return engine;
2972     }
2973     return pe;
2974 }
2975
2976 void QWidgetPrivate::setModal_sys()
2977 {
2978     Q_Q(QWidget);
2979     if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow())
2980         return;
2981     const QWidget * const windowParent = q->window()->parentWidget();
2982     const QWidget * const primaryWindow = windowParent ? windowParent->window() : 0;
2983     OSWindowRef windowRef = qt_mac_window_for(q);
2984
2985     QMacCocoaAutoReleasePool pool;
2986     bool alreadySheet = [windowRef styleMask] & NSDocModalWindowMask;
2987
2988     if (windowParent && q->windowModality() == Qt::WindowModal){
2989         // INVARIANT: Window should be window-modal (which implies a sheet).
2990         if (!alreadySheet) {
2991             // NB: the following call will call setModal_sys recursivly:
2992             recreateMacWindow();
2993             windowRef = qt_mac_window_for(q);
2994         }
2995         if ([windowRef isKindOfClass:[NSPanel class]]){
2996             // If the primary window of the sheet parent is a child of a modal dialog,
2997             // the sheet parent should not be modally shaddowed.
2998             // This goes for the sheet as well:
2999             OSWindowRef ref = primaryWindow ? qt_mac_window_for(primaryWindow) : 0;
3000             bool isDialog = ref ? [ref isKindOfClass:[NSPanel class]] : false;
3001             bool worksWhenModal = isDialog ? [static_cast<NSPanel *>(ref) worksWhenModal] : false;
3002             if (worksWhenModal)
3003                 [static_cast<NSPanel *>(windowRef) setWorksWhenModal:YES];
3004         }
3005     } else {
3006         // INVARIANT: Window shold _not_ be window-modal (and as such, not a sheet).
3007         if (alreadySheet){
3008             // NB: the following call will call setModal_sys recursivly:
3009             recreateMacWindow();
3010             windowRef = qt_mac_window_for(q);
3011         }
3012         if (q->windowModality() == Qt::NonModal
3013             && primaryWindow && primaryWindow->windowModality() == Qt::ApplicationModal) {
3014             // INVARIANT: Our window has a parent that is application modal.
3015             // This means that q is supposed to be on top of this window and
3016             // not be modally shaddowed:
3017             if ([windowRef isKindOfClass:[NSPanel class]])
3018                 [static_cast<NSPanel *>(windowRef) setWorksWhenModal:YES];
3019         }
3020     }
3021
3022 }
3023
3024 void QWidgetPrivate::macUpdateHideOnSuspend()
3025 {
3026     Q_Q(QWidget);
3027     if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow() || q->windowType() != Qt::Tool)
3028         return;
3029     if(q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
3030         [qt_mac_window_for(q) setHidesOnDeactivate:NO];
3031     else
3032         [qt_mac_window_for(q) setHidesOnDeactivate:YES];
3033 }
3034
3035 void QWidgetPrivate::macUpdateOpaqueSizeGrip()
3036 {
3037     Q_Q(QWidget);
3038
3039     if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow())
3040         return;
3041
3042 }
3043
3044 void QWidgetPrivate::macUpdateSizeAttribute()
3045 {
3046     Q_Q(QWidget);
3047     QEvent event(QEvent::MacSizeChange);
3048     QApplication::sendEvent(q, &event);
3049     for (int i = 0; i < children.size(); ++i) {
3050         QWidget *w = qobject_cast<QWidget *>(children.at(i));
3051         if (w && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
3052               && !q->testAttribute(Qt::WA_MacMiniSize) // no attribute set? inherit from parent
3053               && !w->testAttribute(Qt::WA_MacSmallSize)
3054               && !w->testAttribute(Qt::WA_MacNormalSize))
3055             w->d_func()->macUpdateSizeAttribute();
3056     }
3057     resolveFont();
3058 }
3059
3060 void QWidgetPrivate::macUpdateIgnoreMouseEvents()
3061 {
3062 }
3063
3064 void QWidgetPrivate::macUpdateMetalAttribute()
3065 {
3066     Q_Q(QWidget);
3067     bool realWindow = isRealWindow();
3068     if (!q->testAttribute(Qt::WA_WState_Created) || !realWindow)
3069         return;
3070
3071     if (realWindow) {
3072         // Cocoa doesn't let us change the style mask once it's been changed
3073         // So, that means we need to recreate the window.
3074         OSWindowRef cocoaWindow = qt_mac_window_for(q);
3075         if ([cocoaWindow styleMask] & NSTexturedBackgroundWindowMask)
3076             return;
3077         recreateMacWindow();
3078     }
3079 }
3080
3081 void QWidgetPrivate::setEnabled_helper_sys(bool enable)
3082 {
3083     Q_Q(QWidget);
3084     NSView *view = qt_mac_nativeview_for(q);
3085     if ([view isKindOfClass:[NSControl class]])
3086         [static_cast<NSControl *>(view) setEnabled:enable];
3087 }
3088
3089 QT_END_NAMESPACE