diff options
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qapplication_mac.mm | 32 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_win.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_x11.cpp | 35 | ||||
-rw-r--r-- | src/gui/kernel/qcocoaapplicationdelegate_mac.mm | 11 | ||||
-rw-r--r-- | src/gui/kernel/qcocoaview_mac.mm | 4 | ||||
-rw-r--r-- | src/gui/kernel/qcocoawindowdelegate_mac.mm | 17 | ||||
-rw-r--r-- | src/gui/kernel/qlayout.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 25 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_mac.mm | 25 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_p.h | 1 |
10 files changed, 106 insertions, 50 deletions
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 5f8c572..69302ec 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); @@ -1210,6 +1210,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 +1234,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); @@ -2367,6 +2371,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_win.cpp b/src/gui/kernel/qapplication_win.cpp index fae0335..bc32c14 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -2432,10 +2432,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 { diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index f1fb001..15149a5 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -3169,43 +3169,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); 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 fae4821..ff36ca1 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -807,10 +807,10 @@ extern "C" { QWheelEvent qwe(qlocal, qglobal, deltaY, buttons, keyMods, Qt::Vertical); qt_sendSpontaneousEvent(qwidget, &qwe); wheelOK = qwe.isAccepted(); - if (wheelOK && QApplicationPrivate::focus_widget + if (!wheelOK && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != qwidget) { QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(qglobal), qglobal, - deltaZ, buttons, keyMods, Qt::Vertical); + deltaY, buttons, keyMods, Qt::Vertical); qt_sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2); wheelOK = qwe2.isAccepted(); } diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index 03b2fce..fa325f4 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -194,7 +194,6 @@ static void cleanupCocoaWindowDelegate() { NSWindow *window = [notification object]; QWidget *qwidget = m_windowHash->value(window); - // Just here to handle the is zoomed method. QWidgetData *widgetData = qt_qwidget_data(qwidget); if (!(qwidget->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) && [window isZoomed]) { widgetData->window_state = widgetData->window_state | Qt::WindowMaximized; @@ -202,7 +201,6 @@ static void cleanupCocoaWindowDelegate() & ~Qt::WindowMaximized)); qt_sendSpontaneousEvent(qwidget, &e); } - [self checkForMove:[window frame] forWidget:qwidget]; NSRect rect = [[window contentView] frame]; const QSize newSize(rect.size.width, rect.size.height); const QSize &oldSize = widgetData->crect.size(); @@ -212,12 +210,18 @@ static void cleanupCocoaWindowDelegate() } } -- (void)checkForMove:(const NSRect &)newRect forWidget:(QWidget *)qwidget +- (void)windowDidMove:(NSNotification *)notification { - // newRect's origin is bottom left. + // The code underneath needs to translate the window location + // from bottom left (which is the origin used by Cocoa) to + // upper left (which is the origin used by Qt): + NSWindow *window = [notification object]; + NSRect newRect = [window frame]; + QWidget *qwidget = m_windowHash->value(window); QPoint qtPoint = flipPoint(NSMakePoint(newRect.origin.x, newRect.origin.y + newRect.size.height)).toPoint(); const QRect &oldRect = qwidget->frameGeometry(); + if (qtPoint.x() != oldRect.x() || qtPoint.y() != oldRect.y()) { QWidgetData *widgetData = qt_qwidget_data(qwidget); QRect oldCRect = widgetData->crect; @@ -233,11 +237,6 @@ static void cleanupCocoaWindowDelegate() } } -- (void)windowDidMove:(NSNotification *)notification -{ - [self windowDidResize:notification]; -} - -(BOOL)windowShouldClose:(id)windowThatWantsToClose { QWidget *qwidget = m_windowHash->value(windowThatWantsToClose); diff --git a/src/gui/kernel/qlayout.cpp b/src/gui/kernel/qlayout.cpp index aa46249..1d5a70d 100644 --- a/src/gui/kernel/qlayout.cpp +++ b/src/gui/kernel/qlayout.cpp @@ -1239,7 +1239,7 @@ bool QLayout::activate() Must be implemented in subclasses to remove the layout item at \a index from the layout, and return the item. If there is no such item, the function must do nothing and return 0. Items are numbered - consecutively from 0. If an item is deleted, other items will be + consecutively from 0. If an item is removed, other items will be renumbered. The following code fragment shows a safe way to remove all items diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index f5deb96..23a5b08 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -187,6 +187,7 @@ QWidgetPrivate::QWidgetPrivate(int version) : ,inDirtyList(0) ,isScrolled(0) ,isMoved(0) + ,usesDoubleBufferedGLContext(0) #ifdef Q_WS_WIN ,noPaintOnScreen(0) #endif @@ -2149,6 +2150,10 @@ QWidget *QWidget::find(WId id) If a widget is non-native (alien) and winId() is invoked on it, that widget will be provided a native handle. + On Mac OS X, the type returned depends on which framework Qt was linked + against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt + is using Cocoa, {WId} is a pointer to an NSView. + \note We recommend that you do not store this value as it is likely to change at run-time. @@ -4726,10 +4731,13 @@ void QWidget::render(QPaintDevice *target, const QPoint &targetOffset, if (redirected) { target = redirected; offset -= redirectionOffset; - if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp). - const QRegion redirectedSystemClip = redirected->paintEngine()->systemClip(); - if (!redirectedSystemClip.isEmpty()) - paintRegion &= redirectedSystemClip.translated(-offset); + } + + if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp). + if (QPaintEngine *targetEngine = target->paintEngine()) { + const QRegion targetSystemClip = targetEngine->systemClip(); + if (!targetSystemClip.isEmpty()) + paintRegion &= targetSystemClip.translated(-offset); } } @@ -4833,8 +4841,13 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, const QRegion oldSystemClip = enginePriv->systemClip; const QRegion oldSystemViewport = enginePriv->systemViewport; - // This ensures that transformed system clips are inside the current system clip. - enginePriv->setSystemViewport(oldSystemClip); + // This ensures that all painting triggered by render() is clipped to the current engine clip. + if (painter->hasClipping()) { + const QRegion painterClip = painter->deviceTransform().map(painter->clipRegion()); + enginePriv->setSystemViewport(oldSystemClip.isEmpty() ? painterClip : oldSystemClip & painterClip); + } else { + enginePriv->setSystemViewport(oldSystemClip); + } render(target, targetOffset, toBePainted, renderFlags); diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index a00f969..5abaaf8 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -4039,7 +4039,11 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) QMacCocoaAutoReleasePool pool; bool realWindow = isRealWindow(); - if (realWindow && !(w == 0 && h == 0) && !q->testAttribute(Qt::WA_DontShowOnScreen)) { + if (realWindow && !q->testAttribute(Qt::WA_DontShowOnScreen) +#ifndef QT_MAC_USE_COCOA + && !(w == 0 && h == 0) +#endif + ){ applyMaxAndMinSizeConstraints(w, h); topData()->isSetGeometry = 1; topData()->isMove = isMove; @@ -4054,7 +4058,24 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) fStrut.top() + fStrut.bottom() + h)); NSRect cocoaFrameRect = NSMakeRect(frameRect.x(), flipYCoordinate(frameRect.bottom() + 1), frameRect.width(), frameRect.height()); - [window setFrame:cocoaFrameRect display:NO]; + + QPoint currTopLeft = data.crect.topLeft(); + if (currTopLeft.x() == x && currTopLeft.y() == y + && cocoaFrameRect.size.width != 0 + && cocoaFrameRect.size.height != 0) { + [window setFrame:cocoaFrameRect display:NO]; + } else { + // The window is moved and resized (or resized to zero). + // Since Cocoa usually only sends us a resize callback after + // setting a window frame, we issue an explicit move as + // well. To stop Cocoa from optimize away the move (since the move + // would have the same origin as the setFrame call) we shift the + // window back and forth inbetween. + cocoaFrameRect.origin.y += 1; + [window setFrame:cocoaFrameRect display:NO]; + cocoaFrameRect.origin.y -= 1; + [window setFrameOrigin:cocoaFrameRect.origin]; + } #endif topData()->isSetGeometry = 0; } else { diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 19f4b98..e02d329 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -550,6 +550,7 @@ public: uint inDirtyList : 1; uint isScrolled : 1; uint isMoved : 1; + uint usesDoubleBufferedGLContext : 1; #ifdef Q_WS_WIN uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine() |