src/gui/kernel/qwidget_mac.mm
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /****************************************************************************
       
    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 
       
   114 QT_BEGIN_NAMESPACE
       
   115 
       
   116 #define XCOORD_MAX 16383
       
   117 #define WRECT_MAX 8191
       
   118 
       
   119 #ifndef QT_MAC_USE_COCOA
       
   120 
       
   121 extern "C" {
       
   122     extern OSStatus _HIViewScrollRectWithOptions(HIViewRef, const HIRect *, CGFloat, CGFloat,
       
   123                                                  OptionBits) __attribute__ ((weak));
       
   124 }
       
   125 #define kHIViewScrollRectAdjustInvalid 1
       
   126 #define kHIViewScrollRectDontInvalidateRevealedArea 2
       
   127 #endif
       
   128 
       
   129 
       
   130 /*****************************************************************************
       
   131   QWidget debug facilities
       
   132  *****************************************************************************/
       
   133 //#define DEBUG_WINDOW_RGNS
       
   134 //#define DEBUG_WINDOW_CREATE
       
   135 //#define DEBUG_WINDOW_STATE
       
   136 //#define DEBUG_WIDGET_PAINT
       
   137 
       
   138 /*****************************************************************************
       
   139   QWidget globals
       
   140  *****************************************************************************/
       
   141 #ifndef QT_MAC_USE_COCOA
       
   142 typedef QHash<Qt::WindowFlags, WindowGroupRef> WindowGroupHash;
       
   143 Q_GLOBAL_STATIC(WindowGroupHash, qt_mac_window_groups)
       
   144 const UInt32 kWidgetCreatorQt = kEventClassQt;
       
   145 enum {
       
   146     kWidgetPropertyQWidget = 'QWId' //QWidget *
       
   147 };
       
   148 #endif
       
   149 
       
   150 static bool qt_mac_raise_process = true;
       
   151 static OSWindowRef qt_root_win = 0;
       
   152 QWidget *mac_mouse_grabber = 0;
       
   153 QWidget *mac_keyboard_grabber = 0;
       
   154 
       
   155 #ifndef QT_MAC_USE_COCOA
       
   156 #ifdef QT_NAMESPACE
       
   157 
       
   158 // produce the string "com.trolltech.qt-namespace.widget", where "namespace" is the contents of QT_NAMESPACE.
       
   159 #define SS(x) #x
       
   160 #define S0(x) SS(x)
       
   161 #define S "com.trolltech.qt-" S0(QT_NAMESPACE) ".widget"
       
   162 
       
   163 static CFStringRef kObjectQWidget = CFSTR(S);
       
   164 
       
   165 #undef SS
       
   166 #undef S0
       
   167 #undef S
       
   168 
       
   169 #else
       
   170 static CFStringRef kObjectQWidget = CFSTR("com.trolltech.qt.widget");
       
   171 #endif // QT_NAMESPACE
       
   172 #endif // QT_MAC_USE_COCOA
       
   173 
       
   174 /*****************************************************************************
       
   175   Externals
       
   176  *****************************************************************************/
       
   177 extern QWidget *qt_mac_modal_blocked(QWidget *); //qapplication_mac.mm
       
   178 extern void qt_event_request_activate(QWidget *); //qapplication_mac.mm
       
   179 extern bool qt_event_remove_activate(); //qapplication_mac.mm
       
   180 extern void qt_mac_event_release(QWidget *w); //qapplication_mac.mm
       
   181 extern void qt_event_request_showsheet(QWidget *); //qapplication_mac.mm
       
   182 extern void qt_event_request_window_change(QWidget *); //qapplication_mac.mm
       
   183 extern QPointer<QWidget> qt_mouseover; //qapplication_mac.mm
       
   184 extern IconRef qt_mac_create_iconref(const QPixmap &); //qpixmap_mac.cpp
       
   185 extern void qt_mac_set_cursor(const QCursor *, const QPoint &); //qcursor_mac.mm
       
   186 extern void qt_mac_update_cursor(); //qcursor_mac.mm
       
   187 extern bool qt_nograb();
       
   188 extern CGImageRef qt_mac_create_cgimage(const QPixmap &, bool); //qpixmap_mac.cpp
       
   189 extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
       
   190 extern QRegion qt_mac_convert_mac_region(RgnHandle rgn); //qregion_mac.cpp
       
   191 
       
   192 /*****************************************************************************
       
   193   QWidget utility functions
       
   194  *****************************************************************************/
       
   195 void Q_GUI_EXPORT qt_mac_set_raise_process(bool b) { qt_mac_raise_process = b; }
       
   196 static QSize qt_mac_desktopSize()
       
   197 {
       
   198     int w = 0, h = 0;
       
   199     CGDisplayCount cg_count;
       
   200     CGGetActiveDisplayList(0, 0, &cg_count);
       
   201     QVector<CGDirectDisplayID> displays(cg_count);
       
   202     CGGetActiveDisplayList(cg_count, displays.data(), &cg_count);
       
   203     Q_ASSERT(cg_count == (CGDisplayCount)displays.size());
       
   204     for(int i = 0; i < (int)cg_count; ++i) {
       
   205         CGRect r = CGDisplayBounds(displays.at(i));
       
   206         w = qMax<int>(w, qRound(r.origin.x + r.size.width));
       
   207         h = qMax<int>(h, qRound(r.origin.y + r.size.height));
       
   208     }
       
   209     return QSize(w, h);
       
   210 }
       
   211 
       
   212 #ifdef QT_MAC_USE_COCOA
       
   213 static NSDrawer *qt_mac_drawer_for(const QWidget *widget)
       
   214 {
       
   215     // This only goes one level below the content view so start with the window.
       
   216     // This works fine for straight Qt stuff, but runs into problems if we are
       
   217     // embedding, but if that's the case, they probably want to be using
       
   218     // NSDrawer directly.
       
   219     NSView *widgetView = reinterpret_cast<NSView *>(widget->window()->winId());
       
   220     NSArray *windows = [NSApp windows];
       
   221     for (NSWindow *window in windows) {
       
   222         NSArray *drawers = [window drawers];
       
   223         for (NSDrawer *drawer in drawers) {
       
   224             NSArray *views = [[drawer contentView] subviews];
       
   225             for (NSView *view in views) {
       
   226                 if (view == widgetView)
       
   227                     return drawer;
       
   228             }
       
   229         }
       
   230     }
       
   231     return 0;
       
   232 }
       
   233 #endif
       
   234 
       
   235 static void qt_mac_destructView(OSViewRef view)
       
   236 {
       
   237 #ifdef QT_MAC_USE_COCOA
       
   238     [view removeFromSuperview];
       
   239     [view release];
       
   240 #else
       
   241     HIViewRemoveFromSuperview(view);
       
   242     CFRelease(view);
       
   243 #endif
       
   244 }
       
   245 
       
   246 static void qt_mac_destructWindow(OSWindowRef window)
       
   247 {
       
   248 #ifdef QT_MAC_USE_COCOA
       
   249     if ([window isVisible] && [window isSheet]){
       
   250         [NSApp endSheet:window];
       
   251         [window orderOut:window];
       
   252     }
       
   253 
       
   254     [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] resignDelegateForWindow:window];
       
   255     [window release];
       
   256 #else
       
   257     // Remove property to clean up memory:
       
   258     RemoveWindowProperty(window, kWidgetCreatorQt, kWidgetPropertyQWidget);
       
   259     CFRelease(window);
       
   260 #endif
       
   261 }
       
   262 
       
   263 static void qt_mac_destructDrawer(NSDrawer *drawer)
       
   264 {
       
   265 #ifdef QT_MAC_USE_COCOA
       
   266     [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] resignDelegateForDrawer:drawer];
       
   267     [drawer release];
       
   268 #else
       
   269     Q_UNUSED(drawer);
       
   270 #endif
       
   271 }
       
   272 
       
   273 bool qt_mac_can_clickThrough(const QWidget *w)
       
   274 {
       
   275     static int qt_mac_carbon_clickthrough = -1;
       
   276     if (qt_mac_carbon_clickthrough < 0)
       
   277         qt_mac_carbon_clickthrough = !qgetenv("QT_MAC_NO_COCOA_CLICKTHROUGH").isEmpty();
       
   278     bool ret = !qt_mac_carbon_clickthrough;
       
   279     for ( ; w; w = w->parentWidget()) {
       
   280         if (w->testAttribute(Qt::WA_MacNoClickThrough)) {
       
   281             ret = false;
       
   282             break;
       
   283         }
       
   284     }
       
   285     return ret;
       
   286 }
       
   287 
       
   288 bool qt_mac_is_macsheet(const QWidget *w)
       
   289 {
       
   290     if (!w)
       
   291         return false;
       
   292 
       
   293     Qt::WindowModality modality = w->windowModality();
       
   294     if (modality == Qt::ApplicationModal)
       
   295         return false;
       
   296     return w->parentWidget() && (modality == Qt::WindowModal || w->windowType() == Qt::Sheet);
       
   297 }
       
   298 
       
   299 bool qt_mac_is_macdrawer(const QWidget *w)
       
   300 {
       
   301     return (w && w->parentWidget() && w->windowType() == Qt::Drawer);
       
   302 }
       
   303 
       
   304 bool qt_mac_insideKeyWindow(const QWidget *w)
       
   305 {
       
   306 #ifdef QT_MAC_USE_COCOA
       
   307     return [[reinterpret_cast<NSView *>(w->winId()) window] isKeyWindow];
       
   308 #else
       
   309     Q_UNUSED(w);
       
   310 #endif
       
   311     return false;
       
   312 }
       
   313 
       
   314 bool qt_mac_set_drawer_preferred_edge(QWidget *w, Qt::DockWidgetArea where) //users of Qt for Mac OS X can use this..
       
   315 {
       
   316     if(!qt_mac_is_macdrawer(w))
       
   317         return false;
       
   318 
       
   319 #if QT_MAC_USE_COCOA
       
   320     NSDrawer *drawer = qt_mac_drawer_for(w);
       
   321     if (!drawer)
       
   322         return false;
       
   323 	NSRectEdge	edge;
       
   324     if (where & Qt::LeftDockWidgetArea)
       
   325         edge = NSMinXEdge;
       
   326     else if (where & Qt::RightDockWidgetArea)
       
   327         edge = NSMaxXEdge;
       
   328     else if (where & Qt::TopDockWidgetArea)
       
   329 		edge = NSMaxYEdge;
       
   330     else if (where & Qt::BottomDockWidgetArea)
       
   331         edge = NSMinYEdge;
       
   332     else
       
   333         return false;
       
   334 
       
   335     if (edge == [drawer preferredEdge]) //no-op
       
   336         return false;
       
   337 
       
   338     if (w->isVisible()) {
       
   339 	    [drawer close];
       
   340 	    [drawer openOnEdge:edge];
       
   341 	}
       
   342 	[drawer setPreferredEdge:edge];
       
   343 #else
       
   344     OSWindowRef window = qt_mac_window_for(w);
       
   345     OptionBits edge;
       
   346     if(where & Qt::LeftDockWidgetArea)
       
   347         edge = kWindowEdgeLeft;
       
   348     else if(where & Qt::RightDockWidgetArea)
       
   349         edge = kWindowEdgeRight;
       
   350     else if(where & Qt::TopDockWidgetArea)
       
   351         edge = kWindowEdgeTop;
       
   352     else if(where & Qt::BottomDockWidgetArea)
       
   353         edge = kWindowEdgeBottom;
       
   354     else
       
   355         return false;
       
   356 
       
   357     if(edge == GetDrawerPreferredEdge(window)) //no-op
       
   358         return false;
       
   359 
       
   360     //do it
       
   361     SetDrawerPreferredEdge(window, edge);
       
   362     if(w->isVisible()) {
       
   363         CloseDrawer(window, false);
       
   364         OpenDrawer(window, edge, true);
       
   365     }
       
   366 #endif
       
   367     return true;
       
   368 }
       
   369 
       
   370 #ifndef QT_MAC_USE_COCOA
       
   371 Q_GUI_EXPORT
       
   372 #endif
       
   373 QPoint qt_mac_posInWindow(const QWidget *w)
       
   374 {
       
   375     QPoint ret = w->data->wrect.topLeft();
       
   376     while(w && !w->isWindow()) {
       
   377         ret += w->pos();
       
   378         w =  w->parentWidget();
       
   379     }
       
   380     return ret;
       
   381 }
       
   382 
       
   383 //find a QWidget from a OSWindowRef
       
   384 QWidget *qt_mac_find_window(OSWindowRef window)
       
   385 {
       
   386 #ifdef QT_MAC_USE_COCOA
       
   387     return [window QT_MANGLE_NAMESPACE(qt_qwidget)];
       
   388 #else
       
   389     if(!window)
       
   390         return 0;
       
   391 
       
   392     QWidget *ret;
       
   393     if(GetWindowProperty(window, kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(ret), 0, &ret) == noErr)
       
   394         return ret;
       
   395     return 0;
       
   396 #endif
       
   397 }
       
   398 
       
   399 inline static void qt_mac_set_fullscreen_mode(bool b)
       
   400 {
       
   401     extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
       
   402     if(qt_mac_app_fullscreen == b)
       
   403         return;
       
   404     qt_mac_app_fullscreen = b;
       
   405     if (b) {
       
   406         SetSystemUIMode(kUIModeAllSuppressed, 0);
       
   407     } else {
       
   408         SetSystemUIMode(kUIModeNormal, 0);
       
   409     }
       
   410 }
       
   411 
       
   412 Q_GUI_EXPORT OSViewRef qt_mac_nativeview_for(const QWidget *w)
       
   413 {
       
   414     return reinterpret_cast<OSViewRef>(w->data->winid);
       
   415 }
       
   416 
       
   417 Q_GUI_EXPORT OSViewRef qt_mac_get_contentview_for(OSWindowRef w)
       
   418 {
       
   419 #ifdef QT_MAC_USE_COCOA
       
   420     return [w contentView];
       
   421 #else
       
   422     HIViewRef contentView = 0;
       
   423     OSStatus err = GetRootControl(w, &contentView);  // Returns the window's content view (Apple QA1214)
       
   424     if (err == errUnknownControl) {
       
   425         contentView = HIViewGetRoot(w);
       
   426     } else if (err != noErr) {
       
   427         qWarning("Qt:Could not get content or root view of window! %s:%d [%ld]",
       
   428                  __FILE__, __LINE__, err);
       
   429     }
       
   430     return contentView;
       
   431 #endif
       
   432 }
       
   433 
       
   434 bool qt_mac_sendMacEventToWidget(QWidget *widget, EventRef ref)
       
   435 {
       
   436     return widget->macEvent(0, ref);
       
   437 }
       
   438 
       
   439 Q_GUI_EXPORT OSWindowRef qt_mac_window_for(OSViewRef view)
       
   440 {
       
   441 #ifdef QT_MAC_USE_COCOA
       
   442     if (view)
       
   443         return [view window];
       
   444     return 0;
       
   445 #else
       
   446     return HIViewGetWindow(view);
       
   447 #endif
       
   448 }
       
   449 
       
   450 static bool qt_isGenuineQWidget(OSViewRef ref)
       
   451 {
       
   452 #ifdef QT_MAC_USE_COCOA
       
   453     return [ref isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]];
       
   454 #else
       
   455     return HIObjectIsOfClass(HIObjectRef(ref), kObjectQWidget);
       
   456 #endif
       
   457 }
       
   458 
       
   459 bool qt_isGenuineQWidget(const QWidget *window)
       
   460 {
       
   461     return window && qt_isGenuineQWidget(OSViewRef(window->winId()));
       
   462 }
       
   463 
       
   464 Q_GUI_EXPORT OSWindowRef qt_mac_window_for(const QWidget *w)
       
   465 {
       
   466     OSViewRef hiview = qt_mac_nativeview_for(w);
       
   467     if (hiview){
       
   468         OSWindowRef window = qt_mac_window_for(hiview);
       
   469         if (!window && qt_isGenuineQWidget(hiview)) {
       
   470             QWidget *myWindow = w->window();
       
   471             // This is a workaround for NSToolbar. When a widget is hidden
       
   472             // by clicking the toolbar button, Cocoa reparents the widgets
       
   473             // to another window (but Qt doesn't know about it).
       
   474             // When we start showing them, it reparents back,
       
   475             // but at this point it's window is nil, but the window it's being brought
       
   476             // into (the Qt one) is for sure created.
       
   477             // This stops the hierarchy moving under our feet.
       
   478             if (myWindow != w && qt_mac_window_for(qt_mac_nativeview_for(myWindow)))
       
   479                 return qt_mac_window_for(qt_mac_nativeview_for(myWindow));
       
   480 
       
   481             myWindow->d_func()->createWindow_sys();
       
   482             // Reget the hiview since the "create window could potentially move the view (I guess).
       
   483             hiview = qt_mac_nativeview_for(w);
       
   484             window = qt_mac_window_for(hiview);
       
   485         }
       
   486         return window;
       
   487     }
       
   488     return 0;
       
   489 }
       
   490 #ifndef QT_MAC_USE_COCOA
       
   491 /*  Checks if the current group is a 'stay on top' group. If so, the
       
   492     group gets removed from the hash table */
       
   493 static void qt_mac_release_stays_on_top_group(WindowGroupRef group)
       
   494 {
       
   495     for (WindowGroupHash::iterator it = qt_mac_window_groups()->begin(); it != qt_mac_window_groups()->end(); ++it) {
       
   496         if (it.value() == group) {
       
   497             qt_mac_window_groups()->remove(it.key());
       
   498             return;
       
   499         }
       
   500     }
       
   501 }
       
   502 
       
   503 /* Use this function instead of ReleaseWindowGroup, this will be sure to release the
       
   504    stays on top window group (created with qt_mac_get_stays_on_top_group below) */
       
   505 static void qt_mac_release_window_group(WindowGroupRef group)
       
   506 {
       
   507     ReleaseWindowGroup(group);
       
   508     if (GetWindowGroupRetainCount(group) == 0)
       
   509         qt_mac_release_stays_on_top_group(group);
       
   510 }
       
   511 #define ReleaseWindowGroup(x) Are you sure you wanted to do that? (you wanted qt_mac_release_window_group)
       
   512 
       
   513 SInt32 qt_mac_get_group_level(WindowClass wclass)
       
   514 {
       
   515     SInt32 group_level;
       
   516     CGWindowLevel tmpLevel;
       
   517     GetWindowGroupLevelOfType(GetWindowGroupOfClass(wclass), kWindowGroupLevelActive, &tmpLevel);
       
   518     group_level = tmpLevel;
       
   519     return group_level;
       
   520 }
       
   521 #endif
       
   522 
       
   523 #ifndef QT_MAC_USE_COCOA
       
   524 static void qt_mac_set_window_group(OSWindowRef window, Qt::WindowFlags flags, int level)
       
   525 {
       
   526     WindowGroupRef group = 0;
       
   527     if (qt_mac_window_groups()->contains(flags)) {
       
   528         group = qt_mac_window_groups()->value(flags);
       
   529         RetainWindowGroup(group);
       
   530     } else {
       
   531         CreateWindowGroup(kWindowActivationScopeNone, &group);
       
   532         SetWindowGroupLevel(group, level);
       
   533         SetWindowGroupParent(group, GetWindowGroupOfClass(kAllWindowClasses));
       
   534         qt_mac_window_groups()->insert(flags, group);
       
   535     }
       
   536     SetWindowGroup(window, group);
       
   537 }
       
   538 
       
   539 inline static void qt_mac_set_window_group_to_stays_on_top(OSWindowRef window, Qt::WindowType type)
       
   540 {
       
   541     // We create one static stays on top window group so that
       
   542     // all stays on top (aka popups) will fall into the same
       
   543     // group and be able to be raise()'d with releation to one another (from
       
   544     // within the same window group).
       
   545     qt_mac_set_window_group(window, type|Qt::WindowStaysOnTopHint, qt_mac_get_group_level(kOverlayWindowClass));
       
   546 }
       
   547 
       
   548 inline static void qt_mac_set_window_group_to_tooltip(OSWindowRef window)
       
   549 {
       
   550     // Since new groups are created for 'stays on top' windows, the
       
   551     // same must be done for tooltips. Otherwise, tooltips would be drawn
       
   552     // below 'stays on top' widgets even tough they are on the same level.
       
   553     // Also, add 'two' to the group level to make sure they also get on top of popups.
       
   554     qt_mac_set_window_group(window, Qt::ToolTip, qt_mac_get_group_level(kHelpWindowClass)+2);
       
   555 }
       
   556 
       
   557 inline static void qt_mac_set_window_group_to_popup(OSWindowRef window)
       
   558 {
       
   559     // In Qt, a popup is seen as a 'stay on top' window.
       
   560     // Since new groups are created for 'stays on top' windows, the
       
   561     // same must be done for popups. Otherwise, popups would be drawn
       
   562     // below 'stays on top' windows. Add 1 to get above pure stay-on-top windows.
       
   563     qt_mac_set_window_group(window, Qt::Popup, qt_mac_get_group_level(kOverlayWindowClass)+1);
       
   564 }
       
   565 #endif
       
   566 
       
   567 inline static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRect &rect)
       
   568 {
       
   569     if (!widget)
       
   570         return false;
       
   571 
       
   572 #ifndef QT_NO_GRAPHICSVIEW
       
   573     QWidget *tlw = widget->window();
       
   574     QWExtra *extra = qt_widget_private(tlw)->extra;
       
   575     if (extra && extra->proxyWidget) {
       
   576         extra->proxyWidget->update(rect.translated(widget->mapTo(tlw, QPoint())));
       
   577         return true;
       
   578     }
       
   579 #endif
       
   580 
       
   581     return false;
       
   582 }
       
   583 
       
   584 inline static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRegion &rgn)
       
   585 {
       
   586     if (!widget)
       
   587         return false;
       
   588 
       
   589 #ifndef QT_NO_GRAPHICSVIEW
       
   590     QWidget *tlw = widget->window();
       
   591     QWExtra *extra = qt_widget_private(tlw)->extra;
       
   592     if (extra && extra->proxyWidget) {
       
   593         const QPoint offset(widget->mapTo(tlw, QPoint()));
       
   594         const QVector<QRect> rects = rgn.rects();
       
   595         for (int i = 0; i < rects.size(); ++i)
       
   596             extra->proxyWidget->update(rects.at(i).translated(offset));
       
   597         return true;
       
   598     }
       
   599 #endif
       
   600 
       
   601     return false;
       
   602 }
       
   603 
       
   604 void QWidgetPrivate::macUpdateIsOpaque()
       
   605 {
       
   606     Q_Q(QWidget);
       
   607     if (!q->testAttribute(Qt::WA_WState_Created))
       
   608         return;
       
   609 #ifndef QT_MAC_USE_COCOA
       
   610     HIViewFeatures bits;
       
   611     HIViewRef hiview = qt_mac_nativeview_for(q);
       
   612     HIViewGetFeatures(hiview, &bits);
       
   613     if ((bits & kHIViewIsOpaque) == isOpaque)
       
   614         return;
       
   615     if (isOpaque) {
       
   616         HIViewChangeFeatures(hiview, kHIViewIsOpaque, 0);
       
   617     } else {
       
   618         HIViewChangeFeatures(hiview, 0, kHIViewIsOpaque);
       
   619     }
       
   620     if (q->isVisible())
       
   621         HIViewReshapeStructure(qt_mac_nativeview_for(q));
       
   622 #else
       
   623     if (isRealWindow() && !q->testAttribute(Qt::WA_MacBrushedMetal)) {
       
   624         bool opaque = isOpaque;
       
   625         if (extra && extra->imageMask)
       
   626             opaque = false; // we are never opaque when we have a mask.
       
   627         [qt_mac_window_for(q) setOpaque:opaque];
       
   628     }
       
   629 #endif
       
   630 }
       
   631 #ifdef QT_MAC_USE_COCOA
       
   632 static OSWindowRef qt_mac_create_window(QWidget *widget, WindowClass wclass,
       
   633                                         NSUInteger wattr, const QRect &crect)
       
   634 {
       
   635     // Determine if we need to add in our "custom window" attribute. Cocoa is rather clever
       
   636     // in deciding if we need the maximize button or not (i.e., it's resizeable, so you
       
   637     // must need a maximize button). So, the only buttons we have control over are the
       
   638     // close and minimize buttons. If someone wants to customize and NOT have the maximize
       
   639     // button, then we have to do our hack. We only do it for these cases because otherwise
       
   640     // the window looks different when activated. This "QtMacCustomizeWindow" attribute is
       
   641     // intruding on a public space and WILL BREAK in the future.
       
   642     // One can hope that there is a more public API available by that time.
       
   643     Qt::WindowFlags flags = widget ? widget->windowFlags() : Qt::WindowFlags(0);
       
   644     if ((flags & Qt::CustomizeWindowHint)) {
       
   645         if ((flags & (Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint
       
   646                       | Qt::WindowMinimizeButtonHint | Qt::WindowTitleHint))
       
   647             && !(flags & Qt::WindowMaximizeButtonHint))
       
   648             wattr |= QtMacCustomizeWindow;
       
   649     }
       
   650 
       
   651     // If we haven't created the desktop widget, you have to pass the rectangle
       
   652     // in "cocoa coordinates" (i.e., top points to the lower left coordinate).
       
   653     // Otherwise, we do the conversion for you. Since we are the only ones that
       
   654     // create the desktop widget, this is OK (but confusing).
       
   655     NSRect geo = NSMakeRect(crect.left(),
       
   656                             (qt_root_win != 0) ? flipYCoordinate(crect.bottom() + 1) : crect.top(),
       
   657                             crect.width(), crect.height());
       
   658     QMacCocoaAutoReleasePool pool;
       
   659     OSWindowRef window;
       
   660     switch (wclass) {
       
   661     case kMovableModalWindowClass:
       
   662     case kModalWindowClass:
       
   663     case kSheetWindowClass:
       
   664     case kFloatingWindowClass:
       
   665     case kOverlayWindowClass:
       
   666     case kHelpWindowClass: {
       
   667         NSPanel *panel;
       
   668         BOOL needFloating = NO;
       
   669         BOOL worksWhenModal = widget && (widget->windowType() == Qt::Popup);
       
   670         // Add in the extra flags if necessary.
       
   671         switch (wclass) {
       
   672         case kSheetWindowClass:
       
   673             wattr |= NSDocModalWindowMask;
       
   674             break;
       
   675         case kFloatingWindowClass:
       
   676         case kHelpWindowClass:
       
   677             needFloating = YES;
       
   678             wattr |= NSUtilityWindowMask;
       
   679             break;
       
   680         default:
       
   681             break;
       
   682         }
       
   683         panel = [[QT_MANGLE_NAMESPACE(QCocoaPanel) alloc] QT_MANGLE_NAMESPACE(qt_initWithQWidget):widget contentRect:geo styleMask:wattr];
       
   684         [panel setFloatingPanel:needFloating];
       
   685         [panel setWorksWhenModal:worksWhenModal];
       
   686         window = panel;
       
   687         break;
       
   688     }
       
   689     case kDrawerWindowClass: {
       
   690         NSDrawer *drawer = [[NSDrawer alloc] initWithContentSize:geo.size preferredEdge:NSMinXEdge];
       
   691         [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] becomeDelegateForDrawer:drawer widget:widget];
       
   692         QWidget *parentWidget = widget->parentWidget();
       
   693         if (parentWidget)
       
   694             [drawer setParentWindow:qt_mac_window_for(parentWidget)];
       
   695         [drawer setLeadingOffset:0.0];
       
   696         [drawer setTrailingOffset:25.0];
       
   697         window = [[drawer contentView] window];  // Just to make sure we actually return a window
       
   698         break;
       
   699     }
       
   700     default:
       
   701         window = [[QT_MANGLE_NAMESPACE(QCocoaWindow) alloc] QT_MANGLE_NAMESPACE(qt_initWithQWidget):widget contentRect:geo styleMask:wattr];
       
   702         break;
       
   703     }
       
   704     qt_syncCocoaTitleBarButtons(window, widget);
       
   705     return window;
       
   706 }
       
   707 #else
       
   708 static OSWindowRef qt_mac_create_window(QWidget *, WindowClass wclass, WindowAttributes wattr,
       
   709                                         const QRect &crect)
       
   710 {
       
   711     OSWindowRef window;
       
   712     Rect geo;
       
   713     SetRect(&geo, crect.left(), crect.top(), crect.right() + 1, crect.bottom() + 1);
       
   714     OSStatus err;
       
   715     if(geo.right <= geo.left)		geo.right = geo.left + 1;
       
   716     if(geo.bottom <= geo.top)		geo.bottom = geo.top + 1;
       
   717     Rect null_rect;
       
   718 	SetRect(&null_rect, 0, 0, 1, 1);
       
   719     err = CreateNewWindow(wclass, wattr, &null_rect, &window);
       
   720     if(err == noErr) {
       
   721         err = SetWindowBounds(window, kWindowContentRgn, &geo);
       
   722         if(err != noErr)
       
   723             qWarning("QWidget: Internal error (%s:%d)", __FILE__, __LINE__);
       
   724     }
       
   725     return window;
       
   726 }
       
   727 
       
   728 // window events
       
   729 static EventTypeSpec window_events[] = {
       
   730     { kEventClassWindow, kEventWindowClose },
       
   731     { kEventClassWindow, kEventWindowExpanded },
       
   732     { kEventClassWindow, kEventWindowHidden },
       
   733     { kEventClassWindow, kEventWindowZoomed },
       
   734     { kEventClassWindow, kEventWindowCollapsed },
       
   735     { kEventClassWindow, kEventWindowToolbarSwitchMode },
       
   736     { kEventClassWindow, kEventWindowProxyBeginDrag },
       
   737     { kEventClassWindow, kEventWindowProxyEndDrag },
       
   738     { kEventClassWindow, kEventWindowResizeCompleted },
       
   739     { kEventClassWindow, kEventWindowBoundsChanging },
       
   740     { kEventClassWindow, kEventWindowGetRegion },
       
   741     { kEventClassWindow, kEventWindowGetClickModality },
       
   742     { kEventClassWindow, kEventWindowTransitionCompleted },
       
   743 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
       
   744     { kEventClassGesture, kEventGestureStarted },
       
   745     { kEventClassGesture, kEventGestureEnded },
       
   746     { kEventClassGesture, kEventGestureMagnify },
       
   747     { kEventClassGesture, kEventGestureSwipe },
       
   748     { kEventClassGesture, kEventGestureRotate },
       
   749 #endif
       
   750     { kEventClassMouse, kEventMouseDown }
       
   751 };
       
   752 static EventHandlerUPP mac_win_eventUPP = 0;
       
   753 static void cleanup_win_eventUPP()
       
   754 {
       
   755     DisposeEventHandlerUPP(mac_win_eventUPP);
       
   756     mac_win_eventUPP = 0;
       
   757 }
       
   758 static const EventHandlerUPP make_win_eventUPP()
       
   759 {
       
   760     if(mac_win_eventUPP)
       
   761         return mac_win_eventUPP;
       
   762     qAddPostRoutine(cleanup_win_eventUPP);
       
   763     return mac_win_eventUPP = NewEventHandlerUPP(QWidgetPrivate::qt_window_event);
       
   764 }
       
   765 OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, void *)
       
   766 {
       
   767     QScopedLoopLevelCounter loopLevelCounter(qApp->d_func()->threadData);
       
   768     bool handled_event = true;
       
   769     UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
       
   770     switch(eclass) {
       
   771     case kEventClassWindow: {
       
   772         WindowRef wid = 0;
       
   773         GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0,
       
   774                           sizeof(WindowRef), 0, &wid);
       
   775         QWidget *widget = qt_mac_find_window(wid);
       
   776         if(!widget) {
       
   777             handled_event = false;
       
   778         } else if(ekind == kEventWindowGetClickModality) {
       
   779             // Carbon will send us kEventWindowGetClickModality before every
       
   780             // mouse press / release event. By returning 'true', we tell Carbon
       
   781             // that we would like the event target to receive the mouse event even
       
   782             // if the target is modally shaddowed. In Qt, this makes sense when we
       
   783             // e.g. have a popup showing, as the popup will grab the event
       
   784             // and perhaps use it to close itself.
       
   785             // By also setting the current modal window back into the event, we
       
   786             // help Carbon determining which window is supposed to be raised.
       
   787             handled_event = qApp->activePopupWidget() ? true : false;
       
   788         } else if(ekind == kEventWindowClose) {
       
   789             widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
       
   790             QMenuBar::macUpdateMenuBar();
       
   791         } else if (ekind == kEventWindowTransitionCompleted) {
       
   792             WindowTransitionAction transitionAction;
       
   793             GetEventParameter(event, kEventParamWindowTransitionAction, typeWindowTransitionAction,
       
   794                               0, sizeof(transitionAction), 0, &transitionAction);
       
   795             if (transitionAction == kWindowHideTransitionAction)
       
   796                 widget->hide();
       
   797         } else if(ekind == kEventWindowExpanded) {
       
   798             Qt::WindowStates currState = Qt::WindowStates(widget->data->window_state);
       
   799             Qt::WindowStates newState = currState;
       
   800             if (currState & Qt::WindowMinimized)
       
   801                 newState &= ~Qt::WindowMinimized;
       
   802             if (!(currState & Qt::WindowActive))
       
   803                 newState |= Qt::WindowActive;
       
   804             if (newState != currState) {
       
   805                 // newState will differ from currState if the window
       
   806                 // was expanded after clicking on the jewels (as opposed
       
   807                 // to calling QWidget::setWindowState)
       
   808                 widget->data->window_state = newState;
       
   809                 QWindowStateChangeEvent e(currState);
       
   810                 QApplication::sendSpontaneousEvent(widget, &e);
       
   811             }
       
   812 
       
   813             QShowEvent qse;
       
   814             QApplication::sendSpontaneousEvent(widget, &qse);
       
   815         } else if(ekind == kEventWindowZoomed) {
       
   816             WindowPartCode windowPart;
       
   817             GetEventParameter(event, kEventParamWindowPartCode,
       
   818                               typeWindowPartCode, 0, sizeof(windowPart), 0, &windowPart);
       
   819             if(windowPart == inZoomIn && widget->isMaximized()) {
       
   820 
       
   821                 widget->data->window_state = widget->data->window_state & ~Qt::WindowMaximized;
       
   822                 QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state | Qt::WindowMaximized));
       
   823                 QApplication::sendSpontaneousEvent(widget, &e);
       
   824             } else if(windowPart == inZoomOut && !widget->isMaximized()) {
       
   825                 widget->data->window_state = widget->data->window_state | Qt::WindowMaximized;
       
   826                 QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state
       
   827                                                            & ~Qt::WindowMaximized));
       
   828                 QApplication::sendSpontaneousEvent(widget, &e);
       
   829             }
       
   830             extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
       
   831             qt_button_down = 0;
       
   832         } else if(ekind == kEventWindowCollapsed) {
       
   833             if (!widget->isMinimized()) {
       
   834                 widget->data->window_state = widget->data->window_state | Qt::WindowMinimized;
       
   835                 QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state & ~Qt::WindowMinimized));
       
   836                 QApplication::sendSpontaneousEvent(widget, &e);
       
   837             }
       
   838 
       
   839             // Deactivate this window:
       
   840             if (widget->isActiveWindow() && !(widget->windowType() == Qt::Popup)) {
       
   841                 QWidget *w = 0;
       
   842                 if (widget->parentWidget())
       
   843                     w = widget->parentWidget()->window();
       
   844                 if (!w || (!w->isVisible() && !w->isMinimized())) {
       
   845                     for (WindowPtr wp = GetFrontWindowOfClass(kDocumentWindowClass, true);
       
   846                         wp; wp = GetNextWindowOfClass(wp, kDocumentWindowClass, true)) {
       
   847                         if ((w = qt_mac_find_window(wp)))
       
   848                             break;
       
   849                     }
       
   850                 }
       
   851                 if(!(w && w->isVisible() && !w->isMinimized()))
       
   852                     qApp->setActiveWindow(0);
       
   853             }
       
   854 
       
   855             //we send a hide to be like X11/Windows
       
   856             QEvent e(QEvent::Hide);
       
   857             QApplication::sendSpontaneousEvent(widget, &e);
       
   858             extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
       
   859             qt_button_down = 0;
       
   860         } else if(ekind == kEventWindowToolbarSwitchMode) {
       
   861             macSendToolbarChangeEvent(widget);
       
   862             HIToolbarRef toolbar;
       
   863             if (GetWindowToolbar(wid, &toolbar) == noErr) {
       
   864                 if (toolbar) {
       
   865                     // Let HIToolbar do its thang, but things like the OpenGL context
       
   866                     // needs to know about it.
       
   867                     CallNextEventHandler(er, event);
       
   868                     qt_event_request_window_change(widget);
       
   869                     widget->data->fstrut_dirty = true;
       
   870                 }
       
   871             }
       
   872         } else if(ekind == kEventWindowGetRegion) {
       
   873             WindowRef window;
       
   874             GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0,
       
   875                               sizeof(window), 0, &window);
       
   876             WindowRegionCode wcode;
       
   877             GetEventParameter(event, kEventParamWindowRegionCode, typeWindowRegionCode, 0,
       
   878                               sizeof(wcode), 0, &wcode);
       
   879             if (wcode != kWindowOpaqueRgn){
       
   880                 // If the region is kWindowOpaqueRgn, don't call next
       
   881                 // event handler cause this will make the shadow of
       
   882                 // masked windows become offset. Unfortunately, we're not sure why.
       
   883                 CallNextEventHandler(er, event);
       
   884             }
       
   885 			RgnHandle rgn;
       
   886             GetEventParameter(event, kEventParamRgnHandle, typeQDRgnHandle, 0,
       
   887                               sizeof(rgn), 0, &rgn);
       
   888 
       
   889             if(QWidgetPrivate::qt_widget_rgn(qt_mac_find_window(window), wcode, rgn, false))
       
   890                 SetEventParameter(event, kEventParamRgnHandle, typeQDRgnHandle, sizeof(rgn), &rgn);
       
   891         } else if(ekind == kEventWindowProxyBeginDrag) {
       
   892             QIconDragEvent e;
       
   893             QApplication::sendSpontaneousEvent(widget, &e);
       
   894         } else if(ekind == kEventWindowResizeCompleted) {
       
   895             // Create a mouse up event, since such an event is not send by carbon to the
       
   896             // application event handler (while a mouse down <b>is</b> on kEventWindowResizeStarted)
       
   897             EventRef mouseUpEvent;
       
   898             CreateEvent(0, kEventClassMouse, kEventMouseUp, 0, kEventAttributeUserEvent, &mouseUpEvent);
       
   899             UInt16 mbutton = kEventMouseButtonPrimary;
       
   900             SetEventParameter(mouseUpEvent, kEventParamMouseButton, typeMouseButton, sizeof(mbutton), &mbutton);
       
   901             WindowRef window;
       
   902             GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0, sizeof(window), 0, &window);
       
   903             Rect dragRect;
       
   904             GetWindowBounds(window, kWindowGrowRgn, &dragRect);
       
   905             Point pos = {dragRect.bottom, dragRect.right};
       
   906             SetEventParameter(mouseUpEvent, kEventParamMouseLocation, typeQDPoint, sizeof(pos), &pos);
       
   907             SendEventToApplication(mouseUpEvent);
       
   908             ReleaseEvent(mouseUpEvent);
       
   909         } else if(ekind == kEventWindowBoundsChanging) {
       
   910             UInt32 flags = 0;
       
   911             GetEventParameter(event, kEventParamAttributes, typeUInt32, 0,
       
   912                                   sizeof(flags), 0, &flags);
       
   913             Rect nr;
       
   914             GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, 0,
       
   915                                   sizeof(nr), 0, &nr);
       
   916 
       
   917             QRect newRect(nr.left, nr.top, nr.right - nr.left, nr.bottom - nr.top);
       
   918 
       
   919             QTLWExtra * const tlwExtra = widget->d_func()->maybeTopData();
       
   920             if (tlwExtra && tlwExtra->isSetGeometry == 1) {
       
   921                 widget->d_func()->setGeometry_sys_helper(newRect.left(), newRect.top(), newRect.width(), newRect.height(), tlwExtra->isMove);
       
   922             } else {
       
   923                 //implicitly removes the maximized bit
       
   924                 if((widget->data->window_state & Qt::WindowMaximized) &&
       
   925                    IsWindowInStandardState(wid, 0, 0)) {
       
   926                     widget->data->window_state &= ~Qt::WindowMaximized;
       
   927                     QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state
       
   928                                                 | Qt::WindowMaximized));
       
   929                     QApplication::sendSpontaneousEvent(widget, &e);
       
   930 
       
   931                 }
       
   932 
       
   933                 handled_event = false;
       
   934                 const QRect oldRect = widget->data->crect;
       
   935                 if((flags & kWindowBoundsChangeOriginChanged)) {
       
   936                     if(nr.left != oldRect.x() || nr.top != oldRect.y()) {
       
   937                         widget->data->crect.moveTo(nr.left, nr.top);
       
   938                         QMoveEvent qme(widget->data->crect.topLeft(), oldRect.topLeft());
       
   939                         QApplication::sendSpontaneousEvent(widget, &qme);
       
   940                     }
       
   941                 }
       
   942                 if((flags & kWindowBoundsChangeSizeChanged)) {
       
   943                     if (widget->isWindow()) {
       
   944                         QSize newSize = QLayout::closestAcceptableSize(widget, newRect.size());
       
   945                         int dh = newSize.height() - newRect.height();
       
   946                         int dw = newSize.width() - newRect.width();
       
   947                         if (dw != 0 || dh != 0) {
       
   948                             handled_event = true;  // We want to change the bounds, so we handle the event
       
   949 
       
   950                             // set the rect, so we can also do the resize down below (yes, we need to resize).
       
   951                             newRect.setBottom(newRect.bottom() + dh);
       
   952                             newRect.setRight(newRect.right() + dw);
       
   953 
       
   954                             nr.left = newRect.x();
       
   955                             nr.top = newRect.y();
       
   956                             nr.right = nr.left + newRect.width();
       
   957                             nr.bottom = nr.top + newRect.height();
       
   958                             SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), &nr);
       
   959                         }
       
   960                     }
       
   961 
       
   962                     if (oldRect.width() != newRect.width() || oldRect.height() != newRect.height()) {
       
   963                         widget->data->crect.setSize(newRect.size());
       
   964                         HIRect bounds = CGRectMake(0, 0, newRect.width(), newRect.height());
       
   965 
       
   966                         // If the WA_StaticContents attribute is set we can optimize the resize
       
   967                         // by only repainting the newly exposed area. We do this by disabling
       
   968                         // painting when setting the size of the view. The OS will invalidate
       
   969                         // the newly exposed area for us.
       
   970                         const bool staticContents = widget->testAttribute(Qt::WA_StaticContents);
       
   971                         const HIViewRef view = qt_mac_nativeview_for(widget);
       
   972                         if (staticContents)
       
   973                             HIViewSetDrawingEnabled(view, false);
       
   974                         HIViewSetFrame(view, &bounds);
       
   975                         if (staticContents)
       
   976                             HIViewSetDrawingEnabled(view, true);
       
   977 
       
   978                         QResizeEvent qre(newRect.size(), oldRect.size());
       
   979                         QApplication::sendSpontaneousEvent(widget, &qre);
       
   980                         qt_event_request_window_change(widget);
       
   981                     }
       
   982                 }
       
   983             }
       
   984         } else if (ekind == kEventWindowHidden) {
       
   985             // Make sure that we also hide any visible sheets on our window.
       
   986             // Cocoa does the right thing for us.
       
   987             const QObjectList children = widget->children();
       
   988             const int childCount = children.count();
       
   989             for (int i = 0; i < childCount; ++i) {
       
   990                 QObject *obj = children.at(i);
       
   991                 if (obj->isWidgetType()) {
       
   992                     QWidget *widget = static_cast<QWidget *>(obj);
       
   993                     if (qt_mac_is_macsheet(widget) && widget->isVisible())
       
   994                         widget->hide();
       
   995                 }
       
   996             }
       
   997         } else {
       
   998             handled_event = false;
       
   999         }
       
  1000         break; }
       
  1001     case kEventClassMouse: {
       
  1002 #if 0
       
  1003         return SendEventToApplication(event);
       
  1004 #endif
       
  1005 
       
  1006         bool send_to_app = false;
       
  1007         {
       
  1008             WindowPartCode wpc;
       
  1009             if (GetEventParameter(event, kEventParamWindowPartCode, typeWindowPartCode, 0,
       
  1010                                   sizeof(wpc), 0, &wpc) == noErr && wpc != inContent)
       
  1011                 send_to_app = true;
       
  1012         }
       
  1013         if(!send_to_app) {
       
  1014             WindowRef window;
       
  1015             if(GetEventParameter(event, kEventParamWindowRef, typeWindowRef, 0,
       
  1016                                  sizeof(window), 0, &window) == noErr) {
       
  1017                 HIViewRef hiview;
       
  1018                 if(HIViewGetViewForMouseEvent(HIViewGetRoot(window), event, &hiview) == noErr) {
       
  1019                     if(QWidget *w = QWidget::find((WId)hiview)) {
       
  1020 #if 0
       
  1021                         send_to_app = !w->isActiveWindow();
       
  1022 #else
       
  1023                         Q_UNUSED(w);
       
  1024                         send_to_app = true;
       
  1025 #endif
       
  1026                     }
       
  1027                 }
       
  1028             }
       
  1029         }
       
  1030         if(send_to_app)
       
  1031             return SendEventToApplication(event);
       
  1032         handled_event = false;
       
  1033         break; }
       
  1034 
       
  1035 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
       
  1036     case kEventClassGesture: {
       
  1037         // First, find the widget that was under
       
  1038         // the mouse when the gesture happened:
       
  1039         HIPoint screenLocation;
       
  1040         if (GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, 0,
       
  1041                     sizeof(screenLocation), 0, &screenLocation) != noErr) {
       
  1042             handled_event = false;
       
  1043             break;
       
  1044         }
       
  1045         QWidget *widget = QApplication::widgetAt(screenLocation.x, screenLocation.y);
       
  1046         if (!widget) {
       
  1047             handled_event = false;
       
  1048             break;
       
  1049         }
       
  1050 
       
  1051         QNativeGestureEvent qNGEvent;
       
  1052         qNGEvent.position = QPoint(screenLocation.x, screenLocation.y);
       
  1053 
       
  1054         switch (ekind) {
       
  1055             case kEventGestureStarted:
       
  1056                 qNGEvent.gestureType = QNativeGestureEvent::GestureBegin;
       
  1057                 break;
       
  1058             case kEventGestureEnded:
       
  1059                 qNGEvent.gestureType = QNativeGestureEvent::GestureEnd;
       
  1060                 break;
       
  1061             case kEventGestureRotate: {
       
  1062                 CGFloat amount;
       
  1063                 if (GetEventParameter(event, kEventParamRotationAmount, typeCGFloat, 0,
       
  1064                             sizeof(amount), 0, &amount) != noErr) {
       
  1065                     handled_event = false;
       
  1066                     break;
       
  1067                 }
       
  1068                 qNGEvent.gestureType = QNativeGestureEvent::Rotate;
       
  1069                 qNGEvent.percentage = float(-amount);
       
  1070                 break; }
       
  1071             case kEventGestureSwipe: {
       
  1072                 HIPoint swipeDirection;
       
  1073                 if (GetEventParameter(event, kEventParamSwipeDirection, typeHIPoint, 0,
       
  1074                             sizeof(swipeDirection), 0, &swipeDirection) != noErr) {
       
  1075                     handled_event = false;
       
  1076                     break;
       
  1077                 }
       
  1078                 qNGEvent.gestureType = QNativeGestureEvent::Swipe;
       
  1079                 if (swipeDirection.x == 1)
       
  1080                     qNGEvent.angle = 180.0f;
       
  1081                 else if (swipeDirection.x == -1)
       
  1082                     qNGEvent.angle = 0.0f;
       
  1083                 else if (swipeDirection.y == 1)
       
  1084                     qNGEvent.angle = 90.0f;
       
  1085                 else if (swipeDirection.y == -1)
       
  1086                     qNGEvent.angle = 270.0f;
       
  1087                 break; }
       
  1088             case kEventGestureMagnify: {
       
  1089                 CGFloat amount;
       
  1090                 if (GetEventParameter(event, kEventParamMagnificationAmount, typeCGFloat, 0,
       
  1091                             sizeof(amount), 0, &amount) != noErr) {
       
  1092                     handled_event = false;
       
  1093                     break;
       
  1094                 }
       
  1095                 qNGEvent.gestureType = QNativeGestureEvent::Zoom;
       
  1096                 qNGEvent.percentage = float(amount);
       
  1097                 break; }
       
  1098         }
       
  1099 
       
  1100         QApplication::sendSpontaneousEvent(widget, &qNGEvent);
       
  1101     break; }
       
  1102 #endif // gestures
       
  1103 
       
  1104     default:
       
  1105         handled_event = false;
       
  1106     }
       
  1107     if(!handled_event) //let the event go through
       
  1108         return eventNotHandledErr;
       
  1109     return noErr; //we eat the event
       
  1110 }
       
  1111 
       
  1112 // widget events
       
  1113 static HIObjectClassRef widget_class = 0;
       
  1114 static EventTypeSpec widget_events[] = {
       
  1115     { kEventClassHIObject, kEventHIObjectConstruct },
       
  1116     { kEventClassHIObject, kEventHIObjectDestruct },
       
  1117 
       
  1118     { kEventClassControl, kEventControlDraw },
       
  1119     { kEventClassControl, kEventControlInitialize },
       
  1120     { kEventClassControl, kEventControlGetPartRegion },
       
  1121     { kEventClassControl, kEventControlGetClickActivation },
       
  1122     { kEventClassControl, kEventControlSetFocusPart },
       
  1123     { kEventClassControl, kEventControlDragEnter },
       
  1124     { kEventClassControl, kEventControlDragWithin },
       
  1125     { kEventClassControl, kEventControlDragLeave },
       
  1126     { kEventClassControl, kEventControlDragReceive },
       
  1127     { kEventClassControl, kEventControlOwningWindowChanged },
       
  1128     { kEventClassControl, kEventControlBoundsChanged },
       
  1129     { kEventClassControl, kEventControlGetSizeConstraints },
       
  1130     { kEventClassControl, kEventControlVisibilityChanged },
       
  1131 
       
  1132     { kEventClassMouse, kEventMouseDown },
       
  1133     { kEventClassMouse, kEventMouseUp },
       
  1134     { kEventClassMouse, kEventMouseMoved },
       
  1135     { kEventClassMouse, kEventMouseDragged }
       
  1136 };
       
  1137 static EventHandlerUPP mac_widget_eventUPP = 0;
       
  1138 static void cleanup_widget_eventUPP()
       
  1139 {
       
  1140     DisposeEventHandlerUPP(mac_widget_eventUPP);
       
  1141     mac_widget_eventUPP = 0;
       
  1142 }
       
  1143 static const EventHandlerUPP make_widget_eventUPP()
       
  1144 {
       
  1145     if(mac_widget_eventUPP)
       
  1146         return mac_widget_eventUPP;
       
  1147     qAddPostRoutine(cleanup_widget_eventUPP);
       
  1148     return mac_widget_eventUPP = NewEventHandlerUPP(QWidgetPrivate::qt_widget_event);
       
  1149 }
       
  1150 OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event, void *)
       
  1151 {
       
  1152     QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData);
       
  1153 
       
  1154     bool handled_event = true;
       
  1155     UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
       
  1156     switch(eclass) {
       
  1157     case kEventClassHIObject: {
       
  1158         HIViewRef view = 0;
       
  1159         GetEventParameter(event, kEventParamHIObjectInstance, typeHIObjectRef,
       
  1160                           0, sizeof(view), 0, &view);
       
  1161         if(ekind == kEventHIObjectConstruct) {
       
  1162             if(view) {
       
  1163                 HIViewChangeFeatures(view, kHIViewAllowsSubviews, 0);
       
  1164                 SetEventParameter(event, kEventParamHIObjectInstance,
       
  1165                                   typeVoidPtr, sizeof(view), &view);
       
  1166             }
       
  1167         } else if(ekind == kEventHIObjectDestruct) {
       
  1168             //nothing to really do.. or is there?
       
  1169         } else {
       
  1170             handled_event = false;
       
  1171         }
       
  1172         break; }
       
  1173     case kEventClassControl: {
       
  1174         QWidget *widget = 0;
       
  1175         HIViewRef hiview = 0;
       
  1176         if(GetEventParameter(event, kEventParamDirectObject, typeControlRef,
       
  1177                              0, sizeof(hiview), 0, &hiview) == noErr)
       
  1178             widget = QWidget::find((WId)hiview);
       
  1179         if (widget && widget->macEvent(er, event))
       
  1180             return noErr;
       
  1181         if(ekind == kEventControlDraw) {
       
  1182             if(widget && qt_isGenuineQWidget(hiview)) {
       
  1183 
       
  1184                 // if there is a window change event pending for any gl child wigets,
       
  1185                 // send it immediately. (required for flicker-free resizing)
       
  1186                 extern void qt_mac_send_posted_gl_updates(QWidget *widget);
       
  1187                 qt_mac_send_posted_gl_updates(widget);
       
  1188 
       
  1189                 if (QApplicationPrivate::graphicsSystem() && !widget->d_func()->paintOnScreen()) {
       
  1190                     widget->d_func()->syncBackingStore();
       
  1191                     widget->d_func()->dirtyOnWidget = QRegion();
       
  1192                     return noErr;
       
  1193                 }
       
  1194 
       
  1195                 //requested rgn
       
  1196                 RgnHandle rgn;
       
  1197                 GetEventParameter(event, kEventParamRgnHandle, typeQDRgnHandle, 0, sizeof(rgn), 0, &rgn);
       
  1198                 QRegion qrgn(qt_mac_convert_mac_region(rgn));
       
  1199 
       
  1200                 //update handles
       
  1201                 GrafPtr qd = 0;
       
  1202                 CGContextRef cg = 0;
       
  1203                 if(GetEventParameter(event, kEventParamCGContextRef, typeCGContextRef, 0, sizeof(cg), 0, &cg) != noErr) {
       
  1204                     Q_ASSERT(false);
       
  1205                 }
       
  1206                 widget->d_func()->hd = cg;
       
  1207                 widget->d_func()->qd_hd = qd;
       
  1208                 CGContextSaveGState(cg);
       
  1209 
       
  1210 #ifdef DEBUG_WIDGET_PAINT
       
  1211                 const bool doDebug = true;
       
  1212                 if(doDebug)  {
       
  1213                     qDebug("asked to draw %p[%p] [%s::%s] %p[%p] [%d] [%dx%d]", widget, hiview, widget->metaObject()->className(),
       
  1214                            widget->objectName().local8Bit().data(), widget->parentWidget(),
       
  1215                            (HIViewRef)(widget->parentWidget() ? qt_mac_nativeview_for(widget->parentWidget()) : (HIViewRef)0),
       
  1216                            HIViewIsCompositingEnabled(hiview), qt_mac_posInWindow(widget).x(), qt_mac_posInWindow(widget).y());
       
  1217 #if 0
       
  1218                     QVector<QRect> region_rects = qrgn.rects();
       
  1219                     qDebug("Region! %d", region_rects.count());
       
  1220                     for(int i = 0; i < region_rects.count(); i++)
       
  1221                         qDebug("%d %d %d %d", region_rects[i].x(), region_rects[i].y(),
       
  1222                                region_rects[i].width(), region_rects[i].height());
       
  1223                     region_rects = widget->d_func()->clp.rects();
       
  1224                     qDebug("Widget Region! %d", region_rects.count());
       
  1225                     for(int i = 0; i < region_rects.count(); i++)
       
  1226                         qDebug("%d %d %d %d", region_rects[i].x(), region_rects[i].y(),
       
  1227                                region_rects[i].width(), region_rects[i].height());
       
  1228 #endif
       
  1229                 }
       
  1230 #endif
       
  1231                 if (widget->isVisible() && widget->updatesEnabled()) { //process the actual paint event.
       
  1232                     if(widget->testAttribute(Qt::WA_WState_InPaintEvent))
       
  1233                         qWarning("QWidget::repaint: Recursive repaint detected");
       
  1234 
       
  1235                     QPoint redirectionOffset(0, 0);
       
  1236                     QWidget *tl = widget->window();
       
  1237                     if (tl) {
       
  1238                         Qt::WindowFlags flags = tl->windowFlags();
       
  1239                         if (flags & Qt::FramelessWindowHint
       
  1240                             || (flags & Qt::CustomizeWindowHint && !(flags & Qt::WindowTitleHint))) {
       
  1241                             if(tl->d_func()->extra && !tl->d_func()->extra->mask.isEmpty())
       
  1242                                 redirectionOffset += tl->d_func()->extra->mask.boundingRect().topLeft();
       
  1243                         }
       
  1244                     }
       
  1245 
       
  1246                     //setup the context
       
  1247                     widget->setAttribute(Qt::WA_WState_InPaintEvent);
       
  1248                     QPaintEngine *engine = widget->paintEngine();
       
  1249                     if (engine)
       
  1250                         engine->setSystemClip(qrgn);
       
  1251 
       
  1252                     //handle the erase
       
  1253                     if (engine && (!widget->testAttribute(Qt::WA_NoSystemBackground)
       
  1254                         && (widget->isWindow() || widget->autoFillBackground())
       
  1255                         || widget->testAttribute(Qt::WA_TintedBackground)
       
  1256                         || widget->testAttribute(Qt::WA_StyledBackground))) {
       
  1257 #ifdef DEBUG_WIDGET_PAINT
       
  1258                         if(doDebug)
       
  1259                             qDebug(" Handling erase for [%s::%s]", widget->metaObject()->className(),
       
  1260                                    widget->objectName().local8Bit().data());
       
  1261 #endif
       
  1262                         if (!redirectionOffset.isNull())
       
  1263                             widget->d_func()->setRedirected(widget, redirectionOffset);
       
  1264 
       
  1265                         bool was_unclipped = widget->testAttribute(Qt::WA_PaintUnclipped);
       
  1266                         widget->setAttribute(Qt::WA_PaintUnclipped, false);
       
  1267                         QPainter p(widget);
       
  1268                         p.setClipping(false);
       
  1269                         if(was_unclipped)
       
  1270                             widget->setAttribute(Qt::WA_PaintUnclipped);
       
  1271                         widget->d_func()->paintBackground(&p, qrgn, widget->isWindow() ? DrawAsRoot : 0);
       
  1272                         if (widget->testAttribute(Qt::WA_TintedBackground)) {
       
  1273                             QColor tint = widget->palette().window().color();
       
  1274                             tint.setAlphaF(.6);
       
  1275                             const QVector<QRect> &rects = qrgn.rects();
       
  1276                             for (int i = 0; i < rects.size(); ++i)
       
  1277                                 p.fillRect(rects.at(i), tint);
       
  1278                         }
       
  1279                         p.end();
       
  1280                         if (!redirectionOffset.isNull())
       
  1281                             widget->d_func()->restoreRedirected();
       
  1282                     }
       
  1283 
       
  1284                     if (widget->isWindow() && !widget->d_func()->isOpaque
       
  1285                            && !widget->testAttribute(Qt::WA_MacBrushedMetal)) {
       
  1286                         QRect qrgnRect = qrgn.boundingRect();
       
  1287                         CGContextClearRect(cg, CGRectMake(qrgnRect.x(), qrgnRect.y(), qrgnRect.width(), qrgnRect.height()));
       
  1288                     }
       
  1289 
       
  1290 
       
  1291                     if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget))
       
  1292                         CallNextEventHandler(er, event);
       
  1293 
       
  1294                     //send the paint
       
  1295                     redirectionOffset += widget->data->wrect.topLeft(); // Map from system to qt coordinates
       
  1296                     if (!redirectionOffset.isNull())
       
  1297                         widget->d_func()->setRedirected(widget, redirectionOffset);
       
  1298                     qrgn.translate(redirectionOffset);
       
  1299                     QPaintEvent e(qrgn);
       
  1300                     widget->d_func()->dirtyOnWidget = QRegion();
       
  1301 #ifdef QT3_SUPPORT
       
  1302                     e.setErased(true);
       
  1303 #endif
       
  1304                     QApplication::sendSpontaneousEvent(widget, &e);
       
  1305                     if (!redirectionOffset.isNull())
       
  1306                         widget->d_func()->restoreRedirected();
       
  1307 
       
  1308                     //cleanup
       
  1309                     if (engine)
       
  1310                         engine->setSystemClip(QRegion());
       
  1311 
       
  1312                     widget->setAttribute(Qt::WA_WState_InPaintEvent, false);
       
  1313                     if(!widget->testAttribute(Qt::WA_PaintOutsidePaintEvent) && widget->paintingActive())
       
  1314                         qWarning("QWidget: It is dangerous to leave painters active on a widget outside of the PaintEvent");
       
  1315                 }
       
  1316 
       
  1317                 widget->d_func()->hd = 0;
       
  1318                 widget->d_func()->qd_hd = 0;
       
  1319                 CGContextRestoreGState(cg);
       
  1320             } else if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget)) {
       
  1321                 CallNextEventHandler(er, event);
       
  1322             }
       
  1323         } else if(ekind == kEventControlInitialize) {
       
  1324             if(HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget)) {
       
  1325                 UInt32 features = kControlSupportsDragAndDrop | kControlSupportsClickActivation | kControlSupportsFocus;
       
  1326                 SetEventParameter(event, kEventParamControlFeatures, typeUInt32, sizeof(features), &features);
       
  1327             } else {
       
  1328                 handled_event = false;
       
  1329             }
       
  1330         } else if(ekind == kEventControlSetFocusPart) {
       
  1331             if(widget) {
       
  1332                 ControlPartCode part;
       
  1333                 GetEventParameter(event, kEventParamControlPart, typeControlPartCode, 0,
       
  1334                                   sizeof(part), 0, &part);
       
  1335                 if(part == kControlFocusNoPart){
       
  1336                     if (widget->hasFocus())
       
  1337                         QApplicationPrivate::setFocusWidget(0, Qt::OtherFocusReason);
       
  1338                 } else
       
  1339                     widget->setFocus();
       
  1340             }
       
  1341             if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget))
       
  1342                 CallNextEventHandler(er, event);
       
  1343         } else if(ekind == kEventControlGetClickActivation) {
       
  1344             ClickActivationResult clickT = kActivateAndIgnoreClick;
       
  1345             SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult,
       
  1346                               sizeof(clickT), &clickT);
       
  1347         } else if(ekind == kEventControlGetPartRegion) {
       
  1348             handled_event = false;
       
  1349             if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget) && CallNextEventHandler(er, event) == noErr) {
       
  1350                 handled_event = true;
       
  1351                 break;
       
  1352             }
       
  1353             if(widget && !widget->isWindow()) {
       
  1354                 ControlPartCode part;
       
  1355                 GetEventParameter(event, kEventParamControlPart, typeControlPartCode, 0,
       
  1356                                   sizeof(part), 0, &part);
       
  1357                 if(part == kControlClickableMetaPart && widget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
       
  1358                     RgnHandle rgn;
       
  1359                     GetEventParameter(event, kEventParamControlRegion, typeQDRgnHandle, 0,
       
  1360                                       sizeof(rgn), 0, &rgn);
       
  1361                     SetEmptyRgn(rgn);
       
  1362                     handled_event = true;
       
  1363                 } else if(part == kControlStructureMetaPart || part == kControlClickableMetaPart) {
       
  1364                     RgnHandle rgn;
       
  1365                     GetEventParameter(event, kEventParamControlRegion, typeQDRgnHandle, 0,
       
  1366                                       sizeof(rgn), 0, &rgn);
       
  1367                     SetRectRgn(rgn, 0, 0, widget->width(), widget->height());
       
  1368                     if(QWidgetPrivate::qt_widget_rgn(widget, kWindowStructureRgn, rgn, false))
       
  1369                         handled_event = true;
       
  1370                 } else if(part == kControlOpaqueMetaPart) {
       
  1371                     if(widget->d_func()->isOpaque) {
       
  1372                         RgnHandle rgn;
       
  1373                         GetEventParameter(event, kEventParamControlRegion, typeQDRgnHandle, 0,
       
  1374                                           sizeof(RgnHandle), 0, &rgn);
       
  1375                         SetRectRgn(rgn, 0, 0, widget->width(), widget->height());
       
  1376                         QWidgetPrivate::qt_widget_rgn(widget, kWindowStructureRgn, rgn, false);
       
  1377                         SetEventParameter(event, kEventParamControlRegion, typeQDRgnHandle,
       
  1378                                 sizeof(RgnHandle), &rgn);
       
  1379                         handled_event = true;
       
  1380                     }
       
  1381                 }
       
  1382             }
       
  1383         } else if(ekind == kEventControlOwningWindowChanged) {
       
  1384             if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget))
       
  1385                 CallNextEventHandler(er, event);
       
  1386             if(widget && qt_mac_window_for(hiview)) {
       
  1387                 WindowRef foo = 0;
       
  1388                 GetEventParameter(event, kEventParamControlCurrentOwningWindow, typeWindowRef, 0,
       
  1389                                   sizeof(foo), 0, &foo);
       
  1390                 widget->d_func()->initWindowPtr();
       
  1391             }
       
  1392             if (widget)
       
  1393                 qt_event_request_window_change(widget);
       
  1394         } else if(ekind == kEventControlDragEnter || ekind == kEventControlDragWithin ||
       
  1395                   ekind == kEventControlDragLeave || ekind == kEventControlDragReceive) {
       
  1396             // dnd are really handled in qdnd_mac.cpp,
       
  1397             // just modularize the code a little...
       
  1398             DragRef drag;
       
  1399             GetEventParameter(event, kEventParamDragRef, typeDragRef, 0, sizeof(drag), 0, &drag);
       
  1400             handled_event = false;
       
  1401             bool drag_allowed = false;
       
  1402 
       
  1403             QWidget *dropWidget = widget;
       
  1404             if (qobject_cast<QFocusFrame *>(widget)){
       
  1405                 // We might shadow widgets underneath the focus
       
  1406                 // frame, so stay interrested, and let the dnd through
       
  1407                 drag_allowed = true;
       
  1408                 handled_event = true;
       
  1409                 Point where;
       
  1410                 GetDragMouse(drag, &where, 0);
       
  1411                 dropWidget = QApplication::widgetAt(QPoint(where.h, where.v));
       
  1412 
       
  1413                 if (dropWidget != QDragManager::self()->currentTarget()) {
       
  1414                     // We have to 'fake' enter and leave events for the shaddowed widgets:
       
  1415                     if (ekind == kEventControlDragEnter) {
       
  1416                         if (QDragManager::self()->currentTarget())
       
  1417                             QDragManager::self()->currentTarget()->d_func()->qt_mac_dnd_event(kEventControlDragLeave, drag);
       
  1418                         if (dropWidget) {
       
  1419                             dropWidget->d_func()->qt_mac_dnd_event(kEventControlDragEnter, drag);
       
  1420                         }
       
  1421                         // Set dropWidget to zero, so qt_mac_dnd_event
       
  1422                         // doesn't get called a second time below:
       
  1423                         dropWidget = 0;
       
  1424                     } else if (ekind == kEventControlDragLeave) {
       
  1425                         dropWidget = QDragManager::self()->currentTarget();
       
  1426                         if (dropWidget) {
       
  1427                             dropWidget->d_func()->qt_mac_dnd_event(kEventControlDragLeave, drag);
       
  1428                         }
       
  1429                         // Set dropWidget to zero, so qt_mac_dnd_event
       
  1430                         // doesn't get called a second time below:
       
  1431                         dropWidget = 0;
       
  1432                     }
       
  1433                 }
       
  1434             }
       
  1435 
       
  1436             // Send the dnd event to the widget:
       
  1437             if (dropWidget && dropWidget->d_func()->qt_mac_dnd_event(ekind, drag)) {
       
  1438                 drag_allowed = true;
       
  1439                 handled_event = true;
       
  1440             }
       
  1441 
       
  1442             if (ekind == kEventControlDragEnter) {
       
  1443                 // If we don't accept the enter event, we will
       
  1444                 // receive no more drag events for this widget
       
  1445                 const Boolean wouldAccept = drag_allowed ? true : false;
       
  1446                 SetEventParameter(event, kEventParamControlWouldAcceptDrop, typeBoolean,
       
  1447                         sizeof(wouldAccept), &wouldAccept);
       
  1448             }
       
  1449         } else if (ekind == kEventControlBoundsChanged) {
       
  1450             if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_Moved) || widget->testAttribute(Qt::WA_Resized)) {
       
  1451                 handled_event = false;
       
  1452             } else {
       
  1453                 // Sync our view in case some other (non-Qt) view is controlling us.
       
  1454                 handled_event = true;
       
  1455                 Rect newBounds;
       
  1456                 GetEventParameter(event, kEventParamCurrentBounds,
       
  1457                                   typeQDRectangle, 0, sizeof(Rect), 0, &newBounds);
       
  1458                 QRect rect(newBounds.left, newBounds.top,
       
  1459                             newBounds.right - newBounds.left, newBounds.bottom - newBounds.top);
       
  1460 
       
  1461                 bool moved = widget->testAttribute(Qt::WA_Moved);
       
  1462                 bool resized = widget->testAttribute(Qt::WA_Resized);
       
  1463                 widget->setGeometry(rect);
       
  1464                 widget->setAttribute(Qt::WA_Moved, moved);
       
  1465                 widget->setAttribute(Qt::WA_Resized, resized);
       
  1466                 qt_event_request_window_change(widget);
       
  1467             }
       
  1468         } else if (ekind == kEventControlGetSizeConstraints) {
       
  1469             if (!widget || !qt_isGenuineQWidget(widget)) {
       
  1470                 handled_event = false;
       
  1471             } else {
       
  1472                 handled_event = true;
       
  1473                 QWidgetItem item(widget);
       
  1474                 QSize size = item.minimumSize();
       
  1475                 HISize hisize = { size.width(), size.height() };
       
  1476                 SetEventParameter(event, kEventParamMinimumSize, typeHISize, sizeof(HISize), &hisize);
       
  1477                 size = item.maximumSize();
       
  1478                 hisize.width = size.width() + 2; // ### shouldn't have to add 2 (but it works).
       
  1479                 hisize.height = size.height();
       
  1480                 SetEventParameter(event, kEventParamMaximumSize, typeHISize, sizeof(HISize), &hisize);
       
  1481             }
       
  1482         } else if (ekind == kEventControlVisibilityChanged) {
       
  1483             handled_event = false;
       
  1484             if (widget) {
       
  1485                 qt_event_request_window_change(widget);
       
  1486                 if (!HIViewIsVisible(HIViewRef(widget->winId()))) {
       
  1487                     extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
       
  1488                     if (widget == qt_button_down)
       
  1489                         qt_button_down = 0;
       
  1490                 }
       
  1491             }
       
  1492         }
       
  1493         break; }
       
  1494     case kEventClassMouse: {
       
  1495         bool send_to_app = false;
       
  1496         extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
       
  1497         if(qt_button_down)
       
  1498             send_to_app = true;
       
  1499         if(send_to_app) {
       
  1500             OSStatus err = SendEventToApplication(event);
       
  1501             if(err != noErr)
       
  1502                 handled_event = false;
       
  1503         } else {
       
  1504             CallNextEventHandler(er, event);
       
  1505         }
       
  1506         break; }
       
  1507     default:
       
  1508         handled_event = false;
       
  1509         break;
       
  1510     }
       
  1511     if(!handled_event) //let the event go through
       
  1512         return eventNotHandledErr;
       
  1513     return noErr; //we eat the event
       
  1514 }
       
  1515 #endif
       
  1516 
       
  1517 OSViewRef qt_mac_create_widget(QWidget *widget, QWidgetPrivate *widgetPrivate, OSViewRef parent)
       
  1518 {
       
  1519 #ifdef QT_MAC_USE_COCOA
       
  1520     QMacCocoaAutoReleasePool pool;
       
  1521     QT_MANGLE_NAMESPACE(QCocoaView) *view = [[QT_MANGLE_NAMESPACE(QCocoaView) alloc] initWithQWidget:widget widgetPrivate:widgetPrivate];
       
  1522     if (view && parent)
       
  1523         [parent addSubview:view];
       
  1524     return view;
       
  1525 #else
       
  1526     Q_UNUSED(widget);
       
  1527     Q_UNUSED(widgetPrivate);
       
  1528     if(!widget_class) {
       
  1529         OSStatus err = HIObjectRegisterSubclass(kObjectQWidget, kHIViewClassID, 0, make_widget_eventUPP(),
       
  1530                                                 GetEventTypeCount(widget_events), widget_events,
       
  1531                                                 0, &widget_class);
       
  1532         if (err && err != hiObjectClassExistsErr)
       
  1533             qWarning("QWidget: Internal error (%d)", __LINE__);
       
  1534     }
       
  1535     HIViewRef ret = 0;
       
  1536     if(HIObjectCreate(kObjectQWidget, 0, (HIObjectRef*)&ret) != noErr)
       
  1537         qWarning("QWidget: Internal error (%d)", __LINE__);
       
  1538     if(ret && parent)
       
  1539         HIViewAddSubview(parent, ret);
       
  1540     return ret;
       
  1541 #endif
       
  1542 }
       
  1543 
       
  1544 void qt_mac_unregister_widget()
       
  1545 {
       
  1546 #ifndef QT_MAC_USE_COCOA
       
  1547     HIObjectUnregisterClass(widget_class);
       
  1548     widget_class = 0;
       
  1549 #endif
       
  1550 }
       
  1551 
       
  1552 void QWidgetPrivate::toggleDrawers(bool visible)
       
  1553 {
       
  1554     for (int i = 0; i < children.size(); ++i) {
       
  1555         register QObject *object = children.at(i);
       
  1556         if (!object->isWidgetType())
       
  1557             continue;
       
  1558         QWidget *widget = static_cast<QWidget*>(object);
       
  1559         if(qt_mac_is_macdrawer(widget)) {
       
  1560             if(visible) {
       
  1561                 if (!widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
       
  1562                     widget->show();
       
  1563             } else {
       
  1564                 widget->hide();
       
  1565                 widget->setAttribute(Qt::WA_WState_ExplicitShowHide, false);
       
  1566             }
       
  1567         }
       
  1568     }
       
  1569 }
       
  1570 
       
  1571 /*****************************************************************************
       
  1572   QWidgetPrivate member functions
       
  1573  *****************************************************************************/
       
  1574 bool QWidgetPrivate::qt_mac_update_sizer(QWidget *w, int up)
       
  1575 {
       
  1576     // I'm not sure what "up" is
       
  1577     if(!w || !w->isWindow())
       
  1578         return false;
       
  1579 
       
  1580     QTLWExtra *topData = w->d_func()->topData();
       
  1581     QWExtra *extraData = w->d_func()->extraData();
       
  1582     // topData->resizer is only 4 bits, so subtracting -1 from zero causes bad stuff
       
  1583     // to happen, prevent that here (you really want the thing hidden).
       
  1584     if (up >= 0 || topData->resizer != 0)
       
  1585         topData->resizer += up;
       
  1586     OSWindowRef windowRef = qt_mac_window_for(OSViewRef(w->winId()));
       
  1587     {
       
  1588 #ifndef QT_MAC_USE_COCOA
       
  1589         WindowClass wclass;
       
  1590         GetWindowClass(windowRef, &wclass);
       
  1591         if(!(GetAvailableWindowAttributes(wclass) & kWindowResizableAttribute))
       
  1592             return true;
       
  1593 #endif
       
  1594     }
       
  1595     bool remove_grip = (topData->resizer || (w->windowFlags() & Qt::FramelessWindowHint)
       
  1596                         || (extraData->maxw && extraData->maxh &&
       
  1597                             extraData->maxw == extraData->minw && extraData->maxh == extraData->minh));
       
  1598 #ifndef QT_MAC_USE_COCOA
       
  1599     WindowAttributes attr;
       
  1600     GetWindowAttributes(windowRef, &attr);
       
  1601     if(remove_grip) {
       
  1602         if(attr & kWindowResizableAttribute) {
       
  1603             ChangeWindowAttributes(qt_mac_window_for(w), kWindowNoAttributes,
       
  1604                                    kWindowResizableAttribute);
       
  1605             ReshapeCustomWindow(qt_mac_window_for(w));
       
  1606         }
       
  1607     } else if(!(attr & kWindowResizableAttribute)) {
       
  1608         ChangeWindowAttributes(windowRef, kWindowResizableAttribute,
       
  1609                                kWindowNoAttributes);
       
  1610         ReshapeCustomWindow(windowRef);
       
  1611     }
       
  1612 #else
       
  1613     [windowRef setShowsResizeIndicator:!remove_grip];
       
  1614 #endif
       
  1615     return true;
       
  1616 }
       
  1617 
       
  1618 void QWidgetPrivate::qt_clean_root_win()
       
  1619 {
       
  1620 #ifdef QT_MAC_USE_COCOA
       
  1621     [qt_root_win release];
       
  1622 #else
       
  1623     if(!qt_root_win)
       
  1624         return;
       
  1625     CFRelease(qt_root_win);
       
  1626 #endif
       
  1627     qt_root_win = 0;
       
  1628 }
       
  1629 
       
  1630 bool QWidgetPrivate::qt_create_root_win()
       
  1631 {
       
  1632     if(qt_root_win)
       
  1633         return false;
       
  1634     const QSize desktopSize = qt_mac_desktopSize();
       
  1635     QRect desktopRect(QPoint(0, 0), desktopSize);
       
  1636 #ifdef QT_MAC_USE_COCOA
       
  1637     qt_root_win = qt_mac_create_window(0, kOverlayWindowClass, NSBorderlessWindowMask, desktopRect);
       
  1638 #else
       
  1639     WindowAttributes wattr = (kWindowCompositingAttribute | kWindowStandardHandlerAttribute);
       
  1640     qt_root_win = qt_mac_create_window(0, kOverlayWindowClass, wattr, desktopRect);
       
  1641 #endif
       
  1642     if(!qt_root_win)
       
  1643         return false;
       
  1644     qAddPostRoutine(qt_clean_root_win);
       
  1645     return true;
       
  1646 }
       
  1647 
       
  1648 bool QWidgetPrivate::qt_widget_rgn(QWidget *widget, short wcode, RgnHandle rgn, bool force = false)
       
  1649 {
       
  1650     bool ret = false;
       
  1651 #ifndef QT_MAC_USE_COCOA
       
  1652     switch(wcode) {
       
  1653     case kWindowStructureRgn: {
       
  1654         if(widget) {
       
  1655             if(widget->d_func()->extra && !widget->d_func()->extra->mask.isEmpty()) {
       
  1656                 QRegion rin = qt_mac_convert_mac_region(rgn);
       
  1657                 if(!rin.isEmpty()) {
       
  1658                     QPoint rin_tl = rin.boundingRect().topLeft(); //in offset
       
  1659                     rin.translate(-rin_tl.x(), -rin_tl.y()); //bring into same space as below
       
  1660                     QRegion mask = widget->d_func()->extra->mask;
       
  1661                     Qt::WindowFlags flags = widget->windowFlags();
       
  1662                     if(widget->isWindow()
       
  1663                        && !(flags & Qt::FramelessWindowHint
       
  1664                             || (flags & Qt::CustomizeWindowHint && !(flags & Qt::WindowTitleHint)))) {
       
  1665                         QRegion title;
       
  1666                         {
       
  1667                             QMacSmartQuickDrawRegion rgn(qt_mac_get_rgn());
       
  1668                             GetWindowRegion(qt_mac_window_for(widget), kWindowTitleBarRgn, rgn);
       
  1669                             title = qt_mac_convert_mac_region(rgn);
       
  1670                         }
       
  1671                         QRect br = title.boundingRect();
       
  1672                         mask.translate(0, br.height()); //put the mask 'under' the title bar..
       
  1673                         title.translate(-br.x(), -br.y());
       
  1674                         mask += title;
       
  1675                     }
       
  1676 
       
  1677                     QRegion cr = rin & mask;
       
  1678                     cr.translate(rin_tl.x(), rin_tl.y()); //translate back to incoming space
       
  1679                     CopyRgn(QMacSmartQuickDrawRegion(cr.toQDRgn()), rgn);
       
  1680                 }
       
  1681                 ret = true;
       
  1682             } else if(force) {
       
  1683                 QRegion cr(widget->geometry());
       
  1684                 CopyRgn(QMacSmartQuickDrawRegion(cr.toQDRgn()), rgn);
       
  1685                 ret = true;
       
  1686             }
       
  1687         }
       
  1688         break; }
       
  1689     default: break;
       
  1690     }
       
  1691     //qDebug() << widget << ret << wcode << qt_mac_convert_mac_region(rgn);
       
  1692 #else
       
  1693     Q_UNUSED(widget);
       
  1694     Q_UNUSED(wcode);
       
  1695     Q_UNUSED(rgn);
       
  1696     Q_UNUSED(force);
       
  1697 #endif
       
  1698     return ret;
       
  1699 }
       
  1700 
       
  1701 /*****************************************************************************
       
  1702   QWidget member functions
       
  1703  *****************************************************************************/
       
  1704 void QWidgetPrivate::determineWindowClass()
       
  1705 {
       
  1706     Q_Q(QWidget);
       
  1707 #ifndef QT_MAC_USE_COCOA
       
  1708 // ### COCOA:Interleave these better!
       
  1709 
       
  1710     const Qt::WindowType type = q->windowType();
       
  1711     Qt::WindowFlags &flags = data.window_flags;
       
  1712     const bool popup = (type == Qt::Popup);
       
  1713     if (type == Qt::ToolTip || type == Qt::SplashScreen || popup)
       
  1714         flags |= Qt::FramelessWindowHint;
       
  1715 
       
  1716     WindowClass wclass = kSheetWindowClass;
       
  1717     if(qt_mac_is_macdrawer(q))
       
  1718         wclass = kDrawerWindowClass;
       
  1719     else if (q->testAttribute(Qt::WA_ShowModal) && flags & Qt::CustomizeWindowHint)
       
  1720         wclass = kDocumentWindowClass;
       
  1721     else if(popup || (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && type == Qt::SplashScreen))
       
  1722         wclass = kModalWindowClass;
       
  1723     else if(q->testAttribute(Qt::WA_ShowModal))
       
  1724         wclass = kMovableModalWindowClass;
       
  1725     else if(type == Qt::ToolTip)
       
  1726         wclass = kHelpWindowClass;
       
  1727     else if(type == Qt::Tool || (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5
       
  1728                                  && type == Qt::SplashScreen))
       
  1729         wclass = kFloatingWindowClass;
       
  1730     else
       
  1731         wclass = kDocumentWindowClass;
       
  1732 
       
  1733     WindowGroupRef grp = 0;
       
  1734     WindowAttributes wattr = (kWindowCompositingAttribute | kWindowStandardHandlerAttribute);
       
  1735     if (q->testAttribute(Qt::WA_MacFrameworkScaled))
       
  1736         wattr |= kWindowFrameworkScaledAttribute;
       
  1737     if(qt_mac_is_macsheet(q)) {
       
  1738         //grp = GetWindowGroupOfClass(kMovableModalWindowClass);
       
  1739         wclass = kSheetWindowClass;
       
  1740     } else {
       
  1741         grp = GetWindowGroupOfClass(wclass);
       
  1742         // Shift things around a bit to get the correct window class based on the presence
       
  1743         // (or lack) of the border.
       
  1744 	bool customize = flags & Qt::CustomizeWindowHint;
       
  1745         bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint)));
       
  1746         if (framelessWindow) {
       
  1747             if(wclass == kDocumentWindowClass) {
       
  1748                 wattr |= kWindowNoTitleBarAttribute;
       
  1749             } else if(wclass == kFloatingWindowClass) {
       
  1750                 wattr |= kWindowNoTitleBarAttribute;
       
  1751             } else if (wclass  == kMovableModalWindowClass) {
       
  1752                 wclass = kModalWindowClass;
       
  1753             }
       
  1754         } else {
       
  1755             if(wclass != kModalWindowClass)
       
  1756                 wattr |= kWindowResizableAttribute;
       
  1757         }
       
  1758         // Only add extra decorations (well, buttons) for widgets that can have them
       
  1759         // and have an actual border we can put them on.
       
  1760         if(wclass != kModalWindowClass && wclass != kMovableModalWindowClass
       
  1761                 && wclass != kSheetWindowClass && wclass != kPlainWindowClass
       
  1762                 && !framelessWindow && wclass != kDrawerWindowClass
       
  1763                 && wclass != kHelpWindowClass) {
       
  1764             if (flags & Qt::WindowMaximizeButtonHint)
       
  1765                 wattr |= kWindowFullZoomAttribute;
       
  1766             if (flags & Qt::WindowMinimizeButtonHint)
       
  1767                 wattr |= kWindowCollapseBoxAttribute;
       
  1768             if (flags & Qt::WindowSystemMenuHint || flags & Qt::WindowCloseButtonHint)
       
  1769                 wattr |= kWindowCloseBoxAttribute;
       
  1770             if (flags & Qt::MacWindowToolBarButtonHint)
       
  1771                 wattr |= kWindowToolbarButtonAttribute;
       
  1772         } else {
       
  1773             // Clear these hints so that we aren't call them on invalid windows
       
  1774             flags &= ~(Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint
       
  1775                        | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint);
       
  1776         }
       
  1777     }
       
  1778     if((popup || type == Qt::Tool) && !q->isModal())
       
  1779         wattr |= kWindowHideOnSuspendAttribute;
       
  1780     wattr |= kWindowLiveResizeAttribute;
       
  1781 
       
  1782 #ifdef DEBUG_WINDOW_CREATE
       
  1783 #define ADD_DEBUG_WINDOW_NAME(x) { x, #x }
       
  1784     struct {
       
  1785         UInt32 tag;
       
  1786         const char *name;
       
  1787     } known_attribs[] = {
       
  1788         ADD_DEBUG_WINDOW_NAME(kWindowCompositingAttribute),
       
  1789         ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
       
  1790         ADD_DEBUG_WINDOW_NAME(kWindowMetalAttribute),
       
  1791         ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
       
  1792         ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
       
  1793         ADD_DEBUG_WINDOW_NAME(kWindowCollapseBoxAttribute),
       
  1794         ADD_DEBUG_WINDOW_NAME(kWindowHorizontalZoomAttribute),
       
  1795         ADD_DEBUG_WINDOW_NAME(kWindowVerticalZoomAttribute),
       
  1796         ADD_DEBUG_WINDOW_NAME(kWindowResizableAttribute),
       
  1797         ADD_DEBUG_WINDOW_NAME(kWindowNoActivatesAttribute),
       
  1798         ADD_DEBUG_WINDOW_NAME(kWindowNoUpdatesAttribute),
       
  1799         ADD_DEBUG_WINDOW_NAME(kWindowOpaqueForEventsAttribute),
       
  1800         ADD_DEBUG_WINDOW_NAME(kWindowLiveResizeAttribute),
       
  1801         ADD_DEBUG_WINDOW_NAME(kWindowCloseBoxAttribute),
       
  1802         ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
       
  1803         { 0, 0 }
       
  1804     }, known_classes[] = {
       
  1805         ADD_DEBUG_WINDOW_NAME(kHelpWindowClass),
       
  1806         ADD_DEBUG_WINDOW_NAME(kPlainWindowClass),
       
  1807         ADD_DEBUG_WINDOW_NAME(kDrawerWindowClass),
       
  1808         ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
       
  1809         ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
       
  1810         ADD_DEBUG_WINDOW_NAME(kSheetWindowClass),
       
  1811         ADD_DEBUG_WINDOW_NAME(kFloatingWindowClass),
       
  1812         ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
       
  1813         ADD_DEBUG_WINDOW_NAME(kDocumentWindowClass),
       
  1814         ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
       
  1815         ADD_DEBUG_WINDOW_NAME(kMovableModalWindowClass),
       
  1816         ADD_DEBUG_WINDOW_NAME(kModalWindowClass),
       
  1817         { 0, 0 }
       
  1818     };
       
  1819     qDebug("Qt: internal: ************* Creating new window %p (%s::%s)", q, q->metaObject()->className(),
       
  1820             q->objectName().toLocal8Bit().constData());
       
  1821     bool found_class = false;
       
  1822     for(int i = 0; known_classes[i].name; i++) {
       
  1823         if(wclass == known_classes[i].tag) {
       
  1824             found_class = true;
       
  1825             qDebug("Qt: internal: ** Class: %s", known_classes[i].name);
       
  1826             break;
       
  1827         }
       
  1828     }
       
  1829     if(!found_class)
       
  1830         qDebug("Qt: internal: !! Class: Unknown! (%d)", (int)wclass);
       
  1831     if(wattr) {
       
  1832         WindowAttributes tmp_wattr = wattr;
       
  1833         qDebug("Qt: internal: ** Attributes:");
       
  1834         for(int i = 0; tmp_wattr && known_attribs[i].name; i++) {
       
  1835             if((tmp_wattr & known_attribs[i].tag) == known_attribs[i].tag) {
       
  1836                 tmp_wattr ^= known_attribs[i].tag;
       
  1837                 qDebug("Qt: internal: * %s %s", known_attribs[i].name,
       
  1838                         (GetAvailableWindowAttributes(wclass) & known_attribs[i].tag) ? "" : "(*)");
       
  1839             }
       
  1840         }
       
  1841         if(tmp_wattr)
       
  1842             qDebug("Qt: internal: !! Attributes: Unknown (%d)", (int)tmp_wattr);
       
  1843     }
       
  1844 #endif
       
  1845 
       
  1846     /* Just to be extra careful we will change to the kUtilityWindowClass if the
       
  1847        requested attributes cannot be used */
       
  1848     if((GetAvailableWindowAttributes(wclass) & wattr) != wattr) {
       
  1849         WindowClass tmp_class = wclass;
       
  1850         if(wclass == kToolbarWindowClass || wclass == kUtilityWindowClass)
       
  1851             wclass = kFloatingWindowClass;
       
  1852         if(tmp_class != wclass) {
       
  1853             if(!grp)
       
  1854                 grp = GetWindowGroupOfClass(wclass);
       
  1855             wclass = tmp_class;
       
  1856         }
       
  1857     }
       
  1858     topData()->wclass = wclass;
       
  1859     topData()->wattr = wattr;
       
  1860 #else
       
  1861     const Qt::WindowType type = q->windowType();
       
  1862     Qt::WindowFlags &flags = data.window_flags;
       
  1863     const bool popup = (type == Qt::Popup);
       
  1864     if (type == Qt::ToolTip || type == Qt::SplashScreen || popup)
       
  1865         flags |= Qt::FramelessWindowHint;
       
  1866 
       
  1867     WindowClass wclass = kSheetWindowClass;
       
  1868     if(qt_mac_is_macdrawer(q))
       
  1869         wclass = kDrawerWindowClass;
       
  1870     else if (q->testAttribute(Qt::WA_ShowModal) && flags & Qt::CustomizeWindowHint)
       
  1871         wclass = kDocumentWindowClass;
       
  1872     else if(popup || (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && type == Qt::SplashScreen))
       
  1873         wclass = kModalWindowClass;
       
  1874     else if(q->testAttribute(Qt::WA_ShowModal) || type == Qt::Dialog)
       
  1875         wclass = kMovableModalWindowClass;
       
  1876     else if(type == Qt::ToolTip)
       
  1877         wclass = kHelpWindowClass;
       
  1878     else if(type == Qt::Tool || (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5
       
  1879                                  && type == Qt::SplashScreen))
       
  1880         wclass = kFloatingWindowClass;
       
  1881     else
       
  1882         wclass = kDocumentWindowClass;
       
  1883 
       
  1884     WindowAttributes wattr = NSBorderlessWindowMask;
       
  1885     if(qt_mac_is_macsheet(q)) {
       
  1886         //grp = GetWindowGroupOfClass(kMovableModalWindowClass);
       
  1887         wclass = kSheetWindowClass;
       
  1888         wattr = NSTitledWindowMask | NSResizableWindowMask;
       
  1889     } else {
       
  1890 #ifndef QT_MAC_USE_COCOA
       
  1891         grp = GetWindowGroupOfClass(wclass);
       
  1892 #endif
       
  1893         // Shift things around a bit to get the correct window class based on the presence
       
  1894         // (or lack) of the border.
       
  1895 	bool customize = flags & Qt::CustomizeWindowHint;
       
  1896         bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint)));
       
  1897         if (framelessWindow) {
       
  1898             if (wclass == kDocumentWindowClass) {
       
  1899                 wclass = kSimpleWindowClass;
       
  1900             } else if (wclass == kFloatingWindowClass) {
       
  1901                 wclass = kToolbarWindowClass;
       
  1902             } else if (wclass  == kMovableModalWindowClass) {
       
  1903                 wclass  = kModalWindowClass;
       
  1904             }
       
  1905         } else {
       
  1906             wattr |= NSTitledWindowMask;
       
  1907             if (wclass != kModalWindowClass)
       
  1908                 wattr |= NSResizableWindowMask;
       
  1909         }
       
  1910         // Only add extra decorations (well, buttons) for widgets that can have them
       
  1911         // and have an actual border we can put them on.
       
  1912         if (wclass != kModalWindowClass
       
  1913                 && wclass != kSheetWindowClass && wclass != kPlainWindowClass
       
  1914                 && !framelessWindow && wclass != kDrawerWindowClass
       
  1915                 && wclass != kHelpWindowClass) {
       
  1916             if (flags & Qt::WindowMinimizeButtonHint)
       
  1917                 wattr |= NSMiniaturizableWindowMask;
       
  1918             if (flags & Qt::WindowSystemMenuHint || flags & Qt::WindowCloseButtonHint)
       
  1919                 wattr |= NSClosableWindowMask;
       
  1920         } else {
       
  1921             // Clear these hints so that we aren't call them on invalid windows
       
  1922             flags &= ~(Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint
       
  1923                        | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint);
       
  1924         }
       
  1925     }
       
  1926     if (q->testAttribute(Qt::WA_MacBrushedMetal))
       
  1927         wattr |= NSTexturedBackgroundWindowMask;
       
  1928 
       
  1929 #ifdef DEBUG_WINDOW_CREATE
       
  1930 #define ADD_DEBUG_WINDOW_NAME(x) { x, #x }
       
  1931     struct {
       
  1932         UInt32 tag;
       
  1933         const char *name;
       
  1934     } known_attribs[] = {
       
  1935         ADD_DEBUG_WINDOW_NAME(kWindowCompositingAttribute),
       
  1936         ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
       
  1937         ADD_DEBUG_WINDOW_NAME(kWindowMetalAttribute),
       
  1938         ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
       
  1939         ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
       
  1940         ADD_DEBUG_WINDOW_NAME(kWindowCollapseBoxAttribute),
       
  1941         ADD_DEBUG_WINDOW_NAME(kWindowHorizontalZoomAttribute),
       
  1942         ADD_DEBUG_WINDOW_NAME(kWindowVerticalZoomAttribute),
       
  1943         ADD_DEBUG_WINDOW_NAME(kWindowResizableAttribute),
       
  1944         ADD_DEBUG_WINDOW_NAME(kWindowNoActivatesAttribute),
       
  1945         ADD_DEBUG_WINDOW_NAME(kWindowNoUpdatesAttribute),
       
  1946         ADD_DEBUG_WINDOW_NAME(kWindowOpaqueForEventsAttribute),
       
  1947         ADD_DEBUG_WINDOW_NAME(kWindowLiveResizeAttribute),
       
  1948         ADD_DEBUG_WINDOW_NAME(kWindowCloseBoxAttribute),
       
  1949         ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
       
  1950         { 0, 0 }
       
  1951     }, known_classes[] = {
       
  1952         ADD_DEBUG_WINDOW_NAME(kHelpWindowClass),
       
  1953         ADD_DEBUG_WINDOW_NAME(kPlainWindowClass),
       
  1954         ADD_DEBUG_WINDOW_NAME(kDrawerWindowClass),
       
  1955         ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
       
  1956         ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
       
  1957         ADD_DEBUG_WINDOW_NAME(kSheetWindowClass),
       
  1958         ADD_DEBUG_WINDOW_NAME(kFloatingWindowClass),
       
  1959         ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
       
  1960         ADD_DEBUG_WINDOW_NAME(kDocumentWindowClass),
       
  1961         ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
       
  1962         ADD_DEBUG_WINDOW_NAME(kMovableModalWindowClass),
       
  1963         ADD_DEBUG_WINDOW_NAME(kModalWindowClass),
       
  1964         { 0, 0 }
       
  1965     };
       
  1966     qDebug("Qt: internal: ************* Creating new window %p (%s::%s)", q, q->metaObject()->className(),
       
  1967             q->objectName().toLocal8Bit().constData());
       
  1968     bool found_class = false;
       
  1969     for(int i = 0; known_classes[i].name; i++) {
       
  1970         if(wclass == known_classes[i].tag) {
       
  1971             found_class = true;
       
  1972             qDebug("Qt: internal: ** Class: %s", known_classes[i].name);
       
  1973             break;
       
  1974         }
       
  1975     }
       
  1976     if(!found_class)
       
  1977         qDebug("Qt: internal: !! Class: Unknown! (%d)", (int)wclass);
       
  1978     if(wattr) {
       
  1979         WindowAttributes tmp_wattr = wattr;
       
  1980         qDebug("Qt: internal: ** Attributes:");
       
  1981         for(int i = 0; tmp_wattr && known_attribs[i].name; i++) {
       
  1982             if((tmp_wattr & known_attribs[i].tag) == known_attribs[i].tag) {
       
  1983                 tmp_wattr ^= known_attribs[i].tag;
       
  1984                 qDebug("Qt: internal: * %s %s", known_attribs[i].name,
       
  1985                         (GetAvailableWindowAttributes(wclass) & known_attribs[i].tag) ? "" : "(*)");
       
  1986             }
       
  1987         }
       
  1988         if(tmp_wattr)
       
  1989             qDebug("Qt: internal: !! Attributes: Unknown (%d)", (int)tmp_wattr);
       
  1990     }
       
  1991 #endif
       
  1992 
       
  1993 #ifndef QT_MAC_USE_COCOA
       
  1994     /* Just to be extra careful we will change to the kUtilityWindowClass if the
       
  1995        requested attributes cannot be used */
       
  1996     if((GetAvailableWindowAttributes(wclass) & wattr) != wattr) {
       
  1997         WindowClass tmp_class = wclass;
       
  1998         if(wclass == kToolbarWindowClass || wclass == kUtilityWindowClass)
       
  1999             wclass = kFloatingWindowClass;
       
  2000         if(tmp_class != wclass) {
       
  2001             if(!grp)
       
  2002                 grp = GetWindowGroupOfClass(wclass);
       
  2003             wclass = tmp_class;
       
  2004         }
       
  2005     }
       
  2006 #endif
       
  2007 #endif
       
  2008     topData()->wclass = wclass;
       
  2009     topData()->wattr = wattr;
       
  2010 }
       
  2011 
       
  2012 #ifndef QT_MAC_USE_COCOA  // This is handled in Cocoa via our category.
       
  2013 void QWidgetPrivate::initWindowPtr()
       
  2014 {
       
  2015     Q_Q(QWidget);
       
  2016     OSWindowRef windowRef = qt_mac_window_for(qt_mac_nativeview_for(q)); //do not create!
       
  2017     if(!windowRef)
       
  2018         return;
       
  2019     QWidget *window = q->window(), *oldWindow = 0;
       
  2020     if(GetWindowProperty(windowRef, kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(oldWindow), 0, &oldWindow) == noErr) {
       
  2021         Q_ASSERT(window == oldWindow);
       
  2022         return;
       
  2023     }
       
  2024 
       
  2025     if(SetWindowProperty(windowRef, kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(window), &window) != noErr)
       
  2026         qWarning("Qt:Internal error (%s:%d)", __FILE__, __LINE__); //no real way to recover
       
  2027     if(!q->windowType() != Qt::Desktop) { //setup an event callback handler on the window
       
  2028         InstallWindowEventHandler(windowRef, make_win_eventUPP(), GetEventTypeCount(window_events),
       
  2029                 window_events, static_cast<void *>(qApp), &window_event);
       
  2030     }
       
  2031 }
       
  2032 
       
  2033 void QWidgetPrivate::finishCreateWindow_sys_Carbon(OSWindowRef windowRef)
       
  2034 {
       
  2035     Q_Q(QWidget);
       
  2036     const Qt::WindowType type = q->windowType();
       
  2037     Qt::WindowFlags &flags = data.window_flags;
       
  2038     QWidget *parentWidget = q->parentWidget();
       
  2039 
       
  2040     const bool desktop = (type == Qt::Desktop);
       
  2041     const bool dialog = (type == Qt::Dialog
       
  2042                          || type == Qt::Sheet
       
  2043                          || type == Qt::Drawer
       
  2044                          || (flags & Qt::MSWindowsFixedSizeDialogHint));
       
  2045     QTLWExtra *topExtra = topData();
       
  2046     quint32 wattr = topExtra->wattr;
       
  2047     if (!desktop)
       
  2048         SetAutomaticControlDragTrackingEnabledForWindow(windowRef, true);
       
  2049     HIWindowChangeFeatures(windowRef, kWindowCanCollapse, 0);
       
  2050     if (wattr & kWindowHideOnSuspendAttribute)
       
  2051         HIWindowChangeAvailability(windowRef, kHIWindowExposeHidden, 0);
       
  2052     else
       
  2053         HIWindowChangeAvailability(windowRef, 0, kHIWindowExposeHidden);
       
  2054     if ((flags & Qt::WindowStaysOnTopHint))
       
  2055         ChangeWindowAttributes(windowRef, kWindowNoAttributes, kWindowHideOnSuspendAttribute);
       
  2056     if (qt_mac_is_macdrawer(q) && parentWidget)
       
  2057         SetDrawerParent(windowRef, qt_mac_window_for (parentWidget));
       
  2058     if (topExtra->group) {
       
  2059         qt_mac_release_window_group(topExtra->group);
       
  2060         topExtra->group = 0;
       
  2061     }
       
  2062     if (type == Qt::ToolTip)
       
  2063         qt_mac_set_window_group_to_tooltip(windowRef);
       
  2064     else if (type == Qt::Popup && (flags & Qt::WindowStaysOnTopHint))
       
  2065         qt_mac_set_window_group_to_popup(windowRef);
       
  2066     else if (flags & Qt::WindowStaysOnTopHint)
       
  2067         qt_mac_set_window_group_to_stays_on_top(windowRef, type);
       
  2068     else if (dialog)
       
  2069         SetWindowGroup(windowRef, GetWindowGroupOfClass(kMovableModalWindowClass));
       
  2070 
       
  2071 #ifdef DEBUG_WINDOW_CREATE
       
  2072     if (WindowGroupRef grpf = GetWindowGroup(windowRef)) {
       
  2073         QCFString cfname;
       
  2074         CopyWindowGroupName(grpf, &cfname);
       
  2075         SInt32 lvl;
       
  2076         GetWindowGroupLevel(grpf, &lvl);
       
  2077         const char *from = "Default";
       
  2078         if (topExtra && grpf == topData()->group)
       
  2079             from = "Created";
       
  2080         else if (grpf == grp)
       
  2081             from = "Copied";
       
  2082         qDebug("Qt: internal: With window group '%s' [%p] @ %d: %s",
       
  2083                 static_cast<QString>(cfname).toLatin1().constData(), grpf, (int)lvl, from);
       
  2084     } else {
       
  2085         qDebug("Qt: internal: No window group!!!");
       
  2086     }
       
  2087     HIWindowAvailability hi_avail = 0;
       
  2088     if (HIWindowGetAvailability(windowRef, &hi_avail) == noErr) {
       
  2089         struct {
       
  2090             UInt32 tag;
       
  2091             const char *name;
       
  2092         } known_avail[] = {
       
  2093             ADD_DEBUG_WINDOW_NAME(kHIWindowExposeHidden),
       
  2094             { 0, 0 }
       
  2095         };
       
  2096         qDebug("Qt: internal: ** HIWindowAvailibility:");
       
  2097         for (int i = 0; hi_avail && known_avail[i].name; i++) {
       
  2098             if ((hi_avail & known_avail[i].tag) == known_avail[i].tag) {
       
  2099                 hi_avail ^= known_avail[i].tag;
       
  2100                 qDebug("Qt: internal: * %s", known_avail[i].name);
       
  2101             }
       
  2102         }
       
  2103         if (hi_avail)
       
  2104             qDebug("Qt: internal: !! Attributes: Unknown (%d)", (int)hi_avail);
       
  2105     }
       
  2106 #undef ADD_DEBUG_WINDOW_NAME
       
  2107 #endif
       
  2108     if (extra && !extra->mask.isEmpty())
       
  2109         ReshapeCustomWindow(windowRef);
       
  2110     SetWindowModality(windowRef, kWindowModalityNone, 0);
       
  2111     if (qt_mac_is_macdrawer(q))
       
  2112         SetDrawerOffsets(windowRef, 0.0, 25.0);
       
  2113     data.fstrut_dirty = true; // when we create a toplevel widget, the frame strut should be dirty
       
  2114     HIViewRef hiview = (HIViewRef)data.winid;
       
  2115     HIViewRef window_hiview = qt_mac_get_contentview_for(windowRef);
       
  2116     if(!hiview) {
       
  2117         hiview = qt_mac_create_widget(q, this, window_hiview);
       
  2118         setWinId((WId)hiview);
       
  2119     } else {
       
  2120         HIViewAddSubview(window_hiview, hiview);
       
  2121     }
       
  2122     if (hiview) {
       
  2123         Rect win_rect;
       
  2124         GetWindowBounds(qt_mac_window_for (window_hiview), kWindowContentRgn, &win_rect);
       
  2125         HIRect bounds = CGRectMake(0, 0, win_rect.right-win_rect.left, win_rect.bottom-win_rect.top);
       
  2126         HIViewSetFrame(hiview, &bounds);
       
  2127         HIViewSetVisible(hiview, true);
       
  2128         if (q->testAttribute(Qt::WA_DropSiteRegistered))
       
  2129             registerDropSite(true);
       
  2130         transferChildren();
       
  2131     }
       
  2132     initWindowPtr();
       
  2133 
       
  2134     if (topExtra->posFromMove) {
       
  2135         updateFrameStrut();
       
  2136         const QRect &fStrut = frameStrut();
       
  2137         Rect r;
       
  2138         SetRect(&r, data.crect.left(), data.crect.top(), data.crect.right() + 1, data.crect.bottom() + 1);
       
  2139         SetRect(&r, r.left + fStrut.left(), r.top + fStrut.top(),
       
  2140                     (r.left + fStrut.left() + data.crect.width()) - fStrut.right(),
       
  2141                     (r.top + fStrut.top() + data.crect.height()) - fStrut.bottom());
       
  2142         SetWindowBounds(windowRef, kWindowContentRgn, &r);
       
  2143         topExtra->posFromMove = false;
       
  2144     }
       
  2145 
       
  2146     if (q->testAttribute(Qt::WA_WState_WindowOpacitySet)){
       
  2147         q->setWindowOpacity(topExtra->opacity / 255.0f);
       
  2148     } else if (qt_mac_is_macsheet(q)){
       
  2149         SetThemeWindowBackground(qt_mac_window_for(q), kThemeBrushSheetBackgroundTransparent, true);
       
  2150         CGFloat alpha = 0;
       
  2151         GetWindowAlpha(qt_mac_window_for(q), &alpha);
       
  2152         if (alpha == 1){
       
  2153             // For some reason the 'SetThemeWindowBackground' does not seem
       
  2154             // to work. So we do this little hack until it hopefully starts to
       
  2155             // work in newer versions of mac OS.
       
  2156             q->setWindowOpacity(0.95f);
       
  2157             q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
       
  2158         }
       
  2159     } else{
       
  2160         // If the window has been recreated after beeing e.g. a sheet,
       
  2161         // make sure that we don't report a faulty opacity:
       
  2162         q->setWindowOpacity(1.0f);
       
  2163         q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
       
  2164     }
       
  2165 
       
  2166     // Since we only now have a window, sync our state.
       
  2167     macUpdateHideOnSuspend();
       
  2168     macUpdateOpaqueSizeGrip();
       
  2169     macUpdateMetalAttribute();
       
  2170     macUpdateIgnoreMouseEvents();
       
  2171     setWindowTitle_helper(extra->topextra->caption);
       
  2172     setWindowIconText_helper(extra->topextra->iconText);
       
  2173     setWindowFilePath_helper(extra->topextra->filePath);
       
  2174     setWindowModified_sys(q->isWindowModified());
       
  2175     updateFrameStrut();
       
  2176     qt_mac_update_sizer(q);
       
  2177     applyMaxAndMinSizeOnWindow();
       
  2178 }
       
  2179 #else  // QT_MAC_USE_COCOA
       
  2180 void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWindowRef)
       
  2181 {
       
  2182     Q_Q(QWidget);
       
  2183     QMacCocoaAutoReleasePool pool;
       
  2184     NSWindow *windowRef = static_cast<NSWindow *>(voidWindowRef);
       
  2185     const Qt::WindowType type = q->windowType();
       
  2186     Qt::WindowFlags &flags = data.window_flags;
       
  2187     QWidget *parentWidget = q->parentWidget();
       
  2188 
       
  2189     const bool popup = (type == Qt::Popup);
       
  2190     const bool dialog = (type == Qt::Dialog
       
  2191                          || type == Qt::Sheet
       
  2192                          || type == Qt::Drawer
       
  2193                          || (flags & Qt::MSWindowsFixedSizeDialogHint));
       
  2194     QTLWExtra *topExtra = topData();
       
  2195 
       
  2196     if ((popup || type == Qt::Tool || type == Qt::ToolTip) && !q->isModal()) {
       
  2197         [windowRef setHidesOnDeactivate:YES];
       
  2198     } else {
       
  2199         [windowRef setHidesOnDeactivate:NO];
       
  2200     }
       
  2201     [windowRef setHasShadow:YES];
       
  2202     Q_UNUSED(parentWidget);
       
  2203     Q_UNUSED(dialog);
       
  2204 
       
  2205     data.fstrut_dirty = true; // when we create a toplevel widget, the frame strut should be dirty
       
  2206     OSViewRef nsview = (OSViewRef)data.winid;
       
  2207     OSViewRef window_contentview = qt_mac_get_contentview_for(windowRef);
       
  2208     if (!nsview) {
       
  2209         nsview = qt_mac_create_widget(q, this, window_contentview);
       
  2210         setWinId(WId(nsview));
       
  2211     } else {
       
  2212         [window_contentview addSubview:nsview];
       
  2213     }
       
  2214     if (nsview) {
       
  2215         NSRect bounds = [window_contentview bounds];
       
  2216         [nsview setFrame:bounds];
       
  2217         [nsview setHidden:NO];
       
  2218         if (q->testAttribute(Qt::WA_DropSiteRegistered))
       
  2219             registerDropSite(true);
       
  2220         transferChildren();
       
  2221     }
       
  2222 
       
  2223     if (topExtra->posFromMove) {
       
  2224         updateFrameStrut();
       
  2225 
       
  2226         const QRect &fStrut = frameStrut();
       
  2227         const QRect &crect = data.crect;
       
  2228         const QRect frameRect(QPoint(crect.left(), crect.top()),
       
  2229                               QSize(fStrut.left() + fStrut.right() + crect.width(),
       
  2230                                     fStrut.top() + fStrut.bottom() + crect.height()));
       
  2231         NSRect cocoaFrameRect = NSMakeRect(frameRect.x(), flipYCoordinate(frameRect.bottom() + 1),
       
  2232                                            frameRect.width(), frameRect.height());
       
  2233         [windowRef setFrame:cocoaFrameRect display:NO];
       
  2234         topExtra->posFromMove = false;
       
  2235     }
       
  2236 
       
  2237     if (q->testAttribute(Qt::WA_WState_WindowOpacitySet)){
       
  2238         q->setWindowOpacity(topExtra->opacity / 255.0f);
       
  2239     } else if (qt_mac_is_macsheet(q)){
       
  2240         CGFloat alpha = [qt_mac_window_for(q) alphaValue];
       
  2241         if (alpha >= 1.0) {
       
  2242             q->setWindowOpacity(0.95f);
       
  2243             q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
       
  2244         }
       
  2245     } else{
       
  2246         // If the window has been recreated after beeing e.g. a sheet,
       
  2247         // make sure that we don't report a faulty opacity:
       
  2248         q->setWindowOpacity(1.0f);
       
  2249         q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
       
  2250     }
       
  2251 
       
  2252     macUpdateHideOnSuspend();
       
  2253     macUpdateOpaqueSizeGrip();
       
  2254     macUpdateIgnoreMouseEvents();
       
  2255     setWindowTitle_helper(extra->topextra->caption);
       
  2256     setWindowIconText_helper(extra->topextra->iconText);
       
  2257     setWindowModified_sys(q->isWindowModified());
       
  2258     updateFrameStrut();
       
  2259     syncCocoaMask();
       
  2260     macUpdateIsOpaque();
       
  2261     qt_mac_update_sizer(q);
       
  2262     applyMaxAndMinSizeOnWindow();
       
  2263 }
       
  2264 
       
  2265 #endif // QT_MAC_USE_COCOA
       
  2266 
       
  2267 /*
       
  2268  Recreates widget window. Useful if immutable
       
  2269  properties for it has changed.
       
  2270  */
       
  2271 void QWidgetPrivate::recreateMacWindow()
       
  2272 {
       
  2273     Q_Q(QWidget);
       
  2274     OSViewRef myView = qt_mac_nativeview_for(q);
       
  2275     OSWindowRef oldWindow = qt_mac_window_for(myView);
       
  2276 #ifndef QT_MAC_USE_COCOA
       
  2277     HIViewRemoveFromSuperview(myView);
       
  2278     determineWindowClass();
       
  2279     createWindow_sys();
       
  2280     if (QMainWindowLayout *mwl = qobject_cast<QMainWindowLayout *>(q->layout())) {
       
  2281         mwl->updateHIToolBarStatus();
       
  2282     }
       
  2283 
       
  2284     if (IsWindowVisible(oldWindow))
       
  2285         show_sys();
       
  2286 #else
       
  2287     QMacCocoaAutoReleasePool pool;
       
  2288     [myView removeFromSuperview];
       
  2289     determineWindowClass();
       
  2290     createWindow_sys();
       
  2291     if (NSToolbar *toolbar = [oldWindow toolbar]) {
       
  2292         OSWindowRef newWindow = qt_mac_window_for(myView);
       
  2293         [newWindow setToolbar:toolbar];
       
  2294         [toolbar setVisible:[toolbar isVisible]];
       
  2295     }
       
  2296     if ([oldWindow isVisible]){
       
  2297         if ([oldWindow isSheet])
       
  2298             [NSApp endSheet:oldWindow];
       
  2299         [oldWindow orderOut:oldWindow];
       
  2300         show_sys();
       
  2301     }
       
  2302 #endif // QT_MAC_USE_COCOA
       
  2303 
       
  2304     // Release the window after creating the new window, because releasing it early
       
  2305     // may cause the app to quit ("close on last window closed attribute")
       
  2306     qt_mac_destructWindow(oldWindow);
       
  2307 }
       
  2308 
       
  2309 void QWidgetPrivate::createWindow_sys()
       
  2310 {
       
  2311     Q_Q(QWidget);
       
  2312     Qt::WindowFlags &flags = data.window_flags;
       
  2313     QWidget *parentWidget = q->parentWidget();
       
  2314 
       
  2315     QTLWExtra *topExtra = topData();
       
  2316     if (topExtra->embedded)
       
  2317         return;  // Simply return because this view "is" the top window.
       
  2318     quint32 wattr = topExtra->wattr;
       
  2319 
       
  2320     if(parentWidget && (parentWidget->window()->windowFlags() & Qt::WindowStaysOnTopHint)) // If our parent has Qt::WStyle_StaysOnTop, so must we
       
  2321         flags |= Qt::WindowStaysOnTopHint;
       
  2322 
       
  2323     data.fstrut_dirty = true;
       
  2324 
       
  2325     OSWindowRef windowRef = qt_mac_create_window(q, topExtra->wclass, wattr, data.crect);
       
  2326     if (windowRef == 0)
       
  2327         qWarning("QWidget: Internal error: %s:%d: If you reach this error please contact Qt Support and include the\n"
       
  2328                 "      WidgetFlags used in creating the widget.", __FILE__, __LINE__);
       
  2329 #ifndef QT_MAC_USE_COCOA
       
  2330     finishCreateWindow_sys_Carbon(windowRef);
       
  2331 #else
       
  2332     finishCreateWindow_sys_Cocoa(windowRef);
       
  2333 #endif
       
  2334 }
       
  2335 
       
  2336 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
       
  2337 {
       
  2338     Q_Q(QWidget);
       
  2339     OSViewRef destroyid = 0;
       
  2340 #ifndef QT_MAC_USE_COCOA
       
  2341     window_event = 0;
       
  2342 #endif
       
  2343 
       
  2344     Qt::WindowType type = q->windowType();
       
  2345     Qt::WindowFlags flags = data.window_flags;
       
  2346     QWidget *parentWidget = q->parentWidget();
       
  2347 
       
  2348     bool topLevel = (flags & Qt::Window);
       
  2349     bool popup = (type == Qt::Popup);
       
  2350     bool dialog = (type == Qt::Dialog
       
  2351                    || type == Qt::Sheet
       
  2352                    || type == Qt::Drawer
       
  2353                    || (flags & Qt::MSWindowsFixedSizeDialogHint));
       
  2354     bool desktop = (type == Qt::Desktop);
       
  2355 
       
  2356     // Determine this early for top-levels so, we can use it later.
       
  2357     if (topLevel)
       
  2358         determineWindowClass();
       
  2359 
       
  2360     if (desktop) {
       
  2361         QSize desktopSize = qt_mac_desktopSize();
       
  2362         q->setAttribute(Qt::WA_WState_Visible);
       
  2363         data.crect.setRect(0, 0, desktopSize.width(), desktopSize.height());
       
  2364         dialog = popup = false;                  // force these flags off
       
  2365     } else {
       
  2366         q->setAttribute(Qt::WA_WState_Visible, false);
       
  2367 
       
  2368         if (topLevel && (type != Qt::Drawer)) {
       
  2369             if (QDesktopWidget *dsk = QApplication::desktop()) { // calc pos/size from screen
       
  2370                 const bool wasResized = q->testAttribute(Qt::WA_Resized);
       
  2371                 const bool wasMoved = q->testAttribute(Qt::WA_Moved);
       
  2372                 int deskn = dsk->primaryScreen();
       
  2373                 if (parentWidget && parentWidget->windowType() != Qt::Desktop)
       
  2374                     deskn = dsk->screenNumber(parentWidget);
       
  2375                 QRect screenGeo = dsk->screenGeometry(deskn);
       
  2376                 if (!wasResized) {
       
  2377 #ifndef QT_MAC_USE_COCOA
       
  2378                     data.crect.setSize(QSize(screenGeo.width()/2, 4*screenGeo.height()/10));
       
  2379 #else
       
  2380                     NSRect newRect = [NSWindow frameRectForContentRect:NSMakeRect(0, 0,
       
  2381                                                                   screenGeo.width() / 2.,
       
  2382                                                                   4 * screenGeo.height() / 10.)
       
  2383                                         styleMask:topData()->wattr];
       
  2384                     data.crect.setSize(QSize(newRect.size.width, newRect.size.height));
       
  2385 #endif
       
  2386                     // Constrain to minimums and maximums we've set
       
  2387                     if (extra->minw > 0)
       
  2388                         data.crect.setWidth(qMax(extra->minw, data.crect.width()));
       
  2389                     if (extra->minh > 0)
       
  2390                         data.crect.setHeight(qMax(extra->minh, data.crect.height()));
       
  2391                     if (extra->maxw > 0)
       
  2392                         data.crect.setWidth(qMin(extra->maxw, data.crect.width()));
       
  2393                     if (extra->maxh > 0)
       
  2394                         data.crect.setHeight(qMin(extra->maxh, data.crect.height()));
       
  2395                 }
       
  2396                 if (!wasMoved && !q->testAttribute(Qt::WA_DontShowOnScreen))
       
  2397                     data.crect.moveTopLeft(QPoint(screenGeo.width()/4,
       
  2398                                                   3 * screenGeo.height() / 10));
       
  2399             }
       
  2400         }
       
  2401     }
       
  2402 
       
  2403 
       
  2404     if(!window)                              // always initialize
       
  2405         initializeWindow=true;
       
  2406 
       
  2407     hd = 0;
       
  2408     if(window) {                                // override the old window (with a new NSView)
       
  2409         OSViewRef nativeView = OSViewRef(window);
       
  2410         OSViewRef parent = 0;
       
  2411 #ifndef QT_MAC_USE_COCOA
       
  2412         CFRetain(nativeView);
       
  2413 #else
       
  2414         [nativeView retain];
       
  2415 #endif
       
  2416         if (destroyOldWindow)
       
  2417             destroyid = qt_mac_nativeview_for(q);
       
  2418         bool transfer = false;
       
  2419         setWinId((WId)nativeView);
       
  2420 #ifndef QT_MAC_USE_COCOA
       
  2421 #ifndef HIViewInstallEventHandler
       
  2422         // Macro taken from the CarbonEvents Header on Tiger
       
  2423 #define HIViewInstallEventHandler( target, handler, numTypes, list, userData, outHandlerRef ) \
       
  2424                InstallEventHandler( HIObjectGetEventTarget( (HIObjectRef) (target) ), (handler), (numTypes), (list), (userData), (outHandlerRef) )
       
  2425 #endif
       
  2426         HIViewInstallEventHandler(nativeView, make_widget_eventUPP(), GetEventTypeCount(widget_events), widget_events, 0, 0);
       
  2427 #endif
       
  2428         if(topLevel) {
       
  2429             for(int i = 0; i < 2; ++i) {
       
  2430                 if(i == 1) {
       
  2431                     if(!initializeWindow)
       
  2432                         break;
       
  2433                     createWindow_sys();
       
  2434                 }
       
  2435                 if(OSWindowRef windowref = qt_mac_window_for(nativeView)) {
       
  2436 #ifndef QT_MAC_USE_COCOA
       
  2437                     CFRetain(windowref);
       
  2438 #else
       
  2439                     [windowref retain];
       
  2440 #endif
       
  2441                     if (initializeWindow) {
       
  2442                         parent = qt_mac_get_contentview_for(windowref);
       
  2443                     } else {
       
  2444 #ifndef QT_MAC_USE_COCOA
       
  2445                         parent = HIViewGetSuperview(nativeView);
       
  2446 #else
       
  2447                         parent = [nativeView superview];
       
  2448 #endif
       
  2449                     }
       
  2450                     break;
       
  2451                 }
       
  2452             }
       
  2453             if(!parent)
       
  2454                 transfer = true;
       
  2455         } else if (parentWidget) {
       
  2456             // I need to be added to my parent, therefore my parent needs an NSView
       
  2457             parentWidget->createWinId();
       
  2458             parent = qt_mac_nativeview_for(parentWidget);
       
  2459         }
       
  2460         if(parent != nativeView && parent) {
       
  2461 #ifndef QT_MAC_USE_COCOA
       
  2462             HIViewAddSubview(parent, nativeView);
       
  2463 #else
       
  2464             [parent addSubview:nativeView];
       
  2465 #endif
       
  2466         }
       
  2467         if(transfer)
       
  2468             transferChildren();
       
  2469         data.fstrut_dirty = true; // we'll re calculate this later
       
  2470         q->setAttribute(Qt::WA_WState_Visible,
       
  2471 #ifndef QT_MAC_USE_COCOA
       
  2472                         HIViewIsVisible(nativeView)
       
  2473 #else
       
  2474                         ![nativeView isHidden]
       
  2475 #endif
       
  2476                         );
       
  2477         if(initializeWindow) {
       
  2478 #ifndef QT_MAC_USE_COCOA
       
  2479             HIRect bounds = CGRectMake(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
       
  2480             HIViewSetFrame(nativeView, &bounds);
       
  2481             q->setAttribute(Qt::WA_WState_Visible, HIViewIsVisible(nativeView));
       
  2482 #else
       
  2483             NSRect bounds = NSMakeRect(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
       
  2484             [nativeView setFrame:bounds];
       
  2485             q->setAttribute(Qt::WA_WState_Visible, [nativeView isHidden]);
       
  2486 #endif
       
  2487         }
       
  2488 #ifndef QT_MAC_USE_COCOA
       
  2489         initWindowPtr();
       
  2490 #endif
       
  2491     } else if (desktop) {                        // desktop widget
       
  2492         if (!qt_root_win)
       
  2493             QWidgetPrivate::qt_create_root_win();
       
  2494         Q_ASSERT(qt_root_win);
       
  2495         WId rootWinID = 0;
       
  2496 #ifndef QT_MAC_USE_COCOA
       
  2497         CFRetain(qt_root_win);
       
  2498         if(HIViewRef rootContentView = HIViewGetRoot(qt_root_win)) {
       
  2499             rootWinID = (WId)rootContentView;
       
  2500             CFRetain(rootContentView);
       
  2501         }
       
  2502 #else
       
  2503         [qt_root_win retain];
       
  2504         if (OSViewRef rootContentView = [qt_root_win contentView]) {
       
  2505             rootWinID = (WId)rootContentView;
       
  2506             [rootContentView retain];
       
  2507         }
       
  2508 #endif
       
  2509         setWinId(rootWinID);
       
  2510     } else if (topLevel) {
       
  2511         determineWindowClass();
       
  2512         if(OSViewRef osview = qt_mac_create_widget(q, this, 0)) {
       
  2513 #ifndef QT_MAC_USE_COCOA
       
  2514             HIRect bounds = CGRectMake(data.crect.x(), data.crect.y(),
       
  2515                                        data.crect.width(), data.crect.height());
       
  2516             HIViewSetFrame(osview, &bounds);
       
  2517 #else
       
  2518             NSRect bounds = NSMakeRect(data.crect.x(), flipYCoordinate(data.crect.y()),
       
  2519                                        data.crect.width(), data.crect.height());
       
  2520             [osview setFrame:bounds];
       
  2521 #endif
       
  2522             setWinId((WId)osview);
       
  2523         }
       
  2524     } else {
       
  2525         data.fstrut_dirty = false; // non-toplevel widgets don't have a frame, so no need to update the strut
       
  2526         if(OSViewRef osview = qt_mac_create_widget(q, this, qt_mac_nativeview_for(parentWidget))) {
       
  2527 #ifndef QT_MAC_USE_COCOA
       
  2528             HIRect bounds = CGRectMake(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
       
  2529             HIViewSetFrame(osview, &bounds);
       
  2530             setWinId((WId)osview);
       
  2531 #else
       
  2532             NSRect bounds = NSMakeRect(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
       
  2533             [osview setFrame:bounds];
       
  2534             setWinId((WId)osview);
       
  2535 #endif
       
  2536             if (q->testAttribute(Qt::WA_DropSiteRegistered))
       
  2537                 registerDropSite(true);
       
  2538         }
       
  2539     }
       
  2540 
       
  2541     updateIsOpaque();
       
  2542     if (q->hasFocus())
       
  2543         setFocus_sys();
       
  2544     if (!topLevel && initializeWindow)
       
  2545         setWSGeometry();
       
  2546     if (destroyid)
       
  2547         qt_mac_destructView(destroyid);
       
  2548     if (q->testAttribute(Qt::WA_AcceptTouchEvents))
       
  2549         registerTouchWindow();
       
  2550 }
       
  2551 
       
  2552 /*!
       
  2553     Returns the QuickDraw handle of the widget. Use of this function is not
       
  2554     portable. This function will return 0 if QuickDraw is not supported, or
       
  2555     if the handle could not be created.
       
  2556 
       
  2557     \warning This function is only available on Mac OS X.
       
  2558 */
       
  2559 
       
  2560 Qt::HANDLE
       
  2561 QWidget::macQDHandle() const
       
  2562 {
       
  2563 #ifndef QT_MAC_USE_COCOA
       
  2564     return d_func()->qd_hd;
       
  2565 #else
       
  2566     return 0;
       
  2567 #endif
       
  2568 }
       
  2569 
       
  2570 /*!
       
  2571   Returns the CoreGraphics handle of the widget. Use of this function is
       
  2572   not portable. This function will return 0 if no painter context can be
       
  2573   established, or if the handle could not be created.
       
  2574 
       
  2575   \warning This function is only available on Mac OS X.
       
  2576 */
       
  2577 Qt::HANDLE
       
  2578 QWidget::macCGHandle() const
       
  2579 {
       
  2580     return handle();
       
  2581 }
       
  2582 
       
  2583 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
       
  2584 {
       
  2585     Q_D(QWidget);
       
  2586     if (!isWindow() && parentWidget())
       
  2587         parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
       
  2588     d->deactivateWidgetCleanup();
       
  2589     qt_mac_event_release(this);
       
  2590     if(testAttribute(Qt::WA_WState_Created)) {
       
  2591         QMacCocoaAutoReleasePool pool;
       
  2592         setAttribute(Qt::WA_WState_Created, false);
       
  2593         QObjectList chldrn = children();
       
  2594         for(int i = 0; i < chldrn.size(); i++) {  // destroy all widget children
       
  2595             QObject *obj = chldrn.at(i);
       
  2596             if(obj->isWidgetType())
       
  2597                 static_cast<QWidget*>(obj)->destroy(destroySubWindows, destroySubWindows);
       
  2598         }
       
  2599         if(mac_mouse_grabber == this)
       
  2600             releaseMouse();
       
  2601         if(mac_keyboard_grabber == this)
       
  2602             releaseKeyboard();
       
  2603         if(acceptDrops())
       
  2604             setAcceptDrops(false);
       
  2605 
       
  2606         if(testAttribute(Qt::WA_ShowModal))          // just be sure we leave modal
       
  2607             QApplicationPrivate::leaveModal(this);
       
  2608         else if((windowType() == Qt::Popup))
       
  2609             qApp->d_func()->closePopup(this);
       
  2610         if (destroyWindow) {
       
  2611             if(OSViewRef hiview = qt_mac_nativeview_for(this)) {
       
  2612                 OSWindowRef window = 0;
       
  2613                 NSDrawer *drawer = nil;
       
  2614 #ifdef QT_MAC_USE_COCOA
       
  2615                 if (qt_mac_is_macdrawer(this)) {
       
  2616                     drawer = qt_mac_drawer_for(this);
       
  2617                 } else
       
  2618 #endif
       
  2619                 if (isWindow())
       
  2620                     window = qt_mac_window_for(hiview);
       
  2621 
       
  2622                 // Because of how "destruct" works, we have to do just a normal release for the root_win.
       
  2623                 if (window && window == qt_root_win) {
       
  2624 #ifndef QT_MAC_USE_COCOA
       
  2625                     CFRelease(hiview);
       
  2626 #else
       
  2627                     [hiview release];
       
  2628 #endif
       
  2629                 } else {
       
  2630                     qt_mac_destructView(hiview);
       
  2631                 }
       
  2632                 if (drawer)
       
  2633                     qt_mac_destructDrawer(drawer);
       
  2634                 if (window)
       
  2635                     qt_mac_destructWindow(window);
       
  2636             }
       
  2637         }
       
  2638         QT_TRY {
       
  2639             d->setWinId(0);
       
  2640         } QT_CATCH (const std::bad_alloc &) {
       
  2641             // swallow - destructors must not throw
       
  2642 	}
       
  2643     }
       
  2644 }
       
  2645 
       
  2646 void QWidgetPrivate::transferChildren()
       
  2647 {
       
  2648     Q_Q(QWidget);
       
  2649     if (!q->testAttribute(Qt::WA_WState_Created))
       
  2650         return;  // Can't add any views anyway
       
  2651 
       
  2652     QObjectList chlist = q->children();
       
  2653     for (int i = 0; i < chlist.size(); ++i) {
       
  2654         QObject *obj = chlist.at(i);
       
  2655         if (obj->isWidgetType()) {
       
  2656             QWidget *w = (QWidget *)obj;
       
  2657             if (!w->isWindow()) {
       
  2658                 // This seems weird, no need to call it in a loop right?
       
  2659                 if (!topData()->caption.isEmpty())
       
  2660                     setWindowTitle_helper(extra->topextra->caption);
       
  2661                 if (w->testAttribute(Qt::WA_WState_Created)) {
       
  2662 #ifndef QT_MAC_USE_COCOA
       
  2663                     HIViewAddSubview(qt_mac_nativeview_for(q), qt_mac_nativeview_for(w));
       
  2664 #else
       
  2665                     // New NSWindows get an extra reference when drops are
       
  2666                     // registered (at least in 10.5) which means that we may
       
  2667                     // access the window later and get a crash (becasue our
       
  2668                     // widget is dead). Work around this be having the drop
       
  2669                     // site disabled until it is part of the new hierarchy.
       
  2670                     bool oldRegistered = w->testAttribute(Qt::WA_DropSiteRegistered);
       
  2671                     w->setAttribute(Qt::WA_DropSiteRegistered, false);
       
  2672                     [qt_mac_nativeview_for(q) addSubview:qt_mac_nativeview_for(w)];
       
  2673                     w->setAttribute(Qt::WA_DropSiteRegistered, oldRegistered);
       
  2674 #endif
       
  2675                 }
       
  2676             }
       
  2677         }
       
  2678     }
       
  2679 }
       
  2680 
       
  2681 void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
       
  2682 {
       
  2683     Q_Q(QWidget);
       
  2684     QMacCocoaAutoReleasePool pool;
       
  2685     QTLWExtra *topData = maybeTopData();
       
  2686     bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
       
  2687 #ifdef QT_MAC_USE_COCOA
       
  2688     bool wasWindow = q->isWindow();
       
  2689 #endif
       
  2690     OSViewRef old_id = 0;
       
  2691 
       
  2692     if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
       
  2693         q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
       
  2694 
       
  2695     // Maintain the glWidgets list on parent change: remove "our" gl widgets
       
  2696     // from the list on the old parent and grandparents.
       
  2697     if (glWidgets.isEmpty() == false) {
       
  2698         QWidget *current = q->parentWidget();
       
  2699         while (current) {
       
  2700             for (QList<QWidgetPrivate::GlWidgetInfo>::const_iterator it = glWidgets.constBegin();
       
  2701                  it != glWidgets.constEnd(); ++it)
       
  2702                 current->d_func()->glWidgets.removeAll(*it);
       
  2703 
       
  2704             if (current->isWindow())
       
  2705                 break;
       
  2706             current = current->parentWidget();
       
  2707         }
       
  2708     }
       
  2709 
       
  2710 #ifndef QT_MAC_USE_COCOA
       
  2711     EventHandlerRef old_window_event = 0;
       
  2712 #else
       
  2713     bool oldToolbarVisible = false;
       
  2714     NSDrawer *oldDrawer = nil;
       
  2715     NSToolbar *oldToolbar = 0;
       
  2716 #endif
       
  2717     if (wasCreated && !(q->windowType() == Qt::Desktop)) {
       
  2718         old_id = qt_mac_nativeview_for(q);
       
  2719 #ifndef QT_MAC_USE_COCOA
       
  2720         old_window_event = window_event;
       
  2721 #else
       
  2722         OSWindowRef oldWindow = qt_mac_window_for(old_id);
       
  2723         if (qt_mac_is_macdrawer(q)) {
       
  2724             oldDrawer = qt_mac_drawer_for(q);
       
  2725         }
       
  2726         if (wasWindow) {
       
  2727             oldToolbar = [oldWindow toolbar];
       
  2728             oldToolbarVisible = [oldToolbar isVisible];
       
  2729         }
       
  2730 #endif
       
  2731     }
       
  2732     QWidget* oldtlw = q->window();
       
  2733 
       
  2734     if (q->testAttribute(Qt::WA_DropSiteRegistered))
       
  2735         q->setAttribute(Qt::WA_DropSiteRegistered, false);
       
  2736 
       
  2737     //recreate and setup flags
       
  2738     QObjectPrivate::setParent_helper(parent);
       
  2739     QPoint pt = q->pos();
       
  2740     bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
       
  2741     if (wasCreated && !qt_isGenuineQWidget(q))
       
  2742         return;
       
  2743 
       
  2744     if ((data.window_flags & Qt::Sheet) && topData && topData->opacity == 242)
       
  2745         q->setWindowOpacity(1.0f);
       
  2746 
       
  2747     setWinId(0); //do after the above because they may want the id
       
  2748 
       
  2749     data.window_flags = f;
       
  2750     q->setAttribute(Qt::WA_WState_Created, false);
       
  2751     q->setAttribute(Qt::WA_WState_Visible, false);
       
  2752     q->setAttribute(Qt::WA_WState_Hidden, false);
       
  2753     adjustFlags(data.window_flags, q);
       
  2754     // keep compatibility with previous versions, we need to preserve the created state
       
  2755     // (but we recreate the winId for the widget being reparented, again for compatibility)
       
  2756     if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created))) {
       
  2757         createWinId();
       
  2758         if (q->isWindow()) {
       
  2759 #ifndef QT_MAC_USE_COCOA
       
  2760             // We do this down below for wasCreated, so avoid doing this twice
       
  2761             // (only for performance, it gets called a lot anyway).
       
  2762             if (!wasCreated) {
       
  2763                 if (QMainWindowLayout *mwl = qobject_cast<QMainWindowLayout *>(q->layout())) {
       
  2764                     mwl->updateHIToolBarStatus();
       
  2765                 }
       
  2766             }
       
  2767 #else
       
  2768             // Simply transfer our toolbar over. Everything should stay put, unlike in Carbon.
       
  2769             if (oldToolbar && !(f & Qt::FramelessWindowHint)) {
       
  2770                 OSWindowRef newWindow = qt_mac_window_for(q);
       
  2771                 [newWindow setToolbar:oldToolbar];
       
  2772                 [oldToolbar setVisible:oldToolbarVisible];
       
  2773             }
       
  2774 #endif
       
  2775         }
       
  2776     }
       
  2777     if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
       
  2778         q->setAttribute(Qt::WA_WState_Hidden);
       
  2779     q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
       
  2780 
       
  2781     if (wasCreated) {
       
  2782         transferChildren();
       
  2783 #ifndef QT_MAC_USE_COCOA
       
  2784         // If we were a unified window, We just transfered our toolbars out of the unified toolbar.
       
  2785         // So redo the status one more time. It apparently is not an issue with Cocoa.
       
  2786         if (q->isWindow()) {
       
  2787             if (QMainWindowLayout *mwl = qobject_cast<QMainWindowLayout *>(q->layout())) {
       
  2788                 mwl->updateHIToolBarStatus();
       
  2789             }
       
  2790         }
       
  2791 #endif
       
  2792 
       
  2793         if (topData &&
       
  2794                 (!topData->caption.isEmpty() || !topData->filePath.isEmpty()))
       
  2795             setWindowTitle_helper(q->windowTitle());
       
  2796     }
       
  2797 
       
  2798     if (q->testAttribute(Qt::WA_AcceptDrops)
       
  2799         || (!q->isWindow() && q->parentWidget()
       
  2800             && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)))
       
  2801         q->setAttribute(Qt::WA_DropSiteRegistered, true);
       
  2802 
       
  2803     //cleanup
       
  2804 #ifndef QT_MAC_USE_COCOA
       
  2805     if (old_window_event)
       
  2806         RemoveEventHandler(old_window_event);
       
  2807 #endif
       
  2808     if (old_id) { //don't need old window anymore
       
  2809         OSWindowRef window = (oldtlw == q) ? qt_mac_window_for(old_id) : 0;
       
  2810         qt_mac_destructView(old_id);
       
  2811 
       
  2812 #ifdef QT_MAC_USE_COCOA
       
  2813         if (oldDrawer) {
       
  2814             qt_mac_destructDrawer(oldDrawer);
       
  2815         } else
       
  2816 #endif
       
  2817         if (window)
       
  2818             qt_mac_destructWindow(window);
       
  2819     }
       
  2820 
       
  2821     // Maintain the glWidgets list on parent change: add "our" gl widgets
       
  2822     // to the list on the new parent and grandparents.
       
  2823     if (glWidgets.isEmpty() == false) {
       
  2824         QWidget *current = q->parentWidget();
       
  2825         while (current) {
       
  2826             current->d_func()->glWidgets += glWidgets;
       
  2827             if (current->isWindow())
       
  2828                 break;
       
  2829             current = current->parentWidget();
       
  2830         }
       
  2831     }
       
  2832 
       
  2833     invalidateBuffer(q->rect());
       
  2834     qt_event_request_window_change(q);
       
  2835 }
       
  2836 
       
  2837 QPoint QWidget::mapToGlobal(const QPoint &pos) const
       
  2838 {
       
  2839     Q_D(const QWidget);
       
  2840     if (!testAttribute(Qt::WA_WState_Created)) {
       
  2841         QPoint p = pos + data->crect.topLeft();
       
  2842         return isWindow() ?  p : parentWidget()->mapToGlobal(p);
       
  2843     }
       
  2844 #ifndef QT_MAC_USE_COCOA
       
  2845     QPoint tmp = d->mapToWS(pos);
       
  2846     HIPoint hi_pos = CGPointMake(tmp.x(), tmp.y());
       
  2847     HIViewConvertPoint(&hi_pos, qt_mac_nativeview_for(this), 0);
       
  2848     Rect win_rect;
       
  2849     GetWindowBounds(qt_mac_window_for(this), kWindowStructureRgn, &win_rect);
       
  2850     return QPoint((int)hi_pos.x+win_rect.left, (int)hi_pos.y+win_rect.top);
       
  2851 #else
       
  2852     QPoint tmp = d->mapToWS(pos);
       
  2853     NSPoint hi_pos = NSMakePoint(tmp.x(), tmp.y());
       
  2854     hi_pos = [qt_mac_nativeview_for(this) convertPoint:hi_pos toView:nil];
       
  2855     NSRect win_rect = [qt_mac_window_for(this) frame];
       
  2856     hi_pos.x += win_rect.origin.x;
       
  2857     hi_pos.y += win_rect.origin.y;
       
  2858     // If we aren't the desktop we need to flip, if you flip the desktop on itself, you get the other problem.
       
  2859     return ((window()->windowFlags() & Qt::Desktop) == Qt::Desktop) ? QPointF(hi_pos.x, hi_pos.y).toPoint()
       
  2860                                                                     : flipPoint(hi_pos).toPoint();
       
  2861 #endif
       
  2862 }
       
  2863 
       
  2864 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
       
  2865 {
       
  2866     Q_D(const QWidget);
       
  2867     if (!testAttribute(Qt::WA_WState_Created)) {
       
  2868         QPoint p = isWindow() ?  pos : parentWidget()->mapFromGlobal(pos);
       
  2869         return p - data->crect.topLeft();
       
  2870     }
       
  2871 #ifndef QT_MAC_USE_COCOA
       
  2872     Rect win_rect;
       
  2873     GetWindowBounds(qt_mac_window_for(this), kWindowStructureRgn, &win_rect);
       
  2874     HIPoint hi_pos = CGPointMake(pos.x()-win_rect.left, pos.y()-win_rect.top);
       
  2875     HIViewConvertPoint(&hi_pos, 0, qt_mac_nativeview_for(this));
       
  2876     return d->mapFromWS(QPoint((int)hi_pos.x, (int)hi_pos.y));
       
  2877 #else
       
  2878     NSRect win_rect = [qt_mac_window_for(this) frame];
       
  2879     // The Window point is in "Cocoa coordinates," but the view is in "Qt coordinates"
       
  2880     // so make sure to keep them in sync.
       
  2881     NSPoint hi_pos = NSMakePoint(pos.x()-win_rect.origin.x,
       
  2882                                  flipYCoordinate(pos.y())-win_rect.origin.y);
       
  2883     hi_pos = [qt_mac_nativeview_for(this) convertPoint:hi_pos fromView:0];
       
  2884     return d->mapFromWS(QPoint(qRound(hi_pos.x), qRound(hi_pos.y)));
       
  2885 #endif
       
  2886 }
       
  2887 
       
  2888 void QWidgetPrivate::updateSystemBackground()
       
  2889 {
       
  2890 }
       
  2891 
       
  2892 void QWidgetPrivate::setCursor_sys(const QCursor &)
       
  2893 {
       
  2894 #ifndef QT_MAC_USE_COCOA
       
  2895     qt_mac_update_cursor();
       
  2896 #else
       
  2897      Q_Q(QWidget);
       
  2898     if (q->testAttribute(Qt::WA_WState_Created)) {
       
  2899         [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
       
  2900     }
       
  2901 #endif
       
  2902 }
       
  2903 
       
  2904 void QWidgetPrivate::unsetCursor_sys()
       
  2905 {
       
  2906 #ifndef QT_MAC_USE_COCOA
       
  2907     qt_mac_update_cursor();
       
  2908 #else
       
  2909      Q_Q(QWidget);
       
  2910     if (q->testAttribute(Qt::WA_WState_Created)) {
       
  2911         [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
       
  2912     }
       
  2913 #endif
       
  2914 }
       
  2915 
       
  2916 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
       
  2917 {
       
  2918     Q_Q(QWidget);
       
  2919     if (q->isWindow()) {
       
  2920 #ifndef QT_MAC_USE_COCOA
       
  2921         SetWindowTitleWithCFString(qt_mac_window_for(q), QCFString(caption));
       
  2922 #else
       
  2923         QMacCocoaAutoReleasePool pool;
       
  2924         [qt_mac_window_for(q) setTitle:qt_mac_QStringToNSString(caption)];
       
  2925 #endif
       
  2926     }
       
  2927 }
       
  2928 
       
  2929 void QWidgetPrivate::setWindowModified_sys(bool mod)
       
  2930 {
       
  2931     Q_Q(QWidget);
       
  2932     if (q->isWindow() && q->testAttribute(Qt::WA_WState_Created)) {
       
  2933 #ifndef QT_MAC_USE_COCOA
       
  2934         SetWindowModified(qt_mac_window_for(q), mod);
       
  2935 #else
       
  2936         [qt_mac_window_for(q) setDocumentEdited:mod];
       
  2937 #endif
       
  2938     }
       
  2939 }
       
  2940 
       
  2941 void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath)
       
  2942 {
       
  2943     Q_Q(QWidget);
       
  2944 #ifdef QT_MAC_USE_COCOA
       
  2945     QMacCocoaAutoReleasePool pool;
       
  2946     QFileInfo fi(filePath);
       
  2947     [qt_mac_window_for(q) setRepresentedFilename:fi.exists() ? qt_mac_QStringToNSString(filePath) : @""];
       
  2948 #else
       
  2949     bool validRef = false;
       
  2950     FSRef ref;
       
  2951     bzero(&ref, sizeof(ref));
       
  2952     OSStatus status;
       
  2953 
       
  2954     if (!filePath.isEmpty()) {
       
  2955         status = FSPathMakeRef(reinterpret_cast<const UInt8 *>(filePath.toUtf8().constData()), &ref, 0);
       
  2956         validRef = (status == noErr);
       
  2957     }
       
  2958     // Set the proxy regardless, since this is our way of clearing it as well, but ignore the
       
  2959     // return value as well.
       
  2960     if (validRef) {
       
  2961         status = HIWindowSetProxyFSRef(qt_mac_window_for(q), &ref);
       
  2962     } else {
       
  2963         status = RemoveWindowProxy(qt_mac_window_for(q));
       
  2964     }
       
  2965     if (status != noErr)
       
  2966         qWarning("QWidget::setWindowFilePath: Error setting proxyicon for path (%s):%ld",
       
  2967                 qPrintable(filePath), status);
       
  2968 #endif
       
  2969 }
       
  2970 
       
  2971 void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
       
  2972 {
       
  2973     Q_Q(QWidget);
       
  2974 
       
  2975     if (!q->testAttribute(Qt::WA_WState_Created))
       
  2976         return;
       
  2977 
       
  2978     QTLWExtra *topData = this->topData();
       
  2979     if (topData->iconPixmap && !forceReset) // already set
       
  2980         return;
       
  2981 
       
  2982     QIcon icon = q->windowIcon();
       
  2983     QPixmap *pm = 0;
       
  2984     if (!icon.isNull()) {
       
  2985         // now create the extra
       
  2986         if (!topData->iconPixmap) {
       
  2987             pm = new QPixmap(icon.pixmap(QSize(22, 22)));
       
  2988             topData->iconPixmap = pm;
       
  2989         } else {
       
  2990             pm = topData->iconPixmap;
       
  2991         }
       
  2992     }
       
  2993     if (q->isWindow()) {
       
  2994 #ifndef QT_MAC_USE_COCOA
       
  2995         IconRef previousIcon = 0;
       
  2996         if (icon.isNull()) {
       
  2997             RemoveWindowProxy(qt_mac_window_for(q));
       
  2998             previousIcon = topData->windowIcon;
       
  2999             topData->windowIcon = 0;
       
  3000         } else {
       
  3001             WindowClass wclass;
       
  3002             GetWindowClass(qt_mac_window_for(q), &wclass);
       
  3003 
       
  3004             if (wclass == kDocumentWindowClass) {
       
  3005                 IconRef newIcon = qt_mac_create_iconref(*pm);
       
  3006                 previousIcon = topData->windowIcon;
       
  3007                 topData->windowIcon = newIcon;
       
  3008                 SetWindowProxyIcon(qt_mac_window_for(q), newIcon);
       
  3009             }
       
  3010         }
       
  3011 
       
  3012         // Release the previous icon if it was set by this function.
       
  3013         if (previousIcon != 0)
       
  3014             ReleaseIconRef(previousIcon);
       
  3015 #else
       
  3016         QMacCocoaAutoReleasePool pool;
       
  3017         NSButton *iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
       
  3018         if (icon.isNull()) {
       
  3019             [iconButton setImage:nil];
       
  3020         } else {
       
  3021             NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(*pm));
       
  3022             [iconButton setImage:image];
       
  3023             [image release];
       
  3024         }
       
  3025 #endif
       
  3026     }
       
  3027 }
       
  3028 
       
  3029 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
       
  3030 {
       
  3031     Q_Q(QWidget);
       
  3032     if(q->isWindow() && !iconText.isEmpty()) {
       
  3033 #ifndef QT_MAC_USE_COCOA
       
  3034         SetWindowAlternateTitle(qt_mac_window_for(q), QCFString(iconText));
       
  3035 #else
       
  3036         QMacCocoaAutoReleasePool pool;
       
  3037         [qt_mac_window_for(q) setMiniwindowTitle:qt_mac_QStringToNSString(iconText)];
       
  3038 #endif
       
  3039     }
       
  3040 }
       
  3041 
       
  3042 void QWidget::grabMouse()
       
  3043 {
       
  3044     if(isVisible() && !qt_nograb()) {
       
  3045         if(mac_mouse_grabber)
       
  3046             mac_mouse_grabber->releaseMouse();
       
  3047         mac_mouse_grabber=this;
       
  3048     }
       
  3049 }
       
  3050 
       
  3051 void QWidget::grabMouse(const QCursor &)
       
  3052 {
       
  3053     if(isVisible() && !qt_nograb()) {
       
  3054         if(mac_mouse_grabber)
       
  3055             mac_mouse_grabber->releaseMouse();
       
  3056         mac_mouse_grabber=this;
       
  3057     }
       
  3058 }
       
  3059 
       
  3060 void QWidget::releaseMouse()
       
  3061 {
       
  3062     if(!qt_nograb() && mac_mouse_grabber == this)
       
  3063         mac_mouse_grabber = 0;
       
  3064 }
       
  3065 
       
  3066 void QWidget::grabKeyboard()
       
  3067 {
       
  3068     if(!qt_nograb()) {
       
  3069         if(mac_keyboard_grabber)
       
  3070             mac_keyboard_grabber->releaseKeyboard();
       
  3071         mac_keyboard_grabber = this;
       
  3072     }
       
  3073 }
       
  3074 
       
  3075 void QWidget::releaseKeyboard()
       
  3076 {
       
  3077     if(!qt_nograb() && mac_keyboard_grabber == this)
       
  3078         mac_keyboard_grabber = 0;
       
  3079 }
       
  3080 
       
  3081 QWidget *QWidget::mouseGrabber()
       
  3082 {
       
  3083     return mac_mouse_grabber;
       
  3084 }
       
  3085 
       
  3086 QWidget *QWidget::keyboardGrabber()
       
  3087 {
       
  3088     return mac_keyboard_grabber;
       
  3089 }
       
  3090 
       
  3091 void QWidget::activateWindow()
       
  3092 {
       
  3093     QWidget *tlw = window();
       
  3094     if(!tlw->isVisible() || !tlw->isWindow() || (tlw->windowType() == Qt::Desktop))
       
  3095         return;
       
  3096     qt_event_remove_activate();
       
  3097 
       
  3098     QWidget *fullScreenWidget = tlw;
       
  3099     QWidget *parentW = tlw;
       
  3100     // Find the oldest parent or the parent with fullscreen, whichever comes first.
       
  3101     while (parentW) {
       
  3102         fullScreenWidget = parentW->window();
       
  3103         if (fullScreenWidget->windowState() & Qt::WindowFullScreen)
       
  3104             break;
       
  3105         parentW = fullScreenWidget->parentWidget();
       
  3106     }
       
  3107 
       
  3108     if (fullScreenWidget->windowType() != Qt::ToolTip) {
       
  3109         qt_mac_set_fullscreen_mode((fullScreenWidget->windowState() & Qt::WindowFullScreen) &&
       
  3110                                                qApp->desktop()->screenNumber(this) == 0);
       
  3111     }
       
  3112 
       
  3113     bool windowActive;
       
  3114     OSWindowRef win = qt_mac_window_for(tlw);
       
  3115 #ifndef QT_MAC_USE_COCOA
       
  3116     windowActive = IsWindowActive(win);
       
  3117 #else
       
  3118     QMacCocoaAutoReleasePool pool;
       
  3119     windowActive = [win isKeyWindow];
       
  3120 #endif
       
  3121     if ((tlw->windowType() == Qt::Popup)
       
  3122             || (tlw->windowType() == Qt::Tool)
       
  3123             || qt_mac_is_macdrawer(tlw)
       
  3124             || windowActive) {
       
  3125 #ifndef QT_MAC_USE_COCOA
       
  3126         ActivateWindow(win, true);
       
  3127 #else
       
  3128         [win makeKeyWindow];
       
  3129 #endif
       
  3130         qApp->setActiveWindow(tlw);
       
  3131     } else if(!isMinimized()) {
       
  3132 #ifndef QT_MAC_USE_COCOA
       
  3133         SelectWindow(win);
       
  3134 #else
       
  3135         [win makeKeyAndOrderFront:win];
       
  3136 #endif
       
  3137     }
       
  3138 }
       
  3139 
       
  3140 QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
       
  3141 {
       
  3142     return new QMacWindowSurface(q_func());
       
  3143 }
       
  3144 
       
  3145 void QWidgetPrivate::update_sys(const QRect &r)
       
  3146 {
       
  3147     Q_Q(QWidget);
       
  3148     if (r == q->rect()) {
       
  3149         if (updateRedirectedToGraphicsProxyWidget(q, r))
       
  3150             return;
       
  3151         dirtyOnWidget += r;
       
  3152 #ifndef QT_MAC_USE_COCOA
       
  3153             HIViewSetNeedsDisplay(qt_mac_nativeview_for(q), true);
       
  3154 #else
       
  3155             [qt_mac_nativeview_for(q) setNeedsDisplay:YES];
       
  3156 #endif
       
  3157         return;
       
  3158     }
       
  3159 
       
  3160     int x = r.x(), y = r.y(), w = r.width(), h = r.height();
       
  3161     if (w < 0)
       
  3162         w = q->data->crect.width() - x;
       
  3163     if (h < 0)
       
  3164         h = q->data->crect.height() - y;
       
  3165     if (w && h) {
       
  3166         const QRect updateRect = QRect(x, y, w, h);
       
  3167         if (updateRedirectedToGraphicsProxyWidget(q, updateRect))
       
  3168             return;
       
  3169 #ifndef QT_MAC_USE_COCOA
       
  3170         dirtyOnWidget += updateRect;
       
  3171         HIRect r = CGRectMake(x, y, w, h);
       
  3172         HIViewSetNeedsDisplayInRect(qt_mac_nativeview_for(q), &r, true);
       
  3173 #else
       
  3174         [qt_mac_nativeview_for(q) setNeedsDisplayInRect:NSMakeRect(x, y, w, h)];
       
  3175 #endif
       
  3176     }
       
  3177 }
       
  3178 
       
  3179 void QWidgetPrivate::update_sys(const QRegion &rgn)
       
  3180 {
       
  3181     Q_Q(QWidget);
       
  3182     if (updateRedirectedToGraphicsProxyWidget(q, rgn))
       
  3183         return;
       
  3184     dirtyOnWidget += rgn;
       
  3185 #ifndef QT_MAC_USE_COCOA
       
  3186     RgnHandle rgnHandle = rgn.toQDRgnForUpdate_sys();
       
  3187     if (rgnHandle)
       
  3188         HIViewSetNeedsDisplayInRegion(qt_mac_nativeview_for(q), QMacSmartQuickDrawRegion(rgnHandle), true);
       
  3189     else {
       
  3190         HIViewSetNeedsDisplay(qt_mac_nativeview_for(q), true); // do a complete repaint on overflow.
       
  3191     }
       
  3192 #else
       
  3193     // Cocoa doesn't do regions, it seems more efficient to just update the bounding rect instead of a potential number of message passes for each rect.
       
  3194     const QRect &boundingRect = rgn.boundingRect();
       
  3195     [qt_mac_nativeview_for(q) setNeedsDisplayInRect:NSMakeRect(boundingRect.x(),
       
  3196                                                             boundingRect.y(), boundingRect.width(),
       
  3197                                                             boundingRect.height())];
       
  3198 #endif
       
  3199 }
       
  3200 
       
  3201 bool QWidgetPrivate::isRealWindow() const
       
  3202 {
       
  3203     return q_func()->isWindow() && !topData()->embedded;
       
  3204 }
       
  3205 
       
  3206 void QWidgetPrivate::show_sys()
       
  3207 {
       
  3208     Q_Q(QWidget);
       
  3209     if ((q->windowType() == Qt::Desktop)) //desktop is always visible
       
  3210         return;
       
  3211 
       
  3212     invalidateBuffer(q->rect());
       
  3213     if (q->testAttribute(Qt::WA_OutsideWSRange))
       
  3214         return;
       
  3215     QMacCocoaAutoReleasePool pool;
       
  3216     q->setAttribute(Qt::WA_Mapped);
       
  3217     if (q->testAttribute(Qt::WA_DontShowOnScreen))
       
  3218         return;
       
  3219 
       
  3220     bool realWindow = isRealWindow();
       
  3221     if (realWindow && !q->testAttribute(Qt::WA_Moved)) {
       
  3222         q->createWinId();
       
  3223         if (QWidget *p = q->parentWidget()) {
       
  3224             p->createWinId();
       
  3225 #ifndef QT_MAC_USE_COCOA
       
  3226             RepositionWindow(qt_mac_window_for(q), qt_mac_window_for(p), kWindowCenterOnParentWindow);
       
  3227 #else
       
  3228             CGRect parentFrame = NSRectToCGRect([qt_mac_window_for(p) frame]);
       
  3229             OSWindowRef windowRef = qt_mac_window_for(q);
       
  3230             NSRect windowFrame = [windowRef frame];
       
  3231             NSPoint parentCenter = NSMakePoint(CGRectGetMidX(parentFrame), CGRectGetMidY(parentFrame));
       
  3232             [windowRef setFrameTopLeftPoint:NSMakePoint(parentCenter.x - (windowFrame.size.width / 2),
       
  3233                                                         (parentCenter.y + (windowFrame.size.height / 2)))];
       
  3234 #endif
       
  3235         } else {
       
  3236 #ifndef QT_MAC_USE_COCOA
       
  3237             RepositionWindow(qt_mac_window_for(q), 0, kWindowCenterOnMainScreen);
       
  3238 #else
       
  3239             // Ideally we would do a "center" here, but NSWindow's center is more equivalent to
       
  3240             // kWindowAlertPositionOnMainScreen instead of kWindowCenterOnMainScreen.
       
  3241             QRect availGeo = QApplication::desktop()->availableGeometry(q);
       
  3242             // Center the content only.
       
  3243             data.crect.moveCenter(availGeo.center());
       
  3244             QRect fStrut = frameStrut();
       
  3245             QRect frameRect(data.crect.x() - fStrut.left(), data.crect.y() - fStrut.top(),
       
  3246                             fStrut.left() + fStrut.right() + data.crect.width(),
       
  3247                             fStrut.top() + fStrut.bottom() + data.crect.height());
       
  3248             NSRect cocoaFrameRect = NSMakeRect(frameRect.x(), flipYCoordinate(frameRect.bottom() + 1), frameRect.width(), frameRect.height());
       
  3249             [qt_mac_window_for(q) setFrame:cocoaFrameRect display:NO];
       
  3250 #endif
       
  3251         }
       
  3252     }
       
  3253     data.fstrut_dirty = true;
       
  3254     if (realWindow) {
       
  3255          // Delegates can change window state, so record some things earlier.
       
  3256         bool isCurrentlyMinimized = (q->windowState() & Qt::WindowMinimized);
       
  3257         setModal_sys();
       
  3258         OSWindowRef window = qt_mac_window_for(q);
       
  3259 #ifndef QT_MAC_USE_COCOA
       
  3260         SizeWindow(window, q->width(), q->height(), true);
       
  3261 #endif
       
  3262 
       
  3263 #ifdef QT_MAC_USE_COCOA
       
  3264         // Make sure that we end up sending a repaint event to
       
  3265         // the widget if the window has been visible one before:
       
  3266         [qt_mac_get_contentview_for(window) setNeedsDisplay:YES];
       
  3267 #endif
       
  3268         if(qt_mac_is_macsheet(q)) {
       
  3269             qt_event_request_showsheet(q);
       
  3270         } else if(qt_mac_is_macdrawer(q)) {
       
  3271 #ifndef QT_MAC_USE_COCOA
       
  3272             OpenDrawer(window, kWindowEdgeDefault, false);
       
  3273 #else
       
  3274             NSDrawer *drawer = qt_mac_drawer_for(q);
       
  3275             [drawer openOnEdge:[drawer preferredEdge]];
       
  3276 #endif
       
  3277         } else {
       
  3278 #ifndef QT_MAC_USE_COCOA
       
  3279             ShowHide(window, true);
       
  3280 #else
       
  3281             // sync the opacity value back (in case of a fade).
       
  3282             [window setAlphaValue:q->windowOpacity()];
       
  3283             [window makeKeyAndOrderFront:window];
       
  3284 
       
  3285             // If this window is app modal, we need to start spinning
       
  3286             // a modal session for it. Interrupting
       
  3287             // the event dispatcher will make this happend:
       
  3288             if (data.window_modality == Qt::ApplicationModal)
       
  3289                 QEventDispatcherMac::instance()->interrupt();
       
  3290 #endif
       
  3291             if (q->windowType() == Qt::Popup) {
       
  3292 			    if (q->focusWidget())
       
  3293 				    q->focusWidget()->d_func()->setFocus_sys();
       
  3294 				else
       
  3295                     setFocus_sys();
       
  3296 			}
       
  3297             toggleDrawers(true);
       
  3298         }
       
  3299         if (isCurrentlyMinimized) { //show in collapsed state
       
  3300 #ifndef QT_MAC_USE_COCOA
       
  3301             CollapseWindow(window, true);
       
  3302 #else
       
  3303             [window miniaturize:window];
       
  3304 #endif
       
  3305         } else if (!q->testAttribute(Qt::WA_ShowWithoutActivating)) {
       
  3306 #ifndef QT_MAC_USE_COCOA
       
  3307             qt_event_request_activate(q);
       
  3308 #else
       
  3309             [qt_mac_window_for(q) makeKeyWindow];
       
  3310 #endif
       
  3311         }
       
  3312     } else if(topData()->embedded || !q->parentWidget() || q->parentWidget()->isVisible()) {
       
  3313 #ifndef QT_MAC_USE_COCOA
       
  3314         HIViewSetVisible(qt_mac_nativeview_for(q), true);
       
  3315 #else
       
  3316         [qt_mac_nativeview_for(q) setHidden:NO];
       
  3317 
       
  3318 #endif
       
  3319     }
       
  3320 
       
  3321     if (!QWidget::mouseGrabber()){
       
  3322         QWidget *enterWidget = QApplication::widgetAt(QCursor::pos());
       
  3323         QApplicationPrivate::dispatchEnterLeave(enterWidget, qt_mouseover);
       
  3324         qt_mouseover = enterWidget;
       
  3325     }
       
  3326 
       
  3327     qt_event_request_window_change(q);
       
  3328 }
       
  3329 
       
  3330 
       
  3331 QPoint qt_mac_nativeMapFromParent(const QWidget *child, const QPoint &pt)
       
  3332 {
       
  3333 #ifndef QT_MAC_USE_COCOA
       
  3334     CGPoint nativePoint = CGPointMake(pt.x(), pt.y());
       
  3335     HIViewConvertPoint(&nativePoint, qt_mac_nativeview_for(child->parentWidget()),
       
  3336                        qt_mac_nativeview_for(child));
       
  3337 #else
       
  3338     NSPoint nativePoint = [qt_mac_nativeview_for(child) convertPoint:NSMakePoint(pt.x(), pt.y()) fromView:qt_mac_nativeview_for(child->parentWidget())];
       
  3339 #endif
       
  3340     return QPoint(nativePoint.x, nativePoint.y);
       
  3341 }
       
  3342 
       
  3343 
       
  3344 void QWidgetPrivate::hide_sys()
       
  3345 {
       
  3346     Q_Q(QWidget);
       
  3347     if((q->windowType() == Qt::Desktop)) //you can't hide the desktop!
       
  3348         return;
       
  3349 
       
  3350     QMacCocoaAutoReleasePool pool;
       
  3351     if(q->isWindow()) {
       
  3352         OSWindowRef window = qt_mac_window_for(q);
       
  3353         if(qt_mac_is_macsheet(q)) {
       
  3354 #ifndef QT_MAC_USE_COCOA
       
  3355             WindowRef parent = 0;
       
  3356             if(GetSheetWindowParent(window, &parent) != noErr || !parent)
       
  3357                 ShowHide(window, false);
       
  3358             else
       
  3359                 HideSheetWindow(window);
       
  3360 #else
       
  3361             [NSApp endSheet:window];
       
  3362             [window orderOut:window];
       
  3363 #endif
       
  3364         } else if(qt_mac_is_macdrawer(q)) {
       
  3365 #ifndef QT_MAC_USE_COCOA
       
  3366             CloseDrawer(window, false);
       
  3367 #else
       
  3368             [qt_mac_drawer_for(q) close];
       
  3369 #endif
       
  3370         } else {
       
  3371 #ifndef QT_MAC_USE_COCOA
       
  3372             ShowHide(window, false);
       
  3373 #else
       
  3374             [window orderOut:window];
       
  3375 #endif
       
  3376             toggleDrawers(false);
       
  3377 #ifndef QT_MAC_USE_COCOA
       
  3378             // Clear modality (because it seems something that we've always done).
       
  3379             if (data.window_modality != Qt::NonModal) {
       
  3380                 SetWindowModality(window, kWindowModalityNone,
       
  3381                           q->parentWidget() ? qt_mac_window_for(q->parentWidget()->window()) : 0);
       
  3382             }
       
  3383 #endif
       
  3384         }
       
  3385         if(q->isActiveWindow() && !(q->windowType() == Qt::Popup)) {
       
  3386             QWidget *w = 0;
       
  3387             if(q->parentWidget())
       
  3388                 w = q->parentWidget()->window();
       
  3389             if(!w || (!w->isVisible() && !w->isMinimized())) {
       
  3390 #ifndef QT_MAC_USE_COCOA
       
  3391                 for(WindowPtr wp = GetFrontWindowOfClass(kDocumentWindowClass, true);
       
  3392                     wp; wp = GetNextWindowOfClass(wp, kDocumentWindowClass, true)) {
       
  3393                     if((w = qt_mac_find_window(wp)))
       
  3394                         break;
       
  3395                 }
       
  3396                 if (!w){
       
  3397                     for(WindowPtr wp = GetFrontWindowOfClass(kSimpleWindowClass, true);
       
  3398                         wp; wp = GetNextWindowOfClass(wp, kSimpleWindowClass, true)) {
       
  3399                         if((w = qt_mac_find_window(wp)))
       
  3400                             break;
       
  3401                     }
       
  3402                 }
       
  3403 #else
       
  3404                 NSArray *windows = [NSApp windows];
       
  3405                 NSUInteger totalWindows = [windows count];
       
  3406                 for (NSUInteger i = 0; i < totalWindows; ++i) {
       
  3407                     OSWindowRef wp = [windows objectAtIndex:i];
       
  3408                     if ((w = qt_mac_find_window(wp)))
       
  3409                         break;
       
  3410                 }
       
  3411 #endif
       
  3412             }
       
  3413             if(w && w->isVisible() && !w->isMinimized()) {
       
  3414 #ifndef QT_MAC_USE_COCOA
       
  3415             qt_event_request_activate(w);
       
  3416 #else
       
  3417             [qt_mac_window_for(w) makeKeyWindow];
       
  3418 #endif
       
  3419             }
       
  3420         }
       
  3421     } else {
       
  3422          invalidateBuffer(q->rect());
       
  3423 #ifndef QT_MAC_USE_COCOA
       
  3424         HIViewSetVisible(qt_mac_nativeview_for(q), false);
       
  3425 #else
       
  3426         [qt_mac_nativeview_for(q) setHidden:YES];
       
  3427 #endif
       
  3428     }
       
  3429 
       
  3430     if (!QWidget::mouseGrabber()){
       
  3431         QWidget *enterWidget = QApplication::widgetAt(QCursor::pos());
       
  3432         QApplicationPrivate::dispatchEnterLeave(enterWidget, qt_mouseover);
       
  3433         qt_mouseover = enterWidget;
       
  3434     }
       
  3435 
       
  3436     qt_event_request_window_change(q);
       
  3437     deactivateWidgetCleanup();
       
  3438     qt_mac_event_release(q);
       
  3439 }
       
  3440 
       
  3441 void QWidget::setWindowState(Qt::WindowStates newstate)
       
  3442 {
       
  3443     Q_D(QWidget);
       
  3444     bool needShow = false;
       
  3445     Qt::WindowStates oldstate = windowState();
       
  3446     if (oldstate == newstate)
       
  3447         return;
       
  3448 
       
  3449 #ifdef QT_MAC_USE_COCOA
       
  3450     QMacCocoaAutoReleasePool pool;
       
  3451 #endif
       
  3452     bool needSendStateChange = true;
       
  3453     if(isWindow()) {
       
  3454         if((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
       
  3455             if(newstate & Qt::WindowFullScreen) {
       
  3456                 if(QTLWExtra *tlextra = d->topData()) {
       
  3457                     if(tlextra->normalGeometry.width() < 0) {
       
  3458                         if(!testAttribute(Qt::WA_Resized))
       
  3459                             adjustSize();
       
  3460                         tlextra->normalGeometry = geometry();
       
  3461                     }
       
  3462                     tlextra->savedFlags = windowFlags();
       
  3463                 }
       
  3464                 needShow = isVisible();
       
  3465                 const QRect fullscreen(qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(this)));
       
  3466                 setParent(parentWidget(), Qt::Window | Qt::FramelessWindowHint | (windowFlags() & 0xffff0000)); //save
       
  3467                 setGeometry(fullscreen);
       
  3468                 if(!qApp->desktop()->screenNumber(this))
       
  3469                     qt_mac_set_fullscreen_mode(true);
       
  3470             } else {
       
  3471                 needShow = isVisible();
       
  3472                 setParent(parentWidget(), d->topData()->savedFlags);
       
  3473                 setGeometry(d->topData()->normalGeometry);
       
  3474                 if(!qApp->desktop()->screenNumber(this))
       
  3475                     qt_mac_set_fullscreen_mode(false);
       
  3476                 d->topData()->normalGeometry.setRect(0, 0, -1, -1);
       
  3477             }
       
  3478         }
       
  3479 
       
  3480         d->createWinId();
       
  3481 
       
  3482         OSWindowRef window = qt_mac_window_for(this);
       
  3483         if((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
       
  3484             if (newstate & Qt::WindowMinimized) {
       
  3485 #ifndef QT_MAC_USE_COCOA
       
  3486                 CollapseWindow(window, true);
       
  3487 #else
       
  3488                 [window miniaturize:window];
       
  3489 #endif
       
  3490             } else {
       
  3491 #ifndef QT_MAC_USE_COCOA
       
  3492                 CollapseWindow(window, false);
       
  3493 #else
       
  3494                 [window deminiaturize:window];
       
  3495 #endif
       
  3496             }
       
  3497             needSendStateChange = oldstate == windowState(); // Collapse didn't change our flags.
       
  3498         }
       
  3499 
       
  3500         if((newstate & Qt::WindowMaximized) && !((newstate & Qt::WindowFullScreen))) {
       
  3501             if(QTLWExtra *tlextra = d->topData()) {
       
  3502                 if(tlextra->normalGeometry.width() < 0) {
       
  3503                     if(!testAttribute(Qt::WA_Resized))
       
  3504                         adjustSize();
       
  3505                     tlextra->normalGeometry = geometry();
       
  3506                 }
       
  3507             }
       
  3508         } else if(!(newstate & Qt::WindowFullScreen)) {
       
  3509 //            d->topData()->normalGeometry = QRect(0, 0, -1, -1);
       
  3510         }
       
  3511 
       
  3512 #ifdef DEBUG_WINDOW_STATE
       
  3513 #define WSTATE(x) qDebug("%s -- %s --> %s", #x, (oldstate & x) ? "true" : "false", (newstate & x) ? "true" : "false")
       
  3514         WSTATE(Qt::WindowMinimized);
       
  3515         WSTATE(Qt::WindowMaximized);
       
  3516         WSTATE(Qt::WindowFullScreen);
       
  3517 #undef WSTATE
       
  3518 #endif
       
  3519         if(!(newstate & (Qt::WindowMinimized|Qt::WindowFullScreen)) &&
       
  3520            ((oldstate & Qt::WindowFullScreen) || (oldstate & Qt::WindowMinimized) ||
       
  3521             (oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized))) {
       
  3522             if(newstate & Qt::WindowMaximized) {
       
  3523                 data->fstrut_dirty = true;
       
  3524 #ifndef QT_MAC_USE_COCOA
       
  3525                 HIToolbarRef toolbarRef;
       
  3526                 if (GetWindowToolbar(window, &toolbarRef) == noErr && toolbarRef
       
  3527                         && !isVisible() && !IsWindowToolbarVisible(window)) {
       
  3528                     // HIToolbar, needs to be shown so that it's in the structure window
       
  3529                     // Typically this is part of a main window and will get shown
       
  3530                     // during the show, but it's will make the maximize all wrong.
       
  3531                     ShowHideWindowToolbar(window, true, false);
       
  3532                     d->updateFrameStrut();  // In theory the dirty would work, but it's optimized out if the window is not visible :(
       
  3533                 }
       
  3534                 Rect bounds;
       
  3535                 QDesktopWidget *dsk = QApplication::desktop();
       
  3536                 QRect avail = dsk->availableGeometry(dsk->screenNumber(this));
       
  3537                 SetRect(&bounds, avail.x(), avail.y(), avail.x() + avail.width(), avail.y() + avail.height());
       
  3538                 if(QWExtra *extra = d->extraData()) {
       
  3539                     if(bounds.right - bounds.left > extra->maxw)
       
  3540                         bounds.right = bounds.left + extra->maxw;
       
  3541                     if(bounds.bottom - bounds.top > extra->maxh)
       
  3542                         bounds.bottom = bounds.top + extra->maxh;
       
  3543                 }
       
  3544                 if(d->topData()) {
       
  3545                     QRect fs = d->frameStrut();
       
  3546                     bounds.left += fs.left();
       
  3547                     if(bounds.right < avail.x()+avail.width())
       
  3548                         bounds.right = qMin<short>((uint)avail.x()+avail.width(), bounds.right+fs.left());
       
  3549                     if(bounds.bottom < avail.y()+avail.height())
       
  3550                         bounds.bottom = qMin<short>((uint)avail.y()+avail.height(), bounds.bottom+fs.top());
       
  3551                     bounds.top += fs.top();
       
  3552                     bounds.right -= fs.right();
       
  3553                     bounds.bottom -= fs.bottom();
       
  3554                 }
       
  3555                 QRect orect(geometry().x(), geometry().y(), width(), height()),
       
  3556                       nrect(bounds.left, bounds.top, bounds.right - bounds.left,
       
  3557                             bounds.bottom - bounds.top);
       
  3558                 if(orect != nrect) { // the new rect differ from the old
       
  3559                     Point idealSize  = { nrect.height(), nrect.width() };
       
  3560                     ZoomWindowIdeal(window, inZoomOut, &idealSize);
       
  3561                 }
       
  3562 #else
       
  3563                 NSToolbar *toolbarRef = [window toolbar];
       
  3564                 if (toolbarRef && !isVisible() && ![toolbarRef isVisible]) {
       
  3565                     // HIToolbar, needs to be shown so that it's in the structure window
       
  3566                     // Typically this is part of a main window and will get shown
       
  3567                     // during the show, but it's will make the maximize all wrong.
       
  3568                     // ### Not sure this is right for NSToolbar...
       
  3569                     [toolbarRef setVisible:true];
       
  3570 //                    ShowHideWindowToolbar(window, true, false);
       
  3571                     d->updateFrameStrut();  // In theory the dirty would work, but it's optimized out if the window is not visible :(
       
  3572                 }
       
  3573                 // Everything should be handled by Cocoa.
       
  3574                 [window zoom:window];
       
  3575 #endif
       
  3576                 needSendStateChange = oldstate == windowState(); // Zoom didn't change flags.
       
  3577             } else if(oldstate & Qt::WindowMaximized) {
       
  3578 #ifndef QT_MAC_USE_COCOA
       
  3579                 Point idealSize;
       
  3580                 ZoomWindowIdeal(window, inZoomIn, &idealSize);
       
  3581 #else
       
  3582                 [window zoom:window];
       
  3583 #endif
       
  3584                 if(QTLWExtra *tlextra = d->topData()) {
       
  3585                     setGeometry(tlextra->normalGeometry);
       
  3586                     tlextra->normalGeometry.setRect(0, 0, -1, -1);
       
  3587                 }
       
  3588             }
       
  3589         }
       
  3590     }
       
  3591 
       
  3592     data->window_state = newstate;
       
  3593 
       
  3594     if(needShow)
       
  3595         show();
       
  3596 
       
  3597     if(newstate & Qt::WindowActive)
       
  3598         activateWindow();
       
  3599 
       
  3600     qt_event_request_window_change(this);
       
  3601     if (needSendStateChange) {
       
  3602         QWindowStateChangeEvent e(oldstate);
       
  3603         QApplication::sendEvent(this, &e);
       
  3604     }
       
  3605 }
       
  3606 
       
  3607 void QWidgetPrivate::setFocus_sys()
       
  3608 {
       
  3609     Q_Q(QWidget);
       
  3610     if (q->testAttribute(Qt::WA_WState_Created)) {
       
  3611 #ifdef QT_MAC_USE_COCOA
       
  3612         QMacCocoaAutoReleasePool pool;
       
  3613         NSView *view = qt_mac_nativeview_for(q);
       
  3614         [[view window] makeFirstResponder:view];
       
  3615 #else
       
  3616         SetKeyboardFocus(qt_mac_window_for(q), qt_mac_nativeview_for(q), 1);
       
  3617 #endif
       
  3618     }
       
  3619 }
       
  3620 
       
  3621 void QWidgetPrivate::raise_sys()
       
  3622 {
       
  3623     Q_Q(QWidget);
       
  3624     if((q->windowType() == Qt::Desktop))
       
  3625         return;
       
  3626 
       
  3627 #if QT_MAC_USE_COCOA
       
  3628     QMacCocoaAutoReleasePool pool;
       
  3629     if (isRealWindow()) {
       
  3630         // Calling orderFront shows the window on Cocoa too.
       
  3631         if (!q->testAttribute(Qt::WA_DontShowOnScreen) && q->isVisible()) {
       
  3632             [qt_mac_window_for(q) orderFront:qt_mac_window_for(q)];
       
  3633         }
       
  3634         if (qt_mac_raise_process) { //we get to be the active process now
       
  3635             ProcessSerialNumber psn;
       
  3636             GetCurrentProcess(&psn);
       
  3637             SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
       
  3638         }
       
  3639     } else {
       
  3640         // Cocoa doesn't really have an idea of Z-ordering, but you can
       
  3641         // fake it by changing the order of it. But beware, removing an
       
  3642         // NSView will also remove it as the first responder. So we re-set
       
  3643         // the first responder just in case:
       
  3644         NSView *view = qt_mac_nativeview_for(q);
       
  3645         NSView *parentView = [view superview];
       
  3646         NSResponder *firstResponder = [[view window] firstResponder];
       
  3647         [view removeFromSuperview];
       
  3648         [parentView addSubview:view];
       
  3649         [[view window] makeFirstResponder:firstResponder];
       
  3650     }
       
  3651 #else
       
  3652     if(q->isWindow()) {
       
  3653         //raise this window
       
  3654         BringToFront(qt_mac_window_for(q));
       
  3655         if(qt_mac_raise_process) { //we get to be the active process now
       
  3656             ProcessSerialNumber psn;
       
  3657             GetCurrentProcess(&psn);
       
  3658             SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
       
  3659         }
       
  3660     } else if(q->parentWidget()) {
       
  3661         HIViewSetZOrder(qt_mac_nativeview_for(q), kHIViewZOrderAbove, 0);
       
  3662         qt_event_request_window_change(q);
       
  3663     }
       
  3664 #endif
       
  3665 }
       
  3666 
       
  3667 void QWidgetPrivate::lower_sys()
       
  3668 {
       
  3669     Q_Q(QWidget);
       
  3670     if((q->windowType() == Qt::Desktop))
       
  3671         return;
       
  3672 #ifdef QT_MAC_USE_COCOA
       
  3673     QMacCocoaAutoReleasePool pool;
       
  3674     if (isRealWindow()) {
       
  3675         OSWindowRef window = qt_mac_window_for(q);
       
  3676         [window orderBack:window];
       
  3677     } else {
       
  3678         // Cocoa doesn't really have an idea of Z-ordering, but you can
       
  3679         // fake it by changing the order of it. In this case
       
  3680         // we put the item at the beginning of the list, but that means
       
  3681         // we must re-insert everything since we cannot modify the list directly.
       
  3682         NSView *myview = qt_mac_nativeview_for(q);
       
  3683         NSView *parentView = [myview superview];
       
  3684         NSArray *tmpViews = [parentView subviews];
       
  3685         NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]];
       
  3686         [subviews addObjectsFromArray:tmpViews];
       
  3687         NSResponder *firstResponder = [[myview window] firstResponder];
       
  3688         // Implicit assumption that myViewIndex is included in subviews, that's why I'm not checking
       
  3689         // myViewIndex.
       
  3690         NSUInteger index = 0;
       
  3691         NSUInteger myViewIndex = 0;
       
  3692         bool foundMyView = false;
       
  3693         for (NSView *subview in subviews) {
       
  3694             [subview removeFromSuperview];
       
  3695             if (subview == myview) {
       
  3696                 foundMyView = true;
       
  3697                 myViewIndex = index;
       
  3698             }
       
  3699             ++index;
       
  3700         }
       
  3701         [parentView addSubview:myview];
       
  3702         if (foundMyView)
       
  3703             [subviews removeObjectAtIndex:myViewIndex];
       
  3704         for (NSView *subview in subviews)
       
  3705             [parentView addSubview:subview];
       
  3706         [subviews release];
       
  3707         [[myview window] makeFirstResponder:firstResponder];
       
  3708     }
       
  3709 #else
       
  3710     if(q->isWindow()) {
       
  3711         SendBehind(qt_mac_window_for(q), 0);
       
  3712     } else if(q->parentWidget()) {
       
  3713         invalidateBuffer(q->rect());
       
  3714         HIViewSetZOrder(qt_mac_nativeview_for(q), kHIViewZOrderBelow, 0);
       
  3715         qt_event_request_window_change(q);
       
  3716     }
       
  3717 #endif
       
  3718 }
       
  3719 
       
  3720 void QWidgetPrivate::stackUnder_sys(QWidget *w)
       
  3721 {
       
  3722     // stackUnder
       
  3723     Q_Q(QWidget);
       
  3724     if(!w || q->isWindow() || (q->windowType() == Qt::Desktop))
       
  3725         return;
       
  3726 #ifdef QT_MAC_USE_COCOA
       
  3727     // Do the same trick as lower_sys() and put this widget before the widget passed in.
       
  3728     QMacCocoaAutoReleasePool pool;
       
  3729     NSView *myview = qt_mac_nativeview_for(q);
       
  3730     NSView *wView = qt_mac_nativeview_for(w);
       
  3731     NSView *parentView = [myview superview];
       
  3732     NSArray *tmpViews = [parentView subviews];
       
  3733     NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]];
       
  3734     [subviews addObjectsFromArray:tmpViews];
       
  3735     // Implicit assumption that myViewIndex and wViewIndex is included in subviews,
       
  3736     // that's why I'm not checking myViewIndex.
       
  3737     NSUInteger index = 0;
       
  3738     NSUInteger myViewIndex = 0;
       
  3739     NSUInteger wViewIndex = 0;
       
  3740     for (NSView *subview in subviews) {
       
  3741         [subview removeFromSuperview];
       
  3742         if (subview == myview)
       
  3743             myViewIndex = index;
       
  3744         else if (subview == wView)
       
  3745             wViewIndex = index;
       
  3746         ++index;
       
  3747     }
       
  3748 
       
  3749     index = 0;
       
  3750     for (NSView *subview in subviews) {
       
  3751         if (index == myViewIndex)
       
  3752             continue;
       
  3753         if (index == wViewIndex)
       
  3754             [parentView addSubview:myview];
       
  3755         [parentView addSubview:subview];
       
  3756         ++index;
       
  3757     }
       
  3758     [subviews release];
       
  3759 #else
       
  3760     QWidget *p = q->parentWidget();
       
  3761     if(!p || p != w->parentWidget())
       
  3762         return;
       
  3763     invalidateBuffer(q->rect());
       
  3764     HIViewSetZOrder(qt_mac_nativeview_for(q), kHIViewZOrderBelow, qt_mac_nativeview_for(w));
       
  3765     qt_event_request_window_change(q);
       
  3766 #endif
       
  3767 }
       
  3768 
       
  3769 /*
       
  3770     Modifies the bounds for a widgets backing HIView during moves and resizes. Also updates the
       
  3771     widget, either by scrolling its contents or repainting, depending on the WA_StaticContents
       
  3772     and QWidgetPrivate::isOpaque flags.
       
  3773 */
       
  3774 static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newRect)
       
  3775 {
       
  3776 #ifndef QT_MAC_USE_COCOA
       
  3777     HIRect bounds = CGRectMake(newRect.x(), newRect.y(),
       
  3778                                newRect.width(), newRect.height());
       
  3779 
       
  3780     const HIViewRef view = qt_mac_nativeview_for(q);
       
  3781     const bool isMove = (oldRect.topLeft() != newRect.topLeft());
       
  3782     const bool isResize = (oldRect.size() != newRect.size());
       
  3783 
       
  3784 //    qDebug() << oldRect << newRect << isMove << isResize << q->testAttribute(Qt::WA_OpaquePaintEvent) << q->testAttribute(Qt::WA_StaticContents);
       
  3785     QWidgetPrivate *qd = qt_widget_private(q);
       
  3786 
       
  3787     // Perform a normal (complete repaint) update in some cases:
       
  3788     if (
       
  3789         // move-by-scroll requires QWidgetPrivate::isOpaque set
       
  3790         (isMove && q->testAttribute(Qt::WA_OpaquePaintEvent) == false) ||
       
  3791 
       
  3792         // limited update on resize requires WA_StaticContents.
       
  3793         (isResize && q->testAttribute(Qt::WA_StaticContents) == false) ||
       
  3794 
       
  3795         // one of the rects are invalid
       
  3796         (oldRect.isValid() == false || newRect.isValid() == false)  ||
       
  3797 
       
  3798         // the position update is a part of a drag-and-drop operation
       
  3799         QDragManager::self()->object || 
       
  3800         
       
  3801         // we are on Panther (no HIViewSetNeedsDisplayInRect) 
       
  3802         QSysInfo::MacintoshVersion < QSysInfo::MV_10_4 
       
  3803     ){
       
  3804         HIViewSetFrame(view, &bounds);
       
  3805         return;
       
  3806     }
       
  3807 
       
  3808     const int dx = newRect.x() - oldRect.x();
       
  3809     const int dy = newRect.y() - oldRect.y();
       
  3810 
       
  3811     if (isMove) {
       
  3812         // HIViewScrollRect silently fails if we try to scroll anything under the grow box.
       
  3813         // Check if there's one present within the widget rect, and if there is fall back
       
  3814         // to repainting the entire widget.
       
  3815         QWidget const * const parentWidget = q->parentWidget();
       
  3816         const HIViewRef parentView = qt_mac_nativeview_for(parentWidget);
       
  3817         HIViewRef nativeSizeGrip = 0;
       
  3818         if (q->testAttribute(Qt::WA_WState_Created))
       
  3819             HIViewFindByID(HIViewGetRoot(HIViewGetWindow(HIViewRef(q->winId()))), kHIViewWindowGrowBoxID, &nativeSizeGrip);
       
  3820         if (nativeSizeGrip) {
       
  3821             QWidget * const window = q->window();
       
  3822 
       
  3823             const int sizeGripSize = 20;
       
  3824             const QRect oldWidgetRect = QRect(q->mapTo(window, QPoint(0, 0)), QSize(oldRect.width(), oldRect.height()));
       
  3825             const QRect newWidgetRect = QRect(q->mapTo(window, QPoint(0, 0)), QSize(newRect.width(), newRect.height()));
       
  3826             const QRect sizeGripRect = QRect(window->rect().bottomRight() - QPoint(sizeGripSize, sizeGripSize),
       
  3827                                              window->rect().bottomRight());
       
  3828 
       
  3829             if (sizeGripRect.intersects(oldWidgetRect) || sizeGripRect.intersects(newWidgetRect)) {
       
  3830                 HIViewSetFrame(view, &bounds);
       
  3831                 return;
       
  3832             }
       
  3833         }
       
  3834 
       
  3835         // Don't scroll anything outside the parent widget rect.
       
  3836         const QRect scrollRect = (oldRect | newRect) & parentWidget->rect();
       
  3837         const HIRect scrollBounds =
       
  3838             CGRectMake(scrollRect.x(), scrollRect.y(), scrollRect.width(), scrollRect.height());
       
  3839 
       
  3840         // We cannot scroll when the widget has a mask as that would
       
  3841         // scroll the masked out areas too
       
  3842         if (qd->extra && qd->extra->hasMask) {
       
  3843             HIViewMoveBy(view, dx, dy);
       
  3844             return;
       
  3845         }
       
  3846 
       
  3847         OSStatus err = HIViewScrollRect(parentView, &scrollBounds, dx, dy);
       
  3848         if (err != noErr) {
       
  3849             HIViewSetNeedsDisplay(view, true);
       
  3850             qWarning("QWidget: Internal error (%s:%d)", __FILE__, __LINE__);
       
  3851         }
       
  3852     }
       
  3853     // Set the view bounds with drawing disabled to prevent repaints.
       
  3854     HIViewSetDrawingEnabled(view, false);
       
  3855     HIViewSetFrame(view, &bounds);
       
  3856     HIViewSetDrawingEnabled(view, true);
       
  3857 
       
  3858     // Update any newly exposed areas due to resizing.
       
  3859     const int startx = oldRect.width();
       
  3860     const int stopx = newRect.width();
       
  3861     const int starty = oldRect.height();
       
  3862     const int stopy = newRect.height();
       
  3863 
       
  3864     const HIRect verticalSlice = CGRectMake(startx, 0, stopx , stopy);
       
  3865     HIViewSetNeedsDisplayInRect(view, &verticalSlice, true);
       
  3866     const HIRect horizontalSlice = CGRectMake(0, starty, startx, stopy);
       
  3867     HIViewSetNeedsDisplayInRect(view, &horizontalSlice, true);
       
  3868 #else
       
  3869     Q_UNUSED(oldRect);
       
  3870     NSRect bounds = NSMakeRect(newRect.x(), newRect.y(),
       
  3871                                newRect.width(), newRect.height());
       
  3872     [qt_mac_nativeview_for(q) setFrame:bounds];
       
  3873 #endif
       
  3874 }
       
  3875 
       
  3876 /*
       
  3877   Helper function for non-toplevel widgets. Helps to map Qt's 32bit
       
  3878   coordinate system to OS X's 16bit coordinate system.
       
  3879 
       
  3880   Sets the geometry of the widget to data.crect, but clipped to sizes
       
  3881   that OS X can handle. Unmaps widgets that are completely outside the
       
  3882   valid range.
       
  3883 
       
  3884   Maintains data.wrect, which is the geometry of the OS X widget,
       
  3885   measured in this widget's coordinate system.
       
  3886 
       
  3887   if the parent is not clipped, parentWRect is empty, otherwise
       
  3888   parentWRect is the geometry of the parent's OS X rect, measured in
       
  3889   parent's coord sys
       
  3890 */
       
  3891 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
       
  3892 {
       
  3893     Q_Q(QWidget);
       
  3894     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  3895     Q_UNUSED(oldRect);
       
  3896     /*
       
  3897       There are up to four different coordinate systems here:
       
  3898       Qt coordinate system for this widget.
       
  3899       X coordinate system for this widget (relative to wrect).
       
  3900       Qt coordinate system for parent
       
  3901       X coordinate system for parent (relative to parent's wrect).
       
  3902     */
       
  3903     QRect wrect;
       
  3904     //xrect is the X geometry of my X widget. (starts out in  parent's Qt coord sys, and ends up in parent's X coord sys)
       
  3905     QRect xrect = data.crect;
       
  3906 
       
  3907     QRect parentWRect;
       
  3908     if (q->isWindow() && topData()->embedded) {
       
  3909 #ifndef QT_MAC_USE_COCOA
       
  3910         HIViewRef parentView = HIViewGetSuperview(qt_mac_nativeview_for(q));
       
  3911 #else
       
  3912         NSView *parentView = [qt_mac_nativeview_for(q) superview];
       
  3913 #endif
       
  3914         if (parentView) {
       
  3915 #ifndef QT_MAC_USE_COCOA
       
  3916             HIRect tmpRect;
       
  3917             HIViewGetFrame(parentView, &tmpRect);
       
  3918 #else
       
  3919             NSRect tmpRect = [parentView frame];
       
  3920 #endif
       
  3921             parentWRect = QRect(tmpRect.origin.x, tmpRect.origin.y,
       
  3922                                 tmpRect.size.width, tmpRect.size.height);
       
  3923         } else {
       
  3924             const QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
       
  3925             parentWRect = wrectRange;
       
  3926         }
       
  3927     } else {
       
  3928         parentWRect = q->parentWidget()->data->wrect;
       
  3929     }
       
  3930 
       
  3931     if (parentWRect.isValid()) {
       
  3932         // parent is clipped, and we have to clip to the same limit as parent
       
  3933         if (!parentWRect.contains(xrect)) {
       
  3934             xrect &= parentWRect;
       
  3935             wrect = xrect;
       
  3936             //translate from parent's to my Qt coord sys
       
  3937             wrect.translate(-data.crect.topLeft());
       
  3938         }
       
  3939         //translate from parent's Qt coords to parent's X coords
       
  3940         xrect.translate(-parentWRect.topLeft());
       
  3941 
       
  3942     } else {
       
  3943         // parent is not clipped, we may or may not have to clip
       
  3944 
       
  3945         if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
       
  3946             // This is where the main optimization is: we are already
       
  3947             // clipped, and if our clip is still valid, we can just
       
  3948             // move our window, and do not need to move or clip
       
  3949             // children
       
  3950 
       
  3951             QRect vrect = xrect & q->parentWidget()->rect();
       
  3952             vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords
       
  3953             if (data.wrect.contains(vrect)) {
       
  3954                 xrect = data.wrect;
       
  3955                 xrect.translate(data.crect.topLeft());
       
  3956 #ifndef QT_MAC_USE_COCOA
       
  3957                 HIRect bounds = CGRectMake(xrect.x(), xrect.y(),
       
  3958                                            xrect.width(), xrect.height());
       
  3959                 HIViewSetFrame(qt_mac_nativeview_for(q), &bounds);
       
  3960 #else
       
  3961                 NSRect bounds = NSMakeRect(xrect.x(), xrect.y(),
       
  3962                                            xrect.width(), xrect.height());
       
  3963                 [qt_mac_nativeview_for(q) setFrame:bounds];
       
  3964 #endif
       
  3965                 if (q->testAttribute(Qt::WA_OutsideWSRange)) {
       
  3966                     q->setAttribute(Qt::WA_OutsideWSRange, false);
       
  3967                     if (!dontShow) {
       
  3968                         q->setAttribute(Qt::WA_Mapped);
       
  3969 #ifndef QT_MAC_USE_COCOA
       
  3970                         HIViewSetVisible(qt_mac_nativeview_for(q), true);
       
  3971 #else
       
  3972                         [qt_mac_nativeview_for(q) setHidden:NO];
       
  3973 #endif
       
  3974                     }
       
  3975                 }
       
  3976                 return;
       
  3977             }
       
  3978         }
       
  3979 
       
  3980         const QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
       
  3981         if (!validRange.contains(xrect)) {
       
  3982             // we are too big, and must clip
       
  3983             QPoint screenOffset(0, 0); // offset of the part being on screen
       
  3984             const QWidget *parentWidget = q->parentWidget();
       
  3985             while (parentWidget && !parentWidget->isWindow()) {
       
  3986                 screenOffset -= parentWidget->data->crect.topLeft();
       
  3987                 parentWidget = parentWidget->parentWidget();
       
  3988             }
       
  3989             QRect cropRect(screenOffset.x() - WRECT_MAX,
       
  3990                            screenOffset.y() - WRECT_MAX,
       
  3991                            2*WRECT_MAX,
       
  3992                            2*WRECT_MAX);
       
  3993 
       
  3994             xrect &=cropRect;
       
  3995             wrect = xrect;
       
  3996             wrect.translate(-data.crect.topLeft()); // translate wrect in my Qt coordinates
       
  3997         }
       
  3998     }
       
  3999 
       
  4000     // unmap if we are outside the valid window system coord system
       
  4001     bool outsideRange = !xrect.isValid();
       
  4002     bool mapWindow = false;
       
  4003     if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
       
  4004         q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
       
  4005         if (outsideRange) {
       
  4006 #ifndef QT_MAC_USE_COCOA
       
  4007             HIViewSetVisible(qt_mac_nativeview_for(q), false);
       
  4008 #else
       
  4009             [qt_mac_nativeview_for(q) setHidden:YES];
       
  4010 #endif
       
  4011             q->setAttribute(Qt::WA_Mapped, false);
       
  4012         } else if (!q->isHidden()) {
       
  4013             mapWindow = true;
       
  4014         }
       
  4015     }
       
  4016 
       
  4017     if (outsideRange)
       
  4018         return;
       
  4019 
       
  4020     bool jump = (data.wrect != wrect);
       
  4021     data.wrect = wrect;
       
  4022 
       
  4023 
       
  4024     // and now recursively for all children...
       
  4025     // ### can be optimized
       
  4026     for (int i = 0; i < children.size(); ++i) {
       
  4027         QObject *object = children.at(i);
       
  4028         if (object->isWidgetType()) {
       
  4029             QWidget *w = static_cast<QWidget *>(object);
       
  4030             if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
       
  4031                 w->d_func()->setWSGeometry();
       
  4032         }
       
  4033     }
       
  4034 
       
  4035     qt_mac_update_widget_posisiton(q, oldRect, xrect);
       
  4036 
       
  4037     if  (jump)
       
  4038         q->update();
       
  4039 
       
  4040     if (mapWindow && !dontShow) {
       
  4041         q->setAttribute(Qt::WA_Mapped);
       
  4042 #ifndef QT_MAC_USE_COCOA
       
  4043         HIViewSetVisible(qt_mac_nativeview_for(q), true);
       
  4044 #else
       
  4045         [qt_mac_nativeview_for(q) setHidden:NO];
       
  4046 #endif
       
  4047     }
       
  4048 }
       
  4049 
       
  4050 void QWidgetPrivate::adjustWithinMaxAndMinSize(int &w, int &h)
       
  4051 {
       
  4052     if (QWExtra *extra = extraData()) {
       
  4053         w = qMin(w, extra->maxw);
       
  4054         h = qMin(h, extra->maxh);
       
  4055         w = qMax(w, extra->minw);
       
  4056         h = qMax(h, extra->minh);
       
  4057 
       
  4058         // Deal with size increment
       
  4059         if (QTLWExtra *top = topData()) {
       
  4060             if(top->incw) {
       
  4061                 w = w/top->incw;
       
  4062                 w *= top->incw;
       
  4063             }
       
  4064             if(top->inch) {
       
  4065                 h = h/top->inch;
       
  4066                 h *= top->inch;
       
  4067             }
       
  4068         }
       
  4069     }
       
  4070 
       
  4071     if (isRealWindow()) {
       
  4072         w = qMax(0, w);
       
  4073         h = qMax(0, h);
       
  4074     }
       
  4075 }
       
  4076 
       
  4077 void QWidgetPrivate::applyMaxAndMinSizeOnWindow()
       
  4078 {
       
  4079     Q_Q(QWidget);
       
  4080     const float max_f(20000);
       
  4081 #ifndef QT_MAC_USE_COCOA
       
  4082 #define SF(x) ((x > max_f) ? max_f : x)
       
  4083     HISize max = CGSizeMake(SF(extra->maxw), SF(extra->maxh));
       
  4084     HISize min = CGSizeMake(SF(extra->minw), SF(extra->minh));
       
  4085 #undef SF
       
  4086     SetWindowResizeLimits(qt_mac_window_for(q), &min, &max);
       
  4087 #else
       
  4088 #define SF(x) ((x > max_f) ? max_f : x)
       
  4089     NSSize max = NSMakeSize(SF(extra->maxw), SF(extra->maxh));
       
  4090     NSSize min = NSMakeSize(SF(extra->minw), SF(extra->minh));
       
  4091 #undef SF
       
  4092     [qt_mac_window_for(q) setContentMinSize:min];
       
  4093     [qt_mac_window_for(q) setContentMaxSize:max];
       
  4094 #endif
       
  4095 }
       
  4096 
       
  4097 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
       
  4098 {
       
  4099     Q_Q(QWidget);
       
  4100     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  4101 
       
  4102     if(q->windowType() == Qt::Desktop)
       
  4103         return;
       
  4104 
       
  4105     QMacCocoaAutoReleasePool pool;
       
  4106     bool realWindow = isRealWindow();
       
  4107 
       
  4108     if (realWindow && !q->testAttribute(Qt::WA_DontShowOnScreen)){
       
  4109         adjustWithinMaxAndMinSize(w, h);
       
  4110 #ifndef QT_MAC_USE_COCOA
       
  4111         if (w != 0 && h != 0) {
       
  4112             topData()->isSetGeometry = 1;
       
  4113             topData()->isMove = isMove;
       
  4114             Rect r; SetRect(&r, x, y, x + w, y + h);
       
  4115             SetWindowBounds(qt_mac_window_for(q), kWindowContentRgn, &r);
       
  4116             topData()->isSetGeometry = 0;
       
  4117         } else {
       
  4118             setGeometry_sys_helper(x, y, w, h, isMove);
       
  4119         }
       
  4120 #else
       
  4121         QSize  olds = q->size();
       
  4122         const bool isResize = (olds != QSize(w, h));
       
  4123         NSWindow *window = qt_mac_window_for(q);
       
  4124         const QRect &fStrut = frameStrut();
       
  4125         const QRect frameRect(QPoint(x - fStrut.left(), y - fStrut.top()),
       
  4126                               QSize(fStrut.left() + fStrut.right() + w,
       
  4127                                     fStrut.top() + fStrut.bottom() + h));
       
  4128         NSRect cocoaFrameRect = NSMakeRect(frameRect.x(), flipYCoordinate(frameRect.bottom() + 1),
       
  4129                                            frameRect.width(), frameRect.height());
       
  4130         // The setFrame call will trigger a 'windowDidResize' notification for the corresponding
       
  4131         // NSWindow. The pending flag is set, so that the resize event can be send as non-spontaneous.
       
  4132         if (isResize)
       
  4133             q->setAttribute(Qt::WA_PendingResizeEvent);
       
  4134         QPoint currTopLeft = data.crect.topLeft();
       
  4135         if (currTopLeft.x() == x && currTopLeft.y() == y
       
  4136                 && cocoaFrameRect.size.width != 0
       
  4137                 && cocoaFrameRect.size.height != 0) {
       
  4138             [window setFrame:cocoaFrameRect display:NO];
       
  4139         } else {
       
  4140             // The window is moved and resized (or resized to zero).
       
  4141             // Since Cocoa usually only sends us a resize callback after
       
  4142             // setting a window frame, we issue an explicit move as
       
  4143             // well. To stop Cocoa from optimize away the move (since the move
       
  4144             // would have the same origin as the setFrame call) we shift the
       
  4145             // window back and forth inbetween.
       
  4146             cocoaFrameRect.origin.y += 1;
       
  4147             [window setFrame:cocoaFrameRect display:NO];
       
  4148             cocoaFrameRect.origin.y -= 1;
       
  4149             [window setFrameOrigin:cocoaFrameRect.origin];
       
  4150         }
       
  4151 #endif
       
  4152     } else {
       
  4153         setGeometry_sys_helper(x, y, w, h, isMove);
       
  4154     }
       
  4155 }
       
  4156 
       
  4157 void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isMove)
       
  4158 {
       
  4159     Q_Q(QWidget);
       
  4160     bool realWindow = isRealWindow();
       
  4161 
       
  4162     QPoint oldp = q->pos();
       
  4163     QSize  olds = q->size();
       
  4164     const bool isResize = (olds != QSize(w, h));
       
  4165 
       
  4166     if (!realWindow && !isResize && QPoint(x, y) == oldp)
       
  4167         return;
       
  4168 
       
  4169     if (isResize)
       
  4170         data.window_state = data.window_state & ~Qt::WindowMaximized;
       
  4171 
       
  4172     const bool visible = q->isVisible();
       
  4173     data.crect = QRect(x, y, w, h);
       
  4174 
       
  4175     if (realWindow) {
       
  4176         adjustWithinMaxAndMinSize(w, h);
       
  4177         qt_mac_update_sizer(q);
       
  4178 
       
  4179 #ifndef QT_MAC_USE_COCOA
       
  4180         if (q->windowFlags() & Qt::WindowMaximizeButtonHint) {
       
  4181             OSWindowRef window = qt_mac_window_for(q);
       
  4182             if (extra->maxw && extra->maxh && extra->maxw == extra->minw
       
  4183                     && extra->maxh == extra->minh) {
       
  4184                 ChangeWindowAttributes(window, kWindowNoAttributes, kWindowFullZoomAttribute);
       
  4185             } else {
       
  4186                 ChangeWindowAttributes(window, kWindowFullZoomAttribute, kWindowNoAttributes);
       
  4187             }
       
  4188         }
       
  4189         HIRect bounds = CGRectMake(0, 0, w, h);
       
  4190         HIViewSetFrame(qt_mac_nativeview_for(q), &bounds);
       
  4191 #else
       
  4192         [qt_mac_nativeview_for(q) setFrame:NSMakeRect(0, 0, w, h)];
       
  4193 #endif
       
  4194     } else {
       
  4195         const QRect oldRect(oldp, olds);
       
  4196         if (!isResize && QApplicationPrivate::graphicsSystem())
       
  4197             moveRect(oldRect, x - oldp.x(), y - oldp.y());
       
  4198         setWSGeometry(false, oldRect);
       
  4199         if (isResize && QApplicationPrivate::graphicsSystem()) {
       
  4200             invalidateBuffer(q->rect());
       
  4201             if (extra && !graphicsEffect && !extra->mask.isEmpty()) {
       
  4202                 QRegion oldRegion(extra->mask.translated(oldp));
       
  4203                 oldRegion &= oldRect;
       
  4204                 q->parentWidget()->d_func()->invalidateBuffer(oldRegion);
       
  4205             } else {
       
  4206                 q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(oldRect));
       
  4207             }
       
  4208         }
       
  4209     }
       
  4210 
       
  4211     if(isMove || isResize) {
       
  4212         if(!visible) {
       
  4213             if(isMove && q->pos() != oldp)
       
  4214                 q->setAttribute(Qt::WA_PendingMoveEvent, true);
       
  4215             if(isResize)
       
  4216                 q->setAttribute(Qt::WA_PendingResizeEvent, true);
       
  4217         } else {
       
  4218             if(isResize) { //send the resize event..
       
  4219                 QResizeEvent e(q->size(), olds);
       
  4220                 QApplication::sendEvent(q, &e);
       
  4221             }
       
  4222             if(isMove && q->pos() != oldp) { //send the move event..
       
  4223                 QMoveEvent e(q->pos(), oldp);
       
  4224                 QApplication::sendEvent(q, &e);
       
  4225             }
       
  4226         }
       
  4227     }
       
  4228     qt_event_request_window_change(q);
       
  4229 }
       
  4230 
       
  4231 void QWidgetPrivate::setConstraints_sys()
       
  4232 {
       
  4233     updateMaximizeButton_sys();
       
  4234     applyMaxAndMinSizeOnWindow();
       
  4235 }
       
  4236 
       
  4237 void QWidgetPrivate::updateMaximizeButton_sys()
       
  4238 {
       
  4239     Q_Q(QWidget);
       
  4240     if (q->data->window_flags & Qt::CustomizeWindowHint)
       
  4241         return;
       
  4242 
       
  4243     OSWindowRef window = qt_mac_window_for(q);
       
  4244     QTLWExtra * tlwExtra = topData();
       
  4245 #ifdef QT_MAC_USE_COCOA
       
  4246     QMacCocoaAutoReleasePool pool;
       
  4247     NSButton *maximizeButton = [window standardWindowButton:NSWindowZoomButton];
       
  4248 #endif
       
  4249     if (extra->maxw && extra->maxh
       
  4250         && extra->maxw == extra->minw
       
  4251         && extra->maxh == extra->minh) {
       
  4252         // The window has a fixed size, so gray out the maximize button:
       
  4253         if (!tlwExtra->savedWindowAttributesFromMaximized) {
       
  4254 #ifndef QT_MAC_USE_COCOA
       
  4255             GetWindowAttributes(window,
       
  4256                                 (WindowAttributes*)&extra->topextra->savedWindowAttributesFromMaximized);
       
  4257 
       
  4258 #else
       
  4259             tlwExtra->savedWindowAttributesFromMaximized = (![maximizeButton isHidden] && [maximizeButton isEnabled]);
       
  4260 #endif
       
  4261         }
       
  4262 #ifndef QT_MAC_USE_COCOA
       
  4263         ChangeWindowAttributes(window, kWindowNoAttributes, kWindowFullZoomAttribute);
       
  4264 #else
       
  4265        [maximizeButton setEnabled:NO];
       
  4266 #endif
       
  4267 
       
  4268 
       
  4269     } else {
       
  4270         if (tlwExtra->savedWindowAttributesFromMaximized) {
       
  4271 #ifndef QT_MAC_USE_COCOA
       
  4272             ChangeWindowAttributes(window,
       
  4273                                    extra->topextra->savedWindowAttributesFromMaximized,
       
  4274                                    kWindowNoAttributes);
       
  4275 #else
       
  4276             [maximizeButton setEnabled:YES];
       
  4277 #endif
       
  4278             tlwExtra->savedWindowAttributesFromMaximized = 0;
       
  4279         }
       
  4280     }
       
  4281 
       
  4282 
       
  4283 }
       
  4284 
       
  4285 void QWidgetPrivate::scroll_sys(int dx, int dy)
       
  4286 {
       
  4287     if (QApplicationPrivate::graphicsSystem() && !paintOnScreen()) {
       
  4288         scrollChildren(dx, dy);
       
  4289         scrollRect(q_func()->rect(), dx, dy);
       
  4290     } else {
       
  4291         scroll_sys(dx, dy, QRect());
       
  4292     }
       
  4293 }
       
  4294 
       
  4295 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
       
  4296 {
       
  4297     Q_Q(QWidget);
       
  4298 
       
  4299     if (QApplicationPrivate::graphicsSystem() && !paintOnScreen()) {
       
  4300         scrollRect(r, dx, dy);
       
  4301         return;
       
  4302     }
       
  4303 
       
  4304     const bool valid_rect = r.isValid();
       
  4305     if (!q->updatesEnabled() &&  (valid_rect || q->children().isEmpty()))
       
  4306         return;
       
  4307 
       
  4308     qt_event_request_window_change(q);
       
  4309 
       
  4310 #ifdef QT_MAC_USE_COCOA
       
  4311     QMacCocoaAutoReleasePool pool;
       
  4312 #endif
       
  4313 
       
  4314     if(!valid_rect) {        // scroll children
       
  4315         QPoint pd(dx, dy);
       
  4316         QWidgetList moved;
       
  4317         QObjectList chldrn = q->children();
       
  4318         for(int i = 0; i < chldrn.size(); i++) {  //first move all children
       
  4319             QObject *obj = chldrn.at(i);
       
  4320             if(obj->isWidgetType()) {
       
  4321                 QWidget *w = (QWidget*)obj;
       
  4322                 if(!w->isWindow()) {
       
  4323                     w->data->crect = QRect(w->pos() + pd, w->size());
       
  4324                     if (w->testAttribute(Qt::WA_WState_Created)) {
       
  4325 #ifndef QT_MAC_USE_COCOA
       
  4326                         HIRect bounds = CGRectMake(w->data->crect.x(), w->data->crect.y(),
       
  4327                                                    w->data->crect.width(), w->data->crect.height());
       
  4328                         HIViewRef hiview = qt_mac_nativeview_for(w);
       
  4329                         const bool opaque = q->testAttribute(Qt::WA_OpaquePaintEvent);
       
  4330 
       
  4331                         if (opaque)
       
  4332                             HIViewSetDrawingEnabled(hiview,  false);
       
  4333                         HIViewSetFrame(hiview, &bounds);
       
  4334                         if (opaque)
       
  4335                             HIViewSetDrawingEnabled(hiview,  true);
       
  4336 #else
       
  4337                         [qt_mac_nativeview_for(w)
       
  4338                             setFrame:NSMakeRect(w->data->crect.x(), w->data->crect.y(),
       
  4339                                                 w->data->crect.width(), w->data->crect.height())];
       
  4340 #endif
       
  4341                     }
       
  4342                     moved.append(w);
       
  4343                 }
       
  4344             }
       
  4345         }
       
  4346         //now send move events (do not do this in the above loop, breaks QAquaFocusWidget)
       
  4347         for(int i = 0; i < moved.size(); i++) {
       
  4348             QWidget *w = moved.at(i);
       
  4349             QMoveEvent e(w->pos(), w->pos() - pd);
       
  4350             QApplication::sendEvent(w, &e);
       
  4351         }
       
  4352     }
       
  4353 
       
  4354     if (!q->testAttribute(Qt::WA_WState_Created) || !q->isVisible())
       
  4355         return;
       
  4356 
       
  4357     OSViewRef view = qt_mac_nativeview_for(q);
       
  4358 #ifndef QT_MAC_USE_COCOA
       
  4359     HIRect scrollrect = CGRectMake(r.x(), r.y(), r.width(), r.height());
       
  4360    OSStatus err = _HIViewScrollRectWithOptions(view, valid_rect ? &scrollrect : 0, dx, dy, kHIViewScrollRectAdjustInvalid);
       
  4361    if (err) {
       
  4362        // The only parameter that can go wrong, is the rect.
       
  4363        qWarning("QWidget::scroll: Your rectangle was too big for the widget, clipping rect");
       
  4364        scrollrect = CGRectMake(qMax(r.x(), 0), qMax(r.y(), 0),
       
  4365                                qMin(r.width(), q->width()), qMin(r.height(), q->height()));
       
  4366        _HIViewScrollRectWithOptions(view, valid_rect ? &scrollrect : 0, dx, dy, kHIViewScrollRectAdjustInvalid);
       
  4367    }
       
  4368 #else
       
  4369     NSRect scrollRect = valid_rect ? NSMakeRect(r.x(), r.y(), r.width(), r.height())
       
  4370                                    : NSMakeRect(0, 0, q->width(), q->height());
       
  4371 
       
  4372 
       
  4373     // calc the updateRect
       
  4374     NSRect deltaXRect = { {0, 0}, {0, 0} };
       
  4375     NSRect deltaYRect = { {0, 0}, {0, 0} };
       
  4376     if (dy != 0) {
       
  4377         deltaYRect.size.width = scrollRect.size.width;
       
  4378         if (dy > 0) {
       
  4379             deltaYRect.size.height = dy;
       
  4380         } else {
       
  4381             deltaYRect.size.height = -dy;
       
  4382             deltaYRect.origin.y = scrollRect.size.height + dy;
       
  4383         }
       
  4384     }
       
  4385     if (dx != 0) {
       
  4386         deltaXRect.size.height = scrollRect.size.height;
       
  4387         if (dx > 0) {
       
  4388             deltaXRect.size.width = dx;
       
  4389         } else {
       
  4390             deltaXRect.size.width = -dx;
       
  4391             deltaXRect.origin.x = scrollRect.size.width + dx;
       
  4392         }
       
  4393     }
       
  4394 
       
  4395     NSSize deltaSize = NSMakeSize(dx, dy);
       
  4396     [view translateRectsNeedingDisplayInRect:scrollRect by:deltaSize];
       
  4397     [view scrollRect:scrollRect by:deltaSize];
       
  4398     [view setNeedsDisplayInRect:deltaXRect];
       
  4399     [view setNeedsDisplayInRect:deltaYRect];
       
  4400 #endif // QT_MAC_USE_COCOA
       
  4401 }
       
  4402 
       
  4403 int QWidget::metric(PaintDeviceMetric m) const
       
  4404 {
       
  4405     switch(m) {
       
  4406     case PdmHeightMM:
       
  4407         return qRound(metric(PdmHeight) * 25.4 / qreal(metric(PdmDpiY)));
       
  4408     case PdmWidthMM:
       
  4409         return qRound(metric(PdmWidth) * 25.4 / qreal(metric(PdmDpiX)));
       
  4410     case PdmHeight:
       
  4411     case PdmWidth: {
       
  4412 #ifndef QT_MAC_USE_COCOA
       
  4413         HIRect rect;
       
  4414         HIViewGetFrame(qt_mac_nativeview_for(this), &rect);
       
  4415 #else
       
  4416         NSRect rect = [qt_mac_nativeview_for(this) frame];
       
  4417 #endif
       
  4418         if(m == PdmWidth)
       
  4419             return (int)rect.size.width;
       
  4420         return (int)rect.size.height; }
       
  4421     case PdmDepth:
       
  4422         return 32;
       
  4423     case PdmNumColors:
       
  4424         return INT_MAX;
       
  4425     case PdmDpiX:
       
  4426     case PdmPhysicalDpiX: {
       
  4427         Q_D(const QWidget);
       
  4428         if (d->extra && d->extra->customDpiX)
       
  4429             return d->extra->customDpiX;
       
  4430         else if (d->parent)
       
  4431             return static_cast<QWidget *>(d->parent)->metric(m);
       
  4432         extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
       
  4433         return int(qt_mac_defaultDpi_x()); }
       
  4434     case PdmDpiY:
       
  4435     case PdmPhysicalDpiY: {
       
  4436         Q_D(const QWidget);
       
  4437         if (d->extra && d->extra->customDpiY)
       
  4438             return d->extra->customDpiY;
       
  4439         else if (d->parent)
       
  4440             return static_cast<QWidget *>(d->parent)->metric(m);
       
  4441         extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp
       
  4442         return int(qt_mac_defaultDpi_y()); }
       
  4443     default: //leave this so the compiler complains when new ones are added
       
  4444         qWarning("QWidget::metric: Unhandled parameter %d", m);
       
  4445         return QPaintDevice::metric(m);
       
  4446     }
       
  4447     return 0;
       
  4448 }
       
  4449 
       
  4450 void QWidgetPrivate::createSysExtra()
       
  4451 {
       
  4452 #ifdef QT_MAC_USE_COCOA
       
  4453     extra->imageMask = 0;
       
  4454 #endif
       
  4455 }
       
  4456 
       
  4457 void QWidgetPrivate::deleteSysExtra()
       
  4458 {
       
  4459 #ifdef QT_MAC_USE_COCOA
       
  4460     if (extra->imageMask)
       
  4461         CFRelease(extra->imageMask);
       
  4462 #endif
       
  4463 }
       
  4464 
       
  4465 void QWidgetPrivate::createTLSysExtra()
       
  4466 {
       
  4467     extra->topextra->resizer = 0;
       
  4468     extra->topextra->isSetGeometry = 0;
       
  4469     extra->topextra->isMove = 0;
       
  4470     extra->topextra->wattr = 0;
       
  4471     extra->topextra->wclass = 0;
       
  4472     extra->topextra->group = 0;
       
  4473     extra->topextra->windowIcon = 0;
       
  4474     extra->topextra->savedWindowAttributesFromMaximized = 0;
       
  4475 }
       
  4476 
       
  4477 void QWidgetPrivate::deleteTLSysExtra()
       
  4478 {
       
  4479 #ifndef QT_MAC_USE_COCOA
       
  4480     if(extra->topextra->group) {
       
  4481         qt_mac_release_window_group(extra->topextra->group);
       
  4482         extra->topextra->group = 0;
       
  4483     }
       
  4484 #endif
       
  4485 }
       
  4486 
       
  4487 void QWidgetPrivate::updateFrameStrut()
       
  4488 {
       
  4489     Q_Q(QWidget);
       
  4490 
       
  4491     QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this);
       
  4492 
       
  4493     that->data.fstrut_dirty = false;
       
  4494     QTLWExtra *top = that->topData();
       
  4495 
       
  4496 #if QT_MAC_USE_COCOA
       
  4497     // 1 Get the window frame
       
  4498     OSWindowRef oswnd = qt_mac_window_for(q);
       
  4499     NSRect frameW = [oswnd frame];
       
  4500     // 2 Get the content frame - so now
       
  4501     NSRect frameC = [oswnd contentRectForFrameRect:frameW];
       
  4502     top->frameStrut.setCoords(frameC.origin.x - frameW.origin.x,
       
  4503                               (frameW.origin.y + frameW.size.height) - (frameC.origin.y + frameC.size.height),
       
  4504                               (frameW.origin.x + frameW.size.width) - (frameC.origin.x + frameC.size.width),
       
  4505                               frameC.origin.y - frameW.origin.y);
       
  4506 #else
       
  4507     Rect window_r;
       
  4508     GetWindowStructureWidths(qt_mac_window_for(q), &window_r);
       
  4509     top->frameStrut.setCoords(window_r.left, window_r.top, window_r.right, window_r.bottom);
       
  4510 #endif
       
  4511 }
       
  4512 
       
  4513 void QWidgetPrivate::registerDropSite(bool on)
       
  4514 {
       
  4515     Q_Q(QWidget);
       
  4516     if (!q->testAttribute(Qt::WA_WState_Created))
       
  4517         return;
       
  4518 #ifndef QT_MAC_USE_COCOA
       
  4519     SetControlDragTrackingEnabled(qt_mac_nativeview_for(q), on);
       
  4520 #else
       
  4521     NSView *view = qt_mac_nativeview_for(q);
       
  4522     if (on && [view isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) {
       
  4523         [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view) registerDragTypes];
       
  4524     }
       
  4525 #endif
       
  4526 }
       
  4527 
       
  4528 void QWidgetPrivate::registerTouchWindow()
       
  4529 {
       
  4530 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
       
  4531     if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_6)
       
  4532         return;
       
  4533     Q_Q(QWidget);
       
  4534     if (!q->testAttribute(Qt::WA_WState_Created))
       
  4535         return;
       
  4536 #ifndef QT_MAC_USE_COCOA
       
  4537     // Needs implementation!
       
  4538 #else
       
  4539     NSView *view = qt_mac_nativeview_for(q);
       
  4540     [view setAcceptsTouchEvents:YES];
       
  4541 #endif
       
  4542 #endif
       
  4543 }
       
  4544 
       
  4545 void QWidgetPrivate::setMask_sys(const QRegion &region)
       
  4546 {
       
  4547     Q_UNUSED(region);
       
  4548 #ifndef QT_MAC_USE_COCOA
       
  4549     Q_Q(QWidget);
       
  4550     if (q->isWindow())
       
  4551         ReshapeCustomWindow(qt_mac_window_for(q));
       
  4552     else
       
  4553         HIViewReshapeStructure(qt_mac_nativeview_for(q));
       
  4554 #else
       
  4555     if (extra->mask.isEmpty()) {
       
  4556         extra->maskBits = QImage();
       
  4557         finishCocoaMaskSetup();
       
  4558     } else {
       
  4559         syncCocoaMask();
       
  4560     }
       
  4561 
       
  4562 #endif
       
  4563 }
       
  4564 
       
  4565 void QWidgetPrivate::setWindowOpacity_sys(qreal level)
       
  4566 {
       
  4567     Q_Q(QWidget);
       
  4568 
       
  4569     if (!q->isWindow())
       
  4570         return;
       
  4571 
       
  4572     level = qBound(0.0, level, 1.0);
       
  4573     topData()->opacity = (uchar)(level * 255);
       
  4574     if (!q->testAttribute(Qt::WA_WState_Created))
       
  4575         return;
       
  4576 
       
  4577     OSWindowRef oswindow = qt_mac_window_for(q);
       
  4578 #if QT_MAC_USE_COCOA
       
  4579     [oswindow setAlphaValue:level];
       
  4580 #else
       
  4581     SetWindowAlpha(oswindow, level);
       
  4582 #endif
       
  4583 }
       
  4584 
       
  4585 #ifdef QT_MAC_USE_COCOA
       
  4586 void QWidgetPrivate::syncCocoaMask()
       
  4587 {
       
  4588     Q_Q(QWidget);
       
  4589     if (!q->testAttribute(Qt::WA_WState_Created) || !extra)
       
  4590         return;
       
  4591 
       
  4592     if (extra->hasMask && extra->maskBits.size() != q->size()) {
       
  4593         extra->maskBits = QImage(q->size(), QImage::Format_Mono);
       
  4594         extra->maskBits.fill(QColor(Qt::color1).rgba());
       
  4595         extra->maskBits.setNumColors(2);
       
  4596         extra->maskBits.setColor(0, QColor(Qt::color0).rgba());
       
  4597         extra->maskBits.setColor(1, QColor(Qt::color1).rgba());
       
  4598         QPainter painter(&extra->maskBits);
       
  4599         painter.setBrush(Qt::color1);
       
  4600         painter.setPen(Qt::NoPen);
       
  4601         painter.drawRects(extra->mask.rects());
       
  4602         painter.end();
       
  4603         finishCocoaMaskSetup();
       
  4604     }
       
  4605 }
       
  4606 
       
  4607 void QWidgetPrivate::finishCocoaMaskSetup()
       
  4608 {
       
  4609     Q_Q(QWidget);
       
  4610 
       
  4611     if (!q->testAttribute(Qt::WA_WState_Created) || !extra)
       
  4612         return;
       
  4613 
       
  4614     // Technically this is too late to release, because the data behind the image
       
  4615     // has already been released. But it's more tidy to do it here.
       
  4616     // If you are seeing a crash, consider doing a CFRelease before changing extra->maskBits.
       
  4617     if (extra->imageMask) {
       
  4618         CFRelease(extra->imageMask);
       
  4619         extra->imageMask = 0;
       
  4620     }
       
  4621 
       
  4622     if (!extra->maskBits.isNull()) {
       
  4623         QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(0,
       
  4624                                                                        extra->maskBits.bits(),
       
  4625                                                                        extra->maskBits.numBytes(),
       
  4626                                                                        0); // shouldn't need to release.
       
  4627         CGFloat decode[2] = {1, 0};
       
  4628         extra->imageMask = CGImageMaskCreate(extra->maskBits.width(), extra->maskBits.height(),
       
  4629                                              1, 1, extra->maskBits.bytesPerLine(), dataProvider,
       
  4630                                              decode, false);
       
  4631     }
       
  4632     if (q->isWindow()) {
       
  4633         NSWindow *window = qt_mac_window_for(q);
       
  4634         [window setOpaque:(extra->imageMask == 0)];
       
  4635         [window invalidateShadow];
       
  4636     }
       
  4637     [qt_mac_nativeview_for(q) setNeedsDisplay:YES];
       
  4638 }
       
  4639 #endif
       
  4640 
       
  4641 struct QPaintEngineCleanupHandler
       
  4642 {
       
  4643     inline QPaintEngineCleanupHandler() : engine(0) {}
       
  4644     inline ~QPaintEngineCleanupHandler() { delete engine; }
       
  4645     QPaintEngine *engine;
       
  4646 };
       
  4647 
       
  4648 Q_GLOBAL_STATIC(QPaintEngineCleanupHandler, engineHandler)
       
  4649 
       
  4650 QPaintEngine *QWidget::paintEngine() const
       
  4651 {
       
  4652     QPaintEngine *&pe = engineHandler()->engine;
       
  4653     if (!pe)
       
  4654         pe = new QCoreGraphicsPaintEngine();
       
  4655     if (pe->isActive()) {
       
  4656         QPaintEngine *engine = new QCoreGraphicsPaintEngine();
       
  4657         engine->setAutoDestruct(true);
       
  4658         return engine;
       
  4659     }
       
  4660     return pe;
       
  4661 }
       
  4662 
       
  4663 void QWidgetPrivate::setModal_sys()
       
  4664 {
       
  4665     Q_Q(QWidget);
       
  4666     if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow())
       
  4667         return;
       
  4668     const QWidget * const windowParent = q->window()->parentWidget();
       
  4669     const QWidget * const primaryWindow = windowParent ? windowParent->window() : 0;
       
  4670     OSWindowRef windowRef = qt_mac_window_for(q);
       
  4671 
       
  4672 #ifdef QT_MAC_USE_COCOA
       
  4673     QMacCocoaAutoReleasePool pool;
       
  4674     bool alreadySheet = [windowRef styleMask] & NSDocModalWindowMask;
       
  4675 
       
  4676     if (windowParent && q->windowModality() == Qt::WindowModal){
       
  4677         // Window should be window-modal, which implies a sheet.
       
  4678         if (!alreadySheet) {
       
  4679             // NB: the following call will call setModal_sys recursivly:
       
  4680             recreateMacWindow();
       
  4681             windowRef = qt_mac_window_for(q);
       
  4682         }
       
  4683         if ([windowRef isKindOfClass:[NSPanel class]]){
       
  4684             // If the primary window of the sheet parent is a child of a modal dialog,
       
  4685             // the sheet parent should not be modally shaddowed.
       
  4686             // This goes for the sheet as well:
       
  4687             OSWindowRef ref = primaryWindow ? qt_mac_window_for(primaryWindow) : 0;
       
  4688             bool isDialog = ref ? [ref isKindOfClass:[NSPanel class]] : false;
       
  4689             bool worksWhenModal = isDialog ? [static_cast<NSPanel *>(ref) worksWhenModal] : false;
       
  4690             if (worksWhenModal)
       
  4691                 [static_cast<NSPanel *>(windowRef) setWorksWhenModal:YES];
       
  4692         }
       
  4693     } else {
       
  4694         // Window shold not be window-modal, and as such, not a sheet.
       
  4695         if (alreadySheet){
       
  4696             // NB: the following call will call setModal_sys recursivly:
       
  4697             recreateMacWindow();
       
  4698             windowRef = qt_mac_window_for(q);
       
  4699         }
       
  4700         if (q->windowModality() == Qt::ApplicationModal) {
       
  4701             [windowRef setLevel:NSModalPanelWindowLevel];
       
  4702         } else if (primaryWindow && primaryWindow->windowModality() == Qt::ApplicationModal) {
       
  4703             // INVARIANT: Our window is a dialog that has a dialog parent that is
       
  4704             // application modal, or . This means that q is supposed to be on top of this
       
  4705             // dialog and not be modally shaddowed:
       
  4706             [windowRef setLevel:NSModalPanelWindowLevel];
       
  4707             if ([windowRef isKindOfClass:[NSPanel class]])
       
  4708                 [static_cast<NSPanel *>(windowRef) setWorksWhenModal:YES];
       
  4709         } else {
       
  4710             // INVARIANT: q should not be modal.
       
  4711             NSInteger winLevel = -1;
       
  4712             if (q->windowType() == Qt::Popup) {
       
  4713                 winLevel = NSPopUpMenuWindowLevel;
       
  4714                 // Popup should be in at least the same level as its parent.
       
  4715                 if (primaryWindow) {
       
  4716                     OSWindowRef parentRef = qt_mac_window_for(primaryWindow);
       
  4717                     winLevel = qMax([parentRef level], winLevel);
       
  4718                 }
       
  4719             } else if (q->windowType() == Qt::Tool) {
       
  4720                 winLevel = NSFloatingWindowLevel;
       
  4721             } else if (q->windowType() == Qt::Dialog) {
       
  4722                 winLevel = NSModalPanelWindowLevel;
       
  4723             }
       
  4724 
       
  4725             // StayOnTop window should appear above Tool windows.
       
  4726             if (data.window_flags & Qt::WindowStaysOnTopHint)
       
  4727                 winLevel = NSPopUpMenuWindowLevel;
       
  4728             // Tooltips should appear above StayOnTop windows.
       
  4729             if (q->windowType() == Qt::ToolTip)
       
  4730                 winLevel = NSScreenSaverWindowLevel;
       
  4731             // All other types are Normal level.
       
  4732             if (winLevel == -1)
       
  4733                 winLevel = NSNormalWindowLevel;
       
  4734             [windowRef setLevel:winLevel];
       
  4735         }
       
  4736     }
       
  4737 
       
  4738 #else
       
  4739     const bool primaryWindowModal = primaryWindow ? primaryWindow->testAttribute(Qt::WA_ShowModal) : false;
       
  4740     const bool modal = q->testAttribute(Qt::WA_ShowModal);
       
  4741 
       
  4742     WindowClass old_wclass;
       
  4743     GetWindowClass(windowRef, &old_wclass);
       
  4744 
       
  4745     if (modal || primaryWindowModal) {
       
  4746         if (q->windowModality() == Qt::WindowModal
       
  4747                 || (primaryWindow && primaryWindow->windowModality() == Qt::WindowModal)){
       
  4748             // Window should be window-modal (which implies a sheet).
       
  4749             if (old_wclass != kSheetWindowClass){
       
  4750                 // We cannot convert a created window to a sheet.
       
  4751                 // So we recreate the window:
       
  4752                 recreateMacWindow();
       
  4753                 return;
       
  4754             }
       
  4755         } else {
       
  4756             // Window should be application-modal (which implies NOT using a sheet).
       
  4757             if (old_wclass == kSheetWindowClass){
       
  4758                 // We cannot convert a sheet to a window.
       
  4759                 // So we recreate the window:
       
  4760                 recreateMacWindow();
       
  4761                 return;
       
  4762             } else if (!(q->data->window_flags & Qt::CustomizeWindowHint)) {
       
  4763                 if (old_wclass == kDocumentWindowClass || old_wclass == kFloatingWindowClass || old_wclass == kUtilityWindowClass){
       
  4764                     // Only change the class to kMovableModalWindowClass if the no explicit jewels
       
  4765                     // are set (kMovableModalWindowClass can't contain them), and the current window class
       
  4766                     // can be converted to modal (according to carbon doc). Mind the order of
       
  4767                     // HIWindowChangeClass and ChangeWindowAttributes.
       
  4768                     WindowGroupRef group = GetWindowGroup(windowRef);
       
  4769                     HIWindowChangeClass(windowRef, kMovableModalWindowClass);
       
  4770                     quint32 tmpWattr = kWindowCloseBoxAttribute | kWindowHorizontalZoomAttribute;
       
  4771                     ChangeWindowAttributes(windowRef, tmpWattr, kWindowNoAttributes);
       
  4772                     ChangeWindowAttributes(windowRef, kWindowNoAttributes, tmpWattr);
       
  4773                     // If the window belongs to a qt-created group, set that group once more:
       
  4774                     if (data.window_flags & Qt::WindowStaysOnTopHint
       
  4775                             || q->windowType() == Qt::Popup
       
  4776                             || q->windowType() == Qt::ToolTip)
       
  4777                         SetWindowGroup(windowRef, group);
       
  4778                 }
       
  4779                 // Popups are usually handled "special" and are never modal.
       
  4780                 Qt::WindowType winType = q->windowType();
       
  4781                 if (winType != Qt::Popup && winType != Qt::ToolTip)
       
  4782                     SetWindowModality(windowRef, kWindowModalityAppModal, 0);
       
  4783             }
       
  4784         }
       
  4785     } else if (windowRef) {
       
  4786         if (old_wclass == kSheetWindowClass){
       
  4787             // Converting a sheet to a window is complex. It's easier to recreate:
       
  4788             recreateMacWindow();
       
  4789             return;
       
  4790         }
       
  4791 
       
  4792         SetWindowModality(windowRef, kWindowModalityNone, 0);
       
  4793 	if (!(q->data->window_flags & Qt::CustomizeWindowHint)) {
       
  4794 	    if (q->window()->d_func()->topData()->wattr |= kWindowCloseBoxAttribute)
       
  4795 		ChangeWindowAttributes(windowRef, kWindowCloseBoxAttribute, kWindowNoAttributes);
       
  4796 	    if (q->window()->d_func()->topData()->wattr |= kWindowHorizontalZoomAttribute)
       
  4797 		ChangeWindowAttributes(windowRef, kWindowHorizontalZoomAttribute, kWindowNoAttributes);
       
  4798 	    if (q->window()->d_func()->topData()->wattr |= kWindowCollapseBoxAttribute)
       
  4799                 ChangeWindowAttributes(windowRef, kWindowCollapseBoxAttribute, kWindowNoAttributes);
       
  4800 	}
       
  4801 
       
  4802         WindowClass newClass = q->window()->d_func()->topData()->wclass;
       
  4803         if (old_wclass != newClass && newClass != 0){
       
  4804             WindowGroupRef group = GetWindowGroup(windowRef);
       
  4805             HIWindowChangeClass(windowRef, newClass);
       
  4806             // If the window belongs to a qt-created group, set that group once more:
       
  4807             if (data.window_flags & Qt::WindowStaysOnTopHint
       
  4808                 || q->windowType() == Qt::Popup
       
  4809                 || q->windowType() == Qt::ToolTip)
       
  4810                 SetWindowGroup(windowRef, group);
       
  4811         }
       
  4812     }
       
  4813 
       
  4814     // Make sure that HIWindowChangeClass didn't remove drag support
       
  4815     // or reset the opaque size grip setting:
       
  4816     SetAutomaticControlDragTrackingEnabledForWindow(windowRef, true);
       
  4817     macUpdateOpaqueSizeGrip();
       
  4818 #endif
       
  4819 }
       
  4820 
       
  4821 void QWidgetPrivate::macUpdateHideOnSuspend()
       
  4822 {
       
  4823     Q_Q(QWidget);
       
  4824     if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow() || q->windowType() != Qt::Tool)
       
  4825         return;
       
  4826 #ifndef QT_MAC_USE_COCOA
       
  4827     if(q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
       
  4828         ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowHideOnSuspendAttribute);
       
  4829     else
       
  4830         ChangeWindowAttributes(qt_mac_window_for(q), kWindowHideOnSuspendAttribute, 0);
       
  4831 #else
       
  4832     if(q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
       
  4833         [qt_mac_window_for(q) setHidesOnDeactivate:NO];
       
  4834     else
       
  4835         [qt_mac_window_for(q) setHidesOnDeactivate:YES];
       
  4836 #endif
       
  4837 }
       
  4838 
       
  4839 void QWidgetPrivate::macUpdateOpaqueSizeGrip()
       
  4840 {
       
  4841     Q_Q(QWidget);
       
  4842 
       
  4843     if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow())
       
  4844         return;
       
  4845 
       
  4846 #ifndef QT_MAC_USE_COCOA	// Growbox is always transparent on Cocoa. Can emulate with setting a QSizeGrip
       
  4847     HIViewRef growBox;
       
  4848     HIViewFindByID(HIViewGetRoot(qt_mac_window_for(q)), kHIViewWindowGrowBoxID, &growBox);
       
  4849     if (!growBox)
       
  4850         return;
       
  4851     HIGrowBoxViewSetTransparent(growBox, !q->testAttribute(Qt::WA_MacOpaqueSizeGrip));
       
  4852 #endif
       
  4853 }
       
  4854 
       
  4855 void QWidgetPrivate::macUpdateSizeAttribute()
       
  4856 {
       
  4857     Q_Q(QWidget);
       
  4858     QEvent event(QEvent::MacSizeChange);
       
  4859     QApplication::sendEvent(q, &event);
       
  4860     for (int i = 0; i < children.size(); ++i) {
       
  4861         QWidget *w = qobject_cast<QWidget *>(children.at(i));
       
  4862         if (w && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
       
  4863               && !q->testAttribute(Qt::WA_MacMiniSize) // no attribute set? inherit from parent
       
  4864               && !w->testAttribute(Qt::WA_MacSmallSize)
       
  4865               && !w->testAttribute(Qt::WA_MacNormalSize))
       
  4866             w->d_func()->macUpdateSizeAttribute();
       
  4867     }
       
  4868     resolveFont();
       
  4869 }
       
  4870 
       
  4871 void QWidgetPrivate::macUpdateIgnoreMouseEvents()
       
  4872 {
       
  4873 #ifndef QT_MAC_USE_COCOA  // This is handled inside the mouse handler on Cocoa.
       
  4874     Q_Q(QWidget);
       
  4875     if (!q->testAttribute(Qt::WA_WState_Created))
       
  4876         return;
       
  4877 
       
  4878     if(q->isWindow())
       
  4879 	{
       
  4880         if(q->testAttribute(Qt::WA_TransparentForMouseEvents))
       
  4881             ChangeWindowAttributes(qt_mac_window_for(q), kWindowIgnoreClicksAttribute, 0);
       
  4882         else
       
  4883             ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowIgnoreClicksAttribute);
       
  4884         ReshapeCustomWindow(qt_mac_window_for(q));
       
  4885     } else {
       
  4886 #ifndef kHIViewFeatureIgnoresClicks
       
  4887 #define kHIViewFeatureIgnoresClicks kHIViewIgnoresClicks
       
  4888 #endif
       
  4889         if(q->testAttribute(Qt::WA_TransparentForMouseEvents))
       
  4890             HIViewChangeFeatures(qt_mac_nativeview_for(q), kHIViewFeatureIgnoresClicks, 0);
       
  4891         else
       
  4892             HIViewChangeFeatures(qt_mac_nativeview_for(q), 0, kHIViewFeatureIgnoresClicks);
       
  4893         HIViewReshapeStructure(qt_mac_nativeview_for(q));
       
  4894     }
       
  4895 #endif
       
  4896 }
       
  4897 
       
  4898 void QWidgetPrivate::macUpdateMetalAttribute()
       
  4899 {
       
  4900     Q_Q(QWidget);
       
  4901     bool realWindow = isRealWindow();
       
  4902     if (!q->testAttribute(Qt::WA_WState_Created) || !realWindow)
       
  4903         return;
       
  4904 
       
  4905     if (realWindow) {
       
  4906 #if QT_MAC_USE_COCOA
       
  4907         // Cocoa doesn't let us change the style mask once it's been changed
       
  4908         // So, that means we need to recreate the window.
       
  4909         OSWindowRef cocoaWindow = qt_mac_window_for(q);
       
  4910         if ([cocoaWindow styleMask] & NSTexturedBackgroundWindowMask)
       
  4911             return;
       
  4912         recreateMacWindow();
       
  4913 #else
       
  4914         QMainWindowLayout *layout = qobject_cast<QMainWindowLayout *>(q->layout());
       
  4915         if (q->testAttribute(Qt::WA_MacBrushedMetal)) {
       
  4916             if (layout)
       
  4917                 layout->updateHIToolBarStatus();
       
  4918             ChangeWindowAttributes(qt_mac_window_for(q), kWindowMetalAttribute, 0);
       
  4919             ChangeWindowAttributes(qt_mac_window_for(q), kWindowMetalNoContentSeparatorAttribute, 0);
       
  4920         } else {
       
  4921             ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowMetalNoContentSeparatorAttribute);
       
  4922             ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowMetalAttribute);
       
  4923             if (layout)
       
  4924                 layout->updateHIToolBarStatus();
       
  4925         }
       
  4926 #endif
       
  4927     }
       
  4928 }
       
  4929 
       
  4930 void QWidgetPrivate::setEnabled_helper_sys(bool enable)
       
  4931 {
       
  4932 #ifdef QT_MAC_USE_COCOA
       
  4933     Q_Q(QWidget);
       
  4934     NSView *view = qt_mac_nativeview_for(q);
       
  4935     if ([view isKindOfClass:[NSControl class]])
       
  4936         [static_cast<NSControl *>(view) setEnabled:enable];
       
  4937 #else
       
  4938     Q_UNUSED(enable);
       
  4939 #endif
       
  4940 }
       
  4941 
       
  4942 QT_END_NAMESPACE