util/src/gui/kernel/qapplication_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 <Cocoa/Cocoa.h>
       
    77 
       
    78 #include "qapplication.h"
       
    79 #include "qbitarray.h"
       
    80 #include "qclipboard.h"
       
    81 #include "qcursor.h"
       
    82 #include "qdatastream.h"
       
    83 #include "qdatetime.h"
       
    84 #include "qdesktopwidget.h"
       
    85 #include "qdockwidget.h"
       
    86 #include "qevent.h"
       
    87 #include "qhash.h"
       
    88 #include "qlayout.h"
       
    89 #include "qmenubar.h"
       
    90 #include "qmessagebox.h"
       
    91 #include "qmime.h"
       
    92 #include "qpixmapcache.h"
       
    93 #include "qpointer.h"
       
    94 #include "qsessionmanager.h"
       
    95 #include "qsettings.h"
       
    96 #include "qsocketnotifier.h"
       
    97 #include "qstyle.h"
       
    98 #include "qstylefactory.h"
       
    99 #include "qtextcodec.h"
       
   100 #include "qtoolbar.h"
       
   101 #include "qvariant.h"
       
   102 #include "qwidget.h"
       
   103 #include "qcolormap.h"
       
   104 #include "qdir.h"
       
   105 #include "qdebug.h"
       
   106 #include "qtimer.h"
       
   107 #include "qurl.h"
       
   108 #include "private/qmacinputcontext_p.h"
       
   109 #include "private/qpaintengine_mac_p.h"
       
   110 #include "private/qcursor_p.h"
       
   111 #include "private/qapplication_p.h"
       
   112 #include "private/qcolor_p.h"
       
   113 #include "private/qwidget_p.h"
       
   114 #include "private/qkeymapper_p.h"
       
   115 #include "private/qeventdispatcher_mac_p.h"
       
   116 #include "private/qeventdispatcher_unix_p.h"
       
   117 #include <private/qcocoamenuloader_mac_p.h>
       
   118 #include <private/qcocoaapplication_mac_p.h>
       
   119 #include <private/qcocoaapplicationdelegate_mac_p.h>
       
   120 #include <private/qt_cocoa_helpers_mac_p.h>
       
   121 #include <private/qcocoawindow_mac_p.h>
       
   122 #include <private/qpixmap_mac_p.h>
       
   123 #include <private/qdesktopwidget_mac_p.h>
       
   124 #include <private/qeventdispatcher_mac_p.h>
       
   125 #include <qvarlengtharray.h>
       
   126 
       
   127 #ifndef QT_NO_ACCESSIBILITY
       
   128 #  include "qaccessible.h"
       
   129 #endif
       
   130 
       
   131 #ifndef QT_NO_THREAD
       
   132 #  include "qmutex.h"
       
   133 #endif
       
   134 
       
   135 #include <unistd.h>
       
   136 #include <string.h>
       
   137 #include <sys/time.h>
       
   138 #include <sys/select.h>
       
   139 
       
   140 /*****************************************************************************
       
   141   QApplication debug facilities
       
   142  *****************************************************************************/
       
   143 //#define DEBUG_EVENTS //like EventDebug but more specific to Qt
       
   144 //#define DEBUG_DROPPED_EVENTS
       
   145 //#define DEBUG_MOUSE_MAPS
       
   146 //#define DEBUG_MODAL_EVENTS
       
   147 //#define DEBUG_PLATFORM_SETTINGS
       
   148 
       
   149 #define QMAC_SPEAK_TO_ME
       
   150 #ifdef QMAC_SPEAK_TO_ME
       
   151 #include "qregexp.h"
       
   152 #endif
       
   153 
       
   154 #ifndef kThemeBrushAlternatePrimaryHighlightColor
       
   155 #define kThemeBrushAlternatePrimaryHighlightColor -5
       
   156 #endif
       
   157 
       
   158 #define kCMDeviceUnregisteredNotification CFSTR("CMDeviceUnregisteredNotification")
       
   159 #define kCMDefaultDeviceNotification CFSTR("CMDefaultDeviceNotification")
       
   160 #define kCMDeviceProfilesNotification CFSTR("CMDeviceProfilesNotification")
       
   161 #define kCMDefaultDeviceProfileNotification CFSTR("CMDefaultDeviceProfileNotification")
       
   162 
       
   163 QT_BEGIN_NAMESPACE
       
   164 
       
   165 //for qt_mac.h
       
   166 QPaintDevice *qt_mac_safe_pdev = 0;
       
   167 QList<QMacWindowChangeEvent*> *QMacWindowChangeEvent::change_events = 0;
       
   168 
       
   169 /*****************************************************************************
       
   170   Internal variables and functions
       
   171  *****************************************************************************/
       
   172 static struct {
       
   173     bool use_qt_time_limit;
       
   174     QPointer<QWidget> last_widget;
       
   175     int last_x, last_y;
       
   176     int last_modifiers, last_button;
       
   177     EventTime last_time;
       
   178 } qt_mac_dblclick = { false, 0, -1, -1, 0, 0, -2 };
       
   179 
       
   180 static bool app_do_modal = false;       // modal mode
       
   181 extern QWidgetList *qt_modal_stack;     // stack of modal widgets
       
   182 extern bool qt_tab_all_widgets;         // from qapplication.cpp
       
   183 bool qt_mac_app_fullscreen = false;
       
   184 bool qt_scrollbar_jump_to_pos = false;
       
   185 static bool qt_mac_collapse_on_dblclick = true;
       
   186 extern int qt_antialiasing_threshold; // from qapplication.cpp
       
   187 QPointer<QWidget> qt_button_down;                // widget got last button-down
       
   188 #ifndef QT_MAC_USE_COCOA
       
   189 static bool qt_button_down_in_content; // whether the button_down was in the content area.
       
   190 static bool qt_mac_previous_press_in_popup_mode = false;
       
   191 static bool qt_mac_no_click_through_mode = false;
       
   192 static int tablet_button_state = 0;
       
   193 #endif
       
   194 QPointer<QWidget> qt_mouseover;
       
   195 #if defined(QT_DEBUG)
       
   196 static bool        appNoGrab        = false;        // mouse/keyboard grabbing
       
   197 #endif
       
   198 #ifndef QT_MAC_USE_COCOA
       
   199 static EventHandlerRef app_proc_handler = 0;
       
   200 static EventHandlerUPP app_proc_handlerUPP = 0;
       
   201 #endif
       
   202 static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL;
       
   203 static EventHandlerRef tablet_proximity_handler = 0;
       
   204 static EventHandlerUPP tablet_proximity_UPP = 0;
       
   205 bool QApplicationPrivate::native_modal_dialog_active;
       
   206 
       
   207 Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
       
   208 
       
   209 /*****************************************************************************
       
   210   External functions
       
   211  *****************************************************************************/
       
   212 extern void qt_mac_beep(); //qsound_mac.mm
       
   213 extern Qt::KeyboardModifiers qt_mac_get_modifiers(int keys); //qkeymapper_mac.cpp
       
   214 extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
       
   215 extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
       
   216 extern OSWindowRef qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
       
   217 extern QWidget *qt_mac_find_window(OSWindowRef); //qwidget_mac.cpp
       
   218 extern void qt_mac_set_cursor(const QCursor *, const QPoint &); //qcursor_mac.cpp
       
   219 extern bool qt_mac_is_macsheet(const QWidget *); //qwidget_mac.cpp
       
   220 extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
       
   221 extern void qt_mac_command_set_enabled(MenuRef, UInt32, bool); //qmenu_mac.cpp
       
   222 extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); // qapplication.cpp
       
   223 
       
   224 // Forward Decls
       
   225 void onApplicationWindowChangedActivation( QWidget*widget, bool activated );
       
   226 void onApplicationChangedActivation( bool activated );
       
   227 
       
   228 static void qt_mac_read_fontsmoothing_settings()
       
   229 {
       
   230     qt_applefontsmoothing_enabled = true;
       
   231     int w = 10, h = 10;
       
   232     QImage image(w, h, QImage::Format_RGB32);
       
   233     image.fill(0xffffffff);
       
   234     QPainter p(&image);
       
   235     p.drawText(0, h, "X\\");
       
   236     p.end();
       
   237 
       
   238     const int *bits = (const int *) ((const QImage &) image).bits();
       
   239     int bpl = image.bytesPerLine() / 4;
       
   240     for (int y=0; y<w; ++y) {
       
   241         for (int x=0; x<h; ++x) {
       
   242             int r = qRed(bits[x]);
       
   243             int g = qGreen(bits[x]);
       
   244             int b = qBlue(bits[x]);
       
   245             if (r != g || r != b) {
       
   246                 qt_applefontsmoothing_enabled = true;
       
   247                 return;
       
   248             }
       
   249         }
       
   250         bits += bpl;
       
   251     }
       
   252     qt_applefontsmoothing_enabled = false;
       
   253 }
       
   254 
       
   255 Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
       
   256     OSStatus err;
       
   257     AEDesc scriptTextDesc;
       
   258     ComponentInstance theComponent = 0;
       
   259     OSAID scriptID = kOSANullScript, resultID = kOSANullScript;
       
   260 
       
   261     // set up locals to a known state
       
   262     AECreateDesc(typeNull, 0, 0, &scriptTextDesc);
       
   263     scriptID = kOSANullScript;
       
   264     resultID = kOSANullScript;
       
   265 
       
   266     // open the scripting component
       
   267     theComponent = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
       
   268     if (!theComponent) {
       
   269         err = paramErr;
       
   270         goto bail;
       
   271     }
       
   272 
       
   273     // put the script text into an aedesc
       
   274     err = AECreateDesc(typeUTF8Text, script, script_len, &scriptTextDesc);
       
   275     if (err != noErr)
       
   276         goto bail;
       
   277 
       
   278     // compile the script
       
   279     err = OSACompile(theComponent, &scriptTextDesc, kOSAModeNull, &scriptID);
       
   280     if (err != noErr)
       
   281         goto bail;
       
   282 
       
   283     // run the script
       
   284     err = OSAExecute(theComponent, scriptID, kOSANullScript, kOSAModeNull, &resultID);
       
   285 
       
   286     // collect the results - if any
       
   287     if (ret) {
       
   288         AECreateDesc(typeNull, 0, 0, ret);
       
   289         if (err == errOSAScriptError)
       
   290             OSAScriptError(theComponent, kOSAErrorMessage, typeChar, ret);
       
   291         else if (err == noErr && resultID != kOSANullScript)
       
   292             OSADisplay(theComponent, resultID, typeChar, kOSAModeNull, ret);
       
   293     }
       
   294 bail:
       
   295     AEDisposeDesc(&scriptTextDesc);
       
   296     if (scriptID != kOSANullScript)
       
   297         OSADispose(theComponent, scriptID);
       
   298     if (resultID != kOSANullScript)
       
   299         OSADispose(theComponent, resultID);
       
   300     if (theComponent)
       
   301         CloseComponent(theComponent);
       
   302     return err == noErr;
       
   303 }
       
   304 
       
   305 Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, AEDesc *ret)
       
   306 {
       
   307     return qt_mac_execute_apple_script(script, qstrlen(script), ret);
       
   308 }
       
   309 
       
   310 Q_GUI_EXPORT bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret)
       
   311 {
       
   312     const QByteArray l = script.toUtf8(); return qt_mac_execute_apple_script(l.constData(), l.size(), ret);
       
   313 }
       
   314 
       
   315 /* Resolution change magic */
       
   316 void qt_mac_display_change_callbk(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void *)
       
   317 {
       
   318 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
       
   319     const bool resized = flags & kCGDisplayDesktopShapeChangedFlag;
       
   320 #else
       
   321     Q_UNUSED(flags);
       
   322     const bool resized = true;
       
   323 #endif
       
   324     if (resized && qApp) {
       
   325         if (QDesktopWidget *dw = qApp->desktop()) {
       
   326             QResizeEvent *re = new QResizeEvent(dw->size(), dw->size());
       
   327             QApplication::postEvent(dw, re);
       
   328             QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
       
   329         }
       
   330     }
       
   331 }
       
   332 
       
   333 #ifdef DEBUG_PLATFORM_SETTINGS
       
   334 static void qt_mac_debug_palette(const QPalette &pal, const QPalette &pal2, const QString &where)
       
   335 {
       
   336     const char *const groups[] = {"Active", "Disabled", "Inactive" };
       
   337     const char *const roles[] = { "WindowText", "Button", "Light", "Midlight", "Dark", "Mid",
       
   338                             "Text", "BrightText", "ButtonText", "Base", "Window", "Shadow",
       
   339                             "Highlight", "HighlightedText", "Link", "LinkVisited" };
       
   340     if (!where.isNull())
       
   341         qDebug("qt-internal: %s", where.toLatin1().constData());
       
   342     for(int grp = 0; grp < QPalette::NColorGroups; grp++) {
       
   343         for(int role = 0; role < QPalette::NColorRoles; role++) {
       
   344             QBrush b = pal.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role);
       
   345             QPixmap pm = b.texture();
       
   346             qDebug("  %s::%s %d::%d::%d [%p]%s", groups[grp], roles[role], b.color().red(),
       
   347                    b.color().green(), b.color().blue(), pm.isNull() ? 0 : &pm,
       
   348                    pal2.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role) != b ? " (*)" : "");
       
   349         }
       
   350     }
       
   351 
       
   352 }
       
   353 #else
       
   354 #define qt_mac_debug_palette(x, y, z)
       
   355 #endif
       
   356 
       
   357 //raise a notification
       
   358 #ifndef QT_MAC_USE_COCOA
       
   359 static NMRec qt_mac_notification = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
       
   360 #endif
       
   361 void qt_mac_send_notification()
       
   362 {
       
   363 #ifndef QT_MAC_USE_COCOA
       
   364     //send it
       
   365     qt_mac_notification.nmMark = 1; //non-zero magic number
       
   366     qt_mac_notification.qType = nmType;
       
   367     NMInstall(&qt_mac_notification);
       
   368 #else
       
   369     QMacCocoaAutoReleasePool pool;
       
   370     [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
       
   371 #endif
       
   372 }
       
   373 
       
   374 void qt_mac_cancel_notification()
       
   375 {
       
   376 #ifndef QT_MAC_USE_COCOA
       
   377     NMRemove(&qt_mac_notification);
       
   378 #else
       
   379     QMacCocoaAutoReleasePool pool;
       
   380     [[NSApplication sharedApplication] cancelUserAttentionRequest:NSInformationalRequest];
       
   381 #endif
       
   382 }
       
   383 
       
   384 #ifndef QT_MAC_USE_COCOA
       
   385 //find widget (and part) at a given point
       
   386 static short qt_mac_window_at(int x, int y, QWidget **w=0)
       
   387 {
       
   388     Point p;
       
   389     p.h = x;
       
   390     p.v = y;
       
   391     OSWindowRef wp;
       
   392     WindowPartCode wpc;
       
   393     OSStatus err = FindWindowOfClass(&p, kAllWindowClasses, &wp, &wpc);
       
   394     if(err != noErr) {
       
   395         if(w)
       
   396             (*w) = 0;
       
   397         return wpc;
       
   398     }
       
   399     if(w) {
       
   400         if(wp) {
       
   401             *w = qt_mac_find_window(wp);
       
   402 #if 0
       
   403             if(!*w)
       
   404                 qWarning("QApplication: qt_mac_window_at: Couldn't find %d",(int)wp);
       
   405 #endif
       
   406         } else {
       
   407             *w = 0;
       
   408         }
       
   409     }
       
   410     return wpc;
       
   411 }
       
   412 
       
   413 #endif
       
   414 
       
   415 void qt_mac_set_app_icon(const QPixmap &pixmap)
       
   416 {
       
   417 #ifndef QT_MAC_USE_COCOA
       
   418     if(pixmap.isNull()) {
       
   419         RestoreApplicationDockTileImage();
       
   420     } else {
       
   421         CGImageRef img = (CGImageRef)pixmap.macCGHandle();
       
   422         SetApplicationDockTileImage(img);
       
   423         CGImageRelease(img);
       
   424     }
       
   425 #else
       
   426     QMacCocoaAutoReleasePool pool;
       
   427     NSImage *image = NULL;
       
   428     if (pixmap.isNull()) {
       
   429         // Get Application icon from bundle
       
   430         image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; // released below
       
   431     } else {
       
   432         image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
       
   433     }
       
   434 
       
   435     [NSApp setApplicationIconImage:image];
       
   436     [image release];
       
   437 #endif
       
   438 }
       
   439 
       
   440 Q_GUI_EXPORT void qt_mac_set_press_and_hold_context(bool b)
       
   441 {
       
   442     Q_UNUSED(b);
       
   443     qWarning("qt_mac_set_press_and_hold_context: This functionality is no longer available");
       
   444 }
       
   445 
       
   446 bool qt_nograb()                                // application no-grab option
       
   447 {
       
   448 #if defined(QT_DEBUG)
       
   449     return appNoGrab;
       
   450 #else
       
   451     return false;
       
   452 #endif
       
   453 }
       
   454 
       
   455 void qt_mac_update_os_settings()
       
   456 {
       
   457     if (!qApp)
       
   458         return;
       
   459     if (!QApplication::startingUp()) {
       
   460         static bool needToPolish = true;
       
   461         if (needToPolish) {
       
   462             QApplication::style()->polish(qApp);
       
   463             needToPolish = false;
       
   464         }
       
   465     }
       
   466     //focus mode
       
   467     /* First worked as of 10.2.3 */
       
   468     QSettings appleSettings(QLatin1String("apple.com"));
       
   469     QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0);
       
   470     qt_tab_all_widgets = (appleValue.toInt() & 0x2);
       
   471     //paging mode
       
   472     /* First worked as of 10.2.3 */
       
   473     appleValue = appleSettings.value(QLatin1String("AppleScrollerPagingBehavior"), false);
       
   474     qt_scrollbar_jump_to_pos = appleValue.toBool();
       
   475     //collapse
       
   476     /* First worked as of 10.3.3 */
       
   477     appleValue = appleSettings.value(QLatin1String("AppleMiniaturizeOnDoubleClick"), true);
       
   478     qt_mac_collapse_on_dblclick = appleValue.toBool();
       
   479 
       
   480     // Anti-aliasing threshold
       
   481     appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
       
   482     if (appleValue.isValid())
       
   483         qt_antialiasing_threshold = appleValue.toInt();
       
   484 
       
   485 #ifdef DEBUG_PLATFORM_SETTINGS
       
   486     qDebug("qt_mac_update_os_settings *********************************************************************");
       
   487 #endif
       
   488     { // setup the global palette
       
   489         QColor qc;
       
   490         (void) QApplication::style();  // trigger creation of application style and system palettes
       
   491         QPalette pal = *QApplicationPrivate::sys_pal;
       
   492 
       
   493         pal.setBrush( QPalette::Active, QPalette::Highlight, qcolorForTheme(kThemeBrushPrimaryHighlightColor) );
       
   494         pal.setBrush( QPalette::Inactive, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
       
   495 
       
   496         pal.setBrush( QPalette::Disabled, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
       
   497         pal.setBrush( QPalette::Active, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonActiveDarkShadow) );
       
   498 
       
   499         pal.setBrush( QPalette::Inactive, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
       
   500         pal.setBrush( QPalette::Disabled, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
       
   501 
       
   502         qc = qcolorForThemeTextColor(kThemeTextColorDialogActive);
       
   503         pal.setColor(QPalette::Active, QPalette::Text, qc);
       
   504         pal.setColor(QPalette::Active, QPalette::WindowText, qc);
       
   505         pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
       
   506 
       
   507         qc = qcolorForThemeTextColor(kThemeTextColorDialogInactive);
       
   508         pal.setColor(QPalette::Inactive, QPalette::Text, qc);
       
   509         pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
       
   510         pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
       
   511         pal.setColor(QPalette::Disabled, QPalette::Text, qc);
       
   512         pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
       
   513         pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
       
   514         pal.setBrush(QPalette::ToolTipBase, QColor(255, 255, 199));
       
   515 
       
   516         if (!QApplicationPrivate::sys_pal || *QApplicationPrivate::sys_pal != pal) {
       
   517             QApplicationPrivate::setSystemPalette(pal);
       
   518             QApplication::setPalette(pal);
       
   519         }
       
   520 #ifdef DEBUG_PLATFORM_SETTINGS
       
   521         qt_mac_debug_palette(pal, QApplication::palette(), "Global Palette");
       
   522 #endif
       
   523     }
       
   524 
       
   525     QFont fnt = qfontForThemeFont(kThemeApplicationFont);
       
   526 #ifdef DEBUG_PLATFORM_SETTINGS
       
   527     qDebug("qt-internal: Font for Application [%s::%d::%d::%d]",
       
   528            fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
       
   529 #endif
       
   530     if (!QApplicationPrivate::sys_font || *QApplicationPrivate::sys_font != fnt)
       
   531         QApplicationPrivate::setSystemFont(fnt);
       
   532 
       
   533     { //setup the fonts
       
   534         struct FontMap {
       
   535             FontMap(const char *qc, short fk) : qt_class(qc), font_key(fk) { }
       
   536             const char *const qt_class;
       
   537             short font_key;
       
   538         } mac_widget_fonts[] = {
       
   539             FontMap("QPushButton", kThemePushButtonFont),
       
   540             FontMap("QListView", kThemeViewsFont),
       
   541             FontMap("QListBox", kThemeViewsFont),
       
   542             FontMap("QTitleBar", kThemeWindowTitleFont),
       
   543             FontMap("QMenuBar", kThemeMenuTitleFont),
       
   544             FontMap("QMenu", kThemeMenuItemFont),
       
   545             FontMap("QComboMenuItem", kThemeSystemFont),
       
   546             FontMap("QHeaderView", kThemeSmallSystemFont),
       
   547             FontMap("Q3Header", kThemeSmallSystemFont),
       
   548             FontMap("QTipLabel", kThemeSmallSystemFont),
       
   549             FontMap("QLabel", kThemeSystemFont),
       
   550             FontMap("QToolButton", kThemeSmallSystemFont),
       
   551             FontMap("QMenuItem", kThemeMenuItemCmdKeyFont),  // It doesn't exist, but its unique.
       
   552             FontMap("QComboLineEdit", kThemeViewsFont),  // It doesn't exist, but its unique.
       
   553             FontMap("QSmallFont", kThemeSmallSystemFont),  // It doesn't exist, but its unique.
       
   554             FontMap("QMiniFont", kThemeMiniSystemFont),  // It doesn't exist, but its unique.
       
   555             FontMap(0, 0) };
       
   556         for(int i = 0; mac_widget_fonts[i].qt_class; i++) {
       
   557             QFont fnt = qfontForThemeFont(mac_widget_fonts[i].font_key);
       
   558             bool set_font = true;
       
   559             FontHash *hash = qt_app_fonts_hash();
       
   560             if (!hash->isEmpty()) {
       
   561                 FontHash::const_iterator it
       
   562                                         = hash->constFind(mac_widget_fonts[i].qt_class);
       
   563                 if (it != hash->constEnd())
       
   564                     set_font = (fnt != *it);
       
   565             }
       
   566             if (set_font) {
       
   567                 QApplication::setFont(fnt, mac_widget_fonts[i].qt_class);
       
   568 #ifdef DEBUG_PLATFORM_SETTINGS
       
   569                 qDebug("qt-internal: Font for %s [%s::%d::%d::%d]", mac_widget_fonts[i].qt_class,
       
   570                        fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
       
   571 #endif
       
   572             }
       
   573         }
       
   574     }
       
   575     QApplicationPrivate::initializeWidgetPaletteHash();
       
   576 #ifdef DEBUG_PLATFORM_SETTINGS
       
   577     qDebug("qt_mac_update_os_settings END !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
       
   578 #endif
       
   579 }
       
   580 
       
   581 void QApplicationPrivate::initializeWidgetPaletteHash()
       
   582 {
       
   583     { //setup the palette
       
   584         struct PaletteMap {
       
   585             inline PaletteMap(const char *qc, ThemeBrush a, ThemeBrush i) :
       
   586                 qt_class(qc), active(a), inactive(i) { }
       
   587             const char *const qt_class;
       
   588             ThemeBrush active, inactive;
       
   589         } mac_widget_colors[] = {
       
   590             PaletteMap("QToolButton", kThemeTextColorBevelButtonActive, kThemeTextColorBevelButtonInactive),
       
   591             PaletteMap("QAbstractButton", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
       
   592             PaletteMap("QHeaderView", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
       
   593             PaletteMap("Q3Header", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
       
   594             PaletteMap("QComboBox", kThemeTextColorPopupButtonActive, kThemeTextColorPopupButtonInactive),
       
   595             PaletteMap("QAbstractItemView", kThemeTextColorListView, kThemeTextColorDialogInactive),
       
   596             PaletteMap("QMessageBoxLabel", kThemeTextColorAlertActive, kThemeTextColorAlertInactive),
       
   597             PaletteMap("QTabBar", kThemeTextColorTabFrontActive, kThemeTextColorTabFrontInactive),
       
   598             PaletteMap("QLabel", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
       
   599             PaletteMap("QGroupBox", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
       
   600             PaletteMap("QMenu", kThemeTextColorPopupLabelActive, kThemeTextColorPopupLabelInactive),
       
   601             PaletteMap("QTextEdit", 0, 0),
       
   602             PaletteMap("QTextControl", 0, 0),
       
   603             PaletteMap("QLineEdit", 0, 0),
       
   604             PaletteMap(0, 0, 0) };
       
   605         QColor qc;
       
   606         for(int i = 0; mac_widget_colors[i].qt_class; i++) {
       
   607             QPalette pal;
       
   608             if (mac_widget_colors[i].active != 0) {
       
   609                 qc = qcolorForThemeTextColor(mac_widget_colors[i].active);
       
   610                 pal.setColor(QPalette::Active, QPalette::Text, qc);
       
   611                 pal.setColor(QPalette::Active, QPalette::WindowText, qc);
       
   612                 pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
       
   613                 qc = qcolorForThemeTextColor(mac_widget_colors[i].inactive);
       
   614                 pal.setColor(QPalette::Inactive, QPalette::Text, qc);
       
   615                 pal.setColor(QPalette::Disabled, QPalette::Text, qc);
       
   616                 pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
       
   617                 pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
       
   618                 pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
       
   619                 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
       
   620             }
       
   621             if (!strcmp(mac_widget_colors[i].qt_class, "QMenu")) {
       
   622                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemActive);
       
   623                 pal.setBrush(QPalette::ButtonText, qc);
       
   624                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
       
   625                 pal.setBrush(QPalette::HighlightedText, qc);
       
   626                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemDisabled);
       
   627                 pal.setBrush(QPalette::Disabled, QPalette::Text, qc);
       
   628             } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractButton")
       
   629                       || !strcmp(mac_widget_colors[i].qt_class, "QHeaderView")
       
   630                       || !strcmp(mac_widget_colors[i].qt_class, "Q3Header")) { //special
       
   631                 pal.setColor(QPalette::Disabled, QPalette::ButtonText,
       
   632                              pal.color(QPalette::Disabled, QPalette::Text));
       
   633                 pal.setColor(QPalette::Inactive, QPalette::ButtonText,
       
   634                              pal.color(QPalette::Inactive, QPalette::Text));
       
   635                 pal.setColor(QPalette::Active, QPalette::ButtonText,
       
   636                              pal.color(QPalette::Active, QPalette::Text));
       
   637             } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractItemView")) {
       
   638                 pal.setBrush(QPalette::Active, QPalette::Highlight,
       
   639                              qcolorForTheme(kThemeBrushAlternatePrimaryHighlightColor));
       
   640                 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
       
   641                 pal.setBrush(QPalette::Active, QPalette::HighlightedText, qc);
       
   642 #if 1
       
   643                 pal.setBrush(QPalette::Inactive, QPalette::Text,
       
   644                               pal.brush(QPalette::Active, QPalette::Text));
       
   645                 pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
       
   646                               pal.brush(QPalette::Active, QPalette::Text));
       
   647 #endif
       
   648             } else if (!strcmp(mac_widget_colors[i].qt_class, "QTextEdit")
       
   649                        || !strcmp(mac_widget_colors[i].qt_class, "QTextControl")) {
       
   650                 pal.setBrush(QPalette::Inactive, QPalette::Text,
       
   651                               pal.brush(QPalette::Active, QPalette::Text));
       
   652                 pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
       
   653                               pal.brush(QPalette::Active, QPalette::Text));
       
   654             } else if (!strcmp(mac_widget_colors[i].qt_class, "QLineEdit")) {
       
   655                 pal.setBrush(QPalette::Disabled, QPalette::Base,
       
   656                              pal.brush(QPalette::Active, QPalette::Base));
       
   657             }
       
   658 
       
   659             bool set_palette = true;
       
   660             PaletteHash *phash = qt_app_palettes_hash();
       
   661             if (!phash->isEmpty()) {
       
   662                 PaletteHash::const_iterator it
       
   663                                     = phash->constFind(mac_widget_colors[i].qt_class);
       
   664                 if (it != phash->constEnd())
       
   665                     set_palette = (pal != *it);
       
   666             }
       
   667             if (set_palette) {
       
   668                 QApplication::setPalette(pal, mac_widget_colors[i].qt_class);
       
   669 #ifdef DEBUG_PLATFORM_SETTINGS
       
   670                 qt_mac_debug_palette(pal, QApplication::palette(), QLatin1String("Palette for ") + QString::fromLatin1(mac_widget_colors[i].qt_class));
       
   671 #endif
       
   672             }
       
   673         }
       
   674     }
       
   675 }
       
   676 
       
   677 static void qt_mac_event_release(EventRef &event)
       
   678 {
       
   679     ReleaseEvent(event);
       
   680     event = 0;
       
   681 }
       
   682 #ifndef QT_MAC_USE_COCOA
       
   683 static void qt_mac_event_release(QWidget *w, EventRef &event)
       
   684 {
       
   685     if (event) {
       
   686         QWidget *widget = 0;
       
   687         if (GetEventParameter(event, kEventParamQWidget, typeQWidget, 0, sizeof(widget), 0, &widget) == noErr
       
   688            && w == widget) {
       
   689             if (IsEventInQueue(GetMainEventQueue(), event))
       
   690                 RemoveEventFromQueue(GetMainEventQueue(), event);
       
   691             qt_mac_event_release(event);
       
   692         }
       
   693     }
       
   694 }
       
   695 
       
   696 static bool qt_mac_event_remove(EventRef &event)
       
   697 {
       
   698     if (event) {
       
   699         if (IsEventInQueue(GetMainEventQueue(), event))
       
   700             RemoveEventFromQueue(GetMainEventQueue(), event);
       
   701         qt_mac_event_release(event);
       
   702         return true;
       
   703     }
       
   704     return false;
       
   705 }
       
   706 #endif
       
   707 
       
   708 /* sheets */
       
   709 #ifndef QT_MAC_USE_COCOA
       
   710 static EventRef request_showsheet_pending = 0;
       
   711 #endif
       
   712 void qt_event_request_showsheet(QWidget *w)
       
   713 {
       
   714     Q_ASSERT(qt_mac_is_macsheet(w));
       
   715 #ifdef QT_MAC_USE_COCOA
       
   716     [NSApp beginSheet:qt_mac_window_for(w) modalForWindow:qt_mac_window_for(w->parentWidget())
       
   717         modalDelegate:nil didEndSelector:nil contextInfo:0];
       
   718 #else
       
   719     qt_mac_event_remove(request_showsheet_pending);
       
   720     CreateEvent(0, kEventClassQt, kEventQtRequestShowSheet, GetCurrentEventTime(),
       
   721                 kEventAttributeUserEvent, &request_showsheet_pending);
       
   722     SetEventParameter(request_showsheet_pending, kEventParamQWidget, typeQWidget, sizeof(w), &w);
       
   723     PostEventToQueue(GetMainEventQueue(), request_showsheet_pending, kEventPriorityStandard);
       
   724 #endif
       
   725 }
       
   726 
       
   727 static void qt_post_window_change_event(QWidget *widget)
       
   728 {
       
   729     qt_widget_private(widget)->needWindowChange = true;
       
   730     QEvent *glWindowChangeEvent = new QEvent(QEvent::MacGLWindowChange);
       
   731     QApplication::postEvent(widget, glWindowChangeEvent);
       
   732 }
       
   733 
       
   734 /*
       
   735     Posts updates to all child and grandchild OpenGL widgets for the given widget.
       
   736 */
       
   737 static void qt_mac_update_child_gl_widgets(QWidget *widget)
       
   738 {
       
   739     if (widget->isWindow())
       
   740         return;
       
   741 
       
   742     // Update all OpenGL child widgets for the given widget.
       
   743     QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
       
   744     QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
       
   745     QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
       
   746 
       
   747     for (;it != end; ++it) {
       
   748         qt_post_window_change_event(it->widget);
       
   749     }
       
   750 }
       
   751 
       
   752 /*
       
   753     Sends updates to all child and grandchild gl widgets that have updates pending.
       
   754 */
       
   755 void qt_mac_send_posted_gl_updates(QWidget *widget)
       
   756 {
       
   757     QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
       
   758     QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
       
   759     QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
       
   760 
       
   761     for (;it != end; ++it) {
       
   762         QWidget *glWidget = it->widget;
       
   763         if (qt_widget_private(glWidget)->needWindowChange) {
       
   764             QEvent glChangeEvent(QEvent::MacGLWindowChange);
       
   765             QApplication::sendEvent(glWidget, &glChangeEvent);
       
   766         }
       
   767     }
       
   768 }
       
   769 
       
   770 /*
       
   771     Posts updates to all OpenGL widgets within the window that the given widget intersects.
       
   772 */
       
   773 static void qt_mac_update_intersected_gl_widgets(QWidget *widget)
       
   774 {
       
   775 #ifndef QT_MAC_USE_COCOA
       
   776     QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget->window())->glWidgets;
       
   777     if (glWidgets.isEmpty())
       
   778         return;
       
   779 
       
   780     // Exit if the window has not been created yet (mapToGlobal/size will force create it)
       
   781     if (widget->testAttribute(Qt::WA_WState_Created) == false || HIViewGetWindow(qt_mac_nativeview_for(widget)) == 0)
       
   782         return;
       
   783 
       
   784     const QRect globalWidgetRect = QRect(widget->mapToGlobal(QPoint(0, 0)), widget->size());
       
   785 
       
   786     QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
       
   787     QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
       
   788 
       
   789     for (;it != end; ++it){
       
   790         QWidget *glWidget = it->widget;
       
   791         const QRect globalGlWidgetRect = QRect(glWidget->mapToGlobal(QPoint(0, 0)), glWidget->size());
       
   792         if (globalWidgetRect.intersects(globalGlWidgetRect)) {
       
   793             qt_post_window_change_event(glWidget);
       
   794             it->lastUpdateWidget = widget;
       
   795         } else if (it->lastUpdateWidget == widget) {
       
   796             // Update the gl wigets that the widget intersected the last time around,
       
   797             // and that we are not intersecting now. This prevents paint errors when the
       
   798             // intersecting widget leaves a gl widget.
       
   799             qt_post_window_change_event(glWidget);
       
   800             it->lastUpdateWidget = 0;
       
   801         }
       
   802     }
       
   803 #else
       
   804     Q_UNUSED(widget);
       
   805 #endif
       
   806 }
       
   807 
       
   808 /*
       
   809     Posts a kEventQtRequestWindowChange event to the main Carbon event queue.
       
   810 */
       
   811 static EventRef request_window_change_pending = 0;
       
   812 Q_GUI_EXPORT void qt_event_request_window_change()
       
   813 {
       
   814     if(request_window_change_pending)
       
   815         return;
       
   816 
       
   817     CreateEvent(0, kEventClassQt, kEventQtRequestWindowChange, GetCurrentEventTime(),
       
   818                 kEventAttributeUserEvent, &request_window_change_pending);
       
   819     PostEventToQueue(GetMainEventQueue(), request_window_change_pending, kEventPriorityHigh);
       
   820 }
       
   821 
       
   822 /* window changing. This is a hack around Apple's missing functionality, pending the toolbox
       
   823    team fix. --Sam */
       
   824 Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget)
       
   825 {
       
   826     if (!widget)
       
   827         return;
       
   828 
       
   829     // Post a kEventQtRequestWindowChange event. This event is semi-public,
       
   830     // don't remove this line!
       
   831     qt_event_request_window_change();
       
   832 
       
   833     // Post update request on gl widgets unconditionally.
       
   834     if (qt_widget_private(widget)->isGLWidget == true) {
       
   835         qt_post_window_change_event(widget);
       
   836         return;
       
   837     }
       
   838 
       
   839     qt_mac_update_child_gl_widgets(widget);
       
   840     qt_mac_update_intersected_gl_widgets(widget);
       
   841 }
       
   842 
       
   843 /* activation */
       
   844 static struct {
       
   845     QPointer<QWidget> widget;
       
   846     EventRef event;
       
   847     EventLoopTimerRef timer;
       
   848     EventLoopTimerUPP timerUPP;
       
   849 } request_activate_pending = { 0, 0, 0, 0 };
       
   850 bool qt_event_remove_activate()
       
   851 {
       
   852     if (request_activate_pending.timer) {
       
   853         RemoveEventLoopTimer(request_activate_pending.timer);
       
   854         request_activate_pending.timer = 0;
       
   855     }
       
   856     if (request_activate_pending.event)
       
   857         qt_mac_event_release(request_activate_pending.event);
       
   858     return true;
       
   859 }
       
   860 
       
   861 void qt_event_activate_timer_callbk(EventLoopTimerRef r, void *)
       
   862 {
       
   863     EventLoopTimerRef otc = request_activate_pending.timer;
       
   864     qt_event_remove_activate();
       
   865     if (r == otc && !request_activate_pending.widget.isNull()) {
       
   866         const QWidget *tlw = request_activate_pending.widget->window();
       
   867         Qt::WindowType wt = tlw->windowType();
       
   868         if (tlw->isVisible()
       
   869                && ((wt != Qt::Desktop && wt != Qt::Popup && wt != Qt::Tool) || tlw->isModal())) {
       
   870             CreateEvent(0, kEventClassQt, kEventQtRequestActivate, GetCurrentEventTime(),
       
   871                         kEventAttributeUserEvent, &request_activate_pending.event);
       
   872             PostEventToQueue(GetMainEventQueue(), request_activate_pending.event, kEventPriorityHigh);
       
   873         }
       
   874     }
       
   875 }
       
   876 
       
   877 void qt_event_request_activate(QWidget *w)
       
   878 {
       
   879     if (w == request_activate_pending.widget)
       
   880         return;
       
   881 
       
   882     /* We put these into a timer because due to order of events being sent we need to be sure this
       
   883        comes from inside of the event loop */
       
   884     qt_event_remove_activate();
       
   885     if (!request_activate_pending.timerUPP)
       
   886         request_activate_pending.timerUPP = NewEventLoopTimerUPP(qt_event_activate_timer_callbk);
       
   887     request_activate_pending.widget = w;
       
   888     InstallEventLoopTimer(GetMainEventLoop(), 0, 0, request_activate_pending.timerUPP, 0, &request_activate_pending.timer);
       
   889 }
       
   890 
       
   891 
       
   892 /* menubars */
       
   893 #ifndef QT_MAC_USE_COCOA
       
   894 static EventRef request_menubarupdate_pending = 0;
       
   895 #endif
       
   896 void qt_event_request_menubarupdate()
       
   897 {
       
   898 #ifndef QT_MAC_USE_COCOA
       
   899     if (request_menubarupdate_pending) {
       
   900         if (IsEventInQueue(GetMainEventQueue(), request_menubarupdate_pending))
       
   901             return;
       
   902 #ifdef DEBUG_DROPPED_EVENTS
       
   903         qDebug("%s:%d Whoa, we dropped an event on the floor!", __FILE__, __LINE__);
       
   904 #endif
       
   905     }
       
   906 
       
   907     CreateEvent(0, kEventClassQt, kEventQtRequestMenubarUpdate, GetCurrentEventTime(),
       
   908                 kEventAttributeUserEvent, &request_menubarupdate_pending);
       
   909     PostEventToQueue(GetMainEventQueue(), request_menubarupdate_pending, kEventPriorityHigh);
       
   910 #else
       
   911     // Just call this. The request has the benefit that we don't call this multiple times, but
       
   912     // we can optimize this.
       
   913     QMenuBar::macUpdateMenuBar();
       
   914 #endif
       
   915 }
       
   916 
       
   917 #ifndef QT_MAC_USE_COCOA
       
   918 //context menu
       
   919 static EventRef request_context_pending = 0;
       
   920 static void qt_event_request_context(QWidget *w=0, EventRef *where=0)
       
   921 {
       
   922     if (!where)
       
   923         where = &request_context_pending;
       
   924     if (*where)
       
   925         return;
       
   926     CreateEvent(0, kEventClassQt, kEventQtRequestContext, GetCurrentEventTime(),
       
   927                 kEventAttributeUserEvent, where);
       
   928     if (w)
       
   929         SetEventParameter(*where, kEventParamQWidget, typeQWidget, sizeof(w), &w);
       
   930     PostEventToQueue(GetMainEventQueue(), *where, kEventPriorityStandard);
       
   931 }
       
   932 #endif
       
   933 
       
   934 void QApplicationPrivate::createEventDispatcher()
       
   935 {
       
   936     Q_Q(QApplication);
       
   937     if (q->type() != QApplication::Tty)
       
   938         eventDispatcher = new QEventDispatcherMac(q);
       
   939     else
       
   940         eventDispatcher = new QEventDispatcherUNIX(q);
       
   941 }
       
   942 
       
   943 /* clipboard */
       
   944 void qt_event_send_clipboard_changed()
       
   945 {
       
   946 #ifndef QT_MAC_USE_COCOA
       
   947     AppleEvent ae;
       
   948     if (AECreateAppleEvent(kEventClassQt, typeAEClipboardChanged, 0, kAutoGenerateReturnID, kAnyTransactionID, &ae) != noErr)
       
   949         qDebug("Can't happen!!");
       
   950     AppleEvent reply;
       
   951     AESend(&ae, &reply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, 0, 0);
       
   952 #endif
       
   953 }
       
   954 
       
   955 /* app menu */
       
   956 static QMenu *qt_mac_dock_menu = 0;
       
   957 Q_GUI_EXPORT void qt_mac_set_dock_menu(QMenu *menu)
       
   958 {
       
   959     qt_mac_dock_menu = menu;
       
   960 #ifdef QT_MAC_USE_COCOA
       
   961     [NSApp setDockMenu:menu->macMenu()];
       
   962 #else
       
   963     SetApplicationDockTileMenu(menu->macMenu());
       
   964 #endif
       
   965 }
       
   966 
       
   967 /* events that hold pointers to widgets, must be cleaned up like this */
       
   968 void qt_mac_event_release(QWidget *w)
       
   969 {
       
   970     if (w) {
       
   971 #ifndef QT_MAC_USE_COCOA
       
   972         qt_mac_event_release(w, request_showsheet_pending);
       
   973         qt_mac_event_release(w, request_context_pending);
       
   974 #endif
       
   975         if (w == qt_mac_dock_menu) {
       
   976             qt_mac_dock_menu = 0;
       
   977 #ifndef QT_MAC_USE_COCOA
       
   978             SetApplicationDockTileMenu(0);
       
   979 #else
       
   980             [NSApp setDockMenu:0];
       
   981 #endif
       
   982         }
       
   983     }
       
   984 }
       
   985 
       
   986 struct QMacAppleEventTypeSpec {
       
   987     AEEventClass mac_class;
       
   988     AEEventID mac_id;
       
   989 } app_apple_events[] = {
       
   990     { kCoreEventClass, kAEQuitApplication },
       
   991     { kCoreEventClass, kAEOpenDocuments },
       
   992     { kInternetEventClass, kAEGetURL },
       
   993 };
       
   994 
       
   995 #ifndef QT_MAC_USE_COCOA
       
   996 
       
   997 #if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
       
   998 enum
       
   999 {
       
  1000     kEventMouseScroll                          = 11,
       
  1001     kEventParamMouseWheelSmoothVerticalDelta   = 'saxy',
       
  1002     kEventParamMouseWheelSmoothHorizontalDelta = 'saxx',
       
  1003 };
       
  1004 #endif
       
  1005 
       
  1006 /* watched events */
       
  1007 static EventTypeSpec app_events[] = {
       
  1008     { kEventClassQt, kEventQtRequestWindowChange },
       
  1009     { kEventClassQt, kEventQtRequestShowSheet },
       
  1010     { kEventClassQt, kEventQtRequestContext },
       
  1011     { kEventClassQt, kEventQtRequestActivate },
       
  1012     { kEventClassQt, kEventQtRequestMenubarUpdate },
       
  1013 
       
  1014     { kEventClassWindow, kEventWindowActivated },
       
  1015     { kEventClassWindow, kEventWindowDeactivated },
       
  1016 
       
  1017     { kEventClassMouse, kEventMouseScroll },
       
  1018     { kEventClassMouse, kEventMouseWheelMoved },
       
  1019     { kEventClassMouse, kEventMouseDown },
       
  1020     { kEventClassMouse, kEventMouseUp },
       
  1021     { kEventClassMouse, kEventMouseDragged },
       
  1022     { kEventClassMouse, kEventMouseMoved },
       
  1023 
       
  1024     { kEventClassTablet, kEventTabletProximity },
       
  1025 
       
  1026     { kEventClassApplication, kEventAppActivated },
       
  1027     { kEventClassApplication, kEventAppDeactivated },
       
  1028     { kEventClassApplication, kEventAppAvailableWindowBoundsChanged },
       
  1029 
       
  1030     //    { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
       
  1031     { kEventClassKeyboard, kEventRawKeyModifiersChanged },
       
  1032     { kEventClassKeyboard, kEventRawKeyRepeat },
       
  1033     { kEventClassKeyboard, kEventRawKeyUp },
       
  1034     { kEventClassKeyboard, kEventRawKeyDown },
       
  1035 
       
  1036     { kEventClassCommand, kEventCommandProcess },
       
  1037 
       
  1038     { kEventClassAppleEvent, kEventAppleEvent },
       
  1039 
       
  1040     { kAppearanceEventClass, kAEAppearanceChanged }
       
  1041 };
       
  1042 
       
  1043 void qt_init_app_proc_handler()
       
  1044 {
       
  1045     InstallEventHandler(GetApplicationEventTarget(), app_proc_handlerUPP,
       
  1046                         GetEventTypeCount(app_events), app_events, (void *)qApp,
       
  1047                         &app_proc_handler);
       
  1048 }
       
  1049 #endif // QT_MAC_USE_COCOA
       
  1050 
       
  1051 static void qt_init_tablet_proximity_handler()
       
  1052 {
       
  1053     EventTypeSpec	tabletProximityEvent = { kEventClassTablet, kEventTabletProximity };
       
  1054     InstallEventHandler(GetEventMonitorTarget(), tablet_proximity_UPP,
       
  1055                         1, &tabletProximityEvent, qApp, &tablet_proximity_handler);
       
  1056 }
       
  1057 
       
  1058 static void qt_release_tablet_proximity_handler()
       
  1059 {
       
  1060     RemoveEventHandler(tablet_proximity_handler);
       
  1061 }
       
  1062 
       
  1063 QString QApplicationPrivate::appName() const
       
  1064 {
       
  1065     static QString applName;
       
  1066     if (applName.isEmpty()) {
       
  1067         applName = QCoreApplicationPrivate::macMenuBarName();
       
  1068         ProcessSerialNumber psn;
       
  1069         if (applName.isEmpty() && qt_is_gui_used && GetCurrentProcess(&psn) == noErr) {
       
  1070             QCFString cfstr;
       
  1071             CopyProcessName(&psn, &cfstr);
       
  1072             applName = cfstr;
       
  1073         }
       
  1074     }
       
  1075     return applName;
       
  1076 }
       
  1077 
       
  1078 void qt_release_app_proc_handler()
       
  1079 {
       
  1080 #ifndef QT_MAC_USE_COCOA
       
  1081     if (app_proc_handler) {
       
  1082         RemoveEventHandler(app_proc_handler);
       
  1083         app_proc_handler = 0;
       
  1084     }
       
  1085 #endif
       
  1086 }
       
  1087 
       
  1088 void qt_color_profile_changed(CFNotificationCenterRef, void *, CFStringRef, const void *,
       
  1089                               CFDictionaryRef)
       
  1090 {
       
  1091     QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
       
  1092 }
       
  1093 /* platform specific implementations */
       
  1094 void qt_init(QApplicationPrivate *priv, int)
       
  1095 {
       
  1096     if (qt_is_gui_used) {
       
  1097         CGDisplayRegisterReconfigurationCallback(qt_mac_display_change_callbk, 0);
       
  1098         CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
       
  1099         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
       
  1100                                         kCMDeviceUnregisteredNotification, 0,
       
  1101                                         CFNotificationSuspensionBehaviorDeliverImmediately);
       
  1102         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
       
  1103                                         kCMDefaultDeviceNotification, 0,
       
  1104                                         CFNotificationSuspensionBehaviorDeliverImmediately);
       
  1105         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
       
  1106                                         kCMDeviceProfilesNotification, 0,
       
  1107                                         CFNotificationSuspensionBehaviorDeliverImmediately);
       
  1108         CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
       
  1109                                         kCMDefaultDeviceProfileNotification, 0,
       
  1110                                         CFNotificationSuspensionBehaviorDeliverImmediately);
       
  1111         ProcessSerialNumber psn;
       
  1112         if (GetCurrentProcess(&psn) == noErr) {
       
  1113             // Jambi needs to transform itself since most people aren't "used"
       
  1114             // to putting things in bundles, but other people may actually not
       
  1115             // want to tranform the process (running as a helper or something)
       
  1116             // so don't do that for them. This means checking both LSUIElement
       
  1117             // and LSBackgroundOnly. If you set them both... well, you
       
  1118             // shouldn't do that.
       
  1119 
       
  1120             bool forceTransform = true;
       
  1121             CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
       
  1122                                                                    CFSTR("LSUIElement"));
       
  1123             if (value) {
       
  1124                 CFTypeID valueType = CFGetTypeID(value);
       
  1125                 // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
       
  1126                 // A number less so, but OK.
       
  1127                 if (valueType == CFStringGetTypeID())
       
  1128                     forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
       
  1129                 else if (valueType == CFBooleanGetTypeID())
       
  1130                     forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
       
  1131                 else if (valueType == CFNumberGetTypeID()) {
       
  1132                     int valueAsInt;
       
  1133                     CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
       
  1134                     forceTransform = !valueAsInt;
       
  1135                 }
       
  1136             }
       
  1137 
       
  1138             if (forceTransform) {
       
  1139                 value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
       
  1140                                                              CFSTR("LSBackgroundOnly"));
       
  1141                 if (value) {
       
  1142                     CFTypeID valueType = CFGetTypeID(value);
       
  1143                     if (valueType == CFBooleanGetTypeID())
       
  1144                         forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
       
  1145                     else if (valueType == CFStringGetTypeID())
       
  1146                         forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
       
  1147                     else if (valueType == CFNumberGetTypeID()) {
       
  1148                         int valueAsInt;
       
  1149                         CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
       
  1150                         forceTransform = !valueAsInt;
       
  1151                     }
       
  1152                 }
       
  1153             }
       
  1154 
       
  1155 
       
  1156             if (forceTransform) {
       
  1157                 TransformProcessType(&psn, kProcessTransformToForegroundApplication);
       
  1158             }
       
  1159         }
       
  1160     }
       
  1161 
       
  1162     char **argv = priv->argv;
       
  1163 
       
  1164     // Get command line params
       
  1165     if (int argc = priv->argc) {
       
  1166         int i, j = 1;
       
  1167         QString passed_psn;
       
  1168         for(i=1; i < argc; i++) {
       
  1169             if (argv[i] && *argv[i] != '-') {
       
  1170                 argv[j++] = argv[i];
       
  1171                 continue;
       
  1172             }
       
  1173             QByteArray arg(argv[i]);
       
  1174 #if defined(QT_DEBUG)
       
  1175             if (arg == "-nograb")
       
  1176                 appNoGrab = !appNoGrab;
       
  1177             else
       
  1178 #endif // QT_DEBUG
       
  1179                 if (arg.left(5) == "-psn_") {
       
  1180                     passed_psn = QString::fromLatin1(arg.mid(6));
       
  1181                 } else {
       
  1182                     argv[j++] = argv[i];
       
  1183                 }
       
  1184         }
       
  1185         if (j < priv->argc) {
       
  1186             priv->argv[j] = 0;
       
  1187             priv->argc = j;
       
  1188         }
       
  1189 
       
  1190         //special hack to change working directory (for an app bundle) when running from finder
       
  1191         if (!passed_psn.isNull() && QDir::currentPath() == QLatin1String("/")) {
       
  1192             QCFType<CFURLRef> bundleURL(CFBundleCopyBundleURL(CFBundleGetMainBundle()));
       
  1193             QString qbundlePath = QCFString(CFURLCopyFileSystemPath(bundleURL,
       
  1194                                             kCFURLPOSIXPathStyle));
       
  1195             if (qbundlePath.endsWith(QLatin1String(".app")))
       
  1196                 QDir::setCurrent(qbundlePath.section(QLatin1Char('/'), 0, -2));
       
  1197         }
       
  1198    }
       
  1199 
       
  1200     QMacPasteboardMime::initialize();
       
  1201 
       
  1202     qApp->setObjectName(priv->appName());
       
  1203     if (qt_is_gui_used) {
       
  1204         QColormap::initialize();
       
  1205         QFont::initialize();
       
  1206         QCursorData::initialize();
       
  1207         QCoreGraphicsPaintEngine::initialize();
       
  1208 #ifndef QT_NO_ACCESSIBILITY
       
  1209         QAccessible::initialize();
       
  1210 #endif
       
  1211         QMacInputContext::initialize();
       
  1212         QApplicationPrivate::inputContext = new QMacInputContext;
       
  1213 
       
  1214         if (QApplication::desktopSettingsAware())
       
  1215             qt_mac_update_os_settings();
       
  1216 #ifndef QT_MAC_USE_COCOA
       
  1217         if (!app_proc_handler) {
       
  1218             app_proc_handlerUPP = NewEventHandlerUPP(QApplicationPrivate::globalEventProcessor);
       
  1219             qt_init_app_proc_handler();
       
  1220         }
       
  1221 
       
  1222 #endif
       
  1223         if (!app_proc_ae_handlerUPP) {
       
  1224             app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor);
       
  1225             for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
       
  1226                 AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
       
  1227                         app_proc_ae_handlerUPP, SRefCon(qApp), false);
       
  1228         }
       
  1229 
       
  1230         if (QApplicationPrivate::app_style) {
       
  1231             QEvent ev(QEvent::Style);
       
  1232             qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
       
  1233         }
       
  1234     }
       
  1235     if (QApplication::desktopSettingsAware())
       
  1236         QApplicationPrivate::qt_mac_apply_settings();
       
  1237 
       
  1238     // Cocoa application delegate
       
  1239 #ifdef QT_MAC_USE_COCOA
       
  1240     NSApplication *cocoaApp = [NSApplication sharedApplication];
       
  1241     QMacCocoaAutoReleasePool pool;
       
  1242     NSObject *oldDelegate = [cocoaApp delegate];
       
  1243     QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
       
  1244     Q_ASSERT(newDelegate);
       
  1245     [newDelegate setQtPrivate:priv];
       
  1246     // Only do things that make sense to do once, otherwise we crash.
       
  1247     if (oldDelegate != newDelegate && !QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
       
  1248         [newDelegate setReflectionDelegate:oldDelegate];
       
  1249         [cocoaApp setDelegate:newDelegate];
       
  1250 
       
  1251         QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) alloc] init];
       
  1252         if ([NSBundle loadNibNamed:@"qt_menu" owner:qtMenuLoader] == false) {
       
  1253             qFatal("Qt internal error: qt_menu.nib could not be loaded. The .nib file"
       
  1254                    " should be placed in QtGui.framework/Versions/Current/Resources/ "
       
  1255                    " or in the resources directory of your application bundle.");
       
  1256         }
       
  1257 
       
  1258         [cocoaApp setMenu:[qtMenuLoader menu]];
       
  1259         [newDelegate setMenuLoader:qtMenuLoader];
       
  1260         [qtMenuLoader release];
       
  1261 
       
  1262         NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
       
  1263         [eventManager setEventHandler:newDelegate andSelector:@selector(getUrl:withReplyEvent:)
       
  1264           forEventClass:kInternetEventClass andEventID:kAEGetURL];
       
  1265     }
       
  1266 #endif
       
  1267     // Register for Carbon tablet proximity events on the event monitor target.
       
  1268     // This means that we should receive proximity events even when we aren't the active application.
       
  1269     if (!tablet_proximity_handler) {
       
  1270         tablet_proximity_UPP = NewEventHandlerUPP(QApplicationPrivate::tabletProximityCallback);
       
  1271         qt_init_tablet_proximity_handler();
       
  1272     }
       
  1273    priv->native_modal_dialog_active = false;
       
  1274 
       
  1275    qt_mac_read_fontsmoothing_settings();
       
  1276 }
       
  1277 
       
  1278 void qt_release_apple_event_handler()
       
  1279 {
       
  1280     if(app_proc_ae_handlerUPP) {
       
  1281         for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
       
  1282             AERemoveEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
       
  1283                     app_proc_ae_handlerUPP, true);
       
  1284         DisposeAEEventHandlerUPP(app_proc_ae_handlerUPP);
       
  1285         app_proc_ae_handlerUPP = 0;
       
  1286     }
       
  1287 }
       
  1288 
       
  1289 /*****************************************************************************
       
  1290   qt_cleanup() - cleans up when the application is finished
       
  1291  *****************************************************************************/
       
  1292 
       
  1293 void qt_cleanup()
       
  1294 {
       
  1295     CGDisplayRemoveReconfigurationCallback(qt_mac_display_change_callbk, 0);
       
  1296     CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
       
  1297     CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceUnregisteredNotification, 0);
       
  1298     CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceNotification, 0);
       
  1299     CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceProfilesNotification, 0);
       
  1300     CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceProfileNotification, 0);
       
  1301 
       
  1302 #ifndef QT_MAC_USE_COCOA
       
  1303     qt_release_app_proc_handler();
       
  1304     if (app_proc_handlerUPP) {
       
  1305         DisposeEventHandlerUPP(app_proc_handlerUPP);
       
  1306         app_proc_handlerUPP = 0;
       
  1307     }
       
  1308 #endif
       
  1309     qt_release_apple_event_handler();
       
  1310     qt_release_tablet_proximity_handler();
       
  1311     if (tablet_proximity_UPP)
       
  1312         DisposeEventHandlerUPP(tablet_proximity_UPP);
       
  1313 
       
  1314     QPixmapCache::clear();
       
  1315     if (qt_is_gui_used) {
       
  1316 #ifndef QT_NO_ACCESSIBILITY
       
  1317         QAccessible::cleanup();
       
  1318 #endif
       
  1319         QMacInputContext::cleanup();
       
  1320         QCursorData::cleanup();
       
  1321         QFont::cleanup();
       
  1322         QColormap::cleanup();
       
  1323         if (qt_mac_safe_pdev) {
       
  1324             delete qt_mac_safe_pdev;
       
  1325             qt_mac_safe_pdev = 0;
       
  1326         }
       
  1327         extern void qt_mac_unregister_widget(); // qapplication_mac.cpp
       
  1328         qt_mac_unregister_widget();
       
  1329     }
       
  1330 }
       
  1331 
       
  1332 /*****************************************************************************
       
  1333   Platform specific global and internal functions
       
  1334  *****************************************************************************/
       
  1335 void qt_updated_rootinfo()
       
  1336 {
       
  1337 }
       
  1338 
       
  1339 bool qt_wstate_iconified(WId)
       
  1340 {
       
  1341     return false;
       
  1342 }
       
  1343 
       
  1344 /*****************************************************************************
       
  1345   Platform specific QApplication members
       
  1346  *****************************************************************************/
       
  1347 extern QWidget * mac_mouse_grabber;
       
  1348 extern QWidget * mac_keyboard_grabber;
       
  1349 
       
  1350 #ifdef QT3_SUPPORT
       
  1351 void QApplication::setMainWidget(QWidget *mainWidget)
       
  1352 {
       
  1353     QApplicationPrivate::main_widget = mainWidget;
       
  1354     if (QApplicationPrivate::main_widget && windowIcon().isNull()
       
  1355         && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
       
  1356         setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
       
  1357 }
       
  1358 #endif
       
  1359 #ifndef QT_NO_CURSOR
       
  1360 
       
  1361 /*****************************************************************************
       
  1362   QApplication cursor stack
       
  1363  *****************************************************************************/
       
  1364 void QApplication::setOverrideCursor(const QCursor &cursor)
       
  1365 {
       
  1366     qApp->d_func()->cursor_list.prepend(cursor);
       
  1367 
       
  1368 #ifdef QT_MAC_USE_COCOA
       
  1369     QMacCocoaAutoReleasePool pool;
       
  1370     [static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursor)) push];
       
  1371 #else
       
  1372     if (qApp && qApp->activeWindow())
       
  1373         qt_mac_set_cursor(&qApp->d_func()->cursor_list.first(), QCursor::pos());
       
  1374 #endif
       
  1375 }
       
  1376 
       
  1377 void QApplication::restoreOverrideCursor()
       
  1378 {
       
  1379     if (qApp->d_func()->cursor_list.isEmpty())
       
  1380         return;
       
  1381     qApp->d_func()->cursor_list.removeFirst();
       
  1382 
       
  1383 #ifdef QT_MAC_USE_COCOA
       
  1384     QMacCocoaAutoReleasePool pool;
       
  1385     [NSCursor pop];
       
  1386 #else
       
  1387     if (qApp && qApp->activeWindow()) {
       
  1388         const QCursor def(Qt::ArrowCursor);
       
  1389         qt_mac_set_cursor(qApp->d_func()->cursor_list.isEmpty() ? &def : &qApp->d_func()->cursor_list.first(), QCursor::pos());
       
  1390     }
       
  1391 #endif
       
  1392 }
       
  1393 #endif // QT_NO_CURSOR
       
  1394 
       
  1395 QWidget *QApplication::topLevelAt(const QPoint &p)
       
  1396 {
       
  1397 #ifndef QT_MAC_USE_COCOA
       
  1398     QWidget *widget;
       
  1399     qt_mac_window_at(p.x(), p.y(), &widget);
       
  1400     return widget;
       
  1401 #else
       
  1402     NSInteger windowCount;
       
  1403     NSCountWindows(&windowCount);
       
  1404     if (windowCount <= 0)
       
  1405         return 0;  // There's no window to find!
       
  1406     QMacCocoaAutoReleasePool pool;
       
  1407     NSPoint cocoaPoint = flipPoint(p);
       
  1408     QVarLengthArray<NSInteger> windowList(windowCount);
       
  1409     NSWindowList(windowCount, windowList.data());
       
  1410     for (int i = 0; i < windowCount; ++i) {
       
  1411         NSWindow *window = [NSApp windowWithWindowNumber:windowList[i]];
       
  1412         if (window && NSPointInRect(cocoaPoint, [window frame])) {
       
  1413             QWidget *candidateWindow = [window QT_MANGLE_NAMESPACE(qt_qwidget)];
       
  1414             // Check to see if there's a hole in the window where the mask is.
       
  1415             // If there is, we should just continue to see if there is a window below.
       
  1416             if (candidateWindow && !candidateWindow->mask().isEmpty()) {
       
  1417                 QPoint localPoint = candidateWindow->mapFromGlobal(p);
       
  1418                 if (!candidateWindow->mask().contains(localPoint)) {
       
  1419                     continue;
       
  1420                 }
       
  1421             }
       
  1422             return candidateWindow;
       
  1423         }
       
  1424     }
       
  1425     return 0; // Couldn't find a window at this point
       
  1426 #endif
       
  1427 }
       
  1428 
       
  1429 /*****************************************************************************
       
  1430   Main event loop
       
  1431  *****************************************************************************/
       
  1432 
       
  1433 bool QApplicationPrivate::modalState()
       
  1434 {
       
  1435     return app_do_modal;
       
  1436 }
       
  1437 
       
  1438 #ifdef QT_MAC_USE_COCOA
       
  1439 #endif
       
  1440 
       
  1441 void QApplicationPrivate::enterModal_sys(QWidget *widget)
       
  1442 {
       
  1443 #ifdef DEBUG_MODAL_EVENTS
       
  1444     Q_ASSERT(widget);
       
  1445     qDebug("Entering modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
       
  1446             widget, qt_modal_stack ? (int)qt_modal_stack->count() : -1);
       
  1447 #endif
       
  1448     if (!qt_modal_stack)
       
  1449         qt_modal_stack = new QWidgetList;
       
  1450 
       
  1451     dispatchEnterLeave(0, qt_mouseover);
       
  1452     qt_mouseover = 0;
       
  1453 
       
  1454     qt_modal_stack->insert(0, widget);
       
  1455     if (!app_do_modal)
       
  1456         qt_event_request_menubarupdate();
       
  1457     app_do_modal = true;
       
  1458     qt_button_down = 0;
       
  1459 
       
  1460 #ifdef QT_MAC_USE_COCOA
       
  1461     if (!qt_mac_is_macsheet(widget))
       
  1462         QEventDispatcherMacPrivate::beginModalSession(widget);
       
  1463 #endif
       
  1464 }
       
  1465 
       
  1466 void QApplicationPrivate::leaveModal_sys(QWidget *widget)
       
  1467 {
       
  1468     if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
       
  1469 #ifdef DEBUG_MODAL_EVENTS
       
  1470         qDebug("Leaving modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
       
  1471                widget, qt_modal_stack->count());
       
  1472 #endif
       
  1473         if (qt_modal_stack->isEmpty()) {
       
  1474             delete qt_modal_stack;
       
  1475             qt_modal_stack = 0;
       
  1476             QPoint p(QCursor::pos());
       
  1477             app_do_modal = false;
       
  1478             QWidget* w = 0;
       
  1479             if (QWidget *grabber = QWidget::mouseGrabber())
       
  1480                 w = grabber;
       
  1481             else
       
  1482                 w = QApplication::widgetAt(p.x(), p.y());
       
  1483             dispatchEnterLeave(w, qt_mouseover); // send synthetic enter event
       
  1484             qt_mouseover = w;
       
  1485         }
       
  1486 #ifdef QT_MAC_USE_COCOA
       
  1487         if (!qt_mac_is_macsheet(widget))
       
  1488             QEventDispatcherMacPrivate::endModalSession(widget);
       
  1489 #endif
       
  1490     }
       
  1491 #ifdef DEBUG_MODAL_EVENTS
       
  1492     else qDebug("Failure to remove %s::%s::%p -- %p", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(), widget, qt_modal_stack);
       
  1493 #endif
       
  1494     app_do_modal = (qt_modal_stack != 0);
       
  1495     if (!app_do_modal)
       
  1496         qt_event_request_menubarupdate();
       
  1497 }
       
  1498 
       
  1499 QWidget *QApplicationPrivate::tryModalHelper_sys(QWidget *top)
       
  1500 {
       
  1501 #ifndef QT_MAC_USE_COCOA
       
  1502     if(top && qt_mac_is_macsheet(top) && !IsWindowVisible(qt_mac_window_for(top))) {
       
  1503         if(OSWindowRef wp = GetFrontWindowOfClass(kSheetWindowClass, true)) {
       
  1504             if(QWidget *sheet = qt_mac_find_window(wp))
       
  1505                 top = sheet;
       
  1506         }
       
  1507     }
       
  1508 #endif
       
  1509     return top;
       
  1510 }
       
  1511 
       
  1512 #ifndef QT_MAC_USE_COCOA
       
  1513 static bool qt_try_modal(QWidget *widget, EventRef event)
       
  1514 {
       
  1515     QWidget * top = 0;
       
  1516 
       
  1517     if (QApplicationPrivate::tryModalHelper(widget, &top))
       
  1518         return true;
       
  1519 
       
  1520     // INVARIANT: widget is modally shaddowed within its
       
  1521     // window, and should therefore not handle the event.
       
  1522     // However, if the window is not active, the event
       
  1523     // might suggest that we should bring it to front:
       
  1524 
       
  1525     bool block_event = false;
       
  1526 
       
  1527     if (event) {
       
  1528         switch (GetEventClass(event)) {
       
  1529         case kEventClassMouse:
       
  1530         case kEventClassKeyboard:
       
  1531             block_event = true;
       
  1532             break;
       
  1533         }
       
  1534     }
       
  1535 
       
  1536     QWidget *activeWidget = QApplication::activeWindow();
       
  1537     if ((!activeWidget || QApplicationPrivate::isBlockedByModal(activeWidget)) &&
       
  1538        top->isWindow() && block_event && !QApplicationPrivate::native_modal_dialog_active)
       
  1539         top->raise();
       
  1540 
       
  1541 #ifdef DEBUG_MODAL_EVENTS
       
  1542     qDebug("%s:%d -- final decision! (%s)", __FILE__, __LINE__, block_event ? "false" : "true");
       
  1543 #endif
       
  1544     return !block_event;
       
  1545 }
       
  1546 #endif
       
  1547 
       
  1548 OSStatus QApplicationPrivate::tabletProximityCallback(EventHandlerCallRef, EventRef carbonEvent,
       
  1549                                                       void *)
       
  1550 {
       
  1551     OSType eventClass = GetEventClass(carbonEvent);
       
  1552     UInt32 eventKind = GetEventKind(carbonEvent);
       
  1553     if (eventClass != kEventClassTablet || eventKind != kEventTabletProximity)
       
  1554         return eventNotHandledErr;
       
  1555 
       
  1556     // Get the current point of the device and its unique ID.
       
  1557     ::TabletProximityRec proxRec;
       
  1558     GetEventParameter(carbonEvent, kEventParamTabletProximityRec, typeTabletProximityRec, 0,
       
  1559                       sizeof(proxRec), 0, &proxRec);
       
  1560     qt_dispatchTabletProximityEvent(proxRec);
       
  1561     return noErr;
       
  1562 }
       
  1563 
       
  1564 OSStatus
       
  1565 QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event, void *data)
       
  1566 {
       
  1567 #ifndef QT_MAC_USE_COCOA
       
  1568     QApplication *app = (QApplication *)data;
       
  1569     QScopedLoopLevelCounter loopLevelCounter(app->d_func()->threadData);
       
  1570     long result;
       
  1571     if (app->filterEvent(&event, &result))
       
  1572         return result;
       
  1573     if(app->macEventFilter(er, event)) //someone else ate it
       
  1574         return noErr;
       
  1575     QPointer<QWidget> widget;
       
  1576 
       
  1577     /*We assume all events are handled and in
       
  1578       the code below we set it to false when we know we didn't handle it, this
       
  1579       will let rogue events through (shouldn't really happen, but better safe
       
  1580       than sorry) */
       
  1581     bool handled_event=true;
       
  1582     UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
       
  1583     switch(eclass)
       
  1584     {
       
  1585     case kEventClassQt:
       
  1586         if(ekind == kEventQtRequestShowSheet) {
       
  1587             request_showsheet_pending = 0;
       
  1588             QWidget *widget = 0;
       
  1589             GetEventParameter(event, kEventParamQWidget, typeQWidget, 0,
       
  1590                               sizeof(widget), 0, &widget);
       
  1591             if(widget) {
       
  1592                 if (widget->macEvent(er, event))
       
  1593                     return noErr;
       
  1594                 WindowPtr window = qt_mac_window_for(widget);
       
  1595                 bool just_show = !qt_mac_is_macsheet(widget);
       
  1596                 if(!just_show) {
       
  1597                     OSStatus err = ShowSheetWindow(window, qt_mac_window_for(widget->parentWidget()));
       
  1598                     if(err != noErr)
       
  1599                         qWarning("Qt: QWidget: Unable to show as sheet %s::%s [%ld]", widget->metaObject()->className(),
       
  1600                                  widget->objectName().toLocal8Bit().constData(), long(err));
       
  1601                     just_show = true;
       
  1602                 }
       
  1603                 if(just_show) //at least the window will be visible, but the sheet flag doesn't work sadly (probalby too many sheets)
       
  1604                     ShowHide(window, true);
       
  1605             }
       
  1606         } else if(ekind == kEventQtRequestWindowChange) {
       
  1607             qt_mac_event_release(request_window_change_pending);
       
  1608         } else if(ekind == kEventQtRequestMenubarUpdate) {
       
  1609             qt_mac_event_release(request_menubarupdate_pending);
       
  1610             QMenuBar::macUpdateMenuBar();
       
  1611         } else if(ekind == kEventQtRequestActivate) {
       
  1612             qt_mac_event_release(request_activate_pending.event);
       
  1613             if(request_activate_pending.widget) {
       
  1614                 QWidget *tlw = request_activate_pending.widget->window();
       
  1615                 if (tlw->macEvent(er, event))
       
  1616                     return noErr;
       
  1617                 request_activate_pending.widget = 0;
       
  1618                 tlw->activateWindow();
       
  1619                 SelectWindow(qt_mac_window_for(tlw));
       
  1620             }
       
  1621         } else if(ekind == kEventQtRequestContext) {
       
  1622             bool send = false;
       
  1623             if ((send = (event == request_context_pending)))
       
  1624                 qt_mac_event_release(request_context_pending);
       
  1625             if(send) {
       
  1626                 //figure out which widget to send it to
       
  1627                 QPoint where = QCursor::pos();
       
  1628                 QWidget *widget = 0;
       
  1629                 GetEventParameter(event, kEventParamQWidget, typeQWidget, 0,
       
  1630                                   sizeof(widget), 0, &widget);
       
  1631                 if(!widget) {
       
  1632                     if(qt_button_down)
       
  1633                         widget = qt_button_down;
       
  1634                     else
       
  1635                         widget = QApplication::widgetAt(where.x(), where.y());
       
  1636                 }
       
  1637                 if(widget && !isBlockedByModal(widget)) {
       
  1638                     if (widget->macEvent(er, event))
       
  1639                         return noErr;
       
  1640                     QPoint plocal(widget->mapFromGlobal(where));
       
  1641                     const Qt::KeyboardModifiers keyboardModifiers = qt_mac_get_modifiers(GetCurrentEventKeyModifiers());
       
  1642                     QContextMenuEvent qme(QContextMenuEvent::Mouse, plocal, where, keyboardModifiers);
       
  1643                     QApplication::sendEvent(widget, &qme);
       
  1644                     if(qme.isAccepted()) { //once this happens the events before are pitched
       
  1645                         qt_button_down = 0;
       
  1646                         qt_mac_dblclick.last_widget = 0;
       
  1647                     }
       
  1648                 } else {
       
  1649                     handled_event = false;
       
  1650                 }
       
  1651             }
       
  1652         } else {
       
  1653             handled_event = false;
       
  1654         }
       
  1655         break;
       
  1656     case kEventClassTablet:
       
  1657         switch (ekind) {
       
  1658         case kEventTabletProximity:
       
  1659             // Get the current point of the device and its unique ID.
       
  1660             ::TabletProximityRec proxRec;
       
  1661             GetEventParameter(event, kEventParamTabletProximityRec, typeTabletProximityRec, 0,
       
  1662                               sizeof(proxRec), 0, &proxRec);
       
  1663             qt_dispatchTabletProximityEvent(proxRec);
       
  1664         }
       
  1665         break;
       
  1666     case kEventClassMouse:
       
  1667     {
       
  1668         static const int kEventParamQAppSeenMouseEvent = 'QASM';
       
  1669         // Check if we've seen the event, if we have we shouldn't process
       
  1670         // it again as it may lead to spurious "double events"
       
  1671         bool seenEvent;
       
  1672         if (GetEventParameter(event, kEventParamQAppSeenMouseEvent,
       
  1673                               typeBoolean, 0, sizeof(bool), 0, &seenEvent) == noErr) {
       
  1674             if (seenEvent)
       
  1675                 return eventNotHandledErr;
       
  1676         }
       
  1677         seenEvent = true;
       
  1678         SetEventParameter(event, kEventParamQAppSeenMouseEvent, typeBoolean,
       
  1679                           sizeof(bool), &seenEvent);
       
  1680 
       
  1681         Point where;
       
  1682         bool inNonClientArea = false;
       
  1683         GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0,
       
  1684                           sizeof(where), 0, &where);
       
  1685 #if defined(DEBUG_MOUSE_MAPS)
       
  1686         const char *edesc = 0;
       
  1687         switch(ekind) {
       
  1688         case kEventMouseDown: edesc = "MouseButtonPress"; break;
       
  1689         case kEventMouseUp: edesc = "MouseButtonRelease"; break;
       
  1690         case kEventMouseDragged: case kEventMouseMoved: edesc = "MouseMove"; break;
       
  1691         case kEventMouseScroll: edesc = "MouseWheelScroll"; break;
       
  1692         case kEventMouseWheelMoved: edesc = "MouseWheelMove"; break;
       
  1693         }
       
  1694         if(ekind == kEventMouseDown || ekind == kEventMouseUp)
       
  1695             qDebug("Handling mouse: %s", edesc);
       
  1696 #endif
       
  1697         QEvent::Type etype = QEvent::None;
       
  1698         Qt::KeyboardModifiers modifiers;
       
  1699         {
       
  1700             UInt32 mac_modifiers = 0;
       
  1701             GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
       
  1702                               sizeof(mac_modifiers), 0, &mac_modifiers);
       
  1703             modifiers = qt_mac_get_modifiers(mac_modifiers);
       
  1704         }
       
  1705         Qt::MouseButtons buttons;
       
  1706         {
       
  1707             UInt32 mac_buttons = 0;
       
  1708             GetEventParameter(event, kEventParamMouseChord, typeUInt32, 0,
       
  1709                               sizeof(mac_buttons), 0, &mac_buttons);
       
  1710             if (ekind != kEventMouseWheelMoved)
       
  1711                 buttons = qt_mac_get_buttons(mac_buttons);
       
  1712             else
       
  1713                 buttons = QApplication::mouseButtons();
       
  1714         }
       
  1715 
       
  1716         int wheel_deltaX = 0;
       
  1717         int wheel_deltaY = 0;
       
  1718         static EventRef compatibilityEvent = 0;
       
  1719 
       
  1720         if (ekind == kEventMouseScroll) {
       
  1721             // kEventMouseScroll is the new way of dealing with mouse wheel
       
  1722             // events (kEventMouseWheelMoved was the old). kEventMouseScroll results
       
  1723             // in much smoother scrolling when using Mighty Mouse or TrackPad. For
       
  1724             // compatibility with older applications, carbon will also send us
       
  1725             // kEventMouseWheelMoved events if we dont eat this event
       
  1726             // (actually two events; one for horizontal and one for vertical).
       
  1727             // As a results of this, and to make sure we dont't receive duplicate events,
       
  1728             // we try to detect when this happend by checking the 'compatibilityEvent'.
       
  1729             SInt32 mdelt = 0;
       
  1730             GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
       
  1731                               sizeof(mdelt), 0, &mdelt);
       
  1732             wheel_deltaX = mdelt;
       
  1733             mdelt = 0;
       
  1734             GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
       
  1735                               sizeof(mdelt), 0, &mdelt);
       
  1736             wheel_deltaY = mdelt;
       
  1737             GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
       
  1738                               sizeof(compatibilityEvent), 0, &compatibilityEvent);
       
  1739         } else if (ekind == kEventMouseWheelMoved) {
       
  1740             if (event != compatibilityEvent) {
       
  1741                 compatibilityEvent = 0;
       
  1742                 int mdelt = 0;
       
  1743                 GetEventParameter(event, kEventParamMouseWheelDelta, typeSInt32, 0,
       
  1744                         sizeof(mdelt), 0, &mdelt);
       
  1745                 EventMouseWheelAxis axis;
       
  1746                 GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0,
       
  1747                         sizeof(axis), 0, &axis);
       
  1748 
       
  1749                 // Remove acceleration, and use either -120 or 120 as delta:
       
  1750                 if (axis == kEventMouseWheelAxisX)
       
  1751                     wheel_deltaX = qBound(-120, int(mdelt * 10000), 120);
       
  1752                 else
       
  1753                     wheel_deltaY = qBound(-120, int(mdelt * 10000), 120);
       
  1754             }
       
  1755         }
       
  1756 
       
  1757         Qt::MouseButton button = Qt::NoButton;
       
  1758         if(ekind == kEventMouseDown || ekind == kEventMouseUp) {
       
  1759             EventMouseButton mac_button = 0;
       
  1760             GetEventParameter(event, kEventParamMouseButton, typeMouseButton, 0,
       
  1761                               sizeof(mac_button), 0, &mac_button);
       
  1762             button = qt_mac_get_button(mac_button);
       
  1763         }
       
  1764 
       
  1765         switch(ekind) {
       
  1766         case kEventMouseDown:
       
  1767             etype = QEvent::MouseButtonPress;
       
  1768             break;
       
  1769         case kEventMouseUp:
       
  1770             etype = QEvent::MouseButtonRelease;
       
  1771             break;
       
  1772         case kEventMouseDragged:
       
  1773         case kEventMouseMoved:
       
  1774             etype = QEvent::MouseMove;
       
  1775             break;
       
  1776         }
       
  1777 
       
  1778         const bool inPopupMode = app->d_func()->inPopupMode();
       
  1779 
       
  1780         // A click outside a popup closes the popup. Make sure
       
  1781         // that no events are generated for the release part of that click.
       
  1782         // (The press goes to the popup and closes it.)
       
  1783         if (etype == QEvent::MouseButtonPress) {
       
  1784             qt_mac_previous_press_in_popup_mode = inPopupMode;
       
  1785         } else if (qt_mac_previous_press_in_popup_mode && !inPopupMode && etype == QEvent::MouseButtonRelease) {
       
  1786             qt_mac_previous_press_in_popup_mode = false;
       
  1787             handled_event = true;
       
  1788 #if defined(DEBUG_MOUSE_MAPS)
       
  1789             qDebug("Bail out early due to qt_mac_previous_press_in_popup_mode");
       
  1790 #endif
       
  1791             break; // break from case kEventClassMouse
       
  1792         }
       
  1793 
       
  1794         //figure out which widget to send it to
       
  1795         if(inPopupMode) {
       
  1796             QWidget *popup = qApp->activePopupWidget();
       
  1797             if (qt_button_down && qt_button_down->window() == popup) {
       
  1798                 widget = qt_button_down;
       
  1799             } else {
       
  1800                 QPoint pos = popup->mapFromGlobal(QPoint(where.h, where.v));
       
  1801                 widget = popup->childAt(pos);
       
  1802             }
       
  1803             if(!widget)
       
  1804                 widget = popup;
       
  1805         } else {
       
  1806             if(mac_mouse_grabber) {
       
  1807                 widget = mac_mouse_grabber;
       
  1808             } else if (qt_button_down) {
       
  1809                 widget = qt_button_down;
       
  1810             } else {
       
  1811                 {
       
  1812                     WindowPtr window = 0;
       
  1813                     if(GetEventParameter(event, kEventParamWindowRef, typeWindowRef, 0,
       
  1814                                          sizeof(window), 0, &window) != noErr)
       
  1815                         FindWindowOfClass(&where, kAllWindowClasses, &window, 0);
       
  1816                     if(window) {
       
  1817                         HIViewRef hiview;
       
  1818                         if(HIViewGetViewForMouseEvent(HIViewGetRoot(window), event, &hiview) == noErr) {
       
  1819                             widget = QWidget::find((WId)hiview);
       
  1820                             if (widget) {
       
  1821                                 // Make sure we didn't pass over a widget with a "fake hole" in it.
       
  1822                                 QWidget *otherWidget = QApplication::widgetAt(where.h, where.v);
       
  1823                                 if (otherWidget && otherWidget->testAttribute(Qt::WA_MouseNoMask))
       
  1824                                     widget = otherWidget;
       
  1825                             }
       
  1826                         }
       
  1827                     }
       
  1828                 }
       
  1829                 if(!widget) //fallback
       
  1830                     widget = QApplication::widgetAt(where.h, where.v);
       
  1831                 if(ekind == kEventMouseUp && widget) {
       
  1832                     short part = qt_mac_window_at(where.h, where.v);
       
  1833                     if(part == inDrag) {
       
  1834                         UInt32 count = 0;
       
  1835                         GetEventParameter(event, kEventParamClickCount, typeUInt32, NULL,
       
  1836                                           sizeof(count), NULL, &count);
       
  1837                         if(count == 2 && qt_mac_collapse_on_dblclick) {
       
  1838                             if (widget->macEvent(er, event))
       
  1839                                 return noErr;
       
  1840                             widget->setWindowState(widget->windowState() | Qt::WindowMinimized);
       
  1841                             //we send a hide to be like X11/Windows
       
  1842                             QEvent e(QEvent::Hide);
       
  1843                             QApplication::sendSpontaneousEvent(widget, &e);
       
  1844                             break;
       
  1845                         }
       
  1846                     }
       
  1847                 }
       
  1848             }
       
  1849         }
       
  1850         if (widget && widget->macEvent(er, event))
       
  1851             return noErr;
       
  1852         WindowPartCode wpc = qt_mac_window_at(where.h, where.v, 0);
       
  1853         if (wpc == inProxyIcon && modifiers == Qt::ControlModifier && buttons != Qt::NoButton) {
       
  1854             QIconDragEvent e;
       
  1855             QApplication::sendSpontaneousEvent(widget, &e);
       
  1856             if (e.isAccepted()) {
       
  1857                 return noErr; // IconDrag ate it.
       
  1858             }
       
  1859         }
       
  1860         if (inPopupMode == false
       
  1861                 && (qt_button_down == 0 || qt_button_down_in_content == false)
       
  1862                 && (wpc != inContent && wpc != inStructure)) {
       
  1863             inNonClientArea = true;
       
  1864             switch (etype) {
       
  1865             case QEvent::MouseButtonPress: {
       
  1866                 UInt32 count = 0;
       
  1867                 GetEventParameter(event, kEventParamClickCount, typeUInt32, 0,
       
  1868                                       sizeof(count), 0, &count);
       
  1869                 if(count % 2 || count == 0) {
       
  1870                     etype = QEvent::NonClientAreaMouseButtonPress;
       
  1871                 } else {
       
  1872                     etype = QEvent::NonClientAreaMouseButtonDblClick;
       
  1873                 }} break;
       
  1874             case QEvent::MouseButtonRelease:
       
  1875                 etype = QEvent::NonClientAreaMouseButtonRelease;
       
  1876                 break;
       
  1877             case QEvent::MouseMove:
       
  1878                 if (widget == 0 || widget->hasMouseTracking())
       
  1879                     etype = QEvent::NonClientAreaMouseMove;
       
  1880                 break;
       
  1881             default:
       
  1882                 break;
       
  1883             }
       
  1884         }
       
  1885 
       
  1886         if(qt_mac_find_window((FrontWindow()))) { //set the cursor up
       
  1887             QCursor cursor(Qt::ArrowCursor);
       
  1888             QWidget *cursor_widget = widget;
       
  1889             if(cursor_widget && cursor_widget == qt_button_down && ekind == kEventMouseUp)
       
  1890                 cursor_widget = QApplication::widgetAt(where.h, where.v);
       
  1891             if(cursor_widget) { //only over the app, do we set a cursor..
       
  1892                 if(!qApp->d_func()->cursor_list.isEmpty()) {
       
  1893                     cursor = qApp->d_func()->cursor_list.first();
       
  1894                 } else {
       
  1895                     for(; cursor_widget; cursor_widget = cursor_widget->parentWidget()) {
       
  1896                         QWExtra *extra = cursor_widget->d_func()->extraData();
       
  1897                         if(extra && extra->curs && cursor_widget->isEnabled()) {
       
  1898                             cursor = *extra->curs;
       
  1899                             break;
       
  1900                         }
       
  1901                     }
       
  1902                 }
       
  1903             }
       
  1904             qt_mac_set_cursor(&cursor, QPoint(where.h, where.v));
       
  1905         }
       
  1906 
       
  1907         //This mouse button state stuff looks like this on purpose
       
  1908         //although it looks hacky it is VERY intentional..
       
  1909         if(widget && app_do_modal && !qt_try_modal(widget, event)) {
       
  1910             if(ekind == kEventMouseDown && qt_mac_is_macsheet(QApplication::activeModalWidget()))
       
  1911                 QApplication::activeModalWidget()->parentWidget()->activateWindow(); //sheets have a parent
       
  1912             handled_event = false;
       
  1913 #if defined(DEBUG_MOUSE_MAPS)
       
  1914             qDebug("Bail out early due to qt_try_modal");
       
  1915 #endif
       
  1916             break;
       
  1917         }
       
  1918 
       
  1919         UInt32 tabletEventType = 0;
       
  1920         GetEventParameter(event, kEventParamTabletEventType, typeUInt32, 0,
       
  1921                           sizeof(tabletEventType), 0, &tabletEventType);
       
  1922         if (tabletEventType == kEventTabletPoint) {
       
  1923             TabletPointRec tabletPointRec;
       
  1924             GetEventParameter(event, kEventParamTabletPointRec, typeTabletPointRec, 0,
       
  1925                               sizeof(tabletPointRec), 0, &tabletPointRec);
       
  1926             QEvent::Type t = QEvent::TabletMove; //default
       
  1927             int new_tablet_button_state = tabletPointRec.buttons ? 1 : 0;
       
  1928             if (new_tablet_button_state != tablet_button_state)
       
  1929                 if (new_tablet_button_state)
       
  1930                     t = QEvent::TabletPress;
       
  1931                 else
       
  1932                     t = QEvent::TabletRelease;
       
  1933             tablet_button_state = new_tablet_button_state;
       
  1934 
       
  1935             QMacTabletHash *tabletHash = qt_mac_tablet_hash();
       
  1936             if (!tabletHash->contains(tabletPointRec.deviceID) && t != QEvent::TabletRelease) {
       
  1937                 // Never discard TabletRelease events as they may be delivered *after* TabletLeaveProximity events
       
  1938                 qWarning("handleTabletEvent: This tablet device is unknown"
       
  1939                          " (received no proximity event for it). Discarding event.");
       
  1940                 return false;
       
  1941             }
       
  1942             QTabletDeviceData &deviceData = tabletHash->operator[](tabletPointRec.deviceID);
       
  1943             if (t == QEvent::TabletPress) {
       
  1944                 deviceData.widgetToGetPress = widget;
       
  1945             } else if (t == QEvent::TabletRelease && deviceData.widgetToGetPress) {
       
  1946                 widget = deviceData.widgetToGetPress;
       
  1947                 deviceData.widgetToGetPress = 0;
       
  1948             }
       
  1949 
       
  1950             if (widget) {
       
  1951                 int tiltX = ((int)tabletPointRec.tiltX)/(32767/64); // 32K -> 60
       
  1952                 int tiltY = ((int)tabletPointRec.tiltY)/(-32767/64); // 32K -> 60
       
  1953                 HIPoint hiPoint;
       
  1954                 GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, 0, sizeof(HIPoint), 0, &hiPoint);
       
  1955                 QPointF hiRes(hiPoint.x, hiPoint.y);
       
  1956                 QPoint global(where.h, where.v);
       
  1957 
       
  1958 
       
  1959 
       
  1960                 QPoint local(widget->mapFromGlobal(global));
       
  1961                 int z = 0;
       
  1962                 qreal rotation = 0.0;
       
  1963                 qreal tp = 0.0;
       
  1964                 // Again from the Wacom.h header
       
  1965 
       
  1966                 if (deviceData.capabilityMask & 0x0200)     // Z-axis
       
  1967                     z = tabletPointRec.absZ;
       
  1968 
       
  1969                 if (deviceData.capabilityMask & 0x0800)  // Tangential pressure
       
  1970                     tp = tabletPointRec.tangentialPressure / 32767.0;
       
  1971 
       
  1972                 if (deviceData.capabilityMask & 0x2000) // Rotation
       
  1973                     rotation = qreal(tabletPointRec.rotation) / 64.0;
       
  1974 
       
  1975                 QTabletEvent e(t, local, global, hiRes, deviceData.tabletDeviceType,
       
  1976                                deviceData.tabletPointerType,
       
  1977                                qreal(tabletPointRec.pressure / qreal(0xffff)), tiltX, tiltY,
       
  1978                                tp, rotation, z, modifiers, deviceData.tabletUniqueID);
       
  1979                 QApplication::sendSpontaneousEvent(widget, &e);
       
  1980                 if (e.isAccepted()) {
       
  1981                     if (t == QEvent::TabletPress) {
       
  1982                         qt_button_down = widget;
       
  1983                     } else if (t == QEvent::TabletRelease) {
       
  1984                         qt_button_down = 0;
       
  1985                     }
       
  1986 #if defined(DEBUG_MOUSE_MAPS)
       
  1987                     qDebug("Bail out early due to tablet acceptance");
       
  1988 #endif
       
  1989                     break;
       
  1990                 }
       
  1991             }
       
  1992         }
       
  1993 
       
  1994         if(ekind == kEventMouseDown) {
       
  1995             qt_mac_no_click_through_mode = false;
       
  1996             const short windowPart = qt_mac_window_at(where.h, where.v, 0);
       
  1997             // Menubar almost always wins.
       
  1998             if (!inPopupMode && windowPart == inMenuBar) {
       
  1999                 MenuSelect(where); //allow menu tracking
       
  2000                 return noErr;
       
  2001             }
       
  2002 
       
  2003             if (widget && !(GetCurrentKeyModifiers() & cmdKey)) {
       
  2004                 extern bool qt_isGenuineQWidget(const QWidget *); // qwidget_mac.cpp
       
  2005                 QWidget *window = widget->window();
       
  2006                 bool genuineQtWidget = qt_isGenuineQWidget(widget);  // the widget, not the window.
       
  2007                 window->raise();
       
  2008 
       
  2009                 bool needActivate = (window->windowType() != Qt::Desktop)
       
  2010                                      && (window->windowType() != Qt::Popup)
       
  2011                                      && !qt_mac_is_macsheet(window);
       
  2012                 if (needActivate && (!window->isModal() && qobject_cast<QDockWidget *>(window)))
       
  2013                     needActivate = false;
       
  2014 
       
  2015                 if (genuineQtWidget && needActivate)
       
  2016                     needActivate = !window->isActiveWindow()
       
  2017                                     || !IsWindowActive(qt_mac_window_for(window));
       
  2018 
       
  2019                 if (needActivate) {
       
  2020                     window->activateWindow();
       
  2021                     if (!qt_mac_can_clickThrough(widget)) {
       
  2022                         qt_mac_no_click_through_mode = true;
       
  2023                         handled_event = false;
       
  2024 #if defined(DEBUG_MOUSE_MAPS)
       
  2025                         qDebug("Bail out early due to qt_mac_canClickThrough %s::%s", widget->metaObject()->className(),
       
  2026                                 widget->objectName().toLocal8Bit().constData());
       
  2027 #endif
       
  2028                         break;
       
  2029                     }
       
  2030                 }
       
  2031             }
       
  2032 
       
  2033             if(qt_mac_dblclick.last_widget &&
       
  2034                qt_mac_dblclick.last_x != -1 && qt_mac_dblclick.last_y != -1 &&
       
  2035                QRect(qt_mac_dblclick.last_x-2, qt_mac_dblclick.last_y-2, 4, 4).contains(QPoint(where.h, where.v))) {
       
  2036                 if(qt_mac_dblclick.use_qt_time_limit) {
       
  2037                     EventTime now = GetEventTime(event);
       
  2038                     if(qt_mac_dblclick.last_time != -2 && qt_mac_dblclick.last_widget == widget &&
       
  2039                        now - qt_mac_dblclick.last_time <= ((double)QApplicationPrivate::mouse_double_click_time)/1000 &&
       
  2040                        qt_mac_dblclick.last_button == button)
       
  2041                         etype = QEvent::MouseButtonDblClick;
       
  2042                 } else {
       
  2043                     UInt32 count = 0;
       
  2044                     GetEventParameter(event, kEventParamClickCount, typeUInt32, 0,
       
  2045                                       sizeof(count), 0, &count);
       
  2046                     if(!(count % 2) && qt_mac_dblclick.last_modifiers == modifiers &&
       
  2047                        qt_mac_dblclick.last_widget == widget && qt_mac_dblclick.last_button == button)
       
  2048                         etype = QEvent::MouseButtonDblClick;
       
  2049                 }
       
  2050                 if(etype == QEvent::MouseButtonDblClick)
       
  2051                     qt_mac_dblclick.last_widget = 0;
       
  2052             }
       
  2053             if(etype != QEvent::MouseButtonDblClick) {
       
  2054                 qt_mac_dblclick.last_x = where.h;
       
  2055                 qt_mac_dblclick.last_y = where.v;
       
  2056             } else {
       
  2057                 qt_mac_dblclick.last_x = qt_mac_dblclick.last_y = -1;
       
  2058             }
       
  2059         } else if(qt_mac_no_click_through_mode) {
       
  2060             if(ekind == kEventMouseUp)
       
  2061                 qt_mac_no_click_through_mode = false;
       
  2062             handled_event = false;
       
  2063 #if defined(DEBUG_MOUSE_MAPS)
       
  2064             qDebug("Bail out early due to qt_mac_no_click_through_mode");
       
  2065 #endif
       
  2066             break;
       
  2067         }
       
  2068 
       
  2069         QPointer<QWidget> leaveAfterRelease = 0;
       
  2070         switch(ekind) {
       
  2071         case kEventMouseUp:
       
  2072             if (!buttons) {
       
  2073                 if (!inPopupMode && !QWidget::mouseGrabber())
       
  2074                     leaveAfterRelease = qt_button_down;
       
  2075                 qt_button_down = 0;
       
  2076             }
       
  2077             break;
       
  2078         case kEventMouseDown: {
       
  2079             if (!qt_button_down)
       
  2080                 qt_button_down = widget;
       
  2081             WindowPartCode wpc = qt_mac_window_at(where.h, where.v, 0);
       
  2082             qt_button_down_in_content = (wpc == inContent || wpc == inStructure);
       
  2083             break;  }
       
  2084         }
       
  2085 
       
  2086         // Check if we should send enter/leave events:
       
  2087         switch(ekind) {
       
  2088         case kEventMouseDragged:
       
  2089         case kEventMouseMoved:
       
  2090         case kEventMouseUp:
       
  2091         case kEventMouseDown: {
       
  2092             // If we are in popup mode, widget will point to the current popup no matter
       
  2093             // where the mouse cursor is. In that case find out if the mouse cursor is
       
  2094             // really over the popup in order to send correct enter / leave envents.
       
  2095             QWidget * const enterLeaveWidget = (inPopupMode || ekind == kEventMouseUp) ?
       
  2096                     QApplication::widgetAt(where.h, where.v) :  static_cast<QWidget*>(widget);
       
  2097 
       
  2098             if ((QWidget *) qt_mouseover != enterLeaveWidget || inNonClientArea) {
       
  2099 #ifdef DEBUG_MOUSE_MAPS
       
  2100                 qDebug("Entering: %p - %s (%s), Leaving %s (%s)", (QWidget*)enterLeaveWidget,
       
  2101                        enterLeaveWidget ? enterLeaveWidget->metaObject()->className() : "none",
       
  2102                        enterLeaveWidget ? enterLeaveWidget->objectName().toLocal8Bit().constData() : "",
       
  2103                        qt_mouseover ? qt_mouseover->metaObject()->className() : "none",
       
  2104                        qt_mouseover ? qt_mouseover->objectName().toLocal8Bit().constData() : "");
       
  2105 #endif
       
  2106 
       
  2107                 QWidget * const mouseGrabber = QWidget::mouseGrabber();
       
  2108 
       
  2109                 if (inPopupMode) {
       
  2110                     QWidget *enter = enterLeaveWidget;
       
  2111                     QWidget *leave = qt_mouseover;
       
  2112                     if (mouseGrabber) {
       
  2113                         QWidget * const popupWidget = qApp->activePopupWidget();
       
  2114                         if (leave == popupWidget)
       
  2115                             enter = mouseGrabber;
       
  2116                         if (enter == popupWidget)
       
  2117                             leave = mouseGrabber;
       
  2118                         if ((enter == mouseGrabber && leave == popupWidget)
       
  2119                             || (leave == mouseGrabber  && enter == popupWidget)) {
       
  2120                             QApplicationPrivate::dispatchEnterLeave(enter, leave);
       
  2121                             qt_mouseover = enter;
       
  2122                         }
       
  2123                     } else {
       
  2124                         QApplicationPrivate::dispatchEnterLeave(enter, leave);
       
  2125                         qt_mouseover = enter;
       
  2126                     }
       
  2127                 } else if ((!qt_button_down || !qt_mouseover) && !mouseGrabber && !leaveAfterRelease) {
       
  2128                     QApplicationPrivate::dispatchEnterLeave(enterLeaveWidget, qt_mouseover);
       
  2129                     qt_mouseover = enterLeaveWidget;
       
  2130                 }
       
  2131             }
       
  2132             break; }
       
  2133         }
       
  2134 
       
  2135         if(widget) {
       
  2136             QPoint p(where.h, where.v);
       
  2137             QPoint plocal(widget->mapFromGlobal(p));
       
  2138             if(etype == QEvent::MouseButtonPress) {
       
  2139                 qt_mac_dblclick.last_widget = widget;
       
  2140                 qt_mac_dblclick.last_modifiers = modifiers;
       
  2141                 qt_mac_dblclick.last_button = button;
       
  2142                 qt_mac_dblclick.last_time = GetEventTime(event);
       
  2143             }
       
  2144 
       
  2145             if (wheel_deltaX || wheel_deltaY) {
       
  2146 #ifndef QT_NO_WHEELEVENT
       
  2147                 if (wheel_deltaX) {
       
  2148                     QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal);
       
  2149                     QApplication::sendSpontaneousEvent(widget, &qwe);
       
  2150                     if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
       
  2151                         QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
       
  2152                                 wheel_deltaX, buttons, modifiers, Qt::Horizontal);
       
  2153                         QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
       
  2154                         if (!qwe2.isAccepted())
       
  2155                             handled_event = false;
       
  2156                     }
       
  2157                 }
       
  2158                 if (wheel_deltaY) {
       
  2159                     QWheelEvent qwe(plocal, p, wheel_deltaY, buttons, modifiers, Qt::Vertical);
       
  2160                     QApplication::sendSpontaneousEvent(widget, &qwe);
       
  2161                     if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
       
  2162                         QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
       
  2163                                 wheel_deltaY, buttons, modifiers, Qt::Vertical);
       
  2164                         QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
       
  2165                         if (!qwe2.isAccepted())
       
  2166                             handled_event = false;
       
  2167                     }
       
  2168                 }
       
  2169 #endif // QT_NO_WHEELEVENT
       
  2170             } else {
       
  2171 #ifdef QMAC_SPEAK_TO_ME
       
  2172                 const int speak_keys = Qt::AltModifier | Qt::ShiftModifier;
       
  2173 		if(etype == QMouseEvent::MouseButtonDblClick && ((modifiers & speak_keys) == speak_keys)) {
       
  2174                     QVariant v = widget->property("displayText");
       
  2175                     if(!v.isValid()) v = widget->property("text");
       
  2176                     if(!v.isValid()) v = widget->property("windowTitle");
       
  2177                     if(v.isValid()) {
       
  2178                         QString s = v.toString();
       
  2179                         s.replace(QRegExp(QString::fromLatin1("(\\&|\\<[^\\>]*\\>)")), QLatin1String(""));
       
  2180                         SpeechChannel ch;
       
  2181                         NewSpeechChannel(0, &ch);
       
  2182                         SpeakText(ch, s.toLatin1().constData(), s.length());
       
  2183                         DisposeSpeechChannel(ch);
       
  2184                     }
       
  2185                 }
       
  2186 #endif
       
  2187                 Qt::MouseButton buttonToSend = button;
       
  2188                 static bool lastButtonTranslated = false;
       
  2189                 if(ekind == kEventMouseDown &&
       
  2190                    button == Qt::LeftButton && (modifiers & Qt::MetaModifier)) {
       
  2191                     buttonToSend = Qt::RightButton;
       
  2192                     lastButtonTranslated = true;
       
  2193                 } else if(ekind == kEventMouseUp && lastButtonTranslated) {
       
  2194                     buttonToSend = Qt::RightButton;
       
  2195                     lastButtonTranslated = false;
       
  2196                 }
       
  2197                 QMouseEvent qme(etype, plocal, p, buttonToSend, buttons, modifiers);
       
  2198                 QApplication::sendSpontaneousEvent(widget, &qme);
       
  2199                 if(!qme.isAccepted() || inNonClientArea)
       
  2200                     handled_event = false;
       
  2201             }
       
  2202 
       
  2203             if (leaveAfterRelease) {
       
  2204                 QWidget *enter = QApplication::widgetAt(where.h, where.v);
       
  2205                 QApplicationPrivate::dispatchEnterLeave(enter, leaveAfterRelease);
       
  2206                 qt_mouseover = enter;
       
  2207                 leaveAfterRelease = 0;
       
  2208             }
       
  2209 
       
  2210             if(ekind == kEventMouseDown &&
       
  2211                ((button == Qt::RightButton) ||
       
  2212                 (button == Qt::LeftButton && (modifiers & Qt::MetaModifier))))
       
  2213                 qt_event_request_context();
       
  2214 
       
  2215 #ifdef DEBUG_MOUSE_MAPS
       
  2216             const char *event_desc = edesc;
       
  2217             if(etype == QEvent::MouseButtonDblClick)
       
  2218                 event_desc = "Double Click";
       
  2219             else if(etype == QEvent::NonClientAreaMouseButtonPress)
       
  2220                 event_desc = "NonClientMousePress";
       
  2221             else if(etype == QEvent::NonClientAreaMouseButtonRelease)
       
  2222                 event_desc = "NonClientMouseRelease";
       
  2223             else if(etype == QEvent::NonClientAreaMouseMove)
       
  2224                 event_desc = "NonClientMouseMove";
       
  2225             else if(etype == QEvent::NonClientAreaMouseButtonDblClick)
       
  2226                 event_desc = "NonClientMouseDblClick";
       
  2227             qDebug("%d %d (%d %d) - Would send (%s) event to %p %s %s (%d 0x%08x 0x%08x %d)", p.x(), p.y(),
       
  2228                    plocal.x(), plocal.y(), event_desc, (QWidget*)widget,
       
  2229                    widget ? widget->objectName().toLocal8Bit().constData() : "*Unknown*",
       
  2230                    widget ? widget->metaObject()->className() : "*Unknown*",
       
  2231                    button, (int)buttons, (int)modifiers, wheel_deltaX);
       
  2232 #endif
       
  2233         } else {
       
  2234             handled_event = false;
       
  2235         }
       
  2236         break;
       
  2237     }
       
  2238     case kEventClassTextInput:
       
  2239     case kEventClassKeyboard: {
       
  2240         EventRef key_event = event;
       
  2241         if(eclass == kEventClassTextInput) {
       
  2242             Q_ASSERT(ekind == kEventTextInputUnicodeForKeyEvent);
       
  2243             OSStatus err = GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, 0,
       
  2244                                              sizeof(key_event), 0, &key_event);
       
  2245             Q_ASSERT(err == noErr);
       
  2246             Q_UNUSED(err);
       
  2247         }
       
  2248         const UInt32 key_ekind = GetEventKind(key_event);
       
  2249         Q_ASSERT(GetEventClass(key_event) == kEventClassKeyboard);
       
  2250 
       
  2251         if(key_ekind == kEventRawKeyDown)
       
  2252             qt_keymapper_private()->updateKeyMap(er, key_event, data);
       
  2253         if(mac_keyboard_grabber)
       
  2254             widget = mac_keyboard_grabber;
       
  2255         else if (app->activePopupWidget())
       
  2256             widget = (app->activePopupWidget()->focusWidget() ?
       
  2257                       app->activePopupWidget()->focusWidget() : app->activePopupWidget());
       
  2258         else if(QApplication::focusWidget())
       
  2259             widget = QApplication::focusWidget();
       
  2260         else
       
  2261             widget = app->activeWindow();
       
  2262 
       
  2263         if (widget) {
       
  2264             if (widget->macEvent(er, event))
       
  2265                 return noErr;
       
  2266         } else {
       
  2267             // Darn, I need to update tho modifier state, even though
       
  2268             // Qt itself isn't getting them, otherwise the keyboard state get inconsistent.
       
  2269             if (key_ekind == kEventRawKeyModifiersChanged) {
       
  2270                 UInt32 modifiers = 0;
       
  2271                 GetEventParameter(key_event, kEventParamKeyModifiers, typeUInt32, 0,
       
  2272                                   sizeof(modifiers), 0, &modifiers);
       
  2273                 extern void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object); // qkeymapper_mac.cpp
       
  2274                 // Just send it to the qApp for the time being.
       
  2275                 qt_mac_send_modifiers_changed(modifiers, qApp);
       
  2276             }
       
  2277             handled_event = false;
       
  2278             break;
       
  2279         }
       
  2280 
       
  2281         if(app_do_modal && !qt_try_modal(widget, key_event))
       
  2282             break;
       
  2283         if (eclass == kEventClassTextInput) {
       
  2284             handled_event = false;
       
  2285         } else {
       
  2286             handled_event = qt_keymapper_private()->translateKeyEvent(widget, er, key_event, data,
       
  2287                                                                       widget == mac_keyboard_grabber);
       
  2288         }
       
  2289         break; }
       
  2290     case kEventClassWindow: {
       
  2291         WindowRef wid = 0;
       
  2292         GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0,
       
  2293                           sizeof(WindowRef), 0, &wid);
       
  2294         widget = qt_mac_find_window(wid);
       
  2295         if (widget && widget->macEvent(er, event))
       
  2296             return noErr;
       
  2297         if(ekind == kEventWindowActivated) {
       
  2298             if(QApplicationPrivate::app_style) {
       
  2299                 QEvent ev(QEvent::Style);
       
  2300                 QApplication::sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
       
  2301             }
       
  2302 
       
  2303             if(widget && app_do_modal && !qt_try_modal(widget, event))
       
  2304                 break;
       
  2305 
       
  2306             if(widget && widget->window()->isVisible()) {
       
  2307                 QWidget *tlw = widget->window();
       
  2308 		if(tlw->isWindow() && !(tlw->windowType() == Qt::Popup)
       
  2309                    && !qt_mac_is_macdrawer(tlw)
       
  2310                    && (!tlw->parentWidget() || tlw->isModal()
       
  2311                        || !(tlw->windowType() == Qt::Tool))) {
       
  2312                     bool just_send_event = false;
       
  2313                     {
       
  2314                         WindowActivationScope scope;
       
  2315                         if(GetWindowActivationScope((WindowRef)wid, &scope) == noErr &&
       
  2316                            scope == kWindowActivationScopeIndependent) {
       
  2317                             if(GetFrontWindowOfClass(kAllWindowClasses, true) != wid)
       
  2318                                 just_send_event = true;
       
  2319                         }
       
  2320                     }
       
  2321                     if(just_send_event) {
       
  2322                         QEvent e(QEvent::WindowActivate);
       
  2323                         QApplication::sendSpontaneousEvent(widget, &e);
       
  2324                     } else {
       
  2325                         app->setActiveWindow(tlw);
       
  2326                     }
       
  2327                 }
       
  2328                 QMenuBar::macUpdateMenuBar();
       
  2329             }
       
  2330         } else if(ekind == kEventWindowDeactivated) {
       
  2331             if(widget && QApplicationPrivate::active_window == widget)
       
  2332                 app->setActiveWindow(0);
       
  2333         } else {
       
  2334             handled_event = false;
       
  2335         }
       
  2336         break; }
       
  2337     case kEventClassApplication:
       
  2338         if(ekind == kEventAppActivated) {
       
  2339             if(QApplication::desktopSettingsAware())
       
  2340                 qt_mac_update_os_settings();
       
  2341             if(qt_clipboard) { //manufacture an event so the clipboard can see if it has changed
       
  2342                 QEvent ev(QEvent::Clipboard);
       
  2343                 QApplication::sendSpontaneousEvent(qt_clipboard, &ev);
       
  2344             }
       
  2345             if(app) {
       
  2346                 QEvent ev(QEvent::ApplicationActivate);
       
  2347                 QApplication::sendSpontaneousEvent(app, &ev);
       
  2348             }
       
  2349             if(!app->activeWindow()) {
       
  2350                 WindowPtr wp = ActiveNonFloatingWindow();
       
  2351                 if(QWidget *tmp_w = qt_mac_find_window(wp))
       
  2352                     app->setActiveWindow(tmp_w);
       
  2353             }
       
  2354             QMenuBar::macUpdateMenuBar();
       
  2355         } else if(ekind == kEventAppDeactivated) {
       
  2356             //qt_mac_no_click_through_mode = false;
       
  2357             while(app->d_func()->inPopupMode())
       
  2358                 app->activePopupWidget()->close();
       
  2359             if(app) {
       
  2360                 QEvent ev(QEvent::ApplicationDeactivate);
       
  2361                 QApplication::sendSpontaneousEvent(app, &ev);
       
  2362             }
       
  2363             app->setActiveWindow(0);
       
  2364         } else if(ekind == kEventAppAvailableWindowBoundsChanged) {
       
  2365             QDesktopWidgetImplementation::instance()->onResize();
       
  2366         } else {
       
  2367             handled_event = false;
       
  2368         }
       
  2369         break;
       
  2370     case kAppearanceEventClass:
       
  2371         if(ekind == kAEAppearanceChanged) {
       
  2372             if(QApplication::desktopSettingsAware())
       
  2373                 qt_mac_update_os_settings();
       
  2374             if(QApplicationPrivate::app_style) {
       
  2375                 QEvent ev(QEvent::Style);
       
  2376                 QApplication::sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
       
  2377             }
       
  2378         } else {
       
  2379             handled_event = false;
       
  2380         }
       
  2381         break;
       
  2382     case kEventClassAppleEvent:
       
  2383         if(ekind == kEventAppleEvent) {
       
  2384             EventRecord erec;
       
  2385             if(!ConvertEventRefToEventRecord(event, &erec))
       
  2386                 qDebug("Qt: internal: WH0A, unexpected condition reached. %s:%d", __FILE__, __LINE__);
       
  2387             else if(AEProcessAppleEvent(&erec) != noErr)
       
  2388                 handled_event = false;
       
  2389         } else {
       
  2390             handled_event = false;
       
  2391         }
       
  2392         break;
       
  2393     case kEventClassCommand:
       
  2394         if(ekind == kEventCommandProcess) {
       
  2395             HICommand cmd;
       
  2396             GetEventParameter(event, kEventParamDirectObject, typeHICommand,
       
  2397                               0, sizeof(cmd), 0, &cmd);
       
  2398             handled_event = false;
       
  2399             if(!cmd.menu.menuRef && GetApplicationDockTileMenu()) {
       
  2400                 EventRef copy = CopyEvent(event);
       
  2401                 HICommand copy_cmd;
       
  2402                 GetEventParameter(event, kEventParamDirectObject, typeHICommand,
       
  2403                                   0, sizeof(copy_cmd), 0, &copy_cmd);
       
  2404                 copy_cmd.menu.menuRef = GetApplicationDockTileMenu();
       
  2405                 SetEventParameter(copy, kEventParamDirectObject, typeHICommand, sizeof(copy_cmd), &copy_cmd);
       
  2406                 if(SendEventToMenu(copy, copy_cmd.menu.menuRef) == noErr)
       
  2407                     handled_event = true;
       
  2408             }
       
  2409             if(!handled_event) {
       
  2410                 if(cmd.commandID == kHICommandQuit) {
       
  2411                     handled_event = true;
       
  2412                     HiliteMenu(0);
       
  2413                     bool handle_quit = true;
       
  2414                     if(QApplicationPrivate::modalState()) {
       
  2415                         int visible = 0;
       
  2416                         const QWidgetList tlws = QApplication::topLevelWidgets();
       
  2417                         for(int i = 0; i < tlws.size(); ++i) {
       
  2418                             if(tlws.at(i)->isVisible())
       
  2419                                 ++visible;
       
  2420                         }
       
  2421                         handle_quit = (visible <= 1);
       
  2422                     }
       
  2423                     if(handle_quit) {
       
  2424                         QCloseEvent ev;
       
  2425                         QApplication::sendSpontaneousEvent(app, &ev);
       
  2426                         if(ev.isAccepted())
       
  2427                             app->quit();
       
  2428                     } else {
       
  2429                         QApplication::beep();
       
  2430                     }
       
  2431                 } else if(cmd.commandID == kHICommandSelectWindow) {
       
  2432                     if((GetCurrentKeyModifiers() & cmdKey))
       
  2433                         handled_event = true;
       
  2434                 } else if(cmd.commandID == kHICommandAbout) {
       
  2435                     QMessageBox::aboutQt(0);
       
  2436                     HiliteMenu(0);
       
  2437                     handled_event = true;
       
  2438                 }
       
  2439             }
       
  2440         }
       
  2441         break;
       
  2442     }
       
  2443 
       
  2444 #ifdef DEBUG_EVENTS
       
  2445     qDebug("%shandled event %c%c%c%c %d", handled_event ? "(*) " : "",
       
  2446            char(eclass >> 24), char((eclass >> 16) & 255), char((eclass >> 8) & 255),
       
  2447            char(eclass & 255), (int)ekind);
       
  2448 #endif
       
  2449     if(!handled_event) //let the event go through
       
  2450         return eventNotHandledErr;
       
  2451     return noErr; //we eat the event
       
  2452 #else
       
  2453     Q_UNUSED(er);
       
  2454     Q_UNUSED(event);
       
  2455     Q_UNUSED(data);
       
  2456     return eventNotHandledErr;
       
  2457 #endif
       
  2458 }
       
  2459 
       
  2460 // In Carbon this is your one stop for apple events.
       
  2461 // In Cocoa, it ISN'T. This is the catch-all Apple Event handler that exists
       
  2462 // for the time between instantiating the NSApplication, but before the
       
  2463 // NSApplication has installed it's OWN Apple Event handler. When Cocoa has
       
  2464 // that set up, we remove this.  So, if you are debugging problems, you likely
       
  2465 // want to check out QCocoaApplicationDelegate instead.
       
  2466 OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, AppleEvent *, long handlerRefcon)
       
  2467 {
       
  2468     QApplication *app = (QApplication *)handlerRefcon;
       
  2469     bool handled_event=false;
       
  2470     OSType aeID=typeWildCard, aeClass=typeWildCard;
       
  2471     AEGetAttributePtr(ae, keyEventClassAttr, typeType, 0, &aeClass, sizeof(aeClass), 0);
       
  2472     AEGetAttributePtr(ae, keyEventIDAttr, typeType, 0, &aeID, sizeof(aeID), 0);
       
  2473     if(aeClass == kCoreEventClass) {
       
  2474         switch(aeID) {
       
  2475         case kAEQuitApplication: {
       
  2476             extern bool qt_mac_quit_menu_item_enabled; // qmenu_mac.cpp
       
  2477             if (qt_mac_quit_menu_item_enabled) {
       
  2478                 QCloseEvent ev;
       
  2479                 QApplication::sendSpontaneousEvent(app, &ev);
       
  2480                 if(ev.isAccepted()) {
       
  2481                     handled_event = true;
       
  2482                     app->quit();
       
  2483                 }
       
  2484             } else {
       
  2485                 QApplication::beep();  // Sorry, you can't quit right now.
       
  2486             }
       
  2487             break; }
       
  2488         case kAEOpenDocuments: {
       
  2489             AEDescList docs;
       
  2490             if(AEGetParamDesc(ae, keyDirectObject, typeAEList, &docs) == noErr) {
       
  2491                 long cnt = 0;
       
  2492                 AECountItems(&docs, &cnt);
       
  2493                 UInt8 *str_buffer = NULL;
       
  2494                 for(int i = 0; i < cnt; i++) {
       
  2495                     FSRef ref;
       
  2496                     if(AEGetNthPtr(&docs, i+1, typeFSRef, 0, 0, &ref, sizeof(ref), 0) != noErr)
       
  2497                         continue;
       
  2498                     if(!str_buffer)
       
  2499                         str_buffer = (UInt8 *)malloc(1024);
       
  2500                     FSRefMakePath(&ref, str_buffer, 1024);
       
  2501                     QFileOpenEvent ev(QString::fromUtf8((const char *)str_buffer));
       
  2502                     QApplication::sendSpontaneousEvent(app, &ev);
       
  2503                 }
       
  2504                 if(str_buffer)
       
  2505                     free(str_buffer);
       
  2506             }
       
  2507             break; }
       
  2508         default:
       
  2509             break;
       
  2510         }
       
  2511     } else if (aeClass == kInternetEventClass) {
       
  2512         switch (aeID) {
       
  2513         case kAEGetURL: {
       
  2514             char urlData[1024];
       
  2515             Size actualSize;
       
  2516             if (AEGetParamPtr(ae, keyDirectObject, typeChar, 0, urlData,
       
  2517                     sizeof(urlData) - 1, &actualSize) == noErr) {
       
  2518                 urlData[actualSize] = 0;
       
  2519                 QFileOpenEvent ev(QUrl(QString::fromUtf8(urlData)));
       
  2520                 QApplication::sendSpontaneousEvent(app, &ev);
       
  2521             }
       
  2522             break;
       
  2523         }
       
  2524         default:
       
  2525             break;
       
  2526         }
       
  2527     }
       
  2528 #ifdef DEBUG_EVENTS
       
  2529     qDebug("Qt: internal: %shandled Apple event! %c%c%c%c %c%c%c%c", handled_event ? "(*)" : "",
       
  2530            char(aeID >> 24), char((aeID >> 16) & 255), char((aeID >> 8) & 255),char(aeID & 255),
       
  2531            char(aeClass >> 24), char((aeClass >> 16) & 255), char((aeClass >> 8) & 255),char(aeClass & 255));
       
  2532 #else
       
  2533     if(!handled_event) //let the event go through
       
  2534         return eventNotHandledErr;
       
  2535     return noErr; //we eat the event
       
  2536 #endif
       
  2537 }
       
  2538 
       
  2539 /*!
       
  2540     \fn bool QApplication::macEventFilter(EventHandlerCallRef caller, EventRef event)
       
  2541 
       
  2542     \warning This virtual function is only implemented under Mac OS X when against Carbon.
       
  2543 
       
  2544     If you create an application that inherits QApplication and reimplement
       
  2545     this function, you get direct access to all Carbon Events that Qt registers
       
  2546     for from Mac OS X with this function being called with the \a caller and
       
  2547     the \a event.
       
  2548 
       
  2549     Return true if you want to stop the event from being processed.
       
  2550     Return false for normal event dispatching. The default
       
  2551     implementation returns false.
       
  2552 
       
  2553     Cocoa uses a different event system which means this function is NOT CALLED
       
  2554     when building Qt against Cocoa. If you want similar functionality subclass
       
  2555     NSApplication and reimplement the sendEvent: message to handle all the
       
  2556     NSEvents. You also will need to to instantiate your custom NSApplication
       
  2557     before creating a QApplication. See \l
       
  2558     {http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSApplication_Class/Reference/Reference.html}{Apple's
       
  2559     NSApplication Reference} for more information.
       
  2560 
       
  2561 */
       
  2562 bool QApplication::macEventFilter(EventHandlerCallRef, EventRef)
       
  2563 {
       
  2564     return false;
       
  2565 }
       
  2566 
       
  2567 /*!
       
  2568     \internal
       
  2569 */
       
  2570 void QApplicationPrivate::openPopup(QWidget *popup)
       
  2571 {
       
  2572     if (!QApplicationPrivate::popupWidgets)                        // create list
       
  2573         QApplicationPrivate::popupWidgets = new QWidgetList;
       
  2574     QApplicationPrivate::popupWidgets->append(popup);                // add to end of list
       
  2575 
       
  2576     // popups are not focus-handled by the window system (the first
       
  2577     // popup grabbed the keyboard), so we have to do that manually: A
       
  2578     // new popup gets the focus
       
  2579     if (popup->focusWidget()) {
       
  2580         popup->focusWidget()->setFocus(Qt::PopupFocusReason);
       
  2581     } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
       
  2582         popup->setFocus(Qt::PopupFocusReason);
       
  2583     }
       
  2584 }
       
  2585 
       
  2586 /*!
       
  2587     \internal
       
  2588 */
       
  2589 void QApplicationPrivate::closePopup(QWidget *popup)
       
  2590 {
       
  2591     Q_Q(QApplication);
       
  2592     if (!QApplicationPrivate::popupWidgets)
       
  2593         return;
       
  2594 
       
  2595     QApplicationPrivate::popupWidgets->removeAll(popup);
       
  2596     if (popup == qt_button_down)
       
  2597         qt_button_down = 0;
       
  2598     if (QApplicationPrivate::popupWidgets->isEmpty()) {  // this was the last popup
       
  2599         delete QApplicationPrivate::popupWidgets;
       
  2600         QApplicationPrivate::popupWidgets = 0;
       
  2601 
       
  2602         // Special case for Tool windows: since they are activated and deactived together
       
  2603         // with a normal window they never become the QApplicationPrivate::active_window.
       
  2604         QWidget *appFocusWidget = QApplication::focusWidget();
       
  2605         if (appFocusWidget && appFocusWidget->window()->windowType() == Qt::Tool) {
       
  2606             appFocusWidget->setFocus(Qt::PopupFocusReason);
       
  2607         } else if (QApplicationPrivate::active_window) {
       
  2608             if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
       
  2609                 if (fw != QApplication::focusWidget()) {
       
  2610                     fw->setFocus(Qt::PopupFocusReason);
       
  2611                 } else {
       
  2612                     QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
       
  2613                     q->sendEvent(fw, &e);
       
  2614                 }
       
  2615             }
       
  2616         }
       
  2617     } else {
       
  2618         // popups are not focus-handled by the window system (the
       
  2619         // first popup grabbed the keyboard), so we have to do that
       
  2620         // manually: A popup was closed, so the previous popup gets
       
  2621         // the focus.
       
  2622         QWidget* aw = QApplicationPrivate::popupWidgets->last();
       
  2623         if (QWidget *fw = aw->focusWidget())
       
  2624             fw->setFocus(Qt::PopupFocusReason);
       
  2625     }
       
  2626 }
       
  2627 
       
  2628 void QApplication::beep()
       
  2629 {
       
  2630     qt_mac_beep();
       
  2631 }
       
  2632 
       
  2633 void QApplication::alert(QWidget *widget, int duration)
       
  2634 {
       
  2635     if (!QApplicationPrivate::checkInstance("alert"))
       
  2636         return;
       
  2637 
       
  2638     QWidgetList windowsToMark;
       
  2639     if (!widget)
       
  2640         windowsToMark += topLevelWidgets();
       
  2641     else
       
  2642         windowsToMark.append(widget->window());
       
  2643 
       
  2644     bool needNotification = false;
       
  2645     for (int i = 0; i < windowsToMark.size(); ++i) {
       
  2646         QWidget *window = windowsToMark.at(i);
       
  2647         if (!window->isActiveWindow() && window->isVisible()) {
       
  2648             needNotification = true; // yeah, we may set it multiple times, but that's OK.
       
  2649             if (duration != 0) {
       
  2650                QTimer *timer = new QTimer(qApp);
       
  2651                timer->setSingleShot(true);
       
  2652                connect(timer, SIGNAL(timeout()), qApp, SLOT(_q_alertTimeOut()));
       
  2653                if (QTimer *oldTimer = qApp->d_func()->alertTimerHash.value(widget)) {
       
  2654                    qApp->d_func()->alertTimerHash.remove(widget);
       
  2655                    delete oldTimer;
       
  2656                }
       
  2657                qApp->d_func()->alertTimerHash.insert(widget, timer);
       
  2658                timer->start(duration);
       
  2659             }
       
  2660         }
       
  2661     }
       
  2662     if (needNotification)
       
  2663         qt_mac_send_notification();
       
  2664 }
       
  2665 
       
  2666 void QApplicationPrivate::_q_alertTimeOut()
       
  2667 {
       
  2668     if (QTimer *timer = qobject_cast<QTimer *>(q_func()->sender())) {
       
  2669         QHash<QWidget *, QTimer *>::iterator it = alertTimerHash.begin();
       
  2670         while (it != alertTimerHash.end()) {
       
  2671             if (it.value() == timer) {
       
  2672                 alertTimerHash.erase(it);
       
  2673                 timer->deleteLater();
       
  2674                 break;
       
  2675             }
       
  2676             ++it;
       
  2677         }
       
  2678         if (alertTimerHash.isEmpty()) {
       
  2679             qt_mac_cancel_notification();
       
  2680         }
       
  2681     }
       
  2682 }
       
  2683 
       
  2684 void  QApplication::setCursorFlashTime(int msecs)
       
  2685 {
       
  2686     QApplicationPrivate::cursor_flash_time = msecs;
       
  2687 }
       
  2688 
       
  2689 int QApplication::cursorFlashTime()
       
  2690 {
       
  2691     return QApplicationPrivate::cursor_flash_time;
       
  2692 }
       
  2693 
       
  2694 void QApplication::setDoubleClickInterval(int ms)
       
  2695 {
       
  2696     qt_mac_dblclick.use_qt_time_limit = true;
       
  2697     QApplicationPrivate::mouse_double_click_time = ms;
       
  2698 }
       
  2699 
       
  2700 int QApplication::doubleClickInterval()
       
  2701 {
       
  2702     if (!qt_mac_dblclick.use_qt_time_limit) { //get it from the system
       
  2703         QSettings appleSettings(QLatin1String("apple.com"));
       
  2704         /* First worked as of 10.3.3 */
       
  2705         double dci = appleSettings.value(QLatin1String("com/apple/mouse/doubleClickThreshold"), 0.5).toDouble();
       
  2706         return int(dci * 1000);
       
  2707     }
       
  2708     return QApplicationPrivate::mouse_double_click_time;
       
  2709 }
       
  2710 
       
  2711 void QApplication::setKeyboardInputInterval(int ms)
       
  2712 {
       
  2713     QApplicationPrivate::keyboard_input_time = ms;
       
  2714 }
       
  2715 
       
  2716 int QApplication::keyboardInputInterval()
       
  2717 {
       
  2718     // FIXME: get from the system
       
  2719     return QApplicationPrivate::keyboard_input_time;
       
  2720 }
       
  2721 
       
  2722 #ifndef QT_NO_WHEELEVENT
       
  2723 void QApplication::setWheelScrollLines(int n)
       
  2724 {
       
  2725     QApplicationPrivate::wheel_scroll_lines = n;
       
  2726 }
       
  2727 
       
  2728 int QApplication::wheelScrollLines()
       
  2729 {
       
  2730     return QApplicationPrivate::wheel_scroll_lines;
       
  2731 }
       
  2732 #endif
       
  2733 
       
  2734 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
       
  2735 {
       
  2736     switch (effect) {
       
  2737     case Qt::UI_FadeMenu:
       
  2738         QApplicationPrivate::fade_menu = enable;
       
  2739         break;
       
  2740     case Qt::UI_AnimateMenu:
       
  2741         QApplicationPrivate::animate_menu = enable;
       
  2742         break;
       
  2743     case Qt::UI_FadeTooltip:
       
  2744         QApplicationPrivate::fade_tooltip = enable;
       
  2745         break;
       
  2746     case Qt::UI_AnimateTooltip:
       
  2747         QApplicationPrivate::animate_tooltip = enable;
       
  2748         break;
       
  2749     case Qt::UI_AnimateCombo:
       
  2750         QApplicationPrivate::animate_combo = enable;
       
  2751         break;
       
  2752     case Qt::UI_AnimateToolBox:
       
  2753         QApplicationPrivate::animate_toolbox = enable;
       
  2754         break;
       
  2755     case Qt::UI_General:
       
  2756         QApplicationPrivate::fade_tooltip = true;
       
  2757         break;
       
  2758     default:
       
  2759         QApplicationPrivate::animate_ui = enable;
       
  2760         break;
       
  2761     }
       
  2762 
       
  2763     if (enable)
       
  2764         QApplicationPrivate::animate_ui = true;
       
  2765 }
       
  2766 
       
  2767 bool QApplication::isEffectEnabled(Qt::UIEffect effect)
       
  2768 {
       
  2769     if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
       
  2770         return false;
       
  2771 
       
  2772     switch(effect) {
       
  2773     case Qt::UI_AnimateMenu:
       
  2774         return QApplicationPrivate::animate_menu;
       
  2775     case Qt::UI_FadeMenu:
       
  2776         return QApplicationPrivate::fade_menu;
       
  2777     case Qt::UI_AnimateCombo:
       
  2778         return QApplicationPrivate::animate_combo;
       
  2779     case Qt::UI_AnimateTooltip:
       
  2780         return QApplicationPrivate::animate_tooltip;
       
  2781     case Qt::UI_FadeTooltip:
       
  2782         return QApplicationPrivate::fade_tooltip;
       
  2783     case Qt::UI_AnimateToolBox:
       
  2784         return QApplicationPrivate::animate_toolbox;
       
  2785     default:
       
  2786         break;
       
  2787     }
       
  2788     return QApplicationPrivate::animate_ui;
       
  2789 }
       
  2790 
       
  2791 /*!
       
  2792     \internal
       
  2793 */
       
  2794 bool QApplicationPrivate::qt_mac_apply_settings()
       
  2795 {
       
  2796     QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
       
  2797     settings.beginGroup(QLatin1String("Qt"));
       
  2798 
       
  2799     /*
       
  2800       Qt settings.  This is how they are written into the datastream.
       
  2801       Palette/ *             - QPalette
       
  2802       font                   - QFont
       
  2803       libraryPath            - QStringList
       
  2804       style                  - QString
       
  2805       doubleClickInterval    - int
       
  2806       cursorFlashTime        - int
       
  2807       wheelScrollLines       - int
       
  2808       colorSpec              - QString
       
  2809       defaultCodec           - QString
       
  2810       globalStrut/width      - int
       
  2811       globalStrut/height     - int
       
  2812       GUIEffects             - QStringList
       
  2813       Font Substitutions/ *  - QStringList
       
  2814       Font Substitutions/... - QStringList
       
  2815     */
       
  2816 
       
  2817     // read library (ie. plugin) path list
       
  2818     QString libpathkey =
       
  2819         QString::fromLatin1("%1.%2/libraryPath")
       
  2820                     .arg(QT_VERSION >> 16)
       
  2821                     .arg((QT_VERSION & 0xff00) >> 8);
       
  2822     QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
       
  2823     if (!pathlist.isEmpty()) {
       
  2824         QStringList::ConstIterator it = pathlist.begin();
       
  2825         while(it != pathlist.end())
       
  2826             QApplication::addLibraryPath(*it++);
       
  2827     }
       
  2828 
       
  2829     QString defaultcodec = settings.value(QLatin1String("defaultCodec"), QVariant(QLatin1String("none"))).toString();
       
  2830     if (defaultcodec != QLatin1String("none")) {
       
  2831         QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1().constData());
       
  2832         if (codec)
       
  2833             QTextCodec::setCodecForTr(codec);
       
  2834     }
       
  2835 
       
  2836     if (qt_is_gui_used) {
       
  2837         QString str;
       
  2838         QStringList strlist;
       
  2839         int num;
       
  2840 
       
  2841         // read new palette
       
  2842         int i;
       
  2843         QPalette pal(QApplication::palette());
       
  2844         strlist = settings.value(QLatin1String("Palette/active")).toStringList();
       
  2845         if (strlist.count() == QPalette::NColorRoles) {
       
  2846             for (i = 0; i < QPalette::NColorRoles; i++)
       
  2847                 pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
       
  2848                             QColor(strlist[i]));
       
  2849         }
       
  2850         strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
       
  2851         if (strlist.count() == QPalette::NColorRoles) {
       
  2852             for (i = 0; i < QPalette::NColorRoles; i++)
       
  2853                 pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
       
  2854                             QColor(strlist[i]));
       
  2855         }
       
  2856         strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
       
  2857         if (strlist.count() == QPalette::NColorRoles) {
       
  2858             for (i = 0; i < QPalette::NColorRoles; i++)
       
  2859                 pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
       
  2860                             QColor(strlist[i]));
       
  2861         }
       
  2862 
       
  2863         if (pal != QApplication::palette())
       
  2864             QApplication::setPalette(pal);
       
  2865 
       
  2866         // read new font
       
  2867         QFont font(QApplication::font());
       
  2868         str = settings.value(QLatin1String("font")).toString();
       
  2869         if (!str.isEmpty()) {
       
  2870             font.fromString(str);
       
  2871             if (font != QApplication::font())
       
  2872                 QApplication::setFont(font);
       
  2873         }
       
  2874 
       
  2875         // read new QStyle
       
  2876         QString stylename = settings.value(QLatin1String("style")).toString();
       
  2877         if (! stylename.isNull() && ! stylename.isEmpty()) {
       
  2878             QStyle *style = QStyleFactory::create(stylename);
       
  2879             if (style)
       
  2880                 QApplication::setStyle(style);
       
  2881             else
       
  2882                 stylename = QLatin1String("default");
       
  2883         } else {
       
  2884             stylename = QLatin1String("default");
       
  2885         }
       
  2886 
       
  2887         num = settings.value(QLatin1String("doubleClickInterval"),
       
  2888                             QApplication::doubleClickInterval()).toInt();
       
  2889         QApplication::setDoubleClickInterval(num);
       
  2890 
       
  2891         num = settings.value(QLatin1String("cursorFlashTime"),
       
  2892                             QApplication::cursorFlashTime()).toInt();
       
  2893         QApplication::setCursorFlashTime(num);
       
  2894 
       
  2895 #ifndef QT_NO_WHEELEVENT
       
  2896         num = settings.value(QLatin1String("wheelScrollLines"),
       
  2897                             QApplication::wheelScrollLines()).toInt();
       
  2898         QApplication::setWheelScrollLines(num);
       
  2899 #endif
       
  2900 
       
  2901         QString colorspec = settings.value(QLatin1String("colorSpec"),
       
  2902                                             QVariant(QLatin1String("default"))).toString();
       
  2903         if (colorspec == QLatin1String("normal"))
       
  2904             QApplication::setColorSpec(QApplication::NormalColor);
       
  2905         else if (colorspec == QLatin1String("custom"))
       
  2906             QApplication::setColorSpec(QApplication::CustomColor);
       
  2907         else if (colorspec == QLatin1String("many"))
       
  2908             QApplication::setColorSpec(QApplication::ManyColor);
       
  2909         else if (colorspec != QLatin1String("default"))
       
  2910             colorspec = QLatin1String("default");
       
  2911 
       
  2912         int w = settings.value(QLatin1String("globalStrut/width")).toInt();
       
  2913         int h = settings.value(QLatin1String("globalStrut/height")).toInt();
       
  2914         QSize strut(w, h);
       
  2915         if (strut.isValid())
       
  2916             QApplication::setGlobalStrut(strut);
       
  2917 
       
  2918         QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
       
  2919         if (!effects.isEmpty()) {
       
  2920             if (effects.contains(QLatin1String("none")))
       
  2921                 QApplication::setEffectEnabled(Qt::UI_General, false);
       
  2922             if (effects.contains(QLatin1String("general")))
       
  2923                 QApplication::setEffectEnabled(Qt::UI_General, true);
       
  2924             if (effects.contains(QLatin1String("animatemenu")))
       
  2925                 QApplication::setEffectEnabled(Qt::UI_AnimateMenu, true);
       
  2926             if (effects.contains(QLatin1String("fademenu")))
       
  2927                 QApplication::setEffectEnabled(Qt::UI_FadeMenu, true);
       
  2928             if (effects.contains(QLatin1String("animatecombo")))
       
  2929                 QApplication::setEffectEnabled(Qt::UI_AnimateCombo, true);
       
  2930             if (effects.contains(QLatin1String("animatetooltip")))
       
  2931                 QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, true);
       
  2932             if (effects.contains(QLatin1String("fadetooltip")))
       
  2933                 QApplication::setEffectEnabled(Qt::UI_FadeTooltip, true);
       
  2934             if (effects.contains(QLatin1String("animatetoolbox")))
       
  2935                 QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, true);
       
  2936         } else {
       
  2937             QApplication::setEffectEnabled(Qt::UI_General, true);
       
  2938         }
       
  2939 
       
  2940         settings.beginGroup(QLatin1String("Font Substitutions"));
       
  2941         QStringList fontsubs = settings.childKeys();
       
  2942         if (!fontsubs.isEmpty()) {
       
  2943             QStringList::Iterator it = fontsubs.begin();
       
  2944             for (; it != fontsubs.end(); ++it) {
       
  2945                 QString fam = QString::fromLatin1((*it).toLatin1().constData());
       
  2946                 QStringList subs = settings.value(fam).toStringList();
       
  2947                 QFont::insertSubstitutions(fam, subs);
       
  2948             }
       
  2949         }
       
  2950         settings.endGroup();
       
  2951     }
       
  2952 
       
  2953     settings.endGroup();
       
  2954     return true;
       
  2955 }
       
  2956 
       
  2957 // DRSWAT
       
  2958 
       
  2959 bool QApplicationPrivate::canQuit()
       
  2960 {
       
  2961 #ifndef QT_MAC_USE_COCOA
       
  2962     return true;
       
  2963 #else
       
  2964     Q_Q(QApplication);
       
  2965 #ifdef QT_MAC_USE_COCOA
       
  2966     [[NSApp mainMenu] cancelTracking];
       
  2967 #else
       
  2968     HiliteMenu(0);
       
  2969 #endif
       
  2970 
       
  2971     bool handle_quit = true;
       
  2972     if (QApplicationPrivate::modalState() && [[[[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate]
       
  2973                                                    menuLoader] quitMenuItem] isEnabled]) {
       
  2974         int visible = 0;
       
  2975         const QWidgetList tlws = QApplication::topLevelWidgets();
       
  2976         for(int i = 0; i < tlws.size(); ++i) {
       
  2977             if (tlws.at(i)->isVisible())
       
  2978                 ++visible;
       
  2979         }
       
  2980         handle_quit = (visible <= 1);
       
  2981     }
       
  2982     if (handle_quit) {
       
  2983         QCloseEvent ev;
       
  2984         QApplication::sendSpontaneousEvent(q, &ev);
       
  2985         if (ev.isAccepted()) {
       
  2986             return true;
       
  2987         }
       
  2988     }
       
  2989     return false;
       
  2990 #endif
       
  2991 }
       
  2992 
       
  2993 void onApplicationWindowChangedActivation(QWidget *widget, bool activated)
       
  2994 {
       
  2995 #if QT_MAC_USE_COCOA
       
  2996     if (!widget)
       
  2997         return;
       
  2998 
       
  2999     if (activated) {
       
  3000         if (QApplicationPrivate::app_style) {
       
  3001             QEvent ev(QEvent::Style);
       
  3002             qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
       
  3003         }
       
  3004         qApp->setActiveWindow(widget);
       
  3005     } else { // deactivated
       
  3006         if (QApplicationPrivate::active_window == widget)
       
  3007             qApp->setActiveWindow(0);
       
  3008     }
       
  3009 
       
  3010     QMenuBar::macUpdateMenuBar();
       
  3011 
       
  3012 #else
       
  3013     Q_UNUSED(widget);
       
  3014     Q_UNUSED(activated);
       
  3015 #endif
       
  3016 }
       
  3017 
       
  3018 
       
  3019 void onApplicationChangedActivation( bool activated )
       
  3020 {
       
  3021 #if QT_MAC_USE_COCOA
       
  3022     QApplication    *app    = qApp;
       
  3023 
       
  3024 //NSLog(@"App Changed Activation\n");
       
  3025 
       
  3026     if ( activated ) {
       
  3027         if (QApplication::desktopSettingsAware())
       
  3028             qt_mac_update_os_settings();
       
  3029 
       
  3030         if (qt_clipboard) { //manufacture an event so the clipboard can see if it has changed
       
  3031             QEvent ev(QEvent::Clipboard);
       
  3032             qt_sendSpontaneousEvent(qt_clipboard, &ev);
       
  3033         }
       
  3034 
       
  3035         if (app) {
       
  3036             QEvent ev(QEvent::ApplicationActivate);
       
  3037             qt_sendSpontaneousEvent(app, &ev);
       
  3038         }
       
  3039 
       
  3040         if (!app->activeWindow()) {
       
  3041 #if QT_MAC_USE_COCOA
       
  3042             OSWindowRef wp    = [NSApp keyWindow];
       
  3043 #else
       
  3044             OSWindowRef wp = ActiveNonFloatingWindow();
       
  3045 #endif
       
  3046             if (QWidget *tmp_w = qt_mac_find_window(wp))
       
  3047                 app->setActiveWindow(tmp_w);
       
  3048         }
       
  3049         QMenuBar::macUpdateMenuBar();
       
  3050     } else { // de-activated
       
  3051         QApplicationPrivate *priv = [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] qAppPrivate];
       
  3052         while (priv->inPopupMode())
       
  3053             app->activePopupWidget()->close();
       
  3054         if (app) {
       
  3055             QEvent ev(QEvent::ApplicationDeactivate);
       
  3056             qt_sendSpontaneousEvent(app, &ev);
       
  3057         }
       
  3058         app->setActiveWindow(0);
       
  3059     }
       
  3060 #else
       
  3061     Q_UNUSED(activated);
       
  3062 #endif
       
  3063 }
       
  3064 
       
  3065 void QApplicationPrivate::initializeMultitouch_sys()
       
  3066 { }
       
  3067 void QApplicationPrivate::cleanupMultitouch_sys()
       
  3068 { }
       
  3069 
       
  3070 QT_END_NAMESPACE