diff options
Diffstat (limited to 'src/gui/kernel')
27 files changed, 344 insertions, 61 deletions
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index a8c34a8871..9eefa968ad 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -1326,6 +1326,55 @@ QExposeEvent::~QExposeEvent() } /*! + \class QPlatformSurfaceEvent + \since 5.5 + \brief The QPlatformSurfaceEvent class is used to notify about native platform surface events. + \inmodule QtGui + + \ingroup events + + Platform window events are synchronously sent to windows and offscreen surfaces when their + underlying native surfaces are created or are about to be destroyed. + + Applications can respond to these events to know when the underlying platform + surface exists. +*/ + +/*! + \enum QPlatformSurfaceEvent::SurfaceEventType + + This enum describes the type of platform surface event. The possible types are: + + \value SurfaceCreated The underlying native surface has been created + \value SurfaceAboutToBeDestroyed The underlying native surface will be destroyed immediately after this event + + The \c SurfaceAboutToBeDestroyed event type is useful as a means of stopping rendering to + a platform window before it is destroyed. +*/ + +/*! + \fn QPlatformSurfaceEvent::SurfaceEventType QPlatformSurfaceEvent::surfaceEventType() const + + Returns the specific type of platform surface event. +*/ + +/*! + Constructs a platform surface event for the given \a surfaceEventType. +*/ +QPlatformSurfaceEvent::QPlatformSurfaceEvent(SurfaceEventType surfaceEventType) + : QEvent(PlatformSurface) + , m_surfaceEventType(surfaceEventType) +{ +} + +/*! + \internal +*/ +QPlatformSurfaceEvent::~QPlatformSurfaceEvent() +{ +} + +/*! \fn const QRegion &QExposeEvent::region() const Returns the window area that has been exposed. The region is given in local coordinates. @@ -3558,6 +3607,8 @@ static const char *eventClassName(QEvent::Type t) return "QGraphicsSceneEvent"; case QEvent::Timer: return "QTimerEvent"; + case QEvent::PlatformSurface: + return "QPlatformSurfaceEvent"; default: break; } @@ -3816,6 +3867,18 @@ QDebug operator<<(QDebug dbg, const QEvent *e) case QEvent::Timer: dbg << "QTimerEvent(id=" << static_cast<const QTimerEvent *>(e)->timerId() << ')'; break; + case QEvent::PlatformSurface: + dbg << "QPlatformSurfaceEvent(surfaceEventType="; + switch (static_cast<const QPlatformSurfaceEvent *>(e)->surfaceEventType()) { + case QPlatformSurfaceEvent::SurfaceCreated: + dbg << "SurfaceCreated"; + break; + case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: + dbg << "SurfaceAboutToBeDestroyed"; + break; + } + dbg << ')'; + break; default: dbg << eventClassName(type) << '(' << eventTypeName(type) << ", " << (const void *)e << ", type = " << e->type() << ')'; diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 6fca54e2b6..0b6d96a590 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -162,6 +162,8 @@ protected: class Q_GUI_EXPORT QWheelEvent : public QInputEvent { public: + enum { DefaultDeltasPerStep = 120 }; + QWheelEvent(const QPointF &pos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient = Qt::Vertical); @@ -408,6 +410,23 @@ protected: QRegion rgn; }; +class Q_GUI_EXPORT QPlatformSurfaceEvent : public QEvent +{ +public: + enum SurfaceEventType { + SurfaceCreated, + SurfaceAboutToBeDestroyed + }; + + explicit QPlatformSurfaceEvent(SurfaceEventType surfaceEventType); + ~QPlatformSurfaceEvent(); + + inline SurfaceEventType surfaceEventType() const { return m_surfaceEventType; } + +protected: + SurfaceEventType m_surfaceEventType; +}; + class Q_GUI_EXPORT QResizeEvent : public QEvent { public: diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index e3f4794e6d..ded3788dbf 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -215,11 +215,6 @@ static inline void clearFontUnlocked() QGuiApplicationPrivate::app_font = 0; } -static inline bool isPopupWindow(const QWindow *w) -{ - return (w->flags() & Qt::WindowType_Mask) == Qt::Popup; -} - // Geometry specification for top level windows following the convention of the // -geometry command line arguments in X11 (see XParseGeometry). struct QWindowGeometrySpecification @@ -671,7 +666,7 @@ static void updateBlockedStatusRecursion(QWindow *window, bool shouldBeBlocked) void QGuiApplicationPrivate::updateBlockedStatus(QWindow *window) { bool shouldBeBlocked = false; - if (!isPopupWindow(window) && !self->modalWindowList.isEmpty()) + if (!QWindowPrivate::get(window)->isPopup() && !self->modalWindowList.isEmpty()) shouldBeBlocked = self->isWindowBlocked(window); updateBlockedStatusRecursion(window, shouldBeBlocked); } @@ -681,7 +676,7 @@ void QGuiApplicationPrivate::showModalWindow(QWindow *modal) self->modalWindowList.prepend(modal); // Send leave for currently entered window if it should be blocked - if (currentMouseWindow && !isPopupWindow(currentMouseWindow)) { + if (currentMouseWindow && !QWindowPrivate::get(currentMouseWindow)->isPopup()) { bool shouldBeBlocked = self->isWindowBlocked(currentMouseWindow); if (shouldBeBlocked) { // Remove the new window from modalWindowList temporarily so leave can go through @@ -1366,6 +1361,8 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate() } #endif + platform_integration->destroy(); + delete platform_theme; platform_theme = 0; delete platform_integration; @@ -1511,18 +1508,6 @@ int QGuiApplication::exec() */ bool QGuiApplication::notify(QObject *object, QEvent *event) { -#ifndef QT_NO_SHORTCUT - if (event->type() == QEvent::KeyPress) { - // Try looking for a Shortcut before sending key events - QWindow *w = qobject_cast<QWindow *>(object); - QObject *focus = w ? w->focusObject() : 0; - if (!focus) - focus = object; - if (QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focus, static_cast<QKeyEvent *>(event))) - return true; - } -#endif - if (object->isWindowType()) QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast<QWindow *>(object), event); return QCoreApplication::notify(object, event); @@ -1686,7 +1671,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo // will update the global mouse position and cause the second event to be a button only event. QWindowSystemInterfacePrivate::MouseEvent moveEvent(e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, buttons, e->modifiers, e->source); - moveEvent.synthetic = e->synthetic; + if (e->flags & QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic) + moveEvent.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; processMouseEvent(&moveEvent); Q_ASSERT(e->globalPos == QGuiApplicationPrivate::lastCursorPosition); // continue with processing mouse button change event @@ -1698,7 +1684,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo QPointF localPoint = e->localPos; QPointF globalPoint = e->globalPos; - if (e->nullWindow) { + if (e->nullWindow()) { window = QGuiApplication::topLevelAt(globalPoint.toPoint()); if (window) { QPointF delta = globalPoint - globalPoint.toPoint(); @@ -1751,7 +1737,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo ev.setTimestamp(e->timestamp); setMouseEventSource(&ev, e->source); #ifndef QT_NO_CURSOR - if (!e->synthetic) { + if (!e->synthetic()) { if (const QScreen *screen = window->screen()) if (QPlatformCursor *cursor = screen->handle()->cursor()) cursor->pointerEvent(ev); @@ -1769,7 +1755,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo } QGuiApplication::sendSpontaneousEvent(window, &ev); - if (!e->synthetic && !ev.isAccepted() + if (!e->synthetic() && !ev.isAccepted() && !frameStrut && qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) { if (!m_fakeTouchDevice) { @@ -1800,12 +1786,12 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type); QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers); - fake.synthetic = true; + fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; processTouchEvent(&fake); } if (doubleClick) { mousePressButton = Qt::NoButton; - if (!e->window.isNull() || e->nullWindow) { // QTBUG-36364, check if window closed in response to press + if (!e->window.isNull() || e->nullWindow()) { // QTBUG-36364, check if window closed in response to press const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick; QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint, button, buttons, e->modifiers); @@ -1823,7 +1809,7 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh QPointF globalPoint = e->globalPos; QPointF localPoint = e->localPos; - if (e->nullWindow) { + if (e->nullWindow()) { window = QGuiApplication::topLevelAt(globalPoint.toPoint()); if (window) { QPointF delta = globalPoint - globalPoint.toPoint(); @@ -1854,7 +1840,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE { QWindow *window = e->window.data(); modifier_buttons = e->modifiers; - if (e->nullWindow + if (e->nullWindow() #if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) || e->key == Qt::Key_Back || e->key == Qt::Key_Menu #endif @@ -2095,7 +2081,7 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T // subsequent events up to the release are delivered to that same window. // If window is given, just send to that. if (type == QEvent::TabletPress) { - if (e->nullWindow) { + if (e->nullWindow()) { window = QGuiApplication::topLevelAt(e->global.toPoint()); localValid = false; } @@ -2103,7 +2089,7 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T return; tabletPressTarget = window; } else { - if (e->nullWindow) { + if (e->nullWindow()) { window = tabletPressTarget; localValid = false; } @@ -2237,7 +2223,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To touchEvent.setWindow(*winIt); QGuiApplication::sendSpontaneousEvent(*winIt, &touchEvent); } - if (!self->synthesizedMousePoints.isEmpty() && !e->synthetic) { + if (!self->synthesizedMousePoints.isEmpty() && !e->synthetic()) { for (QHash<QWindow *, SynthesizedMouseData>::const_iterator synthIt = self->synthesizedMousePoints.constBegin(), synthItEnd = self->synthesizedMousePoints.constEnd(); synthIt != synthItEnd; ++synthIt) { if (!synthIt->window) @@ -2249,7 +2235,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To buttons & ~Qt::LeftButton, e->modifiers, Qt::MouseEventSynthesizedByQt); - fake.synthetic = true; + fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; processMouseEvent(&fake); } self->synthesizedMousePoints.clear(); @@ -2428,7 +2414,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To } QGuiApplication::sendSpontaneousEvent(w, &touchEvent); - if (!e->synthetic && !touchEvent.isAccepted() && synthesizeMouseFromTouchEventsEnabled()) { + if (!e->synthetic() && !touchEvent.isAccepted() && synthesizeMouseFromTouchEventsEnabled()) { // exclude touchpads as those generate their own mouse events if (touchEvent.device()->type() != QTouchDevice::TouchPad) { Qt::MouseButtons b = eventType == QEvent::TouchEnd ? Qt::NoButton : Qt::LeftButton; @@ -2451,7 +2437,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To b | (buttons & ~Qt::LeftButton), e->modifiers, Qt::MouseEventSynthesizedByQt); - fake.synthetic = true; + fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; processMouseEvent(&fake); break; } diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 209d1dd499..4a4ce22f35 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -289,6 +289,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni \row \li DeleteCompleteLine \li (none) \li (none) \li Ctrl+U \li Ctrl+U \row \li InsertParagraphSeparator \li Enter \li Enter \li Enter \li Enter \row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter, Meta+O \li Shift+Enter \li Shift+Enter + \row \li Backspace \li (none) \li Meta+H \li (none) \li (none) \endtable Note that, since the key sequences used for the standard shortcuts differ @@ -663,6 +664,9 @@ static const struct { { Qt::Key_Play, QT_TRANSLATE_NOOP("QShortcut", "Play") }, { Qt::Key_Zoom, QT_TRANSLATE_NOOP("QShortcut", "Zoom") }, { Qt::Key_Exit, QT_TRANSLATE_NOOP("QShortcut", "Exit") }, + { Qt::Key_TouchpadToggle, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Toggle") }, + { Qt::Key_TouchpadOn, QT_TRANSLATE_NOOP("QShortcut", "Touchpad On") }, + { Qt::Key_TouchpadOff, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Off") }, { 0, 0 } }; @@ -679,6 +683,7 @@ static const struct { \value AddTab Add new tab. \value Back Navigate back. + \value Backspace Delete previous character. \value Bold Bold text. \value Close Close document/tab. \value Copy Copy. diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h index 5a2ce5a8b9..fd2a3e9d7b 100644 --- a/src/gui/kernel/qkeysequence.h +++ b/src/gui/kernel/qkeysequence.h @@ -134,7 +134,8 @@ public: Quit, FullScreen, Deselect, - DeleteCompleteLine + DeleteCompleteLine, + Backspace }; enum SequenceFormat { diff --git a/src/gui/kernel/qoffscreensurface.cpp b/src/gui/kernel/qoffscreensurface.cpp index 5cf77de5d8..fb1dfd8df5 100644 --- a/src/gui/kernel/qoffscreensurface.cpp +++ b/src/gui/kernel/qoffscreensurface.cpp @@ -180,6 +180,9 @@ void QOffscreenSurface::create() d->offscreenWindow->setGeometry(0, 0, d->size.width(), d->size.height()); d->offscreenWindow->create(); } + + QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated); + QGuiApplication::sendEvent(this, &e); } } @@ -191,6 +194,10 @@ void QOffscreenSurface::create() void QOffscreenSurface::destroy() { Q_D(QOffscreenSurface); + + QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed); + QGuiApplication::sendEvent(this, &e); + delete d->platformOffscreenSurface; d->platformOffscreenSurface = 0; if (d->offscreenWindow) { diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 1a8a534e11..07a7c601fa 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -596,6 +596,7 @@ bool QOpenGLContext::create() d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this); if (!d->platformGLContext) return false; + d->platformGLContext->initialize(); d->platformGLContext->setContext(this); if (!d->platformGLContext->isSharing()) d->shareContext = 0; diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp index cf8653426f..d5b15ed5f5 100644 --- a/src/gui/kernel/qpaintdevicewindow.cpp +++ b/src/gui/kernel/qpaintdevicewindow.cpp @@ -76,7 +76,7 @@ void QPaintDeviceWindow::update(const QRect &rect) { Q_D(QPaintDeviceWindow); d->dirtyRegion += rect; - d->triggerUpdate(); + requestUpdate(); } /*! @@ -89,7 +89,7 @@ void QPaintDeviceWindow::update(const QRegion ®ion) { Q_D(QPaintDeviceWindow); d->dirtyRegion += region; - d->triggerUpdate(); + requestUpdate(); } /*! @@ -179,7 +179,6 @@ bool QPaintDeviceWindow::event(QEvent *event) Q_D(QPaintDeviceWindow); if (event->type() == QEvent::UpdateRequest) { - d->paintEventSent = false; if (handle()) // platform window may be gone when the window is closed during app exit d->handleUpdateEvent(); return true; diff --git a/src/gui/kernel/qpaintdevicewindow_p.h b/src/gui/kernel/qpaintdevicewindow_p.h index 1935bb6db5..865861125b 100644 --- a/src/gui/kernel/qpaintdevicewindow_p.h +++ b/src/gui/kernel/qpaintdevicewindow_p.h @@ -46,8 +46,6 @@ class Q_GUI_EXPORT QPaintDeviceWindowPrivate : public QWindowPrivate Q_DECLARE_PUBLIC(QPaintDeviceWindow) public: - QPaintDeviceWindowPrivate() : paintEventSent(false) { } - virtual void beginPaint(const QRegion ®ion) { Q_UNUSED(region); @@ -82,15 +80,6 @@ public: return true; } - void triggerUpdate() - { - Q_Q(QPaintDeviceWindow); - if (!paintEventSent) { - QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest)); - paintEventSent = true; - } - } - void doFlush(const QRegion ®ion) { QRegion toFlush = region; @@ -113,7 +102,6 @@ public: private: QRegion dirtyRegion; - bool paintEventSent; }; diff --git a/src/gui/kernel/qpixelformat.cpp b/src/gui/kernel/qpixelformat.cpp index cfa8a96d69..7e50a0cd41 100644 --- a/src/gui/kernel/qpixelformat.cpp +++ b/src/gui/kernel/qpixelformat.cpp @@ -69,6 +69,7 @@ QT_BEGIN_NAMESPACE \enum QPixelFormat::ColorModel This enum type is used to describe the color model of the pixelformat. + Alpha was added in 5.5. \value RGB The color model is RGB. @@ -86,6 +87,8 @@ QT_BEGIN_NAMESPACE \value HSV The color model is HSV. \value YUV The color model is YUV. + + \value Alpha There is no color model, only alpha is used. */ /*! @@ -282,6 +285,21 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QPixelFormat qPixelFormatAlpha(uchar channelSize, + QPixelFormat::TypeInterpretation typeInterpretation = QPixelFormat::UnsignedInteger) + \relates QPixelFormat + \since 5.5 + + Constructor function for creating an Alpha format. A mask format can be + described by passing 1 to \a channelSize. Its also possible to define very + accurate alpha formats using doubles to describe each pixel by passing 8 + as \a channelSize and FloatingPoint as \a typeInterpretation. + + \sa QPixelFormat::TypeInterpretation +*/ + + +/*! \fn QPixelFormat qPixelFormatCmyk(uchar channelSize, uchar alphaSize = 0, QPixelFormat::AlphaUsage alphaUsage = QPixelFormat::IgnoresAlpha, diff --git a/src/gui/kernel/qpixelformat.h b/src/gui/kernel/qpixelformat.h index f55c97c7c0..b7a4377a69 100644 --- a/src/gui/kernel/qpixelformat.h +++ b/src/gui/kernel/qpixelformat.h @@ -103,7 +103,8 @@ public: CMYK, HSL, HSV, - YUV + YUV, + Alpha }; enum AlphaUsage { @@ -304,6 +305,22 @@ Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatGrayscale(uchar channelSize, typeInt); } +Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatAlpha(uchar channelSize, + QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) Q_DECL_NOTHROW +{ + return QPixelFormat(QPixelFormat::Alpha, + 0, + 0, + 0, + 0, + 0, + channelSize, + QPixelFormat::UsesAlpha, + QPixelFormat::AtBeginning, + QPixelFormat::NotPremultiplied, + typeInt); +} + Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatCmyk(uchar channelSize, uchar alfa=0, QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha, diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index 39b031ef6d..7e291e9050 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -324,6 +324,16 @@ void QPlatformIntegration::initialize() } /*! + Called before the platform integration is deleted. Useful when cleanup relies on virtual + functions. + + \since 5.5 +*/ +void QPlatformIntegration::destroy() +{ +} + +/*! Returns the platforms input context. The default implementation returns 0, implying no input method support. diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h index d510240fa4..ccbe4cc73d 100644 --- a/src/gui/kernel/qplatformintegration.h +++ b/src/gui/kernel/qplatformintegration.h @@ -109,6 +109,7 @@ public: // Event dispatcher: virtual QAbstractEventDispatcher *createEventDispatcher() const = 0; virtual void initialize(); + virtual void destroy(); //Deeper window system integrations virtual QPlatformFontDatabase *fontDatabase() const; diff --git a/src/gui/kernel/qplatformopenglcontext.cpp b/src/gui/kernel/qplatformopenglcontext.cpp index 527bfdd983..bf0dccd440 100644 --- a/src/gui/kernel/qplatformopenglcontext.cpp +++ b/src/gui/kernel/qplatformopenglcontext.cpp @@ -89,6 +89,16 @@ QPlatformOpenGLContext::~QPlatformOpenGLContext() } /*! + Called after a new instance is constructed. The default implementation does nothing. + + Subclasses can use this function to perform additional initialization that relies on + virtual functions. + */ +void QPlatformOpenGLContext::initialize() +{ +} + +/*! Reimplement in subclass if your platform uses framebuffer objects for surfaces. The default implementation returns 0. diff --git a/src/gui/kernel/qplatformopenglcontext.h b/src/gui/kernel/qplatformopenglcontext.h index 261b6921a4..0a2bacfbde 100644 --- a/src/gui/kernel/qplatformopenglcontext.h +++ b/src/gui/kernel/qplatformopenglcontext.h @@ -63,6 +63,8 @@ public: QPlatformOpenGLContext(); virtual ~QPlatformOpenGLContext(); + virtual void initialize(); + virtual QSurfaceFormat format() const = 0; virtual void swapBuffers(QPlatformSurface *surface) = 0; diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index 646bd90e56..92c1b09406 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -320,7 +320,8 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = { {QKeySequence::FullScreen, 1, Qt::CTRL | Qt::Key_F11, KB_Gnome}, {QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE}, {QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11}, - {QKeySequence::DeleteCompleteLine, 0, Qt::CTRL | Qt::Key_U, KB_X11} + {QKeySequence::DeleteCompleteLine, 0, Qt::CTRL | Qt::Key_U, KB_X11}, + {QKeySequence::Backspace, 0, Qt::META | Qt::Key_H, KB_Mac} }; const uint QPlatformThemePrivate::numberOfKeyBindings = sizeof(QPlatformThemePrivate::keyBindings)/(sizeof(QKeyBinding)); @@ -502,9 +503,11 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint) case MouseDoubleClickDistance: { bool ok = false; - int dist = qgetenv("QT_DBL_CLICK_DIST").toInt(&ok); + const int dist = qEnvironmentVariableIntValue("QT_DBL_CLICK_DIST", &ok); return QVariant(ok ? dist : 5); } + case WheelScrollLines: + return QVariant(3); } return QVariant(); } diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h index a41dd8f257..be1eacf002 100644 --- a/src/gui/kernel/qplatformtheme.h +++ b/src/gui/kernel/qplatformtheme.h @@ -101,7 +101,8 @@ public: DialogSnapToDefaultButton, ContextMenuOnMouseRelease, MousePressAndHoldInterval, - MouseDoubleClickDistance + MouseDoubleClickDistance, + WheelScrollLines }; enum DialogType { diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 754395592c..167bd44f0e 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -453,7 +453,7 @@ bool QPlatformWindow::frameStrutEventsEnabled() const QString QPlatformWindow::formatWindowTitle(const QString &title, const QString &separator) { QString fullTitle = title; - if (QGuiApplicationPrivate::displayName) { + if (QGuiApplicationPrivate::displayName && !title.endsWith(*QGuiApplicationPrivate::displayName)) { // Append display name, if set. if (!fullTitle.isEmpty()) fullTitle += separator; @@ -595,6 +595,36 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, } /*! + Requests an QEvent::UpdateRequest event. The event will be + delivered to the QWindow. + + QPlatformWindow subclasses can re-implement this function to + provide display refresh synchronized updates. The event + should be delivered using QWindowPrivate::deliverUpdateRequest() + to not get out of sync with the the internal state of QWindow. + + The default implementation posts an UpdateRequest event to the + window after 5 ms. The additional time is there to give the event + loop a bit of idle time to gather system events. + +*/ +void QPlatformWindow::requestUpdate() +{ + static int timeout = -1; + if (timeout == -1) { + bool ok = false; + timeout = qEnvironmentVariableIntValue("QT_QPA_UPDATE_IDLE_TIME", &ok); + if (!ok) + timeout = 5; + } + + QWindow *w = window(); + QWindowPrivate *wp = (QWindowPrivate *) QObjectPrivate::get(w); + Q_ASSERT(wp->updateTimer == 0); + wp->updateTimer = w->startTimer(timeout, Qt::PreciseTimer); +} + +/*! \class QPlatformWindow \since 4.8 \internal diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 5c351a69d2..87781caf8b 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -129,6 +129,7 @@ public: static QRect initialGeometry(const QWindow *w, const QRect &initialGeometry, int defaultWidth, int defaultHeight); + virtual void requestUpdate(); protected: static QString formatWindowTitle(const QString &title, const QString &separator); QPlatformScreen *screenForGeometry(const QRect &newGeometry) const; diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index cad707ab70..b3e71c77fa 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -310,6 +310,10 @@ QKeySequence::SequenceMatch QShortcutMap::state() Uses ShortcutOverride event to see if any widgets want to override the event. If not, uses nextState(QKeyEvent) to check for a grabbed Shortcut, and dispatchEvent() is found and identical. + + \note that this function should only be called from QWindowSystemInterface, + otherwise it will result in duplicate events. + \sa nextState, dispatchEvent */ bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e) diff --git a/src/gui/kernel/qsurface.h b/src/gui/kernel/qsurface.h index 58b7ce018e..0c02a3564c 100644 --- a/src/gui/kernel/qsurface.h +++ b/src/gui/kernel/qsurface.h @@ -36,7 +36,7 @@ #include <QtCore/qnamespace.h> #include <QtGui/qsurfaceformat.h> - +#include <QtCore/qmetatype.h> #include <QtCore/qsize.h> QT_BEGIN_NAMESPACE @@ -82,4 +82,6 @@ protected: QT_END_NAMESPACE +Q_DECLARE_METATYPE(QSurface*) + #endif //QSURFACE_H diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index c5d88b198b..b9dba10f22 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -404,6 +404,11 @@ void QWindowPrivate::create(bool recursive) window->d_func()->platformWindow->setParent(platformWindow); } } + + if (platformWindow) { + QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated); + QGuiApplication::sendEvent(q, &e); + } } } @@ -1603,6 +1608,10 @@ void QWindow::destroy() bool wasVisible = isVisible(); setVisible(false); + + QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed); + QGuiApplication::sendEvent(this, &e); + delete d->platformWindow; d->resizeEventPending = true; d->receivedExpose = false; @@ -2052,12 +2061,56 @@ bool QWindow::event(QEvent *ev) break; #endif + case QEvent::Timer: { + Q_D(QWindow); + if (static_cast<QTimerEvent *>(ev)->timerId() == d->updateTimer) { + killTimer(d->updateTimer); + d->updateTimer = 0; + d->deliverUpdateRequest(); + } else { + QObject::event(ev); + } + break; + } + default: return QObject::event(ev); } return true; } +void QWindowPrivate::deliverUpdateRequest() +{ + Q_Q(QWindow); + updateRequestPending = false; + QEvent request(QEvent::UpdateRequest); + QCoreApplication::sendEvent(q, &request); +} + +/*! + Schedules a QEvent::UpdateRequest event to be delivered to this window. + + The event is delivered in sync with the display vsync on platforms + where this is possible. When driving animations, this function should + be called once after drawing has completed. + + Calling this function multiple times will result in a single event + being delivered to the window. + + Subclasses of QWindow should reimplement QWindow::event(), intercept + the event and call the application's rendering code, then call the + base class implementation. +*/ + +void QWindow::requestUpdate() +{ + Q_D(QWindow); + if (d->updateRequestPending || !d->platformWindow) + return; + d->updateRequestPending = true; + d->platformWindow->requestUpdate(); +} + /*! Override this to handle key press events (\a ev). diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 473d275b56..2230ed8801 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -286,6 +286,8 @@ public Q_SLOTS: Q_REVISION(1) void alert(int msec); + Q_REVISION(3) void requestUpdate(); + Q_SIGNALS: void screenChanged(QScreen *screen); void modalityChanged(Qt::WindowModality modality); diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index bc5dfa4876..c496d7716b 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -86,6 +86,8 @@ public: , maximumSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX) , modality(Qt::NonModal) , blockedByModalWindow(false) + , updateRequestPending(false) + , updateTimer(0) , transientParent(0) , topLevelScreen(0) #ifndef QT_NO_CURSOR @@ -109,6 +111,8 @@ public: void applyCursor(); #endif + void deliverUpdateRequest(); + QPoint globalPosition() const { Q_Q(const QWindow); QPoint offset = q->position(); @@ -134,6 +138,10 @@ public: virtual void clearFocusObject(); virtual QRectF closestAcceptableGeometry(const QRectF &rect) const; + bool isPopup() const { return (windowFlags & Qt::WindowType_Mask) == Qt::Popup; } + + static QWindowPrivate *get(QWindow *window) { return window->d_func(); } + QWindow::SurfaceType surfaceType; Qt::WindowFlags windowFlags; QWindow *parentWindow; @@ -163,6 +171,9 @@ public: Qt::WindowModality modality; bool blockedByModalWindow; + bool updateRequestPending; + int updateTimer; + QPointer<QWindow> transientParent; QScreen *topLevelScreen; diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 722a695481..32040f92e3 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -220,6 +220,28 @@ bool QWindowSystemInterface::tryHandleShortcutEvent(QWindow *w, ulong timestamp, #endif } +// used by QTestLib to directly send shortcuts to objects +bool QWindowSystemInterface::tryHandleShortcutEventToObject(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, + const QString &text, bool autorep, ushort count) +{ +#ifndef QT_NO_SHORTCUT + QGuiApplicationPrivate::modifier_buttons = mods; + + QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count); + qevent.setTimestamp(timestamp); + return QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(o, &qevent); +#else + Q_UNUSED(w) + Q_UNUSED(timestamp) + Q_UNUSED(k) + Q_UNUSED(mods) + Q_UNUSED(text) + Q_UNUSED(autorep) + Q_UNUSED(count) + return false; +#endif +} + bool QWindowSystemInterface::tryHandleExtendedShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text, bool autorep, ushort count) @@ -265,6 +287,9 @@ void QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Q void QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) { + if (t == QEvent::KeyPress && tlw && QWindowSystemInterface::tryHandleShortcutEvent(tlw, timestamp, k, mods, text)) + return; + QWindowSystemInterfacePrivate::KeyEvent * e = new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); @@ -286,8 +311,12 @@ void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestam quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString& text, bool autorep, - ushort count) + ushort count, bool tryShortcutOverride) { + // on OS X we try the shortcut override even earlier and thus shouldn't handle it here + if (tryShortcutOverride && tlw && type == QEvent::KeyPress && QWindowSystemInterface::tryHandleShortcutEvent(tlw, timestamp, key, modifiers, text)) + return; + QWindowSystemInterfacePrivate::KeyEvent * e = new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); @@ -760,6 +789,11 @@ Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::Keybo QWindowSystemInterface::handleKeyEvent(w, t, k, mods, text, autorep, count); } +Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) +{ + return QWindowSystemInterface::tryHandleShortcutEventToObject(o, timestamp, k, mods, text, autorep, count); +} + static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt) { QWindowSystemInterface::TouchPoint p; diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 30c236b51f..7bb3938fe6 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -83,6 +83,9 @@ public: static bool tryHandleShortcutEvent(QWindow *w, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1); + static bool tryHandleShortcutEventToObject(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, + const QString & text = QString(), bool autorep = false, ushort count = 1); + static bool tryHandleExtendedShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString & text = QString(), bool autorep = false, ushort count = 1); @@ -102,7 +105,7 @@ public: quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString& text = QString(), bool autorep = false, - ushort count = 1); + ushort count = 1, bool tryShortcutOverride = true); static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, Qt::ScrollPhase phase = Qt::ScrollUpdate); static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods = Qt::NoModifier, Qt::ScrollPhase phase = Qt::ScrollUpdate); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index c3f41da835..57411d8101 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -93,11 +93,20 @@ public: class WindowSystemEvent { public: + enum { + Synthetic = 0x1, + NullWindow = 0x2 + }; + explicit WindowSystemEvent(EventType t) - : type(t), synthetic(false) { } + : type(t), flags(0) { } virtual ~WindowSystemEvent() { } + + bool synthetic() const { return flags & Synthetic; } + bool nullWindow() const { return flags & NullWindow; } + EventType type; - bool synthetic; + int flags; }; class CloseEvent : public WindowSystemEvent { @@ -188,9 +197,12 @@ public: class UserEvent : public WindowSystemEvent { public: UserEvent(QWindow * w, ulong time, EventType t) - : WindowSystemEvent(t), window(w), nullWindow(w == 0), timestamp(time) { } + : WindowSystemEvent(t), window(w), timestamp(time) + { + if (!w) + flags |= NullWindow; + } QPointer<QWindow> window; - bool nullWindow; unsigned long timestamp; }; |