diff options
Diffstat (limited to 'src/gui/kernel')
31 files changed, 843 insertions, 763 deletions
diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp index c6addc1..b2afbd0 100644 --- a/src/gui/kernel/qaction.cpp +++ b/src/gui/kernel/qaction.cpp @@ -1370,7 +1370,7 @@ QAction::MenuRole QAction::menuRole() const void QAction::setIconVisibleInMenu(bool visible) { Q_D(QAction); - if (visible != (bool)d->iconVisibleInMenu) { + if (d->iconVisibleInMenu == -1 || visible != bool(d->iconVisibleInMenu)) { int oldValue = d->iconVisibleInMenu; d->iconVisibleInMenu = visible; // Only send data changed if we really need to. diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 98285f0..b9ebf55 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -4989,6 +4989,137 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy) return true; } +/*! \fn QDecoration &QApplication::qwsDecoration() + Return the QWSDecoration used for decorating windows. + + \warning This method is non-portable. It is only available in + Qt for Embedded Linux. + + \sa QDecoration +*/ + +/*! + \fn void QApplication::qwsSetDecoration(QDecoration *decoration) + + Sets the QDecoration derived class to use for decorating the + windows used by Qt for Embedded Linux to the \a decoration + specified. + + This method is non-portable. It is only available in Qt for Embedded Linux. + + \sa QDecoration +*/ + +/*! \fn QDecoration* QApplication::qwsSetDecoration(const QString &decoration) + \overload + + Requests a QDecoration object for \a decoration from the QDecorationFactory. + + The string must be one of the QDecorationFactory::keys(). Keys are + case insensitive. + + A later call to the QApplication constructor will override the + requested style when a "-style" option is passed in as a commandline + parameter. + + Returns 0 if an unknown \a decoration is passed, otherwise the QStyle object + returned is set as the application's GUI style. +*/ + +/*! + \fn bool QApplication::qwsEventFilter(QWSEvent *event) + + This virtual function is only implemented under Qt for Embedded Linux. + + If you create an application that inherits QApplication and + reimplement this function, you get direct access to all QWS (Q + Window System) events that the are received from the QWS master + process. The events are passed in the \a event parameter. + + Return true if you want to stop the event from being processed. + Return false for normal event dispatching. The default + implementation returns false. +*/ + +/*! \fn void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors) + Set Qt for Embedded Linux custom color table. + + Qt for Embedded Linux on 8-bpp displays allocates a standard 216 color cube. + The remaining 40 colors may be used by setting a custom color + table in the QWS master process before any clients connect. + + \a colorTable is an array of up to 40 custom colors. \a start is + the starting index (0-39) and \a numColors is the number of colors + to be set (1-40). + + This method is non-portable. It is available \e only in + Qt for Embedded Linux. + + \note The custom colors will not be used by the default screen + driver. To make use of the new colors, implement a custom screen + driver, or use QDirectPainter. +*/ + +/*! \fn int QApplication::qwsProcessEvent(QWSEvent* event) + \internal +*/ + +/*! \fn int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only) + \internal +*/ + +/*! \fn int QApplication::x11ProcessEvent(XEvent* event) + This function does the core processing of individual X + \a{event}s, normally by dispatching Qt events to the right + destination. + + It returns 1 if the event was consumed by special handling, 0 if + the \a event was consumed by normal handling, and -1 if the \a + event was for an unrecognized widget. + + \sa x11EventFilter() +*/ + +/*! + \fn bool QApplication::x11EventFilter(XEvent *event) + + \warning This virtual function is only implemented under X11. + + If you create an application that inherits QApplication and + reimplement this function, you get direct access to all X events + that the are received from the X server. The events are passed in + the \a event parameter. + + Return true if you want to stop the event from being processed. + Return false for normal event dispatching. The default + implementation returns false. + + It is only the directly addressed messages that are filtered. + You must install an event filter directly on the event + dispatcher, which is returned by + QAbstractEventDispatcher::instance(), to handle system wide + messages. + + \sa x11ProcessEvent() +*/ + +/*! \fn void QApplication::winFocus(QWidget *widget, bool gotFocus) + \internal + \since 4.1 + + If \a gotFocus is true, \a widget will become the active window. + Otherwise the active window is reset to 0. +*/ + +/*! \fn void QApplication::winMouseButtonUp() + \internal + */ + +/*! \fn void QApplication::syncX() + Synchronizes with the X server in the X11 implementation. + This normally takes some time. Does nothing on other platforms. +*/ + QT_END_NAMESPACE #include "moc_qapplication.cpp" diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index ae99e83..d5fa9ea 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -194,8 +194,8 @@ static bool appNoGrab = false; // mouse/keyboard grabbing #ifndef QT_MAC_USE_COCOA static EventHandlerRef app_proc_handler = 0; static EventHandlerUPP app_proc_handlerUPP = 0; -static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL; #endif +static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL; static EventHandlerRef tablet_proximity_handler = 0; static EventHandlerUPP tablet_proximity_UPP = 0; bool QApplicationPrivate::native_modal_dialog_active; @@ -951,7 +951,6 @@ void qt_mac_event_release(QWidget *w) } } -#ifndef QT_MAC_USE_COCOA struct QMacAppleEventTypeSpec { AEEventClass mac_class; AEEventID mac_id; @@ -959,6 +958,7 @@ struct QMacAppleEventTypeSpec { { kCoreEventClass, kAEQuitApplication }, { kCoreEventClass, kAEOpenDocuments } }; +#ifndef QT_MAC_USE_COCOA /* watched events */ static EventTypeSpec app_events[] = { { kEventClassQt, kEventQtRequestWindowChange }, @@ -1156,13 +1156,13 @@ void qt_init(QApplicationPrivate *priv, int) qt_init_app_proc_handler(); } +#endif if (!app_proc_ae_handlerUPP) { app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor); for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, app_proc_ae_handlerUPP, SRefCon(qApp), true); } -#endif if (QApplicationPrivate::app_style) { QEvent ev(QEvent::Style); @@ -1196,10 +1196,6 @@ void qt_init(QApplicationPrivate *priv, int) [qtMenuLoader release]; } #endif - if (QApplication::testAttribute(Qt::AA_MacPluginApplication)) { - extern void qt_mac_set_native_menubar(bool); - qt_mac_set_native_menubar(false); - } // Register for Carbon tablet proximity events on the event monitor target. // This means that we should receive proximity events even when we aren't the active application. if (!tablet_proximity_handler) { @@ -1210,6 +1206,17 @@ void qt_init(QApplicationPrivate *priv, int) } +void qt_release_apple_event_handler() +{ + if(app_proc_ae_handlerUPP) { + for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) + AERemoveEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, + app_proc_ae_handlerUPP, true); + DisposeAEEventHandlerUPP(app_proc_ae_handlerUPP); + app_proc_ae_handlerUPP = 0; + } +} + /***************************************************************************** qt_cleanup() - cleans up when the application is finished *****************************************************************************/ @@ -1223,15 +1230,8 @@ void qt_cleanup() DisposeEventHandlerUPP(app_proc_handlerUPP); app_proc_handlerUPP = 0; } - if(app_proc_ae_handlerUPP) { - for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) - AERemoveEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, - app_proc_ae_handlerUPP, true); - DisposeAEEventHandlerUPP(app_proc_ae_handlerUPP); - app_proc_ae_handlerUPP = NULL; - } #endif - + qt_release_apple_event_handler(); qt_release_tablet_proximity_handler(); if (tablet_proximity_UPP) DisposeEventHandlerUPP(tablet_proximity_UPP); @@ -2358,6 +2358,12 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event #endif } +// In Carbon this is your one stop for apple events. +// In Cocoa, it ISN'T. This is the catch-all Apple Event handler that exists +// for the time between instantiating the NSApplication, but before the +// NSApplication has installed it's OWN Apple Event handler. When Cocoa has +// that set up, we remove this. So, if you are debugging problems, you likely +// want to check out QCocoaApplicationDelegate instead. OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, AppleEvent *, long handlerRefcon) { QApplication *app = (QApplication *)handlerRefcon; diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp index fcfd2a4..1125610 100644 --- a/src/gui/kernel/qapplication_qws.cpp +++ b/src/gui/kernel/qapplication_qws.cpp @@ -2676,9 +2676,6 @@ void QApplication::alert(QWidget *, int) { } -/*! - \internal -*/ int QApplication::qwsProcessEvent(QWSEvent* event) { Q_D(QApplication); @@ -3057,43 +3054,11 @@ int QApplication::qwsProcessEvent(QWSEvent* event) return 0; } -/*! - \fn bool QApplication::qwsEventFilter(QWSEvent *event) - - This virtual function is only implemented under Qt for Embedded Linux. - - If you create an application that inherits QApplication and - reimplement this function, you get direct access to all QWS (Q - Window System) events that the are received from the QWS master - process. The events are passed in the \a event parameter. - - Return true if you want to stop the event from being processed. - Return false for normal event dispatching. The default - implementation returns false. -*/ bool QApplication::qwsEventFilter(QWSEvent *) { return false; } -/*! - Set Qt for Embedded Linux custom color table. - - Qt for Embedded Linux on 8-bpp displays allocates a standard 216 color cube. - The remaining 40 colors may be used by setting a custom color - table in the QWS master process before any clients connect. - - \a colorTable is an array of up to 40 custom colors. \a start is - the starting index (0-39) and \a numColors is the number of colors - to be set (1-40). - - This method is non-portable. It is available \e only in - Qt for Embedded Linux. - - \note The custom colors will not be used by the default screen - driver. To make use of the new colors, implement a custom screen - driver, or use QDirectPainter. -*/ void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors) { if (start < 0 || start > 39) { @@ -3112,30 +3077,11 @@ void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors } #ifndef QT_NO_QWS_MANAGER -/*! - Return the QWSDecoration used for decorating windows. - - \warning This method is non-portable. It is only available in - Qt for Embedded Linux. - - \sa QDecoration -*/ QDecoration &QApplication::qwsDecoration() { return *qws_decoration; } -/*! - \fn void QApplication::qwsSetDecoration(QDecoration *decoration) - - Sets the QDecoration derived class to use for decorating the - windows used by Qt for Embedded Linux to the \a decoration - specified. - - This method is non-portable. It is only available in Qt for Embedded Linux. - - \sa QDecoration -*/ void QApplication::qwsSetDecoration(QDecoration *dec) { if (dec) { @@ -3154,21 +3100,6 @@ void QApplication::qwsSetDecoration(QDecoration *dec) } } -/*! - \overload - - Requests a QDecoration object for \a decoration from the QDecorationFactory. - - The string must be one of the QDecorationFactory::keys(). Keys are - case insensitive. - - A later call to the QApplication constructor will override the - requested style when a "-style" option is passed in as a commandline - parameter. - - Returns 0 if an unknown \a decoration is passed, otherwise the QStyle object - returned is set as the application's GUI style. -*/ QDecoration* QApplication::qwsSetDecoration(const QString &decoration) { QDecoration *decore = QDecorationFactory::create(decoration); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 07b3865..6237657 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -1368,13 +1368,6 @@ QString QApplicationPrivate::appName() const extern uint qGlobalPostedEventsCount(); -/*! - \internal - \since 4.1 - - If \a gotFocus is true, \a widget will become the active window. - Otherwise the active window is reset to 0. -*/ void QApplication::winFocus(QWidget *widget, bool gotFocus) { if (d_func()->inPopupMode()) // some delayed focus event to ignore @@ -1729,6 +1722,21 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam // fall-through intended case WM_KEYUP: case WM_SYSKEYUP: +#if Q_OS_WINCE_WM + case WM_HOTKEY: + if(HIWORD(msg.lParam) == VK_TBACK) { + const bool hotKeyDown = !(LOWORD(msg.lParam) & MOD_KEYUP); + msg.lParam = 0x69 << 16; + msg.wParam = VK_BACK; + if (hotKeyDown) { + msg.message = WM_KEYDOWN; + qt_keymapper_private()->updateKeyMap(msg); + } else { + msg.message = WM_KEYUP; + } + } + // fall-through intended +#endif case WM_IME_CHAR: case WM_IME_KEYDOWN: case WM_CHAR: { @@ -2429,10 +2437,12 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam widget = (QETWidget*)qApp->focusWidget(); HWND focus = ::GetFocus(); //if there is a current widget and the new widget belongs to the same toplevel window + //or if the current widget was embedded into non-qt window (i.e. we won't get WM_ACTIVATEAPP) //then we clear the focus on the widget //in case the new widget belongs to a different widget hierarchy, clearing the focus //will be handled because the active window will change - if (widget && ::IsChild(widget->window()->internalWinId(), focus)) { + const bool embedded = widget && ((QETWidget*)widget->window())->topData()->embedded; + if (widget && (embedded || ::IsChild(widget->window()->internalWinId(), focus))) { widget->clearFocus(); result = true; } else { @@ -2916,7 +2926,6 @@ void qt_win_eatMouseMove() // In DnD, the mouse release event never appears, so the // mouse button state machine must be manually reset -/*! \internal */ void QApplication::winMouseButtonUp() { qt_button_down = 0; diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index d7ca2f4..90376b3 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -2975,15 +2975,10 @@ QWidget *QApplication::topLevelAt(const QPoint &p) #endif } -/*! - Synchronizes with the X server in the X11 implementation. This - normally takes some time. Does nothing on other platforms. -*/ - void QApplication::syncX() { if (X11->display) - XSync(X11->display, False); // don't discard events + XSync(X11->display, False); // don't discard events } @@ -3085,9 +3080,6 @@ static QETWidget *qPRFindWidget(Window oldwin) return wPRmapper ? (QETWidget*)wPRmapper->value((int)oldwin, 0) : 0; } -/*! - \internal -*/ int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only) { if (w && !w->internalWinId()) @@ -3150,17 +3142,6 @@ int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only) return 0; } -/*! - This function does the core processing of individual X - \a{event}s, normally by dispatching Qt events to the right - destination. - - It returns 1 if the event was consumed by special handling, 0 if - the \a event was consumed by normal handling, and -1 if the \a - event was for an unrecognized widget. - - \sa x11EventFilter() -*/ int QApplication::x11ProcessEvent(XEvent* event) { Q_D(QApplication); @@ -3168,43 +3149,48 @@ int QApplication::x11ProcessEvent(XEvent* event) #ifdef ALIEN_DEBUG //qDebug() << "QApplication::x11ProcessEvent:" << event->type; #endif + Time time = 0, userTime = 0; switch (event->type) { case ButtonPress: pressed_window = event->xbutton.window; - X11->userTime = event->xbutton.time; + userTime = event->xbutton.time; // fallthrough intended case ButtonRelease: - X11->time = event->xbutton.time; + time = event->xbutton.time; break; case MotionNotify: - X11->time = event->xmotion.time; + time = event->xmotion.time; break; case XKeyPress: - X11->userTime = event->xkey.time; + userTime = event->xkey.time; // fallthrough intended case XKeyRelease: - X11->time = event->xkey.time; + time = event->xkey.time; break; case PropertyNotify: - X11->time = event->xproperty.time; + time = event->xproperty.time; break; case EnterNotify: case LeaveNotify: - X11->time = event->xcrossing.time; + time = event->xcrossing.time; break; case SelectionClear: - X11->time = event->xselectionclear.time; + time = event->xselectionclear.time; break; default: - break; - } #ifndef QT_NO_XFIXES - if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) { - XFixesSelectionNotifyEvent *req = - reinterpret_cast<XFixesSelectionNotifyEvent *>(event); - X11->time = req->selection_timestamp; - } + if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) { + XFixesSelectionNotifyEvent *req = + reinterpret_cast<XFixesSelectionNotifyEvent *>(event); + time = req->selection_timestamp; + } #endif + break; + } + if (time > X11->time) + X11->time = time; + if (userTime > X11->userTime) + X11->userTime = userTime; QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window); @@ -3837,29 +3823,6 @@ int QApplication::x11ProcessEvent(XEvent* event) return 0; } -/*! - \fn bool QApplication::x11EventFilter(XEvent *event) - - \warning This virtual function is only implemented under X11. - - If you create an application that inherits QApplication and - reimplement this function, you get direct access to all X events - that the are received from the X server. The events are passed in - the \a event parameter. - - Return true if you want to stop the event from being processed. - Return false for normal event dispatching. The default - implementation returns false. - - It is only the directly addressed messages that are filtered. - You must install an event filter directly on the event - dispatcher, which is returned by - QAbstractEventDispatcher::instance(), to handle system wide - messages. - - \sa x11ProcessEvent() -*/ - bool QApplication::x11EventFilter(XEvent *) { return false; diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index 917b5d5..6daf433 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -50,6 +50,7 @@ #include "qvariant.h" #include "qbuffer.h" #include "qimage.h" +#include "qtextcodec.h" QT_BEGIN_NAMESPACE @@ -276,11 +277,12 @@ QClipboard::~QClipboard() */ QString QClipboard::text(QString &subtype, Mode mode) const { - const QMimeData *data = mimeData(mode); + const QMimeData *const data = mimeData(mode); if (!data) return QString(); + + const QStringList formats = data->formats(); if (subtype.isEmpty()) { - QStringList formats = data->formats(); if (formats.contains(QLatin1String("text/plain"))) subtype = QLatin1String("plain"); else { @@ -289,13 +291,21 @@ QString QClipboard::text(QString &subtype, Mode mode) const subtype = formats.at(i).mid(5); break; } + if (subtype.isEmpty()) + return QString(); } - } - if (subtype.isEmpty()) + } else if (!formats.contains(QLatin1String("text/") + subtype)) { return QString(); - if (subtype == QLatin1String("plain")) - return data->text(); - return QString::fromUtf8(data->data(QLatin1String("text/") + subtype)); + } + + const QByteArray rawData = data->data(QLatin1String("text/") + subtype); + + QTextCodec* codec = QTextCodec::codecForMib(106); // utf-8 is default + if (subtype == QLatin1String("html")) + codec = QTextCodec::codecForHtml(rawData, codec); + else + codec = QTextCodec::codecForUtfText(rawData, codec); + return codec->toUnicode(rawData); } /*! diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp index 089cc43..d7eb111 100644 --- a/src/gui/kernel/qclipboard_x11.cpp +++ b/src/gui/kernel/qclipboard_x11.cpp @@ -786,7 +786,7 @@ static Atom send_selection(QClipboardData *d, Atom target, Window window, Atom p QByteArray data; QByteArray fmt = X11->xdndAtomToString(target); - if (fmt.isEmpty() || !QInternalMimeData::hasFormatHelper(QString::fromAscii(fmt), d->source())) { // Not a MIME type we have + if (fmt.isEmpty()) { // Not a MIME type we have DEBUG("QClipboard: send_selection(): converting to type '%s' is not supported", fmt.data()); return XNone; } diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index 6571068..9a24645 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -183,27 +183,32 @@ static void cleanupCocoaApplicationDelegate() { Q_UNUSED(sender); // The reflection delegate gets precedence - NSApplicationTerminateReply reply = NSTerminateCancel; if (reflectionDelegate && [reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)]) { return [reflectionDelegate applicationShouldTerminate:sender]; } if (qtPrivate->canQuit()) { - reply = NSTerminateNow; if (!startedQuit) { startedQuit = true; qAppInstance()->quit(); startedQuit = false; } } - return reply; + + // Prevent Cocoa from terminating the application, since this simply + // exits the program whithout allowing QApplication::exec() to return. + // The call to QApplication::quit() above will instead quit the + // application from the Qt side. + return NSTerminateCancel; } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { Q_UNUSED(aNotification); inLaunch = false; + extern void qt_release_apple_event_handler(); //qapplication_mac.mm + qt_release_apple_event_handler(); } - (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 60ac062..1cbc960 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -199,6 +199,7 @@ extern "C" { composingText = new QString(); composing = false; sendKeyEvents = true; + currentCustomTypes = 0; [self setHidden:YES]; return self; } @@ -213,10 +214,16 @@ extern "C" { object:self]; } --(void)registerDragTypes:(bool)accept +-(void)registerDragTypes { QMacCocoaAutoReleasePool pool; - if (accept) { + // Calling registerForDraggedTypes is slow, so only do it once for each widget + // or when the custom types change. + const QStringList& customTypes = qEnabledDraggedTypes(); + if (currentCustomTypes == 0 || *currentCustomTypes != customTypes) { + if (currentCustomTypes == 0) + currentCustomTypes = new QStringList(); + *currentCustomTypes = customTypes; const NSString* mimeTypeGeneric = @"com.trolltech.qt.MimeTypeName"; NSMutableArray *supportedTypes = [NSMutableArray arrayWithObjects:NSColorPboardType, NSFilenamesPboardType, NSStringPboardType, @@ -228,13 +235,10 @@ extern "C" { NSFilesPromisePboardType, NSInkTextPboardType, NSMultipleTextSelectionPboardType, mimeTypeGeneric, nil]; // Add custom types supported by the application. - const QStringList& customTypes = qEnabledDraggedTypes(); for (int i = 0; i < customTypes.size(); i++) { [supportedTypes addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(customTypes[i]))]; } [self registerForDraggedTypes:supportedTypes]; - } else { - [self unregisterDraggedTypes]; } } @@ -283,6 +287,8 @@ extern "C" { - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender { + if (qwidget->testAttribute(Qt::WA_DropSiteRegistered) == false) + return NSDragOperationNone; [self addDropData:sender]; QMimeData *mimeData = dropData; if (QDragManager::self()->source()) @@ -416,6 +422,8 @@ extern "C" { { delete composingText; [[NSNotificationCenter defaultCenter] removeObserver:self]; + delete currentCustomTypes; + [self unregisterDraggedTypes]; [super dealloc]; } diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index ec1281e..1d4e3e4 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -84,6 +84,7 @@ Q_GUI_EXPORT int composingLength; bool sendKeyEvents; QString *composingText; + QStringList *currentCustomTypes; } - (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; - (void) finishInitWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; @@ -92,7 +93,7 @@ Q_GUI_EXPORT - (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender; - (void)draggingExited:(id < NSDraggingInfo >)sender; - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender; -- (void)registerDragTypes:(bool)accept; +- (void)registerDragTypes; - (void)removeDropData; - (void)addDropData:(id <NSDraggingInfo>)sender; - (void)setSupportedActions:(NSDragOperation)actions; diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp index 4c9c73c..9b2305d 100644 --- a/src/gui/kernel/qdnd_x11.cpp +++ b/src/gui/kernel/qdnd_x11.cpp @@ -542,6 +542,8 @@ bool QX11Data::xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data dm->xdndMimeTransferedPixmapIndex = (dm->xdndMimeTransferedPixmapIndex + 1) % 2; } + } else { + DEBUG("QClipboard: xdndMimeDataForAtom(): converting to type '%s' is not supported", qPrintable(atomName)); } } return data; @@ -622,28 +624,12 @@ QVariant QX11Data::xdndMimeConvertToFormat(Atom a, const QByteArray &data, const if (format == QLatin1String("image/ppm")) { if (a == XA_PIXMAP && data.size() == sizeof(Pixmap)) { Pixmap xpm = *((Pixmap*)data.data()); - Display *dpy = display; - Window r; - int x,y; - uint w,h,bw,d; if (!xpm) return QByteArray(); - XGetGeometry(dpy,xpm, &r,&x,&y,&w,&h,&bw,&d); + QPixmap qpm = QPixmap::fromX11Pixmap(xpm); QImageWriter imageWriter; - GC gc = XCreateGC(dpy, xpm, 0, 0); - QImage imageToWrite; - if (d == 1) { - QBitmap qbm(w,h); - XCopyArea(dpy,xpm,qbm.handle(),gc,0,0,w,h,0,0); - imageWriter.setFormat("PBMRAW"); - imageToWrite = qbm.toImage(); - } else { - QPixmap qpm(w,h); - XCopyArea(dpy,xpm,qpm.handle(),gc,0,0,w,h,0,0); - imageWriter.setFormat("PPMRAW"); - imageToWrite = qpm.toImage(); - } - XFreeGC(dpy,gc); + imageWriter.setFormat("PPMRAW"); + QImage imageToWrite = qpm.toImage(); QBuffer buf; buf.open(QIODevice::WriteOnly); imageWriter.setDevice(&buf); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 8c7e47d..0ab4423 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -675,12 +675,13 @@ QWheelEvent::QWheelEvent(const QPoint &pos, const QPoint& globalPos, int delta, The \a type parameter must be QEvent::KeyPress, QEvent::KeyRelease, or QEvent::ShortcutOverride. - If \a key is 0, the event is not a result of - a known key; for example, it may be the result of a compose - sequence or keyboard macro. The \a modifiers holds the keyboard - modifiers, and the given \a text is the Unicode text that the - key generated. If \a autorep is true, isAutoRepeat() will be - true. \a count is the number of keys involved in the event. + Int \a key is the code for the Qt::Key that the event loop should listen + for. If \a key is 0, the event is not a result of a known key; for + example, it may be the result of a compose sequence or keyboard macro. + The \a modifiers holds the keyboard modifiers, and the given \a text + is the Unicode text that the key generated. If \a autorep is true, + isAutoRepeat() will be true. \a count is the number of keys involved + in the event. */ QKeyEvent::QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, const QString& text, bool autorep, ushort count) @@ -860,6 +861,17 @@ bool QKeyEvent::matches(QKeySequence::StandardKey matchKey) const uint searchkey = (modifiers() | key()) & ~(Qt::KeypadModifier); //The keypad modifier should not make a difference uint platform = QApplicationPrivate::currentPlatform(); +#ifdef Q_WS_MAC + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + uint oldSearchKey = searchkey; + searchkey &= ~(Qt::ControlModifier | Qt::MetaModifier); + if (oldSearchKey & Qt::ControlModifier) + searchkey |= Qt::MetaModifier; + if (oldSearchKey & Qt::MetaModifier) + searchkey |= Qt::ControlModifier; + } +#endif + uint N = QKeySequencePrivate::numberOfKeyBindings; int first = 0; int last = N - 1; diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index cc94aad..8e762d6 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE // // ### Qt 5: remove -class Q_GUI_EXPORT QKeyEventEx : public QKeyEvent +class QKeyEventEx : public QKeyEvent { public: QKeyEventEx(Type type, int key, Qt::KeyboardModifiers modifiers, @@ -76,7 +76,7 @@ protected: }; // ### Qt 5: remove -class Q_GUI_EXPORT QMouseEventEx : public QMouseEvent +class QMouseEventEx : public QMouseEvent { public: QMouseEventEx(Type type, const QPointF &pos, const QPoint &globalPos, diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp index e2d6108..a665c89 100644 --- a/src/gui/kernel/qformlayout.cpp +++ b/src/gui/kernel/qformlayout.cpp @@ -689,12 +689,16 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width) // are split. maxLabelWidth = 0; if (!wrapAllRows) { + int maxFieldMinWidth = 0; //the maximum minimum size of the field for (int i = 0; i < rr; ++i) { const QFormLayoutItem *label = m_matrix(i, 0); const QFormLayoutItem *field = m_matrix(i, 1); - if (label && (label->sizeHint.width() + (field ? field->minSize.width() : 0) <= width)) + if (label && field && label->sideBySide) maxLabelWidth = qMax(maxLabelWidth, label->sizeHint.width()); + if (field) + maxFieldMinWidth = qMax(maxFieldMinWidth, field->minSize.width() + field->sbsHSpace); } + maxLabelWidth = qMin(maxLabelWidth, width - maxFieldMinWidth); } else { maxLabelWidth = width; } diff --git a/src/gui/kernel/qkeymapper.cpp b/src/gui/kernel/qkeymapper.cpp index 535d009..503a33b 100644 --- a/src/gui/kernel/qkeymapper.cpp +++ b/src/gui/kernel/qkeymapper.cpp @@ -116,6 +116,4 @@ QKeyMapperPrivate *qt_keymapper_private() return QKeyMapper::instance()->d_func(); } -Q_GUI_EXPORT QList<int> qt_keymapper_possibleKeys(QKeyEvent *e) { return QKeyMapper::instance()->possibleKeys(e); } - QT_END_NAMESPACE diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp index 39abc5e..01b2c13 100644 --- a/src/gui/kernel/qkeymapper_mac.cpp +++ b/src/gui/kernel/qkeymapper_mac.cpp @@ -161,6 +161,14 @@ Qt::KeyboardModifiers qt_mac_get_modifiers(int keys) ret |= Qt::KeyboardModifier(qt_mac_modifier_symbols[i].qt_code); } } + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + Qt::KeyboardModifiers oldModifiers = ret; + ret &= ~(Qt::MetaModifier | Qt::ControlModifier); + if (oldModifiers & Qt::ControlModifier) + ret |= Qt::MetaModifier; + if (oldModifiers & Qt::MetaModifier) + ret |= Qt::ControlModifier; + } return ret; } static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys) @@ -177,6 +185,15 @@ static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys) ret |= qt_mac_modifier_symbols[i].mac_code; } } + + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + int oldModifiers = ret; + ret &= ~(controlKeyBit | cmdKeyBit); + if (oldModifiers & controlKeyBit) + ret |= cmdKeyBit; + if (oldModifiers & cmdKeyBit) + ret |= controlKeyBit; + } return ret; } void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object) diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 352d26a..d1cb572 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -105,20 +105,39 @@ static bool operator<(int key, const MacSpecialKey &entry) static const MacSpecialKey * const MacSpecialKeyEntriesEnd = entries + NumEntries; -static QChar macSymbolForQtKey(int key) +QChar qt_macSymbolForQtKey(int key) { const MacSpecialKey *i = qBinaryFind(entries, MacSpecialKeyEntriesEnd, key); if (i == MacSpecialKeyEntriesEnd) return QChar(); - return QChar(i->macSymbol); + ushort macSymbol = i->macSymbol; + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) + && (macSymbol == kControlUnicode || macSymbol == kCommandUnicode)) { + if (macSymbol == kControlUnicode) + macSymbol = kCommandUnicode; + else + macSymbol = kControlUnicode; + } + + return QChar(macSymbol); } static int qtkeyForMacSymbol(const QChar ch) { + const ushort unicode = ch.unicode(); for (int i = 0; i < NumEntries; ++i) { const MacSpecialKey &entry = entries[i]; - if (entry.macSymbol == ch.unicode()) - return entry.key; + if (entry.macSymbol == unicode) { + int key = entry.key; + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) + && (unicode == kControlUnicode || unicode == kCommandUnicode)) { + if (unicode == kControlUnicode) + key = Qt::Key_Control; + else + key = Qt::Key_Meta; + } + return key; + } } return -1; } @@ -213,12 +232,14 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni \row \i Open \i Ctrl+O \i Ctrl+O \i Ctrl+O \i Ctrl+O \row \i Close \i Ctrl+F4, Ctrl+W \i Ctrl+W, Ctrl+F4 \i Ctrl+W \i Ctrl+W \row \i Save \i Ctrl+S \i Ctrl+S \i Ctrl+S \i Ctrl+S + \row \i Quit \i \i Ctrl+Q \i Qtrl+Q \i Qtrl+Q \row \i SaveAs \i \i Ctrl+Shift+S \i \i Ctrl+Shift+S \row \i New \i Ctrl+N \i Ctrl+N \i Ctrl+N \i Ctrl+N \row \i Delete \i Del \i Del, Meta+D \i Del, Ctrl+D \i Del, Ctrl+D \row \i Cut \i Ctrl+X, Shift+Del \i Ctrl+X \i Ctrl+X, F20, Shift+Del \i Ctrl+X, F20, Shift+Del \row \i Copy \i Ctrl+C, Ctrl+Ins \i Ctrl+C \i Ctrl+C, F16, Ctrl+Ins \i Ctrl+C, F16, Ctrl+Ins \row \i Paste \i Ctrl+V, Shift+Ins \i Ctrl+V \i Ctrl+V, F18, Shift+Ins \i Ctrl+V, F18, Shift+Ins + \row \i Preferences \i \i Ctrl+, \i \i \row \i Undo \i Ctrl+Z, Alt+Backspace \i Ctrl+Z \i Ctrl+Z, F14 \i Ctrl+Z, F14 \row \i Redo \i Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \i Ctrl+Shift+Z, Ctrl+Y \i Ctrl+Shift+Z \i Ctrl+Shift+Z \row \i Back \i Alt+Left, Backspace \i Ctrl+[ \i Alt+Left \i Alt+Left @@ -521,6 +542,7 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = { {QKeySequence::FindPrevious, 1, Qt::SHIFT | Qt::Key_F3, QApplicationPrivate::KB_Win}, {QKeySequence::ZoomIn, 1, Qt::CTRL | Qt::Key_Plus, QApplicationPrivate::KB_All}, {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Comma, QApplicationPrivate::KB_KDE}, + {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, QApplicationPrivate::KB_Mac}, {QKeySequence::ZoomOut, 1, Qt::CTRL | Qt::Key_Minus, QApplicationPrivate::KB_All}, {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::Key_Period, QApplicationPrivate::KB_KDE}, {QKeySequence::HelpContents, 1, Qt::CTRL | Qt::Key_Question, QApplicationPrivate::KB_Mac}, @@ -538,6 +560,7 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = { {QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, QApplicationPrivate::KB_All}, {QKeySequence::Open, 1, Qt::CTRL | Qt::Key_O, QApplicationPrivate::KB_All}, {QKeySequence::Print, 1, Qt::CTRL | Qt::Key_P, QApplicationPrivate::KB_All}, + {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_KDE | QApplicationPrivate::KB_Mac}, {QKeySequence::Refresh, 1, Qt::CTRL | Qt::Key_R, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac}, {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_R, QApplicationPrivate::KB_KDE}, {QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, QApplicationPrivate::KB_All}, @@ -671,12 +694,14 @@ const uint QKeySequencePrivate::numberOfKeyBindings = sizeof(QKeySequencePrivate \value NextChild Navigate to next tab or child window. \value Open Open document. \value Paste Paste. + \value Preferences Open the preferences dialog. \value PreviousChild Navigate to previous tab or child window. \value Print Print document. + \value Quit Quit the application. \value Redo Redo. \value Refresh Refresh or reload current document. \value Replace Find and replace. - \value SaveAs Save document after prompting the user for a file name. + \value SaveAs Save document after prompting the user for a file name. \value Save Save document. \value SelectAll Select all text. \value SelectEndOfBlock Extend selection to the end of a text block. This shortcut is only used on OS X. @@ -782,6 +807,21 @@ QKeySequence::QKeySequence(const QKeySequence& keysequence) d->ref.ref(); } +#ifdef Q_WS_MAC +static inline int maybeSwapShortcut(int shortcut) +{ + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + uint oldshortcut = shortcut; + shortcut &= ~(Qt::CTRL | Qt::META); + if (oldshortcut & Qt::CTRL) + shortcut |= Qt::META; + if (oldshortcut & Qt::META) + shortcut |= Qt::CTRL; + } + return shortcut; +} +#endif + /*! \since 4.2 @@ -798,10 +838,16 @@ QList<QKeySequence> QKeySequence::keyBindings(StandardKey key) for (uint i = 0; i < QKeySequencePrivate::numberOfKeyBindings ; ++i) { QKeyBinding keyBinding = QKeySequencePrivate::keyBindings[i]; if (keyBinding.standardKey == key && (keyBinding.platform & platform)) { - if (keyBinding.priority > 0) - list.prepend(QKeySequence(QKeySequencePrivate::keyBindings[i].shortcut)); - else - list.append(QKeySequence(QKeySequencePrivate::keyBindings[i].shortcut)); + uint shortcut = +#ifdef Q_WS_MAC + maybeSwapShortcut(QKeySequencePrivate::keyBindings[i].shortcut); +#else + QKeySequencePrivate::keyBindings[i].shortcut; +#endif + if (keyBinding.priority > 0) + list.prepend(QKeySequence(shortcut)); + else + list.append(QKeySequence(shortcut)); } } return list; @@ -969,9 +1015,16 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence gmodifs = globalModifs(); if (gmodifs->isEmpty()) { #ifdef Q_WS_MAC - *gmodifs << QModifKeyName(Qt::CTRL, QChar(kCommandUnicode)); + const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta); + if (dontSwap) + *gmodifs << QModifKeyName(Qt::META, QChar(kCommandUnicode)); + else + *gmodifs << QModifKeyName(Qt::CTRL, QChar(kCommandUnicode)); *gmodifs << QModifKeyName(Qt::ALT, QChar(kOptionUnicode)); - *gmodifs << QModifKeyName(Qt::META, QChar(kControlUnicode)); + if (dontSwap) + *gmodifs << QModifKeyName(Qt::CTRL, QChar(kControlUnicode)); + else + *gmodifs << QModifKeyName(Qt::META, QChar(kControlUnicode)); *gmodifs << QModifKeyName(Qt::SHIFT, QChar(kShiftUnicode)); #endif *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+")) @@ -1069,8 +1122,6 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence if (found) break; } -#ifdef Q_WS_MAC -#endif } return ret; } @@ -1099,15 +1150,30 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat QString s; #if defined(Q_WS_MAC) if (nativeText) { - // On MAC the order is Meta, Alt, Shift, Control. - if ((key & Qt::META) == Qt::META) - s += macSymbolForQtKey(Qt::Key_Meta); - if ((key & Qt::ALT) == Qt::ALT) - s += macSymbolForQtKey(Qt::Key_Alt); - if ((key & Qt::SHIFT) == Qt::SHIFT) - s += macSymbolForQtKey(Qt::Key_Shift); - if ((key & Qt::CTRL) == Qt::CTRL) - s += macSymbolForQtKey(Qt::Key_Control); + // On Mac OS X the order (by default) is Meta, Alt, Shift, Control. + // If the AA_MacDontSwapCtrlAndMeta is enabled, then the order + // is Ctrl, Alt, Shift, Meta. The macSymbolForQtKey does this swap + // for us, which means that we have to adjust our order here. + // The upshot is a lot more infrastructure to keep the number of + // if tests down and the code relatively clean. + static const int ModifierOrder[] = { Qt::META, Qt::ALT, Qt::SHIFT, Qt::CTRL, 0 }; + static const int QtKeyOrder[] = { Qt::Key_Meta, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Control, 0 }; + static const int DontSwapModifierOrder[] = { Qt::CTRL, Qt::ALT, Qt::SHIFT, Qt::META, 0 }; + static const int DontSwapQtKeyOrder[] = { Qt::Key_Control, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Meta, 0 }; + const int *modifierOrder; + const int *qtkeyOrder; + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + modifierOrder = DontSwapModifierOrder; + qtkeyOrder = DontSwapQtKeyOrder; + } else { + modifierOrder = ModifierOrder; + qtkeyOrder = QtKeyOrder; + } + + for (int i = 0; modifierOrder[i] != 0; ++i) { + if (key & modifierOrder[i]) + s += qt_macSymbolForQtKey(qtkeyOrder[i]); + } } else #endif { @@ -1140,7 +1206,7 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat int i=0; #if defined(Q_WS_MAC) if (nativeText) { - QChar ch = macSymbolForQtKey(key); + QChar ch = qt_macSymbolForQtKey(key); if (!ch.isNull()) p = ch; else diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h index 1c4776f..f78e34a 100644 --- a/src/gui/kernel/qkeysequence.h +++ b/src/gui/kernel/qkeysequence.h @@ -136,7 +136,9 @@ public: DeleteEndOfLine, InsertParagraphSeparator, InsertLineSeparator, - SaveAs + SaveAs, + Preferences, + Quit }; QKeySequence(); diff --git a/src/gui/kernel/qlayout.cpp b/src/gui/kernel/qlayout.cpp index 1d5a70d..4463aab 100644 --- a/src/gui/kernel/qlayout.cpp +++ b/src/gui/kernel/qlayout.cpp @@ -1028,8 +1028,13 @@ void QLayout::freeze(int w, int h) void QLayout::setMenuBar(QWidget *widget) { Q_D(QLayout); - if (widget) - addChildWidget(widget); + +#ifdef Q_OS_WINCE_WM + if (widget && widget->size().height() > 0) +#else + if (widget) +#endif + addChildWidget(widget); d->menubar = widget; } diff --git a/src/gui/kernel/qlayoutitem.cpp b/src/gui/kernel/qlayoutitem.cpp index 0fd73b8..c70ab2d 100644 --- a/src/gui/kernel/qlayoutitem.cpp +++ b/src/gui/kernel/qlayoutitem.cpp @@ -54,7 +54,8 @@ QT_BEGIN_NAMESPACE inline static QRect fromLayoutItemRect(QWidgetPrivate *priv, const QRect &rect) { - return priv->fromOrToLayoutItemRect(rect, -1); + return rect.adjusted(priv->leftLayoutItemMargin, priv->topLayoutItemMargin, + -priv->rightLayoutItemMargin, -priv->bottomLayoutItemMargin); } inline static QSize fromLayoutItemSize(QWidgetPrivate *priv, const QSize &size) @@ -64,7 +65,8 @@ inline static QSize fromLayoutItemSize(QWidgetPrivate *priv, const QSize &size) inline static QRect toLayoutItemRect(QWidgetPrivate *priv, const QRect &rect) { - return priv->fromOrToLayoutItemRect(rect, +1); + return rect.adjusted(-priv->leftLayoutItemMargin, -priv->topLayoutItemMargin, + priv->rightLayoutItemMargin, priv->bottomLayoutItemMargin); } inline static QSize toLayoutItemSize(QWidgetPrivate *priv, const QSize &size) diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index ed9654b..f998bb2 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -61,8 +61,6 @@ QT_BEGIN_NAMESPACE -extern bool qt_mac_no_native_menubar; // qmenu_mac.cpp - // To enable verbose output uncomment below //#define DEBUG_QSHORTCUTMAP @@ -660,7 +658,7 @@ bool QShortcutMap::correctWidgetContext(Qt::ShortcutContext context, QWidget *w, { bool visible = w->isVisible(); #ifdef Q_WS_MAC - if (!qt_mac_no_native_menubar && qobject_cast<QMenuBar *>(w)) + if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w)) visible = true; #endif @@ -723,7 +721,7 @@ bool QShortcutMap::correctGraphicsWidgetContext(Qt::ShortcutContext context, QGr { bool visible = w->isVisible(); #ifdef Q_WS_MAC - if (!qt_mac_no_native_menubar && qobject_cast<QMenuBar *>(w)) + if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w)) visible = true; #endif @@ -753,6 +751,7 @@ bool QShortcutMap::correctGraphicsWidgetContext(Qt::ShortcutContext context, QGr tw = tw->parentWidget(); return tw == w; } + return false; } // Below is Qt::WindowShortcut context diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index f000292..9165836 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -826,13 +826,28 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev QWidget *qwidget = [theView qt_qwidget]; QWidget *widgetToGetMouse = qwidget; QWidget *popup = qAppInstance()->activePopupWidget(); - if (popup && popup != qwidget->window()) - widgetToGetMouse = popup; NSView *tmpView = theView; - if (widgetToGetMouse != qwidget) { - tmpView = qt_mac_nativeview_for(widgetToGetMouse); + + if (popup && popup != qwidget->window()) { + widgetToGetMouse = popup; + tmpView = qt_mac_nativeview_for(popup); windowPoint = [[tmpView window] convertScreenToBase:globalPoint]; + + QPoint qWindowPoint(windowPoint.x, windowPoint.y); + if (widgetToGetMouse->rect().contains(qWindowPoint)) { + // Keeping the mouse pressed on a combobox button will make + // the popup pop in front of the mouse. But all mouse events + // will be sendt to the button. Since we want mouse events + // to be sendt to widgets inside the popup, we search for the + // widget in front of the mouse: + tmpView = [tmpView hitTest:windowPoint]; + if (!tmpView) + return false; + widgetToGetMouse = + [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(tmpView) qt_qwidget]; + } } + NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil]; QPoint qlocalPoint(localPoint.x, localPoint.y); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index dd95053..ab529fe 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -167,39 +167,48 @@ static inline bool bypassGraphicsProxyWidget(QWidget *p) extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp -QWidgetPrivate::QWidgetPrivate(int version) : - QObjectPrivate(version), extra(0), focus_child(0) - ,layout(0), widgetItem(0) - ,leftmargin(0), topmargin(0), rightmargin(0), bottommargin(0) - ,leftLayoutItemMargin(0), topLayoutItemMargin(0), rightLayoutItemMargin(0) - ,bottomLayoutItemMargin(0) - ,fg_role(QPalette::NoRole) - ,bg_role(QPalette::NoRole) - ,hd(0) - ,dirty(0) - ,needsFlush(0) - ,dirtyOpaqueChildren(1) - ,isOpaque(0) - ,inDirtyList(0) - ,isScrolled(0) - ,isMoved(0) - ,usesDoubleBufferedGLContext(0) -#ifdef Q_WS_WIN - ,noPaintOnScreen(0) -#endif - ,inheritedFontResolveMask(0) - ,inheritedPaletteResolveMask(0) +QWidgetPrivate::QWidgetPrivate(int version) + : QObjectPrivate(version) + , extra(0) + , focus_next(0) + , focus_prev(0) + , focus_child(0) + , layout(0) + , needsFlush(0) + , redirectDev(0) + , widgetItem(0) + , extraPaintEngine(0) + , polished(0) + , inheritedFontResolveMask(0) + , inheritedPaletteResolveMask(0) + , leftmargin(0) + , topmargin(0) + , rightmargin(0) + , bottommargin(0) + , leftLayoutItemMargin(0) + , topLayoutItemMargin(0) + , rightLayoutItemMargin(0) + , bottomLayoutItemMargin(0) + , hd(0) + , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred) + , fg_role(QPalette::NoRole) + , bg_role(QPalette::NoRole) + , dirtyOpaqueChildren(1) + , isOpaque(0) + , inDirtyList(0) + , isScrolled(0) + , isMoved(0) + , usesDoubleBufferedGLContext(0) #if defined(Q_WS_X11) - ,picture(0) -#endif -#ifdef Q_WS_MAC - ,needWindowChange(0) - ,isGLWidget(0) + , picture(0) +#elif defined(Q_WS_WIN) + , noPaintOnScreen(0) +#elif defined(Q_WS_MAC) + , needWindowChange(0) + , isGLWidget(0) + , window_event(0) + , qd_hd(0) #endif - ,polished(0) - - , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred) - , redirectDev(0) { if (!qApp) { qFatal("QWidget: Must construct a QApplication before a QPaintDevice"); @@ -1345,7 +1354,7 @@ QWidget::~QWidget() d->setDirtyOpaqueRegion(); if (isWindow() && isVisible() && internalWinId()) - hide(); + d->close_helper(QWidgetPrivate::CloseNoEvent); #if defined(Q_WS_WIN) || defined(Q_WS_X11) else if (!internalWinId() && isVisible()) qApp->d_func()->sendSyntheticEnterLeave(this); @@ -1412,36 +1421,26 @@ void QWidgetPrivate::createTLExtra() createExtra(); if (!extra->topextra) { QTLWExtra* x = extra->topextra = new QTLWExtra; + x->icon = 0; + x->iconPixmap = 0; + x->backingStore = 0; x->windowSurface = 0; + x->sharedPainter = 0; + x->incw = x->inch = 0; + x->basew = x->baseh = 0; + x->frameStrut.setCoords(0, 0, 0, 0); + x->normalGeometry = QRect(0,0,-1,-1); + x->savedFlags = 0; x->opacity = 255; x->posFromMove = false; x->sizeAdjusted = false; x->inTopLevelResize = false; x->inRepaint = false; - x->backingStore = 0; - x->icon = 0; - x->iconPixmap = 0; - x->frameStrut.setCoords(0, 0, 0, 0); - x->incw = x->inch = 0; - x->basew = x->baseh = 0; - x->normalGeometry = QRect(0,0,-1,-1); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) x->embedded = 0; -#endif -#if defined(Q_WS_X11) - x->parentWinId = 0; - x->spont_unmapped = 0; - x->dnd = 0; -#endif - x->savedFlags = 0; -#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) - x->qwsManager = 0; -#endif - x->sharedPainter = 0; createTLSysExtra(); #ifdef QWIDGET_EXTRA_DEBUG - static int count = 0; - qDebug() << "tlextra" << ++count; + static int count = 0; + qDebug() << "tlextra" << ++count; #endif } } @@ -1455,27 +1454,28 @@ void QWidgetPrivate::createExtra() { if (!extra) { // if not exists extra = new QWExtra; - extra->minw = extra->minh = 0; - extra->maxw = extra->maxh = QWIDGETSIZE_MAX; + extra->glContext = 0; + extra->topextra = 0; + extra->proxyWidget = 0; +#ifndef QT_NO_CURSOR + extra->curs = 0; +#endif + extra->minw = 0; + extra->minh = 0; + extra->maxw = QWIDGETSIZE_MAX; + extra->maxh = QWIDGETSIZE_MAX; + extra->customDpiX = 0; + extra->customDpiY = 0; extra->explicitMinSize = 0; extra->explicitMaxSize = 0; extra->autoFillBackground = 0; extra->nativeChildrenForced = 0; extra->inRenderWithPainter = 0; extra->hasMask = 0; -#ifndef QT_NO_CURSOR - extra->curs = 0; -#endif - extra->style = 0; - extra->topextra = 0; - extra->proxyWidget = 0; - extra->glContext = 0; - extra->customDpiX = 0; - extra->customDpiY = 0; createSysExtra(); #ifdef QWIDGET_EXTRA_DEBUG - static int count = 0; - qDebug() << "extra" << ++count; + static int count = 0; + qDebug() << "extra" << ++count; #endif } } @@ -1516,45 +1516,6 @@ void QWidgetPrivate::deleteExtra() } /* - Returns true if the background is inherited; otherwise returns - false. - - Mainly used in the paintOnScreen case. -*/ - -bool QWidgetPrivate::isBackgroundInherited() const -{ - Q_Q(const QWidget); - - // windows do not inherit their background - if (q->isWindow() || q->windowType() == Qt::SubWindow) - return false; - - if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent)) - return false; - - const QPalette &pal = q->palette(); - QPalette::ColorRole bg = q->backgroundRole(); - QBrush brush = pal.brush(bg); - - // non opaque brushes leaves us no choice, we must inherit - if (!q->autoFillBackground() || !brush.isOpaque()) - return true; - - if (brush.style() == Qt::SolidPattern) { - // the background is just a solid color. If there is no - // propagated contents, then we claim as performance - // optimization that it was not inheritet. This is the normal - // case in standard Windows or Motif style. - const QWidget *w = q->parentWidget(); - if (!w->d_func()->isBackgroundInherited()) - return false; - } - - return true; -} - -/* Returns true if there are widgets above this which overlap with \a rect, which is in parent's coordinate system (same as crect). */ @@ -1900,24 +1861,6 @@ void QWidgetPrivate::clipToEffectiveMask(QRegion ®ion) const } } -bool QWidgetPrivate::hasBackground() const -{ - Q_Q(const QWidget); - if (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_PaintOnScreen)) - return true; - if (q->testAttribute(Qt::WA_PaintOnScreen)) - return true; - if (!q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) { - const QPalette &pal = q->palette(); - QPalette::ColorRole bg = q->backgroundRole(); - QBrush bgBrush = pal.brush(bg); - return (bgBrush.style() != Qt::NoBrush && - ((q->isWindow() || q->windowType() == Qt::SubWindow) - || (QPalette::ColorRole(bg_role) != QPalette::NoRole || (pal.resolve() & (1<<bg))))); - } - return false; -} - bool QWidgetPrivate::paintOnScreen() const { #if defined(Q_WS_QWS) @@ -4810,7 +4753,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, Q_ASSERT(engine); QPaintEnginePrivate *enginePriv = engine->d_func(); Q_ASSERT(enginePriv); - QPaintDevice *target = painter->worldMatrixEnabled() ? engine->paintDevice() : painter->device(); + QPaintDevice *target = engine->paintDevice(); Q_ASSERT(target); // Render via a pixmap when dealing with non-opaque painters or printers. @@ -6157,14 +6100,6 @@ int QWidgetPrivate::pointToRect(const QPoint &p, const QRect &r) return dx + dy; } -QRect QWidgetPrivate::fromOrToLayoutItemRect(const QRect &rect, int sign) const -{ - QRect r = rect; - r.adjust(-sign * leftLayoutItemMargin, -sign * topLayoutItemMargin, - +sign * rightLayoutItemMargin, +sign * bottomLayoutItemMargin); - return r; -} - /*! \property QWidget::frameSize \brief the size of the widget including any window frame @@ -11420,3 +11355,17 @@ void QWidget::clearMask() setMask(QRegion()); } +/*! \fn const QX11Info &QWidget::x11Info() const + Returns information about the configuration of the X display used to display + the widget. + + \warning This function is only available on X11. +*/ + +/*! \fn Qt::HANDLE QWidget::x11PictureHandle() const + Returns the X11 Picture handle of the widget for XRender + support. Use of this function is not portable. This function will + return 0 if XRender support is not compiled into Qt, if the + XRender extension is not supported on the X11 display, or if the + handle could not be created. +*/ diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index b238279..6d3da61 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -1599,24 +1599,6 @@ bool QWidgetPrivate::qt_create_root_win() return true; } -bool QWidgetPrivate::qt_recreate_root_win() -{ - if(!qt_root_win) //sanity check - return false; - //store old - OSWindowRef old_root_win = qt_root_win; - //recreate - qt_root_win = 0; - qt_create_root_win(); - //cleanup old window -#ifdef QT_MAC_USE_COCOA - [old_root_win release]; -#else - CFRelease(old_root_win); -#endif - return true; -} - bool QWidgetPrivate::qt_widget_rgn(QWidget *widget, short wcode, RgnHandle rgn, bool force = false) { bool ret = false; @@ -2156,6 +2138,7 @@ void QWidgetPrivate::finishCreateWindow_sys_Carbon(OSWindowRef windowRef) setWindowModified_sys(q->isWindowModified()); updateFrameStrut(); qt_mac_update_sizer(q); + applyMaxAndMinSizeOnWindow(); } #else // QT_MAC_USE_COCOA void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWindowRef) @@ -2241,6 +2224,7 @@ void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWin syncCocoaMask(); macUpdateIsOpaque(); qt_mac_update_sizer(q); + applyMaxAndMinSizeOnWindow(); } #endif // QT_MAC_USE_COCOA @@ -3995,7 +3979,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) } } -void QWidgetPrivate::applyMaxAndMinSizeConstraints(int &w, int &h) +void QWidgetPrivate::adjustWithinMaxAndMinSize(int &w, int &h) { if (QWExtra *extra = extraData()) { w = qMin(w, extra->maxw); @@ -4022,6 +4006,26 @@ void QWidgetPrivate::applyMaxAndMinSizeConstraints(int &w, int &h) } } +void QWidgetPrivate::applyMaxAndMinSizeOnWindow() +{ + Q_Q(QWidget); + const float max_f(20000); +#ifndef QT_MAC_USE_COCOA +#define SF(x) ((x > max_f) ? max_f : x) + HISize max = CGSizeMake(SF(extra->maxw), SF(extra->maxh)); + HISize min = CGSizeMake(SF(extra->minw), SF(extra->minh)); +#undef SF + SetWindowResizeLimits(qt_mac_window_for(q), &min, &max); +#else +#define SF(x) ((x > max_f) ? max_f : x) + NSSize max = NSMakeSize(SF(extra->maxw), SF(extra->maxh)); + NSSize min = NSMakeSize(SF(extra->minw), SF(extra->minh)); +#undef SF + [qt_mac_window_for(q) setMinSize:min]; + [qt_mac_window_for(q) setMaxSize:max]; +#endif +} + void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) { Q_Q(QWidget); @@ -4033,17 +4037,18 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) QMacCocoaAutoReleasePool pool; bool realWindow = isRealWindow(); - if (realWindow && !q->testAttribute(Qt::WA_DontShowOnScreen) + if (realWindow && !q->testAttribute(Qt::WA_DontShowOnScreen)){ + adjustWithinMaxAndMinSize(w, h); #ifndef QT_MAC_USE_COCOA - && !(w == 0 && h == 0) -#endif - ){ - applyMaxAndMinSizeConstraints(w, h); - topData()->isSetGeometry = 1; - topData()->isMove = isMove; -#ifndef QT_MAC_USE_COCOA - Rect r; SetRect(&r, x, y, x + w, y + h); - SetWindowBounds(qt_mac_window_for(q), kWindowContentRgn, &r); + if (w != 0 && h != 0) { + topData()->isSetGeometry = 1; + topData()->isMove = isMove; + Rect r; SetRect(&r, x, y, x + w, y + h); + SetWindowBounds(qt_mac_window_for(q), kWindowContentRgn, &r); + topData()->isSetGeometry = 0; + } else { + setGeometry_sys_helper(x, y, w, h, isMove); + } #else NSWindow *window = qt_mac_window_for(q); const QRect &fStrut = frameStrut(); @@ -4071,7 +4076,6 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) [window setFrameOrigin:cocoaFrameRect.origin]; } #endif - topData()->isSetGeometry = 0; } else { setGeometry_sys_helper(x, y, w, h, isMove); } @@ -4096,40 +4100,19 @@ void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isM data.crect = QRect(x, y, w, h); if (realWindow) { - if (QWExtra *extra = extraData()) { - applyMaxAndMinSizeConstraints(w, h); - qt_mac_update_sizer(q); + adjustWithinMaxAndMinSize(w, h); + qt_mac_update_sizer(q); - if (q->windowFlags() & Qt::WindowMaximizeButtonHint) { #ifndef QT_MAC_USE_COCOA - OSWindowRef window = qt_mac_window_for(q); - if(extra->maxw && extra->maxh && extra->maxw == extra->minw - && extra->maxh == extra->minh) { - ChangeWindowAttributes(window, kWindowNoAttributes, kWindowFullZoomAttribute); - } else { - ChangeWindowAttributes(window, kWindowFullZoomAttribute, kWindowNoAttributes); - } -#endif + if (q->windowFlags() & Qt::WindowMaximizeButtonHint) { + OSWindowRef window = qt_mac_window_for(q); + if (extra->maxw && extra->maxh && extra->maxw == extra->minw + && extra->maxh == extra->minh) { + ChangeWindowAttributes(window, kWindowNoAttributes, kWindowFullZoomAttribute); + } else { + ChangeWindowAttributes(window, kWindowFullZoomAttribute, kWindowNoAttributes); } - - // Update max and min constraints: - const float max_f(20000); -#ifndef QT_MAC_USE_COCOA -#define SF(x) ((x > max_f) ? max_f : x) - HISize max = CGSizeMake(SF(extra->maxw), SF(extra->maxh)); - HISize min = CGSizeMake(SF(extra->minw), SF(extra->minh)); -#undef SF - SetWindowResizeLimits(qt_mac_window_for(q), &min, &max); -#else -#define SF(x) ((x > max_f) ? max_f : x) - NSSize max = NSMakeSize(SF(extra->maxw), SF(extra->maxh)); - NSSize min = NSMakeSize(SF(extra->minw), SF(extra->minh)); -#undef SF - [qt_mac_window_for(q) setMinSize:min]; - [qt_mac_window_for(q) setMaxSize:max]; -#endif } -#ifndef QT_MAC_USE_COCOA HIRect bounds = CGRectMake(0, 0, w, h); HIViewSetFrame(qt_mac_nativeview_for(q), &bounds); #else @@ -4175,6 +4158,7 @@ void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isM void QWidgetPrivate::setConstraints_sys() { updateMaximizeButton_sys(); + applyMaxAndMinSizeOnWindow(); } void QWidgetPrivate::updateMaximizeButton_sys() @@ -4436,11 +4420,13 @@ void QWidgetPrivate::deleteSysExtra() void QWidgetPrivate::createTLSysExtra() { + extra->topextra->resizer = 0; + extra->topextra->isSetGeometry = 0; + extra->topextra->isMove = 0; + extra->topextra->wattr = 0; extra->topextra->wclass = 0; extra->topextra->group = 0; extra->topextra->windowIcon = 0; - extra->topextra->resizer = 0; - extra->topextra->isSetGeometry = 0; extra->topextra->savedWindowAttributesFromMaximized = 0; } @@ -4489,8 +4475,8 @@ void QWidgetPrivate::registerDropSite(bool on) SetControlDragTrackingEnabled(qt_mac_nativeview_for(q), on); #else NSView *view = qt_mac_nativeview_for(q); - if ([view isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) { - [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view) registerDragTypes:on]; + if (on && [view isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) { + [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view) registerDragTypes]; } #endif } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 8731551..bf4f091 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -99,88 +99,92 @@ class QWidgetItemV2; class QStyle; struct QTLWExtra { + // *************************** Cross-platform variables ***************************** + + // Regular pointers (keep them together to avoid gaps on 64 bits architectures). + QIcon *icon; // widget icon + QPixmap *iconPixmap; + QWidgetBackingStore *backingStore; + QWindowSurface *windowSurface; + QPainter *sharedPainter; + + // Implicit pointers (shared_null). QString caption; // widget caption QString iconText; // widget icon text QString role; // widget role QString filePath; // widget file path - QIcon *icon; // widget icon - QPixmap *iconPixmap; + + // Other variables. short incw, inch; // size increments + short basew, baseh; // base sizes // frame strut, don't use these directly, use QWidgetPrivate::frameStrut() instead. QRect frameStrut; + QRect normalGeometry; // used by showMin/maximized/FullScreen + Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen + + // *************************** Cross-platform bit fields **************************** uint opacity : 8; uint posFromMove : 1; uint sizeAdjusted : 1; uint inTopLevelResize : 1; uint inRepaint : 1; - QWidgetBackingStore *backingStore; -#if defined(Q_WS_WIN) - ulong savedFlags; // Save window flags while showing fullscreen - uint embedded : 1; // window is embedded in another application -#else - Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen -#endif - short basew, baseh; // base sizes -#if defined(Q_WS_X11) - WId parentWinId; // parent window Id (valid after reparenting) - uint embedded : 1; // window is embedded in another Qt application + uint embedded : 1; + + // *************************** Platform specific values (bit fields first) ********** +#if defined(Q_WS_X11) // <----------------------------------------------------------- X11 uint spont_unmapped: 1; // window was spontaneously unmapped uint dnd : 1; // DND properties installed uint validWMState : 1; // is WM_STATE valid? uint waitingForMapNotify : 1; // show() has been called, haven't got the MapNotify yet + WId parentWinId; // parent window Id (valid after reparenting) WId userTimeWindow; // window id that contains user-time timestamp when WM supports a _NET_WM_USER_TIME_WINDOW atom QPoint fullScreenOffset; -#endif -#if defined(Q_WS_MAC) +#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN + HICON winIconBig; // internal big Windows icon + HICON winIconSmall; // internal small Windows icon +#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC + uint resizer : 4; + uint isSetGeometry : 1; + uint isMove : 1; quint32 wattr; quint32 wclass; WindowGroupRef group; IconRef windowIcon; // the current window icon, if set with setWindowIcon_sys. quint32 savedWindowAttributesFromMaximized; // Saved attributes from when the calling updateMaximizeButton_sys() - uint resizer : 4; - uint isSetGeometry : 1; - uint isMove : 1; - uint embedded : 1; -#endif -#if defined(Q_WS_QWS) && !defined (QT_NO_QWS_MANAGER) +#elif defined(Q_WS_QWS) // <--------------------------------------------------------- QWS +#ifndef QT_NO_QWS_MANAGER QWSManager *qwsManager; #endif -#if defined(Q_WS_WIN) - HICON winIconBig; // internal big Windows icon - HICON winIconSmall; // internal small Windows icon #endif - QRect normalGeometry; // used by showMin/maximized/FullScreen - QWindowSurface *windowSurface; - QPainter *sharedPainter; }; struct QWExtra { - qint32 minw, minh; // minimum size - qint32 maxw, maxh; // maximum size - QPointer<QWidget> focus_proxy; -#ifndef QT_NO_CURSOR - QCursor *curs; -#endif + // *************************** Cross-platform variables ***************************** + + // Regular pointers (keep them together to avoid gaps on 64 bits architectures). + void *glContext; // if the widget is hijacked by QGLWindowSurface QTLWExtra *topextra; // only useful for TLWs QGraphicsProxyWidget *proxyWidget; // if the widget is embedded - void *glContext; // if the widget is hijacked by QGLWindowSurface -#if defined(Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP) - QOleDropTarget *dropTarget; // drop target - QList<QPointer<QWidget> > oleDropWidgets; -#endif -#if defined(Q_WS_X11) - WId xDndProxy; // XDND forwarding to embedded windows +#ifndef QT_NO_CURSOR + QCursor *curs; #endif + QPointer<QStyle> style; + QPointer<QWidget> focus_proxy; + + // Implicit pointers (shared_empty/shared_null). QRegion mask; // widget mask + QString styleSheet; + + // Other variables. + qint32 minw; + qint32 minh; // minimum size + qint32 maxw; + qint32 maxh; // maximum size + quint16 customDpiX; + quint16 customDpiY; QSize staticContentsSize; -//bit flags at the end to improve packing -#if defined(Q_WS_WIN) - uint shown_mode : 8; // widget show mode -#endif -#if defined(Q_WS_X11) - uint compress_events : 1; -#endif + // *************************** Cross-platform bit fields **************************** uint explicitMinSize : 2; uint explicitMaxSize : 2; uint autoFillBackground : 1; @@ -188,16 +192,22 @@ struct QWExtra { uint inRenderWithPainter : 1; uint hasMask : 1; - QPointer<QStyle> style; - QString styleSheet; - - quint16 customDpiX; - quint16 customDpiY; -#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA) + // *************************** Platform specific values (bit fields first) ********** +#if defined(Q_WS_WIN) // <----------------------------------------------------------- WIN +#ifndef QT_NO_DRAGANDDROP + QOleDropTarget *dropTarget; // drop target + QList<QPointer<QWidget> > oleDropWidgets; +#endif +#elif defined(Q_WS_X11) // <--------------------------------------------------------- X11 + uint compress_events : 1; + WId xDndProxy; // XDND forwarding to embedded windows +#elif defined(Q_WS_MAC) // <------------------------------------------------------ MAC +#ifdef QT_MAC_USE_COCOA // Cocoa Mask stuff QImage maskBits; CGImageRef imageMask; #endif +#endif }; class Q_GUI_EXPORT QWidgetPrivate : public QObjectPrivate @@ -205,6 +215,24 @@ class Q_GUI_EXPORT QWidgetPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QWidget) public: + // *************************** Cross-platform *************************************** + enum DrawWidgetFlags { + DrawAsRoot = 0x01, + DrawPaintOnScreen = 0x02, + DrawRecursive = 0x04, + DrawInvisible = 0x08, + DontSubtractOpaqueChildren = 0x10, + DontSetCompositionMode = 0x20, + DontDrawOpaqueChildren = 0x40 + }; + + enum CloseMode { + CloseNoEvent, + CloseWithEvent, + CloseWithSpontaneousEvent + }; + + // Functions. explicit QWidgetPrivate(int version = QObjectPrivateVersion); ~QWidgetPrivate(); @@ -214,10 +242,6 @@ public: QPainter *sharedPainter() const; void setSharedPainter(QPainter *painter); QWidgetBackingStore *maybeBackingStore() const; -#ifdef Q_WS_QWS - void setMaxWindowState_helper(); - void setFullScreenSize_helper(); -#endif void init(QWidget *desktopWidget, Qt::WindowFlags f); void create_sys(WId window, bool initializeWindow, bool destroyOldWindow); void createRecursively(); @@ -238,23 +262,6 @@ public: QPalette naturalWidgetPalette(uint inheritedMask) const; void setMask_sys(const QRegion &); -#ifdef Q_WS_WIN - bool shouldShowMaximizeButton(); - void winUpdateIsOpaque(); -#endif - -#ifdef Q_WS_MAC - void macUpdateSizeAttribute(); - void macUpdateHideOnSuspend(); - void macUpdateOpaqueSizeGrip(); - void macUpdateIgnoreMouseEvents(); - void macUpdateMetalAttribute(); - void macUpdateIsOpaque(); - void setEnabled_helper_sys(bool enable); - bool isRealWindow() const; - void applyMaxAndMinSizeConstraints(int &w, int &h); -#endif - void raise_sys(); void lower_sys(); void stackUnder_sys(QWidget *); @@ -279,20 +286,9 @@ public: void setStyle_helper(QStyle *newStyle, bool propagate, bool metalHack = false); void inheritStyle(); - bool isBackgroundInherited() const; - void setUpdatesEnabled_helper(bool ); void paintBackground(QPainter *, const QRegion &, const QPoint & = QPoint(), int flags = DrawAsRoot) const; - enum DrawWidgetFlags { - DrawAsRoot = 0x01, - DrawPaintOnScreen = 0x02, - DrawRecursive = 0x04, - DrawInvisible = 0x08, - DontSubtractOpaqueChildren = 0x10, - DontSetCompositionMode = 0x20, - DontDrawOpaqueChildren = 0x40 - }; bool isAboutToShow() const; QRegion prepareToRender(const QRegion ®ion, QWidget::RenderFlags renderFlags); void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion, @@ -315,10 +311,6 @@ public: QWindowSurface *createDefaultWindowSurface(); QWindowSurface *createDefaultWindowSurface_sys(); void repaint_sys(const QRegion &rgn); -#ifdef Q_WS_MAC - void update_sys(const QRect &rect); - void update_sys(const QRegion &rgn); -#endif QRect clipRect() const; QRegion clipRegion() const; @@ -329,42 +321,20 @@ public: void updateIsOpaque(); void setOpaque(bool opaque); void updateIsTranslucent(); - bool hasBackground() const; bool paintOnScreen() const; QRegion getOpaqueRegion() const; const QRegion &getOpaqueChildren() const; void setDirtyOpaqueRegion(); - QRegion opaqueChildren; - - enum CloseMode { - CloseNoEvent, - CloseWithEvent, - CloseWithSpontaneousEvent - }; bool close_helper(CloseMode mode); - bool compositeEvent(QEvent *e); void setWindowIcon_helper(); void setWindowIcon_sys(bool forceReset = false); void setWindowOpacity_sys(qreal opacity); - void adjustQuitOnCloseAttribute(); -#if defined(Q_WS_X11) - void setWindowRole(); - void sendStartupMessage(const char *message) const; - void setNetWmWindowTypes(); - void x11UpdateIsOpaque(); -#endif - -#if defined (Q_WS_WIN) - void reparentChildren(); -#endif - void scrollChildren(int dx, int dy); - void moveRect(const QRect &, int dx, int dy); void scrollRect(const QRect &, int dx, int dy); void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize); @@ -378,7 +348,6 @@ public: void reparentFocusWidgets(QWidget *oldtlw); static int pointToRect(const QPoint &p, const QRect &r); - QRect fromOrToLayoutItemRect(const QRect &rect, int sign) const; void setWinId(WId); void showChildren(bool spontaneous); @@ -388,9 +357,6 @@ public: void scroll_sys(int dx, int dy, const QRect &r); void deactivateWidgetCleanup(); void setGeometry_sys(int, int, int, int, bool); -#ifdef Q_WS_MAC - void setGeometry_sys_helper(int, int, int, int, bool); -#endif void sendPendingMoveAndResizeEvents(bool recursive = false, bool disableUpdates = false); void activateChildLayoutsRecursively(); void show_recursive(); @@ -402,10 +368,6 @@ public: void setEnabled_helper(bool); void registerDropSite(bool); -#if defined(Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP) - QOleDropTarget *registerOleDnd(QWidget *widget); - void unregisterOleDnd(QWidget *widget, QOleDropTarget *target); -#endif static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = 0); void updateFrameStrut(); @@ -415,32 +377,11 @@ public: void setWindowIconText_helper(const QString &cap); void setWindowTitle_sys(const QString &cap); -#ifdef Q_OS_WIN - void grabMouseWhileInWindow(); -#endif - #ifndef QT_NO_CURSOR void setCursor_sys(const QCursor &cursor); void unsetCursor_sys(); #endif -#ifdef Q_WS_MAC - void setWindowModified_sys(bool b); - void updateMaximizeButton_sys(); - void setWindowFilePath_sys(const QString &filePath); - void createWindow_sys(); - void recreateMacWindow(); -#ifndef QT_MAC_USE_COCOA - void initWindowPtr(); - void finishCreateWindow_sys_Carbon(OSWindowRef windowRef); -#else - void finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ windowRef); - void syncCocoaMask(); - void finishCocoaMaskSetup(); -#endif - void determineWindowClass(); - void transferChildren(); -#endif void setWindowTitle_helper(const QString &cap); void setWindowFilePath_helper(const QString &filePath); @@ -456,59 +397,89 @@ public: QInputContext *inputContext() const; -#if defined(Q_WS_QWS) - void moveSurface(QWindowSurface *surface, const QPoint &offset); + void setModal_sys(); - QRegion localRequestedRegion() const; - QRegion localAllocatedRegion() const; + inline void setRedirected(QPaintDevice *replacement, const QPoint &offset) + { + Q_ASSERT(q_func()->testAttribute(Qt::WA_WState_InPaintEvent)); + redirectDev = replacement; + redirectOffset = offset; + } - void blitToScreen(const QRegion &globalrgn); -#ifndef QT_NO_CURSOR - void updateCursor() const; -#endif + inline QPaintDevice *redirected(QPoint *offset) const + { + if (offset) + *offset = redirectDev ? redirectOffset : QPoint(); + return redirectDev; + } - QScreen* getScreen() const; + inline void restoreRedirected() + { redirectDev = 0; } - friend class QWSManager; - friend class QWSManagerPrivate; - friend class QDecoration; -#endif + inline void enforceNativeChildren() + { + if (!extra) + createExtra(); - static int instanceCounter; // Current number of widget instances - static int maxInstances; // Maximum number of widget instances + if (extra->nativeChildrenForced) + return; + extra->nativeChildrenForced = 1; -#ifdef QT_KEYPAD_NAVIGATION - static QPointer<QWidget> editingWidget; -#endif + for (int i = 0; i < children.size(); ++i) { + if (QWidget *child = qobject_cast<QWidget *>(children.at(i))) + child->setAttribute(Qt::WA_NativeWindow); + } + } - QWidgetData data; + inline bool nativeChildrenForced() const + { + return extra ? extra->nativeChildrenForced : false; + } + + QSize adjustedSize() const; + +#ifndef Q_WS_QWS // Almost cross-platform :-) + void setWSGeometry(bool dontShow=false, const QRect &oldRect = QRect()); + + inline QPoint mapToWS(const QPoint &p) const + { return p - data.wrect.topLeft(); } + + inline QPoint mapFromWS(const QPoint &p) const + { return p + data.wrect.topLeft(); } + + inline QRect mapToWS(const QRect &r) const + { QRect rr(r); rr.translate(-data.wrect.topLeft()); return rr; } + + inline QRect mapFromWS(const QRect &r) const + { QRect rr(r); rr.translate(data.wrect.topLeft()); return rr; } +#endif + // Variables. + // Regular pointers (keep them together to avoid gaps on 64 bit architectures). QWExtra *extra; QWidget *focus_next; QWidget *focus_prev; QWidget *focus_child; -#ifndef QT_NO_ACTION - QList<QAction*> actions; -#endif QLayout *layout; + QRegion *needsFlush; + QPaintDevice *redirectDev; QWidgetItemV2 *widgetItem; -#if !defined(QT_NO_IM) - QPointer<QInputContext> ic; -#endif + QPaintEngine *extraPaintEngine; + mutable const QMetaObject *polished; // All widgets are initially added into the uncreatedWidgets set. Once // they receive a window id they are removed and added to the mapper static QWidgetMapper *mapper; static QWidgetSet *uncreatedWidgets; +#if !defined(QT_NO_IM) + QPointer<QInputContext> ic; +#endif +#ifdef QT_KEYPAD_NAVIGATION + static QPointer<QWidget> editingWidget; +#endif - short leftmargin, topmargin, rightmargin, bottommargin; - - signed char leftLayoutItemMargin; - signed char topLayoutItemMargin; - signed char rightLayoutItemMargin; - signed char bottomLayoutItemMargin; - - // ### TODO: reorganize private/extra/topextra to save memory - QPointer<QWidget> compositeChildGrab; + // Implicit pointers (shared_null/shared_empty). + QRegion opaqueChildren; + QRegion dirty; #ifndef QT_NO_TOOLTIP QString toolTip; #endif @@ -518,14 +489,37 @@ public: #ifndef QT_NO_WHATSTHIS QString whatsThis; #endif - QString accessibleName, accessibleDescription; +#ifndef QT_NO_ACCESSIBILITY + QString accessibleName; + QString accessibleDescription; +#endif + // Other variables. + uint inheritedFontResolveMask; + uint inheritedPaletteResolveMask; + short leftmargin; + short topmargin; + short rightmargin; + short bottommargin; + signed char leftLayoutItemMargin; + signed char topLayoutItemMargin; + signed char rightLayoutItemMargin; + signed char bottomLayoutItemMargin; + static int instanceCounter; // Current number of widget instances + static int maxInstances; // Maximum number of widget instances + Qt::HANDLE hd; + QWidgetData data; + QSizePolicy size_policy; + QLocale locale; + QPoint redirectOffset; +#ifndef QT_NO_ACTION + QList<QAction*> actions; +#endif + + // Bit fields. + uint high_attributes[3]; // the low ones are in QWidget::widget_attributes QPalette::ColorRole fg_role : 8; QPalette::ColorRole bg_role : 8; - uint high_attributes[3]; // the low ones are in QWidget::widget_attributes - Qt::HANDLE hd; - QRegion dirty; - QRegion *needsFlush; uint dirtyOpaqueChildren : 1; uint isOpaque : 1; uint inDirtyList : 1; @@ -533,35 +527,33 @@ public: uint isMoved : 1; uint usesDoubleBufferedGLContext : 1; -#ifdef Q_WS_WIN - uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine() -#endif - - uint inheritedFontResolveMask; - uint inheritedPaletteResolveMask; -#if defined(Q_WS_X11) + // *************************** Platform specific ************************************ +#if defined(Q_WS_X11) // <----------------------------------------------------------- X11 QX11Info xinfo; Qt::HANDLE picture; + static QWidget *mouseGrabber; + static QWidget *keyboardGrabber; + + void setWindowRole(); + void sendStartupMessage(const char *message) const; + void setNetWmWindowTypes(); + void x11UpdateIsOpaque(); + bool isBackgroundInherited() const; +#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN + uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine() + + bool shouldShowMaximizeButton(); + void winUpdateIsOpaque(); + void reparentChildren(); +#ifndef QT_NO_DRAGANDDROP + QOleDropTarget *registerOleDnd(QWidget *widget); + void unregisterOleDnd(QWidget *widget, QOleDropTarget *target); #endif -#if defined(Q_WS_MAC) - enum PaintChildrenOPs { - PC_None = 0x00, - PC_Now = 0x01, - PC_NoPaint = 0x04, - PC_Later = 0x10 - }; - EventHandlerRef window_event; - bool qt_mac_dnd_event(uint, DragRef); - void toggleDrawers(bool); - //mac event functions - static bool qt_create_root_win(); - static void qt_clean_root_win(); - static bool qt_recreate_root_win(); - static bool qt_mac_update_sizer(QWidget *, int up = 0); - static OSStatus qt_window_event(EventHandlerCallRef er, EventRef event, void *); - static OSStatus qt_widget_event(EventHandlerCallRef er, EventRef event, void *); - static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool); - static bool qt_widget_shape(QWidget *, short, HIMutableShapeRef, bool); + void grabMouseWhileInWindow(); +#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC + // This is new stuff + uint needWindowChange : 1; + uint isGLWidget : 1; // Each wiget keeps a list of all its child and grandchild OpenGL widgets. // This list is used to update the gl context whenever a parent and a granparent @@ -574,95 +566,70 @@ public: QWidget * widget; QWidget * lastUpdateWidget; }; - QList<GlWidgetInfo> glWidgets; // dirtyOnWidget contains the areas in the widget that needs to be repained, // in the same way as dirtyOnScreen does for the window. Areas are added in // dirtyWidget_sys and cleared in the paint event. In scroll_sys we then use // this information repaint invalid areas when widgets are scrolled. QRegion dirtyOnWidget; + EventHandlerRef window_event; + QList<GlWidgetInfo> glWidgets; //these are here just for code compat (HIViews) Qt::HANDLE qd_hd; - // This is new stuff - uint needWindowChange : 1; - uint isGLWidget : 1; -#endif - -#if defined(Q_WS_X11) || defined (Q_WS_WIN) || defined(Q_WS_MAC) -#ifdef Q_WS_MAC - void setWSGeometry(bool dontShow=false, const QRect &oldRect = QRect()); + void macUpdateSizeAttribute(); + void macUpdateHideOnSuspend(); + void macUpdateOpaqueSizeGrip(); + void macUpdateIgnoreMouseEvents(); + void macUpdateMetalAttribute(); + void macUpdateIsOpaque(); + void setEnabled_helper_sys(bool enable); + bool isRealWindow() const; + void adjustWithinMaxAndMinSize(int &w, int &h); + void applyMaxAndMinSizeOnWindow(); + void update_sys(const QRect &rect); + void update_sys(const QRegion &rgn); + void setGeometry_sys_helper(int, int, int, int, bool); + void setWindowModified_sys(bool b); + void updateMaximizeButton_sys(); + void setWindowFilePath_sys(const QString &filePath); + void createWindow_sys(); + void recreateMacWindow(); +#ifndef QT_MAC_USE_COCOA + void initWindowPtr(); + void finishCreateWindow_sys_Carbon(OSWindowRef windowRef); #else - void setWSGeometry(bool dontShow=false); + void finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ windowRef); + void syncCocoaMask(); + void finishCocoaMaskSetup(); #endif + void determineWindowClass(); + void transferChildren(); + bool qt_mac_dnd_event(uint, DragRef); + void toggleDrawers(bool); + //mac event functions + static bool qt_create_root_win(); + static void qt_clean_root_win(); + static bool qt_mac_update_sizer(QWidget *, int up = 0); + static OSStatus qt_window_event(EventHandlerCallRef er, EventRef event, void *); + static OSStatus qt_widget_event(EventHandlerCallRef er, EventRef event, void *); + static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool); +#elif defined(Q_WS_QWS) // <--------------------------------------------------------- QWS + void setMaxWindowState_helper(); + void setFullScreenSize_helper(); + void moveSurface(QWindowSurface *surface, const QPoint &offset); + QRegion localRequestedRegion() const; + QRegion localAllocatedRegion() const; - inline QPoint mapToWS(const QPoint &p) const - { return p - data.wrect.topLeft(); } - - inline QPoint mapFromWS(const QPoint &p) const - { return p + data.wrect.topLeft(); } - - inline QRect mapToWS(const QRect &r) const - { QRect rr(r); rr.translate(-data.wrect.topLeft()); return rr; } - - inline QRect mapFromWS(const QRect &r) const - { QRect rr(r); rr.translate(data.wrect.topLeft()); return rr; } + friend class QWSManager; + friend class QWSManagerPrivate; + friend class QDecoration; +#ifndef QT_NO_CURSOR + void updateCursor() const; #endif - - QPaintEngine *extraPaintEngine; - - mutable const QMetaObject *polished; - - void setModal_sys(); - QSizePolicy size_policy; - QLocale locale; - -#ifdef Q_WS_X11 - static QWidget *mouseGrabber; - static QWidget *keyboardGrabber; + QScreen* getScreen() const; #endif - QPaintDevice *redirectDev; - QPoint redirectOffset; - - inline void setRedirected(QPaintDevice *replacement, const QPoint &offset) - { - Q_ASSERT(q_func()->testAttribute(Qt::WA_WState_InPaintEvent)); - redirectDev = replacement; - redirectOffset = offset; - } - - inline QPaintDevice *redirected(QPoint *offset) const - { - if (offset) - *offset = redirectDev ? redirectOffset : QPoint(); - return redirectDev; - } - - inline void restoreRedirected() - { redirectDev = 0; } - - inline void enforceNativeChildren() - { - if (!extra) - createExtra(); - - if (extra->nativeChildrenForced) - return; - extra->nativeChildrenForced = 1; - - for (int i = 0; i < children.size(); ++i) { - if (QWidget *child = qobject_cast<QWidget *>(children.at(i))) - child->setAttribute(Qt::WA_NativeWindow); - } - } - - inline bool nativeChildrenForced() const - { - return extra ? extra->nativeChildrenForced : false; - } - - QSize adjustedSize() const; }; inline QWExtra *QWidgetPrivate::extraData() const diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp index 1445f57..94bdb85 100644 --- a/src/gui/kernel/qwidget_qws.cpp +++ b/src/gui/kernel/qwidget_qws.cpp @@ -565,20 +565,6 @@ void QWidget::activateWindow() } } -/* - Should we require that q is a toplevel window ??? - - Used by QWSManager - */ -void QWidgetPrivate::blitToScreen(const QRegion &globalrgn) -{ - Q_Q(QWidget); - QWidget *win = q->window(); - QBrush bgBrush = win->palette().brush(win->backgroundRole()); - bool opaque = bgBrush.style() == Qt::NoBrush || bgBrush.isOpaque(); - QWidget::qwsDisplay()->repaintRegion(win->data->winid, win->windowFlags(), opaque, globalrgn); -} - void QWidgetPrivate::show_sys() { Q_Q(QWidget); @@ -1037,6 +1023,9 @@ void QWidgetPrivate::deleteSysExtra() void QWidgetPrivate::createTLSysExtra() { +#ifndef QT_NO_QWS_MANAGER + extra->topextra->qwsManager = 0; +#endif } void QWidgetPrivate::deleteTLSysExtra() diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index cfdabaf..0f341fd 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -1025,13 +1025,13 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (newstate & Qt::WindowFullScreen) { if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized)) d->topData()->normalGeometry = geometry(); - d->topData()->savedFlags = GetWindowLongA(internalWinId(), GWL_STYLE); + d->topData()->savedFlags = Qt::WindowFlags(GetWindowLongA(internalWinId(), GWL_STYLE)); #ifndef Q_FLATTEN_EXPOSE UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP; #else UINT style = WS_POPUP; #endif - if (d->topData()->savedFlags & WS_SYSMENU) + if (ulong(d->topData()->savedFlags) & WS_SYSMENU) style |= WS_SYSMENU; if (isVisible()) style |= WS_VISIBLE; @@ -1234,7 +1234,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget* w) (In all comments below: s/X/Windows/g) */ -void QWidgetPrivate::setWSGeometry(bool dontShow) +void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &) { Q_Q(QWidget); Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); @@ -1704,7 +1704,6 @@ int QWidget::metric(PaintDeviceMetric m) const return val; } -#ifndef Q_WS_WINCE void QWidgetPrivate::createSysExtra() { #ifndef QT_NO_DRAGANDDROP @@ -1712,6 +1711,7 @@ void QWidgetPrivate::createSysExtra() #endif } +#ifndef Q_WS_WINCE void QWidgetPrivate::deleteSysExtra() { } @@ -1719,8 +1719,9 @@ void QWidgetPrivate::deleteSysExtra() void QWidgetPrivate::createTLSysExtra() { - extra->topextra->winIconSmall = 0; + extra->topextra->savedFlags = 0; extra->topextra->winIconBig = 0; + extra->topextra->winIconSmall = 0; } void QWidgetPrivate::deleteTLSysExtra() diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp index cca928e..435fd31 100644 --- a/src/gui/kernel/qwidget_wince.cpp +++ b/src/gui/kernel/qwidget_wince.cpp @@ -535,7 +535,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (newstate & Qt::WindowFullScreen) { if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized)) d->topData()->normalGeometry = geometry(); - d->topData()->savedFlags = GetWindowLongA(internalWinId(), GWL_STYLE); + d->topData()->savedFlags = (Qt::WindowFlags) GetWindowLongA(internalWinId(), GWL_STYLE); UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP; if (isVisible()) style |= WS_VISIBLE; @@ -598,13 +598,6 @@ void QWidget::setWindowState(Qt::WindowStates newstate) QApplication::sendEvent(this, &e); } - -void QWidgetPrivate::createSysExtra() { -#ifndef QT_NO_DRAGANDDROP - extra->dropTarget = 0; -#endif -} - void QWidgetPrivate::deleteSysExtra() { Q_Q(QWidget); diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 76734d4..b35740a 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -906,6 +906,44 @@ void QWidgetPrivate::x11UpdateIsOpaque() #endif } +/* + Returns true if the background is inherited; otherwise returns + false. + + Mainly used in the paintOnScreen case. +*/ +bool QWidgetPrivate::isBackgroundInherited() const +{ + Q_Q(const QWidget); + + // windows do not inherit their background + if (q->isWindow() || q->windowType() == Qt::SubWindow) + return false; + + if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent)) + return false; + + const QPalette &pal = q->palette(); + QPalette::ColorRole bg = q->backgroundRole(); + QBrush brush = pal.brush(bg); + + // non opaque brushes leaves us no choice, we must inherit + if (!q->autoFillBackground() || !brush.isOpaque()) + return true; + + if (brush.style() == Qt::SolidPattern) { + // the background is just a solid color. If there is no + // propagated contents, then we claim as performance + // optimization that it was not inheritet. This is the normal + // case in standard Windows or Motif style. + const QWidget *w = q->parentWidget(); + if (!w->d_func()->isBackgroundInherited()) + return false; + } + + return true; +} + void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); @@ -2152,7 +2190,7 @@ static void do_size_hints(QWidget* widget, QWExtra *x) parentWRect is the geometry of the parent's X rect, measured in parent's coord sys */ -void QWidgetPrivate::setWSGeometry(bool dontShow) +void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &) { Q_Q(QWidget); Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); @@ -2610,8 +2648,8 @@ int QWidget::metric(PaintDeviceMetric m) const void QWidgetPrivate::createSysExtra() { - extra->xDndProxy = 0; extra->compress_events = true; + extra->xDndProxy = 0; } void QWidgetPrivate::deleteSysExtra() @@ -2620,8 +2658,11 @@ void QWidgetPrivate::deleteSysExtra() void QWidgetPrivate::createTLSysExtra() { + extra->topextra->spont_unmapped = 0; + extra->topextra->dnd = 0; extra->topextra->validWMState = 0; extra->topextra->waitingForMapNotify = 0; + extra->topextra->parentWinId = 0; extra->topextra->userTimeWindow = 0; } @@ -2747,12 +2788,6 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal opacity) 32, PropModeReplace, (uchar*)&value, 1); } -/*! - Returns information about the configuration of the X display used to display - the widget. - - \warning This function is only available on X11. -*/ const QX11Info &QWidget::x11Info() const { Q_D(const QWidget); @@ -2789,13 +2824,6 @@ QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys() return new QX11WindowSurface(q_func()); } -/*! - Returns the X11 Picture handle of the widget for XRender - support. Use of this function is not portable. This function will - return 0 if XRender support is not compiled into Qt, if the - XRender extension is not supported on the X11 display, or if the - handle could not be created. -*/ Qt::HANDLE QWidget::x11PictureHandle() const { #ifndef QT_NO_XRENDER diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/gui/kernel/qx11embed_x11.cpp index 6329135..ae93efe 100644 --- a/src/gui/kernel/qx11embed_x11.cpp +++ b/src/gui/kernel/qx11embed_x11.cpp @@ -1297,9 +1297,6 @@ bool QX11EmbedContainer::eventFilter(QObject *o, QEvent *event) // focus is set to our focus proxy. We want to intercept all // keypresses. if (o == window() && d->client) { - if (!d->isEmbedded() && d->activeContainer == this) - d->moveInputToProxy(); - if (d->clientIsXEmbed) { sendXEmbedMessage(d->client, x11Info().display(), XEMBED_WINDOW_ACTIVATE); } else { @@ -1307,6 +1304,8 @@ bool QX11EmbedContainer::eventFilter(QObject *o, QEvent *event) if (hasFocus()) XSetInputFocus(x11Info().display(), d->client, XRevertToParent, x11Time()); } + if (!d->isEmbedded()) + d->moveInputToProxy(); } break; case QEvent::WindowDeactivate: @@ -1729,10 +1728,10 @@ void QX11EmbedContainerPrivate::acceptClient(WId window) checkGrab(); if (q->hasFocus()) { XSetInputFocus(q->x11Info().display(), client, XRevertToParent, x11Time()); - } else { - if (!isEmbedded()) - moveInputToProxy(); } + } else { + if (!isEmbedded()) + moveInputToProxy(); } emit q->clientIsEmbedded(); @@ -1749,11 +1748,9 @@ void QX11EmbedContainerPrivate::acceptClient(WId window) void QX11EmbedContainerPrivate::moveInputToProxy() { Q_Q(QX11EmbedContainer); - WId focus; - int revert_to; - XGetInputFocus(q->x11Info().display(), &focus, &revert_to); - if (focus != focusProxy->internalWinId()) - XSetInputFocus(q->x11Info().display(), focusProxy->internalWinId(), XRevertToParent, x11Time()); + // Following Owen Taylor's advice from the XEmbed specification to + // always use CurrentTime when no explicit user action is involved. + XSetInputFocus(q->x11Info().display(), focusProxy->internalWinId(), XRevertToParent, CurrentTime); } /*! \internal |