source: trunk/src/gui/kernel/qapplication_mac.mm@ 345

Last change on this file since 345 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 116.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
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 "private/qmacinputcontext_p.h"
108#include "private/qpaintengine_mac_p.h"
109#include "private/qcursor_p.h"
110#include "private/qapplication_p.h"
111#include "private/qcolor_p.h"
112#include "private/qwidget_p.h"
113#include "private/qkeymapper_p.h"
114#include "private/qeventdispatcher_mac_p.h"
115#include "private/qeventdispatcher_unix_p.h"
116#include <private/qcocoamenuloader_mac_p.h>
117#include <private/qcocoaapplication_mac_p.h>
118#include <private/qcocoaapplicationdelegate_mac_p.h>
119#include <private/qt_cocoa_helpers_mac_p.h>
120#include <private/qcocoawindow_mac_p.h>
121#include <private/qpixmap_mac_p.h>
122#include <private/qdesktopwidget_mac_p.h>
123#include <private/qeventdispatcher_mac_p.h>
124#include <qvarlengtharray.h>
125
126#ifndef QT_NO_ACCESSIBILITY
127# include "qaccessible.h"
128#endif
129
130#ifndef QT_NO_THREAD
131# include "qmutex.h"
132#endif
133
134#include <unistd.h>
135#include <string.h>
136#include <sys/time.h>
137#include <sys/select.h>
138
139/*****************************************************************************
140 QApplication debug facilities
141 *****************************************************************************/
142//#define DEBUG_EVENTS //like EventDebug but more specific to Qt
143//#define DEBUG_DROPPED_EVENTS
144//#define DEBUG_MOUSE_MAPS
145//#define DEBUG_MODAL_EVENTS
146//#define DEBUG_PLATFORM_SETTINGS
147
148#define QMAC_SPEAK_TO_ME
149#ifdef QMAC_SPEAK_TO_ME
150#include "qregexp.h"
151#endif
152
153#ifndef kThemeBrushAlternatePrimaryHighlightColor
154#define kThemeBrushAlternatePrimaryHighlightColor -5
155#endif
156
157
158QT_BEGIN_NAMESPACE
159
160//for qt_mac.h
161QPaintDevice *qt_mac_safe_pdev = 0;
162QList<QMacWindowChangeEvent*> *QMacWindowChangeEvent::change_events = 0;
163extern QHash<QByteArray, QFont> *qt_app_fonts_hash(); // qapplication.cpp
164
165/*****************************************************************************
166 Internal variables and functions
167 *****************************************************************************/
168static struct {
169 bool use_qt_time_limit;
170 QPointer<QWidget> last_widget;
171 int last_x, last_y;
172 int last_modifiers, last_button;
173 EventTime last_time;
174} qt_mac_dblclick = { false, 0, -1, -1, 0, 0, -2 };
175
176static bool app_do_modal = false; // modal mode
177extern QWidgetList *qt_modal_stack; // stack of modal widgets
178extern bool qt_tab_all_widgets; // from qapplication.cpp
179bool qt_mac_app_fullscreen = false;
180bool qt_scrollbar_jump_to_pos = false;
181static bool qt_mac_collapse_on_dblclick = true;
182extern int qt_antialiasing_threshold; // from qapplication.cpp
183QPointer<QWidget> qt_button_down; // widget got last button-down
184#ifndef QT_MAC_USE_COCOA
185static bool qt_button_down_in_content; // whether the button_down was in the content area.
186static bool qt_mac_previous_press_in_popup_mode = false;
187static bool qt_mac_no_click_through_mode = false;
188static int tablet_button_state = 0;
189#endif
190QPointer<QWidget> qt_mouseover;
191#if defined(QT_DEBUG)
192static bool appNoGrab = false; // mouse/keyboard grabbing
193#endif
194#ifndef QT_MAC_USE_COCOA
195static EventHandlerRef app_proc_handler = 0;
196static EventHandlerUPP app_proc_handlerUPP = 0;
197static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL;
198#endif
199static EventHandlerRef tablet_proximity_handler = 0;
200static EventHandlerUPP tablet_proximity_UPP = 0;
201bool QApplicationPrivate::native_modal_dialog_active;
202
203/*****************************************************************************
204 External functions
205 *****************************************************************************/
206extern void qt_mac_beep(); //qsound_mac.mm
207extern Qt::KeyboardModifiers qt_mac_get_modifiers(int keys); //qkeymapper_mac.cpp
208extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
209extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
210extern OSWindowRef qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
211extern QWidget *qt_mac_find_window(OSWindowRef); //qwidget_mac.cpp
212extern void qt_mac_set_cursor(const QCursor *, const QPoint &); //qcursor_mac.cpp
213extern bool qt_mac_is_macsheet(const QWidget *); //qwidget_mac.cpp
214extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
215extern void qt_mac_command_set_enabled(MenuRef, UInt32, bool); //qmenu_mac.cpp
216extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); // qapplication.cpp
217
218// Forward Decls
219void onApplicationWindowChangedActivation( QWidget*widget, bool activated );
220void onApplicationChangedActivation( bool activated );
221
222Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
223 OSStatus err;
224 AEDesc scriptTextDesc;
225 ComponentInstance theComponent = 0;
226 OSAID scriptID = kOSANullScript, resultID = kOSANullScript;
227
228 // set up locals to a known state
229 AECreateDesc(typeNull, 0, 0, &scriptTextDesc);
230 scriptID = kOSANullScript;
231 resultID = kOSANullScript;
232
233 // open the scripting component
234 theComponent = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
235 if (!theComponent) {
236 err = paramErr;
237 goto bail;
238 }
239
240 // put the script text into an aedesc
241 err = AECreateDesc(typeUTF8Text, script, script_len, &scriptTextDesc);
242 if (err != noErr)
243 goto bail;
244
245 // compile the script
246 err = OSACompile(theComponent, &scriptTextDesc, kOSAModeNull, &scriptID);
247 if (err != noErr)
248 goto bail;
249
250 // run the script
251 err = OSAExecute(theComponent, scriptID, kOSANullScript, kOSAModeNull, &resultID);
252
253 // collect the results - if any
254 if (ret) {
255 AECreateDesc(typeNull, 0, 0, ret);
256 if (err == errOSAScriptError)
257 OSAScriptError(theComponent, kOSAErrorMessage, typeChar, ret);
258 else if (err == noErr && resultID != kOSANullScript)
259 OSADisplay(theComponent, resultID, typeChar, kOSAModeNull, ret);
260 }
261bail:
262 AEDisposeDesc(&scriptTextDesc);
263 if (scriptID != kOSANullScript)
264 OSADispose(theComponent, scriptID);
265 if (resultID != kOSANullScript)
266 OSADispose(theComponent, resultID);
267 if (theComponent)
268 CloseComponent(theComponent);
269 return err == noErr;
270}
271
272Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, AEDesc *ret)
273{
274 return qt_mac_execute_apple_script(script, qstrlen(script), ret);
275}
276
277Q_GUI_EXPORT bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret)
278{
279 const QByteArray l = script.toUtf8(); return qt_mac_execute_apple_script(l.constData(), l.size(), ret);
280}
281
282/* Resolution change magic */
283void qt_mac_display_change_callbk(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void *)
284{
285#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
286 const bool resized = flags & kCGDisplayDesktopShapeChangedFlag;
287#else
288 Q_UNUSED(flags);
289 const bool resized = true;
290#endif
291 if (resized && qApp) {
292 if (QDesktopWidget *dw = qApp->desktop()) {
293 QResizeEvent *re = new QResizeEvent(dw->size(), dw->size());
294 QApplication::postEvent(dw, re);
295 QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
296 }
297 }
298}
299
300#ifdef DEBUG_PLATFORM_SETTINGS
301static void qt_mac_debug_palette(const QPalette &pal, const QPalette &pal2, const QString &where)
302{
303 const char *const groups[] = {"Active", "Disabled", "Inactive" };
304 const char *const roles[] = { "WindowText", "Button", "Light", "Midlight", "Dark", "Mid",
305 "Text", "BrightText", "ButtonText", "Base", "Window", "Shadow",
306 "Highlight", "HighlightedText", "Link", "LinkVisited" };
307 if (!where.isNull())
308 qDebug("qt-internal: %s", where.toLatin1().constData());
309 for(int grp = 0; grp < QPalette::NColorGroups; grp++) {
310 for(int role = 0; role < QPalette::NColorRoles; role++) {
311 QBrush b = pal.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role);
312 QPixmap pm = b.texture();
313 qDebug(" %s::%s %d::%d::%d [%p]%s", groups[grp], roles[role], b.color().red(),
314 b.color().green(), b.color().blue(), pm.isNull() ? 0 : &pm,
315 pal2.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role) != b ? " (*)" : "");
316 }
317 }
318
319}
320#else
321#define qt_mac_debug_palette(x, y, z)
322#endif
323
324//raise a notification
325#ifndef QT_MAC_USE_COCOA
326static NMRec qt_mac_notification = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
327#endif
328void qt_mac_send_notification()
329{
330#ifndef QT_MAC_USE_COCOA
331 //send it
332 qt_mac_notification.nmMark = 1; //non-zero magic number
333 qt_mac_notification.qType = nmType;
334 NMInstall(&qt_mac_notification);
335#else
336 QMacCocoaAutoReleasePool pool;
337 [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
338#endif
339}
340
341void qt_mac_cancel_notification()
342{
343#ifndef QT_MAC_USE_COCOA
344 NMRemove(&qt_mac_notification);
345#else
346 QMacCocoaAutoReleasePool pool;
347 [[NSApplication sharedApplication] cancelUserAttentionRequest:NSInformationalRequest];
348#endif
349}
350
351#ifndef QT_MAC_USE_COCOA
352//find widget (and part) at a given point
353static short qt_mac_window_at(int x, int y, QWidget **w=0)
354{
355 Point p;
356 p.h = x;
357 p.v = y;
358 OSWindowRef wp;
359 WindowPartCode wpc;
360 OSStatus err = FindWindowOfClass(&p, kAllWindowClasses, &wp, &wpc);
361 if(err != noErr) {
362 if(w)
363 (*w) = 0;
364 return wpc;
365 }
366 if(w) {
367 if(wp) {
368 *w = qt_mac_find_window(wp);
369#if 0
370 if(!*w)
371 qWarning("QApplication: qt_mac_window_at: Couldn't find %d",(int)wp);
372#endif
373 } else {
374 *w = 0;
375 }
376 }
377 return wpc;
378}
379
380#endif
381
382void qt_mac_set_app_icon(const QPixmap &pixmap)
383{
384#ifndef QT_MAC_USE_COCOA
385 if(pixmap.isNull()) {
386 RestoreApplicationDockTileImage();
387 } else {
388 CGImageRef img = (CGImageRef)pixmap.macCGHandle();
389 SetApplicationDockTileImage(img);
390 CGImageRelease(img);
391 }
392#else
393 QMacCocoaAutoReleasePool pool;
394 NSImage *image = NULL;
395 if (pixmap.isNull()) {
396 // Get Application icon from bundle
397 image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; // released below
398 } else {
399 image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
400 }
401
402 [NSApp setApplicationIconImage:image];
403 [image release];
404#endif
405}
406
407Q_GUI_EXPORT void qt_mac_set_press_and_hold_context(bool b)
408{
409 Q_UNUSED(b);
410 qWarning("qt_mac_set_press_and_hold_context: This functionality is no longer available");
411}
412
413bool qt_nograb() // application no-grab option
414{
415#if defined(QT_DEBUG)
416 return appNoGrab;
417#else
418 return false;
419#endif
420}
421
422void qt_mac_update_os_settings()
423{
424 if (!qApp)
425 return;
426 if (!QApplication::startingUp()) {
427 static bool needToPolish = true;
428 if (needToPolish) {
429 QApplication::style()->polish(qApp);
430 needToPolish = false;
431 }
432 }
433 //focus mode
434 /* First worked as of 10.2.3 */
435 QSettings appleSettings(QLatin1String("apple.com"));
436 QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0);
437 qt_tab_all_widgets = (appleValue.toInt() & 0x2);
438 //paging mode
439 /* First worked as of 10.2.3 */
440 appleValue = appleSettings.value(QLatin1String("AppleScrollerPagingBehavior"), false);
441 qt_scrollbar_jump_to_pos = appleValue.toBool();
442 //collapse
443 /* First worked as of 10.3.3 */
444 appleValue = appleSettings.value(QLatin1String("AppleMiniaturizeOnDoubleClick"), true);
445 qt_mac_collapse_on_dblclick = appleValue.toBool();
446
447 // Anti-aliasing threshold
448 appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
449 if (appleValue.isValid())
450 qt_antialiasing_threshold = appleValue.toInt();
451
452#ifdef DEBUG_PLATFORM_SETTINGS
453 qDebug("qt_mac_update_os_settings *********************************************************************");
454#endif
455 { // setup the global palette
456 QColor qc;
457 (void) QApplication::style(); // trigger creation of application style and system palettes
458 QPalette pal = *QApplicationPrivate::sys_pal;
459
460 pal.setBrush( QPalette::Active, QPalette::Highlight, qcolorForTheme(kThemeBrushPrimaryHighlightColor) );
461 pal.setBrush( QPalette::Inactive, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
462
463 pal.setBrush( QPalette::Disabled, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
464 pal.setBrush( QPalette::Active, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonActiveDarkShadow) );
465
466 pal.setBrush( QPalette::Inactive, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
467 pal.setBrush( QPalette::Disabled, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
468
469 qc = qcolorForThemeTextColor(kThemeTextColorDialogActive);
470 pal.setColor(QPalette::Active, QPalette::Text, qc);
471 pal.setColor(QPalette::Active, QPalette::WindowText, qc);
472 pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
473
474 qc = qcolorForThemeTextColor(kThemeTextColorDialogInactive);
475 pal.setColor(QPalette::Inactive, QPalette::Text, qc);
476 pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
477 pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
478 pal.setColor(QPalette::Disabled, QPalette::Text, qc);
479 pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
480 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
481 pal.setBrush(QPalette::ToolTipBase, QColor(255, 255, 199));
482
483 if (!QApplicationPrivate::sys_pal || *QApplicationPrivate::sys_pal != pal) {
484 QApplicationPrivate::setSystemPalette(pal);
485 QApplication::setPalette(pal);
486 }
487#ifdef DEBUG_PLATFORM_SETTINGS
488 qt_mac_debug_palette(pal, QApplication::palette(), "Global Palette");
489#endif
490 }
491
492 QFont fnt = qfontForThemeFont(kThemeApplicationFont);
493#ifdef DEBUG_PLATFORM_SETTINGS
494 qDebug("qt-internal: Font for Application [%s::%d::%d::%d]",
495 fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
496#endif
497 if (!QApplicationPrivate::sys_font || *QApplicationPrivate::sys_font != fnt)
498 QApplicationPrivate::setSystemFont(fnt);
499
500 { //setup the fonts
501 struct FontMap {
502 FontMap(const char *qc, short fk) : qt_class(qc), font_key(fk) { }
503 const char *const qt_class;
504 short font_key;
505 } mac_widget_fonts[] = {
506 FontMap("QPushButton", kThemePushButtonFont),
507 FontMap("QListView", kThemeViewsFont),
508 FontMap("QListBox", kThemeViewsFont),
509 FontMap("QTitleBar", kThemeWindowTitleFont),
510 FontMap("QMenuBar", kThemeMenuTitleFont),
511 FontMap("QMenu", kThemeMenuItemFont),
512 FontMap("QComboMenuItem", kThemeSystemFont),
513 FontMap("QHeaderView", kThemeSmallSystemFont),
514 FontMap("Q3Header", kThemeSmallSystemFont),
515 FontMap("QTipLabel", kThemeSmallSystemFont),
516 FontMap("QLabel", kThemeSystemFont),
517 FontMap("QToolButton", kThemeSmallSystemFont),
518 FontMap("QMenuItem", kThemeMenuItemCmdKeyFont), // It doesn't exist, but its unique.
519 FontMap("QComboLineEdit", kThemeViewsFont), // It doesn't exist, but its unique.
520 FontMap("QSmallFont", kThemeSmallSystemFont), // It doesn't exist, but its unique.
521 FontMap("QMiniFont", kThemeMiniSystemFont), // It doesn't exist, but its unique.
522 FontMap(0, 0) };
523 for(int i = 0; mac_widget_fonts[i].qt_class; i++) {
524 QFont fnt = qfontForThemeFont(mac_widget_fonts[i].font_key);
525 bool set_font = true;
526 QHash<QByteArray, QFont> *hash = qt_app_fonts_hash();
527 if (!hash->isEmpty()) {
528 QHash<QByteArray, QFont>::const_iterator it
529 = hash->constFind(mac_widget_fonts[i].qt_class);
530 if (it != hash->constEnd())
531 set_font = (fnt != *it);
532 }
533 if (set_font) {
534 QApplication::setFont(fnt, mac_widget_fonts[i].qt_class);
535#ifdef DEBUG_PLATFORM_SETTINGS
536 qDebug("qt-internal: Font for %s [%s::%d::%d::%d]", mac_widget_fonts[i].qt_class,
537 fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
538#endif
539 }
540 }
541 }
542 QApplicationPrivate::initializeWidgetPaletteHash();
543#ifdef DEBUG_PLATFORM_SETTINGS
544 qDebug("qt_mac_update_os_settings END !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
545#endif
546}
547
548void QApplicationPrivate::initializeWidgetPaletteHash()
549{
550 { //setup the palette
551 struct PaletteMap {
552 inline PaletteMap(const char *qc, ThemeBrush a, ThemeBrush i) :
553 qt_class(qc), active(a), inactive(i) { }
554 const char *const qt_class;
555 ThemeBrush active, inactive;
556 } mac_widget_colors[] = {
557 PaletteMap("QToolButton", kThemeTextColorBevelButtonActive, kThemeTextColorBevelButtonInactive),
558 PaletteMap("QAbstractButton", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
559 PaletteMap("QHeaderView", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
560 PaletteMap("Q3Header", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
561 PaletteMap("QComboBox", kThemeTextColorPopupButtonActive, kThemeTextColorPopupButtonInactive),
562 PaletteMap("QAbstractItemView", kThemeTextColorListView, kThemeTextColorDialogInactive),
563 PaletteMap("QMessageBoxLabel", kThemeTextColorAlertActive, kThemeTextColorAlertInactive),
564 PaletteMap("QTabBar", kThemeTextColorTabFrontActive, kThemeTextColorTabFrontInactive),
565 PaletteMap("QLabel", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
566 PaletteMap("QGroupBox", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
567 PaletteMap("QMenu", kThemeTextColorPopupLabelActive, kThemeTextColorPopupLabelInactive),
568 PaletteMap("QTextEdit", 0, 0),
569 PaletteMap("QTextControl", 0, 0),
570 PaletteMap("QLineEdit", 0, 0),
571 PaletteMap(0, 0, 0) };
572 QColor qc;
573 for(int i = 0; mac_widget_colors[i].qt_class; i++) {
574 QPalette pal;
575 if (mac_widget_colors[i].active != 0) {
576 qc = qcolorForThemeTextColor(mac_widget_colors[i].active);
577 pal.setColor(QPalette::Active, QPalette::Text, qc);
578 pal.setColor(QPalette::Active, QPalette::WindowText, qc);
579 pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
580 qc = qcolorForThemeTextColor(mac_widget_colors[i].inactive);
581 pal.setColor(QPalette::Inactive, QPalette::Text, qc);
582 pal.setColor(QPalette::Disabled, QPalette::Text, qc);
583 pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
584 pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
585 pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
586 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
587 }
588 if (!strcmp(mac_widget_colors[i].qt_class, "QMenu")) {
589 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemActive);
590 pal.setBrush(QPalette::ButtonText, qc);
591 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
592 pal.setBrush(QPalette::HighlightedText, qc);
593 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemDisabled);
594 pal.setBrush(QPalette::Disabled, QPalette::Text, qc);
595 } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractButton")
596 || !strcmp(mac_widget_colors[i].qt_class, "QHeaderView")
597 || !strcmp(mac_widget_colors[i].qt_class, "Q3Header")) { //special
598 pal.setColor(QPalette::Disabled, QPalette::ButtonText,
599 pal.color(QPalette::Disabled, QPalette::Text));
600 pal.setColor(QPalette::Inactive, QPalette::ButtonText,
601 pal.color(QPalette::Inactive, QPalette::Text));
602 pal.setColor(QPalette::Active, QPalette::ButtonText,
603 pal.color(QPalette::Active, QPalette::Text));
604 } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractItemView")) {
605 pal.setBrush(QPalette::Active, QPalette::Highlight,
606 qcolorForTheme(kThemeBrushAlternatePrimaryHighlightColor));
607 qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
608 pal.setBrush(QPalette::Active, QPalette::HighlightedText, qc);
609#if 1
610 pal.setBrush(QPalette::Inactive, QPalette::Text,
611 pal.brush(QPalette::Active, QPalette::Text));
612 pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
613 pal.brush(QPalette::Active, QPalette::Text));
614#endif
615 } else if (!strcmp(mac_widget_colors[i].qt_class, "QTextEdit")
616 || !strcmp(mac_widget_colors[i].qt_class, "QTextControl")) {
617 pal.setBrush(QPalette::Inactive, QPalette::Text,
618 pal.brush(QPalette::Active, QPalette::Text));
619 pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
620 pal.brush(QPalette::Active, QPalette::Text));
621 } else if (!strcmp(mac_widget_colors[i].qt_class, "QLineEdit")) {
622 pal.setBrush(QPalette::Disabled, QPalette::Base,
623 pal.brush(QPalette::Active, QPalette::Base));
624 }
625
626 bool set_palette = true;
627 extern QHash<QByteArray, QPalette> *qt_app_palettes_hash(); //qapplication.cpp
628 QHash<QByteArray, QPalette> *phash = qt_app_palettes_hash();
629 if (!phash->isEmpty()) {
630 QHash<QByteArray, QPalette>::const_iterator it
631 = phash->constFind(mac_widget_colors[i].qt_class);
632 if (it != phash->constEnd())
633 set_palette = (pal != *it);
634 }
635 if (set_palette) {
636 QApplication::setPalette(pal, mac_widget_colors[i].qt_class);
637#ifdef DEBUG_PLATFORM_SETTINGS
638 qt_mac_debug_palette(pal, QApplication::palette(), QLatin1String("Palette for ") + QString::fromLatin1(mac_widget_colors[i].qt_class));
639#endif
640 }
641 }
642 }
643}
644
645static void qt_mac_event_release(EventRef &event)
646{
647 ReleaseEvent(event);
648 event = 0;
649}
650#ifndef QT_MAC_USE_COCOA
651static void qt_mac_event_release(QWidget *w, EventRef &event)
652{
653 if (event) {
654 QWidget *widget = 0;
655 if (GetEventParameter(event, kEventParamQWidget, typeQWidget, 0, sizeof(widget), 0, &widget) == noErr
656 && w == widget) {
657 if (IsEventInQueue(GetMainEventQueue(), event))
658 RemoveEventFromQueue(GetMainEventQueue(), event);
659 qt_mac_event_release(event);
660 }
661 }
662}
663
664static bool qt_mac_event_remove(EventRef &event)
665{
666 if (event) {
667 if (IsEventInQueue(GetMainEventQueue(), event))
668 RemoveEventFromQueue(GetMainEventQueue(), event);
669 qt_mac_event_release(event);
670 return true;
671 }
672 return false;
673}
674#endif
675
676/* sheets */
677#ifndef QT_MAC_USE_COCOA
678static EventRef request_showsheet_pending = 0;
679#endif
680void qt_event_request_showsheet(QWidget *w)
681{
682 Q_ASSERT(qt_mac_is_macsheet(w));
683#ifdef QT_MAC_USE_COCOA
684 [NSApp beginSheet:qt_mac_window_for(w) modalForWindow:qt_mac_window_for(w->parentWidget())
685 modalDelegate:nil didEndSelector:nil contextInfo:0];
686#else
687 qt_mac_event_remove(request_showsheet_pending);
688 CreateEvent(0, kEventClassQt, kEventQtRequestShowSheet, GetCurrentEventTime(),
689 kEventAttributeUserEvent, &request_showsheet_pending);
690 SetEventParameter(request_showsheet_pending, kEventParamQWidget, typeQWidget, sizeof(w), &w);
691 PostEventToQueue(GetMainEventQueue(), request_showsheet_pending, kEventPriorityStandard);
692#endif
693}
694
695static void qt_post_window_change_event(QWidget *widget)
696{
697 qt_widget_private(widget)->needWindowChange = true;
698 QEvent *glWindowChangeEvent = new QEvent(QEvent::MacGLWindowChange);
699 QApplication::postEvent(widget, glWindowChangeEvent);
700}
701
702/*
703 Posts updates to all child and grandchild OpenGL widgets for the given widget.
704*/
705static void qt_mac_update_child_gl_widgets(QWidget *widget)
706{
707 if (widget->isWindow())
708 return;