summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/kernel.pri24
-rw-r--r--src/gui/kernel/qclipboard.cpp32
-rw-r--r--src/gui/kernel/qcursor.cpp127
-rw-r--r--src/gui/kernel/qcursor_qpa.cpp135
-rw-r--r--src/gui/kernel/qdnd.cpp1
-rw-r--r--src/gui/kernel/qevent.cpp869
-rw-r--r--src/gui/kernel/qevent.h30
-rw-r--r--src/gui/kernel/qevent_p.h14
-rw-r--r--src/gui/kernel/qguiapplication.cpp190
-rw-r--r--src/gui/kernel/qguiapplication.h7
-rw-r--r--src/gui/kernel/qguiapplication_p.h8
-rw-r--r--src/gui/kernel/qkeymapper.cpp31
-rw-r--r--src/gui/kernel/qkeysequence.cpp32
-rw-r--r--src/gui/kernel/qoffscreensurface.cpp1
-rw-r--r--src/gui/kernel/qopenglcontext.cpp135
-rw-r--r--src/gui/kernel/qopenglcontext.h5
-rw-r--r--src/gui/kernel/qopenglcontext_p.h8
-rw-r--r--src/gui/kernel/qopenglwindow.cpp622
-rw-r--r--src/gui/kernel/qopenglwindow.h (renamed from src/gui/kernel/qclipboard_qpa.cpp)85
-rw-r--r--src/gui/kernel/qpaintdevicewindow.cpp215
-rw-r--r--src/gui/kernel/qpaintdevicewindow.h (renamed from src/gui/kernel/qplatformscreenpageflipper.h)65
-rw-r--r--src/gui/kernel/qpaintdevicewindow_p.h (renamed from src/gui/kernel/qplatformscreenpageflipper.cpp)155
-rw-r--r--src/gui/kernel/qpalette.cpp45
-rw-r--r--src/gui/kernel/qpalette.h2
-rw-r--r--src/gui/kernel/qpixelformat.cpp569
-rw-r--r--src/gui/kernel/qpixelformat.h391
-rw-r--r--src/gui/kernel/qplatformintegration.cpp21
-rw-r--r--src/gui/kernel/qplatformmenu.h12
-rw-r--r--src/gui/kernel/qplatformnativeinterface.cpp6
-rw-r--r--src/gui/kernel/qplatformnativeinterface.h2
-rw-r--r--src/gui/kernel/qplatformscreen.cpp9
-rw-r--r--src/gui/kernel/qplatformscreen.h2
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon.cpp (renamed from src/gui/kernel/qplatformsystemtrayicon_qpa.cpp)0
-rw-r--r--src/gui/kernel/qplatformtheme.cpp6
-rw-r--r--src/gui/kernel/qplatformtheme.h1
-rw-r--r--src/gui/kernel/qplatformwindow.cpp23
-rw-r--r--src/gui/kernel/qplatformwindow.h1
-rw-r--r--src/gui/kernel/qrasterwindow.cpp136
-rw-r--r--src/gui/kernel/qrasterwindow.h (renamed from src/gui/kernel/qkeymapper_qpa.cpp)51
-rw-r--r--src/gui/kernel/qscreen.cpp10
-rw-r--r--src/gui/kernel/qscreen.h6
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp40
-rw-r--r--src/gui/kernel/qsurfaceformat.h3
-rw-r--r--src/gui/kernel/qwindow.cpp177
-rw-r--r--src/gui/kernel/qwindow_p.h13
-rw-r--r--src/gui/kernel/qwindowdefs_win.h4
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp43
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h19
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h28
49 files changed, 3539 insertions, 872 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index e9e4a1d818..1169985ea8 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -66,13 +66,14 @@ HEADERS += \
kernel/qplatformsharedgraphicscache.h \
kernel/qplatformdialoghelper.h \
kernel/qplatformservices.h \
- kernel/qplatformscreenpageflipper.h \
kernel/qplatformsystemtrayicon.h \
- kernel/qplatformsessionmanager.h
+ kernel/qplatformsessionmanager.h \
+ kernel/qpixelformat.h \
+ kernel/qpaintdevicewindow.h \
+ kernel/qpaintdevicewindow_p.h \
+ kernel/qrasterwindow.h
SOURCES += \
- kernel/qclipboard_qpa.cpp \
- kernel/qcursor_qpa.cpp \
kernel/qgenericpluginfactory.cpp \
kernel/qgenericplugin.cpp \
kernel/qwindowsysteminterface.cpp \
@@ -109,7 +110,6 @@ SOURCES += \
kernel/qinputmethod.cpp \
kernel/qkeysequence.cpp \
kernel/qkeymapper.cpp \
- kernel/qkeymapper_qpa.cpp \
kernel/qpalette.cpp \
kernel/qguivariant.cpp \
kernel/qscreen.cpp \
@@ -119,20 +119,24 @@ SOURCES += \
kernel/qplatformsharedgraphicscache.cpp \
kernel/qplatformdialoghelper.cpp \
kernel/qplatformservices.cpp \
- kernel/qplatformscreenpageflipper.cpp \
- kernel/qplatformsystemtrayicon_qpa.cpp \
+ kernel/qplatformsystemtrayicon.cpp \
kernel/qplatformsessionmanager.cpp \
- kernel/qplatformmenu.cpp
+ kernel/qplatformmenu.cpp \
+ kernel/qpixelformat.cpp \
+ kernel/qpaintdevicewindow.cpp \
+ kernel/qrasterwindow.cpp
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
HEADERS += \
kernel/qplatformopenglcontext.h \
kernel/qopenglcontext.h \
- kernel/qopenglcontext_p.h
+ kernel/qopenglcontext_p.h \
+ kernel/qopenglwindow.h
SOURCES += \
kernel/qplatformopenglcontext.cpp \
- kernel/qopenglcontext.cpp
+ kernel/qopenglcontext.cpp \
+ kernel/qopenglwindow.cpp
}
win32:HEADERS+=kernel/qwindowdefs_win.h
diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp
index 3c2d36ce86..672eb9eb65 100644
--- a/src/gui/kernel/qclipboard.cpp
+++ b/src/gui/kernel/qclipboard.cpp
@@ -50,6 +50,10 @@
#include "qimage.h"
#include "qtextcodec.h"
+#include "private/qguiapplication_p.h"
+#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformclipboard.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -438,6 +442,12 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode)
\sa setMimeData()
*/
+const QMimeData* QClipboard::mimeData(Mode mode) const
+{
+ QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
+ if (!clipboard->supportsMode(mode)) return 0;
+ return clipboard->mimeData(mode);
+}
/*!
\fn void QClipboard::setMimeData(QMimeData *src, Mode mode)
@@ -458,6 +468,13 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode)
\sa mimeData()
*/
+void QClipboard::setMimeData(QMimeData* src, Mode mode)
+{
+ QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
+ if (!clipboard->supportsMode(mode)) return;
+
+ clipboard->setMimeData(src,mode);
+}
/*!
\fn void QClipboard::clear(Mode mode)
@@ -472,7 +489,10 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode)
\sa QClipboard::Mode, supportsSelection()
*/
-
+void QClipboard::clear(Mode mode)
+{
+ setMimeData(0, mode);
+}
/*!
Returns \c true if the clipboard supports mouse selection; otherwise
@@ -527,6 +547,11 @@ bool QClipboard::ownsFindBuffer() const
Returns \c true if the clipboard supports the clipboard mode speacified by \a mode;
otherwise returns \c false.
*/
+bool QClipboard::supportsMode(Mode mode) const
+{
+ QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
+ return clipboard->supportsMode(mode);
+}
/*!
\internal
@@ -534,6 +559,11 @@ bool QClipboard::ownsFindBuffer() const
Returns \c true if the clipboard supports the clipboard data speacified by \a mode;
otherwise returns \c false.
*/
+bool QClipboard::ownsMode(Mode mode) const
+{
+ QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
+ return clipboard->ownsMode(mode);
+}
/*!
\internal
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index a33b264704..87774b2056 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -51,6 +51,9 @@
#include <private/qcursor_p.h>
#include <qdebug.h>
+#include <qpa/qplatformcursor.h>
+#include <private/qguiapplication_p.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -172,6 +175,13 @@ QT_BEGIN_NAMESPACE
\sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal()
*/
+QPoint QCursor::pos(const QScreen *screen)
+{
+ if (screen)
+ if (const QPlatformCursor *cursor = screen->handle()->cursor())
+ return cursor->pos();
+ return QGuiApplicationPrivate::lastCursorPosition.toPoint();
+}
/*!
\fn QPoint QCursor::pos()
@@ -191,7 +201,10 @@ QT_BEGIN_NAMESPACE
\sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen()
*/
-
+QPoint QCursor::pos()
+{
+ return QCursor::pos(QGuiApplication::primaryScreen());
+}
/*!
\fn void QCursor::setPos(QScreen *screen, int x, int y)
@@ -214,6 +227,19 @@ QT_BEGIN_NAMESPACE
\sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal()
*/
+void QCursor::setPos(QScreen *screen, int x, int y)
+{
+ if (screen) {
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+ const QPoint pos = QPoint(x, y);
+ // Need to check, since some X servers generate null mouse move
+ // events, causing looping in applications which call setPos() on
+ // every mouse move event.
+ if (pos != cursor->pos())
+ cursor->setPos(pos);
+ }
+ }
+}
/*!
\fn void QCursor::setPos(int x, int y)
@@ -226,6 +252,10 @@ QT_BEGIN_NAMESPACE
\sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen()
*/
+void QCursor::setPos(int x, int y)
+{
+ QCursor::setPos(QGuiApplication::primaryScreen(), x, y);
+}
/*!
\fn void QCursor::setPos (const QPoint &p)
@@ -401,34 +431,6 @@ QCursor::QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
d = QCursorData::setBitmap(bitmap, mask, hotX, hotY);
}
-QCursorData *qt_cursorTable[Qt::LastCursor + 1];
-bool QCursorData::initialized = false;
-
-/*! \internal */
-void QCursorData::cleanup()
-{
- if(!QCursorData::initialized)
- return;
-
- for (int shape = 0; shape <= Qt::LastCursor; ++shape) {
- // In case someone has a static QCursor defined with this shape
- if (!qt_cursorTable[shape]->ref.deref())
- delete qt_cursorTable[shape];
- qt_cursorTable[shape] = 0;
- }
- QCursorData::initialized = false;
-}
-
-/*! \internal */
-void QCursorData::initialize()
-{
- if (QCursorData::initialized)
- return;
- for (int shape = 0; shape <= Qt::LastCursor; ++shape)
- qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape);
- QCursorData::initialized = true;
-}
-
/*!
Constructs a cursor with the default arrow shape.
*/
@@ -602,6 +604,73 @@ QDebug operator<<(QDebug dbg, const QCursor &c)
}
#endif
+/*****************************************************************************
+ Internal QCursorData class
+ *****************************************************************************/
+
+QCursorData *qt_cursorTable[Qt::LastCursor + 1];
+bool QCursorData::initialized = false;
+
+QCursorData::QCursorData(Qt::CursorShape s)
+ : ref(1), cshape(s), bm(0), bmm(0), hx(0), hy(0)
+{
+}
+
+QCursorData::~QCursorData()
+{
+ delete bm;
+ delete bmm;
+}
+
+/*! \internal */
+void QCursorData::cleanup()
+{
+ if(!QCursorData::initialized)
+ return;
+
+ for (int shape = 0; shape <= Qt::LastCursor; ++shape) {
+ // In case someone has a static QCursor defined with this shape
+ if (!qt_cursorTable[shape]->ref.deref())
+ delete qt_cursorTable[shape];
+ qt_cursorTable[shape] = 0;
+ }
+ QCursorData::initialized = false;
+}
+
+/*! \internal */
+void QCursorData::initialize()
+{
+ if (QCursorData::initialized)
+ return;
+ for (int shape = 0; shape <= Qt::LastCursor; ++shape)
+ qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape);
+ QCursorData::initialized = true;
+}
+
+QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
+{
+ if (!QCursorData::initialized)
+ QCursorData::initialize();
+ if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
+ qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
+ QCursorData *c = qt_cursorTable[0];
+ c->ref.ref();
+ return c;
+ }
+ QCursorData *d = new QCursorData;
+ d->bm = new QBitmap(bitmap);
+ d->bmm = new QBitmap(mask);
+ d->cshape = Qt::BitmapCursor;
+ d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
+ d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
+
+ return d;
+}
+
+void QCursorData::update()
+{
+}
+
QT_END_NAMESPACE
#endif // QT_NO_CURSOR
diff --git a/src/gui/kernel/qcursor_qpa.cpp b/src/gui/kernel/qcursor_qpa.cpp
deleted file mode 100644
index 0b19a47c69..0000000000
--- a/src/gui/kernel/qcursor_qpa.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qcursor.h>
-#include <qscreen.h>
-#include <private/qcursor_p.h>
-#include <qpa/qplatformcursor.h>
-#include <private/qguiapplication_p.h>
-#include <qbitmap.h>
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-#ifndef QT_NO_CURSOR
-
-/*****************************************************************************
- Internal QCursorData class
- *****************************************************************************/
-
-QCursorData::QCursorData(Qt::CursorShape s)
- : ref(1), cshape(s), bm(0), bmm(0), hx(0), hy(0)
-{
-}
-
-QCursorData::~QCursorData()
-{
- delete bm;
- delete bmm;
-}
-
-
-/*****************************************************************************
- Global cursors
- *****************************************************************************/
-
-extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp
-
-QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
-{
- if (!QCursorData::initialized)
- QCursorData::initialize();
- if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
- qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
- QCursorData *c = qt_cursorTable[0];
- c->ref.ref();
- return c;
- }
- QCursorData *d = new QCursorData;
- d->bm = new QBitmap(bitmap);
- d->bmm = new QBitmap(mask);
- d->cshape = Qt::BitmapCursor;
- d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
- d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
-
- return d;
-}
-
-void QCursorData::update()
-{
-}
-
-#endif //QT_NO_CURSOR
-
-QPoint QCursor::pos()
-{
- return QCursor::pos(QGuiApplication::primaryScreen());
-}
-
-QPoint QCursor::pos(const QScreen *screen)
-{
- if (screen)
- if (const QPlatformCursor *cursor = screen->handle()->cursor())
- return cursor->pos();
- return QGuiApplicationPrivate::lastCursorPosition.toPoint();
-}
-
-void QCursor::setPos(QScreen *screen, int x, int y)
-{
- if (screen) {
- if (QPlatformCursor *cursor = screen->handle()->cursor()) {
- const QPoint pos = QPoint(x, y);
- // Need to check, since some X servers generate null mouse move
- // events, causing looping in applications which call setPos() on
- // every mouse move event.
- if (pos != cursor->pos())
- cursor->setPos(pos);
- }
- }
-}
-
-void QCursor::setPos(int x, int y)
-{
- QCursor::setPos(QGuiApplication::primaryScreen(), x, y);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp
index d34a135eb7..328ca389ed 100644
--- a/src/gui/kernel/qdnd.cpp
+++ b/src/gui/kernel/qdnd.cpp
@@ -142,6 +142,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
QGuiApplicationPrivate::instance()->notifyDragStarted(o);
const Qt::DropAction result = m_platformDrag->drag(m_object);
m_object = 0;
+ o->deleteLater();
return result;
}
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index d6741af152..958df48f17 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -46,6 +46,7 @@
#include "qpa/qplatformdrag.h"
#include "private/qevent_p.h"
#include "qdebug.h"
+#include "qmetaobject.h"
#include "qmimedata.h"
#include "private/qdnd_p.h"
#include "qevent_p.h"
@@ -287,6 +288,8 @@ QMouseEvent::~QMouseEvent()
\l Qt::MouseEventNotSynthesized is returned always.
\sa Qt::MouseEventSource
+ \sa QGraphicsSceneMouseEvent::source()
+ \sa QGraphicsSceneMouseEvent::setSource()
*/
Qt::MouseEventSource QMouseEvent::source() const
{
@@ -301,6 +304,8 @@ Qt::MouseEventSource QMouseEvent::source() const
The mouse event flags provide additional information about a mouse event.
\sa Qt::MouseEventFlag
+ \sa QGraphicsSceneMouseEvent::flags()
+ \sa QGraphicsSceneMouseEvent::setFlags()
*/
Qt::MouseEventFlags QMouseEvent::flags() const
{
@@ -1185,7 +1190,7 @@ Qt::FocusReason QFocusEvent::reason() const
The event contains a region() that needs to be updated, and a
rect() that is the bounding rectangle of that region. Both are
- provided because many widgets can't make much use of region(),
+ provided because many widgets cannot make much use of region(),
and rect() can be much faster than region().boundingRect().
\section1 Automatic Clipping
@@ -1302,7 +1307,8 @@ QMoveEvent::~QMoveEvent()
*/
/*!
- Constructs an expose event for the given \a exposeRegion.
+ Constructs an expose event for the given \a exposeRegion which must be
+ in local coordinates.
*/
QExposeEvent::QExposeEvent(const QRegion &exposeRegion)
: QEvent(Expose)
@@ -1320,7 +1326,7 @@ QExposeEvent::~QExposeEvent()
/*!
\fn const QRegion &QExposeEvent::region() const
- Returns the window area that has been exposed.
+ Returns the window area that has been exposed. The region is given in local coordinates.
*/
/*!
@@ -1977,40 +1983,63 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const
\ingroup events
- Tablet Events are generated from a Wacom tablet. Most of the time you will
- want to deal with events from the tablet as if they were events from a
- mouse; for example, you would retrieve the cursor position with x(), y(),
- pos(), globalX(), globalY(), and globalPos(). In some situations you may
- wish to retrieve the extra information provided by the tablet device
- driver; for example, you might want to do subpixeling with higher
- resolution coordinates or you may want to adjust color brightness based on
- pressure. QTabletEvent allows you to read the pressure(), the xTilt(), and
- yTilt(), as well as the type of device being used with device() (see
- \l{TabletDevice}). It can also give you the minimum and maximum values for
- each device's pressure and high resolution coordinates.
-
- A tablet event contains a special accept flag that indicates whether the
- receiver wants the event. You should call QTabletEvent::accept() if you
- handle the tablet event; otherwise it will be sent to the parent widget.
- The exception are TabletEnterProximity and TabletLeaveProximity events,
- these are only sent to QApplication and don't check whether or not they are
- accepted.
-
- The QWidget::setEnabled() function can be used to enable or
- disable mouse and keyboard events for a widget.
-
- The event handler QWidget::tabletEvent() receives all three types of
- tablet events. Qt will first send a tabletEvent then, if it is not
- accepted, it will send a mouse event. This allows applications that
- don't utilize tablets to use a tablet like a mouse, while also
- enabling those who want to use both tablets and mouses differently.
+ \e{Tablet events} are generated from tablet peripherals such as Wacom
+ tablets and various other brands, and electromagnetic stylus devices
+ included with some types of tablet computers. (It is not the same as
+ \l QTouchEvent which a touchscreen generates, even when a passive stylus is
+ used on a touchscreen.)
+
+ Tablet events are similar to mouse events; for example, the \l x(), \l y(),
+ \l pos(), \l globalX(), \l globalY(), and \l globalPos() accessors provide
+ the cursor position, and you can see which \l buttons() are pressed
+ (pressing the stylus tip against the tablet surface is equivalent to a left
+ mouse button). But tablet events also pass through some extra information
+ that the tablet device driver provides; for example, you might want to do
+ subpixel rendering with higher resolution coordinates (\l hiResGlobalX()
+ and \l hiResGlobalY()), adjust color brightness based on the \l pressure()
+ of the tool against the tablet surface, use different brushes depending on
+ the type of tool in use (\l device()), modulate the brush shape in some way
+ according to the X-axis and Y-axis tilt of the tool with respect to the
+ tablet surface (\l xTilt() and \l yTilt()), and use a virtual eraser
+ instead of a brush if the user switches to the other end of a double-ended
+ stylus (\l pointerType()).
+
+ Every event contains an accept flag that indicates whether the receiver
+ wants the event. You should call QTabletEvent::accept() if you handle the
+ tablet event; otherwise it will be sent to the parent widget. The exception
+ are TabletEnterProximity and TabletLeaveProximity events: these are only
+ sent to QApplication and do not check whether or not they are accepted.
+
+ The QWidget::setEnabled() function can be used to enable or disable
+ mouse, tablet and keyboard events for a widget.
+
+ The event handler QWidget::tabletEvent() receives TabletPress,
+ TabletRelease and TabletMove events. Qt will first send a
+ tablet event, then if it is not accepted by any widget, it will send a
+ mouse event. This allows users of applications that are not designed for
+ tablets to use a tablet like a mouse. However high-resolution drawing
+ applications should handle the tablet events, because they can occur at a
+ higher frequency, which is a benefit for smooth and accurate drawing.
+ If the tablet events are rejected, the synthetic mouse events may be
+ compressed for efficiency.
+
+ New in Qt 5.4: QTabletEvent includes all information available from the
+ device, including \l QTabletEvent::buttons(). Previously it was not
+ possible to accept all tablet events and also know which stylus buttons
+ were pressed.
+
+ Note that pressing the stylus button while the stylus hovers over the
+ tablet will generate a button press on some types of tablets, while on
+ other types it will be necessary to press the stylus against the tablet
+ surface in order to register the simultaneous stylus button press.
\section1 Notes for X11 Users
- Qt uses the following hard-coded names to identify tablet
- devices from the xorg.conf file on X11 (apart from IRIX):
- 'stylus', 'pen', and 'eraser'. If the devices have other names,
- they will not be picked up Qt.
+ If the tablet is configured in xorg.conf to use the Wacom driver, there
+ will be separate XInput "devices" for the stylus, eraser, and (optionally)
+ cursor and touchpad. Qt recognizes these by their names. Otherwise, if the
+ tablet is configured to use the evdev driver, there will be only one device
+ and applications may not be able to distinguish the stylus from the eraser.
*/
/*!
@@ -2068,11 +2097,73 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const
The \a tangentialPressure parameter contins the tangential pressure of an air
brush. If the device does not support tangential pressure, pass 0 here.
+ \a rotation contains the device's rotation in degrees. 4D mice and the Wacom
+ Art Pen support rotation. If the device does not support rotation, pass 0 here.
+
+ The \a button that caused the event is given as a value from the
+ \l Qt::MouseButton enum. If the event \a type is not \l TabletPress or
+ \l TabletRelease, the appropriate button for this event is \l Qt::NoButton.
+
+ \a buttons is the state of all buttons at the time of the event.
+
+ \sa pos(), globalPos(), device(), pressure(), xTilt(), yTilt(), uniqueId(), rotation(),
+ tangentialPressure(), z()
+*/
+
+QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalPos,
+ int device, int pointerType,
+ qreal pressure, int xTilt, int yTilt, qreal tangentialPressure,
+ qreal rotation, int z, Qt::KeyboardModifiers keyState, qint64 uniqueID,
+ Qt::MouseButton button, Qt::MouseButtons buttons)
+ : QInputEvent(type, keyState),
+ mPos(pos),
+ mGPos(globalPos),
+ mDev(device),
+ mPointerType(pointerType),
+ mXT(xTilt),
+ mYT(yTilt),
+ mZ(z),
+ mPress(pressure),
+ mTangential(tangentialPressure),
+ mRot(rotation),
+ mUnique(uniqueID),
+ mExtra(new QTabletEventPrivate(button, buttons))
+{
+}
+
+/*!
+ Construct a tablet event of the given \a type.
+
+ The \a pos parameter indicates where the event occurred in the
+ widget; \a globalPos is the corresponding position in absolute
+ coordinates.
+
+ \a pressure contains the pressure exerted on the \a device.
+
+ \a pointerType describes the type of pen that is being used.
+
+ \a xTilt and \a yTilt contain the device's degree of tilt from the
+ x and y axes respectively.
+
+ \a keyState specifies which keyboard modifiers are pressed (e.g.,
+ \uicontrol{Ctrl}).
+
+ The \a uniqueID parameter contains the unique ID for the current device.
+
+ The \a z parameter contains the coordinate of the device on the tablet, this
+ is usually given by a wheel on 4D mouse. If the device does not support a
+ Z-axis, pass zero here.
+
+ The \a tangentialPressure parameter contins the tangential pressure of an air
+ brush. If the device does not support tangential pressure, pass 0 here.
+
\a rotation contains the device's rotation in degrees. 4D mice support
rotation. If the device does not support rotation, pass 0 here.
\sa pos(), globalPos(), device(), pressure(), xTilt(), yTilt(), uniqueId(), rotation(),
tangentialPressure(), z()
+
+ \deprecated in 5.4: use the constructor with MouseButton status
*/
QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalPos,
@@ -2091,7 +2182,7 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP
mTangential(tangentialPressure),
mRot(rotation),
mUnique(uniqueID),
- mExtra(0)
+ mExtra(new QTabletEventPrivate(Qt::NoButton, Qt::NoButton))
{
}
@@ -2103,6 +2194,34 @@ QTabletEvent::~QTabletEvent()
}
/*!
+ Returns the button that caused the event.
+
+ Note that the returned value is always Qt::NoButton for \l TabletMove,
+ \l TabletEnterProximity and \l TabletLeaveProximity events.
+
+ \sa buttons(), Qt::MouseButton
+*/
+Qt::MouseButton QTabletEvent::button() const
+{
+ return static_cast<QTabletEventPrivate *>(mExtra)->b;
+}
+
+/*!
+ Returns the button state when the event was generated. The button state is
+ a combination of buttons from the \l Qt::MouseButton enum using the OR
+ operator. For \l TabletMove events, this is all buttons that are pressed
+ down. For \l TabletPress events this includes the button that caused the
+ event. For \l TabletRelease events this excludes the button that caused the
+ event.
+
+ \sa button(), Qt::MouseButton
+*/
+Qt::MouseButtons QTabletEvent::buttons() const
+{
+ return static_cast<QTabletEventPrivate *>(mExtra)->buttonState;
+}
+
+/*!
\fn TabletDevices QTabletEvent::device() const
Returns the type of device that generated the event.
@@ -2132,7 +2251,7 @@ QTabletEvent::~QTabletEvent()
\fn qreal QTabletEvent::rotation() const
Returns the rotation of the current device in degress. This is usually
- given by a 4D Mouse. If the device doesn't support rotation this value is
+ given by a 4D Mouse. If the device does not support rotation this value is
always 0.0.
*/
@@ -3036,7 +3155,7 @@ QActionEvent::~QActionEvent()
If spontaneous() is true, the event originated outside the
application. In this case, the user hid the window using the
window manager controls, either by iconifying the window or by
- switching to another virtual desktop where the window isn't
+ switching to another virtual desktop where the window is not
visible. The window will become hidden but not withdrawn. If the
window was iconified, QWidget::isMinimized() returns \c true.
@@ -3237,330 +3356,470 @@ QShortcutEvent::~QShortcutEvent()
#ifndef QT_NO_DEBUG_STREAM
+static inline void formatTouchPoint(QDebug d, const QTouchEvent::TouchPoint &tp)
+{
+ d << "TouchPoint(" << tp.id() << ' ' << tp.rect();
+ switch (tp.state()) {
+ case Qt::TouchPointPressed:
+ d << " pressed";
+ break;
+ case Qt::TouchPointReleased:
+ d << " released";
+ break;
+ case Qt::TouchPointMoved:
+ d << " moved";
+ break;
+ case Qt::TouchPointStationary:
+ d << " stationary";
+ break;
+ }
+ d << ')';
+}
+
static inline void formatTouchEvent(QDebug d, const char *name, const QTouchEvent &t)
{
d << "QTouchEvent(" << name << " states: " << t.touchPointStates();
- const QList<QTouchEvent::TouchPoint> points = t.touchPoints();
- const int size = points.size();
- d << ", " << size << " points: ";
- for (int i = 0; i < size; ++i) {
+ d << ", " << t.touchPoints().size() << " points: " << t.touchPoints() << ')';
+}
+
+static void formatUnicodeString(QDebug d, const QString &s)
+{
+ d << '"' << hex;
+ for (int i = 0; i < s.size(); ++i) {
if (i)
- d << ", ";
- d << points.at(i).pos() << ' ' << points.at(i).rect();
- switch (points.at(i).state()) {
- case Qt::TouchPointPressed:
- d << " pressed";
- break;
- case Qt::TouchPointReleased:
- d << " released";
- break;
- case Qt::TouchPointMoved:
- d << " moved";
- break;
- case Qt::TouchPointStationary:
- d << " stationary";
- break;
+ d << ',';
+ d << "U+" << s.at(i).unicode();
+ }
+ d << dec << '"';
+}
+
+static inline void formatInputMethodEvent(QDebug d, const QInputMethodEvent *e)
+{
+ d << "QInputMethodEvent(";
+ if (!e->preeditString().isEmpty()) {
+ d << "preedit=";
+ formatUnicodeString(d, e->preeditString());
+ }
+ if (!e->commitString().isEmpty()) {
+ d << ", commit=";
+ formatUnicodeString(d, e->commitString());
+ }
+ if (e->replacementLength()) {
+ d << ", replacementStart=" << e->replacementStart() << ", replacementLength="
+ << e->replacementLength();
+ }
+ if (const int attributeCount = e->attributes().size()) {
+ d << ", attributes= {";
+ for (int a = 0; a < attributeCount; ++a) {
+ const QInputMethodEvent::Attribute &at = e->attributes().at(a);
+ if (a)
+ d << ',';
+ d << "[type= " << at.type << ", start=" << at.start << ", length=" << at.length
+ << ", value=" << at.value << ']';
}
+ d << '}';
}
d << ')';
}
-QDebug operator<<(QDebug dbg, const QEvent *e) {
- // More useful event output could be added here
- if (!e)
- return dbg << "QEvent(this = 0x0)";
- const char *n = 0;
- switch (e->type()) {
- case QEvent::Timer:
- n = "Timer";
- break;
- case QEvent::MouseButtonPress:
- case QEvent::MouseMove:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- {
- const QMouseEvent *me = static_cast<const QMouseEvent*>(e);
- switch(me->type()) {
- case QEvent::MouseButtonPress:
- n = "MouseButtonPress";
- break;
- case QEvent::MouseMove:
- n = "MouseMove";
- break;
- case QEvent::MouseButtonRelease:
- n = "MouseButtonRelease";
- break;
- case QEvent::MouseButtonDblClick:
- default:
- n = "MouseButtonDblClick";
- break;
+static inline void formatInputMethodQueryEvent(QDebug d, const QInputMethodQueryEvent *e)
+{
+ const Qt::InputMethodQueries queries = e->queries();
+ d << "QInputMethodQueryEvent(queries=" << showbase << hex << int(queries)
+ << noshowbase << dec << ", {";
+ for (unsigned mask = 1; mask <= Qt::ImTextAfterCursor; mask<<=1) {
+ if (queries & mask) {
+ const QVariant value = e->value(static_cast<Qt::InputMethodQuery>(mask));
+ if (value.isValid())
+ d << '[' << showbase << hex << mask << noshowbase << dec << '=' << value << "],";
}
- QDebug nsp = dbg.nospace();
- nsp << "QMouseEvent(" << n
- << ", " << me->button()
- << ", " << hex << (int)me->buttons()
- << ", " << hex << (int)me->modifiers() << dec;
- if (const Qt::MouseEventSource source = me->source())
- nsp << ", source = " << source;
- nsp << ')';
}
- return dbg.space();
+ d << "})";
+}
-#ifndef QT_NO_TOOLTIP
- case QEvent::ToolTip:
- n = "ToolTip";
- break;
-#endif
- case QEvent::WindowActivate:
- n = "WindowActivate";
- break;
- case QEvent::WindowDeactivate:
- n = "WindowDeactivate";
- break;
- case QEvent::ActivationChange:
- n = "ActivationChange";
- break;
-#ifndef QT_NO_WHEELEVENT
- case QEvent::Wheel:
- dbg.nospace() << "QWheelEvent("
- << static_cast<const QWheelEvent *>(e)->pixelDelta()
- << static_cast<const QWheelEvent *>(e)->angleDelta()
- << ')';
- return dbg.space();
-#endif
+static const char *eventTypeName(QEvent::Type t)
+{
+ static const int enumIdx = QEvent::staticMetaObject.indexOfEnumerator("Type");
+ return t <= QEvent::User
+ ? QEvent::staticMetaObject.enumerator(enumIdx).valueToKey(t)
+ : "User";
+}
+
+static const char *eventClassName(QEvent::Type t)
+{
+ switch (t) {
+ case QEvent::ActionAdded:
+ case QEvent::ActionRemoved:
+ case QEvent::ActionChanged:
+ return "QActionEvent";
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::NonClientAreaMouseMove:
+ case QEvent::NonClientAreaMouseButtonPress:
+ case QEvent::NonClientAreaMouseButtonRelease:
+ case QEvent::NonClientAreaMouseButtonDblClick:
+ return "QMouseEvent";
+ case QEvent::DragEnter:
+ return "QDragEnterEvent";
+ case QEvent::DragMove:
+ return "QDragMoveEvent";
+ case QEvent::Drop:
+ return "QDropEvent";
case QEvent::KeyPress:
case QEvent::KeyRelease:
case QEvent::ShortcutOverride:
- {
- const QKeyEvent *ke = static_cast<const QKeyEvent*>(e);
- switch(ke->type()) {
- case QEvent::ShortcutOverride:
- n = "ShortcutOverride";
- break;
- case QEvent::KeyRelease:
- n = "KeyRelease";
- break;
- case QEvent::KeyPress:
- default:
- n = "KeyPress";
- break;
- }
- dbg.nospace() << "QKeyEvent(" << n
- << ", " << hex << ke->key()
- << ", " << hex << (int)ke->modifiers()
- << ", \"" << ke->text()
- << "\", " << ke->isAutoRepeat()
- << ", " << ke->count()
- << ')';
- }
- return dbg.space();
+ return "QKeyEvent";
case QEvent::FocusIn:
- n = "FocusIn";
- break;
case QEvent::FocusOut:
- n = "FocusOut";
- break;
- case QEvent::Enter:
- n = "Enter";
- break;
- case QEvent::Leave:
- n = "Leave";
- break;
- case QEvent::PaletteChange:
- n = "PaletteChange";
- break;
- case QEvent::PolishRequest:
- n = "PolishRequest";
- break;
- case QEvent::Polish:
- n = "Polish";
- break;
- case QEvent::UpdateRequest:
- n = "UpdateRequest";
- break;
+ case QEvent::FocusAboutToChange:
+ return "QFocusEvent";
+ case QEvent::ChildAdded:
+ case QEvent::ChildPolished:
+ case QEvent::ChildRemoved:
+ return "QChildEvent";
case QEvent::Paint:
- n = "Paint";
- break;
+ return "QPaintEvent";
case QEvent::Move:
- n = "Move";
- break;
+ return "QMoveEvent";
case QEvent::Resize:
- n = "Resize";
- break;
- case QEvent::Create:
- n = "Create";
- break;
- case QEvent::Destroy:
- n = "Destroy";
- break;
- case QEvent::Close:
- n = "Close";
- break;
- case QEvent::Quit:
- n = "Quit";
- break;
- case QEvent::FileOpen:
- n = "FileOpen";
- break;
+ return "QResizeEvent";
case QEvent::Show:
- n = "Show";
- break;
- case QEvent::ShowToParent:
- n = "ShowToParent";
- break;
+ return "QShowEvent";
case QEvent::Hide:
- n = "Hide";
- break;
- case QEvent::HideToParent:
- n = "HideToParent";
- break;
- case QEvent::None:
- n = "None";
- break;
- case QEvent::ParentChange:
- n = "ParentChange";
- break;
- case QEvent::ParentAboutToChange:
- n = "ParentAboutToChange";
- break;
+ return "QHideEvent";
+ case QEvent::Enter:
+ return "QEnterEvent";
+ case QEvent::Close:
+ return "QCloseEvent";
+ case QEvent::FileOpen:
+ return "QFileOpenEvent";
+#ifndef QT_NO_GESTURES
+ case QEvent::NativeGesture:
+ return "QNativeGestureEvent";
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
+ return "QGestureEvent";
+#endif
case QEvent::HoverEnter:
- n = "HoverEnter";
- break;
- case QEvent::HoverMove:
- n = "HoverMove";
- break;
case QEvent::HoverLeave:
- n = "HoverLeave";
- break;
- case QEvent::ZOrderChange:
- n = "ZOrderChange";
- break;
- case QEvent::StyleChange:
- n = "StyleChange";
- break;
- case QEvent::DragEnter:
- n = "DragEnter";
- break;
- case QEvent::DragMove:
- n = "DragMove";
- break;
- case QEvent::DragLeave:
- n = "DragLeave";
- break;
- case QEvent::Drop:
- n = "Drop";
- break;
+ case QEvent::HoverMove:
+ return "QHoverEvent";
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ case QEvent::TabletPress:
+ case QEvent::TabletMove:
+ case QEvent::TabletRelease:
+ return "QTabletEvent";
+ case QEvent::StatusTip:
+ return "QStatusTipEvent";
+ case QEvent::ToolTip:
+ return "QHelpEvent";
+ case QEvent::WindowStateChange:
+ return "QWindowStateChangeEvent";
+ case QEvent::Wheel:
+ return "QWheelEvent";
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ return "QTouchEvent";
+ case QEvent::Shortcut:
+ return "QShortcutEvent";
+ case QEvent::InputMethod:
+ return "QInputMethodEvent";
+ case QEvent::InputMethodQuery:
+ return "QInputMethodQueryEvent";
+ case QEvent::OrientationChange:
+ return "QScreenOrientationChangeEvent";
+ case QEvent::ScrollPrepare:
+ return "QScrollPrepareEvent";
+ case QEvent::Scroll:
+ return "QScrollEvent";
case QEvent::GraphicsSceneMouseMove:
- n = "GraphicsSceneMouseMove";
- break;
case QEvent::GraphicsSceneMousePress:
- n = "GraphicsSceneMousePress";
- break;
case QEvent::GraphicsSceneMouseRelease:
- n = "GraphicsSceneMouseRelease";
- break;
case QEvent::GraphicsSceneMouseDoubleClick:
- n = "GraphicsSceneMouseDoubleClick";
- break;
+ return "QGraphicsSceneMouseEvent";
case QEvent::GraphicsSceneContextMenu:
- n = "GraphicsSceneContextMenu";
- break;
case QEvent::GraphicsSceneHoverEnter:
- n = "GraphicsSceneHoverEnter";
- break;
case QEvent::GraphicsSceneHoverMove:
- n = "GraphicsSceneHoverMove";
- break;
case QEvent::GraphicsSceneHoverLeave:
- n = "GraphicsSceneHoverLeave";
- break;
case QEvent::GraphicsSceneHelp:
- n = "GraphicsSceneHelp";
- break;
case QEvent::GraphicsSceneDragEnter:
- n = "GraphicsSceneDragEnter";
- break;
case QEvent::GraphicsSceneDragMove:
- n = "GraphicsSceneDragMove";
- break;
case QEvent::GraphicsSceneDragLeave:
- n = "GraphicsSceneDragLeave";
- break;
case QEvent::GraphicsSceneDrop:
- n = "GraphicsSceneDrop";
- break;
case QEvent::GraphicsSceneWheel:
- n = "GraphicsSceneWheel";
+ return "QGraphicsSceneEvent";
+ case QEvent::Timer:
+ return "QTimerEvent";
+ default:
break;
- case QEvent::GraphicsSceneResize:
- n = "GraphicsSceneResize";
+ }
+ return "QEvent";
+}
+
+namespace {
+// Make protected QObject::staticQtMetaObject accessible for formatting enums.
+class DebugHelper : public QObject {
+public:
+ static const char *mouseButtonToString(Qt::MouseButton button)
+ {
+ static const int enumIdx = QObject::staticQtMetaObject.indexOfEnumerator("MouseButtons");
+ return QObject::staticQtMetaObject.enumerator(enumIdx).valueToKey(button);
+ }
+
+ static QByteArray mouseButtonsToString(Qt::MouseButtons buttons)
+ {
+ QByteArray result;
+ for (int i = 0; (uint)(1 << i) <= Qt::MaxMouseButton; ++i) {
+ const Qt::MouseButton button = static_cast<Qt::MouseButton>(1 << i);
+ if (buttons.testFlag(button)) {
+ if (!result.isEmpty())
+ result.append('|');
+ result.append(mouseButtonToString(button));
+ }
+ }
+ if (result.isEmpty())
+ result.append("NoButton");
+ return result;
+ }
+
+ static const char *mouseEventSourceToString(Qt::MouseEventSource source)
+ {
+ static const int enumIdx = QObject::staticQtMetaObject.indexOfEnumerator("MouseEventSource");
+ return QObject::staticQtMetaObject.enumerator(enumIdx).valueToKey(source);
+ }
+
+ static const char *focusReasonToString(Qt::FocusReason reason)
+ {
+ static const int enumIdx = QObject::staticQtMetaObject.indexOfEnumerator("FocusReason");
+ return QObject::staticQtMetaObject.enumerator(enumIdx).valueToKey(reason);
+ }
+
+# ifndef QT_NO_GESTURES
+ static const char *nativeGestureTypeToString(Qt::NativeGestureType type)
+ {
+ static const int enumIdx = QObject::staticQtMetaObject.indexOfEnumerator("NativeGestureType");
+ return QObject::staticQtMetaObject.enumerator(enumIdx).valueToKey(type);
+ }
+# endif // !QT_NO_GESTURES
+};
+} // namespace
+
+# ifndef QT_NO_DRAGANDDROP
+
+static void formatDropEvent(QDebug d, const QDropEvent *e)
+{
+ const QEvent::Type type = e->type();
+ d << eventClassName(type) << "(dropAction=" << e->dropAction() << ", proposedAction="
+ << e->proposedAction() << ", possibleActions=" << e->possibleActions()
+ << ", posF=" << e->posF();
+ if (type == QEvent::DragMove || type == QEvent::DragEnter)
+ d << ", answerRect=" << static_cast<const QDragMoveEvent *>(e)->answerRect();
+ d << ", formats=" << e->mimeData()->formats();
+ if (const Qt::KeyboardModifiers mods = e->keyboardModifiers())
+ d << ", keyboardModifiers=" << mods;
+ d << ", " << DebugHelper::mouseButtonsToString(e->mouseButtons()).constData();
+}
+
+# endif // !QT_NO_DRAGANDDROP
+
+# ifndef QT_NO_TABLETEVENT
+
+static void formatTabletEvent(QDebug d, const QTabletEvent *e)
+{
+ const QEvent::Type type = e->type();
+
+ static const int deviceEnumIdx = QTabletEvent::staticMetaObject.indexOfEnumerator("TabletDevice");
+ static const int pointerTypeEnumIdx = QTabletEvent::staticMetaObject.indexOfEnumerator("PointerType");
+ const char* device = QTabletEvent::staticMetaObject.enumerator(deviceEnumIdx).valueToKey(e->device());
+ const char* pointerType = QTabletEvent::staticMetaObject.enumerator(pointerTypeEnumIdx).valueToKey(e->pointerType());
+
+ d << eventClassName(type) << '(' << eventTypeName(type)
+ << ", device=" << device
+ << ", pointerType=" << pointerType
+ << ", uniqueId=" << e->uniqueId()
+ << ", pos=" << e->posF()
+ << ", z=" << e->z()
+ << ", xTilt=" << e->xTilt()
+ << ", yTilt=" << e->yTilt()
+ << ", " << DebugHelper::mouseButtonsToString(e->buttons()).constData();
+ if (type == QEvent::TabletPress || type == QEvent::TabletMove)
+ d << ", pressure=" << e->pressure();
+ if (e->device() == QTabletEvent::RotationStylus || e->device() == QTabletEvent::FourDMouse)
+ d << ", rotation=" << e->rotation();
+ if (e->device() == QTabletEvent::Airbrush)
+ d << ", tangentialPressure=" << e->tangentialPressure();
+}
+
+# endif // !QT_NO_TABLETEVENT
+
+QDebug operator<<(QDebug dbg, const QTouchEvent::TouchPoint &tp)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ formatTouchPoint(dbg, tp);
+ return dbg;
+}
+
+QDebug operator<<(QDebug dbg, const QEvent *e)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ if (!e) {
+ dbg << "QEvent(this = 0x0)";
+ return dbg;
+ }
+ // More useful event output could be added here
+ const QEvent::Type type = e->type();
+ switch (type) {
+ case QEvent::Expose:
+ dbg << "QExposeEvent(" << static_cast<const QExposeEvent *>(e)->region() << ')';
+ break;
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::NonClientAreaMouseButtonPress:
+ case QEvent::NonClientAreaMouseMove:
+ case QEvent::NonClientAreaMouseButtonRelease:
+ case QEvent::NonClientAreaMouseButtonDblClick:
+ {
+ const QMouseEvent *me = static_cast<const QMouseEvent*>(e);
+ const Qt::MouseButton button = me->button();
+ const Qt::MouseButtons buttons = me->buttons();
+ dbg << "QMouseEvent(" << eventTypeName(type);
+ if (type != QEvent::MouseMove && type != QEvent::NonClientAreaMouseMove)
+ dbg << ", " << DebugHelper::mouseButtonToString(button);
+ if (buttons && button != buttons)
+ dbg << ", buttons=" << DebugHelper::mouseButtonsToString(buttons).constData();
+ if (const int mods = int(me->modifiers()))
+ dbg << ", modifiers=0x" << hex << mods << dec;
+ dbg << ", localPos=" << me->localPos() << ", screenPos=" << me->screenPos();
+ if (me->source())
+ dbg << ", " << DebugHelper::mouseEventSourceToString(me->source());
+ if (const Qt::MouseEventFlags flags = me->flags())
+ dbg << ", flags = " << hex << int(flags) << dec;
+ dbg << ')';
+ }
break;
- case QEvent::GraphicsSceneMove:
- n = "GraphicsSceneMove";
+# ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel: {
+ const QWheelEvent *we = static_cast<const QWheelEvent *>(e);
+ dbg << "QWheelEvent(" << "pixelDelta=" << we->pixelDelta() << ", angleDelta=" << we->angleDelta() << ')';
+ }
break;
- case QEvent::CursorChange:
- n = "CursorChange";
+# endif // !QT_NO_WHEELEVENT
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::ShortcutOverride:
+ {
+ const QKeyEvent *ke = static_cast<const QKeyEvent *>(e);
+ dbg << "QKeyEvent(" << eventTypeName(type)
+ << ", key=0x" << hex << ke->key() << dec;
+ if (const int mods = ke->modifiers())
+ dbg << ", modifiers=0x" << hex << mods << dec;
+ if (!ke->text().isEmpty())
+ dbg << ", text=" << ke->text();
+ if (ke->isAutoRepeat())
+ dbg << ", autorepeat, count=" << ke->count();
+ dbg << ')';
+ }
break;
- case QEvent::ToolTipChange:
- n = "ToolTipChange";
+ case QEvent::Shortcut: {
+ const QShortcutEvent *se = static_cast<const QShortcutEvent *>(e);
+ dbg << "QShortcutEvent(" << se->key().toString() << ", id=" << se->shortcutId();
+ if (se->isAmbiguous())
+ dbg << ", ambiguous";
+ dbg << ')';
+ }
break;
- case QEvent::StatusTip:
- n = "StatusTip";
+ case QEvent::FocusAboutToChange:
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ dbg << "QFocusEvent(" << eventTypeName(type) << ", "
+ << DebugHelper::focusReasonToString(static_cast<const QFocusEvent *>(e)->reason())
+ << ')';
break;
- case QEvent::WhatsThis:
- n = "WhatsThis";
+ case QEvent::Move: {
+ const QMoveEvent *me = static_cast<const QMoveEvent *>(e);
+ dbg << "QMoveEvent(" << me->pos();
+ if (!me->spontaneous())
+ dbg << ", non-spontaneous";
+ dbg << ')';
+ }
+ break;
+ case QEvent::Resize: {
+ const QResizeEvent *re = static_cast<const QResizeEvent *>(e);
+ dbg << "QResizeEvent(" << re->size();
+ if (!re->spontaneous())
+ dbg << ", non-spontaneous";
+ dbg << ')';
+ }
break;
- case QEvent::FontChange:
- n = "FontChange";
+# ifndef QT_NO_DRAGANDDROP
+ case QEvent::DragEnter:
+ case QEvent::DragMove:
+ case QEvent::Drop:
+ formatDropEvent(dbg, static_cast<const QDropEvent *>(e));
break;
- case QEvent::Style:
- n = "Style";
+# endif // !QT_NO_DRAGANDDROP
+ case QEvent::InputMethod:
+ formatInputMethodEvent(dbg, static_cast<const QInputMethodEvent *>(e));
break;
- case QEvent::KeyboardLayoutChange:
- n = "KeyboardLayoutChange";
+ case QEvent::InputMethodQuery:
+ formatInputMethodQueryEvent(dbg, static_cast<const QInputMethodQueryEvent *>(e));
break;
- case QEvent::DynamicPropertyChange:
- n = "DynamicPropertyChange";
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ formatTouchEvent(dbg, eventTypeName(type), *static_cast<const QTouchEvent*>(e));
break;
- case QEvent::GrabMouse:
- n = "GrabMouse";
+ case QEvent::ChildAdded:
+ case QEvent::ChildPolished:
+ case QEvent::ChildRemoved:
+ dbg << "QChildEvent(" << eventTypeName(type) << ", " << (static_cast<const QChildEvent*>(e))->child() << ')';
break;
- case QEvent::UngrabMouse:
- n = "UngrabMouse";
+# ifndef QT_NO_GESTURES
+ case QEvent::NativeGesture: {
+ const QNativeGestureEvent *ne = static_cast<const QNativeGestureEvent *>(e);
+ dbg << "QNativeGestureEvent(" << DebugHelper::nativeGestureTypeToString(ne->gestureType())
+ << "localPos=" << ne->localPos() << ", value=" << ne->value() << ')';
+ }
+ break;
+# endif // !QT_NO_GESTURES
+ case QEvent::ApplicationStateChange:
+ dbg << "QApplicationStateChangeEvent("
+ << static_cast<const QApplicationStateChangeEvent *>(e)->applicationState() << ')';
break;
- case QEvent::GrabKeyboard:
- n = "GrabKeyboard";
+ case QEvent::ContextMenu:
+ dbg << "QContextMenuEvent(" << static_cast<const QContextMenuEvent *>(e)->pos() << ')';
break;
- case QEvent::UngrabKeyboard:
- n = "UngrabKeyboard";
+# ifndef QT_NO_TABLETEVENT
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ case QEvent::TabletPress:
+ case QEvent::TabletMove:
+ case QEvent::TabletRelease:
+ formatTabletEvent(dbg, static_cast<const QTabletEvent *>(e));
break;
- case QEvent::TouchBegin:
- n = "TouchBegin";
- case QEvent::TouchUpdate:
- n = n ? n : "TouchUpdate";
- case QEvent::TouchEnd:
- n = n ? n : "TouchEnd";
- formatTouchEvent(dbg.nospace(), n, *static_cast<const QTouchEvent*>(e));
- return dbg.space();
- case QEvent::ChildAdded: n = n ? n : "ChildAdded";
- case QEvent::ChildPolished: n = n ? n : "ChildPolished";
- case QEvent::ChildRemoved: n = n ? n : "ChildRemoved";
- dbg.nospace() << "QChildEvent(" << n << ", " << (static_cast<const QChildEvent*>(e))->child();
- return dbg.space();
-#ifndef QT_NO_GESTURES
- case QEvent::Gesture:
- n = "Gesture";
+# endif // !QT_NO_TABLETEVENT
+ case QEvent::Enter:
+ dbg << "QEnterEvent(" << static_cast<const QEnterEvent *>(e)->pos() << ')';
+ break;
+ case QEvent::Timer:
+ dbg << "QTimerEvent(id=" << static_cast<const QTimerEvent *>(e)->timerId() << ')';
break;
-#endif
default:
- dbg.nospace() << "QEvent(" << (const void *)e << ", type = " << e->type() << ')';
- return dbg.space();
+ dbg << eventClassName(type) << '(' << eventTypeName(type) << ", "
+ << (const void *)e << ", type = " << e->type() << ')';
+ break;
}
-
- dbg.nospace() << 'Q' << n << "Event(" << (const void *)e << ')';
- return dbg.space();
+ return dbg;
}
-#endif
+#endif // !QT_NO_DEBUG_STREAM
/*!
\class QShortcutEvent
@@ -3570,7 +3829,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e) {
\ingroup events
\inmodule QtGui
- Normally you don't need to use this class directly; QShortcut
+ Normally you do not need to use this class directly; QShortcut
provides a higher-level interface to handle shortcut keys.
\sa QShortcut
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 0a826284c9..d128c34134 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -223,6 +223,9 @@ protected:
#ifndef QT_NO_TABLETEVENT
class Q_GUI_EXPORT QTabletEvent : public QInputEvent
{
+ Q_GADGET
+ Q_ENUMS(TabletDevice)
+ Q_ENUMS(PointerType)
public:
enum TabletDevice { NoDevice, Puck, Stylus, Airbrush, FourDMouse,
XFreeEraser /*internal*/, RotationStylus };
@@ -230,7 +233,12 @@ public:
QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos,
int device, int pointerType, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
- Qt::KeyboardModifiers keyState, qint64 uniqueID);
+ Qt::KeyboardModifiers keyState, qint64 uniqueID); // ### remove in Qt 6
+ QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos,
+ int device, int pointerType, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z,
+ Qt::KeyboardModifiers keyState, qint64 uniqueID,
+ Qt::MouseButton button, Qt::MouseButtons buttons);
~QTabletEvent();
inline QPoint pos() const { return mPos.toPoint(); }
@@ -257,6 +265,8 @@ public:
inline qreal rotation() const { return mRot; }
inline int xTilt() const { return mXT; }
inline int yTilt() const { return mYT; }
+ Qt::MouseButton button() const;
+ Qt::MouseButtons buttons() const;
protected:
QPointF mPos, mGPos;
@@ -264,9 +274,8 @@ protected:
qreal mPress, mTangential, mRot;
qint64 mUnique;
- // I don't know what the future holds for tablets but there could be some
- // new devices coming along, and there seem to be "holes" in the
- // OS-specific events for this.
+ // QTabletEventPrivate for extra storage.
+ // ### Qt 6: QPointingEvent will have Buttons, QTabletEvent will inherit
void *mExtra;
};
#endif // QT_NO_TABLETEVENT
@@ -377,8 +386,6 @@ public:
inline const QRegion &region() const { return m_region; }
protected:
- friend class QApplication;
- friend class QCoreApplication;
QRect m_rect;
QRegion m_region;
bool m_erased;
@@ -395,7 +402,6 @@ public:
protected:
QPoint p, oldp;
friend class QApplication;
- friend class QCoreApplication;
};
class Q_GUI_EXPORT QExposeEvent : public QEvent
@@ -421,7 +427,6 @@ public:
protected:
QSize s, olds;
friend class QApplication;
- friend class QCoreApplication;
};
@@ -601,7 +606,6 @@ public:
inline void ignore(const QRect & r) { ignore(); rect = r; }
protected:
- friend class QApplication;
QRect rect;
};
@@ -760,7 +764,11 @@ public:
enum InfoFlag {
Pen = 0x0001
};
+#ifndef Q_MOC_RUN
+ // otherwise moc gives
+ // Error: Meta object features not supported for nested classes
Q_DECLARE_FLAGS(InfoFlags, InfoFlag)
+#endif
explicit TouchPoint(int id = -1);
TouchPoint(const TouchPoint &other);
@@ -881,6 +889,10 @@ protected:
Q_DECLARE_TYPEINFO(QTouchEvent::TouchPoint, Q_MOVABLE_TYPE);
Q_DECLARE_OPERATORS_FOR_FLAGS(QTouchEvent::TouchPoint::InfoFlags)
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QTouchEvent::TouchPoint &);
+#endif
+
class Q_GUI_EXPORT QScrollPrepareEvent : public QEvent
{
public:
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index e01216e9f1..d24f3768a8 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -92,6 +92,20 @@ public:
QVector<QPointF> rawScreenPositions;
};
+#ifndef QT_NO_TABLETEVENT
+class QTabletEventPrivate
+{
+public:
+ inline QTabletEventPrivate(Qt::MouseButton button, Qt::MouseButtons buttons)
+ : b(button),
+ buttonState(buttons)
+ { }
+
+ Qt::MouseButton b;
+ Qt::MouseButtons buttonState;
+};
+#endif // QT_NO_TABLETEVENT
+
QT_END_NAMESPACE
#endif // QEVENT_P_H
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 4727e754cd..51b1db8cf1 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -82,6 +82,7 @@
#include <qpa/qwindowsysteminterface_p.h>
#include "private/qwindow_p.h"
#include "private/qcursor_p.h"
+#include "private/qopenglcontext_p.h"
#include "private/qdnd_p.h"
#include <qpa/qplatformthemefactory_p.h>
@@ -118,7 +119,7 @@ Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier;
QPointF QGuiApplicationPrivate::lastCursorPosition(qInf(), qInf());
-bool QGuiApplicationPrivate::tabletState = false;
+Qt::MouseButtons QGuiApplicationPrivate::tabletState = Qt::NoButton;
QWindow *QGuiApplicationPrivate::tabletPressTarget = 0;
QWindow *QGuiApplicationPrivate::currentMouseWindow = 0;
@@ -509,6 +510,7 @@ static QWindowGeometrySpecification windowGeometrySpecification;
\li \c {-qwindowgeometry} \e geometry, specifies window geometry for
the main window using the X11-syntax. For example:
\c {-qwindowgeometry 100x100+50+50}
+ \li \c {-qwindowicon}, sets the default window icon
\li \c {-qwindowtitle}, sets the title of the first window
\li \c{-reverse}, sets the application's layout direction to
Qt::RightToLeft. This option is intended to aid debugging and should
@@ -606,7 +608,8 @@ QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags
: QCoreApplicationPrivate(argc, argv, flags),
styleHints(0),
inputMethod(0),
- lastTouchType(QEvent::TouchEnd)
+ lastTouchType(QEvent::TouchEnd),
+ ownGlobalShareContext(false)
{
self = this;
application_type = QCoreApplicationPrivate::Gui;
@@ -903,7 +906,19 @@ QList<QScreen *> QGuiApplication::screens()
This signal is emitted whenever a new screen \a screen has been added to the system.
- \sa screens(), primaryScreen()
+ \sa screens(), primaryScreen(), screenRemoved()
+*/
+
+/*!
+ \fn void QGuiApplication::screenRemoved(QScreen *screen)
+
+ This signal is emitted whenever a \a screen is removed from the system. It
+ provides an opportunity to manage the windows on the screen before Qt falls back
+ to moving them to the primary screen.
+
+ \sa screens(), screenAdded(), QObject::destroyed(), QWindow::setScreen()
+
+ \since 5.4
*/
@@ -1115,12 +1130,15 @@ void QGuiApplicationPrivate::createPlatformIntegration()
// Get command line params
+ QString icon;
+
int j = argc ? 1 : 0;
for (int i=1; i<argc; i++) {
if (argv[i] && *argv[i] != '-') {
argv[j++] = argv[i];
continue;
}
+ const bool isXcb = platformName == "xcb";
QByteArray arg = argv[i];
if (arg.startsWith("--"))
arg.remove(0, 1);
@@ -1133,12 +1151,16 @@ void QGuiApplicationPrivate::createPlatformIntegration()
} else if (arg == "-platformtheme") {
if (++i < argc)
platformThemeName = QString::fromLocal8Bit(argv[i]);
- } else if (arg == "-qwindowgeometry" || (platformName == "xcb" && arg == "-geometry")) {
+ } else if (arg == "-qwindowgeometry" || (isXcb && arg == "-geometry")) {
if (++i < argc)
windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]);
- } else if (arg == "-qwindowtitle" || (platformName == "xcb" && arg == "-title")) {
+ } else if (arg == "-qwindowtitle" || (isXcb && arg == "-title")) {
if (++i < argc)
firstWindowTitle = QString::fromLocal8Bit(argv[i]);
+ } else if (arg == "-qwindowicon" || (isXcb && arg == "-icon")) {
+ if (++i < argc) {
+ icon = QString::fromLocal8Bit(argv[i]);
+ }
} else {
argv[j++] = argv[i];
}
@@ -1151,6 +1173,8 @@ void QGuiApplicationPrivate::createPlatformIntegration()
init_platform(QLatin1String(platformName), platformPluginPath, platformThemeName, argc, argv);
+ if (!icon.isEmpty())
+ forcedWindowIcon = QDir::isAbsolutePath(icon) ? QIcon(icon) : QIcon::fromTheme(icon);
}
/*!
@@ -1296,6 +1320,17 @@ void QGuiApplicationPrivate::init()
qRegisterGuiGetInterpolator();
#endif
+ // set a global share context when enabled unless there is already one
+#ifndef QT_NO_OPENGL
+ if (qApp->testAttribute(Qt::AA_ShareOpenGLContexts) && !qt_gl_global_share_context()) {
+ QOpenGLContext *ctx = new QOpenGLContext;
+ ctx->setFormat(QSurfaceFormat::defaultFormat());
+ ctx->create();
+ qt_gl_set_global_share_context(ctx);
+ ownGlobalShareContext = true;
+ }
+#endif
+
QWindowSystemInterfacePrivate::eventTime.start();
is_app_running = true;
@@ -1357,6 +1392,13 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
QPixmapCache::clear();
+#ifndef QT_NO_OPENGL
+ if (ownGlobalShareContext) {
+ delete qt_gl_global_share_context();
+ qt_gl_set_global_share_context(0);
+ }
+#endif
+
delete platform_theme;
platform_theme = 0;
delete platform_integration;
@@ -1454,6 +1496,20 @@ QPlatformNativeInterface *QGuiApplication::platformNativeInterface()
}
/*!
+ Returns a function pointer from the platformplugin matching \a function
+*/
+QFunctionPointer QGuiApplication::platformFunction(const QByteArray &function)
+{
+ QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
+ if (!pi) {
+ qWarning() << "QGuiApplication::platformFunction(): Must construct a QGuiApplication before accessing a platform function";
+ return Q_NULLPTR;
+ }
+
+ return pi->nativeInterface() ? pi->nativeInterface()->platformFunction(function) : Q_NULLPTR;
+}
+
+/*!
Enters the main event loop and waits until exit() is called, and then
returns the value that was set to exit() (which is 0 if exit() is called
via quit()).
@@ -1576,8 +1632,9 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
case QWindowSystemInterfacePrivate::WindowScreenChanged:
QGuiApplicationPrivate::processWindowScreenChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowScreenChangedEvent *>(e));
break;
- case QWindowSystemInterfacePrivate::ApplicationStateChanged:
- QGuiApplicationPrivate::setApplicationState(static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e)->newState);
+ case QWindowSystemInterfacePrivate::ApplicationStateChanged: {
+ QWindowSystemInterfacePrivate::ApplicationStateChangedEvent * changeEvent = static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e);
+ QGuiApplicationPrivate::setApplicationState(changeEvent->newState, changeEvent->forcePropagate); }
break;
case QWindowSystemInterfacePrivate::FlushEvents:
QWindowSystemInterface::deferredFlushWindowSystemEvents();
@@ -1594,10 +1651,6 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
QGuiApplicationPrivate::reportGeometryChange(
static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e));
break;
- case QWindowSystemInterfacePrivate::ScreenAvailableGeometry:
- QGuiApplicationPrivate::reportAvailableGeometryChange(
- static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
- break;
case QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInch:
QGuiApplicationPrivate::reportLogicalDotsPerInchChange(
static_cast<QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *>(e));
@@ -1664,7 +1717,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
// with the current event, we fake a move-only event that we recurse and process first. This
// 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->timestamp, e->type, e->localPos, e->globalPos, buttons, e->modifiers, e->source);
+ moveEvent.synthetic = e->synthetic;
processMouseEvent(&moveEvent);
Q_ASSERT(e->globalPos == QGuiApplicationPrivate::lastCursorPosition);
// continue with processing mouse button change event
@@ -1854,13 +1908,17 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
ev.setAccepted(false);
static bool backKeyPressAccepted = false;
+ static bool menuKeyPressAccepted = false;
if (e->keyType == QEvent::KeyPress) {
backKeyPressAccepted = e->key == Qt::Key_Back && ev.isAccepted();
- } else if (e->keyType == QEvent::KeyRelease && e->key == Qt::Key_Back && !backKeyPressAccepted && !ev.isAccepted()) {
- if (!window)
- qApp->quit();
- else
- QWindowSystemInterface::handleCloseEvent(window);
+ menuKeyPressAccepted = e->key == Qt::Key_Menu && ev.isAccepted();
+ } else if (e->keyType == QEvent::KeyRelease) {
+ if (e->key == Qt::Key_Back && !backKeyPressAccepted && !ev.isAccepted()) {
+ if (window)
+ QWindowSystemInterface::handleCloseEvent(window);
+ } else if (e->key == Qt::Key_Menu && !menuKeyPressAccepted && !ev.isAccepted()) {
+ platform_theme->showPlatformMenuBar();
+ }
}
#endif
}
@@ -1972,7 +2030,7 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
{
if (QWindow *window = wse->window.data()) {
if (QScreen *screen = wse->screen.data())
- window->d_func()->setScreen(screen, false /* recreate */);
+ window->d_func()->setTopLevelScreen(screen, false /* recreate */);
else // Fall back to default behavior, and try to find some appropriate screen
window->setScreen(0);
}
@@ -2058,10 +2116,8 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
{
#ifndef QT_NO_TABLETEVENT
QEvent::Type type = QEvent::TabletMove;
- if (e->down != tabletState) {
- type = e->down ? QEvent::TabletPress : QEvent::TabletRelease;
- tabletState = e->down;
- }
+ if (e->buttons != tabletState)
+ type = (e->buttons > tabletState) ? QEvent::TabletPress : QEvent::TabletRelease;
QWindow *window = e->window.data();
modifier_buttons = e->modifiers;
@@ -2093,12 +2149,21 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
QPointF delta = e->global - e->global.toPoint();
local = window->mapFromGlobal(e->global.toPoint()) + delta;
}
+ Qt::MouseButtons stateChange = e->buttons ^ tabletState;
+ Qt::MouseButton button = Qt::NoButton;
+ for (int check = Qt::LeftButton; check <= int(Qt::MaxMouseButton); check = check << 1) {
+ if (check & stateChange) {
+ button = Qt::MouseButton(check);
+ break;
+ }
+ }
QTabletEvent ev(type, local, e->global,
e->device, e->pointerType, e->pressure, e->xTilt, e->yTilt,
e->tangentialPressure, e->rotation, e->z,
- e->modifiers, e->uid);
+ e->modifiers, e->uid, button, e->buttons);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &ev);
+ tabletState = e->buttons;
#else
Q_UNUSED(e)
#endif
@@ -2110,7 +2175,7 @@ void QGuiApplicationPrivate::processTabletEnterProximityEvent(QWindowSystemInter
QTabletEvent ev(QEvent::TabletEnterProximity, QPointF(), QPointF(),
e->device, e->pointerType, 0, 0, 0,
0, 0, 0,
- Qt::NoModifier, e->uid);
+ Qt::NoModifier, e->uid, Qt::NoButton, tabletState);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
#else
@@ -2124,7 +2189,7 @@ void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInter
QTabletEvent ev(QEvent::TabletLeaveProximity, QPointF(), QPointF(),
e->device, e->pointerType, 0, 0, 0,
0, 0, 0,
- Qt::NoModifier, e->uid);
+ Qt::NoModifier, e->uid, Qt::NoButton, tabletState);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
#else
@@ -2213,7 +2278,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
e->timestamp,
synthIt->pos,
synthIt->screenPos,
- Qt::NoButton,
+ buttons & ~Qt::LeftButton,
e->modifiers,
Qt::MouseEventSynthesizedByQt);
fake.synthetic = true;
@@ -2415,7 +2480,9 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
QWindowSystemInterfacePrivate::MouseEvent fake(w, e->timestamp,
touchPoint.pos(),
touchPoint.screenPos(),
- b, e->modifiers);
+ b | (buttons & ~Qt::LeftButton),
+ e->modifiers,
+ Qt::MouseEventSynthesizedByQt);
fake.synthetic = true;
processMouseEvent(&fake);
break;
@@ -2483,40 +2550,36 @@ void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate:
return;
QScreen *s = e->screen.data();
- s->d_func()->geometry = e->geometry;
- Qt::ScreenOrientation primaryOrientation = s->primaryOrientation();
- s->d_func()->updatePrimaryOrientation();
+ bool geometryChanged = e->geometry != s->d_func()->geometry;
+ s->d_func()->geometry = e->geometry;
- emit s->geometryChanged(s->geometry());
- emit s->physicalSizeChanged(s->physicalSize());
- emit s->physicalDotsPerInchChanged(s->physicalDotsPerInch());
- emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch());
- foreach (QScreen* sibling, s->virtualSiblings())
- emit sibling->virtualGeometryChanged(sibling->virtualGeometry());
+ bool availableGeometryChanged = e->availableGeometry != s->d_func()->availableGeometry;
+ s->d_func()->availableGeometry = e->availableGeometry;
- if (s->primaryOrientation() != primaryOrientation)
- emit s->primaryOrientationChanged(s->primaryOrientation());
+ if (geometryChanged) {
+ Qt::ScreenOrientation primaryOrientation = s->primaryOrientation();
+ s->d_func()->updatePrimaryOrientation();
- if (s->d_func()->orientation == Qt::PrimaryOrientation)
- updateFilteredScreenOrientation(s);
-}
+ emit s->geometryChanged(s->geometry());
+ emit s->physicalSizeChanged(s->physicalSize());
+ emit s->physicalDotsPerInchChanged(s->physicalDotsPerInch());
+ emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch());
-void QGuiApplicationPrivate::reportAvailableGeometryChange(
- QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e)
-{
- // This operation only makes sense after the QGuiApplication constructor runs
- if (QCoreApplication::startingUp())
- return;
+ if (s->primaryOrientation() != primaryOrientation)
+ emit s->primaryOrientationChanged(s->primaryOrientation());
- if (!e->screen)
- return;
+ if (s->d_func()->orientation == Qt::PrimaryOrientation)
+ updateFilteredScreenOrientation(s);
+ }
- QScreen *s = e->screen.data();
- s->d_func()->availableGeometry = e->availableGeometry;
+ if (availableGeometryChanged)
+ emit s->availableGeometryChanged(s->geometry());
- foreach (QScreen* sibling, s->virtualSiblings())
- emit sibling->virtualGeometryChanged(sibling->virtualGeometry());
+ if (geometryChanged || availableGeometryChanged) {
+ foreach (QScreen* sibling, s->virtualSiblings())
+ emit sibling->virtualGeometryChanged(sibling->virtualGeometry());
+ }
}
void QGuiApplicationPrivate::reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e)
@@ -2656,6 +2719,15 @@ QClipboard * QGuiApplication::clipboard()
#endif
/*!
+ \since 5.4
+ \fn void QGuiApplication::paletteChanged(const QPalette &palette)
+
+ This signal is emitted when the \a palette of the application changes.
+
+ \sa palette()
+*/
+
+/*!
Returns the default application palette.
\sa setPalette()
@@ -2681,6 +2753,7 @@ void QGuiApplication::setPalette(const QPalette &pal)
else
*QGuiApplicationPrivate::app_pal = pal;
applicationResourceFlags |= ApplicationPaletteExplicitlySet;
+ emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal);
}
QRect QGuiApplicationPrivate::applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window)
@@ -2890,9 +2963,9 @@ Qt::ApplicationState QGuiApplication::applicationState()
\sa applicationState()
*/
-void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state)
+void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state, bool forcePropagate)
{
- if (applicationState == state)
+ if ((applicationState == state) && !forcePropagate)
return;
applicationState = state;
@@ -3093,6 +3166,8 @@ void QGuiApplicationPrivate::saveState()
On system start-up, the default layout direction depends on the
application's language.
+ The notifier signal was introduced in Qt 5.4.
+
\sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
*/
@@ -3103,7 +3178,10 @@ void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction)
layout_direction = direction;
- QGuiApplicationPrivate::self->notifyLayoutDirectionChange();
+ if (qGuiApp) {
+ emit qGuiApp->layoutDirectionChanged(direction);
+ QGuiApplicationPrivate::self->notifyLayoutDirectionChange();
+ }
}
Qt::LayoutDirection QGuiApplication::layoutDirection()
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index 6d9a4b2376..6e751e1275 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -75,7 +75,7 @@ class Q_GUI_EXPORT QGuiApplication : public QCoreApplication
Q_OBJECT
Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon)
Q_PROPERTY(QString applicationDisplayName READ applicationDisplayName WRITE setApplicationDisplayName)
- Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection)
+ Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(QString platformName READ platformName STORED false)
Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE setQuitOnLastWindowClosed)
@@ -143,6 +143,8 @@ public:
static QPlatformNativeInterface *platformNativeInterface();
+ static QFunctionPointer platformFunction(const QByteArray &function);
+
static void setQuitOnLastWindowClosed(bool quit);
static bool quitOnLastWindowClosed();
@@ -163,14 +165,17 @@ public:
Q_SIGNALS:
void fontDatabaseChanged();
void screenAdded(QScreen *screen);
+ void screenRemoved(QScreen *screen);
void lastWindowClosed();
void focusObjectChanged(QObject *focusObject);
void focusWindowChanged(QWindow *focusWindow);
void applicationStateChanged(Qt::ApplicationState state);
+ void layoutDirectionChanged(Qt::LayoutDirection direction);
#ifndef QT_NO_SESSIONMANAGER
void commitDataRequest(QSessionManager &sessionManager);
void saveStateRequest(QSessionManager &sessionManager);
#endif
+ void paletteChanged(const QPalette &pal);
protected:
bool event(QEvent *);
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 1ec808ec27..d82abfe20a 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -137,7 +137,6 @@ public:
static void reportScreenOrientationChange(QScreen *screen);
static void reportScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e);
static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
- static void reportAvailableGeometryChange(QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e);
static void reportLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e);
static void reportRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e);
static void processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce);
@@ -207,7 +206,7 @@ public:
static int mousePressY;
static int mouse_double_click_distance;
static QPointF lastCursorPosition;
- static bool tabletState;
+ static Qt::MouseButtons tabletState;
static QWindow *tabletPressTarget;
static QWindow *currentMouseWindow;
static Qt::ApplicationState applicationState;
@@ -234,6 +233,7 @@ public:
QInputMethod *inputMethod;
QString firstWindowTitle;
+ QIcon forcedWindowIcon;
static QList<QObject *> generic_plugin_list;
#ifndef QT_NO_SHORTCUT
@@ -288,7 +288,7 @@ public:
static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window);
- static void setApplicationState(Qt::ApplicationState state);
+ static void setApplicationState(Qt::ApplicationState state, bool forcePropagate = false);
protected:
virtual void notifyThemeChanged();
@@ -306,6 +306,8 @@ private:
static QTouchDevice *m_fakeTouchDevice;
static int m_fakeMouseSourcePointId;
QAtomicPointer<QDrawHelperGammaTables> m_gammaTables;
+
+ bool ownGlobalShareContext;
};
Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k);
diff --git a/src/gui/kernel/qkeymapper.cpp b/src/gui/kernel/qkeymapper.cpp
index 0e150a9c1e..2ec72fd2d0 100644
--- a/src/gui/kernel/qkeymapper.cpp
+++ b/src/gui/kernel/qkeymapper.cpp
@@ -45,6 +45,9 @@
#include <private/qobject_p.h>
#include "qkeymapper_p.h"
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -117,4 +120,32 @@ QKeyMapperPrivate *qt_keymapper_private()
return QKeyMapper::instance()->d_func();
}
+QKeyMapperPrivate::QKeyMapperPrivate()
+{
+ keyboardInputLocale = QLocale::system();
+ keyboardInputDirection = keyboardInputLocale.textDirection();
+}
+
+QKeyMapperPrivate::~QKeyMapperPrivate()
+{
+ // clearMappings();
+}
+
+void QKeyMapperPrivate::clearMappings()
+{
+}
+
+QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e)
+{
+ QList<int> result = QGuiApplicationPrivate::platformIntegration()->possibleKeys(e);
+ if (!result.isEmpty())
+ return result;
+
+ if (e->key() && (e->key() != Qt::Key_unknown))
+ result << int(e->key() + e->modifiers());
+ else if (!e->text().isEmpty())
+ result << int(e->text().at(0).unicode() + e->modifiers());
+ return result;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 59cdabbc0f..8261ac7208 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -490,7 +490,7 @@ static const struct {
{ Qt::Key_BrightnessAdjust, QT_TRANSLATE_NOOP("QShortcut", "Adjust Brightness") },
{ Qt::Key_Finance, QT_TRANSLATE_NOOP("QShortcut", "Finance") },
{ Qt::Key_Community, QT_TRANSLATE_NOOP("QShortcut", "Community") },
- { Qt::Key_AudioRewind, QT_TRANSLATE_NOOP("QShortcut", "Audio Rewind") },
+ { Qt::Key_AudioRewind, QT_TRANSLATE_NOOP("QShortcut", "Media Rewind") },
{ Qt::Key_BackForward, QT_TRANSLATE_NOOP("QShortcut", "Back Forward") },
{ Qt::Key_ApplicationLeft, QT_TRANSLATE_NOOP("QShortcut", "Application Left") },
{ Qt::Key_ApplicationRight, QT_TRANSLATE_NOOP("QShortcut", "Application Right") },
@@ -550,17 +550,40 @@ static const struct {
{ Qt::Key_Bluetooth, QT_TRANSLATE_NOOP("QShortcut", "Bluetooth") },
{ Qt::Key_WLAN, QT_TRANSLATE_NOOP("QShortcut", "Wireless") },
{ Qt::Key_UWB, QT_TRANSLATE_NOOP("QShortcut", "Ultra Wide Band") },
- { Qt::Key_AudioForward, QT_TRANSLATE_NOOP("QShortcut", "Audio Forward") },
+ { Qt::Key_AudioForward, QT_TRANSLATE_NOOP("QShortcut", "Media Fast Forward") },
{ Qt::Key_AudioRepeat, QT_TRANSLATE_NOOP("QShortcut", "Audio Repeat") },
{ Qt::Key_AudioRandomPlay, QT_TRANSLATE_NOOP("QShortcut", "Audio Random Play") },
{ Qt::Key_Subtitle, QT_TRANSLATE_NOOP("QShortcut", "Subtitle") },
{ Qt::Key_AudioCycleTrack, QT_TRANSLATE_NOOP("QShortcut", "Audio Cycle Track") },
{ Qt::Key_Time, QT_TRANSLATE_NOOP("QShortcut", "Time") },
- { Qt::Key_Select, QT_TRANSLATE_NOOP("QShortcut", "Select") },
+ { Qt::Key_Hibernate, QT_TRANSLATE_NOOP("QShortcut", "Hibernate") },
{ Qt::Key_View, QT_TRANSLATE_NOOP("QShortcut", "View") },
{ Qt::Key_TopMenu, QT_TRANSLATE_NOOP("QShortcut", "Top Menu") },
+ { Qt::Key_PowerDown, QT_TRANSLATE_NOOP("QShortcut", "Power Down") },
{ Qt::Key_Suspend, QT_TRANSLATE_NOOP("QShortcut", "Suspend") },
- { Qt::Key_Hibernate, QT_TRANSLATE_NOOP("QShortcut", "Hibernate") },
+
+ { Qt::Key_MicMute, QT_TRANSLATE_NOOP("QShortcut", "Microphone Mute") },
+
+ { Qt::Key_Red, QT_TRANSLATE_NOOP("QShortcut", "Red") },
+ { Qt::Key_Green, QT_TRANSLATE_NOOP("QShortcut", "Green") },
+ { Qt::Key_Yellow, QT_TRANSLATE_NOOP("QShortcut", "Yellow") },
+ { Qt::Key_Blue, QT_TRANSLATE_NOOP("QShortcut", "Blue") },
+
+ { Qt::Key_ChannelUp, QT_TRANSLATE_NOOP("QShortcut", "Channel Up") },
+ { Qt::Key_ChannelDown, QT_TRANSLATE_NOOP("QShortcut", "Channel Down") },
+
+ { Qt::Key_Guide, QT_TRANSLATE_NOOP("QShortcut", "Guide") },
+ { Qt::Key_Info, QT_TRANSLATE_NOOP("QShortcut", "Info") },
+ { Qt::Key_Settings, QT_TRANSLATE_NOOP("QShortcut", "Settings") },
+
+ { Qt::Key_MicVolumeUp, QT_TRANSLATE_NOOP("QShortcut", "Microphone Volume Up") },
+ { Qt::Key_MicVolumeDown, QT_TRANSLATE_NOOP("QShortcut", "Microphone Volume Down") },
+
+ { Qt::Key_New, QT_TRANSLATE_NOOP("QShortcut", "New") },
+ { Qt::Key_Open, QT_TRANSLATE_NOOP("QShortcut", "Open") },
+ { Qt::Key_Find, QT_TRANSLATE_NOOP("QShortcut", "Find") },
+ { Qt::Key_Undo, QT_TRANSLATE_NOOP("QShortcut", "Undo") },
+ { Qt::Key_Redo, QT_TRANSLATE_NOOP("QShortcut", "Redo") },
// --------------------------------------------------------------
// More consistent namings
@@ -647,6 +670,7 @@ static const struct {
{ Qt::Key_Execute, QT_TRANSLATE_NOOP("QShortcut", "Execute") },
{ Qt::Key_Play, QT_TRANSLATE_NOOP("QShortcut", "Play") },
{ Qt::Key_Zoom, QT_TRANSLATE_NOOP("QShortcut", "Zoom") },
+ { Qt::Key_Exit, QT_TRANSLATE_NOOP("QShortcut", "Exit") },
{ 0, 0 }
};
diff --git a/src/gui/kernel/qoffscreensurface.cpp b/src/gui/kernel/qoffscreensurface.cpp
index 003e3a0cc9..0307a4a2ad 100644
--- a/src/gui/kernel/qoffscreensurface.cpp
+++ b/src/gui/kernel/qoffscreensurface.cpp
@@ -90,6 +90,7 @@ public:
, surfaceType(QSurface::OpenGLSurface)
, platformOffscreenSurface(0)
, offscreenWindow(0)
+ , requestedFormat(QSurfaceFormat::defaultFormat())
, screen(0)
, size(1, 1)
{
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 406c784c5c..be8fa2415d 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -63,6 +63,7 @@
#ifndef QT_OPENGL_ES_2
#include <QOpenGLFunctions_1_0>
+#include <QOpenGLFunctions_3_2_Core>
#endif
QT_BEGIN_NAMESPACE
@@ -242,6 +243,28 @@ QMutex QOpenGLContextPrivate::makeCurrentTrackerMutex;
#endif
/*!
+ \internal
+
+ This function is used by Qt::AA_ShareOpenGLContexts and the Qt
+ WebEngine to set up context sharing across multiple windows. Do
+ not use it for any other purpose.
+
+ Please maintain the binary compatibility of these functions.
+*/
+void qt_gl_set_global_share_context(QOpenGLContext *context)
+{
+ global_share_context = context;
+}
+
+/*!
+ \internal
+*/
+QOpenGLContext *qt_gl_global_share_context()
+{
+ return global_share_context;
+}
+
+/*!
\class QOpenGLContext
\inmodule QtGui
\since 5.0
@@ -335,23 +358,14 @@ QOpenGLContext *QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context
return previous;
}
-/*!
- \internal
-
- This function is used by the Qt WebEngine to set up context sharing
- across multiple windows. Do not use it for any other purpose.
-*/
void QOpenGLContextPrivate::setGlobalShareContext(QOpenGLContext *context)
{
- global_share_context = context;
+ qt_gl_set_global_share_context(context);
}
-/*!
- \internal
-*/
QOpenGLContext *QOpenGLContextPrivate::globalShareContext()
{
- return global_share_context;
+ return qt_gl_global_share_context();
}
int QOpenGLContextPrivate::maxTextureSize()
@@ -370,9 +384,25 @@ int QOpenGLContextPrivate::maxTextureSize()
GLint size;
GLint next = 64;
funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- QOpenGLFunctions_1_0 *gl1funcs = q->versionFunctions<QOpenGLFunctions_1_0>();
- gl1funcs->initializeOpenGLFunctions();
- gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
+
+ QOpenGLFunctions_1_0 *gl1funcs = 0;
+ QOpenGLFunctions_3_2_Core *gl3funcs = 0;
+
+ if (q->format().profile() == QSurfaceFormat::CoreProfile) {
+ gl3funcs = q->versionFunctions<QOpenGLFunctions_3_2_Core>();
+ gl3funcs->initializeOpenGLFunctions();
+ } else {
+ gl1funcs = q->versionFunctions<QOpenGLFunctions_1_0>();
+ gl1funcs->initializeOpenGLFunctions();
+ }
+
+ Q_ASSERT(gl1funcs || gl3funcs);
+
+ if (gl1funcs)
+ gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
+ else
+ gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
+
if (size == 0) {
return max_texture_size;
}
@@ -383,7 +413,11 @@ int QOpenGLContextPrivate::maxTextureSize()
if (next > max_texture_size)
break;
funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
+ if (gl1funcs)
+ gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
+ else
+ gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
+
} while (next > size);
max_texture_size = size;
@@ -456,6 +490,12 @@ QOpenGLContext::QOpenGLContext(QObject *parent)
/*!
Sets the \a format the OpenGL context should be compatible with. You need
to call create() before it takes effect.
+
+ When the format is not explicitly set via this function, the format returned
+ by QSurfaceFormat::defaultFormat() will be used. This means that when having
+ multiple contexts, individual calls to this function can be replaced by one
+ single call to QSurfaceFormat::setDefaultFormat() before creating the first
+ context.
*/
void QOpenGLContext::setFormat(const QSurfaceFormat &format)
{
@@ -486,6 +526,64 @@ void QOpenGLContext::setScreen(QScreen *screen)
}
/*!
+ Set the native handles for this context. When create() is called and a
+ native handle is set, configuration settings, like format(), are ignored
+ since this QOpenGLContext will wrap an already created native context
+ instead of creating a new one from scratch.
+
+ On some platforms the native context handle is not sufficient and other
+ related handles (for example, for a window or display) have to be provided
+ in addition. Therefore \a handle is variant containing a platform-specific
+ value type. These classes can be found in the QtPlatformHeaders module.
+
+ When create() is called with native handles set, the handles' ownership are
+ not taken, meaning that destroy() will not destroy the native context.
+
+ \note Some frameworks track the current context and surfaces internally.
+ Making the adopted QOpenGLContext current via Qt will have no effect on such
+ other frameworks' internal state. Therefore a subsequent makeCurrent done
+ via the other framework may have no effect. It is therefore advisable to
+ make explicit calls to make no context and surface current to reset the
+ other frameworks' internal state after performing OpenGL operations via Qt.
+
+ \note Using foreign contexts with Qt windows and Qt contexts with windows
+ and surfaces created by other frameworks may give unexpected results,
+ depending on the platform, due to potential mismatches in context and window
+ pixel formats. To make sure this does not happen, avoid making contexts and
+ surfaces from different frameworks current together. Instead, prefer
+ approaches based on context sharing where OpenGL resources like textures are
+ accessible both from Qt's and the foreign framework's contexts.
+
+ \since 5.4
+ \sa nativeHandle()
+*/
+void QOpenGLContext::setNativeHandle(const QVariant &handle)
+{
+ Q_D(QOpenGLContext);
+ d->nativeHandle = handle;
+}
+
+/*!
+ Returns the native handle for the context.
+
+ This function provides access to the QOpenGLContext's underlying native
+ context. The returned variant contains a platform-specific value type. These
+ classes can be found in the module QtPlatformHeaders.
+
+ On platforms where retrieving the native handle is not supported, or if
+ neither create() nor setNativeHandle() was called, a null variant is
+ returned.
+
+ \since 5.4
+ \sa setNativeHandle()
+ */
+QVariant QOpenGLContext::nativeHandle() const
+{
+ Q_D(const QOpenGLContext);
+ return d->nativeHandle;
+}
+
+/*!
Attempts to create the OpenGL context with the current configuration.
The current configuration includes the format, the share context, and the
@@ -502,11 +600,15 @@ void QOpenGLContext::setScreen(QScreen *screen)
Returns \c true if the native context was successfully created and is ready to
be used with makeCurrent(), swapBuffers(), etc.
+ \note If the context is already created, this function will first call
+ destroy(), and then create a new OpenGL context.
+
\sa makeCurrent(), destroy(), format()
*/
bool QOpenGLContext::create()
{
- destroy();
+ if (isValid())
+ destroy();
Q_D(QOpenGLContext);
d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this);
@@ -557,6 +659,7 @@ void QOpenGLContext::destroy()
d->versionFunctionsBackend.clear();
delete d->textureFunctions;
d->textureFunctions = 0;
+ d->nativeHandle = QVariant();
}
/*!
diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h
index 19aecee75a..99f2fece51 100644
--- a/src/gui/kernel/qopenglcontext.h
+++ b/src/gui/kernel/qopenglcontext.h
@@ -64,6 +64,7 @@
#include <QtCore/qhash.h>
#include <QtCore/qpair.h>
+#include <QtCore/qvariant.h>
QT_BEGIN_NAMESPACE
@@ -153,6 +154,7 @@ public:
void setFormat(const QSurfaceFormat &format);
void setShareContext(QOpenGLContext *shareContext);
void setScreen(QScreen *screen);
+ void setNativeHandle(const QVariant &handle);
bool create();
bool isValid() const;
@@ -161,6 +163,7 @@ public:
QOpenGLContext *shareContext() const;
QOpenGLContextGroup *shareGroup() const;
QScreen *screen() const;
+ QVariant nativeHandle() const;
GLuint defaultFramebufferObject() const;
@@ -242,4 +245,4 @@ QT_END_NAMESPACE
#endif // QT_NO_OPENGL
-#endif // QGUIGLCONTEXT_H
+#endif // QOPENGLCONTEXT_H
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index e9907480f2..2d27b19ebe 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -206,13 +206,13 @@ public:
, surface(0)
, functions(0)
, textureFunctions(0)
- , current_fbo(0)
, max_texture_size(-1)
, workaround_brokenFBOReadBack(false)
, workaround_brokenTexSubImage(false)
, workaround_missingPrecisionQualifiers(false)
, active_engine(0)
{
+ requestedFormat = QSurfaceFormat::defaultFormat();
}
virtual ~QOpenGLContextPrivate()
@@ -237,7 +237,6 @@ public:
mutable QSet<QByteArray> extensionNames;
QOpenGLTextureHelper* textureFunctions;
- GLuint current_fbo;
GLint max_texture_size;
bool workaround_brokenFBOReadBack;
@@ -246,6 +245,8 @@ public:
QPaintEngineEx *active_engine;
+ QVariant nativeHandle;
+
static QOpenGLContext *setCurrentContext(QOpenGLContext *context);
static void setGlobalShareContext(QOpenGLContext *context);
@@ -276,6 +277,9 @@ public:
#endif
};
+Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context);
+Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
+
QT_END_NAMESPACE
#endif // QT_NO_OPENGL
diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp
new file mode 100644
index 0000000000..a0261c2f04
--- /dev/null
+++ b/src/gui/kernel/qopenglwindow.cpp
@@ -0,0 +1,622 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenglwindow.h"
+#include "qpaintdevicewindow_p.h"
+#include <QtGui/QOpenGLFramebufferObject>
+#include <QtGui/QOpenGLPaintDevice>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtGui/private/qopenglextensions_p.h>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/QOffscreenSurface>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOpenGLWindow
+ \inmodule QtGui
+ \since 5.4
+ \brief The QOpenGLWindow class is a convenience subclass of QWindow to perform OpenGL painting.
+
+ QOpenGLWindow is an enhanced QWindow that allows easily creating windows that
+ perform OpenGL rendering using an API that is compatible with QOpenGLWidget
+ and is similar to the legacy QGLWidget. Unlike QOpenGLWidget, QOpenGLWindow
+ has no dependency on the widgets module and offers better performance.
+
+ A typical application will subclass QOpenGLWindow and reimplement the following
+ virtual functions:
+
+ \list
+
+ \li initializeGL() to perform OpenGL resource initialization
+
+ \li resizeGL() to set up the transformation matrices and other window size dependent resources
+
+ \li paintGL() to issue OpenGL commands or draw using QPainter
+
+ \endlist
+
+ To schedule a repaint, call the update() function. Note that this will not
+ immediately result in a call to paintGL(). Calling update() multiple times in
+ a row will not change the behavior in any way.
+
+ This is a slot so it can be connected to a \l QTimer::timeout() signal to
+ perform animation. Note however that in the modern OpenGL world it is a much
+ better choice to rely on synchronization to the vertical refresh rate of the
+ display. See \l{QSurfaceFormat::setSwapInterval()}{setSwapInterval()} on a
+ description of the swap interval. With a swap interval of \c 1, which is the
+ case on most systems by default, the
+ \l{QOpenGLContext::swapBuffers()}{swapBuffers()} call, that is executed
+ internally by QOpenGLWindow after each repaint, will block and wait for
+ vsync. This means that whenever the swap is done, an update can be scheduled
+ again by calling update(), without relying on timers.
+
+ To request a specific configuration for the context, use setFormat()
+ like for any other QWindow. This allows, among others, requesting a
+ given OpenGL version and profile, or enabling depth and stencil
+ buffers.
+
+ Unlike QWindow, QOpenGLWindow allows opening a painter on itself and perform
+ QPainter-based drawing.
+
+ QOpenGLWindow supports multiple update behaviors. The default,
+ \c NoPartialUpdate is equivalent to a regular, OpenGL-based QWindow or the
+ legacy QGLWidget. In contrast, \c PartialUpdateBlit and \c PartialUpdateBlend are
+ more in line with QOpenGLWidget's way of working, where there is always an
+ extra, dedicated framebuffer object present. These modes allow, by
+ sacrificing some performance, redrawing only a smaller area on each paint and
+ having the rest of the content preserved from of the previous frame. This is
+ useful for applications than render incrementally using QPainter, because
+ this way they do not have to redraw the entire window content on each
+ paintGL() call.
+
+ For more information on graphics in Qt, see \l {Graphics}.
+ */
+
+/*!
+ \enum QOpenGLWindow::UpdateBehavior
+
+ This enum describes the update strategy of the QOpenGLWindow.
+
+ \value NoPartialUpdate Indicates that the entire window surface will
+ redrawn on each update and so no additional framebuffers are needed.
+ This is the setting used in most cases and is equivalent to how drawing
+ directly via QWindow would function.
+
+ \value PartialUpdateBlit Indicates that the drawing performed in paintGL()
+ does not cover the entire window. In this case an extra framebuffer object
+ is created under the hood, and rendering performed in paintGL() will target
+ this framebuffer. This framebuffer is then blitted onto the window surface's
+ default framebuffer after each paint. This allows having QPainter-based drawing
+ code in paintGL() which only repaints a smaller area at a time, because, unlike
+ NoPartialUpdate, the previous content is preserved.
+
+ \value PartialUpdateBlend Similar to PartialUpdateBlit, but instead of using
+ framebuffer blits, the contents of the extra framebuffer is rendered by
+ drawing a textured quad with blending enabled. This, unlike PartialUpdateBlit,
+ allows alpha blended content and works even when the glBlitFramebuffer is
+ not available. Performance-wise this setting is likely to be somewhat slower
+ than PartialUpdateBlit.
+ */
+
+/*!
+ \fn void QOpenGLWindow::frameSwapped()
+
+ This signal is emitted after the potentially blocking
+ \l{QOpenGLContext::swapBuffers()}{buffer swap} has been done. Applications
+ that wish to continuously repaint synchronized to the vertical refresh,
+ should issue an update() upon this signal. This allows for a much smoother
+ experience compared to the traditional usage of timers.
+*/
+
+// GLES2 builds won't have these constants with the suffixless names
+#ifndef GL_READ_FRAMEBUFFER
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#endif
+#ifndef GL_DRAW_FRAMEBUFFER
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#endif
+
+class QOpenGLWindowPaintDevice : public QOpenGLPaintDevice
+{
+public:
+ QOpenGLWindowPaintDevice(QOpenGLWindow *window) : m_window(window) { }
+ void ensureActiveTarget() Q_DECL_OVERRIDE;
+
+ QOpenGLWindow *m_window;
+};
+
+class QOpenGLWindowPrivate : public QPaintDeviceWindowPrivate
+{
+ Q_DECLARE_PUBLIC(QOpenGLWindow)
+public:
+ QOpenGLWindowPrivate(QOpenGLWindow::UpdateBehavior updateBehavior)
+ : updateBehavior(updateBehavior)
+ , hasFboBlit(false)
+ {
+ }
+
+ ~QOpenGLWindowPrivate()
+ {
+ Q_Q(QOpenGLWindow);
+ if (q->isValid()) {
+ q->makeCurrent(); // this works even when the platformwindow is destroyed
+ paintDevice.reset(0);
+ fbo.reset(0);
+ blitter.destroy();
+ q->doneCurrent();
+ }
+ }
+
+ static QOpenGLWindowPrivate *get(QOpenGLWindow *w) { return w->d_func(); }
+
+ void bindFBO()
+ {
+ if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
+ fbo->bind();
+ else
+ QOpenGLFramebufferObject::bindDefault();
+ }
+
+ void beginPaint(const QRegion &region) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(region);
+ Q_Q(QOpenGLWindow);
+
+ if (!context) {
+ context.reset(new QOpenGLContext);
+ context->setFormat(q->requestedFormat());
+ if (!context->create())
+ qWarning("QOpenGLWindow::beginPaint: Failed to create context");
+ if (!context->makeCurrent(q))
+ qWarning("QOpenGLWindow::beginPaint: Failed to make context current");
+
+ paintDevice.reset(new QOpenGLWindowPaintDevice(q));
+ if (updateBehavior == QOpenGLWindow::PartialUpdateBlit)
+ hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit();
+
+ q->initializeGL();
+ } else {
+ context->makeCurrent(q);
+ }
+
+ if (updateBehavior > QOpenGLWindow::NoPartialUpdate) {
+ if (!fbo || fbo->size() != q->size() * q->devicePixelRatio()) {
+ QOpenGLFramebufferObjectFormat fboFormat;
+ fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ if (q->requestedFormat().samples() > 0) {
+ if (updateBehavior != QOpenGLWindow::PartialUpdateBlend)
+ fboFormat.setSamples(q->requestedFormat().samples());
+ else
+ qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling");
+ }
+ fbo.reset(new QOpenGLFramebufferObject(q->size() * q->devicePixelRatio(), fboFormat));
+ markWindowAsDirty();
+ }
+ } else {
+ markWindowAsDirty();
+ }
+
+ const int deviceWidth = q->width() * q->devicePixelRatio();
+ const int deviceHeight = q->height() * q->devicePixelRatio();
+ paintDevice->setSize(QSize(deviceWidth, deviceHeight));
+ paintDevice->setDevicePixelRatio(q->devicePixelRatio());
+ context->functions()->glViewport(0, 0, deviceWidth, deviceHeight);
+
+ context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject());
+
+ q->paintUnderGL();
+
+ if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
+ fbo->bind();
+ }
+
+ void endPaint() Q_DECL_OVERRIDE
+ {
+ Q_Q(QOpenGLWindow);
+
+ if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
+ fbo->release();
+
+ context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject());
+
+ if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) {
+ QOpenGLExtensions extensions(context.data());
+ extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle());
+ extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject());
+ extensions.glBlitFramebuffer(0, 0, q->width(), q->height(),
+ 0, 0, q->width(), q->height(),
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) {
+ if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) {
+ context->functions()->glEnable(GL_BLEND);
+ context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ if (!blitter.isCreated())
+ blitter.create();
+
+ QRect windowRect(QPoint(0, 0), fbo->size());
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect);
+ blitter.bind();
+ blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft);
+ blitter.release();
+
+ if (updateBehavior == QOpenGLWindow::PartialUpdateBlend)
+ context->functions()->glDisable(GL_BLEND);
+ }
+
+ q->paintOverGL();
+ }
+
+ void flush(const QRegion &region) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(region);
+ Q_Q(QOpenGLWindow);
+ context->swapBuffers(q);
+ emit q->frameSwapped();
+ }
+
+ QOpenGLWindow::UpdateBehavior updateBehavior;
+ bool hasFboBlit;
+ QScopedPointer<QOpenGLContext> context;
+ QScopedPointer<QOpenGLFramebufferObject> fbo;
+ QScopedPointer<QOpenGLWindowPaintDevice> paintDevice;
+ QOpenGLTextureBlitter blitter;
+ QColor backgroundColor;
+ QScopedPointer<QOffscreenSurface> offscreenSurface;
+};
+
+void QOpenGLWindowPaintDevice::ensureActiveTarget()
+{
+ QOpenGLWindowPrivate::get(m_window)->bindFBO();
+}
+
+/*!
+ Constructs a new QOpenGLWindow with the given \a parent and \a updateBehavior.
+
+ \sa QOpenGLWindow::UpdateBehavior
+ */
+QOpenGLWindow::QOpenGLWindow(QOpenGLWindow::UpdateBehavior updateBehavior, QWindow *parent)
+ : QPaintDeviceWindow(*(new QOpenGLWindowPrivate(updateBehavior)), parent)
+{
+ setSurfaceType(QSurface::OpenGLSurface);
+}
+
+/*!
+ \return the update behavior for this QOpenGLWindow.
+*/
+QOpenGLWindow::UpdateBehavior QOpenGLWindow::updateBehavior() const
+{
+ Q_D(const QOpenGLWindow);
+ return d->updateBehavior;
+}
+
+/*!
+ \return \c true if the window's OpenGL resources, like the context, have
+ been successfully initialized. Note that the return value is always \c false
+ until the window becomes exposed (shown).
+*/
+bool QOpenGLWindow::isValid() const
+{
+ Q_D(const QOpenGLWindow);
+ return d->context && d->context->isValid();
+}
+
+/*!
+ Prepares for rendering OpenGL content for this window by making the
+ corresponding context current and binding the framebuffer object, if there is
+ one, in that context context.
+
+ It is not necessary to call this function in most cases, because it is called
+ automatically before invoking paintGL(). It is provided nonetheless to support
+ advanced, multi-threaded scenarios where a thread different than the GUI or main
+ thread may want to update the surface or framebuffer contents. See QOpenGLContext
+ for more information on threading related issues.
+
+ This function is suitable for calling also when the underlying platform window
+ is already destroyed. This means that it is safe to call this function from
+ a QOpenGLWindow subclass' destructor. If there is no native window anymore,
+ an offscreen surface is used instead. This ensures that OpenGL resource
+ cleanup operations in the destructor will always work, as long as
+ this function is called first.
+
+ \sa QOpenGLContext, context(), paintGL(), doneCurrent()
+ */
+void QOpenGLWindow::makeCurrent()
+{
+ Q_D(QOpenGLWindow);
+
+ if (!isValid())
+ return;
+
+ // The platform window may be destroyed at this stage and therefore
+ // makeCurrent() may not safely be called with 'this'.
+ if (handle()) {
+ d->context->makeCurrent(this);
+ } else {
+ if (!d->offscreenSurface) {
+ d->offscreenSurface.reset(new QOffscreenSurface);
+ d->offscreenSurface->setFormat(d->context->format());
+ d->offscreenSurface->create();
+ }
+ d->context->makeCurrent(d->offscreenSurface.data());
+ }
+
+ d->bindFBO();
+}
+
+/*!
+ Releases the context.
+
+ It is not necessary to call this function in most cases, since the widget
+ will make sure the context is bound and released properly when invoking
+ paintGL().
+
+ \sa makeCurrent()
+ */
+void QOpenGLWindow::doneCurrent()
+{
+ Q_D(QOpenGLWindow);
+
+ if (!isValid())
+ return;
+
+ d->context->doneCurrent();
+}
+
+/*!
+ \return The QOpenGLContext used by this window or \c 0 if not yet initialized.
+ */
+QOpenGLContext *QOpenGLWindow::context() const
+{
+ Q_D(const QOpenGLWindow);
+ return d->context.data();
+}
+
+/*!
+ The framebuffer object handle used by this window.
+
+ When the update behavior is set to \c NoPartialUpdate, there is no separate
+ framebuffer object. In this case the returned value is the ID of the
+ default framebuffer.
+
+ Otherwise the value of the ID of the framebuffer object or \c 0 if not
+ yet initialized.
+ */
+GLuint QOpenGLWindow::defaultFramebufferObject() const
+{
+ Q_D(const QOpenGLWindow);
+ if (d->updateBehavior > NoPartialUpdate && d->fbo)
+ return d->fbo->handle();
+ else if (QOpenGLContext *ctx = QOpenGLContext::currentContext())
+ return ctx->defaultFramebufferObject();
+ else
+ return 0;
+}
+
+extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
+
+/*!
+ Returns a 32-bit RGB image of the framebuffer.
+
+ \note This is a potentially expensive operation because it relies on
+ glReadPixels() to read back the pixels. This may be slow and can stall the
+ GPU pipeline.
+
+ \note When used together with update behavior \c NoPartialUpdate, the returned
+ image may not contain the desired content when called after the front and back
+ buffers have been swapped (unless preserved swap is enabled in the underlying
+ windowing system interface). In this mode the function reads from the back
+ buffer and the contents of that may not match the content on the screen (the
+ front buffer). In this case the only place where this function can safely be
+ used is paintGL() or paintOverGL().
+ */
+QImage QOpenGLWindow::grabFramebuffer()
+{
+ if (!isValid())
+ return QImage();
+
+ makeCurrent();
+ return qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false);
+}
+
+/*!
+ This virtual function is called once before the first call to paintGL() or
+ resizeGL(). Reimplement it in a subclass.
+
+ This function should set up any required OpenGL resources and state.
+
+ There is no need to call makeCurrent() because this has already been done
+ when this function is called. Note however that the framebuffer, in case
+ partial update mode is used, is not yet available at this stage, so avoid
+ issuing draw calls from here. Defer such calls to paintGL() instead.
+
+ \sa paintGL(), resizeGL()
+ */
+void QOpenGLWindow::initializeGL()
+{
+}
+
+/*!
+ This virtual function is called whenever the widget has been resized.
+ Reimplement it in a subclass. The new size is passed in \a w and \a h.
+
+ \note This is merely a convenience function in order to provide an API that is
+ compatible with QOpenGLWidget. Unlike with QOpenGLWidget, derived classes are
+ free to choose to override resizeEvent() instead of this function.
+
+ \note Avoid issuing OpenGL commands from this function as there may not be a
+ context current when it is invoked. If it cannot be avoided, call makeCurrent().
+
+ \note Scheduling updates from here is not necessary. The windowing systems
+ will send expose events that trigger an update automatically.
+
+ \sa initializeGL(), paintGL()
+ */
+void QOpenGLWindow::resizeGL(int w, int h)
+{
+ Q_UNUSED(w);
+ Q_UNUSED(h);
+}
+
+/*!
+ This virtual function is called whenever the window contents needs to be
+ painted. Reimplement it in a subclass.
+
+ There is no need to call makeCurrent() because this has already
+ been done when this function is called.
+
+ Before invoking this function, the context and the framebuffer, if there is
+ one, are bound, and the viewport is set up by a call to glViewport(). No
+ other state is set and no clearing or drawing is performed by the framework.
+
+ \note When using a partial update behavior, like \c PartialUpdateBlend, the
+ output of the previous paintGL() call is preserved and, after the additional
+ drawing perfomed in the current invocation of the function, the content is
+ blitted or blended over the content drawn directly to the window in
+ paintUnderGL().
+
+ \sa initializeGL(), resizeGL(), paintUnderGL(), paintOverGL(), UpdateBehavior
+ */
+void QOpenGLWindow::paintGL()
+{
+}
+
+/*!
+ The virtual function is called before each invocation of paintGL().
+
+ When the update mode is set to \c NoPartialUpdate, there is no difference
+ between this function and paintGL(), performing rendering in either of them
+ leads to the same result.
+
+ The difference becomes significant when using \c PartialUpdateBlend, where an
+ extra framebuffer object is used. There, paintGL() targets this additional
+ framebuffer object, which preserves its contents, while paintUnderGL() and
+ paintOverGL() target the default framebuffer, i.e. directly the window
+ surface, the contents of which is lost after each displayed frame.
+
+ \note Avoid relying on this function when the update behavior is
+ \c PartialUpdateBlit. This mode involves blitting the extra framebuffer used by
+ paintGL() onto the default framebuffer after each invocation of paintGL(),
+ thus overwriting all drawing generated in this function.
+
+ \sa paintGL(), paintOverGL(), UpdateBehavior
+ */
+void QOpenGLWindow::paintUnderGL()
+{
+}
+
+/*!
+ This virtual function is called after each invocation of paintGL().
+
+ When the update mode is set to NoPartialUpdate, there is no difference
+ between this function and paintGL(), performing rendering in either of them
+ leads to the same result.
+
+ Like paintUnderGL(), rendering in this function targets the default
+ framebuffer of the window, regardless of the update behavior. It gets called
+ after paintGL() has returned and the blit (PartialUpdateBlit) or quad drawing
+ (PartialUpdateBlend) has been done.
+
+ \sa paintGL(), paintUnderGL(), UpdateBehavior
+ */
+void QOpenGLWindow::paintOverGL()
+{
+}
+
+/*!
+ Paint \a event handler. Calls paintGL().
+
+ \sa paintGL()
+ */
+void QOpenGLWindow::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+ paintGL();
+}
+
+/*!
+ Resize \a event handler. Calls resizeGL().
+
+ \sa resizeGL()
+ */
+void QOpenGLWindow::resizeEvent(QResizeEvent *event)
+{
+ Q_UNUSED(event);
+ resizeGL(width(), height());
+}
+
+/*!
+ \internal
+ */
+int QOpenGLWindow::metric(PaintDeviceMetric metric) const
+{
+ Q_D(const QOpenGLWindow);
+
+ switch (metric) {
+ case PdmDepth:
+ if (d->paintDevice)
+ return d->paintDevice->depth();
+ break;
+ case PdmDevicePixelRatio:
+ if (d->paintDevice)
+ return d->paintDevice->devicePixelRatio();
+ break;
+ default:
+ break;
+ }
+ return QPaintDeviceWindow::metric(metric);
+
+}
+
+/*!
+ \internal
+ */
+QPaintDevice *QOpenGLWindow::redirected(QPoint *) const
+{
+ Q_D(const QOpenGLWindow);
+ if (QOpenGLContext::currentContext() == d->context.data())
+ return d->paintDevice.data();
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qclipboard_qpa.cpp b/src/gui/kernel/qopenglwindow.h
index ff8a210cba..e30de3b6ac 100644
--- a/src/gui/kernel/qclipboard_qpa.cpp
+++ b/src/gui/kernel/qopenglwindow.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -39,51 +39,68 @@
**
****************************************************************************/
-#include "qclipboard.h"
+#ifndef QOPENGLWINDOW_H
+#define QOPENGLWINDOW_H
-#ifndef QT_NO_CLIPBOARD
+#include <QtCore/qglobal.h>
-#include "qmimedata.h"
-#include "private/qguiapplication_p.h"
-#include <qpa/qplatformclipboard.h>
-#include <qpa/qplatformintegration.h>
+#ifndef QT_NO_OPENGL
+
+#include <QtGui/QPaintDeviceWindow>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QImage>
QT_BEGIN_NAMESPACE
-QT_USE_NAMESPACE
+class QOpenGLWindowPrivate;
-void QClipboard::clear(Mode mode)
+class Q_GUI_EXPORT QOpenGLWindow : public QPaintDeviceWindow
{
- setMimeData(0, mode);
-}
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QOpenGLWindow)
-const QMimeData* QClipboard::mimeData(Mode mode) const
-{
- QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
- if (!clipboard->supportsMode(mode)) return 0;
- return clipboard->mimeData(mode);
-}
+public:
+ enum UpdateBehavior {
+ NoPartialUpdate,
+ PartialUpdateBlit,
+ PartialUpdateBlend
+ };
-void QClipboard::setMimeData(QMimeData* src, Mode mode)
-{
- QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
- if (!clipboard->supportsMode(mode)) return;
+ explicit QOpenGLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = 0);
- clipboard->setMimeData(src,mode);
-}
+ UpdateBehavior updateBehavior() const;
+ bool isValid() const;
-bool QClipboard::supportsMode(Mode mode) const
-{
- QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
- return clipboard->supportsMode(mode);
-}
+ void makeCurrent();
+ void doneCurrent();
-bool QClipboard::ownsMode(Mode mode) const
-{
- QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
- return clipboard->ownsMode(mode);
-}
+ QOpenGLContext *context() const;
+
+ GLuint defaultFramebufferObject() const;
-#endif // QT_NO_CLIPBOARD
+ QImage grabFramebuffer();
+
+Q_SIGNALS:
+ void frameSwapped();
+
+protected:
+ virtual void initializeGL();
+ virtual void resizeGL(int w, int h);
+ virtual void paintGL();
+ virtual void paintUnderGL();
+ virtual void paintOverGL();
+
+ void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
+ void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
+ int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
+ QPaintDevice *redirected(QPoint *) const Q_DECL_OVERRIDE;
+
+private:
+ Q_DISABLE_COPY(QOpenGLWindow)
+};
QT_END_NAMESPACE
+
+#endif // QT_NO_OPENGL
+
+#endif
diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp
new file mode 100644
index 0000000000..9c6a255ca7
--- /dev/null
+++ b/src/gui/kernel/qpaintdevicewindow.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpaintdevicewindow_p.h"
+
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QPaintDeviceWindow
+ \inmodule QtGui
+ \since 5.4
+ \brief Convenience subclass of QWindow that is also a QPaintDevice.
+
+ QPaintDeviceWindow is like a regular QWindow, with the added functionality
+ of being a paint device too. Whenever the content needs to be updated,
+ the virtual paintEvent() function is called. Subclasses, that reimplement
+ this function, can then simply open a QPainter on the window.
+
+ \note This class cannot directly be used in applications. It rather serves
+ as a base for subclasses like QOpenGLWindow.
+
+ \sa QOpenGLWindow
+*/
+
+/*!
+ Marks the entire window as dirty and schedules a repaint.
+
+ \note Subsequent calls to this function before the next paint
+ event will get ignored.
+*/
+void QPaintDeviceWindow::update()
+{
+ update(QRect(QPoint(0,0), size()));
+}
+
+/*!
+ Marks the \a rect of the window as dirty and schedules a repaint.
+
+ \note Subsequent calls to this function before the next paint
+ event will get ignored.
+*/
+void QPaintDeviceWindow::update(const QRect &rect)
+{
+ Q_D(QPaintDeviceWindow);
+ d->dirtyRegion += rect;
+ d->triggerUpdate();
+}
+
+/*!
+ Marks the \a region of the window as dirty and schedules a repaint.
+
+ \note Subsequent calls to this function before the next paint
+ event will get ignored.
+*/
+void QPaintDeviceWindow::update(const QRegion &region)
+{
+ Q_D(QPaintDeviceWindow);
+ d->dirtyRegion += region;
+ d->triggerUpdate();
+}
+
+/*!
+ Handles paint events passed in the \a event parameter.
+
+ The default implementation does nothing. Reimplement this function to
+ perform painting. If necessary, the dirty area is retrievable from
+ the \a event.
+*/
+void QPaintDeviceWindow::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+ // Do nothing
+}
+
+/*!
+ \internal
+ */
+int QPaintDeviceWindow::metric(PaintDeviceMetric metric) const
+{
+ QScreen *screen = this->screen();
+ if (!screen && QGuiApplication::primaryScreen())
+ screen = QGuiApplication::primaryScreen();
+
+ switch (metric) {
+ case PdmWidth:
+ return width();
+ case PdmWidthMM:
+ if (screen)
+ return width() * screen->physicalSize().width() / screen->geometry().width();
+ break;
+ case PdmHeight:
+ return height();
+ case PdmHeightMM:
+ if (screen)
+ return height() * screen->physicalSize().height() / screen->geometry().height();
+ break;
+ case PdmDpiX:
+ if (screen)
+ return qRound(screen->logicalDotsPerInchX());
+ break;
+ case PdmDpiY:
+ if (screen)
+ return qRound(screen->logicalDotsPerInchY());
+ break;
+ case PdmPhysicalDpiX:
+ if (screen)
+ return qRound(screen->physicalDotsPerInchX());
+ break;
+ case PdmPhysicalDpiY:
+ if (screen)
+ return qRound(screen->physicalDotsPerInchY());
+ break;
+ case PdmDevicePixelRatio:
+ if (screen)
+ return screen->devicePixelRatio();
+ break;
+ default:
+ break;
+ }
+
+ return QPaintDevice::metric(metric);
+}
+
+/*!
+ \internal
+ */
+void QPaintDeviceWindow::exposeEvent(QExposeEvent *exposeEvent)
+{
+ Q_UNUSED(exposeEvent);
+ Q_D(QPaintDeviceWindow);
+ if (isExposed()) {
+ d->markWindowAsDirty();
+ // Do not rely on exposeEvent->region() as it has some issues for the
+ // time being, namely that it is sometimes in local coordinates,
+ // sometimes relative to the parent, depending on the platform plugin.
+ // We require local coords here.
+ d->doFlush(QRect(QPoint(0, 0), size()));
+ }
+}
+
+/*!
+ \internal
+ */
+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;
+ }
+
+ return QWindow::event(event);
+}
+
+/*!
+ \internal
+ */
+QPaintDeviceWindow::QPaintDeviceWindow(QPaintDeviceWindowPrivate &dd, QWindow *parent)
+ : QWindow(dd, parent)
+{
+}
+
+/*!
+ \internal
+ */
+QPaintEngine *QPaintDeviceWindow::paintEngine() const
+{
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformscreenpageflipper.h b/src/gui/kernel/qpaintdevicewindow.h
index 232e37d24a..ee7d07254e 100644
--- a/src/gui/kernel/qplatformscreenpageflipper.h
+++ b/src/gui/kernel/qpaintdevicewindow.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -39,54 +39,47 @@
**
****************************************************************************/
-#ifndef QPLATFORMSCREENPAGEFLIPPER_H
-#define QPLATFORMSCREENPAGEFLIPPER_H
+#ifndef QPAINTDEVICEWINDOW_H
+#define QPAINTDEVICEWINDOW_H
-//
-// W A R N I N G
-// -------------
-//
-// This file is part of the QPA API and is not meant to be used
-// in applications. Usage of this API may make your code
-// source and binary incompatible with future versions of Qt.
-//
-
-#include <QtCore/QObject>
+#include <QtGui/QWindow>
+#include <QtGui/QPaintDevice>
QT_BEGIN_NAMESPACE
-class Q_GUI_EXPORT QPlatformScreenBuffer {
-public:
- QPlatformScreenBuffer();
- virtual ~QPlatformScreenBuffer();
+class QPaintDeviceWindowPrivate;
+class QPaintEvent;
+
+class Q_GUI_EXPORT QPaintDeviceWindow : public QWindow, public QPaintDevice
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPaintDeviceWindow)
- bool isDestroyed() const;
- bool isReady() const;
+public:
+ void update(const QRect &rect);
+ void update(const QRegion &region);
- virtual void aboutToBeDisplayed();
- virtual void displayed();
- virtual void release() = 0;
+ using QWindow::width;
+ using QWindow::height;
+ using QWindow::devicePixelRatio;
- virtual void *handle() const = 0;
+public Q_SLOTS:
+ void update();
protected:
- bool m_destroyed;
- bool m_ready;
-};
+ virtual void paintEvent(QPaintEvent *event);
-class Q_GUI_EXPORT QPlatformScreenPageFlipper : public QObject
-{
- Q_OBJECT
-public:
- explicit QPlatformScreenPageFlipper(QObject *parent = 0);
+ int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
+ void exposeEvent(QExposeEvent *) Q_DECL_OVERRIDE;
+ bool event(QEvent *event) Q_DECL_OVERRIDE;
- virtual bool displayBuffer(QPlatformScreenBuffer *) = 0;
+ QPaintDeviceWindow(QPaintDeviceWindowPrivate &dd, QWindow *parent);
-Q_SIGNALS:
- void bufferDisplayed(QPlatformScreenBuffer *);
- void bufferReleased(QPlatformScreenBuffer *);
+private:
+ QPaintEngine *paintEngine() const Q_DECL_OVERRIDE;
+ Q_DISABLE_COPY(QPaintDeviceWindow)
};
QT_END_NAMESPACE
-#endif // QPLATFORMSCREENPAGEFLIPPER_H
+#endif
diff --git a/src/gui/kernel/qplatformscreenpageflipper.cpp b/src/gui/kernel/qpaintdevicewindow_p.h
index 8665adc463..65313eda87 100644
--- a/src/gui/kernel/qplatformscreenpageflipper.cpp
+++ b/src/gui/kernel/qpaintdevicewindow_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -39,83 +39,92 @@
**
****************************************************************************/
-#include "qplatformscreenpageflipper.h"
+#ifndef QPAINTDEVICEWINDOW_P_H
+#define QPAINTDEVICEWINDOW_P_H
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QPlatformScreenBuffer
- \since 5.0
- \internal
- \preliminary
- \ingroup qpa
-
- \brief The QPlatformScreenBuffer class provides an abstraction for screen buffers.
- */
-QPlatformScreenBuffer::QPlatformScreenBuffer()
- : m_destroyed(false)
- , m_ready(true)
-{
-
-}
-
-QPlatformScreenBuffer::~QPlatformScreenBuffer()
-{
+#include <QtGui/QPaintDeviceWindow>
+#include <QtCore/QCoreApplication>
+#include <QtGui/private/qwindow_p.h>
+#include <QtGui/QPaintEvent>
-}
-
-bool QPlatformScreenBuffer::isDestroyed() const
-{
- return m_destroyed;
-}
-
-bool QPlatformScreenBuffer::isReady() const
-{
- return m_ready;
-}
-
-void QPlatformScreenBuffer::aboutToBeDisplayed()
-{
-}
-
-void QPlatformScreenBuffer::displayed()
-{
-}
-
-
-/*!
- \class QPlatformScreenPageFlipper
- \since 5.0
- \internal
- \preliminary
- \ingroup qpa
-
- \brief The QPlatformScreenPageFlipper class provides an abstract interface for display buffer swapping
-
- Implement the displayBuffer() function to initiate a buffer swap. The
- bufferDisplayed() signal should be emitted once the buffer is actually displayed on
- the screen. The bufferReleased() signal should be emitted when the buffer data is no
- longer owned by the display hardware.
-*/
+QT_BEGIN_NAMESPACE
-QPlatformScreenPageFlipper::QPlatformScreenPageFlipper(QObject *parent)
- :QObject(parent)
+class Q_GUI_EXPORT QPaintDeviceWindowPrivate : public QWindowPrivate
{
+ Q_DECLARE_PUBLIC(QPaintDeviceWindow)
+
+public:
+ QPaintDeviceWindowPrivate() : paintEventSent(false) { }
+
+ virtual void beginPaint(const QRegion &region)
+ {
+ Q_UNUSED(region);
+ }
+
+ virtual void endPaint()
+ {
+ }
+
+ virtual void flush(const QRegion &region)
+ {
+ Q_UNUSED(region);
+ }
+
+ bool paint(const QRegion &region)
+ {
+ Q_Q(QPaintDeviceWindow);
+ QRegion toPaint = region & dirtyRegion;
+ if (toPaint.isEmpty())
+ return false;
+
+ // Clear the region now. The overridden functions may call update().
+ dirtyRegion -= toPaint;
+
+ beginPaint(toPaint);
+
+ QPaintEvent paintEvent(toPaint);
+ q->paintEvent(&paintEvent);
+
+ endPaint();
+
+ return true;
+ }
+
+ void triggerUpdate()
+ {
+ Q_Q(QPaintDeviceWindow);
+ if (!paintEventSent) {
+ QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
+ paintEventSent = true;
+ }
+ }
+
+ void doFlush(const QRegion &region)
+ {
+ QRegion toFlush = region;
+ if (paint(toFlush))
+ flush(toFlush);
+ }
+
+ void handleUpdateEvent()
+ {
+ if (dirtyRegion.isEmpty())
+ return;
+ doFlush(dirtyRegion);
+ }
+
+ void markWindowAsDirty()
+ {
+ Q_Q(QPaintDeviceWindow);
+ dirtyRegion += QRect(QPoint(0, 0), q->size());
+ }
+
+private:
+ QRegion dirtyRegion;
+ bool paintEventSent;
+};
-}
-
-/*!
- \fn bool QPlatformScreenPageFlipper::displayBuffer(QPlatformScreenBuffer *buffer)
-
- Implemented in subclasses to display \a buffer directly on the screen. Returns \c true
- if it is possible to display the buffer, and \c false if the buffer cannot be displayed.
-
- If this function returns \c true, the buffer must not be modified or destroyed before the
- bufferReleased() signal is emitted. The signal bufferDisplayed() is emitted when the buffer
- is displayed on the screen. The two signals may be emitted in either order.
-
- This function is allowed to block.
-*/
QT_END_NAMESPACE
+#endif //QPAINTDEVICEWINDOW_P_H
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index f284c20af5..52b0372ea8 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -643,11 +643,22 @@ QPalette::QPalette(const QPalette &p)
}
/*!
+ \fn QPalette::QPalette(QPalette &&other)
+ \since 5.4
+
+ Move-constructs a QPalette instance, making it point at the same
+ object that \a other was pointing to.
+
+ After being moved from, you can only assign to or destroy \a other.
+ Any other operation will result in undefined behavior.
+*/
+
+/*!
Destroys the palette.
*/
QPalette::~QPalette()
{
- if(!d->ref.deref())
+ if (d && !d->ref.deref())
delete d;
}
@@ -668,7 +679,7 @@ QPalette &QPalette::operator=(const QPalette &p)
{
p.d->ref.ref();
data = p.data;
- if(!d->ref.deref())
+ if (d && !d->ref.deref())
delete d;
d = p.d;
return *this;
@@ -1141,9 +1152,33 @@ Q_GUI_EXPORT QPalette qt_fusionPalette()
}
#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug dbg, const QPalette &)
+QDebug operator<<(QDebug dbg, const QPalette &p)
{
- dbg.nospace() << "QPalette()";
+ const char *colorGroupNames[] = {"Active", "Disabled", "Inactive"};
+ const char *colorRoleNames[] =
+ {"WindowText", "Button", "Light", "Midlight", "Dark", "Mid", "Text",
+ "BrightText", "ButtonText", "Base", "Window", "Shadow", "Highlight",
+ "HighlightedText", "Link", "LinkVisited", "AlternateBase", "NoRole",
+ "ToolTipBase","ToolTipText" };
+ QDebug nospace = dbg.nospace();
+ const uint mask = p.resolve();
+ nospace << "QPalette(resolve=" << hex << showbase << mask << ',';
+ for (int role = 0; role < (int)QPalette::NColorRoles; ++role) {
+ if (mask & (1<<role)) {
+ if (role)
+ nospace << ',';
+ nospace << colorRoleNames[role] << ":[";
+ for (int group = 0; group < (int)QPalette::NColorGroups; ++group) {
+ if (group)
+ nospace << ',';
+ const QRgb color = p.color(static_cast<QPalette::ColorGroup>(group),
+ static_cast<QPalette::ColorRole>(role)).rgba();
+ nospace << colorGroupNames[group] << ':' << color;
+ }
+ nospace << ']';
+ }
+ }
+ nospace << ')' << noshowbase << dec;
return dbg.space();
}
#endif
diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h
index 8d9754d388..8c344be1e6 100644
--- a/src/gui/kernel/qpalette.h
+++ b/src/gui/kernel/qpalette.h
@@ -70,6 +70,8 @@ public:
~QPalette();
QPalette &operator=(const QPalette &palette);
#ifdef Q_COMPILER_RVALUE_REFS
+ QPalette(QPalette &&other) Q_DECL_NOTHROW
+ : d(other.d), data(other.data) { other.d = Q_NULLPTR; }
inline QPalette &operator=(QPalette &&other)
{
for_faster_swapping_dont_use = other.for_faster_swapping_dont_use;
diff --git a/src/gui/kernel/qpixelformat.cpp b/src/gui/kernel/qpixelformat.cpp
new file mode 100644
index 0000000000..90ab2db93e
--- /dev/null
+++ b/src/gui/kernel/qpixelformat.cpp
@@ -0,0 +1,569 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpixelformat.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QPixelFormat
+ \inmodule QtGui
+ \since 5.4
+ \brief QPixelFormat is a class for describing different pixel
+ layouts in graphics buffers
+
+ In Qt there is a often a need to represent the layout of the pixels in a
+ graphics buffer. Internally QPixelFormat stores everything in a 64 bit
+ datastructure. This gives performance but also some limitations.
+
+ QPixelFormat can describe 5 color channels and 1 alpha channel, each can use
+ 6 bits to describe the size of the color channel.
+
+ The position of the alpha channel is described with a separate enum. This is
+ to make it possible to describe QImage formats like ARGB32, and also
+ describe typical OpenGL formats like RBGA8888.
+
+ How pixels are suppose to be read is determined by the TypeInterpretation
+ enum. It describes if color values are suppose to be read byte per byte,
+ or if a pixel is suppose to be read as a complete int and then masked.
+ \sa TypeInterpretation
+
+ There is no support for describing YUV's macro pixels. Instead a list of YUV
+ formats has been made. When a QPixelFormat is describing a YUV format, the
+ bitsPerPixel value has been deduced by the YUV Layout enum. Also, the color
+ channels should all be set to zero except the fifth color channel that
+ should store the bitsPerPixel value.
+*/
+
+/*!
+ \enum QPixelFormat::ColorModel
+
+ This enum type is used to describe the color model of the pixelformat.
+
+ \value RGB The color model is RGB.
+
+ \value BGR This is logically the opposite endian version of RGB. However,
+ for ease of use it has its own model.
+
+ \value Indexed The color model uses a color palette.
+
+ \value Grayscale The color model is Grayscale.
+
+ \value CMYK The color model is CMYK.
+
+ \value HSL The color model is HSL.
+
+ \value HSV The color model is HSV.
+
+ \value YUV The color model is YUV.
+*/
+
+/*!
+ \enum QPixelFormat::AlphaUsage
+
+ This enum describes if the alpha channel is used or not. Sometimes the
+ pixelformat will have a size for the alpha channel, but the pixel format
+ does actually not use the alpha channel. For example RGB32 is such a
+ format. The RGB channels are 8 bits each, and there is no alpha channel.
+ But the complete size for each pixel is 32. Therefore the alpha channel size
+ is 8, but the alpha channel is ignored. Its important to note that in such
+ situations the position of the alpha channel is significant.
+
+ \value IgnoresAlpha The alpha channel is not used.
+
+ \value UsesAlpha The alpha channel is used.
+*/
+
+/*!
+ \enum QPixelFormat::AlphaPosition
+
+ This enum type is used to describe the alpha channels position relative to the
+ color channels.
+
+ \value AtBeginning The alpha channel will be put in front of the color
+ channels . E.g. ARGB.
+
+ \value AtEnd The alpha channel will be put in the back of the color
+ channels. E.g. RGBA.
+*/
+
+/*!
+ \enum QPixelFormat::AlphaPremultiplied
+
+ This enum type describes the boolean state if the alpha channel is multiplied
+ into the color channels or not.
+
+ \value NotPremultiplied The alpha channel is not multiplied into the color channels.
+
+ \value Premultiplied The alpha channel is multiplied into the color channels.
+*/
+
+/*!
+ \enum QPixelFormat::TypeInterpretation
+
+ This enum describes how each pixel is interpreted. If a pixel is read as a
+ full 32 bit unsigned integer and then each channel is masked out, or if
+ each byte is read as unsigned char values. Typically QImage formats
+ interpret one pixel as an unsigned integer and then the color channels are
+ masked out. OpenGL on the other hand typically interpreted pixels "one byte
+ after the other", Ie. unsigned byte.
+
+ QImage also have the format Format_RGBA8888 (and its derivatives), where
+ the pixels are interpreted as unsigned bytes. OpenGL has extensions that makes it
+ possible to upload pixel buffers in an unsigned integer format.
+
+ \image qpixelformat-argb32buffer.png An unsigned integer ARGB32 pixel.
+
+ The image above shows a ARGB pixel in memory read as an unsigned integer.
+ However, if this pixel was read byte for byte on a little endian system the
+ first byte would be the byte containing the B-channel. The next byte would
+ be the G-channel, then the R-channel and finally the A-channel. This shows
+ that on little endian systems, how each pixel is interpreted is significant
+ for integer formats. This is not the case on big endian systems.
+
+ \value UnsignedInteger
+ \value UnsignedShort
+ \value UnsignedByte
+ \value FloatingPoint
+*/
+
+/*!
+ \enum QPixelFormat::ByteOrder
+
+ This enum describes the ByteOrder of the pixel format. This enum is mostly
+ ignored but have some use cases for YUV formats. BGR formats have their own
+ color model, and should not be described by using the opposite endianness
+ on an RGB format.
+
+ \value LittleEndian The byte order is little endian.
+ \value BigEndian The byte order is big endian.
+ \value CurrentSystemEndian This enum will not be stored, but is converted in
+ the constructor to the endian enum that matches
+ the enum of the current system.
+
+*/
+
+/*!
+ \enum QPixelFormat::YUVLayout
+
+ YUV is not represented by describing the size of the color channels. This is
+ because YUV often use macro pixels, making the concept of sperate color channels
+ invalid. Instead the different YUV layouts are described with this enum.
+
+ \value YUV444
+ \value YUV422
+ \value YUV411
+ \value YUV420P
+ \value YUV420SP
+ \value YV12
+ \value UYVY
+ \value YUYV
+ \value NV12
+ \value NV21
+ \value IMC1
+ \value IMC2
+ \value IMC3
+ \value IMC4
+ \value Y8
+ \value Y16
+*/
+
+/*!
+ \fn QPixelFormat::QPixelFormat()
+
+ Creates a null pixelformat. This format maps to QImage::Format_Invalid.
+*/
+
+/*!
+ \fn QPixelFormat::QPixelFormat(ColorModel colorModel,
+ uchar firstSize,
+ uchar secondSize,
+ uchar thirdSize,
+ uchar fourthSize,
+ uchar fifthSize,
+ uchar alphaSize,
+ AlphaUsage alphaUsage,
+ AlphaPosition alphaPosition,
+ AlphaPremultiplied premultiplied,
+ TypeInterpretation typeInterpretation,
+ ByteOrder byteOrder = CurrentSystemEndian,
+ uchar subEnum = 0)
+
+ Creates a QPixelFormat which assigns its data to the attributes.
+ \a colorModel will be put into a buffer which is 4 bits long.
+
+ \a firstSize \a secondSize \a thirdSize \a fourthSize \a fifthSize \a
+ alphaSize are all meant to represent the size of a channel. The channels will
+ be used for different uses dependent on the \a colorModel. For RGB the
+ firstSize will represent the Red channel. On CMYK it will represent the
+ value of the Cyan channel.
+
+ \a alphaUsage represents if the alpha channel is used or not.
+
+ \a alphaPosition is the position of the alpha channel.
+
+ \a premultiplied represents if the alpha channel is already multiplied with
+ the color channels.
+
+ \a typeInterpretation is how the pixel is interpreted.
+
+ \a byteOrder represents the endianness of the pixelformat. This defaults to
+ CurrentSystemEndian.
+
+ \a subEnum is used for colorModels that have to store some extra
+ information with supplying an extra enum. This is used by YUV to store the
+ YUV type The default value is 0.
+*/
+
+/*!
+ \fn QPixelFormat qPixelFormatRgba(uchar redSize,
+ uchar greenSize,
+ uchar blueSize,
+ uchar alphaSize,
+ QPixelFormat::AlphaUsage alphaUsage,
+ QPixelFormat::AlphaPosition alphaPosition,
+ QPixelFormat::AlphaPremultiplied premultiplied = QPixelFormat::NotPremultiplied,
+ QPixelFormat::TypeInterpretation typeInterpretation = QPixelFormat::UnsignedInteger)
+ \relates QPixelFormat
+
+ Constructor function making an RGB pixelformat. \a redSize \a greenSize \a
+ blueSize represent the size of each color channel. \a alphaSize describes
+ the alpha channel size and its position is described with \a alphaPosition.
+ \a alphaUsage is used to determine if the alpha channel is used or not.
+ Setting the alpha channel size to 8 and alphaUsage to IgnoresAlpha is how
+ it is possible to create a 32 bit format where the rgb channels only use 24
+ bits combined. \a premultiplied \a typeInterpretation are
+ accessible with accessors with the same name.
+
+ \sa QPixelFormat::TypeInterpretation
+*/
+
+/*!
+ \fn QPixelFormat qPixelFormatGrayscale(uchar channelSize,
+ QPixelFormat::TypeInterpretation typeInterpretation = QPixelFormat::UnsignedInteger)
+ \relates QPixelFormat
+
+ Constructor function for creating a Grayscale format. Monochrome formats can be
+ described by passing 1 to \a channelSize. Its also possible to define very
+ accurate grayscale 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,
+ QPixelFormat::AlphaPosition alphaPosition = QPixelFormat::AtBeginning,
+ QPixelFormat::TypeInterpretation typeInterpretation = QPixelFormat::UnsignedInteger)
+ \relates QPixelFormat
+
+ Constructor function for creating CMYK formats. The channel count will be 4 or
+ 5 depending on if \a alphaSize is bigger than zero or not. The CMYK color
+ channels will all be set to the value of \a channelSize.
+
+ \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with
+ the accessors with the same name.
+
+ \sa QPixelFormat::TypeInterpretation
+*/
+
+/*!
+ \fn QPixelFormat qPixelFormatHsl(uchar channelSize,
+ uchar alphaSize = 0,
+ QPixelFormat::AlphaUsage alphaUsage = QPixelFormat::IgnoresAlpha,
+ QPixelFormat::AlphaPosition alphaPosition = QPixelFormat::AtBeginning,
+ QPixelFormat::TypeInterpretation typeInterpretation = QPixelFormat::FloatingPoint)
+ \relates QPixelFormat
+
+ Constructor function for creating HSL formats. The channel count will be 3 or 4
+ depending on if \a alphaSize is bigger than 0.
+
+ \a channelSize will set the hueSize saturationSize and lightnessSize to the same value.
+
+ \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with
+ the accessors with the same name.
+*/
+
+/*!
+ \fn QPixelFormat qPixelFormatHsv(uchar channelSize,
+ uchar alphaSize = 0,
+ QPixelFormat::AlphaUsage alphaUsage = QPixelFormat::IgnoresAlpha,
+ QPixelFormat::AlphaPosition alphaPosition = QPixelFormat::AtBeginning,
+ QPixelFormat::TypeInterpretation typeInterpretation = QPixelFormat::FloatingPoint)
+ \relates QPixelFormat
+
+ Constructor function for creating HSV formats. The channel count will be 3 or 4
+ depending on if \a alphaSize is bigger than 0.
+
+ \a channelSize will set the hueSize saturationSize and brightnessSize to the same value.
+
+ \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with
+ the accessors with the same name.
+*/
+
+/*!
+ \fn QPixelFormat qPixelFormatYuv(QPixelFormat::YUVLayout yuvLayout,
+ uchar alphaSize = 0,
+ QPixelFormat::AlphaUsage alphaUsage = QPixelFormat::IgnoresAlpha,
+ QPixelFormat::AlphaPosition alphaPosition = QPixelFormat::AtBeginning,
+ QPixelFormat::AlphaPremultiplied premultiplied = QPixelFormat::NotPremultiplied,
+ QPixelFormat::TypeInterpretation typeInterpretation = QPixelFormat::UnsignedByte,
+ QPixelFormat::ByteOrder byteOrder = QPixelFormat::LittleEndian)
+ \relates QPixelFormat
+
+ Constructor function for creating a QPixelFormat describing a YUV format with
+ \a yuvLayout. \a alphaSize describes the size of a potential alpha channel
+ and is position is described with \a alphaPosition. The "first" "second" ..
+ "fifth" channels are all set to 0. \a alphaUsage \a premultiplied \a
+ typeInterpretation and \a byteOrder will work as with other formats.
+*/
+
+/*!
+ \fn ColorModel QPixelFormat::colorModel() const
+
+ Accessor function for getting the colorModel.
+*/
+
+/*!
+ \fn uchar QPixelFormat::channelCount() const
+
+ Accessor function for getting the channelCount. Channel Count is deduced
+ by color channels with a size > 0 and if the size of the alpha channel is > 0.
+*/
+
+/*!
+ \fn uchar QPixelFormat::redSize() const
+
+ Accessor function for the size of the red color channel.
+*/
+
+/*!
+ \fn uchar QPixelFormat::greenSize() const
+
+ Accessor function for the size of the green color channel.
+*/
+
+/*!
+ \fn uchar QPixelFormat::blueSize() const
+
+ Accessor function for the size of the blue color channel.
+*/
+
+/*!
+ \fn uchar QPixelFormat::cyanSize() const
+
+ Accessor function for the cyan color channel.
+*/
+
+/*!
+ \fn uchar QPixelFormat::magentaSize() const
+
+ Accessor function for the megenta color channel.
+*/
+
+/*!
+ \fn uchar QPixelFormat::yellowSize() const
+
+ Accessor function for the yellow color channel.
+*/
+
+/*!
+ \fn uchar QPixelFormat::blackSize() const
+
+ Accessor function for the black/key color channel.
+*/
+
+/*!
+ \fn uchar QPixelFormat::hueSize() const
+
+ Accessor function for the hue channel size.
+*/
+
+/*!
+ \fn uchar QPixelFormat::saturationSize() const
+
+ Accessor function for the saturation channel size.
+*/
+
+/*!
+ \fn uchar QPixelFormat::lightnessSize() const
+
+ Accessor function for the lightness channel size.
+*/
+
+/*!
+ \fn uchar QPixelFormat::brightnessSize() const
+
+ Accessor function for the brightness channel size.
+*/
+
+/*!
+ \fn uchar QPixelFormat::alphaSize() const
+
+ Accessor function for the alpha channel size.
+*/
+
+/*!
+ \fn uchar QPixelFormat::bitsPerPixel() const
+
+ Accessor function for the bits used per pixel. This function returns the
+ sum of the color channels + the size of the alpha channel.
+*/
+
+/*!
+ \fn AlphaPremultiplied QPixelFormat::premultiplied() const
+
+ Accessor function for the AlphaPremultiplied enum. This indicates if the
+ alpha channel is multiplied in to the color channels.
+
+*/
+
+/*!
+ \fn TypeInterpretation QPixelFormat::typeInterpretation() const
+
+ Accessor function for the type representation of a color channel or a pixel.
+
+ \sa TypeInterpretation
+*/
+
+/*!
+ \fn ByteOrder QPixelFormat::byteOrder() const
+
+ The byte order is almost always set the the byte order of the current
+ system. However, it can be useful to describe some YUV formats. This
+ function should never return QPixelFormat::CurrentSystemEndian as this
+ value is translated to a endian value in the constructor.
+*/
+
+/*!
+ \fn AlphaUsage QPixelFormat::alphaUsage() const
+
+ Accessor function for alphaUsage.
+*/
+
+/*!
+ \fn AlphaPosition QPixelFormat::alphaPosition() const
+
+ Accessor function for alphaPosition.
+*/
+
+/*!
+ \fn YUVLayout QPixelFormat::yuvLayout() const
+
+ Accessor function for the YUVLayout. It is difficult to describe the color
+ channels of a YUV pixel format since YUV color model uses macro pixels.
+ Instead the layout of the pixels are stored as an enum.
+*/
+
+/*!
+ \fn uchar QPixelFormat::subEnum() const
+
+ Accessor for the datapart which contains subEnums
+ This is the same as the yuvLayout() function.
+
+ \sa yuvLayout()
+ \internal
+*/
+
+Q_STATIC_ASSERT(sizeof(QPixelFormat) == sizeof(quint64));
+
+
+namespace QtPrivate {
+ QPixelFormat QPixelFormat_createYUV(QPixelFormat::YUVLayout yuvLayout,
+ uchar alphaSize,
+ QPixelFormat::AlphaUsage alphaUsage,
+ QPixelFormat::AlphaPosition alphaPosition,
+ QPixelFormat::AlphaPremultiplied premultiplied,
+ QPixelFormat::TypeInterpretation typeInterpretation,
+ QPixelFormat::ByteOrder byteOrder)
+ {
+ uchar bits_per_pixel = 0;
+ switch (yuvLayout) {
+ case QPixelFormat::YUV444:
+ bits_per_pixel = 24;
+ break;
+ case QPixelFormat::YUV422:
+ bits_per_pixel = 16;
+ break;
+ case QPixelFormat::YUV411:
+ case QPixelFormat::YUV420P:
+ case QPixelFormat::YUV420SP:
+ case QPixelFormat::YV12:
+ bits_per_pixel = 12;
+ break;
+ case QPixelFormat::UYVY:
+ case QPixelFormat::YUYV:
+ bits_per_pixel = 16;
+ break;
+ case QPixelFormat::NV12:
+ case QPixelFormat::NV21:
+ bits_per_pixel = 12;
+ break;
+ case QPixelFormat::IMC1:
+ case QPixelFormat::IMC2:
+ case QPixelFormat::IMC3:
+ case QPixelFormat::IMC4:
+ bits_per_pixel = 12;
+ break;
+ case QPixelFormat::Y8:
+ bits_per_pixel = 8;
+ break;
+ case QPixelFormat::Y16:
+ bits_per_pixel = 16;
+ break;
+ }
+
+ return QPixelFormat(QPixelFormat::YUV,
+ 0, 0, 0, 0,
+ bits_per_pixel,
+ alphaSize,
+ alphaUsage,
+ alphaPosition,
+ premultiplied,
+ typeInterpretation,
+ byteOrder,
+ yuvLayout);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qpixelformat.h b/src/gui/kernel/qpixelformat.h
new file mode 100644
index 0000000000..60bfbed824
--- /dev/null
+++ b/src/gui/kernel/qpixelformat.h
@@ -0,0 +1,391 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPIXELFORMAT_H
+#define QPIXELFORMAT_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPixelFormat
+{
+ // QPixelFormat basically is a glorified quint64, split into several fields.
+ // We could use bit-fields, but GCC at least generates horrible, horrible code for them,
+ // so we do the bit-twiddling ourselves.
+ enum FieldWidth {
+ ModelFieldWidth = 4,
+ FirstFieldWidth = 6,
+ SecondFieldWidth = FirstFieldWidth,
+ ThirdFieldWidth = FirstFieldWidth,
+ FourthFieldWidth = FirstFieldWidth,
+ FifthFieldWidth = FirstFieldWidth,
+ AlphaFieldWidth = FirstFieldWidth,
+ AlphaUsageFieldWidth = 1,
+ AlphaPositionFieldWidth = 1,
+ PremulFieldWidth = 1,
+ TypeInterpretationFieldWidth = 4,
+ ByteOrderFieldWidth = 2,
+ SubEnumFieldWidth = 6,
+ UnusedFieldWidth = 9,
+
+ TotalFieldWidthByWidths = ModelFieldWidth + FirstFieldWidth + SecondFieldWidth + ThirdFieldWidth +
+ FourthFieldWidth + FifthFieldWidth + AlphaFieldWidth + AlphaUsageFieldWidth +
+ AlphaPositionFieldWidth + PremulFieldWidth + TypeInterpretationFieldWidth +
+ ByteOrderFieldWidth + SubEnumFieldWidth + UnusedFieldWidth
+ };
+
+ enum Field {
+ ModelField = 0,
+ // work around bug in old clang versions: when building webkit
+ // with XCode 4.6 and older this fails compilation, thus cast to int
+ FirstField = ModelField + int(ModelFieldWidth),
+ SecondField = FirstField + FirstFieldWidth,
+ ThirdField = SecondField + SecondFieldWidth,
+ FourthField = ThirdField + ThirdFieldWidth,
+ FifthField = FourthField + FourthFieldWidth,
+ AlphaField = FifthField + FifthFieldWidth,
+ AlphaUsageField = AlphaField + AlphaFieldWidth,
+ AlphaPositionField = AlphaUsageField + AlphaUsageFieldWidth,
+ PremulField = AlphaPositionField + AlphaPositionFieldWidth,
+ TypeInterpretationField = PremulField + PremulFieldWidth,
+ ByteOrderField = TypeInterpretationField + TypeInterpretationFieldWidth,
+ SubEnumField = ByteOrderField + ByteOrderFieldWidth,
+ UnusedField = SubEnumField + SubEnumFieldWidth,
+
+ TotalFieldWidthByOffsets = UnusedField + UnusedFieldWidth
+ };
+
+ Q_STATIC_ASSERT(uint(TotalFieldWidthByWidths) == uint(TotalFieldWidthByOffsets));
+ Q_STATIC_ASSERT(uint(TotalFieldWidthByWidths) == 8 * sizeof(quint64));
+
+ Q_DECL_CONSTEXPR inline uchar get(Field offset, FieldWidth width) const Q_DECL_NOTHROW
+ { return uchar((data >> uint(offset)) & ((Q_UINT64_C(1) << uint(width)) - Q_UINT64_C(1))); }
+ Q_DECL_CONSTEXPR static inline quint64 set(Field offset, FieldWidth width, uchar value)
+ { return (quint64(value) & ((Q_UINT64_C(1) << uint(width)) - Q_UINT64_C(1))) << uint(offset); }
+
+public:
+ enum ColorModel {
+ RGB,
+ BGR,
+ Indexed,
+ Grayscale,
+ CMYK,
+ HSL,
+ HSV,
+ YUV
+ };
+
+ enum AlphaUsage {
+ UsesAlpha,
+ IgnoresAlpha
+ };
+
+ enum AlphaPosition {
+ AtBeginning,
+ AtEnd
+ };
+
+ enum AlphaPremultiplied {
+ NotPremultiplied,
+ Premultiplied
+ };
+
+ enum TypeInterpretation {
+ UnsignedInteger,
+ UnsignedShort,
+ UnsignedByte,
+ FloatingPoint
+ };
+
+ enum YUVLayout {
+ YUV444,
+ YUV422,
+ YUV411,
+ YUV420P,
+ YUV420SP,
+ YV12,
+ UYVY,
+ YUYV,
+ NV12,
+ NV21,
+ IMC1,
+ IMC2,
+ IMC3,
+ IMC4,
+ Y8,
+ Y16
+ };
+
+ enum ByteOrder {
+ LittleEndian,
+ BigEndian,
+ CurrentSystemEndian
+ };
+
+ Q_DECL_CONSTEXPR inline QPixelFormat() Q_DECL_NOTHROW : data(0) {}
+ Q_DECL_CONSTEXPR inline QPixelFormat(ColorModel colorModel,
+ uchar firstSize,
+ uchar secondSize,
+ uchar thirdSize,
+ uchar fourthSize,
+ uchar fifthSize,
+ uchar alphaSize,
+ AlphaUsage alphaUsage,
+ AlphaPosition alphaPosition,
+ AlphaPremultiplied premultiplied,
+ TypeInterpretation typeInterpretation,
+ ByteOrder byteOrder = CurrentSystemEndian,
+ uchar subEnum = 0) Q_DECL_NOTHROW;
+
+ Q_DECL_CONSTEXPR inline ColorModel colorModel() const Q_DECL_NOTHROW { return ColorModel(get(ModelField, ModelFieldWidth)); }
+ Q_DECL_CONSTEXPR inline uchar channelCount() const Q_DECL_NOTHROW { return (get(FirstField, FirstFieldWidth) > 0) +
+ (get(SecondField, SecondFieldWidth) > 0) +
+ (get(ThirdField, ThirdFieldWidth) > 0) +
+ (get(FourthField, FourthFieldWidth) > 0) +
+ (get(FifthField, FifthFieldWidth) > 0) +
+ (get(AlphaField, AlphaFieldWidth) > 0); }
+
+ Q_DECL_CONSTEXPR inline uchar redSize() const Q_DECL_NOTHROW { return get(FirstField, FirstFieldWidth); }
+ Q_DECL_CONSTEXPR inline uchar greenSize() const Q_DECL_NOTHROW { return get(SecondField, SecondFieldWidth); }
+ Q_DECL_CONSTEXPR inline uchar blueSize() const Q_DECL_NOTHROW { return get(ThirdField, ThirdFieldWidth); }
+
+ Q_DECL_CONSTEXPR inline uchar cyanSize() const Q_DECL_NOTHROW { return get(FirstField, FirstFieldWidth); }
+ Q_DECL_CONSTEXPR inline uchar magentaSize() const Q_DECL_NOTHROW { return get(SecondField, SecondFieldWidth); }
+ Q_DECL_CONSTEXPR inline uchar yellowSize() const Q_DECL_NOTHROW { return get(ThirdField, ThirdFieldWidth); }
+ Q_DECL_CONSTEXPR inline uchar blackSize() const Q_DECL_NOTHROW { return get(FourthField, FourthFieldWidth); }
+
+ Q_DECL_CONSTEXPR inline uchar hueSize() const Q_DECL_NOTHROW { return get(FirstField, FirstFieldWidth); }
+ Q_DECL_CONSTEXPR inline uchar saturationSize() const Q_DECL_NOTHROW { return get(SecondField, SecondFieldWidth); }
+ Q_DECL_CONSTEXPR inline uchar lightnessSize() const Q_DECL_NOTHROW { return get(ThirdField, ThirdFieldWidth); }
+ Q_DECL_CONSTEXPR inline uchar brightnessSize() const Q_DECL_NOTHROW { return get(ThirdField, ThirdFieldWidth); }
+
+ Q_DECL_CONSTEXPR inline uchar alphaSize() const Q_DECL_NOTHROW { return get(AlphaField, AlphaFieldWidth); }
+
+ Q_DECL_CONSTEXPR inline uchar bitsPerPixel() const Q_DECL_NOTHROW { return get(FirstField, FirstFieldWidth) +
+ get(SecondField, SecondFieldWidth) +
+ get(ThirdField, ThirdFieldWidth) +
+ get(FourthField, FourthFieldWidth) +
+ get(FifthField, FifthFieldWidth) +
+ get(AlphaField, AlphaFieldWidth); }
+
+ Q_DECL_CONSTEXPR inline AlphaUsage alphaUsage() const Q_DECL_NOTHROW { return AlphaUsage(get(AlphaUsageField, AlphaUsageFieldWidth)); }
+ Q_DECL_CONSTEXPR inline AlphaPosition alphaPosition() const Q_DECL_NOTHROW { return AlphaPosition(get(AlphaPositionField, AlphaPositionFieldWidth)); }
+ Q_DECL_CONSTEXPR inline AlphaPremultiplied premultiplied() const Q_DECL_NOTHROW { return AlphaPremultiplied(get(PremulField, PremulFieldWidth)); }
+ Q_DECL_CONSTEXPR inline TypeInterpretation typeInterpretation() const Q_DECL_NOTHROW { return TypeInterpretation(get(TypeInterpretationField, TypeInterpretationFieldWidth)); }
+ Q_DECL_CONSTEXPR inline ByteOrder byteOrder() const Q_DECL_NOTHROW { return ByteOrder(get(ByteOrderField, ByteOrderFieldWidth)); }
+
+ Q_DECL_CONSTEXPR inline YUVLayout yuvLayout() const Q_DECL_NOTHROW { return YUVLayout(get(SubEnumField, SubEnumFieldWidth)); }
+ Q_DECL_CONSTEXPR inline uchar subEnum() const Q_DECL_NOTHROW { return get(SubEnumField, SubEnumFieldWidth); }
+
+private:
+ Q_DECL_CONSTEXPR static inline ByteOrder resolveByteOrder(ByteOrder bo)
+ { return bo == CurrentSystemEndian ? Q_BYTE_ORDER == Q_LITTLE_ENDIAN ? LittleEndian : BigEndian : bo ; }
+
+private:
+ quint64 data;
+
+ friend Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator==(QPixelFormat fmt1, QPixelFormat fmt2)
+ { return fmt1.data == fmt2.data; }
+
+ friend Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator!=(QPixelFormat fmt1, QPixelFormat fmt2)
+ { return !(fmt1 == fmt2); }
+};
+Q_STATIC_ASSERT(sizeof(QPixelFormat) == sizeof(quint64));
+Q_DECLARE_TYPEINFO(QPixelFormat, Q_PRIMITIVE_TYPE);
+
+
+namespace QtPrivate {
+ QPixelFormat Q_GUI_EXPORT QPixelFormat_createYUV(QPixelFormat::YUVLayout yuvLayout,
+ uchar alphaSize,
+ QPixelFormat::AlphaUsage alphaUsage,
+ QPixelFormat::AlphaPosition alphaPosition,
+ QPixelFormat::AlphaPremultiplied premultiplied,
+ QPixelFormat::TypeInterpretation typeInterpretation,
+ QPixelFormat::ByteOrder byteOrder);
+}
+
+Q_DECL_CONSTEXPR
+QPixelFormat::QPixelFormat(ColorModel mdl,
+ uchar firstSize,
+ uchar secondSize,
+ uchar thirdSize,
+ uchar fourthSize,
+ uchar fifthSize,
+ uchar alfa,
+ AlphaUsage usage,
+ AlphaPosition position,
+ AlphaPremultiplied premult,
+ TypeInterpretation typeInterp,
+ ByteOrder b_order,
+ uchar s_enum) Q_DECL_NOTHROW
+ : data(set(ModelField, ModelFieldWidth, uchar(mdl)) |
+ set(FirstField, FirstFieldWidth, firstSize) |
+ set(SecondField, SecondFieldWidth, secondSize) |
+ set(ThirdField, ThirdFieldWidth, thirdSize) |
+ set(FourthField, FourthFieldWidth, fourthSize) |
+ set(FifthField, FifthFieldWidth, fifthSize) |
+ set(AlphaField, AlphaFieldWidth, alfa) |
+ set(AlphaUsageField, AlphaUsageFieldWidth, uchar(usage)) |
+ set(AlphaPositionField, AlphaPositionFieldWidth, uchar(position)) |
+ set(PremulField, PremulFieldWidth, uchar(premult)) |
+ set(TypeInterpretationField, TypeInterpretationFieldWidth, uchar(typeInterp)) |
+ set(ByteOrderField, ByteOrderFieldWidth, uchar(resolveByteOrder(b_order))) |
+ set(SubEnumField, SubEnumFieldWidth, s_enum) |
+ set(UnusedField, UnusedFieldWidth, 0))
+{
+}
+
+Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatRgba(uchar red,
+ uchar green,
+ uchar blue,
+ uchar alfa,
+ QPixelFormat::AlphaUsage usage,
+ QPixelFormat::AlphaPosition position,
+ QPixelFormat::AlphaPremultiplied pmul=QPixelFormat::NotPremultiplied,
+ QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) Q_DECL_NOTHROW
+{
+ return QPixelFormat(QPixelFormat::RGB,
+ red,
+ green,
+ blue,
+ 0,
+ 0,
+ alfa,
+ usage,
+ position,
+ pmul,
+ typeInt);
+}
+
+Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatGrayscale(uchar channelSize,
+ QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) Q_DECL_NOTHROW
+{
+ return QPixelFormat(QPixelFormat::Grayscale,
+ channelSize,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ QPixelFormat::IgnoresAlpha,
+ QPixelFormat::AtBeginning,
+ QPixelFormat::NotPremultiplied,
+ typeInt);
+}
+
+Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatCmyk(uchar channelSize,
+ uchar alfa=0,
+ QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
+ QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
+ QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedInteger) Q_DECL_NOTHROW
+{
+ return QPixelFormat(QPixelFormat::CMYK,
+ channelSize,
+ channelSize,
+ channelSize,
+ channelSize,
+ 0,
+ alfa,
+ usage,
+ position,
+ QPixelFormat::NotPremultiplied,
+ typeInt);
+}
+
+Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatHsl(uchar channelSize,
+ uchar alfa=0,
+ QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
+ QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
+ QPixelFormat::TypeInterpretation typeInt=QPixelFormat::FloatingPoint) Q_DECL_NOTHROW
+{
+ return QPixelFormat(QPixelFormat::HSL,
+ channelSize,
+ channelSize,
+ channelSize,
+ 0,
+ 0,
+ alfa,
+ usage,
+ position,
+ QPixelFormat::NotPremultiplied,
+ typeInt);
+}
+
+Q_DECL_CONSTEXPR inline QPixelFormat qPixelFormatHsv(uchar channelSize,
+ uchar alfa=0,
+ QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
+ QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
+ QPixelFormat::TypeInterpretation typeInt=QPixelFormat::FloatingPoint) Q_DECL_NOTHROW
+{
+ return QPixelFormat(QPixelFormat::HSV,
+ channelSize,
+ channelSize,
+ channelSize,
+ 0,
+ 0,
+ alfa,
+ usage,
+ position,
+ QPixelFormat::NotPremultiplied,
+ typeInt);
+}
+
+inline QPixelFormat qPixelFormatYuv(QPixelFormat::YUVLayout layout,
+ uchar alfa=0,
+ QPixelFormat::AlphaUsage usage=QPixelFormat::IgnoresAlpha,
+ QPixelFormat::AlphaPosition position=QPixelFormat::AtBeginning,
+ QPixelFormat::AlphaPremultiplied p_mul=QPixelFormat::NotPremultiplied,
+ QPixelFormat::TypeInterpretation typeInt=QPixelFormat::UnsignedByte,
+ QPixelFormat::ByteOrder b_order=QPixelFormat::LittleEndian)
+{
+ return QtPrivate::QPixelFormat_createYUV(layout,
+ alfa,
+ usage,
+ position,
+ p_mul,
+ typeInt,
+ b_order);
+}
+
+QT_END_NAMESPACE
+
+#endif //QPIXELFORMAT_H
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index da192a8e25..f20482a859 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -271,13 +271,32 @@ QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::Pix
}
#ifndef QT_NO_OPENGL
+/*!
+ Factory function for QPlatformOpenGLContext. The \a context parameter is a pointer to
+ the context for which a platform-specific context backend needs to be
+ created. Configuration settings like the format, share context and screen have to be
+ taken from this QOpenGLContext and the resulting platform context is expected to be
+ backed by a native context that fulfills these criteria.
+
+ If the context has native handles set, no new native context is expected to be created.
+ Instead, the provided handles have to be used. In this case the ownership of the handle
+ must not be taken and the platform implementation is not allowed to destroy the native
+ context. Configuration parameters like the format are also to be ignored. Instead, the
+ platform implementation is responsible for querying the configuriation from the provided
+ native context.
+
+ Returns a pointer to a QPlatformOpenGLContext instance or \c NULL if the context could
+ not be created.
+
+ \sa QOpenGLContext
+*/
QPlatformOpenGLContext *QPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
Q_UNUSED(context);
qWarning("This plugin does not support createPlatformOpenGLContext!");
return 0;
}
-#endif
+#endif // QT_NO_OPENGL
/*!
Factory function for QPlatformSharedGraphicsCache. This function will return 0 if the platform
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index b88f2a7e84..5731b4f56a 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -86,7 +86,7 @@ public:
virtual void setChecked(bool isChecked) = 0;
virtual void setShortcut(const QKeySequence& shortcut) = 0;
virtual void setEnabled(bool enabled) = 0;
-
+ virtual void setIconSize(int size) = 0;
virtual void setNativeContents(WId item) { Q_UNUSED(item); }
Q_SIGNALS:
@@ -98,6 +98,8 @@ class Q_GUI_EXPORT QPlatformMenu : public QObject
{
Q_OBJECT
public:
+ enum MenuType { DefaultMenu = 0, EditMenu };
+
virtual void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) = 0;
virtual void removeMenuItem(QPlatformMenuItem *menuItem) = 0;
virtual void syncMenuItem(QPlatformMenuItem *menuItem) = 0;
@@ -112,11 +114,17 @@ public:
virtual void setVisible(bool visible) = 0;
virtual void setMinimumWidth(int width) { Q_UNUSED(width); }
virtual void setFont(const QFont &font) { Q_UNUSED(font); }
+ virtual void setMenuType(MenuType type) { Q_UNUSED(type); }
virtual void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item)
{
+ showPopup(parentWindow, QRect(pos, QSize()), item);
+ }
+
+ virtual void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
+ {
Q_UNUSED(parentWindow);
- Q_UNUSED(pos);
+ Q_UNUSED(targetRect);
Q_UNUSED(item);
setVisible(true);
}
diff --git a/src/gui/kernel/qplatformnativeinterface.cpp b/src/gui/kernel/qplatformnativeinterface.cpp
index 6571a47849..2e5485f1c2 100644
--- a/src/gui/kernel/qplatformnativeinterface.cpp
+++ b/src/gui/kernel/qplatformnativeinterface.cpp
@@ -118,6 +118,12 @@ QPlatformNativeInterface::NativeResourceForBackingStoreFunction QPlatformNativeI
return 0;
}
+QFunctionPointer QPlatformNativeInterface::platformFunction(const QByteArray &function) const
+{
+ Q_UNUSED(function);
+ return Q_NULLPTR;
+}
+
/*!
Contains generic window properties that the platform may utilize.
*/
diff --git a/src/gui/kernel/qplatformnativeinterface.h b/src/gui/kernel/qplatformnativeinterface.h
index eaa24a9e55..58d13c4320 100644
--- a/src/gui/kernel/qplatformnativeinterface.h
+++ b/src/gui/kernel/qplatformnativeinterface.h
@@ -85,6 +85,8 @@ public:
virtual NativeResourceForWindowFunction nativeResourceFunctionForWindow(const QByteArray &resource);
virtual NativeResourceForBackingStoreFunction nativeResourceFunctionForBackingStore(const QByteArray &resource);
+ virtual QFunctionPointer platformFunction(const QByteArray &function) const;
+
virtual QVariantMap windowProperties(QPlatformWindow *window) const;
virtual QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
virtual QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index 6bf7915425..a7ff94ac4f 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -275,15 +275,6 @@ QPlatformScreen * QPlatformScreen::platformScreenForWindow(const QWindow *window
*/
/*!
- Implemented in subclasses to return a page flipper object for the screen, or 0 if the
- hardware does not support page flipping. The default implementation returns 0.
- */
-QPlatformScreenPageFlipper *QPlatformScreen::pageFlipper() const
-{
- return 0;
-}
-
-/*!
Reimplement this function in subclass to return the cursor of the screen.
The default implementation returns 0.
diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h
index 085a147e8d..151a6386d9 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -71,7 +71,6 @@ class QPlatformOpenGLContext;
class QPlatformScreenPrivate;
class QPlatformWindow;
class QPlatformCursor;
-class QPlatformScreenPageFlipper;
class QScreen;
class QSurfaceFormat;
@@ -115,7 +114,6 @@ public:
virtual QString name() const { return QString(); }
- virtual QPlatformScreenPageFlipper *pageFlipper() const;
virtual QPlatformCursor *cursor() const;
protected:
diff --git a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp b/src/gui/kernel/qplatformsystemtrayicon.cpp
index bc37f99210..bc37f99210 100644
--- a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp
+++ b/src/gui/kernel/qplatformsystemtrayicon.cpp
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index d3d3d3c222..d1b1106b28 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -508,7 +508,11 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
case MousePressAndHoldInterval:
return QVariant(800);
case MouseDoubleClickDistance:
- return QVariant(5);
+ {
+ bool ok = false;
+ int dist = qgetenv("QT_DBL_CLICK_DIST").toInt(&ok);
+ return QVariant(ok ? dist : 5);
+ }
}
return QVariant();
}
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index a2d14be0fb..ad2b4a2164 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -276,6 +276,7 @@ public:
virtual QPlatformMenuItem* createPlatformMenuItem() const;
virtual QPlatformMenu* createPlatformMenu() const;
virtual QPlatformMenuBar* createPlatformMenuBar() const;
+ virtual void showPlatformMenuBar() {}
virtual bool usePlatformNativeDialog(DialogType type) const;
virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index faaf418522..bb7b690992 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -474,6 +474,29 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString &
}
/*!
+ Helper function for finding the new screen for \a newGeometry in response to
+ a geometry changed event. Returns the new screen if the window was moved to
+ another virtual sibling. If the screen changes, the platform plugin should call
+ QWindowSystemInterface::handleWindowScreenChanged().
+ \note: The current screen will always be returned for child windows since
+ they should never signal screen changes.
+
+ \since 5.4
+ \sa QWindowSystemInterface::handleWindowScreenChanged()
+*/
+QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const
+{
+ QPlatformScreen *currentScreen = screen();
+ if (!parent() && !currentScreen->geometry().intersects(newGeometry)) {
+ Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
+ if (screen->geometry().intersects(newGeometry))
+ return screen;
+ }
+ }
+ return currentScreen;
+}
+
+/*!
Reimplement this method to set whether the window demands attention
(for example, by flashing the taskbar icon) depending on \a enabled.
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 39bd8324a0..8f0e5ff352 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -139,6 +139,7 @@ public:
protected:
static QString formatWindowTitle(const QString &title, const QString &separator);
+ QPlatformScreen *screenForGeometry(const QRect &newGeometry) const;
QScopedPointer<QPlatformWindowPrivate> d_ptr;
private:
diff --git a/src/gui/kernel/qrasterwindow.cpp b/src/gui/kernel/qrasterwindow.cpp
new file mode 100644
index 0000000000..5f4d707f86
--- /dev/null
+++ b/src/gui/kernel/qrasterwindow.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** This file is part of the QtGui module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and Digia. For licensing terms and
+ ** conditions see http://qt.digia.com/licensing. For further information
+ ** use the contact form at http://qt.digia.com/contact-us.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU Lesser
+ ** General Public License version 2.1 as published by the Free Software
+ ** Foundation and appearing in the file LICENSE.LGPL included in the
+ ** packaging of this file. Please review the following information to
+ ** ensure the GNU Lesser General Public License version 2.1 requirements
+ ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Digia gives you certain additional
+ ** rights. These rights are described in the Digia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3.0 as published by the Free Software
+ ** Foundation and appearing in the file LICENSE.GPL included in the
+ ** packaging of this file. Please review the following information to
+ ** ensure the GNU General Public License version 3.0 requirements will be
+ ** met: http://www.gnu.org/copyleft/gpl.html.
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include "qrasterwindow.h"
+
+#include <QtGui/private/qpaintdevicewindow_p.h>
+
+#include <QtGui/QBackingStore>
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QRasterWindow
+ \inmodule QtGui
+ \since 5.4
+ \brief QRasterWindow is a convenience class for using QPainter on a QWindow
+
+ QRasterWindow is a QWindow with a raster-based, non-OpenGL surface. On top of
+ the functionality offered by QWindow, QRasterWindow adds a virtual
+ paintEvent() function and the possibility to open a QPainter on itself. The
+ underlying paint engine will be the raster one, meaning that all drawing will
+ happen on the CPU. For performing accelerated, OpenGL-based drawing, use
+ QOpenGLWindow instead.
+
+ Internally the class is thin wrapper for QWindow and QBackingStore
+ and is very similar to the \l{Raster Window Example}{Raster Window
+ Example} that uses these classes directly.
+
+ \sa QPaintDeviceWindow::paintEvent(), QPaintDeviceWindow::update()
+*/
+
+class QRasterWindowPrivate : public QPaintDeviceWindowPrivate
+{
+ Q_DECLARE_PUBLIC(QRasterWindow)
+public:
+ void beginPaint(const QRegion &region) Q_DECL_OVERRIDE
+ {
+ Q_Q(QRasterWindow);
+ if (backingstore->size() != q->size()) {
+ backingstore->resize(q->size());
+ markWindowAsDirty();
+ }
+ backingstore->beginPaint(region);
+ }
+
+ void endPaint() Q_DECL_OVERRIDE
+ {
+ backingstore->endPaint();
+ }
+
+ void flush(const QRegion &region) Q_DECL_OVERRIDE
+ {
+ Q_Q(QRasterWindow);
+ backingstore->flush(region, q);
+ }
+
+ QScopedPointer<QBackingStore> backingstore;
+};
+
+/*!
+ Constructs a new QRasterWindow with \a parent.
+*/
+QRasterWindow::QRasterWindow(QWindow *parent)
+ : QPaintDeviceWindow(*(new QRasterWindowPrivate), parent)
+{
+ setSurfaceType(QSurface::RasterSurface);
+ d_func()->backingstore.reset(new QBackingStore(this));
+}
+
+/*!
+ \internal
+*/
+int QRasterWindow::metric(PaintDeviceMetric metric) const
+{
+ Q_D(const QRasterWindow);
+
+ switch (metric) {
+ case PdmDepth:
+ return d->backingstore->paintDevice()->depth();
+ case PdmDevicePixelRatio:
+ return d->backingstore->paintDevice()->devicePixelRatio();
+ default:
+ break;
+ }
+ return QPaintDeviceWindow::metric(metric);
+}
+
+/*!
+ \internal
+*/
+QPaintDevice *QRasterWindow::redirected(QPoint *) const
+{
+ Q_D(const QRasterWindow);
+ return d->backingstore->paintDevice();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qkeymapper_qpa.cpp b/src/gui/kernel/qrasterwindow.h
index 3966909db1..93e8421c6b 100644
--- a/src/gui/kernel/qkeymapper_qpa.cpp
+++ b/src/gui/kernel/qrasterwindow.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -39,44 +39,31 @@
**
****************************************************************************/
-#include "qkeymapper_p.h"
-#include <qdebug.h>
-#include <private/qevent_p.h>
-#include <private/qlocale_p.h>
-#include <private/qguiapplication_p.h>
-#include <qpa/qplatformintegration.h>
+#ifndef QRASTERWINDOW_H
+#define QRASTERWINDOW_H
-QT_BEGIN_NAMESPACE
+#include <QtGui/QPaintDeviceWindow>
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
+class QRasterWindowPrivate;
-QKeyMapperPrivate::QKeyMapperPrivate()
+class Q_GUI_EXPORT QRasterWindow : public QPaintDeviceWindow
{
- keyboardInputLocale = QLocale::system();
- keyboardInputDirection = keyboardInputLocale.textDirection();
-}
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QRasterWindow)
-QKeyMapperPrivate::~QKeyMapperPrivate()
-{
- // clearMappings();
-}
+public:
+ explicit QRasterWindow(QWindow *parent = 0);
-void QKeyMapperPrivate::clearMappings()
-{
-}
+protected:
+ int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
+ QPaintDevice *redirected(QPoint *) const Q_DECL_OVERRIDE;
-QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e)
-{
- QList<int> result = QGuiApplicationPrivate::platformIntegration()->possibleKeys(e);
- if (!result.isEmpty())
- return result;
-
- if (e->key() && (e->key() != Qt::Key_unknown))
- result << int(e->key() + e->modifiers());
- else if (!e->text().isEmpty())
- result << int(e->text().at(0).unicode() + e->modifiers());
- return result;
-}
+private:
+ Q_DISABLE_COPY(QRasterWindow)
+};
QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 70ee631fc8..90f48d4593 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -74,6 +74,16 @@ QScreen::QScreen(QPlatformScreen *screen)
{
}
+
+/*!
+ Destroys the screen.
+ */
+QScreen::~QScreen()
+{
+ if (qApp)
+ Q_EMIT qApp->screenRemoved(this);
+}
+
/*!
Get the platform screen handle.
*/
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index bdd5939657..4ee48ad5ad 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -69,11 +69,11 @@ class Q_GUI_EXPORT QScreen : public QObject
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(int depth READ depth CONSTANT)
Q_PROPERTY(QSize size READ size NOTIFY geometryChanged)
- Q_PROPERTY(QSize availableSize READ availableSize NOTIFY virtualGeometryChanged)
+ Q_PROPERTY(QSize availableSize READ availableSize NOTIFY availableGeometryChanged)
Q_PROPERTY(QSize virtualSize READ virtualSize NOTIFY virtualGeometryChanged)
Q_PROPERTY(QSize availableVirtualSize READ availableVirtualSize NOTIFY virtualGeometryChanged)
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
- Q_PROPERTY(QRect availableGeometry READ availableGeometry NOTIFY virtualGeometryChanged)
+ Q_PROPERTY(QRect availableGeometry READ availableGeometry NOTIFY availableGeometryChanged)
Q_PROPERTY(QRect virtualGeometry READ virtualGeometry NOTIFY virtualGeometryChanged)
Q_PROPERTY(QRect availableVirtualGeometry READ availableVirtualGeometry NOTIFY virtualGeometryChanged)
Q_PROPERTY(QSizeF physicalSize READ physicalSize NOTIFY physicalSizeChanged)
@@ -89,6 +89,7 @@ class Q_GUI_EXPORT QScreen : public QObject
Q_PROPERTY(qreal refreshRate READ refreshRate NOTIFY refreshRateChanged)
public:
+ ~QScreen();
QPlatformScreen *handle() const;
QString name() const;
@@ -141,6 +142,7 @@ public:
Q_SIGNALS:
void geometryChanged(const QRect &geometry);
+ void availableGeometryChanged(const QRect &geometry);
void physicalSizeChanged(const QSizeF &size);
void physicalDotsPerInchChanged(qreal dpi);
void logicalDotsPerInchChanged(qreal dpi);
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index 2b8e611dff..f077abc6a2 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -196,6 +196,9 @@ public:
/*!
Constructs a default initialized QSurfaceFormat.
+
+ \note By default OpenGL 2.0 is requested since this provides the highest
+ grade of portability between platforms and OpenGL implementations.
*/
QSurfaceFormat::QSurfaceFormat() : d(new QSurfaceFormatPrivate)
{
@@ -730,6 +733,43 @@ int QSurfaceFormat::swapInterval() const
return d->swapInterval;
}
+Q_GLOBAL_STATIC(QSurfaceFormat, qt_default_surface_format)
+
+/*!
+ Sets the global default surface \a format.
+
+ This format is used by default in QOpenGLContext, QWindow, QOpenGLWidget and
+ similar classes.
+
+ It can always be overridden on a per-instance basis by using the class in
+ question's own setFormat() function. However, it is often more convenient to
+ set the format for all windows once at the start of the application. It also
+ guarantees proper behavior in cases where shared contexts are required,
+ because settings the format via this function guarantees that all contexts
+ and surfaces, even the ones created internally by Qt, will use the same
+ format.
+
+ \since 5.4
+ \sa defaultFormat()
+ */
+void QSurfaceFormat::setDefaultFormat(const QSurfaceFormat &format)
+{
+ *qt_default_surface_format() = format;
+}
+
+/*!
+ Returns the global default surface format.
+
+ When setDefaultFormat() is not called, this is a default-constructed QSurfaceFormat.
+
+ \since 5.4
+ \sa setDefaultFormat()
+ */
+QSurfaceFormat QSurfaceFormat::defaultFormat()
+{
+ return *qt_default_surface_format();
+}
+
/*!
Returns \c true if all the options of the two QSurfaceFormat objects
\a a and \a b are equal.
diff --git a/src/gui/kernel/qsurfaceformat.h b/src/gui/kernel/qsurfaceformat.h
index 453beac5cd..05aba2f83c 100644
--- a/src/gui/kernel/qsurfaceformat.h
+++ b/src/gui/kernel/qsurfaceformat.h
@@ -138,6 +138,9 @@ public:
int swapInterval() const;
void setSwapInterval(int interval);
+ static void setDefaultFormat(const QSurfaceFormat &format);
+ static QSurfaceFormat defaultFormat();
+
private:
QSurfaceFormatPrivate *d;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 6724d68c95..2cf4f41126 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -156,9 +156,7 @@ QWindow::QWindow(QScreen *targetScreen)
, QSurface(QSurface::Window)
{
Q_D(QWindow);
- d->screen = targetScreen;
- if (!d->screen)
- d->screen = QGuiApplication::primaryScreen();
+ d->connectToScreen(targetScreen ? targetScreen : QGuiApplication::primaryScreen());
d->init();
}
@@ -178,10 +176,8 @@ QWindow::QWindow(QWindow *parent)
{
Q_D(QWindow);
d->parentWindow = parent;
- if (parent)
- d->screen = parent->screen();
- if (!d->screen)
- d->screen = QGuiApplication::primaryScreen();
+ if (!parent)
+ d->connectToScreen(QGuiApplication::primaryScreen());
d->init();
}
@@ -203,10 +199,8 @@ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent)
{
Q_D(QWindow);
d->parentWindow = parent;
- if (parent)
- d->screen = parent->screen();
- if (!d->screen)
- d->screen = QGuiApplication::primaryScreen();
+ if (!parent)
+ d->connectToScreen(QGuiApplication::primaryScreen());
d->init();
}
@@ -215,14 +209,8 @@ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent)
*/
QWindow::~QWindow()
{
- if (QGuiApplicationPrivate::focus_window == this)
- QGuiApplicationPrivate::focus_window = 0;
- if (QGuiApplicationPrivate::currentMouseWindow == this)
- QGuiApplicationPrivate::currentMouseWindow = 0;
- if (QGuiApplicationPrivate::tabletPressTarget == this)
- QGuiApplicationPrivate::tabletPressTarget = 0;
- QGuiApplicationPrivate::window_list.removeAll(this);
destroy();
+ QGuiApplicationPrivate::window_list.removeAll(this);
}
void QWindowPrivate::init()
@@ -231,12 +219,13 @@ void QWindowPrivate::init()
// If your application aborts here, you are probably creating a QWindow
// before the screen list is populated.
- if (!screen) {
+ if (!parentWindow && !topLevelScreen) {
qFatal("Cannot create window: no screens available");
exit(1);
}
- QObject::connect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*)));
QGuiApplicationPrivate::window_list.prepend(q);
+
+ requestedFormat = QSurfaceFormat::defaultFormat();
}
/*!
@@ -353,23 +342,57 @@ void QWindowPrivate::updateVisibility()
emit q->visibilityChanged(visibility);
}
-void QWindowPrivate::setScreen(QScreen *newScreen, bool recreate)
+inline bool QWindowPrivate::windowRecreationRequired(QScreen *newScreen) const
+{
+ Q_Q(const QWindow);
+ const QScreen *oldScreen = q->screen();
+ return oldScreen != newScreen && platformWindow
+ && !(oldScreen && oldScreen->virtualSiblings().contains(newScreen));
+}
+
+inline void QWindowPrivate::disconnectFromScreen()
+{
+ if (topLevelScreen) {
+ Q_Q(QWindow);
+ QObject::disconnect(topLevelScreen, &QObject::destroyed, q, &QWindow::screenDestroyed);
+ topLevelScreen = 0;
+ }
+}
+
+void QWindowPrivate::connectToScreen(QScreen *screen)
{
Q_Q(QWindow);
- if (newScreen != screen) {
- const bool shouldRecreate = recreate && platformWindow != 0
- && !(screen && screen->virtualSiblings().contains(newScreen));
+ disconnectFromScreen();
+ topLevelScreen = screen;
+ if (topLevelScreen)
+ QObject::connect(topLevelScreen, &QObject::destroyed, q, &QWindow::screenDestroyed);
+}
+
+void QWindowPrivate::emitScreenChangedRecursion(QScreen *newScreen)
+{
+ Q_Q(QWindow);
+ emit q->screenChanged(newScreen);
+ foreach (QObject *child, q->children()) {
+ if (child->isWindowType())
+ static_cast<QWindow *>(child)->d_func()->emitScreenChangedRecursion(newScreen);
+ }
+}
+
+void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
+{
+ Q_Q(QWindow);
+ if (parentWindow) {
+ qWarning() << this << Q_FUNC_INFO << '(' << newScreen << "): Attempt to set a screen on a child window.";
+ return;
+ }
+ if (newScreen != topLevelScreen) {
+ const bool shouldRecreate = recreate && windowRecreationRequired(newScreen);
if (shouldRecreate)
q->destroy();
- if (screen)
- q->disconnect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*)));
- screen = newScreen;
- if (newScreen) {
- q->connect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*)));
- if (shouldRecreate)
- create(true);
- }
- emit q->screenChanged(newScreen);
+ connectToScreen(newScreen);
+ if (newScreen && shouldRecreate)
+ create(true);
+ emitScreenChangedRecursion(newScreen);
}
}
@@ -455,11 +478,14 @@ void QWindow::setVisible(bool visible)
QCoreApplication::removePostedEvents(qApp, QEvent::Quit);
if (type() == Qt::Window) {
- QString &firstWindowTitle = QGuiApplicationPrivate::instance()->firstWindowTitle;
+ QGuiApplicationPrivate *app_priv = QGuiApplicationPrivate::instance();
+ QString &firstWindowTitle = app_priv->firstWindowTitle;
if (!firstWindowTitle.isEmpty()) {
setTitle(firstWindowTitle);
firstWindowTitle = QString();
}
+ if (!app_priv->forcedWindowIcon.isNull())
+ setIcon(app_priv->forcedWindowIcon);
}
QShowEvent showEvent;
@@ -557,8 +583,20 @@ QWindow *QWindow::parent() const
void QWindow::setParent(QWindow *parent)
{
Q_D(QWindow);
+ if (d->parentWindow == parent)
+ return;
+
+ QScreen *newScreen = parent ? parent->screen() : screen();
+ if (d->windowRecreationRequired(newScreen)) {
+ qWarning() << this << Q_FUNC_INFO << '(' << parent << "): Cannot change screens (" << screen() << newScreen << ')';
+ return;
+ }
QObject::setParent(parent);
+ if (parent)
+ d->disconnectFromScreen();
+ else
+ d->connectToScreen(newScreen);
if (d->platformWindow) {
if (parent && parent->d_func()->platformWindow) {
@@ -644,7 +682,13 @@ void QWindow::setModality(Qt::WindowModality modality)
this function after create() has been called will not re-resolve the
surface format of the native surface.
- \sa create(), destroy()
+ When the format is not explicitly set via this function, the format returned
+ by QSurfaceFormat::defaultFormat() will be used. This means that when having
+ multiple windows, individual calls to this function can be replaced by one
+ single call to QSurfaceFormat::setDefaultFormat() before creating the first
+ window.
+
+ \sa create(), destroy(), QSurfaceFormat::setDefaultFormat()
*/
void QWindow::setFormat(const QSurfaceFormat &format)
{
@@ -1532,21 +1576,36 @@ void QWindow::resize(const QSize &newSize)
void QWindow::destroy()
{
Q_D(QWindow);
+ if (!d->platformWindow)
+ return;
+
QObjectList childrenWindows = children();
for (int i = 0; i < childrenWindows.size(); i++) {
QObject *object = childrenWindows.at(i);
if (object->isWindowType()) {
QWindow *w = static_cast<QWindow*>(object);
- QGuiApplicationPrivate::window_list.removeAll(w);
w->destroy();
}
}
+
+ if (QGuiApplicationPrivate::focus_window == this)
+ QGuiApplicationPrivate::focus_window = parent();
+ if (QGuiApplicationPrivate::currentMouseWindow == this)
+ QGuiApplicationPrivate::currentMouseWindow = parent();
+ if (QGuiApplicationPrivate::tabletPressTarget == this)
+ QGuiApplicationPrivate::tabletPressTarget = parent();
+
+ bool wasVisible = isVisible();
+
setVisible(false);
delete d->platformWindow;
d->resizeEventPending = true;
d->receivedExpose = false;
d->exposed = false;
d->platformWindow = 0;
+
+ if (wasVisible)
+ d->maybeQuitOnLastWindowClosed();
}
/*!
@@ -1613,15 +1672,14 @@ bool QWindow::setMouseGrabEnabled(bool grab)
/*!
Returns the screen on which the window is shown.
- The value returned will not change when the window is moved
- between virtual screens (as returned by QScreen::virtualSiblings()).
+ For child windows, this returns the screen of the corresponding top level window.
\sa setScreen(), QScreen::virtualSiblings()
*/
QScreen *QWindow::screen() const
{
Q_D(const QWindow);
- return d->screen;
+ return d->parentWindow ? d->parentWindow->screen() : d->topLevelScreen;
}
/*!
@@ -1632,6 +1690,8 @@ QScreen *QWindow::screen() const
Note that if the screen is part of a virtual desktop of multiple screens,
the window can appear on any of the screens returned by QScreen::virtualSiblings().
+ This function only works for top level windows.
+
\sa screen(), QScreen::virtualSiblings()
*/
void QWindow::setScreen(QScreen *newScreen)
@@ -1639,13 +1699,15 @@ void QWindow::setScreen(QScreen *newScreen)
Q_D(QWindow);
if (!newScreen)
newScreen = QGuiApplication::primaryScreen();
- d->setScreen(newScreen, true /* recreate */);
+ d->setTopLevelScreen(newScreen, true /* recreate */);
}
void QWindow::screenDestroyed(QObject *object)
{
Q_D(QWindow);
- if (object == static_cast<QObject *>(d->screen)) {
+ if (d->parentWindow)
+ return;
+ if (object == static_cast<QObject *>(d->topLevelScreen)) {
const bool wasVisible = isVisible();
setScreen(0);
// destroy() might have hidden our window, show it again.
@@ -1801,15 +1863,13 @@ bool QWindow::close()
if (parent())
return false;
- if (QGuiApplicationPrivate::focus_window == this)
- QGuiApplicationPrivate::focus_window = 0;
- if (QGuiApplicationPrivate::currentMouseWindow == this)
- QGuiApplicationPrivate::currentMouseWindow = 0;
+ if (!d->platformWindow)
+ return true;
- QGuiApplicationPrivate::window_list.removeAll(this);
- destroy();
- d->maybeQuitOnLastWindowClosed();
- return true;
+ bool accepted = false;
+ QWindowSystemInterface::handleCloseEvent(this, &accepted);
+ QWindowSystemInterface::flushWindowSystemEvents();
+ return accepted;
}
/*!
@@ -1955,15 +2015,10 @@ bool QWindow::event(QEvent *ev)
break;
#endif
- case QEvent::Close: {
- Q_D(QWindow);
- bool wasVisible = isVisible();
- if (ev->isAccepted()) {
+ case QEvent::Close:
+ if (ev->isAccepted())
destroy();
- if (wasVisible)
- d->maybeQuitOnLastWindowClosed();
- }
- break; }
+ break;
case QEvent::Expose:
exposeEvent(static_cast<QExposeEvent *>(ev));
@@ -2175,8 +2230,10 @@ Q_GUI_EXPORT QWindowPrivate *qt_window_private(QWindow *window)
void QWindowPrivate::maybeQuitOnLastWindowClosed()
{
- Q_Q(QWindow);
+ if (!QCoreApplication::instance())
+ return;
+ Q_Q(QWindow);
// Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent
bool quitOnClose = QGuiApplication::quitOnLastWindowClosed() && !q->parent();
@@ -2335,7 +2392,7 @@ void QWindowPrivate::setCursor(const QCursor *newCursor)
hasCursor = false;
}
// Only attempt to set cursor and emit signal if there is an actual platform cursor
- if (screen->handle()->cursor()) {
+ if (q->screen()->handle()->cursor()) {
applyCursor();
QEvent event(QEvent::CursorChange);
QGuiApplication::sendEvent(q, &event);
@@ -2346,7 +2403,7 @@ void QWindowPrivate::applyCursor()
{
Q_Q(QWindow);
if (platformWindow) {
- if (QPlatformCursor *platformCursor = screen->handle()->cursor()) {
+ if (QPlatformCursor *platformCursor = q->screen()->handle()->cursor()) {
QCursor *c = QGuiApplication::overrideCursor();
if (!c && hasCursor)
c = &cursor;
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 51d78bb9cd..cd789a6b71 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -95,11 +95,12 @@ public:
, modality(Qt::NonModal)
, blockedByModalWindow(false)
, transientParent(0)
- , screen(0)
+ , topLevelScreen(0)
#ifndef QT_NO_CURSOR
, cursor(Qt::ArrowCursor)
, hasCursor(false)
#endif
+ , compositing(false)
{
isWindow = true;
}
@@ -131,8 +132,12 @@ public:
void updateVisibility();
void _q_clearAlert();
- void setScreen(QScreen *newScreen, bool recreate);
+ bool windowRecreationRequired(QScreen *newScreen) const;
void create(bool recursive);
+ void setTopLevelScreen(QScreen *newScreen, bool recreate);
+ void connectToScreen(QScreen *topLevelScreen);
+ void disconnectFromScreen();
+ void emitScreenChangedRecursion(QScreen *newScreen);
virtual void clearFocusObject();
@@ -166,12 +171,14 @@ public:
bool blockedByModalWindow;
QPointer<QWindow> transientParent;
- QScreen *screen;
+ QScreen *topLevelScreen;
#ifndef QT_NO_CURSOR
QCursor cursor;
bool hasCursor;
#endif
+
+ bool compositing;
};
diff --git a/src/gui/kernel/qwindowdefs_win.h b/src/gui/kernel/qwindowdefs_win.h
index fea995a0f5..0dd027e585 100644
--- a/src/gui/kernel/qwindowdefs_win.h
+++ b/src/gui/kernel/qwindowdefs_win.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -107,7 +107,7 @@ Q_DECLARE_HANDLE(HRGN);
#ifndef HMONITOR
Q_DECLARE_HANDLE(HMONITOR);
#endif
-#ifndef HRESULT
+#ifndef _HRESULT_DEFINED
typedef long HRESULT;
#endif
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 49ff8bcb0d..59766d0bb2 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -133,11 +133,11 @@ void QWindowSystemInterface::handleWindowScreenChanged(QWindow *tlw, QScreen *sc
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState newState)
+void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate)
{
Q_ASSERT(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState));
QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *e =
- new QWindowSystemInterfacePrivate::ApplicationStateChangedEvent(newState);
+ new QWindowSystemInterfacePrivate::ApplicationStateChangedEvent(newState, forcePropagate);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -493,17 +493,10 @@ void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry)
+void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry)
{
QWindowSystemInterfacePrivate::ScreenGeometryEvent *e =
- new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
-}
-
-void QWindowSystemInterface::handleScreenAvailableGeometryChange(QScreen *screen, const QRect &availableGeometry)
-{
- QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e =
- new QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent(screen, availableGeometry);
+ new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry, availableGeometry);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -629,24 +622,42 @@ void QWindowSystemInterface::handleFileOpenEvent(const QUrl &url)
QGuiApplicationPrivate::processWindowSystemEvent(&e);
}
-void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
- int device, int pointerType, qreal pressure, int xTilt, int yTilt,
+void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, const QPointF &local, const QPointF &global,
+ int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z, qint64 uid,
Qt::KeyboardModifiers modifiers)
{
QWindowSystemInterfacePrivate::TabletEvent *e =
- new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, down, local, global, device, pointerType, pressure,
+ new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, local, global, device, pointerType, buttons, pressure,
xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
+void QWindowSystemInterface::handleTabletEvent(QWindow *w, const QPointF &local, const QPointF &global,
+ int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z, qint64 uid,
+ Qt::KeyboardModifiers modifiers)
+{
+ ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+ handleTabletEvent(w, time, local, global, device, pointerType, buttons, pressure,
+ xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
+}
+
+void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
+ int device, int pointerType, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z, qint64 uid,
+ Qt::KeyboardModifiers modifiers)
+{
+ handleTabletEvent(w, timestamp, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure,
+ xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
+}
+
void QWindowSystemInterface::handleTabletEvent(QWindow *w, bool down, const QPointF &local, const QPointF &global,
int device, int pointerType, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z, qint64 uid,
Qt::KeyboardModifiers modifiers)
{
- ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleTabletEvent(w, time, down, local, global, device, pointerType, pressure,
+ handleTabletEvent(w, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure,
xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
}
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 71feb1bcb7..c681185c35 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -138,6 +138,7 @@ public:
static void handleTouchCancelEvent(QWindow *w, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
static void handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier);
+ // rect is relative to parent
static void handleGeometryChange(QWindow *w, const QRect &newRect, const QRect &oldRect = QRect());
static void handleCloseEvent(QWindow *w, bool *accepted = 0);
static void handleEnterEvent(QWindow *w, const QPointF &local = QPointF(), const QPointF& global = QPointF());
@@ -148,8 +149,9 @@ public:
static void handleWindowStateChanged(QWindow *w, Qt::WindowState newState);
static void handleWindowScreenChanged(QWindow *w, QScreen *newScreen);
- static void handleApplicationStateChanged(Qt::ApplicationState newState);
+ static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
+ // region is in local coordinates, do not confuse with geometry which is parent-relative
static void handleExposeEvent(QWindow *tlw, const QRegion &region);
#ifndef QT_NO_DRAGANDDROP
@@ -162,8 +164,7 @@ public:
// Changes to the screen
static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation);
- static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry);
- static void handleScreenAvailableGeometryChange(QScreen *screen, const QRect &newAvailableGeometry);
+ static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry, const QRect &newAvailableGeometry);
static void handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal newDpiX, qreal newDpiY);
static void handleScreenRefreshRateChange(QScreen *screen, qreal newRefreshRate);
@@ -172,14 +173,22 @@ public:
static void handleFileOpenEvent(const QString& fileName);
static void handleFileOpenEvent(const QUrl &url);
+ static void handleTabletEvent(QWindow *w, ulong timestamp, const QPointF &local, const QPointF &global,
+ int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z, qint64 uid,
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ static void handleTabletEvent(QWindow *w, const QPointF &local, const QPointF &global,
+ int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
+ qreal tangentialPressure, qreal rotation, int z, qint64 uid,
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier);
static void handleTabletEvent(QWindow *w, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
int device, int pointerType, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z, qint64 uid,
- Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier); // ### remove in Qt 6
static void handleTabletEvent(QWindow *w, bool down, const QPointF &local, const QPointF &global,
int device, int pointerType, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z, qint64 uid,
- Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier); // ### remove in Qt 6
static void handleTabletEnterProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid);
static void handleTabletEnterProximityEvent(int device, int pointerType, qint64 uid);
static void handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid);
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 8e503bbf3d..87f40e2b04 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -176,11 +176,12 @@ public:
class ApplicationStateChangedEvent : public WindowSystemEvent {
public:
- ApplicationStateChangedEvent(Qt::ApplicationState newState)
- : WindowSystemEvent(ApplicationStateChanged), newState(newState)
+ ApplicationStateChangedEvent(Qt::ApplicationState newState, bool forcePropagate = false)
+ : WindowSystemEvent(ApplicationStateChanged), newState(newState), forcePropagate(forcePropagate)
{ }
Qt::ApplicationState newState;
+ bool forcePropagate;
};
class FlushEventsEvent : public WindowSystemEvent {
@@ -278,17 +279,10 @@ public:
class ScreenGeometryEvent : public WindowSystemEvent {
public:
- ScreenGeometryEvent(QScreen *s, const QRect &g)
- : WindowSystemEvent(ScreenGeometry), screen(s), geometry(g) { }
+ ScreenGeometryEvent(QScreen *s, const QRect &g, const QRect &ag)
+ : WindowSystemEvent(ScreenGeometry), screen(s), geometry(g), availableGeometry(ag) { }
QPointer<QScreen> screen;
QRect geometry;
- };
-
- class ScreenAvailableGeometryEvent : public WindowSystemEvent {
- public:
- ScreenAvailableGeometryEvent(QScreen *s, const QRect &g)
- : WindowSystemEvent(ScreenAvailableGeometry), screen(s), availableGeometry(g) { }
- QPointer<QScreen> screen;
QRect availableGeometry;
};
@@ -337,19 +331,19 @@ public:
class TabletEvent : public InputEvent {
public:
- static void handleTabletEvent(QWindow *w, bool down, const QPointF &local, const QPointF &global,
- int device, int pointerType, qreal pressure, int xTilt, int yTilt,
+ static void handleTabletEvent(QWindow *w, const QPointF &local, const QPointF &global,
+ int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z, qint64 uid,
Qt::KeyboardModifiers modifiers = Qt::NoModifier);
- TabletEvent(QWindow *w, ulong time, bool down, const QPointF &local, const QPointF &global,
- int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tpressure,
+ TabletEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global,
+ int device, int pointerType, Qt::MouseButtons b, qreal pressure, int xTilt, int yTilt, qreal tpressure,
qreal rotation, int z, qint64 uid, Qt::KeyboardModifiers mods)
: InputEvent(w, time, Tablet, mods),
- down(down), local(local), global(global), device(device), pointerType(pointerType),
+ buttons(b), local(local), global(global), device(device), pointerType(pointerType),
pressure(pressure), xTilt(xTilt), yTilt(yTilt), tangentialPressure(tpressure),
rotation(rotation), z(z), uid(uid) { }
- bool down;
+ Qt::MouseButtons buttons;
QPointF local;
QPointF global;
int device;