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