summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorThierry Bastian <thierry.bastian@nokia.com>2011-03-24 09:27:07 (GMT)
committerThierry Bastian <thierry.bastian@nokia.com>2011-03-24 09:27:07 (GMT)
commitce80b75964ba5b1071112eb9bc04977da8079b23 (patch)
treee6fc4154aecc3581b9720d2f4482e97f3ecb3f49 /src/gui
parentfdeeaa9d61efea9cca783a1d4098ae505df24390 (diff)
parent295fbcba490712fe6e6f61926836920366134b55 (diff)
downloadQt-ce80b75964ba5b1071112eb9bc04977da8079b23.zip
Qt-ce80b75964ba5b1071112eb9bc04977da8079b23.tar.gz
Qt-ce80b75964ba5b1071112eb9bc04977da8079b23.tar.bz2
Merge branch 'master-upstream'
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp12
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h3
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h6
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp28
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h1
-rw-r--r--src/gui/gui.pro4
-rw-r--r--src/gui/image/image.pri3
-rw-r--r--src/gui/image/qnativeimagehandleprovider_p.h69
-rw-r--r--src/gui/image/qpixmap.cpp28
-rw-r--r--src/gui/image/qpixmap_blitter.cpp2
-rw-r--r--src/gui/image/qpixmap_blitter_p.h2
-rw-r--r--src/gui/image/qpixmap_s60.cpp31
-rw-r--r--src/gui/image/qpixmapdata_p.h3
-rw-r--r--src/gui/image/qpnghandler.cpp67
-rw-r--r--src/gui/image/qvolatileimagedata.cpp1
-rw-r--r--src/gui/image/qvolatileimagedata_symbian.cpp3
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h11
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp251
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp5
-rw-r--r--src/gui/itemviews/qabstractitemview.h2
-rw-r--r--src/gui/kernel/kernel.pri6
-rw-r--r--src/gui/kernel/qapplication_p.h2
-rw-r--r--src/gui/kernel/qapplication_qpa.cpp11
-rw-r--r--src/gui/kernel/qapplication_s60.cpp124
-rw-r--r--src/gui/kernel/qclipboard_win.cpp15
-rw-r--r--src/gui/kernel/qcocoaintrospection_mac.mm2
-rw-r--r--src/gui/kernel/qcocoaintrospection_p.h2
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h16
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm111
-rw-r--r--src/gui/kernel/qcocoawindowdelegate_mac.mm21
-rw-r--r--src/gui/kernel/qdesktopwidget_qpa_p.h2
-rw-r--r--src/gui/kernel/qdesktopwidget_s60.cpp164
-rw-r--r--src/gui/kernel/qevent.cpp1
-rw-r--r--src/gui/kernel/qeventdispatcher_glib_qpa.cpp2
-rw-r--r--src/gui/kernel/qeventdispatcher_glib_qpa_p.h2
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa.cpp3
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa_p.h2
-rw-r--r--src/gui/kernel/qplatformclipboard_qpa.cpp6
-rw-r--r--src/gui/kernel/qplatformclipboard_qpa.h5
-rw-r--r--src/gui/kernel/qplatformcursor_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformeventloopintegration_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformeventloopintegration_qpa.h2
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.h2
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.cpp22
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.h14
-rw-r--r--src/gui/kernel/qplatformintegrationfactory_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformintegrationfactory_qpa_p.h2
-rw-r--r--src/gui/kernel/qplatformintegrationplugin_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformintegrationplugin_qpa.h2
-rw-r--r--src/gui/kernel/qplatformnativeinterface_qpa.cpp53
-rw-r--r--src/gui/kernel/qplatformnativeinterface_qpa.h65
-rw-r--r--src/gui/kernel/qplatformscreen_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformscreen_qpa.h2
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.h2
-rw-r--r--src/gui/kernel/qplatformwindowformat_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformwindowformat_qpa.h2
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm24
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h32
-rw-r--r--src/gui/kernel/qt_s60_p.h89
-rw-r--r--src/gui/kernel/qwidget.cpp57
-rw-r--r--src/gui/kernel/qwidget_mac.mm6
-rw-r--r--src/gui/kernel/qwidget_p.h20
-rw-r--r--src/gui/kernel/qwidget_s60.cpp57
-rw-r--r--src/gui/kernel/qwidget_x11.cpp10
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.cpp32
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.h13
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa_p.h12
-rw-r--r--src/gui/math3d/qvector2d.cpp5
-rw-r--r--src/gui/math3d/qvector3d.cpp5
-rw-r--r--src/gui/math3d/qvector4d.cpp5
-rw-r--r--src/gui/painting/painting.pri12
-rw-r--r--src/gui/painting/qbackingstore.cpp5
-rw-r--r--src/gui/painting/qbackingstore_p.h3
-rw-r--r--src/gui/painting/qblittable.cpp2
-rw-r--r--src/gui/painting/qblittable_p.h2
-rw-r--r--src/gui/painting/qgraphicssystem_runtime.cpp15
-rw-r--r--src/gui/painting/qgraphicssystem_runtime_p.h3
-rw-r--r--src/gui/painting/qgraphicssystemfactory.cpp2
-rw-r--r--src/gui/painting/qpaintengine_blitter.cpp2
-rw-r--r--src/gui/painting/qpaintengine_blitter_p.h2
-rw-r--r--src/gui/painting/qpainterpath.cpp8
-rw-r--r--src/gui/painting/qprintengine_pdf.cpp2
-rw-r--r--src/gui/painting/qprinterinfo_p.h2
-rw-r--r--src/gui/painting/qunifiedtoolbarsurface_mac.cpp131
-rw-r--r--src/gui/painting/qunifiedtoolbarsurface_mac_p.h15
-rw-r--r--src/gui/painting/qwindowsurface.cpp28
-rw-r--r--src/gui/painting/qwindowsurface_p.h6
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp56
-rw-r--r--src/gui/painting/qwindowsurface_raster_p.h12
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp35
-rw-r--r--src/gui/painting/qwindowsurface_s60_p.h2
-rw-r--r--src/gui/painting/qwindowsurface_x11.cpp12
-rw-r--r--src/gui/painting/qwindowsurface_x11_p.h1
-rw-r--r--src/gui/styles/qmacstyle_mac.mm2
-rw-r--r--src/gui/styles/qs60style.cpp58
-rw-r--r--src/gui/styles/qs60style_p.h12
-rw-r--r--src/gui/styles/qs60style_s60.cpp46
-rw-r--r--src/gui/styles/qs60style_simulated.cpp2
-rw-r--r--src/gui/text/qfont.cpp102
-rw-r--r--src/gui/text/qfont.h43
-rw-r--r--src/gui/text/qfont_p.h7
-rw-r--r--src/gui/text/qfont_qpa.cpp2
-rw-r--r--src/gui/text/qfontdatabase.cpp21
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp2
-rw-r--r--src/gui/text/qfontdatabase_win.cpp220
-rw-r--r--src/gui/text/qfontengine_coretext.mm22
-rw-r--r--src/gui/text/qfontengine_coretext_p.h2
-rw-r--r--src/gui/text/qfontengine_mac_p.h2
-rw-r--r--src/gui/text/qfontengine_p.h2
-rw-r--r--src/gui/text/qfontengine_qpa.cpp2
-rw-r--r--src/gui/text/qfontengine_qpa_p.h2
-rw-r--r--src/gui/text/qfontengine_win.cpp2
-rw-r--r--src/gui/text/qfontengine_win_p.h2
-rw-r--r--src/gui/text/qfontenginedirectwrite.cpp641
-rw-r--r--src/gui/text/qfontenginedirectwrite_p.h133
-rw-r--r--src/gui/text/qglyphs.cpp2
-rw-r--r--src/gui/text/qglyphs.h2
-rw-r--r--src/gui/text/qglyphs_p.h2
-rw-r--r--src/gui/text/qplatformfontdatabase_qpa.cpp4
-rw-r--r--src/gui/text/qplatformfontdatabase_qpa.h2
-rw-r--r--src/gui/text/qtextcontrol.cpp11
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp2
-rw-r--r--src/gui/text/qtextformat.cpp22
-rw-r--r--src/gui/text/qtextformat.h11
-rw-r--r--src/gui/text/qtextlayout.cpp47
-rw-r--r--src/gui/text/qtextobject.cpp2
-rw-r--r--src/gui/text/text.pri6
-rw-r--r--src/gui/util/qflickgesture.cpp46
-rw-r--r--src/gui/util/qflickgesture_p.h2
-rw-r--r--src/gui/util/qscroller.cpp35
-rw-r--r--src/gui/util/qscroller.h8
-rw-r--r--src/gui/util/qscroller_mac.mm8
-rw-r--r--src/gui/util/qscroller_p.h11
-rw-r--r--src/gui/util/qscrollerproperties.cpp2
-rw-r--r--src/gui/util/qscrollerproperties.h2
-rw-r--r--src/gui/util/qscrollerproperties_p.h2
-rw-r--r--src/gui/util/qsystemtrayicon_win.cpp1
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp2
-rw-r--r--src/gui/widgets/qcombobox.cpp2
-rw-r--r--src/gui/widgets/qlinecontrol.cpp6
-rw-r--r--src/gui/widgets/qmainwindow.cpp13
-rw-r--r--src/gui/widgets/qmainwindowlayout.cpp4
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm6
-rw-r--r--src/gui/widgets/qmainwindowlayout_p.h4
-rw-r--r--src/gui/widgets/qsplashscreen.cpp4
147 files changed, 2992 insertions, 544 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index ecc8941..0af36ac 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -417,6 +417,11 @@
click focus to items underneath when being clicked on. This flag
allows you create a non-focusable item that can be clicked on without
changing the focus. \endomit
+
+ \omitvalue ItemStopsFocusHandling \omit Same as
+ ItemStopsClickFocusPropagation, but also suppresses focus-out. This flag
+ allows you to completely take over focus handling.
+ This flag was introduced in Qt 4.7.
*/
/*!
@@ -5577,8 +5582,10 @@ void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *s
parent->d_ptr->subFocusItemChange();
} while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
- if (scene && !scene->isActive())
+ if (scene && !scene->isActive()) {
+ scene->d_func()->passiveFocusItem = subFocusItem;
scene->d_func()->lastFocusItem = subFocusItem;
+ }
}
/*!
@@ -11555,6 +11562,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
case QGraphicsItem::ItemStopsClickFocusPropagation:
str = "ItemStopsClickFocusPropagation";
break;
+ case QGraphicsItem::ItemStopsFocusHandling:
+ str = "ItemStopsFocusHandling";
+ break;
}
debug << str;
return debug;
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index e59a7c9..67c9cd3 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -107,7 +107,8 @@ public:
ItemIsPanel = 0x4000,
ItemIsFocusScope = 0x8000, // internal
ItemSendsScenePositionChanges = 0x10000,
- ItemStopsClickFocusPropagation = 0x20000
+ ItemStopsClickFocusPropagation = 0x20000,
+ ItemStopsFocusHandling = 0x40000
// NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
};
Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 5c82116..90ff43f 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -559,7 +559,7 @@ public:
quint32 dirtyChildrenBoundingRect : 1;
// Packed 32 bits
- quint32 flags : 18;
+ quint32 flags : 19;
quint32 paintedViewBoundingRectsNeedRepaint : 1;
quint32 dirtySceneTransform : 1;
quint32 geometryChanged : 1;
@@ -573,9 +573,9 @@ public:
quint32 sceneTransformTranslateOnly : 1;
quint32 notifyBoundingRectChanged : 1;
quint32 notifyInvalidated : 1;
- quint32 mouseSetsFocus : 1;
// New 32 bits
+ quint32 mouseSetsFocus : 1;
quint32 explicitActivate : 1;
quint32 wantsActive : 1;
quint32 holesInSiblingIndex : 1;
@@ -586,7 +586,7 @@ public:
quint32 mayHaveChildWithGraphicsEffect : 1;
quint32 isDeclarativeItem : 1;
quint32 sendParentChangeNotification : 1;
- quint32 padding : 22;
+ quint32 padding : 21;
// Optional stacking order
int globalStackingOrder;
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 77ccc8e..7932a73 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -306,6 +306,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
rectAdjust(2),
focusItem(0),
lastFocusItem(0),
+ passiveFocusItem(0),
tabFocusFirst(0),
activePanel(0),
lastActivePanel(0),
@@ -630,6 +631,8 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
focusItem = 0;
if (item == lastFocusItem)
lastFocusItem = 0;
+ if (item == passiveFocusItem)
+ passiveFocusItem = 0;
if (item == activePanel) {
// ### deactivate...
activePanel = 0;
@@ -1317,8 +1320,10 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou
// Set focus on the topmost enabled item that can take focus.
bool setFocus = false;
+
foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
- if (item->isBlockedByModalPanel()) {
+ if (item->isBlockedByModalPanel()
+ || (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling)) {
// Make sure we don't clear focus.
setFocus = true;
break;
@@ -1331,10 +1336,10 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou
break;
}
}
- if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
- break;
if (item->isPanel())
break;
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
+ break;
}
// Check for scene modality.
@@ -2980,7 +2985,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
QGraphicsItem *QGraphicsScene::focusItem() const
{
Q_D(const QGraphicsScene);
- return isActive() ? d->focusItem : d->lastFocusItem;
+ return isActive() ? d->focusItem : d->passiveFocusItem;
}
/*!
@@ -3054,6 +3059,7 @@ void QGraphicsScene::clearFocus()
Q_D(QGraphicsScene);
if (d->hasFocus) {
d->hasFocus = false;
+ d->passiveFocusItem = d->focusItem;
setFocusItem(0, Qt::OtherFocusReason);
}
}
@@ -3757,9 +3763,9 @@ void QGraphicsScene::focusInEvent(QFocusEvent *focusEvent)
focusEvent->ignore();
break;
default:
- if (d->lastFocusItem) {
+ if (d->passiveFocusItem) {
// Set focus on the last focus item
- setFocusItem(d->lastFocusItem, focusEvent->reason());
+ setFocusItem(d->passiveFocusItem, focusEvent->reason());
}
break;
}
@@ -3778,6 +3784,7 @@ void QGraphicsScene::focusOutEvent(QFocusEvent *focusEvent)
{
Q_D(QGraphicsScene);
d->hasFocus = false;
+ d->passiveFocusItem = d->focusItem;
setFocusItem(0, focusEvent->reason());
// Remove all popups when the scene loses focus.
@@ -5908,6 +5915,7 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
// Set focus on the topmost enabled item that can take focus.
bool setFocus = false;
+
foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
@@ -5921,6 +5929,11 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
break;
if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
break;
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling) {
+ // Make sure we don't clear focus.
+ setFocus = true;
+ break;
+ }
}
// If nobody could take focus, clear it.
@@ -5953,7 +5966,8 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
}
if (item && item->isPanel())
break;
- if (item && (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation))
+ if (item && (item->d_ptr->flags
+ & (QGraphicsItem::ItemStopsClickFocusPropagation | QGraphicsItem::ItemStopsFocusHandling)))
break;
}
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 2314e37..9460a4d 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -150,6 +150,7 @@ public:
quint32 rectAdjust;
QGraphicsItem *focusItem;
QGraphicsItem *lastFocusItem;
+ QGraphicsItem *passiveFocusItem;
QGraphicsWidget *tabFocusFirst;
QGraphicsItem *activePanel;
QGraphicsItem *lastActivePanel;
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 076fe0a..fda76a2 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -79,6 +79,10 @@ neon:*-g++* {
QMAKE_EXTRA_COMPILERS += neon_compiler
}
+win32:!contains(QT_CONFIG, directwrite) {
+ DEFINES += QT_NO_DIRECTWRITE
+}
+
contains(QMAKE_MAC_XARCH, no) {
DEFINES += QT_NO_MAC_XARCH
} else {
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index a5e37f3..72738c9 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -31,7 +31,8 @@ HEADERS += \
image/qpixmapfilter_p.h \
image/qimagepixmapcleanuphooks_p.h \
image/qvolatileimage_p.h \
- image/qvolatileimagedata_p.h
+ image/qvolatileimagedata_p.h \
+ image/qnativeimagehandleprovider_p.h
SOURCES += \
image/qbitmap.cpp \
diff --git a/src/gui/image/qnativeimagehandleprovider_p.h b/src/gui/image/qnativeimagehandleprovider_p.h
new file mode 100644
index 0000000..4e6ed38
--- /dev/null
+++ b/src/gui/image/qnativeimagehandleprovider_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNATIVEIMAGEHANDLEPROVIDER_P_H
+#define QNATIVEIMAGEHANDLEPROVIDER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNativeImageHandleProvider
+{
+public:
+ virtual void get(void **handle, QString *type) = 0;
+ virtual void release(void *handle, const QString &type) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QNATIVEIMAGEHANDLEPROVIDER_P_H
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 6e13324..34804e5 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -71,6 +71,10 @@
# include "private/qpixmap_mac_p.h"
#endif
+#ifdef Q_WS_QPA
+# include "qplatformintegration_qpa.h"
+#endif
+
#if defined(Q_WS_X11)
# include "qx11info_x11.h"
# include <private/qt_x11_p.h>
@@ -98,12 +102,26 @@ static bool qt_pixmap_thread_test()
qFatal("QPixmap: Must construct a QApplication before a QPaintDevice");
return false;
}
-#ifndef Q_WS_WIN
- if (!QApplication::testAttribute(Qt::AA_X11InitThreads) && qApp->thread() != QThread::currentThread()) {
- qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread");
- return false;
- }
+
+ if (qApp->thread() != QThread::currentThread()) {
+ bool fail = false;
+#if defined (Q_WS_X11)
+ if (!QApplication::testAttribute(Qt::AA_X11InitThreads))
+ fail = true;
+#elif defined (Q_WS_QPA)
+ if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps)) {
+ printf("Lighthouse plugin does not support threaded pixmaps!\n");
+ fail = true;
+ }
+#else
+ if (QApplicationPrivate::graphics_system_name != QLatin1String("raster"))
+ fail = true;
#endif
+ if (fail) {
+ qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread");
+ return false;
+ }
+ }
return true;
}
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index e8a7b89..26d3b87 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h
index 55b5618..9f4260c 100644
--- a/src/gui/image/qpixmap_blitter_p.h
+++ b/src/gui/image/qpixmap_blitter_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index ca5f133..32d8dd7 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -374,6 +374,8 @@ CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
To be sure that QPixmap does not modify your original instance, you should
make a copy of your \c CFbsBitmap before calling this function.
If the CFbsBitmap is not valid this function will return a null QPixmap.
+ For performance reasons it is recommended to use a \a bitmap with a display
+ mode of EColor16MAP or EColor16MU whenever possible.
\warning This function is only available on Symbian OS.
@@ -599,6 +601,9 @@ bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect)
return res;
}
+Q_GUI_EXPORT int qt_defaultDpiX();
+Q_GUI_EXPORT int qt_defaultDpiY();
+
int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
{
if (!cfbsBitmap)
@@ -609,28 +614,18 @@ int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
return cfbsBitmap->SizeInPixels().iWidth;
case QPaintDevice::PdmHeight:
return cfbsBitmap->SizeInPixels().iHeight;
- case QPaintDevice::PdmWidthMM: {
- TInt twips = cfbsBitmap->SizeInTwips().iWidth;
- return (int)(twips * (25.4/KTwipsPerInch));
- }
- case QPaintDevice::PdmHeightMM: {
- TInt twips = cfbsBitmap->SizeInTwips().iHeight;
- return (int)(twips * (25.4/KTwipsPerInch));
- }
+ case QPaintDevice::PdmWidthMM:
+ return qRound(cfbsBitmap->SizeInPixels().iWidth * 25.4 / qt_defaultDpiX());
+ case QPaintDevice::PdmHeightMM:
+ return qRound(cfbsBitmap->SizeInPixels().iHeight * 25.4 / qt_defaultDpiY());
case QPaintDevice::PdmNumColors:
return TDisplayModeUtils::NumDisplayModeColors(cfbsBitmap->DisplayMode());
case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX: {
- TReal inches = cfbsBitmap->SizeInTwips().iWidth / (TReal)KTwipsPerInch;
- TInt pixels = cfbsBitmap->SizeInPixels().iWidth;
- return pixels / inches;
- }
+ case QPaintDevice::PdmPhysicalDpiX:
+ return qt_defaultDpiX();
case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY: {
- TReal inches = cfbsBitmap->SizeInTwips().iHeight / (TReal)KTwipsPerInch;
- TInt pixels = cfbsBitmap->SizeInPixels().iHeight;
- return pixels / inches;
- }
+ case QPaintDevice::PdmPhysicalDpiY:
+ return qt_defaultDpiY();
case QPaintDevice::PdmDepth:
return TDisplayModeUtils::NumDisplayModeBitsPerPixel(cfbsBitmap->DisplayMode());
default:
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index db5ff4a..6bbce09 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -72,7 +72,8 @@ public:
enum NativeType {
FbsBitmap,
SgImage,
- VolatileImage
+ VolatileImage,
+ NativeImageHandleProvider
};
#endif
enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass,
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index a9aad51..d88c437 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -109,6 +109,7 @@ public:
bool readPngHeader();
bool readPngImage(QImage *image);
+ void readPngTexts(png_info *info);
QImage::Format readImageFormat();
@@ -359,6 +360,39 @@ static void CALLBACK_CALL_TYPE qt_png_warning(png_structp /*png_ptr*/, png_const
}
#endif
+
+/*!
+ \internal
+*/
+void Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngTexts(png_info *info)
+{
+#ifndef QT_NO_IMAGE_TEXT
+ png_textp text_ptr;
+ int num_text=0;
+ png_get_text(png_ptr, info, &text_ptr, &num_text);
+
+ while (num_text--) {
+ QString key, value;
+ key = QString::fromLatin1(text_ptr->key);
+#if defined(PNG_iTXt_SUPPORTED)
+ if (text_ptr->itxt_length) {
+ value = QString::fromUtf8(text_ptr->text, int(text_ptr->itxt_length));
+ } else
+#endif
+ {
+ value = QString::fromLatin1(text_ptr->text, int(text_ptr->text_length));
+ }
+ if (!description.isEmpty())
+ description += QLatin1String("\n\n");
+ description += key + QLatin1String(": ") + value.simplified();
+ readTexts.append(key);
+ readTexts.append(value);
+ text_ptr++;
+ }
+#endif
+}
+
+
/*!
\internal
*/
@@ -394,30 +428,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngHeader()
png_set_read_fn(png_ptr, this, iod_read_fn);
png_read_info(png_ptr, info_ptr);
-#ifndef QT_NO_IMAGE_TEXT
- png_textp text_ptr;
- int num_text=0;
- png_get_text(png_ptr,info_ptr,&text_ptr,&num_text);
-
- while (num_text--) {
- QString key, value;
- key = QString::fromLatin1(text_ptr->key);
-#if defined(PNG_iTXt_SUPPORTED)
- if (text_ptr->itxt_length) {
- value = QString::fromUtf8(text_ptr->text, int(text_ptr->itxt_length));
- } else
-#endif
- {
- value = QString::fromLatin1(QByteArray(text_ptr->text, int(text_ptr->text_length)));
- }
- if (!description.isEmpty())
- description += QLatin1String("\n\n");
- description += key + QLatin1String(": ") + value.simplified();
- readTexts.append(key);
- readTexts.append(value);
- text_ptr++;
- }
-#endif
+ readPngTexts(info_ptr);
state = ReadHeader;
return true;
@@ -492,11 +503,15 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage)
outImage->setDotsPerMeterX(png_get_x_pixels_per_meter(png_ptr,info_ptr));
outImage->setDotsPerMeterY(png_get_y_pixels_per_meter(png_ptr,info_ptr));
+ state = ReadingEnd;
+ png_read_end(png_ptr, end_info);
+
+#ifndef QT_NO_IMAGE_TEXT
+ readPngTexts(end_info);
for (int i = 0; i < readTexts.size()-1; i+=2)
outImage->setText(readTexts.at(i), readTexts.at(i+1));
+#endif
- state = ReadingEnd;
- png_read_end(png_ptr, end_info);
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
delete [] row_pointers;
png_ptr = 0;
diff --git a/src/gui/image/qvolatileimagedata.cpp b/src/gui/image/qvolatileimagedata.cpp
index 51b5995..d7b964c 100644
--- a/src/gui/image/qvolatileimagedata.cpp
+++ b/src/gui/image/qvolatileimagedata.cpp
@@ -68,6 +68,7 @@ QVolatileImageData::QVolatileImageData(void *, void *)
}
QVolatileImageData::QVolatileImageData(const QVolatileImageData &other)
+ : QSharedData()
{
image = other.image;
// The detach is not mandatory here but we do it nonetheless in order to
diff --git a/src/gui/image/qvolatileimagedata_symbian.cpp b/src/gui/image/qvolatileimagedata_symbian.cpp
index 474d0ef..6e2909b 100644
--- a/src/gui/image/qvolatileimagedata_symbian.cpp
+++ b/src/gui/image/qvolatileimagedata_symbian.cpp
@@ -392,6 +392,9 @@ void QVolatileImageData::initWithBitmap(CFbsBitmap *source)
} else if (needsCopy) {
// Rasterize extended and compressed bitmaps.
bitmap = rasterizeBitmap(source, EColor16MAP);
+ } else if (source->DisplayMode() == EGray2) {
+ // The pixels will be inverted, must make a copy.
+ bitmap = rasterizeBitmap(source, source->DisplayMode());
} else {
// Efficient path: no pixel data copying. Just duplicate. This of course
// means the original bitmap's data may get modified, but that's fine
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 8c8ffd4..de3577f 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -93,6 +93,9 @@ public:
TCoeInputCapabilities inputCapabilities();
+ void resetSplitViewWidget(bool keepInputWidget = false);
+ void ensureFocusWidgetVisible(QWidget *widget);
+
protected:
void timerEvent(QTimerEvent *timerEvent);
@@ -104,9 +107,11 @@ private:
void queueInputCapabilitiesChanged();
bool needsInputPanel();
void commitTemporaryPreeditString();
+ bool isWidgetVisible(QWidget *widget, int offset = 0);
private Q_SLOTS:
void ensureInputCapabilitiesChanged();
+ void translateInputWidget();
// From MCoeFepAwareTextEditor
public:
@@ -155,9 +160,15 @@ private:
QBasicTimer m_tempPreeditStringTimeout;
bool m_hasTempPreeditString;
+ int m_splitViewResizeBy;
+ Qt::WindowStates m_splitViewPreviousWindowStates;
+ QRectF m_transformation;
+
friend class tst_QInputContext;
};
+Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable);
+
QT_END_NAMESPACE
#endif // QT_NO_IM
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 1bef64d..9d8dd41 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -48,6 +48,8 @@
#include <qgraphicsscene.h>
#include <qgraphicswidget.h>
#include <qsymbianevent.h>
+#include <qlayout.h>
+#include <qdesktopwidget.h>
#include <private/qcore_symbian_p.h>
#include <fepitfr.h>
@@ -67,8 +69,16 @@
// that support text selection.
#define QT_EAknEditorFlagSelectionVisible 0x100000
+// EAknEditorFlagEnablePartialScreen is only valid from Sym^3 onwards.
+#define QT_EAknEditorFlagEnablePartialScreen 0x200000
+
QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable)
+{
+ S60->partial_keyboard = enable;
+}
+
QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
: QInputContext(parent),
m_fepState(q_check_ptr(new CAknEdwinState)), // CBase derived object needs check on new
@@ -80,13 +90,19 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_inlinePosition(0),
m_formatRetriever(0),
m_pointerHandler(0),
- m_hasTempPreeditString(false)
+ m_hasTempPreeditString(false),
+ m_splitViewResizeBy(0),
+ m_splitViewPreviousWindowStates(Qt::WindowNoState)
{
m_fepState->SetObjectProvider(this);
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
- m_fepState->SetFlags(EAknEditorFlagDefault | QT_EAknEditorFlagSelectionVisible);
- else
- m_fepState->SetFlags(EAknEditorFlagDefault);
+ int defaultFlags = EAknEditorFlagDefault;
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ if (S60->partial_keyboard) {
+ defaultFlags |= QT_EAknEditorFlagEnablePartialScreen;
+ }
+ defaultFlags |= QT_EAknEditorFlagSelectionVisible;
+ }
+ m_fepState->SetFlags(defaultFlags);
m_fepState->SetDefaultInputMode( EAknEditorTextInputMode );
m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
m_fepState->SetDefaultCase( EAknEditorTextCase );
@@ -210,6 +226,21 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
return false;
switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ // Alphanumeric keypad doesn't like it when we click and text is still getting displayed
+ // It ignores the mouse event, so we need to commit and send a selection event (which will get triggered
+ // after the commit)
+ if (!m_preeditString.isEmpty()) {
+ commitCurrentString(false);
+
+ int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
+
+ QList<QInputMethodEvent::Attribute> selectAttributes;
+ selectAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, 0, QVariant());
+ QInputMethodEvent selectEvent(QLatin1String(""), selectAttributes);
+ sendEvent(selectEvent);
+ }
+ break;
case QEvent::KeyPress:
commitTemporaryPreeditString();
// fall through intended
@@ -343,6 +374,165 @@ TCoeInputCapabilities QCoeFepInputContext::inputCapabilities()
return TCoeInputCapabilities(m_textCapabilities, this, 0);
}
+void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
+{
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
+
+ if (!gv) {
+ return;
+ }
+
+ QSymbianControl *symControl = static_cast<QSymbianControl*>(gv->effectiveWinId());
+ symControl->CancelLongTapTimer();
+
+ const bool alwaysResize = (gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
+ QWidget *windowToMove = gv->window();
+
+ bool userResize = gv->testAttribute(Qt::WA_Resized);
+
+ windowToMove->setUpdatesEnabled(false);
+
+ if (!alwaysResize) {
+ if (gv->scene()) {
+ if (gv->scene()->focusItem())
+ disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ QGraphicsItem *rootItem;
+ foreach (QGraphicsItem *item, gv->scene()->items()) {
+ if (!item->parentItem()) {
+ rootItem = item;
+ break;
+ }
+ }
+ if (rootItem)
+ rootItem->resetTransform();
+ }
+ } else {
+ if (m_splitViewResizeBy)
+ gv->resize(gv->rect().width(), m_splitViewResizeBy);
+ }
+ // Resizing might have led to widget losing its original windowstate.
+ // Restore previous window state.
+
+ if (m_splitViewPreviousWindowStates != windowToMove->windowState())
+ windowToMove->setWindowState(m_splitViewPreviousWindowStates);
+
+ windowToMove->setUpdatesEnabled(true);
+
+ gv->setAttribute(Qt::WA_Resized, userResize); //not a user resize
+
+ m_splitViewResizeBy = 0;
+ if (!keepInputWidget) {
+ m_splitViewPreviousWindowStates = Qt::WindowNoState;
+ S60->splitViewLastWidget = 0;
+ }
+}
+
+// Checks if a given widget is visible in the splitview rect. The offset
+// parameter can be used to validate if moving widget upwards or downwards
+// by the offset would make a difference for the visibility.
+
+bool QCoeFepInputContext::isWidgetVisible(QWidget *widget, int offset)
+{
+ bool visible = false;
+ if (widget) {
+ QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+ QWidget *window = QApplication::activeWindow();
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
+ if (gv && window) {
+ if (QGraphicsScene *scene = gv->scene()) {
+ if (QGraphicsItem *focusItem = scene->focusItem()) {
+ QPoint cursorPos = window->mapToGlobal(focusItem->cursor().pos());
+ cursorPos.setY(cursorPos.y() + offset);
+ if (splitViewRect.contains(cursorPos)) {
+ visible = true;
+ }
+ }
+ }
+ }
+ }
+ return visible;
+}
+
+// Ensure that the input widget is visible in the splitview rect.
+
+void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
+{
+ // Native side opening and closing its virtual keyboard when it changes the keyboard layout,
+ // has an adverse impact on long tap timer. Cancel the timer when splitview opens to avoid this.
+ QSymbianControl *symControl = static_cast<QSymbianControl*>(widget->effectiveWinId());
+ symControl->CancelLongTapTimer();
+
+ // Graphicsviews that have vertical scrollbars should always be resized to the splitview area.
+ // Graphicsviews without scrollbars should be translated.
+
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
+ if (!gv)
+ return;
+
+ const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
+ const bool moveWithinVisibleArea = (S60->splitViewLastWidget != 0);
+
+ QWidget *windowToMove = gv ? gv : symControl->widget();
+ if (!windowToMove->isWindow())
+ windowToMove = windowToMove->window();
+ if (!windowToMove) {
+ return;
+ }
+
+ // When opening the keyboard (not moving within the splitview area), save the original
+ // window state. In some cases, ensuring input widget visibility might lead to window
+ // states getting changed.
+
+ if (!moveWithinVisibleArea) {
+ S60->splitViewLastWidget = widget;
+ m_splitViewPreviousWindowStates = windowToMove->windowState();
+ }
+
+ int windowTop = widget->window()->pos().y();
+
+ const bool userResize = widget->testAttribute(Qt::WA_Resized);
+
+ QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+
+
+ // When resizing a window widget, it will lose its maximized window state.
+ // Native applications hide statuspane in splitview state, so lets move to
+ // fullscreen mode. This makes available area slightly bigger, which helps usability
+ // and greatly reduces event passing in orientation switch cases,
+ // as the statuspane size is not changing.
+
+ if (!(windowToMove->windowState() & Qt::WindowFullScreen)) {
+ windowToMove->setWindowState(
+ (windowToMove->windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowFullScreen);
+ }
+
+ if (alwaysResize) {
+ windowToMove->setUpdatesEnabled(false);
+ if (!moveWithinVisibleArea)
+ m_splitViewResizeBy = widget->height();
+
+ windowTop = widget->geometry().top();
+ widget->resize(widget->width(), splitViewRect.height() - windowTop);
+
+ if (gv->scene()) {
+ const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
+ gv->ensureVisible(microFocusRect);
+ }
+ windowToMove->setUpdatesEnabled(true);
+ } else {
+ if (!moveWithinVisibleArea) {
+ // Check if the widget contains cursorPositionChanged signal and connect to it.
+ const char *signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged())).constData();
+ int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal + 1);
+ if (index != -1)
+ connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ }
+ translateInputWidget();
+ }
+
+ widget->setAttribute(Qt::WA_Resized, userResize); //not a user resize
+}
+
static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat, bool validStyleColor)
{
QTextCharFormat qFormat;
@@ -474,10 +664,12 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
m_fepState->SetPermittedCases(flags);
ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate);
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
- flags = QT_EAknEditorFlagSelectionVisible;
- else
- flags = 0;
+ flags = 0;
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ if (S60->partial_keyboard)
+ flags |= QT_EAknEditorFlagEnablePartialScreen;
+ flags |= QT_EAknEditorFlagSelectionVisible;
+ }
if (hints & ImhUppercaseOnly && !(hints & ImhLowercaseOnly)
|| hints & ImhLowercaseOnly && !(hints & ImhUppercaseOnly)) {
flags |= EAknEditorFlagFixedCase;
@@ -604,6 +796,47 @@ void QCoeFepInputContext::ensureInputCapabilitiesChanged()
m_pendingInputCapabilitiesChanged = false;
}
+void QCoeFepInputContext::translateInputWidget()
+{
+ QGraphicsView *gv = qobject_cast<QGraphicsView *>(S60->splitViewLastWidget);
+ QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+
+ QRectF cursor = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
+ QPolygon cursorP = gv->mapFromScene(cursor);
+ QRectF vkbRect = QRectF(splitViewRect.bottomLeft(), qApp->desktop()->rect().bottomRight());
+ if (cursor.isEmpty() || vkbRect.isEmpty())
+ return;
+
+ // Fetch root item (i.e. graphicsitem with no parent)
+ QGraphicsItem *rootItem;
+ foreach (QGraphicsItem *item, gv->scene()->items()) {
+ if (!item->parentItem()) {
+ rootItem = item;
+ break;
+ }
+ }
+ if (!rootItem)
+ return;
+
+ m_transformation = (rootItem->transform().isTranslating()) ? QRectF(0,0, gv->width(), rootItem->transform().dy()) : QRectF();
+
+ // Do nothing if the cursor is visible in the splitview area.
+ if (splitViewRect.contains(cursorP.boundingRect()))
+ return;
+
+ // New Y position should be ideally at the center of the splitview area.
+ // If that would expose unpainted canvas, limit the tranformation to the visible scene bottom.
+
+ const qreal maxY = gv->sceneRect().bottom() - splitViewRect.bottom() + m_transformation.height();
+ qreal dy = -(qMin(maxY, (cursor.bottom() - vkbRect.top() / 2)));
+
+ // Do not allow transform above screen top.
+ if (m_transformation.height() + dy > 0)
+ return;
+
+ rootItem->setTransform(QTransform::fromTranslate(0, dy), true);
+}
+
void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* /*aCustomDraw*/,
MFepInlineTextFormatRetriever& aInlineTextFormatRetriever,
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 291ec6e..d671496 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -194,6 +194,8 @@ void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index
}
}
+#ifndef QT_NO_GESTURES
+
// stores and restores the selection and current item when flicking
void QAbstractItemViewPrivate::_q_scrollerStateChanged()
{
@@ -225,6 +227,7 @@ void QAbstractItemViewPrivate::_q_scrollerStateChanged()
}
}
+#endif // QT_NO_GESTURES
/*!
\class QAbstractItemView
@@ -1661,7 +1664,9 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
break;
case QEvent::ScrollPrepare:
executeDelayedItemsLayout();
+#ifndef QT_NO_GESTURES
connect(QScroller::scroller(d->viewport), SIGNAL(stateChanged(QScroller::State)), this, SLOT(_q_scrollerStateChanged()), Qt::UniqueConnection);
+#endif
break;
default:
diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h
index 20cfb87..f11f209 100644
--- a/src/gui/itemviews/qabstractitemview.h
+++ b/src/gui/itemviews/qabstractitemview.h
@@ -359,7 +359,9 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged())
+#ifndef QT_NO_GESTURES
Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged())
+#endif
friend class QTreeViewPrivate; // needed to compile with MSVC
friend class QAccessibleItemRow;
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 0ff3d88..32fa3d3 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -223,7 +223,8 @@ qpa {
kernel/qdesktopwidget_qpa_p.h \
kernel/qplatformeventloopintegration_qpa.h \
kernel/qplatformcursor_qpa.h \
- kernel/qplatformclipboard_qpa.h
+ kernel/qplatformclipboard_qpa.h \
+ kernel/qplatformnativeinterface_qpa.h
SOURCES += \
kernel/qapplication_qpa.cpp \
@@ -246,7 +247,8 @@ qpa {
kernel/qplatformeventloopintegration_qpa.cpp \
kernel/qplatformglcontext_qpa.cpp \
kernel/qplatformcursor_qpa.cpp \
- kernel/qplatformclipboard_qpa.cpp
+ kernel/qplatformclipboard_qpa.cpp \
+ kernel/qplatformnativeinterface_qpa.cpp
contains(QT_CONFIG, glib) {
SOURCES += \
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index a6815a8..954c6de 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -639,6 +639,8 @@ public:
int pressureSupported;
int maxTouchPressure;
QList<QTouchEvent::TouchPoint> appAllTouchPoints;
+
+ bool useTranslucentEGLSurfaces;
#endif
private:
diff --git a/src/gui/kernel/qapplication_qpa.cpp b/src/gui/kernel/qapplication_qpa.cpp
index cd76adf..cb5439c 100644
--- a/src/gui/kernel/qapplication_qpa.cpp
+++ b/src/gui/kernel/qapplication_qpa.cpp
@@ -51,6 +51,7 @@
#endif
#include "private/qwidget_p.h"
+#include "private/qevent_p.h"
#include "qgenericpluginfactory_qpa.h"
#include "qplatformintegrationfactory_qpa_p.h"
@@ -816,8 +817,14 @@ void QApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEven
if (app_do_modal && !qt_try_modal(focusW, e->keyType))
return;
- QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
- QApplication::sendSpontaneousEvent(focusW, &ev);
+ if (e->nativeScanCode || e->nativeVirtualKey || e->nativeModifiers) {
+ QKeyEventEx ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount,
+ e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers);
+ QApplication::sendSpontaneousEvent(focusW, &ev);
+ } else {
+ QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
+ QApplication::sendSpontaneousEvent(focusW, &ev);
+ }
}
void QApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 586869a..3d642d0 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -96,6 +96,9 @@ QT_BEGIN_NAMESPACE
// Goom Events through Window Server
static const int KGoomMemoryLowEvent = 0x10282DBF;
static const int KGoomMemoryGoodEvent = 0x20026790;
+// Split view open/close events from AVKON
+static const int KSplitViewOpenEvent = 0x2001E2C0;
+static const int KSplitViewCloseEvent = 0x2001E2C1;
#if defined(QT_DEBUG)
static bool appNoGrab = false; // Grabbing enabled
@@ -401,6 +404,7 @@ QSymbianControl::QSymbianControl(QWidget *w)
, m_longTapDetector(0)
, m_ignoreFocusChanged(0)
, m_symbianPopupIsOpen(0)
+ , m_inExternalScreenOverride(false)
{
}
@@ -408,9 +412,11 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
{
if (!desktop)
{
- if (isWindowOwning || !qwidget->parentWidget())
- CreateWindowL(S60->windowGroup());
- else
+ if (isWindowOwning || !qwidget->parentWidget()
+ || qwidget->parentWidget()->windowType() == Qt::Desktop) {
+ RWindowGroup &wg(S60->windowGroup(qwidget));
+ CreateWindowL(wg);
+ } else {
/**
* TODO: in order to avoid creating windows for all ancestors of
* this widget up to the root window, the parameter passed to
@@ -420,6 +426,7 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
* is created for a widget between this one and the root window.
*/
CreateWindowL(qwidget->parentWidget()->winId());
+ }
// Necessary in order to be able to track the activation status of
// the control's window
@@ -452,7 +459,7 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
windowPurpose = ETfxPurposeSplashScreenWindow;
break;
default:
- windowPurpose = (isWindowOwning || !qwidget->parentWidget())
+ windowPurpose = (isWindowOwning || !qwidget->parentWidget() || qwidget->parentWidget()->windowType() == Qt::Desktop)
? ETfxPurposeWindow : ETfxPurposeChildWindow;
break;
}
@@ -983,14 +990,15 @@ TKeyResponse QSymbianControl::handleVirtualMouse(const TKeyEvent& keyEvent,TEven
}
}
//clip to screen size (window server allows a sprite hotspot to be outside the screen)
+ int screenNumber = S60->screenNumberForWidget(qwidget);
if (x < 0)
x = 0;
- else if (x >= S60->screenWidthInPixels)
- x = S60->screenWidthInPixels - 1;
+ else if (x >= S60->screenWidthInPixelsForScreen[screenNumber])
+ x = S60->screenWidthInPixelsForScreen[screenNumber] - 1;
if (y < 0)
y = 0;
- else if (y >= S60->screenHeightInPixels)
- y = S60->screenHeightInPixels - 1;
+ else if (y >= S60->screenHeightInPixelsForScreen[screenNumber])
+ y = S60->screenHeightInPixelsForScreen[screenNumber] - 1;
TPoint epos(x, y);
TPoint cpos = epos - PositionRelativeToScreen();
fakeEvent.iPosition = cpos;
@@ -1124,7 +1132,8 @@ void QSymbianControl::Draw(const TRect& controlRect) const
// Do nothing
break;
case QWExtra::Blit:
- if (qwidget->d_func()->isOpaque)
+ case QWExtra::BlitWriteAlpha:
+ if (qwidget->d_func()->isOpaque || nativePaintMode == QWExtra::BlitWriteAlpha)
gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
break;
@@ -1167,6 +1176,18 @@ void QSymbianControl::SizeChanged()
QSize newSize(Size().iWidth, Size().iHeight);
if (oldSize != newSize) {
+ const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
+ const int screenNumber = S60->screenNumberForWidget(qwidget);
+ if (!m_inExternalScreenOverride && isFullscreen && screenNumber > 0) {
+ int screenWidth = S60->screenWidthInPixelsForScreen[screenNumber];
+ int screenHeight = S60->screenHeightInPixelsForScreen[screenNumber];
+ TSize screenSize(screenWidth, screenHeight);
+ if (screenWidth > 0 && screenHeight > 0 && screenSize != Size()) {
+ m_inExternalScreenOverride = true;
+ SetExtent(TPoint(0, 0), screenSize);
+ return;
+ }
+ }
QRect cr = qwidget->geometry();
cr.setSize(newSize);
qwidget->data->crect = cr;
@@ -1189,6 +1210,8 @@ void QSymbianControl::SizeChanged()
}
}
+ m_inExternalScreenOverride = false;
+
// CCoeControl::SetExtent calls SizeChanged, but does not call
// PositionChanged, so we call it here to ensure that the widget's
// position is updated.
@@ -1224,6 +1247,11 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop)
return;
+#ifdef Q_WS_S60
+ if (S60->splitViewLastWidget)
+ return;
+#endif
+
// Popups never get focused, but still receive the FocusChanged when they are hidden.
if (QApplicationPrivate::popupWidgets != 0
|| (qwidget->windowType() & Qt::Popup) == Qt::Popup)
@@ -1302,9 +1330,56 @@ void QSymbianControl::handleClientAreaChange()
}
}
+bool QSymbianControl::isSplitViewWidget(QWidget *widget) {
+ bool returnValue = true;
+ //Ignore events sent to non-active windows, not visible widgets and not parents of input widget.
+ if (!qwidget->isActiveWindow()
+ || !qwidget->isVisible()
+ || !qwidget->isAncestorOf(widget)) {
+
+ returnValue = false;
+ }
+ return returnValue;
+}
+
void QSymbianControl::HandleResourceChange(int resourceType)
{
switch (resourceType) {
+ case KSplitViewCloseEvent: //intentional fall-through
+ case KSplitViewOpenEvent: {
+#if !defined(QT_NO_IM) && defined(Q_WS_S60)
+
+ //Fetch widget getting the text input
+ QWidget *widget = QWidget::keyboardGrabber();
+ if (!widget) {
+ if (QApplicationPrivate::popupWidgets) {
+ widget = QApplication::activePopupWidget()->focusWidget();
+ if (!widget) {
+ widget = QApplication::activePopupWidget();
+ }
+ } else {
+ widget = QApplicationPrivate::focus_widget;
+ if (!widget) {
+ widget = qwidget;
+ }
+ }
+ }
+ if (widget) {
+ QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(widget->inputContext());
+ if (!ic) {
+ ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext());
+ }
+ if (ic && isSplitViewWidget(widget)) {
+ if (resourceType == KSplitViewCloseEvent) {
+ ic->resetSplitViewWidget();
+ } else {
+ ic->ensureFocusWidgetVisible(widget);
+ }
+ }
+ }
+#endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
+ }
+ break;
case KInternalStatusPaneChange:
handleClientAreaChange();
if (IsFocused() && IsVisible()) {
@@ -1592,6 +1667,32 @@ void qt_init(QApplicationPrivate * /* priv */, int)
QObject::connect(qApp, SIGNAL(aboutToQuit()), qApp, SLOT(_q_aboutToQuit()));
#endif
+#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = true;
+
+ const TUid KIvePropertyCat = {0x2726beef};
+ enum TIvePropertyChipType {
+ EVCBCM2727B1 = 0x00000000,
+ EVCBCM2763A0 = 0x04000100,
+ EVCBCM2763B0 = 0x04000102,
+ EVCBCM2763C0 = 0x04000103,
+ EVCBCM2763C1 = 0x04000104,
+ EVCBCMUnknown = 0x7fffffff
+ };
+
+ TInt chipType = EVCBCMUnknown;
+ if (RProperty::Get(KIvePropertyCat, 0 /*chip type*/, chipType) == KErrNone) {
+ if (chipType == EVCBCM2727B1) {
+ // We have only 32MB GPU memory. Use raster surfaces
+ // for transparent TLWs.
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+ }
+ } else {
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+ }
+#else
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+#endif
/*
### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
int argc = priv->argc;
@@ -1988,7 +2089,10 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
return 1;
}
break;
- case EEventScreenDeviceChanged:
+ case EEventScreenDeviceChanged: // fallthrough
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ case EEventDisplayChanged:
+#endif
if (callSymbianEventFilters(symbianEvent))
return 1;
if (S60)
diff --git a/src/gui/kernel/qclipboard_win.cpp b/src/gui/kernel/qclipboard_win.cpp
index 52b9663..ea41165 100644
--- a/src/gui/kernel/qclipboard_win.cpp
+++ b/src/gui/kernel/qclipboard_win.cpp
@@ -52,6 +52,7 @@
#include "qt_windows.h"
#include "qdnd_p.h"
#include <private/qwidget_p.h>
+#include <private/qsystemlibrary_p.h>
QT_BEGIN_NAMESPACE
@@ -70,6 +71,9 @@ void QtCeFlushClipboard();
#endif
+typedef BOOL (WINAPI *PtrIsHungAppWindow)(HWND);
+
+static PtrIsHungAppWindow ptrIsHungAppWindow = 0;
class QClipboardWatcher : public QInternalMimeData {
public:
@@ -327,9 +331,16 @@ bool QClipboard::event(QEvent *e)
d->releaseIData();
propagate = true;
}
-
if (propagate && d->nextClipboardViewer) {
- SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam);
+ if (ptrIsHungAppWindow == 0) {
+ QSystemLibrary library(QLatin1String("User32"));
+ ptrIsHungAppWindow = (PtrIsHungAppWindow)library.resolve("IsHungAppWindow");
+ }
+ if (ptrIsHungAppWindow && ptrIsHungAppWindow(d->nextClipboardViewer)) {
+ qWarning("%s: Cowardly refusing to send clipboard message to hung application...", Q_FUNC_INFO);
+ } else {
+ SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam);
+ }
}
return true;
diff --git a/src/gui/kernel/qcocoaintrospection_mac.mm b/src/gui/kernel/qcocoaintrospection_mac.mm
index 9b536b7..70c893a 100644
--- a/src/gui/kernel/qcocoaintrospection_mac.mm
+++ b/src/gui/kernel/qcocoaintrospection_mac.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qcocoaintrospection_p.h b/src/gui/kernel/qcocoaintrospection_p.h
index b9422e8..1c7d6ac 100644
--- a/src/gui/kernel/qcocoaintrospection_p.h
+++ b/src/gui/kernel/qcocoaintrospection_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index c4b74c6..7d41f3d 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -533,22 +533,6 @@ QT_END_NAMESPACE
return de.isAccepted();
}
-- (void)displayIfNeeded
-{
-
- QWidget *qwidget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
- if (qwidget == 0) {
- [super displayIfNeeded];
- return;
- }
-
- if (QApplicationPrivate::graphicsSystem() != 0) {
- if (QWidgetBackingStore *bs = qt_widget_private(qwidget)->maybeBackingStore())
- bs->sync(qwidget, qwidget->rect());
- }
- [super displayIfNeeded];
-}
-
// This is a hack and it should be removed once we find the real cause for
// the painting problems.
// We have a static variable that signals if we have been called before or not.
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 5e8b37e..54e7e3e 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -51,6 +51,8 @@
#include <private/qmacinputcontext_p.h>
#include <private/qevent_p.h>
#include <private/qbackingstore_p.h>
+#include <private/qwindowsurface_raster_p.h>
+#include <private/qunifiedtoolbarsurface_mac_p.h>
#include <qscrollarea.h>
#include <qhash.h>
@@ -246,8 +248,79 @@ static int qCocoaViewCount = 0;
{
if (!qwidget)
return;
- if (QApplicationPrivate::graphicsSystem() != 0 && !qwidgetprivate->isInUnifiedToolbar) {
- // INVARIANT: We use a different graphics system.
+
+ // Getting context.
+ CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+ qt_mac_retain_graphics_context(context);
+
+ // We use a different graphics system.
+ if (QApplicationPrivate::graphicsSystem() != 0) {
+
+ // Raster engine.
+ if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) {
+
+ if (!qwidgetprivate->isInUnifiedToolbar) {
+
+ // Qt handles the painting occuring inside the window.
+ // Cocoa also keeps track of all widgets as NSView and therefore might
+ // ask for a repainting of a widget even if Qt is already taking care of it.
+ //
+ // The only valid reason for Cocoa to call drawRect: is for window manipulation
+ // (ie. resize, ...).
+ //
+ // Qt will then forward the update to the children.
+ if (!qwidget->isWindow()) {
+ qt_mac_release_graphics_context(context);
+ return;
+ }
+
+ QRasterWindowSurface *winSurface = dynamic_cast<QRasterWindowSurface *>(qwidget->windowSurface());
+ if (!winSurface || !winSurface->needsFlush) {
+ qt_mac_release_graphics_context(context);
+ return;
+ }
+
+ // Clip to region.
+ const QVector<QRect> &rects = winSurface->regionToFlush.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ const QRect &rect = rects.at(i);
+ CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()));
+ }
+ CGContextClip(context);
+
+ QRect r = winSurface->regionToFlush.boundingRect();
+ const CGRect area = CGRectMake(r.x(), r.y(), r.width(), r.height());
+
+ qt_mac_draw_image(context, winSurface->imageContext(), area, area);
+
+ winSurface->needsFlush = false;
+ winSurface->regionToFlush = QRegion();
+
+ } else {
+
+ QUnifiedToolbarSurface *unifiedSurface = qwidgetprivate->unifiedSurface;
+ if (!unifiedSurface) {
+ qt_mac_release_graphics_context(context);
+ return;
+ }
+
+ int areaX = qwidgetprivate->toolbar_offset.x();
+ int areaY = qwidgetprivate->toolbar_offset.y();
+ int areaWidth = qwidget->geometry().width();
+ int areaHeight = qwidget->geometry().height();
+ const CGRect area = CGRectMake(areaX, areaY, areaWidth, areaHeight);
+ const CGRect drawingArea = CGRectMake(0, 0, areaWidth, areaHeight);
+
+ qt_mac_draw_image(context, unifiedSurface->imageContext(), area, drawingArea);
+
+ qwidgetprivate->flushRequested = false;
+
+ }
+
+ CGContextFlush(context);
+ qt_mac_release_graphics_context(context);
+ return;
+ }
// Qt handles the painting occuring inside the window.
// Cocoa also keeps track of all widgets as NSView and therefore might
@@ -263,25 +336,14 @@ static int qCocoaViewCount = 0;
}
// Since we don't want to use the native engine, we must exit, however
- // widgets that are set to paint on screen, spesifically QGLWidget,
+ // widgets that are set to paint on screen, specifically QGLWidget,
// requires the following code to execute in order to be drawn.
if (!qwidget->testAttribute(Qt::WA_PaintOnScreen))
return;
}
- CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
- CGContextRetain(cg);
- qwidgetprivate->hd = cg;
-
- // We steal the CGContext for flushing in the unified toolbar with the raster engine.
- if (QApplicationPrivate::graphicsSystem() != 0 && qwidgetprivate->isInUnifiedToolbar && qwidgetprivate->unifiedSurface) {
- qwidgetprivate->cgContext = cg;
- qwidgetprivate->hasOwnContext = true;
- qwidgetprivate->unifiedSurface->flush(qwidget, qwidgetprivate->ut_rg, qwidgetprivate->ut_pt);
- return;
- }
-
- CGContextSaveGState(cg);
+ // Native engine.
+ qwidgetprivate->hd = context;
if (qwidget->isVisible() && qwidget->updatesEnabled()) { //process the actual paint event.
if (qwidget->testAttribute(Qt::WA_WState_InPaintEvent))
@@ -316,18 +378,18 @@ static int qCocoaViewCount = 0;
engine->setSystemClip(qrgn);
if (qwidgetprivate->extra && qwidgetprivate->extra->hasMask) {
CGRect widgetRect = CGRectMake(0, 0, qwidget->width(), qwidget->height());
- CGContextTranslateCTM (cg, 0, widgetRect.size.height);
- CGContextScaleCTM(cg, 1, -1);
+ CGContextTranslateCTM (context, 0, widgetRect.size.height);
+ CGContextScaleCTM(context, 1, -1);
if (qwidget->isWindow())
- CGContextClearRect(cg, widgetRect);
- CGContextClipToMask(cg, widgetRect, qwidgetprivate->extra->imageMask);
- CGContextScaleCTM(cg, 1, -1);
- CGContextTranslateCTM (cg, 0, -widgetRect.size.height);
+ CGContextClearRect(context, widgetRect);
+ CGContextClipToMask(context, widgetRect, qwidgetprivate->extra->imageMask);
+ CGContextScaleCTM(context, 1, -1);
+ CGContextTranslateCTM (context, 0, -widgetRect.size.height);
}
if (qwidget->isWindow() && !qwidgetprivate->isOpaque
&& !qwidget->testAttribute(Qt::WA_MacBrushedMetal)) {
- CGContextClearRect(cg, NSRectToCGRect(aRect));
+ CGContextClearRect(context, NSRectToCGRect(aRect));
}
qwidget->setAttribute(Qt::WA_WState_InPaintEvent, false);
@@ -358,8 +420,7 @@ static int qCocoaViewCount = 0;
" widget outside of the PaintEvent");
}
qwidgetprivate->hd = 0;
- CGContextRestoreGState(cg);
- CGContextRelease(cg);
+ qt_mac_release_graphics_context(context);
}
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm
index b8be627..1faf068 100644
--- a/src/gui/kernel/qcocoawindowdelegate_mac.mm
+++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm
@@ -48,6 +48,9 @@
#include <qlayout.h>
#include <qcoreapplication.h>
#include <qmenubar.h>
+#include <QMainWindow>
+#include <QToolBar>
+#include <private/qmainwindowlayout_p.h>
QT_BEGIN_NAMESPACE
extern QWidgetData *qt_qwidget_data(QWidget *); // qwidget.cpp
@@ -215,6 +218,24 @@ static void cleanupCocoaWindowDelegate()
QWidgetPrivate::qt_mac_update_sizer(qwidget);
[self syncSizeForWidget:qwidget toSize:newSize fromSize:oldSize];
}
+
+ // We force the repaint to be synchronized with the resize of the window.
+ // Otherwise, the resize looks sluggish because we paint one event loop later.
+ if ([[window contentView] inLiveResize]) {
+ qwidget->repaint();
+
+ // We need to repaint the toolbar as well.
+ QMainWindow* mWindow = qobject_cast<QMainWindow*>(qwidget->window());
+ if (mWindow) {
+ QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout());
+ QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList;
+
+ for (int i = 0; i < toolbarList.size(); ++i) {
+ QToolBar* toolbar = toolbarList.at(i);
+ toolbar->repaint();
+ }
+ }
+ }
}
- (void)windowDidMove:(NSNotification *)notification
diff --git a/src/gui/kernel/qdesktopwidget_qpa_p.h b/src/gui/kernel/qdesktopwidget_qpa_p.h
index 47ccca2..abee8a1 100644
--- a/src/gui/kernel/qdesktopwidget_qpa_p.h
+++ b/src/gui/kernel/qdesktopwidget_qpa_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/gui/kernel/qdesktopwidget_s60.cpp
index 3653ae2..62a4d40 100644
--- a/src/gui/kernel/qdesktopwidget_s60.cpp
+++ b/src/gui/kernel/qdesktopwidget_s60.cpp
@@ -44,36 +44,67 @@
#include "qwidget_p.h"
#include "qt_s60_p.h"
#include <w32std.h>
-
-#include "hal.h"
-#include "hal_data.h"
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+#include <graphics/displaycontrol.h>
+#endif
QT_BEGIN_NAMESPACE
-class QDesktopWidgetPrivate : public QWidgetPrivate
+extern int qt_symbian_create_desktop_on_screen;
+
+class QSingleDesktopWidget : public QWidget
+{
+public:
+ QSingleDesktopWidget();
+ ~QSingleDesktopWidget();
+};
+
+QSingleDesktopWidget::QSingleDesktopWidget()
+ : QWidget(0, Qt::Desktop)
+{
+}
+
+QSingleDesktopWidget::~QSingleDesktopWidget()
{
+ const QObjectList &childList = children();
+ for (int i = childList.size(); i > 0 ;) {
+ --i;
+ childList.at(i)->setParent(0);
+ }
+}
+class QDesktopWidgetPrivate : public QWidgetPrivate
+{
public:
QDesktopWidgetPrivate();
~QDesktopWidgetPrivate();
-
static void init(QDesktopWidget *that);
static void cleanup();
+ static void init_sys();
static int screenCount;
static int primaryScreen;
static QVector<QRect> *rects;
static QVector<QRect> *workrects;
+ static QVector<QWidget *> *screens;
static int refcount;
+
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ static MDisplayControl *displayControl;
+#endif
};
int QDesktopWidgetPrivate::screenCount = 1;
int QDesktopWidgetPrivate::primaryScreen = 0;
QVector<QRect> *QDesktopWidgetPrivate::rects = 0;
QVector<QRect> *QDesktopWidgetPrivate::workrects = 0;
+QVector<QWidget *> *QDesktopWidgetPrivate::screens = 0;
int QDesktopWidgetPrivate::refcount = 0;
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+MDisplayControl *QDesktopWidgetPrivate::displayControl = 0;
+#endif
QDesktopWidgetPrivate::QDesktopWidgetPrivate()
{
@@ -88,25 +119,55 @@ QDesktopWidgetPrivate::~QDesktopWidgetPrivate()
void QDesktopWidgetPrivate::init(QDesktopWidget *that)
{
- Q_UNUSED(that);
-// int screenCount=0;
-
- // ### TODO: Implement proper multi-display support
- QDesktopWidgetPrivate::screenCount = 1;
-// if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone)
-// QDesktopWidgetPrivate::screenCount = screenCount;
-// else
-// QDesktopWidgetPrivate::screenCount = 0;
+ // Note that on S^3 devices the screen count retrieved via RWsSession
+ // will always be 2 but the width and height for screen number 1 will
+ // be 0 as long as TV-out is not connected.
+ //
+ // On the other hand a valid size for screen 1 will be reported even
+ // after the cable is disconnected. In order to overcome this, we use
+ // MDisplayControl::NumberOfResolutions() to check if the display is
+ // valid or not.
+
+ screenCount = S60->screenCount();
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ if (displayControl) {
+ if (displayControl->NumberOfResolutions() < 1)
+ screenCount = 1;
+ }
+#endif
+ if (screenCount < 1) {
+ qWarning("No screen available");
+ screenCount = 1;
+ }
rects = new QVector<QRect>();
workrects = new QVector<QRect>();
-
- rects->resize(QDesktopWidgetPrivate::screenCount);
- workrects->resize(QDesktopWidgetPrivate::screenCount);
-
- (*rects)[0].setRect(0, 0, S60->screenWidthInPixels, S60->screenHeightInPixels);
- QRect wr = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
- (*workrects)[0].setRect(wr.x(), wr.y(), wr.width(), wr.height());
+ screens = new QVector<QWidget *>();
+
+ rects->resize(screenCount);
+ workrects->resize(screenCount);
+ screens->resize(screenCount);
+
+ for (int i = 0; i < screenCount; ++i) {
+ // All screens will have a position of (0, 0) as there is no true virtual desktop
+ // or pointer event support for multiple screens on Symbian.
+ QRect r(0, 0,
+ S60->screenWidthInPixelsForScreen[i], S60->screenHeightInPixelsForScreen[i]);
+ // Stop here if empty and ignore this screen.
+ if (r.isEmpty()) {
+ screenCount = i;
+ break;
+ }
+ (*rects)[i] = r;
+ QRect wr;
+ if (i == 0)
+ wr = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+ else
+ wr = rects->at(i);
+ (*workrects)[i].setRect(wr.x(), wr.y(), wr.width(), wr.height());
+ (*screens)[i] = 0;
+ }
+ (*screens)[0] = that;
}
void QDesktopWidgetPrivate::cleanup()
@@ -115,6 +176,29 @@ void QDesktopWidgetPrivate::cleanup()
rects = 0;
delete workrects;
workrects = 0;
+ if (screens) {
+ // First item is the QDesktopWidget so skip it.
+ for (int i = 1; i < screens->count(); ++i)
+ delete screens->at(i);
+ }
+ delete screens;
+ screens = 0;
+}
+
+void QDesktopWidgetPrivate::init_sys()
+{
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ if (S60->screenCount() > 1) {
+ CWsScreenDevice *dev = S60->screenDevice(1);
+ if (dev) {
+ displayControl = static_cast<MDisplayControl *>(
+ dev->GetInterface(MDisplayControl::ETypeId));
+ if (displayControl) {
+ displayControl->EnableDisplayChangeEvents(ETrue);
+ }
+ }
+ }
+#endif
}
@@ -122,6 +206,7 @@ QDesktopWidget::QDesktopWidget()
: QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop)
{
setObjectName(QLatin1String("desktop"));
+ QDesktopWidgetPrivate::init_sys();
QDesktopWidgetPrivate::init(this);
}
@@ -131,7 +216,7 @@ QDesktopWidget::~QDesktopWidget()
bool QDesktopWidget::isVirtualDesktop() const
{
- return true;
+ return false;
}
int QDesktopWidget::primaryScreen() const
@@ -145,9 +230,23 @@ int QDesktopWidget::numScreens() const
return QDesktopWidgetPrivate::screenCount;
}
-QWidget *QDesktopWidget::screen(int /* screen */)
+static inline QWidget *newSingleDesktopWidget(int screen)
{
- return this;
+ qt_symbian_create_desktop_on_screen = screen;
+ QWidget *w = new QSingleDesktopWidget;
+ qt_symbian_create_desktop_on_screen = -1;
+ return w;
+}
+
+QWidget *QDesktopWidget::screen(int screen)
+{
+ Q_D(QDesktopWidget);
+ if (screen < 0 || screen >= d->screenCount)
+ screen = d->primaryScreen;
+ if (!d->screens->at(screen)
+ || d->screens->at(screen)->windowType() != Qt::Desktop)
+ (*d->screens)[screen] = newSingleDesktopWidget(screen);
+ return (*d->screens)[screen];
}
const QRect QDesktopWidget::availableGeometry(int screen) const
@@ -168,14 +267,19 @@ const QRect QDesktopWidget::screenGeometry(int screen) const
return d->rects->at(screen);
}
-int QDesktopWidget::screenNumber(const QWidget * /* widget */) const
+int QDesktopWidget::screenNumber(const QWidget *widget) const
{
- return QDesktopWidgetPrivate::primaryScreen;
+ Q_D(const QDesktopWidget);
+ return widget
+ ? S60->screenNumberForWidget(widget)
+ : d->primaryScreen;
}
-int QDesktopWidget::screenNumber(const QPoint & /* point */) const
+int QDesktopWidget::screenNumber(const QPoint &point) const
{
- return QDesktopWidgetPrivate::primaryScreen;
+ Q_UNUSED(point);
+ Q_D(const QDesktopWidget);
+ return d->primaryScreen;
}
void QDesktopWidget::resizeEvent(QResizeEvent *)
@@ -203,6 +307,10 @@ void QDesktopWidget::resizeEvent(QResizeEvent *)
if (oldrect != newrect)
emit workAreaResized(j);
}
+
+ if (oldscreencount != d->screenCount) {
+ emit screenCountChanged(d->screenCount);
+ }
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 698c94b..277a5e8 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -43,6 +43,7 @@
#include "qcursor.h"
#include "qapplication.h"
#include "private/qapplication_p.h"
+#include "private/qevent_p.h"
#include "private/qkeysequence_p.h"
#include "qwidget.h"
#include "qgraphicsview.h"
diff --git a/src/gui/kernel/qeventdispatcher_glib_qpa.cpp b/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
index 01d40ca..603aa2d 100644
--- a/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
+++ b/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qeventdispatcher_glib_qpa_p.h b/src/gui/kernel/qeventdispatcher_glib_qpa_p.h
index 1c32ab2..701f673 100644
--- a/src/gui/kernel/qeventdispatcher_glib_qpa_p.h
+++ b/src/gui/kernel/qeventdispatcher_glib_qpa_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp
index 519d2a6..de53618 100644
--- a/src/gui/kernel/qeventdispatcher_qpa.cpp
+++ b/src/gui/kernel/qeventdispatcher_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -172,7 +172,6 @@ public:
{
if (qApp && (qApp->thread() == QThread::currentThread())) {
m_isEventLoopIntegrationRunning = true;
- QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
eventLoopIntegration->startEventLoop();
}
}
diff --git a/src/gui/kernel/qeventdispatcher_qpa_p.h b/src/gui/kernel/qeventdispatcher_qpa_p.h
index 8065c3e..d4d2be1 100644
--- a/src/gui/kernel/qeventdispatcher_qpa_p.h
+++ b/src/gui/kernel/qeventdispatcher_qpa_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformclipboard_qpa.cpp b/src/gui/kernel/qplatformclipboard_qpa.cpp
index fff4e19..957a4df 100644
--- a/src/gui/kernel/qplatformclipboard_qpa.cpp
+++ b/src/gui/kernel/qplatformclipboard_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -40,6 +40,8 @@
****************************************************************************/
#include "qplatformclipboard_qpa.h"
+#ifndef QT_NO_CLIPBOARD
+
QT_BEGIN_NAMESPACE
class QClipboardData
@@ -99,3 +101,5 @@ bool QPlatformClipboard::supportsMode(QClipboard::Mode mode) const
}
QT_END_NAMESPACE
+
+#endif //QT_NO_CLIPBOARD
diff --git a/src/gui/kernel/qplatformclipboard_qpa.h b/src/gui/kernel/qplatformclipboard_qpa.h
index 3f7bfbb..3381c06 100644
--- a/src/gui/kernel/qplatformclipboard_qpa.h
+++ b/src/gui/kernel/qplatformclipboard_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -44,6 +44,8 @@
#include <qplatformdefs.h>
+#ifndef QT_NO_CLIPBOARD
+
#include <QtGui/QClipboard>
QT_BEGIN_HEADER
@@ -66,5 +68,6 @@ QT_END_NAMESPACE
QT_END_HEADER
+#endif // QT_NO_CLIPBOARD
#endif //QPLATFORMCLIPBOARD_QPA_H
diff --git a/src/gui/kernel/qplatformcursor_qpa.cpp b/src/gui/kernel/qplatformcursor_qpa.cpp
index ac557b9..2ea8332 100644
--- a/src/gui/kernel/qplatformcursor_qpa.cpp
+++ b/src/gui/kernel/qplatformcursor_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp
index fdb3852..0ed43eb 100644
--- a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp
+++ b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.h b/src/gui/kernel/qplatformeventloopintegration_qpa.h
index 6e0f984..87df7ae 100644
--- a/src/gui/kernel/qplatformeventloopintegration_qpa.h
+++ b/src/gui/kernel/qplatformeventloopintegration_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp
index 1673aed..86740e8 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.cpp
+++ b/src/gui/kernel/qplatformglcontext_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h
index 807ed3d..a680c85 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.h
+++ b/src/gui/kernel/qplatformglcontext_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp
index 0cac57d..c45a953 100644
--- a/src/gui/kernel/qplatformintegration_qpa.cpp
+++ b/src/gui/kernel/qplatformintegration_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -102,6 +102,9 @@ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const
\sa QPlatformClipboard
*/
+
+#ifndef QT_NO_CLIPBOARD
+
QPlatformClipboard *QPlatformIntegration::clipboard() const
{
static QPlatformClipboard *clipboard = 0;
@@ -111,6 +114,13 @@ QPlatformClipboard *QPlatformIntegration::clipboard() const
return clipboard;
}
+#endif
+
+QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
+{
+ return 0;
+}
+
/*!
\class QPlatformIntegration
\since 4.8
@@ -211,4 +221,14 @@ QPlatformClipboard *QPlatformIntegration::clipboard() const
QRect(x,y,width,height).
*/
+
+bool QPlatformIntegration::hasCapability(Capability cap) const
+{
+ return false;
+}
+
+
+
+
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h
index 7050245..0aacefa 100644
--- a/src/gui/kernel/qplatformintegration_qpa.h
+++ b/src/gui/kernel/qplatformintegration_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -60,12 +60,19 @@ class QWidget;
class QPlatformEventLoopIntegration;
class QPlatformFontDatabase;
class QPlatformClipboard;
+class QPlatformNativeInterface;
class Q_GUI_EXPORT QPlatformIntegration
{
public:
+ enum Capability {
+ ThreadedPixmaps = 1,
+ };
+
virtual ~QPlatformIntegration() { }
+ virtual bool hasCapability(Capability cap) const;
+
// GraphicsSystem functions
virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const = 0;
virtual QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const = 0;
@@ -79,7 +86,9 @@ public:
//Deeper window system integrations
virtual QPlatformFontDatabase *fontDatabase() const;
+#ifndef QT_NO_CLIPBOARD
virtual QPlatformClipboard *clipboard() const;
+#endif
// Experimental in mainthread eventloop integration
// This should only be used if it is only possible to do window system event processing in
@@ -89,7 +98,8 @@ public:
//jl:XXX should it be hasGLContext and do we need it at all?
virtual bool hasOpenGL() const;
-
+// Access native handles. The window handle is already available from Wid;
+ virtual QPlatformNativeInterface *nativeInterface() const;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegrationfactory_qpa.cpp b/src/gui/kernel/qplatformintegrationfactory_qpa.cpp
index 17a130d..4135c9e 100644
--- a/src/gui/kernel/qplatformintegrationfactory_qpa.cpp
+++ b/src/gui/kernel/qplatformintegrationfactory_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformintegrationfactory_qpa_p.h b/src/gui/kernel/qplatformintegrationfactory_qpa_p.h
index 77e1da1..a6042a8 100644
--- a/src/gui/kernel/qplatformintegrationfactory_qpa_p.h
+++ b/src/gui/kernel/qplatformintegrationfactory_qpa_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformintegrationplugin_qpa.cpp b/src/gui/kernel/qplatformintegrationplugin_qpa.cpp
index 3bf2474..62920b6 100644
--- a/src/gui/kernel/qplatformintegrationplugin_qpa.cpp
+++ b/src/gui/kernel/qplatformintegrationplugin_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformintegrationplugin_qpa.h b/src/gui/kernel/qplatformintegrationplugin_qpa.h
index 9c37cf7..17bcba0 100644
--- a/src/gui/kernel/qplatformintegrationplugin_qpa.h
+++ b/src/gui/kernel/qplatformintegrationplugin_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.cpp b/src/gui/kernel/qplatformnativeinterface_qpa.cpp
new file mode 100644
index 0000000..ace4a7b
--- /dev/null
+++ b/src/gui/kernel/qplatformnativeinterface_qpa.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformnativeinterface_qpa.h"
+
+QT_BEGIN_NAMESPACE
+
+void *QPlatformNativeInterface::nativeResourceForWidget(const QByteArray &resource, QWidget *widget)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(widget);
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.h b/src/gui/kernel/qplatformnativeinterface_qpa.h
new file mode 100644
index 0000000..5ea2c13
--- /dev/null
+++ b/src/gui/kernel/qplatformnativeinterface_qpa.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMNATIVEINTERFACE_QPA_H
+#define QPLATFORMNATIVEINTERFACE_QPA_H
+
+#include <QtGui/qwindowdefs.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QWidget;
+
+class Q_GUI_EXPORT QPlatformNativeInterface
+{
+public:
+ virtual void *nativeResourceForWidget(const QByteArray &resource, QWidget *widget);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLATFORMNATIVEINTERFACE_QPA_H
diff --git a/src/gui/kernel/qplatformscreen_qpa.cpp b/src/gui/kernel/qplatformscreen_qpa.cpp
index 118835f..c9f3dc6 100644
--- a/src/gui/kernel/qplatformscreen_qpa.cpp
+++ b/src/gui/kernel/qplatformscreen_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformscreen_qpa.h b/src/gui/kernel/qplatformscreen_qpa.h
index 1f52764..b3bb121 100644
--- a/src/gui/kernel/qplatformscreen_qpa.h
+++ b/src/gui/kernel/qplatformscreen_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp
index b6b6693..19bf7a9 100644
--- a/src/gui/kernel/qplatformwindow_qpa.cpp
+++ b/src/gui/kernel/qplatformwindow_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h
index abc35d1..41a4bac 100644
--- a/src/gui/kernel/qplatformwindow_qpa.h
+++ b/src/gui/kernel/qplatformwindow_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp
index 44b0698..ddc6239 100644
--- a/src/gui/kernel/qplatformwindowformat_qpa.cpp
+++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qplatformwindowformat_qpa.h b/src/gui/kernel/qplatformwindowformat_qpa.h
index 790385b..fa01a8a 100644
--- a/src/gui/kernel/qplatformwindowformat_qpa.h
+++ b/src/gui/kernel/qplatformwindowformat_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index f4a1ea5..32123ee 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -1794,7 +1794,29 @@ void qt_mac_display(QWidget *widget)
{
NSView *theNSView = qt_mac_nativeview_for(widget);
[theNSView display];
- return;
+}
+
+void qt_mac_setNeedsDisplay(QWidget *widget)
+{
+ NSView *theNSView = qt_mac_nativeview_for(widget);
+ [theNSView setNeedsDisplay:YES];
+}
+
+void qt_mac_setNeedsDisplayInRect(QWidget *widget, QRegion region)
+{
+ NSView *theNSView = qt_mac_nativeview_for(widget);
+ if (region.isEmpty()) {
+ [theNSView setNeedsDisplay:YES];
+ return;
+ }
+
+ QVector<QRect> rects = region.rects();
+ for (int i = 0; i < rects.count(); ++i) {
+ const QRect &rect = rects.at(i);
+ NSRect nsrect = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
+ [theNSView setNeedsDisplayInRect:nsrect];
+ }
+
}
#endif // QT_MAC_USE_COCOA
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
index 334d9e8..a49753a 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
@@ -301,7 +301,39 @@ public:
void qt_mac_post_retranslateAppMenu();
+#ifdef QT_MAC_USE_COCOA
void qt_mac_display(QWidget *widget);
+void qt_mac_setNeedsDisplay(QWidget *widget);
+void qt_mac_setNeedsDisplayInRect(QWidget *widget, QRegion region);
+#endif // QT_MAC_USE_COCOA
+
+
+// Utility functions to ease the use of Core Graphics contexts.
+
+inline void qt_mac_retain_graphics_context(CGContextRef context)
+{
+ CGContextRetain(context);
+ CGContextSaveGState(context);
+}
+
+inline void qt_mac_release_graphics_context(CGContextRef context)
+{
+ CGContextRestoreGState(context);
+ CGContextRelease(context);
+}
+
+inline void qt_mac_draw_image(CGContextRef context, CGContextRef imageContext, CGRect area, CGRect drawingArea)
+{
+ CGImageRef image = CGBitmapContextCreateImage(imageContext);
+ CGImageRef subImage = CGImageCreateWithImageInRect(image, area);
+
+ CGContextTranslateCTM (context, 0, drawingArea.origin.y + CGRectGetMaxY(drawingArea));
+ CGContextScaleCTM(context, 1, -1);
+ CGContextDrawImage(context, drawingArea, subImage);
+
+ CGImageRelease(subImage);
+ CGImageRelease(image);
+}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 40697bf..3bb27c3 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -64,6 +64,7 @@
#include "qapplication.h"
#include "qelapsedtimer.h"
#include "QtCore/qthreadstorage.h"
+#include "qwidget_p.h"
#include <w32std.h>
#include <coecntrl.h>
#include <eikenv.h>
@@ -84,6 +85,8 @@ QT_BEGIN_NAMESPACE
// system events seems to start with 0x10
const TInt KInternalStatusPaneChange = 0x50000000;
+static const int qt_symbian_max_screens = 4;
+
//this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2
#define Q_SYMBIAN_ECOLOR16MAP TDisplayMode(13)
@@ -142,7 +145,10 @@ public:
int avkonComponentsSupportTransparency : 1;
int menuBeingConstructed : 1;
int orientationSet : 1;
+ int partial_keyboard : 1;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
+ QPointer<QWidget> splitViewLastWidget;
+
static CEikButtonGroupContainer *cba;
enum ScanCodeState {
@@ -154,8 +160,14 @@ public:
static inline void updateScreenSize();
inline RWsSession& wsSession();
+ static inline int screenCount();
static inline RWindowGroup& windowGroup();
+ static inline RWindowGroup& windowGroup(const QWidget *widget);
+ static inline RWindowGroup& windowGroup(int screenNumber);
inline CWsScreenDevice* screenDevice();
+ inline CWsScreenDevice* screenDevice(const QWidget *widget);
+ inline CWsScreenDevice* screenDevice(int screenNumber);
+ static inline int screenNumberForWidget(const QWidget *widget);
static inline CCoeAppUi* appUi();
static inline CEikMenuBar* menuBar();
#ifdef Q_WS_S60
@@ -172,6 +184,11 @@ public:
#ifdef Q_OS_SYMBIAN
TTrapHandler *s60InstalledTrapHandler;
#endif
+
+ int screenWidthInPixelsForScreen[qt_symbian_max_screens];
+ int screenHeightInPixelsForScreen[qt_symbian_max_screens];
+ int screenWidthInTwipsForScreen[qt_symbian_max_screens];
+ int screenHeightInTwipsForScreen[qt_symbian_max_screens];
};
Q_AUTOTEST_EXPORT QS60Data* qGlobalS60Data();
@@ -252,6 +269,7 @@ private:
#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event);
#endif
+ bool isSplitViewWidget(QWidget *widget);
public:
void handleClientAreaChange();
@@ -270,6 +288,8 @@ private:
// Fader object used to fade everything except this menu and the CBA.
TAknPopupFader popupFader;
#endif
+
+ bool m_inExternalScreenOverride : 1;
};
inline QS60Data::QS60Data()
@@ -297,6 +317,7 @@ inline QS60Data::QS60Data()
avkonComponentsSupportTransparency(0),
menuBeingConstructed(0),
orientationSet(0),
+ partial_keyboard(0),
s60ApplicationFactory(0)
#ifdef Q_OS_SYMBIAN
,s60InstalledTrapHandler(0)
@@ -320,6 +341,17 @@ inline void QS60Data::updateScreenSize()
S60->defaultDpiY = S60->screenHeightInPixels / inches;
inches = S60->screenWidthInTwips / (TReal)KTwipsPerInch;
S60->defaultDpiX = S60->screenWidthInPixels / inches;
+
+ int screens = S60->screenCount();
+ for (int i = 0; i < screens; ++i) {
+ CWsScreenDevice *dev = S60->screenDevice(i);
+ mode = dev->CurrentScreenMode();
+ dev->GetScreenModeSizeAndRotation(mode, params);
+ S60->screenWidthInPixelsForScreen[i] = params.iPixelSize.iWidth;
+ S60->screenHeightInPixelsForScreen[i] = params.iPixelSize.iHeight;
+ S60->screenWidthInTwipsForScreen[i] = params.iTwipsSize.iWidth;
+ S60->screenHeightInTwipsForScreen[i] = params.iTwipsSize.iHeight;
+ }
}
inline RWsSession& QS60Data::wsSession()
@@ -330,11 +362,38 @@ inline RWsSession& QS60Data::wsSession()
return tls.localData()->wsSession;
}
+inline int QS60Data::screenCount()
+{
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ CCoeEnv *env = CCoeEnv::Static();
+ if (env) {
+ return qMin(env->WsSession().NumberOfScreens(), qt_symbian_max_screens);
+ }
+#endif
+ return 1;
+}
+
inline RWindowGroup& QS60Data::windowGroup()
{
return CCoeEnv::Static()->RootWin();
}
+inline RWindowGroup& QS60Data::windowGroup(const QWidget *widget)
+{
+ return windowGroup(screenNumberForWidget(widget));
+}
+
+inline RWindowGroup& QS60Data::windowGroup(int screenNumber)
+{
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ RWindowGroup *wg = CCoeEnv::Static()->RootWin(screenNumber);
+ return wg ? *wg : windowGroup();
+#else
+ Q_UNUSED(screenNumber);
+ return windowGroup();
+#endif
+}
+
inline CWsScreenDevice* QS60Data::screenDevice()
{
if(!tls.hasLocalData()) {
@@ -343,6 +402,36 @@ inline CWsScreenDevice* QS60Data::screenDevice()
return tls.localData()->screenDevice;
}
+inline CWsScreenDevice* QS60Data::screenDevice(const QWidget *widget)
+{
+ return screenDevice(screenNumberForWidget(widget));
+}
+
+inline CWsScreenDevice* QS60Data::screenDevice(int screenNumber)
+{
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ CCoeEnv *env = CCoeEnv::Static();
+ if (env) {
+ CWsScreenDevice *dev = env->ScreenDevice(screenNumber);
+ return dev ? dev : screenDevice();
+ } else {
+ return screenDevice();
+ }
+#else
+ return screenDevice();
+#endif
+}
+
+inline int QS60Data::screenNumberForWidget(const QWidget *widget)
+{
+ if (!widget)
+ return 0;
+ const QWidget *w = widget;
+ while (w->parentWidget())
+ w = w->parentWidget();
+ return qt_widget_private(const_cast<QWidget *>(w))->symbianScreenNumber;
+}
+
inline CCoeAppUi* QS60Data::appUi()
{
return CCoeEnv::Static()-> AppUi();
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index feedb2a..59b7eb9 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -310,6 +310,8 @@ QWidgetPrivate::QWidgetPrivate(int version)
, needWindowChange(0)
, window_event(0)
, qd_hd(0)
+#elif defined(Q_OS_SYMBIAN)
+ , symbianScreenNumber(0)
#endif
{
if (!qApp) {
@@ -326,9 +328,10 @@ QWidgetPrivate::QWidgetPrivate(int version)
drawRectOriginalAdded = false;
originalDrawMethod = true;
changeMethods = false;
- hasOwnContext = false;
isInUnifiedToolbar = false;
unifiedSurface = 0;
+ toolbar_ancestor = 0;
+ flushRequested = false;
touchEventsEnabled = false;
#endif // QT_MAC_USE_COCOA
#ifdef QWIDGET_EXTRA_DEBUG
@@ -364,9 +367,12 @@ QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
Q_Q(QWidget);
QWindowSurface *surface;
+#ifndef QT_NO_PROPERTIES
if (q->property("_q_DummyWindowSurface").toBool()) {
surface = new QDummyWindowSurface(q);
- } else {
+ } else
+#endif
+ {
if (QApplicationPrivate::graphicsSystem())
surface = QApplicationPrivate::graphicsSystem()->createWindowSurface(q);
else
@@ -1294,6 +1300,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
// programmer specified desktop widget
xinfo = desktopWidget->d_func()->xinfo;
}
+#elif defined(Q_OS_SYMBIAN)
+ if (desktopWidget) {
+ symbianScreenNumber = qt_widget_private(desktopWidget)->symbianScreenNumber;
+ }
#elif defined(Q_WS_QPA)
if (desktopWidget) {
int screen = desktopWidget->d_func()->topData()->screenIndex;
@@ -1336,8 +1346,8 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
//give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
#ifdef Q_OS_SYMBIAN
if (isGLWidget) {
- // Don't waste GPU mem for unnecessary large egl surface
- data.crect = QRect(0,0,2,2);
+ // Don't waste GPU mem for unnecessary large egl surface until resized by application
+ data.crect = QRect(0,0,1,1);
} else {
data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,360,640);
}
@@ -1379,6 +1389,16 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
QApplication::postEvent(q, new QEvent(QEvent::PolishRequest));
extraPaintEngine = 0;
+
+#ifdef QT_MAC_USE_COCOA
+ // If we add a child to the unified toolbar, we have to redirect the painting.
+ if (parentWidget && parentWidget->d_func() && parentWidget->d_func()->isInUnifiedToolbar) {
+ if (parentWidget->d_func()->unifiedSurface) {
+ QWidget *toolbar = parentWidget->d_func()->toolbar_ancestor;
+ parentWidget->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset);
+ }
+ }
+#endif // QT_MAC_USE_COCOA
}
@@ -2093,6 +2113,11 @@ void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirt
if (disableSubtractOpaqueSiblings || q->isWindow())
return;
+#ifdef QT_MAC_USE_COCOA
+ if (q->d_func()->isInUnifiedToolbar)
+ return;
+#endif // QT_MAC_USE_COCOA
+
QRect clipBoundingRect;
bool dirtyClipBoundingRect = true;
@@ -10385,6 +10410,12 @@ void QWidget::repaint(const QRect &rect)
return;
if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
tlwExtra->inRepaint = true;
@@ -10414,6 +10445,12 @@ void QWidget::repaint(const QRegion &rgn)
return;
if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
tlwExtra->inRepaint = true;
@@ -10471,6 +10508,12 @@ void QWidget::update(const QRect &rect)
}
if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
tlwExtra->backingStore->markDirty(rect, this);
@@ -10495,6 +10538,12 @@ void QWidget::update(const QRegion &rgn)
}
if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
tlwExtra->backingStore->markDirty(rgn, this);
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 9a5a5f1..34918e4 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2476,6 +2476,8 @@ void QWidgetPrivate::createWindow_sys()
void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
{
Q_Q(QWidget);
+ QMacCocoaAutoReleasePool pool;
+
OSViewRef destroyid = 0;
#ifndef QT_MAC_USE_COCOA
window_event = 0;
@@ -3239,6 +3241,8 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
ReleaseIconRef(previousIcon);
#else
QMacCocoaAutoReleasePool pool;
+ if (icon.isNull())
+ return;
NSButton *iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
if (iconButton == nil) {
QCFString string(q->windowTitle());
@@ -4421,6 +4425,8 @@ void QWidgetPrivate::adjustWithinMaxAndMinSize(int &w, int &h)
void QWidgetPrivate::applyMaxAndMinSizeOnWindow()
{
Q_Q(QWidget);
+ QMacCocoaAutoReleasePool pool;
+
const float max_f(20000);
#ifndef QT_MAC_USE_COCOA
#define SF(x) ((x > max_f) ? max_f : x)
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 1083a1f..e5a2c35 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -113,6 +113,8 @@ class QWidgetItemV2;
class QStyle;
+class QUnifiedToolbarSurface;
+
class Q_AUTOTEST_EXPORT QWidgetBackingStoreTracker
{
@@ -322,6 +324,11 @@ struct QWExtra {
*/
ZeroFill,
+ /**
+ * Blit backing store, propagating alpha channel into the framebuffer.
+ */
+ BlitWriteAlpha,
+
Default = Blit
};
@@ -856,15 +863,15 @@ public:
bool originalDrawMethod;
// Do we need to change the methods?
bool changeMethods;
- bool hasOwnContext;
- CGContextRef cgContext;
- QRegion ut_rg;
- QPoint ut_pt;
+
+ // Unified toolbar variables
bool isInUnifiedToolbar;
- QWindowSurface *unifiedSurface;
+ QUnifiedToolbarSurface *unifiedSurface;
QPoint toolbar_offset;
+ QWidget *toolbar_ancestor;
+ bool flushRequested;
bool touchEventsEnabled;
-#endif
+#endif // QT_MAC_USE_COCOA
void determineWindowClass();
void transferChildren();
bool qt_mac_dnd_event(uint, DragRef);
@@ -900,6 +907,7 @@ public:
#elif defined(Q_OS_SYMBIAN) // <--------------------------------------------------------- SYMBIAN
static QWidget *mouseGrabber;
static QWidget *keyboardGrabber;
+ int symbianScreenNumber; // only valid for desktop widget and top-levels
void s60UpdateIsOpaque();
void reparentChildren();
void registerTouchWindow();
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 85164d2..b031936 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -84,6 +84,8 @@ QWidget *QWidgetPrivate::mouseGrabber = 0;
QWidget *QWidgetPrivate::keyboardGrabber = 0;
CEikButtonGroupContainer *QS60Data::cba = 0;
+int qt_symbian_create_desktop_on_screen = -1;
+
static bool isEqual(const QList<QAction*>& a, const QList<QAction*>& b)
{
if ( a.count() != b.count())
@@ -349,12 +351,18 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
int sh = clientRect.Height();
if (desktop) {
- TSize screenSize = S60->screenDevice()->SizeInPixels();
+ symbianScreenNumber = qMax(qt_symbian_create_desktop_on_screen, 0);
+ TSize screenSize = S60->screenDevice(symbianScreenNumber)->SizeInPixels();
data.crect.setRect(0, 0, screenSize.iWidth, screenSize.iHeight);
q->setAttribute(Qt::WA_DontShowOnScreen);
} else if (topLevel && !q->testAttribute(Qt::WA_Resized)){
int width = sw;
int height = sh;
+ if (symbianScreenNumber > 0) {
+ TSize screenSize = S60->screenDevice(symbianScreenNumber)->SizeInPixels();
+ width = screenSize.iWidth;
+ height = screenSize.iHeight;
+ }
if (extra) {
width = qMax(qMin(width, extra->maxw), extra->minw);
height = qMax(qMin(height, extra->maxh), extra->minh);
@@ -644,7 +652,7 @@ void QWidgetPrivate::raise_sys()
// If toplevel widget, raise app to foreground
if (q->isWindow())
- S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup().Identifier(), 0);
+ S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup(q).Identifier(), 0);
}
}
@@ -656,7 +664,7 @@ void QWidgetPrivate::lower_sys()
if (q->internalWinId()) {
// If toplevel widget, lower app to background
if (q->isWindow())
- S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup().Identifier(), -1);
+ S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup(q).Identifier(), -1);
else
q->internalWinId()->DrawableWindow()->SetOrdinalPosition(-1);
}
@@ -726,6 +734,11 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
{
Q_Q(QWidget);
+ if (parent && parent->windowType() == Qt::Desktop) {
+ symbianScreenNumber = qt_widget_private(parent)->symbianScreenNumber;
+ parent = 0;
+ }
+
bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
@@ -796,25 +809,33 @@ void QWidgetPrivate::s60UpdateIsOpaque()
{
Q_Q(QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground))
+ if (!q->testAttribute(Qt::WA_WState_Created))
return;
+ const bool writeAlpha = extraData()->nativePaintMode == QWExtra::BlitWriteAlpha;
+ if (!q->testAttribute(Qt::WA_TranslucentBackground) && !writeAlpha)
+ return;
+ const bool requireAlphaChannel = !isOpaque || writeAlpha;
+
createTLExtra();
RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow());
#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
- window->SetSurfaceTransparency(!isOpaque);
- extra->topextra->nativeWindowTransparencyEnabled = !isOpaque;
-#else
- if (!isOpaque) {
+ if (QApplicationPrivate::instance()->useTranslucentEGLSurfaces) {
+ window->SetSurfaceTransparency(!isOpaque);
+ extra->topextra->nativeWindowTransparencyEnabled = !isOpaque;
+ return;
+ }
+#endif
+ if (requireAlphaChannel) {
const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
if (window->SetTransparencyAlphaChannel() == KErrNone) {
window->SetBackgroundColor(TRgb(255, 255, 255, 0));
extra->topextra->nativeWindowTransparencyEnabled = 1;
-
- if (extra->topextra->backingStore.data() &&
- QApplicationPrivate::graphics_system_name == QLatin1String("openvg")) {
+ if (extra->topextra->backingStore.data() && (
+ QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
+ || QApplicationPrivate::graphics_system_name == QLatin1String("opengl"))) {
// Semi-transparent EGL surfaces aren't supported. We need to
// recreate backing store to get translucent surface (raster surface).
extra->topextra->backingStore.create(q);
@@ -825,7 +846,6 @@ void QWidgetPrivate::s60UpdateIsOpaque()
window->SetTransparentRegion(TRegionFix<1>());
extra->topextra->nativeWindowTransparencyEnabled = 0;
}
-#endif
}
void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
@@ -1041,7 +1061,7 @@ int QWidget::metric(PaintDeviceMetric m) const
} else if (m == PdmHeight) {
val = data->crect.height();
} else {
- CWsScreenDevice *scr = S60->screenDevice();
+ CWsScreenDevice *scr = S60->screenDevice(this);
switch(m) {
case PdmDpiX:
case PdmPhysicalDpiX:
@@ -1211,7 +1231,16 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint;
if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint) {
setAttribute(Qt::WA_OutsideWSRange, false);
- window->SetExtentToWholeScreen();
+ if (d->symbianScreenNumber > 0) {
+ int w = S60->screenWidthInPixelsForScreen[d->symbianScreenNumber];
+ int h = S60->screenHeightInPixelsForScreen[d->symbianScreenNumber];
+ if (w <= 0 || h <= 0)
+ window->SetExtentToWholeScreen();
+ else
+ window->SetExtent(TPoint(0, 0), TSize(w, h));
+ } else {
+ window->SetExtentToWholeScreen();
+ }
} else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint)) {
setAttribute(Qt::WA_OutsideWSRange, false);
TRect maxExtent = qt_QRect2TRect(qApp->desktop()->availableGeometry(this));
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index 4bff5ac..c6753fc 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -346,7 +346,7 @@ Q_GUI_EXPORT void qt_x11_enforce_cursor(QWidget * w)
qt_x11_enforce_cursor(w, false);
}
-Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
+void qt_x11_wait_for_window_manager(QWidget *w, bool sendPostedEvents)
{
if (!w || (!w->isWindow() && !w->internalWinId()))
return;
@@ -361,7 +361,8 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
WId winid = w->internalWinId();
// first deliver events that are already in the local queue
- QApplication::sendPostedEvents();
+ if (sendPostedEvents)
+ QApplication::sendPostedEvents();
// the normal sequence is:
// ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose
@@ -396,6 +397,11 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
} while(1);
}
+Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget *w)
+{
+ qt_x11_wait_for_window_manager(w, true);
+}
+
void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)
{
if (!w->isVisible()) // not managed by the window manager
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
index b6177b0..740bb82 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -150,6 +150,36 @@ void QWindowSystemInterface::handleKeyEvent(QWidget *tlw, ulong timestamp, QEven
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
+void QWindowSystemInterface::handleExtendedKeyEvent(QWidget *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+ quint32 nativeScanCode, quint32 nativeVirtualKey,
+ quint32 nativeModifiers,
+ const QString& text, bool autorep,
+ ushort count)
+{
+ unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
+ handleExtendedKeyEvent(w, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
+ text, autorep, count);
+}
+
+void QWindowSystemInterface::handleExtendedKeyEvent(QWidget *tlw, ulong timestamp, QEvent::Type type, int key,
+ Qt::KeyboardModifiers modifiers,
+ quint32 nativeScanCode, quint32 nativeVirtualKey,
+ quint32 nativeModifiers,
+ const QString& text, bool autorep,
+ ushort count)
+{
+ if (tlw) {
+ QWidgetData *data = qt_qwidget_data(tlw);
+ if (data->in_destructor)
+ tlw = 0;
+ }
+
+ QWindowSystemInterfacePrivate::KeyEvent * e =
+ new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers,
+ nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
+ QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
void QWindowSystemInterface::handleWheelEvent(QWidget *w, const QPoint & local, const QPoint & global, int d, Qt::Orientation o) {
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
handleWheelEvent(w, time, local, global, d, o);
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h
index 39c2f79..a882fc1 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -64,6 +64,17 @@ public:
static void handleKeyEvent(QWidget *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
static void handleKeyEvent(QWidget *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
+ static void handleExtendedKeyEvent(QWidget *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+ quint32 nativeScanCode, quint32 nativeVirtualKey,
+ quint32 nativeModifiers,
+ const QString& text = QString(), bool autorep = false,
+ ushort count = 1);
+ static void handleExtendedKeyEvent(QWidget *w, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+ quint32 nativeScanCode, quint32 nativeVirtualKey,
+ quint32 nativeModifiers,
+ const QString& text = QString(), bool autorep = false,
+ ushort count = 1);
+
static void handleWheelEvent(QWidget *w, const QPoint & local, const QPoint & global, int d, Qt::Orientation o);
static void handleWheelEvent(QWidget *w, ulong timestamp, const QPoint & local, const QPoint & global, int d, Qt::Orientation o);
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
index 3491a1a..6be86ad 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
@@ -142,13 +142,23 @@ public:
public:
KeyEvent(QWidget *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
:UserEvent(w, time, Key), key(k), unicode(text), repeat(autorep),
- repeatCount(count), modifiers(mods), keyType(t) { }
+ repeatCount(count), modifiers(mods), keyType(t),
+ nativeScanCode(0), nativeVirtualKey(0), nativeModifiers(0) { }
+ KeyEvent(QWidget *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods,
+ quint32 nativeSC, quint32 nativeVK, quint32 nativeMods,
+ const QString & text = QString(), bool autorep = false, ushort count = 1)
+ :UserEvent(w, time, Key), key(k), unicode(text), repeat(autorep),
+ repeatCount(count), modifiers(mods), keyType(t),
+ nativeScanCode(nativeSC), nativeVirtualKey(nativeVK), nativeModifiers(nativeMods) { }
int key;
QString unicode;
bool repeat;
ushort repeatCount;
Qt::KeyboardModifiers modifiers;
QEvent::Type keyType;
+ quint32 nativeScanCode;
+ quint32 nativeVirtualKey;
+ quint32 nativeModifiers;
};
class TouchEvent : public UserEvent {
diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp
index 7f5a937..1fccfc9 100644
--- a/src/gui/math3d/qvector2d.cpp
+++ b/src/gui/math3d/qvector2d.cpp
@@ -60,6 +60,11 @@ QT_BEGIN_NAMESPACE
The QVector2D class can also be used to represent vertices in 2D space.
We therefore do not need to provide a separate vertex class.
+ \bold{Note:} By design values in the QVector2D instance are stored as \c float.
+ This means that on platforms where the \c qreal arguments to QVector2D
+ functions are represented by \c double values, it is possible to
+ lose precision.
+
\sa QVector3D, QVector4D, QQuaternion
*/
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp
index 2414b5f..7bf0400 100644
--- a/src/gui/math3d/qvector3d.cpp
+++ b/src/gui/math3d/qvector3d.cpp
@@ -63,6 +63,11 @@ QT_BEGIN_NAMESPACE
The QVector3D class can also be used to represent vertices in 3D space.
We therefore do not need to provide a separate vertex class.
+ \bold{Note:} By design values in the QVector3D instance are stored as \c float.
+ This means that on platforms where the \c qreal arguments to QVector3D
+ functions are represented by \c double values, it is possible to
+ lose precision.
+
\sa QVector2D, QVector4D, QQuaternion
*/
diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp
index 74dedc4..23befc0 100644
--- a/src/gui/math3d/qvector4d.cpp
+++ b/src/gui/math3d/qvector4d.cpp
@@ -59,6 +59,11 @@ QT_BEGIN_NAMESPACE
The QVector4D class can also be used to represent vertices in 4D space.
We therefore do not need to provide a separate vertex class.
+ \bold{Note:} By design values in the QVector4D instance are stored as \c float.
+ This means that on platforms where the \c qreal arguments to QVector4D
+ functions are represented by \c double values, it is possible to
+ lose precision.
+
\sa QQuaternion, QVector2D, QVector3D
*/
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 51f2538..65e7af4 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -234,8 +234,10 @@ x11 {
}
!embedded:!qpa:mac {
- HEADERS += painting/qwindowsurface_mac_p.h
- SOURCES += painting/qwindowsurface_mac.cpp
+ HEADERS += painting/qwindowsurface_mac_p.h \
+ painting/qunifiedtoolbarsurface_mac_p.h
+ SOURCES += painting/qwindowsurface_mac.cpp \
+ painting/qunifiedtoolbarsurface_mac.cpp
}
embedded {
@@ -260,12 +262,6 @@ symbian {
QMAKE_CXXFLAGS.ARMCC *= -O3
}
-mac {
- HEADERS += painting/qunifiedtoolbarsurface_mac_p.h
- SOURCES += painting/qunifiedtoolbarsurface_mac.cpp
-}
-
-
NEON_SOURCES += painting/qdrawhelper_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 129bba5..e5d8abc 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -1143,6 +1143,11 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
return;
}
+ // If there's no partial update support we always need
+ // to do a full repaint before flushing
+ if (!windowSurface->hasPartialUpdateSupport())
+ fullUpdatePending = true;
+
// Nothing to repaint.
if (!isDirty()) {
qt_flush(exposedWidget, exposedRegion, windowSurface, tlw, tlwOffset);
diff --git a/src/gui/painting/qbackingstore_p.h b/src/gui/painting/qbackingstore_p.h
index 47387ab..39bf66c 100644
--- a/src/gui/painting/qbackingstore_p.h
+++ b/src/gui/painting/qbackingstore_p.h
@@ -262,7 +262,8 @@ private:
}
inline bool hasStaticContents() const
- { return !staticWidgets.isEmpty() && windowSurface->hasStaticContentsSupport(); }
+ { return !staticWidgets.isEmpty() && windowSurface->hasStaticContentsSupport()
+ && windowSurface->hasPartialUpdateSupport(); }
friend QRegion qt_dirtyRegion(QWidget *);
friend class QWidgetPrivate;
diff --git a/src/gui/painting/qblittable.cpp b/src/gui/painting/qblittable.cpp
index f4b84a9..5802531 100644
--- a/src/gui/painting/qblittable.cpp
+++ b/src/gui/painting/qblittable.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/painting/qblittable_p.h b/src/gui/painting/qblittable_p.h
index cb56cb2..9d0e822 100644
--- a/src/gui/painting/qblittable_p.h
+++ b/src/gui/painting/qblittable_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp
index 5841d40..46a6f81 100644
--- a/src/gui/painting/qgraphicssystem_runtime.cpp
+++ b/src/gui/painting/qgraphicssystem_runtime.cpp
@@ -319,6 +319,16 @@ QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const
return m_windowSurface->offset(widget);
}
+bool QRuntimeWindowSurface::hasStaticContentsSupport() const
+{
+ return m_windowSurface->hasStaticContentsSupport();
+}
+
+bool QRuntimeWindowSurface::hasPartialUpdateSupport() const
+{
+ return m_windowSurface->hasPartialUpdateSupport();
+}
+
QRuntimeGraphicsSystem::QRuntimeGraphicsSystem()
: m_windowSurfaceDestroyPolicy(DestroyImmediately),
m_graphicsSystem(0)
@@ -394,7 +404,10 @@ void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name)
if(m_windowSurfaceDestroyPolicy == DestroyAfterFirstFlush)
proxy->m_pendingWindowSurface.reset(proxy->m_windowSurface.take());
- proxy->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget));
+ QWindowSurface *newWindowSurface = m_graphicsSystem->createWindowSurface(widget);
+ newWindowSurface->setGeometry(proxy->geometry());
+
+ proxy->m_windowSurface.reset(newWindowSurface);
qt_widget_private(widget)->invalidateBuffer(widget->rect());
}
diff --git a/src/gui/painting/qgraphicssystem_runtime_p.h b/src/gui/painting/qgraphicssystem_runtime_p.h
index 30b4e3e..998fa98 100644
--- a/src/gui/painting/qgraphicssystem_runtime_p.h
+++ b/src/gui/painting/qgraphicssystem_runtime_p.h
@@ -129,6 +129,9 @@ public:
virtual QPoint offset(const QWidget *widget) const;
+ virtual bool hasStaticContentsSupport() const;
+ virtual bool hasPartialUpdateSupport() const;
+
QScopedPointer<QWindowSurface> m_windowSurface;
QScopedPointer<QWindowSurface> m_pendingWindowSurface;
diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp
index 5605fc1..62a60d7 100644
--- a/src/gui/painting/qgraphicssystemfactory.cpp
+++ b/src/gui/painting/qgraphicssystemfactory.cpp
@@ -45,6 +45,7 @@
#include "qmutex.h"
#include "qapplication.h"
+#include <private/qapplication_p.h>
#include "qgraphicssystem_raster_p.h"
#include "qgraphicssystem_runtime_p.h"
#include "qdebug.h"
@@ -79,6 +80,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key)
}
#endif
+ QApplicationPrivate::graphics_system_name = system;
if (system == QLatin1String("raster"))
return new QRasterGraphicsSystem;
else if (system == QLatin1String("runtime"))
diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp
index 2e8d9dd..500748e 100644
--- a/src/gui/painting/qpaintengine_blitter.cpp
+++ b/src/gui/painting/qpaintengine_blitter.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/painting/qpaintengine_blitter_p.h b/src/gui/painting/qpaintengine_blitter_p.h
index c8aa536..be8b2bc 100644
--- a/src/gui/painting/qpaintengine_blitter_p.h
+++ b/src/gui/painting/qpaintengine_blitter_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 8bff021..49f1a5f 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1724,7 +1724,7 @@ static void qt_painterpath_isect_line(const QPointF &p1,
}
static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
- int *winding)
+ int *winding, int depth = 0)
{
qreal y = pt.y();
qreal x = pt.x();
@@ -1739,7 +1739,7 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
// hit lower limit... This is a rough threshold, but its a
// tradeoff between speed and precision.
const qreal lower_bound = qreal(.001);
- if (bounds.width() < lower_bound && bounds.height() < lower_bound) {
+ if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound)) {
// We make the assumption here that the curve starts to
// approximate a line after while (i.e. that it doesn't
// change direction drastically during its slope)
@@ -1752,8 +1752,8 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
// split curve and try again...
QBezier first_half, second_half;
bezier.split(&first_half, &second_half);
- qt_painterpath_isect_curve(first_half, pt, winding);
- qt_painterpath_isect_curve(second_half, pt, winding);
+ qt_painterpath_isect_curve(first_half, pt, winding, depth + 1);
+ qt_painterpath_isect_curve(second_half, pt, winding, depth + 1);
}
}
diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp
index f262144..b7f5160 100644
--- a/src/gui/painting/qprintengine_pdf.cpp
+++ b/src/gui/painting/qprintengine_pdf.cpp
@@ -936,7 +936,7 @@ void QPdfEnginePrivate::writeInfo()
xprintf("\n/Creator ");
printString(creator);
xprintf("\n/Producer ");
- printString(QString::fromLatin1("Qt " QT_VERSION_STR " (C) 2010 Nokia Corporation and/or its subsidiary(-ies)"));
+ printString(QString::fromLatin1("Qt " QT_VERSION_STR " (C) 2011 Nokia Corporation and/or its subsidiary(-ies)"));
QDateTime now = QDateTime::currentDateTime().toUTC();
QTime t = now.time();
QDate d = now.date();
diff --git a/src/gui/painting/qprinterinfo_p.h b/src/gui/painting/qprinterinfo_p.h
index 7781d59..fcc1acb 100644
--- a/src/gui/painting/qprinterinfo_p.h
+++ b/src/gui/painting/qprinterinfo_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
index 02ba8db..3876c3d 100644
--- a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
+++ b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -55,7 +55,6 @@ QUnifiedToolbarSurface::QUnifiedToolbarSurface(QWidget *widget)
{
d_ptr->image = 0;
d_ptr->inSetGeometry = false;
- setStaticContentsSupport(true);
setGeometry(QRect(QPoint(0, 0), QSize(widget->width(), 100))); // FIXME: Fix height.
}
@@ -71,7 +70,7 @@ QPaintDevice *QUnifiedToolbarSurface::paintDevice()
return &d_ptr->image->image;
}
-void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, const QPoint &offset)
+void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, QWidget *parent_toolbar, const QPoint &offset)
{
if (object != 0) {
if (object->isWidgetType()) {
@@ -83,9 +82,10 @@ void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, const QPoint &of
widget->d_func()->unifiedSurface = this;
widget->d_func()->isInUnifiedToolbar = true;
widget->d_func()->toolbar_offset = offset;
+ widget->d_func()->toolbar_ancestor = parent_toolbar;
for (int i = 0; i < object->children().size(); ++i) {
- recursiveRedirect(object->children().at(i), offset);
+ recursiveRedirect(object->children().at(i), parent_toolbar, offset);
}
}
}
@@ -95,7 +95,35 @@ void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, const QPoint &of
void QUnifiedToolbarSurface::insertToolbar(QWidget *toolbar, const QPoint &offset)
{
setGeometry(QRect(QPoint(0, 0), QSize(offset.x() + toolbar->width(), 100))); // FIXME
- recursiveRedirect(toolbar, offset);
+ recursiveRedirect(toolbar, toolbar, offset);
+}
+
+// We basically undo what we set in recursiveRedirect().
+void QUnifiedToolbarSurface::recursiveRemoval(QObject *object)
+{
+ if (object != 0) {
+ if (object->isWidgetType()) {
+ QWidget *widget = qobject_cast<QWidget *>(object);
+
+ // If it's a pop-up or something similar, we don't redirect it.
+ if (widget->windowType() & Qt::Window)
+ return;
+
+ widget->d_func()->unifiedSurface = 0;
+ widget->d_func()->isInUnifiedToolbar = false;
+ widget->d_func()->toolbar_offset = QPoint();
+ widget->d_func()->toolbar_ancestor = 0;
+ }
+
+ for (int i = 0; i < object->children().size(); ++i) {
+ recursiveRemoval(object->children().at(i));
+ }
+ }
+}
+
+void QUnifiedToolbarSurface::removeToolbar(QToolBar *toolbar)
+{
+ recursiveRemoval(toolbar);
}
void QUnifiedToolbarSurface::setGeometry(const QRect &rect)
@@ -127,70 +155,25 @@ void QUnifiedToolbarSurface::updateToolbarOffset(QWidget *widget)
mlayout->updateUnifiedToolbarOffset();
}
-void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
+void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
{
- Q_D(QUnifiedToolbarSurface);
-
- QRegion flushingRegion(widget->rect());
-
- if (!d->image || rgn.rectCount() == 0) {
- return;
- }
-
+ Q_UNUSED(region);
Q_UNUSED(offset);
- // Get a context for the widget.
- CGContextRef context;
- if (!(widget->d_func()->hasOwnContext)) {
- widget->d_func()->ut_rg = rgn;
- widget->d_func()->ut_pt = offset;
- qt_mac_display(widget);
- return;
- } else {
- // We render the content of the toolbar in the surface.
- updateToolbarOffset(widget);
- QRect beginPaintRect(widget->d_func()->toolbar_offset.x(), widget->d_func()->toolbar_offset.y(), widget->geometry().width(), widget->geometry().height());
- QRegion beginPaintRegion(beginPaintRect);
-
- context = widget->d_func()->cgContext;
- beginPaint(beginPaintRegion);
- widget->render(widget->d_func()->unifiedSurface->paintDevice(), widget->d_func()->toolbar_offset, QRegion(), QWidget::DrawChildren);
- }
+ this->flush(widget);
+}
- CGContextSaveGState(context);
+void QUnifiedToolbarSurface::flush(QWidget *widget)
+{
+ Q_D(QUnifiedToolbarSurface);
- int areaX = widget->d_func()->toolbar_offset.x();
- int areaY = widget->d_func()->toolbar_offset.y();
- int areaWidth = widget->geometry().width();
- int areaHeight = widget->geometry().height();
- const CGRect area = CGRectMake(areaX, areaY, areaWidth, areaHeight);
+ if (!d->image)
+ return;
- // Clip to region.
- const QVector<QRect> &rects = flushingRegion.rects();
- for (int i = 0; i < rects.size(); ++i) {
- const QRect &rect = rects.at(i);
- CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()));
+ if (widget->d_func()->flushRequested) {
+ // We call display: directly to avoid flickering in the toolbar.
+ qt_mac_display(widget);
}
- CGContextAddRect(context, area);
- CGContextClip(context);
-
-
- CGImageRef image = CGBitmapContextCreateImage(d->image->cg);
- CGImageRef subImage = CGImageCreateWithImageInRect(image, area);
-
- const CGRect drawingArea = CGRectMake(0, 0, areaWidth, areaHeight);
- qt_mac_drawCGImage(context, &drawingArea, subImage);
-
- CGImageRelease(subImage);
- CGImageRelease(image);
-
- CGContextFlush(context);
-
- // Restore context.
- CGContextRestoreGState(context);
- CGContextRelease(context);
- widget->d_func()->cgContext = 0;
- widget->d_func()->hasOwnContext = false;
}
void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widget)
@@ -198,7 +181,7 @@ void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widge
Q_D(QUnifiedToolbarSurface);
int width = geometry().width();
- int height = geometry().height();
+ int height = 100; // FIXME
if (d->image) {
width = qMax(d->image->width(), width);
height = qMax(d->image->height(), height);
@@ -254,6 +237,28 @@ void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widge
delete oldImage;
}
+CGContextRef QUnifiedToolbarSurface::imageContext()
+{
+ Q_D(QUnifiedToolbarSurface);
+ return d->image->cg;
+}
+
+void QUnifiedToolbarSurface::renderToolbar(QWidget *widget, bool forceFlush)
+{
+ QWidget *toolbar = widget->d_func()->toolbar_ancestor;
+
+ updateToolbarOffset(toolbar);
+ QRect beginPaintRect(toolbar->d_func()->toolbar_offset.x(), toolbar->d_func()->toolbar_offset.y(), toolbar->geometry().width(), toolbar->geometry().height());
+ QRegion beginPaintRegion(beginPaintRect);
+
+ beginPaint(beginPaintRegion);
+ toolbar->render(paintDevice(), toolbar->d_func()->toolbar_offset, QRegion(toolbar->geometry()), QWidget::DrawChildren);
+ toolbar->d_func()->flushRequested = true;
+
+ if (forceFlush)
+ flush(toolbar);
+}
+
QT_END_NAMESPACE
#endif // QT_MAC_USE_COCOA
diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h
index 3bc0404..0a7ebf1 100644
--- a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h
+++ b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -55,6 +55,7 @@
#include <private/qwindowsurface_raster_p.h>
#include <QWidget>
+#include <QToolBar>
#include <private/qwidget_p.h>
#include <private/qnativeimage_p.h>
@@ -78,16 +79,22 @@ public:
QUnifiedToolbarSurface(QWidget *widget);
~QUnifiedToolbarSurface();
+ void flush(QWidget *widget);
void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
void setGeometry(const QRect &rect);
void beginPaint(const QRegion &rgn);
void insertToolbar(QWidget *toolbar, const QPoint &offset);
+ void removeToolbar(QToolBar *toolbar);
+ void updateToolbarOffset(QWidget *widget);
+ void renderToolbar(QWidget *widget, bool forceFlush = false);
+ void recursiveRedirect(QObject *widget, QWidget *parent_toolbar, const QPoint &offset);
-private:
QPaintDevice *paintDevice();
- void updateToolbarOffset(QWidget *widget);
+ CGContextRef imageContext();
+
+private:
void prepareBuffer(QImage::Format format, QWidget *widget);
- void recursiveRedirect(QObject *widget, const QPoint &offset);
+ void recursiveRemoval(QObject *object);
Q_DECLARE_PRIVATE(QUnifiedToolbarSurface)
QScopedPointer<QUnifiedToolbarSurfacePrivate> d_ptr;
diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp
index 029b9dc..9b71818 100644
--- a/src/gui/painting/qwindowsurface.cpp
+++ b/src/gui/painting/qwindowsurface.cpp
@@ -52,8 +52,6 @@ class QWindowSurfacePrivate
public:
QWindowSurfacePrivate(QWidget *w)
: window(w)
- , staticContentsSupport(0)
- , partialUpdateSupport(1)
{
}
@@ -65,8 +63,6 @@ public:
#endif //Q_WS_QPA
QRegion staticContents;
QList<QImage*> bufferImages;
- uint staticContentsSupport : 1;
- uint partialUpdateSupport : 1;
};
/*!
@@ -313,16 +309,7 @@ QPoint QWindowSurface::offset(const QWidget *widget) const
bool QWindowSurface::hasStaticContentsSupport() const
{
- return d_ptr->staticContentsSupport;
-}
-
-void QWindowSurface::setStaticContentsSupport(bool enable)
-{
- if (enable && !d_ptr->partialUpdateSupport) {
- qWarning("QWindowSurface::setStaticContentsSupport: static contents support requires partial update support");
- return;
- }
- d_ptr->staticContentsSupport = enable;
+ return false;
}
void QWindowSurface::setStaticContents(const QRegion &region)
@@ -337,21 +324,12 @@ QRegion QWindowSurface::staticContents() const
bool QWindowSurface::hasStaticContents() const
{
- return d_ptr->staticContentsSupport && !d_ptr->staticContents.isEmpty();
+ return hasStaticContentsSupport() && !d_ptr->staticContents.isEmpty();
}
bool QWindowSurface::hasPartialUpdateSupport() const
{
- return d_ptr->partialUpdateSupport;
-}
-
-void QWindowSurface::setPartialUpdateSupport(bool enable)
-{
- if (!enable && d_ptr->staticContentsSupport) {
- qWarning("QWindowSurface::setPartialUpdateSupport: static contents support requires partial update support");
- return;
- }
- d_ptr->partialUpdateSupport = enable;
+ return true;
}
#ifdef Q_WS_QPA
diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h
index 62137ef..4a2775f 100644
--- a/src/gui/painting/qwindowsurface_p.h
+++ b/src/gui/painting/qwindowsurface_p.h
@@ -100,16 +100,14 @@ public:
virtual QPoint offset(const QWidget *widget) const;
inline QRect rect(const QWidget *widget) const;
- bool hasStaticContentsSupport() const;
- bool hasPartialUpdateSupport() const;
+ virtual bool hasStaticContentsSupport() const;
+ virtual bool hasPartialUpdateSupport() const;
void setStaticContents(const QRegion &region);
QRegion staticContents() const;
protected:
bool hasStaticContents() const;
- void setStaticContentsSupport(bool enable);
- void setPartialUpdateSupport(bool enable);
private:
QWindowSurfacePrivate *d_ptr;
diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp
index 419518ac..a5c45c0 100644
--- a/src/gui/painting/qwindowsurface_raster.cpp
+++ b/src/gui/painting/qwindowsurface_raster.cpp
@@ -103,7 +103,11 @@ QRasterWindowSurface::QRasterWindowSurface(QWidget *window, bool setDefaultSurfa
#endif
d_ptr->image = 0;
d_ptr->inSetGeometry = false;
- setStaticContentsSupport(true);
+
+#ifdef QT_MAC_USE_COCOA
+ needsFlush = false;
+ regionToFlush = QRegion();
+#endif // QT_MAC_USE_COCOA
}
@@ -272,41 +276,26 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
#ifdef Q_WS_MAC
+ Q_UNUSED(offset);
+
// This is mainly done for native components like native "open file" dialog.
if (widget->testAttribute(Qt::WA_DontShowOnScreen)) {
return;
}
#ifdef QT_MAC_USE_COCOA
- // Unified toolbar hack.
- QMainWindow* mWindow = qobject_cast<QMainWindow*>(widget->window());
- if (mWindow) {
- QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout());
- QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList;
- for (int i = 0; i < toolbarList.size(); ++i) {
- QToolBar* toolbar = toolbarList.at(i);
- if (mLayout->toolBarArea(toolbar) == Qt::TopToolBarArea) {
- QWidget* tbWidget = (QWidget*) toolbar;
- if (tbWidget->d_func()->unifiedSurface) {
- tbWidget->d_func()->unifiedSurface->flush(tbWidget, rgn, offset);
- }
- }
- }
- }
-#endif // QT_MAC_USE_COCOA
+ this->needsFlush = true;
+ this->regionToFlush += rgn;
- Q_UNUSED(offset);
+ // The actual flushing will be processed in [view drawRect:rect]
+ qt_mac_setNeedsDisplay(widget);
+
+#else
// Get a context for the widget.
-#ifndef QT_MAC_USE_COCOA
CGContextRef context;
CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
QDBeginCGContext(port, &context);
-#else
- QMacCocoaAutoReleasePool pool;
- extern CGContextRef qt_mac_graphicsContextFor(QWidget *);
- CGContextRef context = qt_mac_graphicsContextFor(widget);
-#endif
CGContextRetain(context);
CGContextSaveGState(context);
@@ -332,16 +321,12 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
CGImageRelease(subImage);
CGImageRelease(image);
-#ifndef QT_MAC_USE_COCOA
QDEndCGContext(port, &context);
-#else
- CGContextFlush(context);
-#endif
// Restore context.
CGContextRestoreGState(context);
CGContextRelease(context);
-
+#endif // QT_MAC_USE_COCOA
#endif // Q_WS_MAC
@@ -425,6 +410,11 @@ bool QRasterWindowSurface::scroll(const QRegion &area, int dx, int dy)
#endif
}
+bool QRasterWindowSurface::hasStaticContentsSupport() const
+{
+ return true;
+}
+
void QRasterWindowSurface::prepareBuffer(QImage::Format format, QWidget *widget)
{
@@ -487,4 +477,12 @@ void QRasterWindowSurface::prepareBuffer(QImage::Format format, QWidget *widget)
delete oldImage;
}
+#ifdef QT_MAC_USE_COCOA
+CGContextRef QRasterWindowSurface::imageContext()
+{
+ Q_D(QRasterWindowSurface);
+ return d->image->cg;
+}
+#endif // QT_MAC_USE_COCOA
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qwindowsurface_raster_p.h b/src/gui/painting/qwindowsurface_raster_p.h
index 903810b..669511d 100644
--- a/src/gui/painting/qwindowsurface_raster_p.h
+++ b/src/gui/painting/qwindowsurface_raster_p.h
@@ -56,6 +56,10 @@
#include <qglobal.h>
#include "private/qwindowsurface_p.h"
+#ifdef QT_MAC_USE_COCOA
+# include <private/qt_cocoa_helpers_mac_p.h>
+#endif // QT_MAC_USE_COCOA
+
QT_BEGIN_NAMESPACE
#ifdef Q_WS_WIN
@@ -105,6 +109,14 @@ public:
void beginPaint(const QRegion &rgn);
void setGeometry(const QRect &rect);
bool scroll(const QRegion &area, int dx, int dy);
+ bool hasStaticContentsSupport() const;
+
+#ifdef QT_MAC_USE_COCOA
+ CGContextRef imageContext();
+
+ bool needsFlush;
+ QRegion regionToFlush;
+#endif // QT_MAC_USE_COCOA
private:
#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index 71556d7..4fa25cb 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -63,7 +63,6 @@ struct QS60WindowSurfacePrivate
TDisplayMode displayMode(bool opaque)
{
-
TDisplayMode mode = S60->screenDevice()->DisplayMode();
if (opaque) {
mode = EColor16MU;
@@ -76,10 +75,18 @@ TDisplayMode displayMode(bool opaque)
return mode;
}
+bool blitWriteAlpha(QWidgetPrivate *widgetPrivate)
+{
+ QWExtra *extra = widgetPrivate->extraData();
+ return extra ? extra->nativePaintMode == QWExtra::BlitWriteAlpha : false;
+}
+
QS60WindowSurface::QS60WindowSurface(QWidget* widget)
: QWindowSurface(widget), d_ptr(new QS60WindowSurfacePrivate)
{
- TDisplayMode mode = displayMode(qt_widget_private(widget)->isOpaque);
+ QWidgetPrivate *widgetPrivate = qt_widget_private(widget);
+ const bool opaque = widgetPrivate->isOpaque && !blitWriteAlpha(widgetPrivate);
+ TDisplayMode mode = displayMode(opaque);
// We create empty CFbsBitmap here -> it will be resized in setGeometry
CFbsBitmap *bitmap = new CFbsBitmap; // CBase derived object needs check on new
Q_CHECK_PTR(bitmap);
@@ -90,8 +97,6 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget)
data->fromSymbianBitmap(bitmap, true);
d_ptr->device = QPixmap(data);
}
-
- setStaticContentsSupport(true);
}
QS60WindowSurface::~QS60WindowSurface()
@@ -124,7 +129,8 @@ void QS60WindowSurface::beginPaint(const QRegion &rgn)
S60->wsSession().Finish();
#endif
- if (!qt_widget_private(window())->isOpaque) {
+ QWidgetPrivate *windowPrivate = qt_widget_private(window());
+ if (!windowPrivate->isOpaque || blitWriteAlpha(windowPrivate)) {
QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data());
TDisplayMode mode = displayMode(false);
@@ -133,12 +139,14 @@ void QS60WindowSurface::beginPaint(const QRegion &rgn)
pixmapData->beginDataAccess();
- QPainter p(&pixmapData->image);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- const QVector<QRect> rects = rgn.rects();
- const QColor blank = Qt::transparent;
- for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- p.fillRect(*it, blank);
+ if (!windowPrivate->isOpaque) {
+ QPainter p(&pixmapData->image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ const QVector<QRect> rects = rgn.rects();
+ const QColor blank = Qt::transparent;
+ for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+ p.fillRect(*it, blank);
+ }
}
pixmapData->endDataAccess();
@@ -231,6 +239,11 @@ void QS60WindowSurface::setGeometry(const QRect& rect)
QWindowSurface::setGeometry(rect);
}
+bool QS60WindowSurface::hasStaticContentsSupport() const
+{
+ return true;
+}
+
CFbsBitmap* QS60WindowSurface::symbianBitmap() const
{
QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data());
diff --git a/src/gui/painting/qwindowsurface_s60_p.h b/src/gui/painting/qwindowsurface_s60_p.h
index d0d4925..f730c87 100644
--- a/src/gui/painting/qwindowsurface_s60_p.h
+++ b/src/gui/painting/qwindowsurface_s60_p.h
@@ -79,6 +79,8 @@ public:
void setGeometry(const QRect &rect);
+ bool hasStaticContentsSupport() const;
+
CFbsBitmap *symbianBitmap() const;
private:
diff --git a/src/gui/painting/qwindowsurface_x11.cpp b/src/gui/painting/qwindowsurface_x11.cpp
index 2324bc2..ab4f53e 100644
--- a/src/gui/painting/qwindowsurface_x11.cpp
+++ b/src/gui/painting/qwindowsurface_x11.cpp
@@ -70,9 +70,6 @@ QX11WindowSurface::QX11WindowSurface(QWidget *widget)
#ifndef QT_NO_XRENDER
d_ptr->translucentBackground = X11->use_xrender
&& widget->x11Info().depth() == 32;
- setStaticContentsSupport(!d_ptr->translucentBackground);
-#else
- setStaticContentsSupport(true);
#endif
}
@@ -253,4 +250,13 @@ QPixmap QX11WindowSurface::grabWidget(const QWidget *widget,
return px;
}
+bool QX11WindowSurface::hasStaticContentsSupport() const
+{
+#ifndef QT_NO_XRENDER
+ return !d_ptr->translucentBackground;
+#else
+ return true;
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qwindowsurface_x11_p.h b/src/gui/painting/qwindowsurface_x11_p.h
index 88753ea..d5179dd 100644
--- a/src/gui/painting/qwindowsurface_x11_p.h
+++ b/src/gui/painting/qwindowsurface_x11_p.h
@@ -80,6 +80,7 @@ public:
bool scroll(const QRegion &area, int dx, int dy);
QPixmap grabWidget(const QWidget *widget,
const QRect& rectangle = QRect()) const;
+ bool hasStaticContentsSupport() const;
private:
QX11WindowSurfacePrivate *d_ptr;
GC gc;
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 64722c7..2d21628 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -3084,7 +3084,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
}
break;
case PE_PanelScrollAreaCorner: {
- const QBrush brush(qApp->palette().brush(QPalette::Base));
+ const QBrush brush(opt->palette.brush(QPalette::Base));
p->fillRect(opt->rect, brush);
p->setPen(QPen(QColor(217, 217, 217)));
p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index ecc2539..7a89478 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -118,6 +118,7 @@ const short *QS60StylePrivate::m_pmPointer = QS60StylePrivate::data[0];
// theme background texture
QPixmap *QS60StylePrivate::m_background = 0;
+QPixmap *QS60StylePrivate::m_placeHolderTexture = 0;
// theme palette
QPalette *QS60StylePrivate::m_themePalette = 0;
@@ -155,6 +156,10 @@ const double KTabFontMul = 0.72;
QS60StylePrivate::~QS60StylePrivate()
{
clearCaches(); //deletes also background image
+ if (m_placeHolderTexture) {
+ delete m_placeHolderTexture;
+ m_placeHolderTexture = 0;
+ }
deleteThemePalette();
#ifdef Q_WS_S60
removeAnimations();
@@ -505,7 +510,10 @@ void QS60StylePrivate::setBackgroundTexture(QApplication *app) const
{
Q_UNUSED(app)
QPalette applicationPalette = QApplication::palette();
- applicationPalette.setBrush(QPalette::Window, backgroundTexture());
+ // The initial QPalette::Window is just a placeHolder QPixmap to save RAM
+ // if the actual texture is not needed. The real texture is created just before
+ // painting it in qt_s60_fill_background().
+ applicationPalette.setBrush(QPalette::Window, placeHolderTexture());
setThemePalette(&applicationPalette);
}
@@ -630,25 +638,6 @@ QPixmap QS60StylePrivate::cachedFrame(SkinFrameElements frame, const QSize &size
return result;
}
-void QS60StylePrivate::refreshUI()
-{
- QList<QWidget *> widgets = QApplication::allWidgets();
-
- for (int i = 0; i < widgets.size(); ++i) {
- QWidget *widget = widgets.at(i);
- if (widget == 0)
- continue;
-
- if (widget->style()) {
- widget->style()->polish(widget);
- QEvent event(QEvent::StyleChange);
- qApp->sendEvent(widget, &event);
- }
- widget->update();
- widget->updateGeometry();
- }
-}
-
void QS60StylePrivate::setFont(QWidget *widget) const
{
QS60StyleEnums::FontCategories fontCategory = QS60StyleEnums::FC_Undefined;
@@ -678,7 +667,7 @@ void QS60StylePrivate::setFont(QWidget *widget) const
}
}
-void QS60StylePrivate::setThemePalette(QWidget *widget) const
+void QS60StylePrivate::setThemePalette(QWidget *widget)
{
if(!widget)
return;
@@ -719,8 +708,10 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const
palette->setColor(QPalette::LinkVisited, palette->color(QPalette::Link).darker());
palette->setColor(QPalette::Highlight,
s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0));
- // set background image as a texture brush
- palette->setBrush(QPalette::Window, backgroundTexture());
+ // The initial QPalette::Window is just a placeHolder QPixmap to save RAM
+ // if the actual texture is not needed. The real texture is created just before
+ // painting it in qt_s60_fill_background().
+ palette->setBrush(QPalette::Window, placeHolderTexture());
// set as transparent so that styled full screen theme background is visible
palette->setBrush(QPalette::Base, Qt::transparent);
// set button color based on pixel colors
@@ -761,7 +752,7 @@ void QS60StylePrivate::storeThemePalette(QPalette *palette)
}
// set widget specific palettes
-void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
+void QS60StylePrivate::setThemePaletteHash(QPalette *palette)
{
if (!palette)
return;
@@ -2643,10 +2634,13 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
//native items have small empty areas at the beginning and end of menu item
sz.setWidth(sz.width() + 2 * pixelMetric(PM_MenuHMargin) + 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth));
- if (QS60StylePrivate::isTouchSupported())
+ if (QS60StylePrivate::isTouchSupported()) {
//Make itemview easier to use in touch devices
+ sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin));
//QCommonStyle does not adjust height with horizontal margin, it only adjusts width
- sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin) - 8); //QCommonstyle adds 8 to height that this style handles through PM values
+ if (ct == CT_MenuItem)
+ sz.setHeight(sz.height() - 8); //QCommonstyle adds 8 to height that this style handles through PM values
+ }
break;
#ifndef QT_NO_COMBOBOX
case CT_ComboBox: {
@@ -3545,10 +3539,18 @@ extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget);
bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
{
- const QPixmap backgroundTexture(QS60StylePrivate::backgroundTexture());
- if (backgroundTexture.cacheKey() != brush.texture().cacheKey())
+ // Check if the widget's palette matches placeholder or actual background texture.
+ // When accessing backgroundTexture, use parameter value 'true' to avoid creating
+ // the texture, if it is not already created.
+
+ const QPixmap placeHolder(QS60StylePrivate::placeHolderTexture());
+ const QPixmap bg(QS60StylePrivate::backgroundTexture(true));
+ if (placeHolder.cacheKey() != brush.texture().cacheKey()
+ && bg.cacheKey() != brush.texture().cacheKey())
return false;
+ const QPixmap backgroundTexture(QS60StylePrivate::backgroundTexture());
+
const QPaintDevice *target = painter->device();
if (target->devType() == QInternal::Widget) {
const QWidget *widget = static_cast<const QWidget *>(target);
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index 242c451..3628b27 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/gui/styles/qs60style_p.h
@@ -554,7 +554,8 @@ public:
static QPixmap frame(SkinFrameElements frame, const QSize &size,
SkinElementFlags flags = KDefaultSkinElementFlags);
- static QPixmap backgroundTexture();
+ static QPixmap backgroundTexture(bool skipCreation = false);
+ static QPixmap placeHolderTexture();
#ifdef Q_WS_S60
void handleDynamicLayoutVariantSwitch();
@@ -592,13 +593,11 @@ private:
static QPixmap cachedFrame(SkinFrameElements frame, const QSize &size,
SkinElementFlags flags = KDefaultSkinElementFlags);
- static void refreshUI();
-
// set S60 font for widget
void setFont(QWidget *widget) const;
- void setThemePalette(QWidget *widget) const;
+ static void setThemePalette(QWidget *widget);
void setThemePalette(QPalette *palette) const;
- void setThemePaletteHash(QPalette *palette) const;
+ static void setThemePaletteHash(QPalette *palette);
static void storeThemePalette(QPalette *palette);
static void deleteThemePalette();
static bool equalToThemePalette(QColor color, QPalette::ColorRole role);
@@ -616,6 +615,9 @@ private:
// Contains background texture.
static QPixmap *m_background;
+ // Placeholder pixmap for the real background texture.
+ static QPixmap *m_placeHolderTexture;
+
const static SkinElementFlags KDefaultSkinElementFlags;
// defined theme palette
static QPalette *m_themePalette;
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index 600c631..c5149a3 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -66,7 +66,6 @@
#include <aknnavi.h>
#include <gulicon.h>
#include <AknBitmapAnimation.h>
-
#include <centralrepository.h>
#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
@@ -640,13 +639,14 @@ QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask
QPixmap pixmap;
QScopedPointer<QPixmapData> pd(QPixmapData::create(0, 0, QPixmapData::PixmapType));
- bool nativeMaskSupported = (pd->toNativeType(QPixmapData::VolatileImage) != 0);
- if (mask && nativeMaskSupported) {
- // Efficient path, less copying and conversion.
+ if (mask) {
+ // Try the efficient path with less copying and conversion.
QVolatileImage img(icon, mask);
pd->fromNativeType(&img, QPixmapData::VolatileImage);
- pixmap = QPixmap(pd.take());
- } else {
+ if (!pd->isNull())
+ pixmap = QPixmap(pd.take());
+ }
+ if (pixmap.isNull()) {
// Potentially more expensive path.
pd->fromNativeType(icon, QPixmapData::FbsBitmap);
pixmap = QPixmap(pd.take());
@@ -1391,7 +1391,7 @@ QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, Skin
return result;
}
-QPixmap QS60StylePrivate::backgroundTexture()
+QPixmap QS60StylePrivate::backgroundTexture(bool skipCreation)
{
bool createNewBackground = false;
TRect applicationRect = (static_cast<CEikAppUi*>(S60->appUi())->ApplicationRect());
@@ -1406,14 +1406,40 @@ QPixmap QS60StylePrivate::backgroundTexture()
}
}
- if (createNewBackground) {
+ if (createNewBackground && !skipCreation) {
QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen,
- QSize(applicationRect.Width(), applicationRect.Height()), 0, SkinElementFlags());
+ QSize(applicationRect.Width(), applicationRect.Height()), 0, SkinElementFlags());
m_background = new QPixmap(background);
+
+ // Notify all widgets that palette is updated with the actual background texture.
+ QPalette pal = QApplication::palette();
+ pal.setBrush(QPalette::Window, *m_background);
+ QApplication::setPalette(pal);
+ setThemePaletteHash(&pal);
+ storeThemePalette(&pal);
+ foreach (QWidget *widget, QApplication::allWidgets()){
+ QEvent e(QEvent::PaletteChange);
+ QApplication::sendEvent(widget, &e);
+ setThemePalette(widget);
+ widget->ensurePolished();
+ }
}
+ if (!m_background)
+ return QPixmap();
return *m_background;
}
+// Generates 1*1 white pixmap as a placeholder for real texture.
+// The actual theme texture is drawn in qt_s60_fill_background().
+QPixmap QS60StylePrivate::placeHolderTexture()
+{
+ if (!m_placeHolderTexture) {
+ m_placeHolderTexture = new QPixmap(1,1);
+ m_placeHolderTexture->fill(Qt::white);
+ }
+ return *m_placeHolderTexture;
+}
+
QSize QS60StylePrivate::screenSize()
{
return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels);
@@ -1428,8 +1454,8 @@ QS60Style::QS60Style()
void QS60StylePrivate::handleDynamicLayoutVariantSwitch()
{
clearCaches(QS60StylePrivate::CC_LayoutChange);
+ setBackgroundTexture(qApp);
setActiveLayout();
- refreshUI();
foreach (QWidget *widget, QApplication::allWidgets())
widget->ensurePolished();
}
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp
index 77e0d0e..7223c6b 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/gui/styles/qs60style_simulated.cpp
@@ -308,7 +308,7 @@ QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size,
return result;
}
-QPixmap QS60StylePrivate::backgroundTexture()
+QPixmap QS60StylePrivate::backgroundTexture(bool /*skipCreation*/)
{
if (!m_background) {
const QSize size = QApplication::desktop()->screen()->size();
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 64eb27a..f77e237 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -383,6 +383,9 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
if (! (mask & QFont::StretchResolved))
request.stretch = other->request.stretch;
+ if (! (mask & QFont::HintingPreferenceResolved))
+ request.hintingPreference = other->request.hintingPreference;
+
if (! (mask & QFont::UnderlineResolved))
underline = other->underline;
@@ -917,6 +920,105 @@ int QFont::pointSize() const
}
/*!
+ \since 4.8
+
+ \enum QFont::HintingPreference
+
+ This enum describes the different levels of hinting that can be applied
+ to glyphs to improve legibility on displays where it might be warranted
+ by the density of pixels.
+
+ \value PreferDefaultHinting Use the default hinting level for the target platform.
+ \value PreferNoHinting If possible, render text without hinting the outlines
+ of the glyphs. The text layout will be typographically accurate and
+ scalable, using the same metrics as are used e.g. when printing.
+ \value PreferVerticalHinting If possible, render text with no horizontal hinting,
+ but align glyphs to the pixel grid in the vertical direction. The text will appear
+ crisper on displays where the density is too low to give an accurate rendering
+ of the glyphs. But since the horizontal metrics of the glyphs are unhinted, the text's
+ layout will be scalable to higher density devices (such as printers) without impacting
+ details such as line breaks.
+ \value PreferFullHinting If possible, render text with hinting in both horizontal and
+ vertical directions. The text will be altered to optimize legibility on the target
+ device, but since the metrics will depend on the target size of the text, the positions
+ of glyphs, line breaks, and other typographical detail will not scale, meaning that a
+ text layout may look different on devices with different pixel densities.
+
+ Please note that this enum only describes a preference, as the full range of hinting levels
+ are not supported on all of Qt's supported platforms. The following table details the effect
+ of a given hinting preference on a selected set of target platforms.
+
+ \table
+ \header
+ \o
+ \o PreferDefaultHinting
+ \o PreferNoHinting
+ \o PreferVerticalHinting
+ \o PreferFullHinting
+ \row
+ \o Windows Vista (w/o Platform Update) and earlier
+ \o Full hinting
+ \o Full hinting
+ \o Full hinting
+ \o Full hinting
+ \row
+ \o Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt
+ \o Full hinting
+ \o Vertical hinting
+ \o Vertical hinting
+ \o Full hinting
+ \row
+ \o FreeType
+ \o Operating System setting
+ \o No hinting
+ \o Vertical hinting (light)
+ \o Full hinting
+ \row
+ \o Cocoa on Mac OS X
+ \o No hinting
+ \o No hinting
+ \o No hinting
+ \o No hinting
+ \endtable
+
+ \note Please be aware that altering the hinting preference on Windows is available through
+ the DirectWrite font engine. This is available on Windows Vista after installing the platform
+ update, and on Windows 7. In order to use this extension, configure Qt using -directwrite.
+ The target application will then depend on the availability of DirectWrite on the target
+ system.
+
+*/
+
+/*!
+ \since 4.8
+
+ Set the preference for the hinting level of the glyphs to \a hintingPreference. This is a hint
+ to the underlying font rendering system to use a certain level of hinting, and has varying
+ support across platforms. See the table in the documentation for QFont::HintingPreference for
+ more details.
+
+ The default hinting preference is QFont::PreferDefaultHinting.
+*/
+void QFont::setHintingPreference(HintingPreference hintingPreference)
+{
+ detach();
+
+ d->request.hintingPreference = hintingPreference;
+
+ resolve_mask |= QFont::HintingPreferenceResolved;
+}
+
+/*!
+ \since 4.8
+
+ Returns the currently preferred hinting level for glyphs rendered with this font.
+*/
+QFont::HintingPreference QFont::hintingPreference() const
+{
+ return QFont::HintingPreference(d->request.hintingPreference);
+}
+
+/*!
Sets the point size to \a pointSize. The point size must be
greater than zero.
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index e7e8a40..8dbc746 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -93,6 +93,13 @@ public:
NoFontMerging = 0x8000
};
+ enum HintingPreference {
+ PreferDefaultHinting = 0,
+ PreferNoHinting = 1,
+ PreferVerticalHinting = 2,
+ PreferFullHinting = 3
+ };
+
enum Weight {
Light = 25,
Normal = 50,
@@ -133,22 +140,23 @@ public:
};
enum ResolveProperties {
- FamilyResolved = 0x0001,
- SizeResolved = 0x0002,
- StyleHintResolved = 0x0004,
- StyleStrategyResolved = 0x0008,
- WeightResolved = 0x0010,
- StyleResolved = 0x0020,
- UnderlineResolved = 0x0040,
- OverlineResolved = 0x0080,
- StrikeOutResolved = 0x0100,
- FixedPitchResolved = 0x0200,
- StretchResolved = 0x0400,
- KerningResolved = 0x0800,
- CapitalizationResolved = 0x1000,
- LetterSpacingResolved = 0x2000,
- WordSpacingResolved = 0x4000,
- AllPropertiesResolved = 0x7fff
+ FamilyResolved = 0x0001,
+ SizeResolved = 0x0002,
+ StyleHintResolved = 0x0004,
+ StyleStrategyResolved = 0x0008,
+ WeightResolved = 0x0010,
+ StyleResolved = 0x0020,
+ UnderlineResolved = 0x0040,
+ OverlineResolved = 0x0080,
+ StrikeOutResolved = 0x0100,
+ FixedPitchResolved = 0x0200,
+ StretchResolved = 0x0400,
+ KerningResolved = 0x0800,
+ CapitalizationResolved = 0x1000,
+ LetterSpacingResolved = 0x2000,
+ WordSpacingResolved = 0x4000,
+ HintingPreferenceResolved = 0x8000,
+ AllPropertiesResolved = 0xffff
};
QFont();
@@ -213,6 +221,9 @@ public:
void setCapitalization(Capitalization);
Capitalization capitalization() const;
+ void setHintingPreference(HintingPreference hintingPreference);
+ HintingPreference hintingPreference() const;
+
// is raw mode still needed?
bool rawMode() const;
void setRawMode(bool);
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 0a3f76d..c1a5048 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -72,7 +72,7 @@ struct QFontDef
: pointSize(-1.0), pixelSize(-1),
styleStrategy(QFont::PreferDefault), styleHint(QFont::AnyStyle),
weight(50), fixedPitch(false), style(QFont::StyleNormal), stretch(100),
- ignorePitch(true)
+ ignorePitch(true), hintingPreference(QFont::PreferDefaultHinting)
#ifdef Q_WS_MAC
,fixedPitchComputed(false)
#endif
@@ -97,8 +97,9 @@ struct QFontDef
uint stretch : 12; // 0-400
uint ignorePitch : 1;
+ uint hintingPreference : 2;
uint fixedPitchComputed : 1; // for Mac OS X only
- int reserved : 16; // for future extensions
+ int reserved : 14; // for future extensions
bool exactMatch(const QFontDef &other) const;
bool operator==(const QFontDef &other) const
@@ -111,6 +112,7 @@ struct QFontDef
&& styleStrategy == other.styleStrategy
&& ignorePitch == other.ignorePitch && fixedPitch == other.fixedPitch
&& family == other.family
+ && hintingPreference == other.hintingPreference
#ifdef Q_WS_X11
&& addStyle == other.addStyle
#endif
@@ -125,6 +127,7 @@ struct QFontDef
if (styleHint != other.styleHint) return styleHint < other.styleHint;
if (styleStrategy != other.styleStrategy) return styleStrategy < other.styleStrategy;
if (family != other.family) return family < other.family;
+ if (hintingPreference != other.hintingPreference) return hintingPreference < other.hintingPreference;
#ifdef Q_WS_X11
if (addStyle != other.addStyle) return addStyle < other.addStyle;
diff --git a/src/gui/text/qfont_qpa.cpp b/src/gui/text/qfont_qpa.cpp
index 7b09b59..ff12da8 100644
--- a/src/gui/text/qfont_qpa.cpp
+++ b/src/gui/text/qfont_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 1e94bf5..cbe0423 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -81,6 +81,10 @@
# define FM_DEBUG if (false) qDebug
#endif
+#if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
+# include <dwrite.h>
+#endif
+
QT_BEGIN_NAMESPACE
#define SMOOTH_SCALABLE 0xffff
@@ -643,13 +647,24 @@ public:
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
, symbianExtras(0)
#endif
+#if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
+ , directWriteFactory(0)
+ , directWriteGdiInterop(0)
+#endif
{ }
+
~QFontDatabasePrivate() {
free();
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
if (symbianExtras)
delete symbianExtras;
#endif
+#if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
+ if (directWriteGdiInterop)
+ directWriteGdiInterop->Release();
+ if (directWriteFactory != 0)
+ directWriteFactory->Release();
+#endif
}
QtFontFamily *family(const QString &f, bool = false);
void free() {
@@ -667,6 +682,12 @@ public:
#endif
QtFontFamily **families;
+#if defined(Q_WS_WIN) && !defined(QT_NO_DIRECTWRITE)
+ IDWriteFactory *directWriteFactory;
+ IDWriteGdiInterop *directWriteGdiInterop;
+#endif
+
+
struct ApplicationFont {
QString fileName;
QByteArray data;
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index e6d99c6..7bcce56 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp
index e2c5116..8279195 100644
--- a/src/gui/text/qfontdatabase_win.cpp
+++ b/src/gui/text/qfontdatabase_win.cpp
@@ -49,6 +49,11 @@
#include "qabstractfileengine.h"
#include "qendian.h"
+#if !defined(QT_NO_DIRECTWRITE)
+# include "qsettings.h"
+# include "qfontenginedirectwrite_p.h"
+#endif
+
#ifdef Q_OS_WINCE
# include <QTemporaryFile>
#endif
@@ -542,6 +547,65 @@ static void initFontInfo(QFontEngineWin *fe, const QFontDef &request, const QFon
}
}
+#if !defined(QT_NO_DIRECTWRITE)
+static void initFontInfo(QFontEngineDirectWrite *fe, const QFontDef &request,
+ const QFontPrivate *fp, IDWriteFont *font)
+{
+ fe->fontDef = request;
+
+ IDWriteFontFamily *fontFamily = NULL;
+ HRESULT hr = font->GetFontFamily(&fontFamily);
+
+ IDWriteLocalizedStrings *familyNames = NULL;
+ if (SUCCEEDED(hr))
+ hr = fontFamily->GetFamilyNames(&familyNames);
+
+ UINT32 index = 0;
+ BOOL exists = false;
+
+ wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
+
+ if (SUCCEEDED(hr)) {
+ int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH);
+
+ if (defaultLocaleSuccess)
+ hr = familyNames->FindLocaleName(localeName, &index, &exists);
+
+ if (SUCCEEDED(hr) && !exists)
+ hr = familyNames->FindLocaleName(L"en-us", &index, &exists);
+ }
+
+ if (!exists)
+ index = 0;
+
+ UINT32 length = 0;
+ if (SUCCEEDED(hr))
+ hr = familyNames->GetStringLength(index, &length);
+
+ wchar_t *name = new (std::nothrow) wchar_t[length+1];
+ if (name == NULL)
+ hr = E_OUTOFMEMORY;
+
+ // Get the family name.
+ if (SUCCEEDED(hr))
+ hr = familyNames->GetString(index, name, length + 1);
+
+ if (SUCCEEDED(hr))
+ fe->fontDef.family = QString::fromWCharArray(name);
+
+ delete[] name;
+ if (familyNames != NULL)
+ familyNames->Release();
+
+ if (FAILED(hr))
+ qErrnoWarning(hr, "initFontInfo: Failed to get family name");
+
+ if (fe->fontDef.pointSize < 0)
+ fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / fp->dpi;
+ else if (fe->fontDef.pixelSize == -1)
+ fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * fp->dpi / 72.);
+}
+#endif
static const char *other_tryFonts[] = {
"Arial",
@@ -595,6 +659,14 @@ static const char *kr_tryFonts[] = {
static const char **tryFonts = 0;
+#if !defined(QT_NO_DIRECTWRITE)
+static QString fontNameSubstitute(const QString &familyName)
+{
+ QLatin1String key("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\"
+ "FontSubstitutes");
+ return QSettings(key, QSettings::NativeFormat).value(familyName, familyName).toString();
+}
+#endif
static inline HFONT systemFont()
{
@@ -629,6 +701,15 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
HFONT hfont = 0;
+
+#if !defined(QT_NO_DIRECTWRITE)
+ bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting)
+ || (request.hintingPreference == QFont::PreferVerticalHinting);
+ IDWriteFont *directWriteFont = 0;
+#else
+ bool useDirectWrite = false;
+#endif
+
if (fp->rawMode) { // will choose a stock font
int f, deffnt = SYSTEM_FONT;
QString fam = desc->family->name.toLower();
@@ -745,6 +826,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
fam = QLatin1String("Courier New");
memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
+
hfont = CreateFontIndirect(&lf);
if (!hfont)
qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect failed");
@@ -759,52 +841,120 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
res = GetTextMetrics(hdc, &tm);
avWidth = tm.tmAveCharWidth;
ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE;
-
SelectObject(hdc, oldObj);
- if (hfont && (!ttf || request.stretch != 100)) {
- DeleteObject(hfont);
- if (!res)
- qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed");
- lf.lfWidth = avWidth * request.stretch/100;
- hfont = CreateFontIndirect(&lf);
- if (!hfont)
- qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect with stretch failed");
- }
+ if (!ttf || !useDirectWrite) {
+ useDirectWrite = false;
+
+ if (hfont && (!ttf || request.stretch != 100)) {
+ DeleteObject(hfont);
+ if (!res)
+ qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed");
+ lf.lfWidth = avWidth * request.stretch/100;
+ hfont = CreateFontIndirect(&lf);
+ if (!hfont)
+ qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect with stretch failed");
+ }
#ifndef Q_WS_WINCE
- if (hfont == 0) {
- hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
- stockFont = true;
- }
+ if (hfont == 0) {
+ hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
+ stockFont = true;
+ }
#else
- if (hfont == 0) {
- hfont = (HFONT)GetStockObject(SYSTEM_FONT);
- stockFont = true;
+ if (hfont == 0) {
+ hfont = (HFONT)GetStockObject(SYSTEM_FONT);
+ stockFont = true;
+ }
+#endif
+
+ }
+
+#if !defined(QT_NO_DIRECTWRITE)
+ else {
+ // Default to false for DirectWrite (and re-enable once/if everything
+ // turns out okay)
+ useDirectWrite = false;
+
+ QFontDatabasePrivate *db = privateDb();
+ if (db->directWriteFactory == 0) {
+ HRESULT hr = DWriteCreateFactory(
+ DWRITE_FACTORY_TYPE_SHARED,
+ __uuidof(IDWriteFactory),
+ reinterpret_cast<IUnknown **>(&db->directWriteFactory)
+ );
+ if (FAILED(hr)) {
+ qErrnoWarning("QFontEngine::loadEngine: DWriteCreateFactory failed");
+ } else {
+ hr = db->directWriteFactory->GetGdiInterop(&db->directWriteGdiInterop);
+ if (FAILED(hr))
+ qErrnoWarning("QFontEngine::loadEngine: GetGdiInterop failed");
+ }
+ }
+
+ if (db->directWriteGdiInterop != 0) {
+ QString nameSubstitute = fontNameSubstitute(QString::fromWCharArray(lf.lfFaceName));
+ memcpy(lf.lfFaceName, nameSubstitute.utf16(),
+ sizeof(wchar_t) * qMin(nameSubstitute.length() + 1, LF_FACESIZE));
+
+ HRESULT hr = db->directWriteGdiInterop->CreateFontFromLOGFONT(
+ &lf,
+ &directWriteFont);
+ if (FAILED(hr)) {
+ qErrnoWarning("QFontEngine::loadEngine: CreateFontFromLOGFONT failed "
+ "for %ls (0x%lx)",
+ lf.lfFaceName, hr);
+ } else {
+ DeleteObject(hfont);
+ useDirectWrite = true;
+ }
+ }
}
#endif
}
- QFontEngineWin *few = new QFontEngineWin(font_name, hfont, stockFont, lf);
-
- if (preferClearTypeAA)
- few->glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
-
- // Also check for OpenType tables when using complex scripts
- // ### TODO: This only works for scripts that require OpenType. More generally
- // for scripts that do not require OpenType we should just look at the list of
- // supported writing systems in the font's OS/2 table.
- if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = few->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- FM_DEBUG(" OpenType support missing for script\n");
- delete few;
- return 0;
+
+ QFontEngine *fe = 0;
+ if (!useDirectWrite) {
+ QFontEngineWin *few = new QFontEngineWin(font_name, hfont, stockFont, lf);
+ if (preferClearTypeAA)
+ few->glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
+
+ // Also check for OpenType tables when using complex scripts
+ // ### TODO: This only works for scripts that require OpenType. More generally
+ // for scripts that do not require OpenType we should just look at the list of
+ // supported writing systems in the font's OS/2 table.
+ if (scriptRequiresOpenType(script)) {
+ HB_Face hbFace = few->harfbuzzFace();
+ if (!hbFace || !hbFace->supported_scripts[script]) {
+ FM_DEBUG(" OpenType support missing for script\n");
+ delete few;
+ return 0;
+ }
}
+
+ initFontInfo(few, request, fp);
+ fe = few;
}
- QFontEngine *fe = few;
- initFontInfo(few, request, fp);
+#if !defined(QT_NO_DIRECTWRITE)
+ else {
+ QFontDatabasePrivate *db = privateDb();
+ QFontEngineDirectWrite *fedw = new QFontEngineDirectWrite(font_name,
+ db->directWriteFactory,
+ db->directWriteGdiInterop,
+ directWriteFont,
+ request.pixelSize);
+
+ initFontInfo(fedw, request, fp, directWriteFont);
+
+ fe = fedw;
+ }
+
+ if (directWriteFont != 0)
+ directWriteFont->Release();
+#endif
+
if(script == QUnicodeTables::Common
&& !(request.styleStrategy & QFont::NoFontMerging)
&& !(desc->family->writingSystems[QFontDatabase::Symbol] & QtFontFamily::Supported)) {
@@ -836,7 +986,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
list << QLatin1String(*tf);
++tf;
}
- QFontEngine *mfe = new QFontEngineMultiWin(few, list);
+ QFontEngine *mfe = new QFontEngineMultiWin(fe, list);
mfe->fontDef = fe->fontDef;
fe = mfe;
}
diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm
index 2ae60b1..4d9192e 100644
--- a/src/gui/text/qfontengine_coretext.mm
+++ b/src/gui/text/qfontengine_coretext.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -119,14 +119,27 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const
return engines.count() - 1;
}
-bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags,
+bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *) const
{
QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
reinterpret_cast<const UniChar *>(str),
len, kCFAllocatorNull);
QCFType<CFAttributedStringRef> attributedString = CFAttributedStringCreate(0, cfstring, attributeDict);
- QCFType<CTTypesetterRef> typeSetter = CTTypesetterCreateWithAttributedString(attributedString);
+ QCFType<CTTypesetterRef> typeSetter;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ if (flags & QTextEngine::RightToLeft) {
+ const void *optionKeys[] = { kCTTypesetterOptionForcedEmbeddingLevel };
+ const short rtlForcedEmbeddingLevelValue = 1;
+ const void *rtlOptionValues[] = { CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &rtlForcedEmbeddingLevelValue) };
+ QCFType<CFDictionaryRef> options = CFDictionaryCreate(kCFAllocatorDefault, optionKeys, rtlOptionValues, 1,
+ &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ typeSetter = CTTypesetterCreateWithAttributedStringAndOptions(attributedString, options);
+ } else
+#endif
+ typeSetter = CTTypesetterCreateWithAttributedString(attributedString);
+
CFRange range = {0, 0};
QCFType<CTLineRef> line = CTTypesetterCreateLine(typeSetter, range);
CFArrayRef array = CTLineGetGlyphRuns(line);
@@ -234,7 +247,8 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
int idx = rtlOffset + rtlSign * i;
outGlyphs[idx] = tmpGlyphs[i] | fontIndex;
outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x);
- outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y);
+ // Use negative y advance for flipped coordinate system
+ outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i].y - tmpPoints[i + 1].y);
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
outAdvances_x[idx] = outAdvances_x[idx].round();
diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h
index b4450fa..7d17aef 100644
--- a/src/gui/text/qfontengine_coretext_p.h
+++ b/src/gui/text/qfontengine_coretext_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h
index 5577c76..6967348 100644
--- a/src/gui/text/qfontengine_mac_p.h
+++ b/src/gui/text/qfontengine_mac_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index bbb242b..f501141 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -117,6 +117,8 @@ public:
// S60 types
S60FontEngine, // Cannot be simply called "S60". Reason is qt_s60Data.h
+ DirectWrite,
+
TestFontEngine = 0x1000
};
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index cccbc92..851bb59 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qfontengine_qpa_p.h b/src/gui/text/qfontengine_qpa_p.h
index 467fca6..e15beae 100644
--- a/src/gui/text/qfontengine_qpa_p.h
+++ b/src/gui/text/qfontengine_qpa_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
index ecb0384..82d9da0 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/gui/text/qfontengine_win.cpp
@@ -1286,7 +1286,7 @@ QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, co
// -------------------------------------- Multi font engine
-QFontEngineMultiWin::QFontEngineMultiWin(QFontEngineWin *first, const QStringList &fallbacks)
+QFontEngineMultiWin::QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks)
: QFontEngineMulti(fallbacks.size()+1),
fallbacks(fallbacks)
{
diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h
index 22085e8..28d8000 100644
--- a/src/gui/text/qfontengine_win_p.h
+++ b/src/gui/text/qfontengine_win_p.h
@@ -150,7 +150,7 @@ private:
class QFontEngineMultiWin : public QFontEngineMulti
{
public:
- QFontEngineMultiWin(QFontEngineWin *first, const QStringList &fallbacks);
+ QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks);
void loadEngine(int at);
QStringList fallbacks;
diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp
new file mode 100644
index 0000000..af5bab2
--- /dev/null
+++ b/src/gui/text/qfontenginedirectwrite.cpp
@@ -0,0 +1,641 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_NO_DIRECTWRITE
+
+#include "qfontenginedirectwrite_p.h"
+
+#include <qendian.h>
+#include <dwrite.h>
+#include <private/qnativeimage_p.h>
+
+#include <d2d1.h>
+
+QT_BEGIN_NAMESPACE
+
+// Convert from design units to logical pixels
+#define DESIGN_TO_LOGICAL(DESIGN_UNIT_VALUE) \
+ QFixed::fromReal((qreal(DESIGN_UNIT_VALUE) / qreal(m_unitsPerEm)) * fontDef.pixelSize)
+
+namespace {
+
+ class GeometrySink: public IDWriteGeometrySink
+ {
+ public:
+ GeometrySink(QPainterPath *path) : m_path(path), m_refCount(0)
+ {
+ Q_ASSERT(m_path != 0);
+ }
+
+ IFACEMETHOD_(void, AddBeziers)(const D2D1_BEZIER_SEGMENT *beziers, UINT bezierCount);
+ IFACEMETHOD_(void, AddLines)(const D2D1_POINT_2F *points, UINT pointCount);
+ IFACEMETHOD_(void, BeginFigure)(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN figureBegin);
+ IFACEMETHOD(Close)();
+ IFACEMETHOD_(void, EndFigure)(D2D1_FIGURE_END figureEnd);
+ IFACEMETHOD_(void, SetFillMode)(D2D1_FILL_MODE fillMode);
+ IFACEMETHOD_(void, SetSegmentFlags)(D2D1_PATH_SEGMENT vertexFlags);
+
+ IFACEMETHOD_(unsigned long, AddRef)();
+ IFACEMETHOD_(unsigned long, Release)();
+ IFACEMETHOD(QueryInterface)(IID const &riid, void **ppvObject);
+
+ private:
+ inline static QPointF fromD2D1_POINT_2F(const D2D1_POINT_2F &inp)
+ {
+ return QPointF(inp.x, inp.y);
+ }
+
+ unsigned long m_refCount;
+ QPointF m_startPoint;
+ QPainterPath *m_path;
+ };
+
+ void GeometrySink::AddBeziers(const D2D1_BEZIER_SEGMENT *beziers,
+ UINT bezierCount)
+ {
+ for (uint i=0; i<bezierCount; ++i) {
+ QPointF c1 = fromD2D1_POINT_2F(beziers[i].point1);
+ QPointF c2 = fromD2D1_POINT_2F(beziers[i].point2);
+ QPointF p2 = fromD2D1_POINT_2F(beziers[i].point3);
+
+ m_path->cubicTo(c1, c2, p2);
+ }
+ }
+
+ void GeometrySink::AddLines(const D2D1_POINT_2F *points, UINT pointsCount)
+ {
+ for (uint i=0; i<pointsCount; ++i)
+ m_path->lineTo(fromD2D1_POINT_2F(points[i]));
+ }
+
+ void GeometrySink::BeginFigure(D2D1_POINT_2F startPoint,
+ D2D1_FIGURE_BEGIN /*figureBegin*/)
+ {
+ m_startPoint = fromD2D1_POINT_2F(startPoint);
+ m_path->moveTo(m_startPoint);
+ }
+
+ IFACEMETHODIMP GeometrySink::Close()
+ {
+ return E_NOTIMPL;
+ }
+
+ void GeometrySink::EndFigure(D2D1_FIGURE_END figureEnd)
+ {
+ if (figureEnd == D2D1_FIGURE_END_CLOSED)
+ m_path->closeSubpath();
+ }
+
+ void GeometrySink::SetFillMode(D2D1_FILL_MODE fillMode)
+ {
+ m_path->setFillRule(fillMode == D2D1_FILL_MODE_ALTERNATE
+ ? Qt::OddEvenFill
+ : Qt::WindingFill);
+ }
+
+ void GeometrySink::SetSegmentFlags(D2D1_PATH_SEGMENT /*vertexFlags*/)
+ {
+ /* Not implemented */
+ }
+
+ IFACEMETHODIMP_(unsigned long) GeometrySink::AddRef()
+ {
+ return InterlockedIncrement(&m_refCount);
+ }
+
+ IFACEMETHODIMP_(unsigned long) GeometrySink::Release()
+ {
+ unsigned long newCount = InterlockedDecrement(&m_refCount);
+ if (newCount == 0)
+ {
+ delete this;
+ return 0;
+ }
+
+ return newCount;
+ }
+
+ IFACEMETHODIMP GeometrySink::QueryInterface(IID const &riid, void **ppvObject)
+ {
+ if (__uuidof(IDWriteGeometrySink) == riid) {
+ *ppvObject = this;
+ } else if (__uuidof(IUnknown) == riid) {
+ *ppvObject = this;
+ } else {
+ *ppvObject = NULL;
+ return E_FAIL;
+ }
+
+ AddRef();
+ return S_OK;
+ }
+
+}
+
+QFontEngineDirectWrite::QFontEngineDirectWrite(const QString &name,
+ IDWriteFactory *directWriteFactory,
+ IDWriteGdiInterop *directWriteGdiInterop,
+ IDWriteFont *directWriteFont,
+ qreal pixelSize)
+ : m_name(name)
+ , m_directWriteFont(directWriteFont)
+ , m_directWriteFontFace(0)
+ , m_directWriteFactory(directWriteFactory)
+ , m_directWriteBitmapRenderTarget(0)
+ , m_directWriteGdiInterop(directWriteGdiInterop)
+ , m_lineThickness(-1)
+ , m_unitsPerEm(-1)
+ , m_ascent(-1)
+ , m_descent(-1)
+ , m_xHeight(-1)
+ , m_lineGap(-1)
+{
+ m_directWriteFont->AddRef();
+ m_directWriteFactory->AddRef();
+ m_directWriteGdiInterop->AddRef();
+
+ fontDef.pixelSize = pixelSize;
+
+ HRESULT hr = m_directWriteFont->CreateFontFace(&m_directWriteFontFace);
+ if (FAILED(hr))
+ qErrnoWarning("QFontEngineDirectWrite: CreateFontFace failed");
+
+ collectMetrics();
+}
+
+QFontEngineDirectWrite::~QFontEngineDirectWrite()
+{
+ m_directWriteFont->Release();
+ m_directWriteFactory->Release();
+ m_directWriteGdiInterop->Release();
+
+ if (m_directWriteBitmapRenderTarget != 0)
+ m_directWriteBitmapRenderTarget->Release();
+}
+
+void QFontEngineDirectWrite::collectMetrics()
+{
+ if (m_directWriteFont != 0) {
+ DWRITE_FONT_METRICS metrics;
+
+ m_directWriteFont->GetMetrics(&metrics);
+ m_unitsPerEm = metrics.designUnitsPerEm;
+
+ m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
+ m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
+ m_descent = DESIGN_TO_LOGICAL(metrics.descent);
+ m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
+ m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
+ }
+}
+
+QFixed QFontEngineDirectWrite::lineThickness() const
+{
+ if (m_lineThickness > 0)
+ return m_lineThickness;
+ else
+ return QFontEngine::lineThickness();
+}
+
+bool QFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+ if (m_directWriteFontFace) {
+ DWORD t = qbswap<quint32>(tag);
+
+ const void *tableData = 0;
+ void *tableContext = 0;
+ UINT32 tableSize;
+ BOOL exists;
+ HRESULT hr = m_directWriteFontFace->TryGetFontTable(
+ t, &tableData, &tableSize, &tableContext, &exists
+ );
+
+ if (SUCCEEDED(hr)) {
+ if (!exists)
+ return false;
+
+ if (buffer == 0) {
+ *length = tableSize;
+ return true;
+ } else if (*length < tableSize) {
+ return false;
+ }
+
+ qMemCopy(buffer, tableData, tableSize);
+ m_directWriteFontFace->ReleaseFontTable(tableContext);
+
+ return true;
+ } else {
+ qErrnoWarning("QFontEngineDirectWrite::getSfntTableData: TryGetFontTable failed");
+ }
+ }
+
+ return false;
+}
+
+QFixed QFontEngineDirectWrite::emSquareSize() const
+{
+ if (m_unitsPerEm > 0)
+ return m_unitsPerEm;
+ else
+ return QFontEngine::emSquareSize();
+}
+
+inline unsigned int getChar(const QChar *str, int &i, const int len)
+{
+ unsigned int uc = str[i].unicode();
+ if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
+ uint low = str[i+1].unicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ ++i;
+ }
+ }
+ return uc;
+}
+
+bool QFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
+ int *nglyphs, QTextEngine::ShaperFlags flags) const
+{
+ if (m_directWriteFontFace != 0) {
+ QVarLengthArray<UINT32> codePoints(len);
+ for (int i=0; i<len; ++i) {
+ codePoints[i] = getChar(str, i, len);
+ if (flags & QTextEngine::RightToLeft)
+ codePoints[i] = QChar::mirroredChar(codePoints[i]);
+ }
+
+ QVarLengthArray<UINT16> glyphIndices(len);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(),
+ len,
+ glyphIndices.data());
+
+ if (SUCCEEDED(hr)) {
+ for (int i=0; i<len; ++i)
+ glyphs->glyphs[i] = glyphIndices[i];
+
+ *nglyphs = len;
+
+ if (!(flags & QTextEngine::GlyphIndicesOnly))
+ recalcAdvances(glyphs, 0);
+
+ return true;
+ } else {
+ qErrnoWarning("QFontEngineDirectWrite::stringToCMap: GetGlyphIndicesW failed");
+ }
+ }
+
+ return false;
+}
+
+void QFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const
+{
+ if (m_directWriteFontFace == 0)
+ return;
+
+ QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);
+
+ // ### Caching?
+ for(int i=0; i<glyphs->numGlyphs; i++)
+ glyphIndices[i] = UINT16(glyphs->glyphs[i]);
+
+ QVarLengthArray<DWRITE_GLYPH_METRICS> glyphMetrics(glyphIndices.size());
+ HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(glyphIndices.data(),
+ glyphIndices.size(),
+ glyphMetrics.data());
+ if (SUCCEEDED(hr)) {
+ for (int i=0; i<glyphs->numGlyphs; ++i) {
+ glyphs->advances_x[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth);
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
+ glyphs->advances_x[i] = glyphs->advances_x[i].round();
+ glyphs->advances_y[i] = 0;
+ }
+ } else {
+ qErrnoWarning("QFontEngineDirectWrite::recalcAdvances: GetDesignGlyphMetrics failed");
+ }
+}
+
+void QFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags)
+{
+ if (m_directWriteFontFace == 0)
+ return;
+
+ QVarLengthArray<UINT16> glyphIndices(nglyphs);
+ QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(nglyphs);
+ QVarLengthArray<FLOAT> glyphAdvances(nglyphs);
+
+ for (int i=0; i<nglyphs; ++i) {
+ glyphIndices[i] = glyphs[i];
+ glyphOffsets[i].advanceOffset = positions[i].x.toReal();
+ glyphOffsets[i].ascenderOffset = -positions[i].y.toReal();
+ glyphAdvances[i] = 0.0;
+ }
+
+ GeometrySink geometrySink(path);
+ HRESULT hr = m_directWriteFontFace->GetGlyphRunOutline(
+ fontDef.pixelSize,
+ glyphIndices.data(),
+ glyphAdvances.data(),
+ glyphOffsets.data(),
+ nglyphs,
+ false,
+ flags & QTextItem::RightToLeft,
+ &geometrySink
+ );
+
+ if (FAILED(hr))
+ qErrnoWarning("QFontEngineDirectWrite::addGlyphsToPath: GetGlyphRunOutline failed");
+}
+
+glyph_metrics_t QFontEngineDirectWrite::boundingBox(const QGlyphLayout &glyphs)
+{
+ if (glyphs.numGlyphs == 0)
+ return glyph_metrics_t();
+
+ bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
+
+ QFixed w = 0;
+ for (int i = 0; i < glyphs.numGlyphs; ++i) {
+ w += round ? glyphs.effectiveAdvance(i).round() : glyphs.effectiveAdvance(i);
+
+ }
+
+ return glyph_metrics_t(0, -m_ascent, w - lastRightBearing(glyphs), m_ascent + m_descent, w, 0);
+}
+
+glyph_metrics_t QFontEngineDirectWrite::boundingBox(glyph_t g)
+{
+ if (m_directWriteFontFace == 0)
+ return glyph_metrics_t();
+
+ UINT16 glyphIndex = g;
+
+ DWRITE_GLYPH_METRICS glyphMetrics;
+ HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(&glyphIndex, 1, &glyphMetrics);
+ if (SUCCEEDED(hr)) {
+ QFixed advanceWidth = DESIGN_TO_LOGICAL(glyphMetrics.advanceWidth);
+ QFixed leftSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.leftSideBearing);
+ QFixed rightSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.rightSideBearing);
+ QFixed advanceHeight = DESIGN_TO_LOGICAL(glyphMetrics.advanceHeight);
+ QFixed verticalOriginY = DESIGN_TO_LOGICAL(glyphMetrics.verticalOriginY);
+
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+ advanceWidth = advanceWidth.round();
+ advanceHeight = advanceHeight.round();
+ }
+
+ QFixed width = advanceWidth - leftSideBearing - rightSideBearing;
+
+ return glyph_metrics_t(-leftSideBearing, -verticalOriginY,
+ width, m_ascent + m_descent,
+ advanceWidth, advanceHeight);
+ } else {
+ qErrnoWarning("QFontEngineDirectWrite::boundingBox: GetDesignGlyphMetrics failed");
+ }
+
+ return glyph_metrics_t();
+}
+
+QFixed QFontEngineDirectWrite::ascent() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? m_ascent.round()
+ : m_ascent;
+}
+
+QFixed QFontEngineDirectWrite::descent() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? (m_descent - 1).round()
+ : (m_descent - 1);
+}
+
+QFixed QFontEngineDirectWrite::leading() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? m_lineGap.round()
+ : m_lineGap;
+}
+
+QFixed QFontEngineDirectWrite::xHeight() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? m_xHeight.round()
+ : m_xHeight;
+}
+
+qreal QFontEngineDirectWrite::maxCharWidth() const
+{
+ // ###
+ return 0;
+}
+
+extern uint qt_pow_gamma[256];
+
+QImage QFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
+{
+ QImage im = imageForGlyph(glyph, subPixelPosition, 0, QTransform());
+
+ QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
+ QVector<QRgb> colors(256);
+ for (int i=0; i<256; ++i)
+ colors[i] = qRgba(0, 0, 0, i);
+ indexed.setColorTable(colors);
+
+ for (int y=0; y<im.height(); ++y) {
+ uint *src = (uint*) im.scanLine(y);
+ uchar *dst = indexed.scanLine(y);
+ for (int x=0; x<im.width(); ++x) {
+ *dst = 255 - (qt_pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.);
+ ++dst;
+ ++src;
+ }
+ }
+
+ return indexed;
+}
+
+bool QFontEngineDirectWrite::supportsSubPixelPositions() const
+{
+ return true;
+}
+
+QImage QFontEngineDirectWrite::imageForGlyph(glyph_t t,
+ QFixed subPixelPosition,
+ int margin,
+ const QTransform &xform)
+{
+ glyph_metrics_t metrics = QFontEngine::boundingBox(t, xform);
+ int width = (metrics.width + margin * 2 + 4).ceil().toInt() ;
+ int height = (metrics.height + margin * 2 + 4).ceil().toInt();
+
+ UINT16 glyphIndex = t;
+ FLOAT glyphAdvance = metrics.xoff.toReal();
+
+ DWRITE_GLYPH_OFFSET glyphOffset;
+ glyphOffset.advanceOffset = 0;
+ glyphOffset.ascenderOffset = 0;
+
+ DWRITE_GLYPH_RUN glyphRun;
+ glyphRun.fontFace = m_directWriteFontFace;
+ glyphRun.fontEmSize = fontDef.pixelSize;
+ glyphRun.glyphCount = 1;
+ glyphRun.glyphIndices = &glyphIndex;
+ glyphRun.glyphAdvances = &glyphAdvance;
+ glyphRun.isSideways = false;
+ glyphRun.bidiLevel = 0;
+ glyphRun.glyphOffsets = &glyphOffset;
+
+ QFixed x = margin - metrics.x.round() + subPixelPosition;
+ QFixed y = margin - metrics.y.floor();
+
+ DWRITE_MATRIX transform;
+ transform.dx = x.toReal();
+ transform.dy = y.toReal();
+ transform.m11 = xform.m11();
+ transform.m12 = xform.m12();
+ transform.m21 = xform.m21();
+ transform.m22 = xform.m22();
+
+ IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
+ HRESULT hr = m_directWriteFactory->CreateGlyphRunAnalysis(
+ &glyphRun,
+ 1.0f,
+ &transform,
+ DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
+ DWRITE_MEASURING_MODE_NATURAL,
+ 0.0, 0.0,
+ &glyphAnalysis
+ );
+
+ if (SUCCEEDED(hr)) {
+ RECT rect;
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = width;
+ rect.bottom = height;
+
+ int size = width * height * 3;
+ BYTE *alphaValues = new BYTE[size];
+ qMemSet(alphaValues, size, 0);
+
+ hr = glyphAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1,
+ &rect,
+ alphaValues,
+ size);
+
+ if (SUCCEEDED(hr)) {
+ QImage img(width, height, QImage::Format_RGB32);
+ img.fill(0xffffffff);
+
+ for (int y=0; y<height; ++y) {
+ uint *dest = reinterpret_cast<uint *>(img.scanLine(y));
+ BYTE *src = alphaValues + width * 3 * y;
+
+ for (int x=0; x<width; ++x) {
+ dest[x] = *(src) << 16
+ | *(src + 1) << 8
+ | *(src + 2);
+
+ src += 3;
+ }
+ }
+
+ delete[] alphaValues;
+ glyphAnalysis->Release();
+
+ return img;
+ } else {
+ delete[] alphaValues;
+ glyphAnalysis->Release();
+
+ qErrnoWarning("QFontEngineDirectWrite::imageForGlyph: CreateAlphaTexture failed");
+ }
+
+ } else {
+ qErrnoWarning("QFontEngineDirectWrite::imageForGlyph: CreateGlyphRunAnalysis failed");
+ }
+
+ return QImage();
+}
+
+QImage QFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t,
+ QFixed subPixelPosition,
+ int margin,
+ const QTransform &xform)
+{
+ QImage mask = imageForGlyph(t, subPixelPosition, margin, xform);
+ return mask.depth() == 32
+ ? mask
+ : mask.convertToFormat(QImage::Format_RGB32);
+}
+
+const char *QFontEngineDirectWrite::name() const
+{
+ return 0;
+}
+
+bool QFontEngineDirectWrite::canRender(const QChar *string, int len)
+{
+ for (int i=0; i<len; ++i) {
+ BOOL exists;
+ UINT32 codePoint = getChar(string, i, len);
+ HRESULT hr = m_directWriteFont->HasCharacter(codePoint, &exists);
+ if (FAILED(hr)) {
+ qErrnoWarning("QFontEngineDirectWrite::canRender: HasCharacter failed");
+ return false;
+ } else if (!exists) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QFontEngine::Type QFontEngineDirectWrite::type() const
+{
+ return QFontEngine::DirectWrite;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DIRECTWRITE
diff --git a/src/gui/text/qfontenginedirectwrite_p.h b/src/gui/text/qfontenginedirectwrite_p.h
new file mode 100644
index 0000000..80f90b8
--- /dev/null
+++ b/src/gui/text/qfontenginedirectwrite_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFONTENGINEDIRECTWRITE_H
+#define QFONTENGINEDIRECTWRITE_H
+
+#ifndef QT_NO_DIRECTWRITE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qfontengine_p.h"
+
+struct IDWriteFont ;
+struct IDWriteFontFace ;
+struct IDWriteFactory ;
+struct IDWriteBitmapRenderTarget ;
+struct IDWriteGdiInterop ;
+
+QT_BEGIN_NAMESPACE
+
+class QFontEngineDirectWrite : public QFontEngine
+{
+ Q_OBJECT
+public:
+ explicit QFontEngineDirectWrite(const QString &name,
+ IDWriteFactory *directWriteFactory,
+ IDWriteGdiInterop *directWriteGdiInterop,
+ IDWriteFont *directWriteFont,
+ qreal pixelSize);
+ ~QFontEngineDirectWrite();
+
+ QFixed lineThickness() const;
+ bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
+ QFixed emSquareSize() const;
+
+ bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
+ void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const;
+
+ void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags);
+
+ glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
+ glyph_metrics_t boundingBox(glyph_t g);
+
+ QFixed ascent() const;
+ QFixed descent() const;
+ QFixed leading() const;
+ QFixed xHeight() const;
+ qreal maxCharWidth() const;
+
+ const char *name() const;
+
+ bool supportsSubPixelPositions() const;
+
+ QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition);
+ QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin,
+ const QTransform &xform);
+
+ bool canRender(const QChar *string, int len);
+ Type type() const;
+
+private:
+ QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
+ void collectMetrics();
+
+ QString m_name;
+ IDWriteFont *m_directWriteFont;
+ IDWriteFontFace *m_directWriteFontFace;
+ IDWriteFactory *m_directWriteFactory;
+ IDWriteBitmapRenderTarget *m_directWriteBitmapRenderTarget;
+ IDWriteGdiInterop *m_directWriteGdiInterop;
+
+ QFixed m_lineThickness;
+ int m_unitsPerEm;
+ QFixed m_ascent;
+ QFixed m_descent;
+ QFixed m_xHeight;
+ QFixed m_lineGap;
+ FaceId m_faceId;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DIRECTWRITE
+
+#endif // QFONTENGINEDIRECTWRITE_H
diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphs.cpp
index 2447752..affa08a 100644
--- a/src/gui/text/qglyphs.cpp
+++ b/src/gui/text/qglyphs.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qglyphs.h b/src/gui/text/qglyphs.h
index 282ecb4..5f37136 100644
--- a/src/gui/text/qglyphs.h
+++ b/src/gui/text/qglyphs.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qglyphs_p.h b/src/gui/text/qglyphs_p.h
index c39f5d0..c632e2f 100644
--- a/src/gui/text/qglyphs_p.h
+++ b/src/gui/text/qglyphs_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp
index afe762a..6fa25e7 100644
--- a/src/gui/text/qplatformfontdatabase_qpa.cpp
+++ b/src/gui/text/qplatformfontdatabase_qpa.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -214,7 +214,7 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicode
Q_UNUSED(handle);
QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
QFontEngineQPA *engine = new QFontEngineQPA(fontDef,*fileDataPtr);
- qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family << script;
+ //qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family << script;
return engine;
}
diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h
index a1faea9..e0e4f04 100644
--- a/src/gui/text/qplatformfontdatabase_qpa.h
+++ b/src/gui/text/qplatformfontdatabase_qpa.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index c847bb5..b7a2697 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -1608,7 +1608,10 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
if (!(buttons & Qt::LeftButton))
return;
- if (!((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable)))
+ const bool selectable = interactionFlags & Qt::TextSelectableByMouse;
+ const bool editable = interactionFlags & Qt::TextEditable;
+
+ if (!selectable && !editable)
return;
if (!(mousePressed
@@ -1624,6 +1627,10 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
startDrag();
return;
}
+
+ if (!selectable)
+ return;
+
const qreal mouseX = qreal(mousePos.x());
int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit);
@@ -1639,7 +1646,7 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
extendBlockwiseSelection(newCursorPos);
else if (selectedWordOnDoubleClick.hasSelection())
extendWordwiseSelection(newCursorPos, mouseX);
- else if (interactionFlags & Qt::TextSelectableByMouse)
+ else
setCursorPosition(newCursorPos, QTextCursor::KeepAnchor);
if (interactionFlags & Qt::TextEditable) {
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index 838face..684de00 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -3160,7 +3160,7 @@ QRectF QTextDocumentLayoutPrivate::frameBoundingRectInternal(QTextFrame *frame)
QRectF QTextDocumentLayout::blockBoundingRect(const QTextBlock &block) const
{
Q_D(const QTextDocumentLayout);
- if (d->docPrivate->pageSize.isNull())
+ if (d->docPrivate->pageSize.isNull() || !block.isValid())
return QRectF();
d->ensureLayoutedByPosition(block.position() + block.length());
QTextFrame *frame = d->document->frameAt(block.position());
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index c9af401..a02ea49 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -411,6 +411,9 @@ void QTextFormatPrivate::recalcFont() const
case QTextFormat::FontStyleHint:
f.setStyleHint(static_cast<QFont::StyleHint>(props.at(i).value.toInt()), f.styleStrategy());
break;
+ case QTextFormat::FontHintingPreference:
+ f.setHintingPreference(static_cast<QFont::HintingPreference>(props.at(i).value.toInt()));
+ break;
case QTextFormat::FontStyleStrategy:
f.setStyleStrategy(static_cast<QFont::StyleStrategy>(props.at(i).value.toInt()));
break;
@@ -1565,6 +1568,25 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
\sa font()
*/
+/*!
+ \since 4.8
+
+ \fn void QTextCharFormat::setFontHintingPreference(QFont::HintingPreference hintingPreference)
+
+ Sets the hinting preference of the text format's font to be \a hintingPreference.
+
+ \sa setFont(), QFont::setHintingPreference()
+*/
+
+/*!
+ \since 4.8
+
+ \fn QFont::HintingPreference QTextCharFormat::fontHintingPreference() const
+
+ Returns the hinting preference set for this text format.
+
+ \sa font(), QFont::hintingPreference()
+*/
/*!
\fn QPen QTextCharFormat::textOutline() const
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index 9a573a0..ff28eaa 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -177,6 +177,7 @@ public:
FontStyleHint = 0x1FE3,
FontStyleStrategy = 0x1FE4,
FontKerning = 0x1FE5,
+ FontHintingPreference = 0x1FE6,
FontFamily = 0x2000,
FontPointSize = 0x2001,
FontSizeAdjustment = 0x2002,
@@ -460,6 +461,16 @@ public:
QFont::StyleStrategy fontStyleStrategy() const
{ return static_cast<QFont::StyleStrategy>(intProperty(FontStyleStrategy)); }
+ inline void setFontHintingPreference(QFont::HintingPreference hintingPreference)
+ {
+ setProperty(FontHintingPreference, hintingPreference);
+ }
+
+ inline QFont::HintingPreference fontHintingPreference() const
+ {
+ return static_cast<QFont::HintingPreference>(intProperty(FontHintingPreference));
+ }
+
inline void setFontKerning(bool enable)
{ setProperty(FontKerning, enable); }
inline bool fontKerning() const
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 354e8a9..8eff7d2 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -1754,6 +1754,7 @@ namespace {
int glyphCount;
int maxGlyphs;
int currentPosition;
+ glyph_t previousGlyph;
QFixed minw;
QFixed softHyphenWidth;
@@ -1781,6 +1782,15 @@ namespace {
return glyphs.glyphs[logClusters[currentPosition - 1]];
}
+ inline void saveCurrentGlyph()
+ {
+ previousGlyph = 0;
+ if (currentPosition > 0 &&
+ logClusters[currentPosition - 1] < glyphs.numGlyphs) {
+ previousGlyph = currentGlyph(); // needed to calculate right bearing later
+ }
+ }
+
inline void adjustRightBearing(glyph_t glyph)
{
qreal rb;
@@ -1795,6 +1805,12 @@ namespace {
adjustRightBearing(currentGlyph());
}
+ inline void adjustPreviousRightBearing()
+ {
+ if (previousGlyph > 0)
+ adjustRightBearing(previousGlyph);
+ }
+
inline void resetRightBearing()
{
rightBearing = QFixed(1); // Any positive number is defined as invalid since only
@@ -1871,22 +1887,7 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap);
int item = -1;
- int newItem = -1;
- int left = 0;
- int right = eng->layoutData->items.size()-1;
- while(left <= right) {
- int middle = ((right-left)/2)+left;
- if (line.from > eng->layoutData->items[middle].position)
- left = middle+1;
- else if(line.from < eng->layoutData->items[middle].position)
- right = middle-1;
- else {
- newItem = middle;
- break;
- }
- }
- if (newItem == -1)
- newItem = right;
+ int newItem = eng->findItem(line.from);
LB_DEBUG("from: %d: item=%d, total %d, width available %f", line.from, newItem, eng->layoutData->items.size(), line.width.toReal());
@@ -1898,6 +1899,7 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.currentPosition = line.from;
int end = 0;
lbh.logClusters = eng->layoutData->logClustersPtr;
+ lbh.previousGlyph = 0;
while (newItem < eng->layoutData->items.size()) {
lbh.resetRightBearing();
@@ -1958,6 +1960,7 @@ void QTextLine::layout_helper(int maxGlyphs)
current, lbh.logClusters, lbh.glyphs);
} else {
lbh.tmpData.length++;
+ lbh.adjustPreviousRightBearing();
}
line += lbh.tmpData;
goto found;
@@ -1988,9 +1991,7 @@ void QTextLine::layout_helper(int maxGlyphs)
} else {
lbh.whiteSpaceOrObject = false;
bool sb_or_ws = false;
- glyph_t previousGlyph = 0;
- if (lbh.currentPosition > 0 && lbh.logClusters[lbh.currentPosition - 1] <lbh.glyphs.numGlyphs)
- previousGlyph = lbh.currentGlyph(); // needed to calculate right bearing later
+ lbh.saveCurrentGlyph();
do {
addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
current, lbh.logClusters, lbh.glyphs);
@@ -2015,7 +2016,7 @@ void QTextLine::layout_helper(int maxGlyphs)
// b) if we are so short of available width that the
// soft hyphen is the first breakable position, then
// we don't want to show it. However we initially
- // have to take the width for it into accoun so that
+ // have to take the width for it into account so that
// the text document layout sees the overflow and
// switch to break-anywhere mode, in which we
// want the soft-hyphen to slip into the next line
@@ -2043,8 +2044,9 @@ void QTextLine::layout_helper(int maxGlyphs)
// we are too wide, fix right bearing
if (rightBearing <= 0)
lbh.rightBearing = rightBearing; // take from cache
- else if (previousGlyph > 0)
- lbh.adjustRightBearing(previousGlyph);
+ else
+ lbh.adjustPreviousRightBearing();
+
if (!breakany) {
line.textWidth += lbh.softHyphenWidth;
}
@@ -2052,6 +2054,7 @@ void QTextLine::layout_helper(int maxGlyphs)
goto found;
}
}
+ lbh.saveCurrentGlyph();
}
if (lbh.currentPosition == end)
newItem = item + 1;
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index c5b6e14..0081550 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -1504,7 +1504,7 @@ QTextBlock QTextBlock::next() const
*/
QTextBlock QTextBlock::previous() const
{
- if (!isValid())
+ if (!p)
return QTextBlock();
return QTextBlock(p, p->blockMap().previous(n));
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index d3e8f2d..7fb2783 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -81,6 +81,12 @@ win32 {
HEADERS += text/qfontengine_win_p.h
}
+contains(QT_CONFIG, directwrite) {
+ LIBS_PRIVATE += -ldwrite
+ HEADERS += text/qfontenginedirectwrite_p.h
+ SOURCES += text/qfontenginedirectwrite.cpp
+}
+
unix:x11 {
HEADERS += \
text/qfontengine_x11_p.h \
diff --git a/src/gui/util/qflickgesture.cpp b/src/gui/util/qflickgesture.cpp
index eb0cc8d..fdd2a95 100644
--- a/src/gui/util/qflickgesture.cpp
+++ b/src/gui/util/qflickgesture.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -75,6 +75,7 @@ static QMouseEvent *copyMouseEvent(QEvent *e)
QMouseEvent *me = static_cast<QMouseEvent *>(e);
return new QMouseEvent(me->type(), QPoint(0, 0), me->globalPos(), me->button(), me->buttons(), me->modifiers());
}
+#ifndef QT_NO_GRAPHICSVIEW
case QEvent::GraphicsSceneMousePress:
case QEvent::GraphicsSceneMouseRelease:
case QEvent::GraphicsSceneMouseMove: {
@@ -103,6 +104,7 @@ static QMouseEvent *copyMouseEvent(QEvent *e)
return copy;
#endif
}
+#endif // QT_NO_GRAPHICSVIEW
default:
return 0;
}
@@ -265,6 +267,7 @@ protected:
if (mouseTarget) {
sendingEvent = true;
+#ifndef QT_NO_GRAPHICSVIEW
QGraphicsItem *grabber = 0;
if (mouseTarget->parentWidget()) {
if (QGraphicsView *gv = qobject_cast<QGraphicsView *>(mouseTarget->parentWidget())) {
@@ -281,12 +284,14 @@ protected:
qFGDebug() << "QFG: ungrabbing" << grabber;
grabber->ungrabMouse();
}
+#endif // QT_NO_GRAPHICSVIEW
if (me) {
QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), me->globalPos(), me->button(), me->buttons(), me->modifiers());
qt_sendSpontaneousEvent(mouseTarget, &copy);
}
+#ifndef QT_NO_GRAPHICSVIEW
if (grabber && (flags & RegrabMouseAfterwards)) {
// GraphicsView Mouse Handling Workaround #2:
// we need to re-grab the mouse after sending a faked mouse
@@ -296,6 +301,7 @@ protected:
qFGDebug() << "QFG: re-grabbing" << grabber;
grabber->grabMouse();
}
+#endif
sendingEvent = false;
}
}
@@ -357,10 +363,12 @@ QFlickGestureRecognizer::QFlickGestureRecognizer(Qt::MouseButton button)
*/
QGesture *QFlickGestureRecognizer::create(QObject *target)
{
+#ifndef QT_NO_GRAPHICSVIEW
QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target);
if (go && button == Qt::NoButton) {
go->setAcceptTouchEvents(true);
}
+#endif
return new QFlickGesture(target, button);
}
@@ -389,7 +397,9 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
return Ignore; // nothing to do without a scroller?
QWidget *receiverWidget = qobject_cast<QWidget *>(d->receiver);
+#ifndef QT_NO_GRAPHICSVIEW
QGraphicsObject *receiverGraphicsObject = qobject_cast<QGraphicsObject *>(d->receiver);
+#endif
// this is only set for events that we inject into the event loop via sendEvent()
if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) {
@@ -398,7 +408,9 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
}
const QMouseEvent *me = 0;
+#ifndef QT_NO_GRAPHICSVIEW
const QGraphicsSceneMouseEvent *gsme = 0;
+#endif
const QTouchEvent *te = 0;
QPoint globalPos;
@@ -415,6 +427,7 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
globalPos = me->globalPos();
}
break;
+#ifndef QT_NO_GRAPHICSVIEW
case QEvent::GraphicsSceneMousePress:
case QEvent::GraphicsSceneMouseRelease:
case QEvent::GraphicsSceneMouseMove:
@@ -425,6 +438,7 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
globalPos = gsme->screenPos();
}
break;
+#endif
case QEvent::TouchBegin:
case QEvent::TouchEnd:
case QEvent::TouchUpdate:
@@ -466,7 +480,11 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
break;
}
- if (!me && !gsme && !te) // Neither mouse nor touch
+ if (!me
+#ifndef QT_NO_GRAPHICSVIEW
+ && !gsme
+#endif
+ && !te) // Neither mouse nor touch
return Ignore;
// get the current pointer position in local coordinates.
@@ -502,6 +520,7 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
}
break;
+#ifndef QT_NO_GRAPHICSVIEW
case QEvent::GraphicsSceneMousePress:
if (gsme && gsme->button() == button && gsme->buttons() == button) {
point = gsme->scenePos();
@@ -529,6 +548,7 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
inputType = QScroller::InputMove;
}
break;
+#endif
case QEvent::TouchBegin:
inputType = QScroller::InputPress;
@@ -568,12 +588,14 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
if (QWidget *w = qobject_cast<QWidget *>(as->target())) {
scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size());
+#ifndef QT_NO_GRAPHICSVIEW
} else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) {
if (go->scene() && !go->scene()->views().isEmpty()) {
foreach (QGraphicsView *gv, go->scene()->views())
scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect()))
.translated(gv->mapToGlobal(QPoint(0, 0)));
}
+#endif
}
// active scrollers always have priority
if (scrollerRegion.contains(globalPos))
@@ -588,8 +610,10 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
if (inputType) {
if (QWidget *w = qobject_cast<QWidget *>(d->receiver))
point = w->mapFromGlobal(point.toPoint());
+#ifndef QT_NO_GRAPHICSVIEW
else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->receiver))
point = go->mapFromScene(point);
+#endif
// inform the scroller about the new event
scroller->handleInput(inputType, point, monotonicTimer.elapsed());
@@ -602,7 +626,11 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
// Consume all mouse events while dragging or scrolling to avoid nasty
// side effects with Qt's standard widgets.
- if ((me || gsme) && scrollerIsActive)
+ if ((me
+#ifndef QT_NO_GRAPHICSVIEW
+ || gsme
+#endif
+ ) && scrollerIsActive)
result |= ConsumeEventHint;
// The only problem with this approach is that we consume the
@@ -610,7 +638,11 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
// have to fake a MouseRelease "somewhere" to not mess with the internal
// states of Qt's widgets (a QPushButton would stay in 'pressed' state
// forever, if it doesn't receive a MouseRelease).
- if (me || gsme) {
+ if (me
+#ifndef QT_NO_GRAPHICSVIEW
+ || gsme
+#endif
+ ) {
if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive)
PressDelayHandler::instance()->scrollerBecameActive();
else if (scrollerWasScrolling && (scroller->state() == QScroller::Dragging || scroller->state() == QScroller::Inactive))
@@ -622,7 +654,9 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
} else {
switch (event->type()) {
case QEvent::MouseButtonPress:
+#ifndef QT_NO_GRAPHICSVIEW
case QEvent::GraphicsSceneMousePress:
+#endif
if (scroller->state() == QScroller::Pressed) {
int pressDelay = int(1000 * scroller->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal());
if (pressDelay > 0) {
@@ -639,7 +673,9 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
break;
case QEvent::MouseMove:
+#ifndef QT_NO_GRAPHICSVIEW
case QEvent::GraphicsSceneMouseMove:
+#endif
if (PressDelayHandler::instance()->isDelaying())
result |= ConsumeEventHint;
// fall through
@@ -647,7 +683,9 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
result |= scrollerIsActive ? TriggerGesture : Ignore;
break;
+#ifndef QT_NO_GRAPHICSVIEW
case QEvent::GraphicsSceneMouseRelease:
+#endif
case QEvent::MouseButtonRelease:
if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive))
result |= ConsumeEventHint;
diff --git a/src/gui/util/qflickgesture_p.h b/src/gui/util/qflickgesture_p.h
index c3c263b..451b579 100644
--- a/src/gui/util/qflickgesture_p.h
+++ b/src/gui/util/qflickgesture_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp
index d60f44e..9c2d24d 100644
--- a/src/gui/util/qscroller.cpp
+++ b/src/gui/util/qscroller.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -192,6 +192,7 @@ static qreal progressForValue(const QEasingCurve &curve, qreal value)
}
+#ifndef QT_NO_ANIMATION
class QScrollTimer : public QAbstractAnimation
{
public:
@@ -230,6 +231,7 @@ private:
bool ignoreUpdate;
int skip;
};
+#endif // QT_NO_ANIMATION
/*!
\class QScroller
@@ -376,6 +378,7 @@ void QScroller::setScrollerProperties(const QScrollerProperties &sp)
}
}
+#ifndef QT_NO_GESTURES
/*!
Registers a custom scroll gesture recognizer, grabs it for the \a
@@ -426,11 +429,12 @@ Qt::GestureType QScroller::grabGesture(QObject *target, ScrollerGestureType scro
widget->grabGesture(sp->recognizerType);
if (scrollGestureType == TouchGesture)
widget->setAttribute(Qt::WA_AcceptTouchEvents);
-
+#ifndef QT_NO_GRAPHICSVIEW
} else if (QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target)) {
if (scrollGestureType == TouchGesture)
go->setAcceptTouchEvents(true);
go->grabGesture(sp->recognizerType);
+#endif // QT_NO_GRAPHICSVIEW
}
return sp->recognizerType;
}
@@ -469,9 +473,10 @@ void QScroller::ungrabGesture(QObject *target)
if (target->isWidgetType()) {
QWidget *widget = static_cast<QWidget *>(target);
widget->ungrabGesture(sp->recognizerType);
-
+#ifndef QT_NO_GRAPHICSVIEW
} else if (QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target)) {
go->ungrabGesture(sp->recognizerType);
+#endif
}
QGestureRecognizer::unregisterRecognizer(sp->recognizerType);
@@ -479,6 +484,8 @@ void QScroller::ungrabGesture(QObject *target)
sp->recognizer = 0;
}
+#endif // QT_NO_GESTURES
+
/*!
\internal
*/
@@ -496,9 +503,11 @@ QScroller::QScroller(QObject *target)
QScroller::~QScroller()
{
Q_D(QScroller);
+#ifndef QT_NO_GESTURES
QGestureRecognizer::unregisterRecognizer(d->recognizerType);
// do not delete the recognizer. The QGestureManager is doing this.
d->recognizer = 0;
+#endif
QScrollerPrivate::allScrollers.remove(d->target);
QScrollerPrivate::activeScrollers.remove(this);
@@ -562,6 +571,7 @@ QPointF QScroller::pixelPerMeter() const
Q_D(const QScroller);
QPointF ppm = d->pixelPerMeter;
+#ifndef QT_NO_GRAPHICSVIEW
if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->target)) {
QTransform viewtr;
//TODO: the first view isn't really correct - maybe use an additional field in the prepare event?
@@ -576,6 +586,7 @@ QPointF QScroller::pixelPerMeter() const
ppm.ry() /= QLineF(p0, py).length();
}
}
+#endif // QT_NO_GRAPHICSVIEW
return ppm;
}
@@ -869,8 +880,10 @@ void QScroller::setSnapPositionsY(qreal first, qreal interval)
QScrollerPrivate::QScrollerPrivate(QScroller *q, QObject *_target)
: target(_target)
+#ifndef QT_NO_GESTURES
, recognizer(0)
, recognizerType(Qt::CustomGesture)
+#endif
, state(QScroller::Inactive)
, firstScroll(true)
, pressTimestamp(0)
@@ -879,7 +892,9 @@ QScrollerPrivate::QScrollerPrivate(QScroller *q, QObject *_target)
, snapIntervalX(0.0)
, snapFirstY(-1.0)
, snapIntervalY(0.0)
+#ifndef QT_NO_ANIMATION
, scrollTimer(new QScrollTimer(this))
+#endif
, q_ptr(q)
{
connect(target, SIGNAL(destroyed(QObject*)), this, SLOT(targetDestroyed()));
@@ -919,7 +934,9 @@ const char *QScrollerPrivate::inputName(QScroller::Input input)
void QScrollerPrivate::targetDestroyed()
{
+#ifndef QT_NO_ANIMATION
scrollTimer->stop();
+#endif
delete q_ptr;
}
@@ -945,7 +962,9 @@ void QScrollerPrivate::timerTick()
}
}
+#ifndef QT_NO_ANIMATION
scrollTimer->stop();
+#endif
}
/*!
@@ -1436,11 +1455,13 @@ bool QScrollerPrivate::prepareScrolling(const QPointF &position)
if (QWidget *w = qobject_cast<QWidget *>(target))
setDpiFromWidget(w);
+#ifndef QT_NO_GRAPHICSVIEW
if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(target)) {
//TODO: the first view isn't really correct - maybe use an additional field in the prepare event?
if (go->scene() && !go->scene()->views().isEmpty())
setDpiFromWidget(go->scene()->views().first());
}
+#endif
if (state == QScroller::Scrolling) {
recalcScrollingSegments();
@@ -1690,7 +1711,9 @@ void QScrollerPrivate::setState(QScroller::State newstate)
switch (newstate) {
case QScroller::Inactive:
+#ifndef QT_NO_ANIMATION
scrollTimer->stop();
+#endif
// send the last scroll event (but only after the current state change was finished)
if (!firstScroll)
@@ -1700,7 +1723,9 @@ void QScrollerPrivate::setState(QScroller::State newstate)
break;
case QScroller::Pressed:
+#ifndef QT_NO_ANIMATION
scrollTimer->stop();
+#endif
oldVelocity = releaseVelocity;
releaseVelocity = QPointF(0, 0);
@@ -1708,12 +1733,16 @@ void QScrollerPrivate::setState(QScroller::State newstate)
case QScroller::Dragging:
dragDistance = QPointF(0, 0);
+#ifndef QT_NO_ANIMATION
if (state == QScroller::Pressed)
scrollTimer->start();
+#endif
break;
case QScroller::Scrolling:
+#ifndef QT_NO_ANIMATION
scrollTimer->start();
+#endif
break;
}
diff --git a/src/gui/util/qscroller.h b/src/gui/util/qscroller.h
index 7d7e1ca..1599c7d 100644
--- a/src/gui/util/qscroller.h
+++ b/src/gui/util/qscroller.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -55,8 +55,10 @@ QT_MODULE(Gui)
class QWidget;
class QScrollerPrivate;
class QScrollerProperties;
+#ifndef QT_NO_GESTURES
class QFlickGestureRecognizer;
class QMouseFlickGestureRecognizer;
+#endif
class Q_GUI_EXPORT QScroller : public QObject
{
@@ -94,9 +96,11 @@ public:
static QScroller *scroller(QObject *target);
static const QScroller *scroller(const QObject *target);
+#ifndef QT_NO_GESTURES
static Qt::GestureType grabGesture(QObject *target, ScrollerGestureType gestureType = TouchGesture);
static Qt::GestureType grabbedGesture(QObject *target);
static void ungrabGesture(QObject *target);
+#endif
static QList<QScroller *> activeScrollers();
@@ -139,7 +143,9 @@ private:
Q_DISABLE_COPY(QScroller)
Q_DECLARE_PRIVATE(QScroller)
+#ifndef QT_NO_GESTURES
friend class QFlickGestureRecognizer;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/util/qscroller_mac.mm b/src/gui/util/qscroller_mac.mm
index 3203036..4bf69c1 100644
--- a/src/gui/util/qscroller_mac.mm
+++ b/src/gui/util/qscroller_mac.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -39,12 +39,14 @@
**
****************************************************************************/
+#include <QtCore/qglobal.h>
+
+#ifdef Q_WS_MAC
+
#import <Cocoa/Cocoa.h>
#include "qscroller_p.h"
-#ifdef Q_WS_MAC
-
QPointF QScrollerPrivate::realDpi(int screen)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
diff --git a/src/gui/util/qscroller_p.h b/src/gui/util/qscroller_p.h
index d16eef9..8c5f2e7 100644
--- a/src/gui/util/qscroller_p.h
+++ b/src/gui/util/qscroller_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -69,10 +69,13 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_GESTURES
class QFlickGestureRecognizer;
+#endif
+#ifndef QT_NO_ANIMATION
class QScrollTimer;
-
+#endif
class QScrollerPrivate : public QObject
{
Q_OBJECT
@@ -152,8 +155,10 @@ public:
// non static
QObject *target;
QScrollerProperties properties;
+#ifndef QT_NO_GESTURES
QFlickGestureRecognizer *recognizer;
Qt::GestureType recognizerType;
+#endif
// scroller state:
@@ -194,7 +199,9 @@ public:
QElapsedTimer monotonicTimer;
QPointF releaseVelocity; // the starting velocity of the scrolling state
+#ifndef QT_NO_ANIMATION
QScrollTimer *scrollTimer;
+#endif
QScroller *q_ptr;
};
diff --git a/src/gui/util/qscrollerproperties.cpp b/src/gui/util/qscrollerproperties.cpp
index b159e05..85e2e82 100644
--- a/src/gui/util/qscrollerproperties.cpp
+++ b/src/gui/util/qscrollerproperties.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/util/qscrollerproperties.h b/src/gui/util/qscrollerproperties.h
index e292d8d..75d8932 100644
--- a/src/gui/util/qscrollerproperties.h
+++ b/src/gui/util/qscrollerproperties.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/util/qscrollerproperties_p.h b/src/gui/util/qscrollerproperties_p.h
index 093f615..76d8b0a 100644
--- a/src/gui/util/qscrollerproperties_p.h
+++ b/src/gui/util/qscrollerproperties_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp
index 2b7935b..5a0e179 100644
--- a/src/gui/util/qsystemtrayicon_win.cpp
+++ b/src/gui/util/qsystemtrayicon_win.cpp
@@ -305,6 +305,7 @@ bool QSystemTrayIconSys::winEvent( MSG *m, long *result )
case WM_CONTEXTMENU:
if (q->contextMenu()) {
q->contextMenu()->popup(gpos);
+ q->contextMenu()->activateWindow();
}
emit q->activated(QSystemTrayIcon::Context);
break;
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 7460f32..f948af9 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -1386,6 +1386,7 @@ bool QAbstractScrollAreaPrivate::canStartScrollingAt( const QPoint &startPos )
{
Q_Q(QAbstractScrollArea);
+#ifndef QT_NO_GRAPHICSVIEW
// don't start scrolling when a drag mode has been set.
// don't start scrolling on a movable item.
if (QGraphicsView *view = qobject_cast<QGraphicsView *>(q)) {
@@ -1397,6 +1398,7 @@ bool QAbstractScrollAreaPrivate::canStartScrollingAt( const QPoint &startPos )
if (childItem && (childItem->flags() & QGraphicsItem::ItemIsMovable))
return false;
}
+#endif
// don't start scrolling on a QAbstractSlider
if (qobject_cast<QAbstractSlider *>(q->viewport()->childAt(startPos))) {
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index b5dda5a..d63ccfb 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -705,11 +705,13 @@ void QComboBoxPrivateContainer::hideEvent(QHideEvent *)
{
emit resetButton();
combo->update();
+#ifndef QT_NO_GRAPHICSVIEW
// QGraphicsScenePrivate::removePopup closes the combo box popup, it hides it non-explicitly.
// Hiding/showing the QComboBox after this will unexpectedly show the popup as well.
// Re-hiding the popup container makes sure it is explicitly hidden.
if (QGraphicsProxyWidget *proxy = graphicsProxyWidget())
proxy->hide();
+#endif
}
void QComboBoxPrivateContainer::mousePressEvent(QMouseEvent *e)
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index f20e018..3eac64a 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -414,10 +414,14 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
if (isGettingInput) {
// If any text is being input, remove selected text.
priorState = m_undoState;
+ if (echoMode() == QLineEdit::PasswordEchoOnEdit && !passwordEchoEditing()) {
+ updatePasswordEchoEditing(true);
+ m_selstart = 0;
+ m_selend = m_text.length();
+ }
removeSelectedText();
}
-
int c = m_cursor; // cursor position after insertion of commit string
if (event->replacementStart() <= 0)
c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength());
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index fd61783..43d6796 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -1521,12 +1521,23 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
#ifdef QT_MAC_USE_COCOA
// Activate the unified toolbar with the raster engine.
- if (windowSurface()) {
+ if (windowSurface() && set) {
d->layout->unifiedSurface = new QUnifiedToolbarSurface(this);
}
#endif // QT_MAC_USE_COCOA
d->layout->updateHIToolBarStatus();
+
+#ifdef QT_MAC_USE_COCOA
+ // Deactivate the unified toolbar with the raster engine.
+ if (windowSurface() && !set) {
+ if (d->layout->unifiedSurface) {
+ delete d->layout->unifiedSurface;
+ d->layout->unifiedSurface = 0;
+ }
+ }
+#endif // QT_MAC_USE_COCOA
+
// Enabling the unified toolbar clears the opaque size grip setting, update it.
d->macUpdateOpaqueSizeGrip();
#else
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp
index 6bc07e1..d4afe07 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/gui/widgets/qmainwindowlayout.cpp
@@ -73,6 +73,10 @@
# include <private/qt_cocoa_helpers_mac_p.h>
#endif
+#ifdef QT_NO_DOCKWIDGET
+extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
+#endif
+
#ifdef Q_DEBUG_MAINWINDOW_LAYOUT
# include <QTextStream>
#endif
diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm
index e428ffc..761a433 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/gui/widgets/qmainwindowlayout_mac.mm
@@ -356,10 +356,10 @@ void QMainWindowLayout::updateHIToolBarStatus()
while (!qtoolbarsInUnifiedToolbarList.isEmpty()) {
// Should shrink the list by one every time.
QToolBar *toolbar = qtoolbarsInUnifiedToolbarList.first();
- layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar);
#if defined(QT_MAC_USE_COCOA)
- toolbar->d_func()->isInUnifiedToolbar = false;
+ unifiedSurface->removeToolbar(toolbar);
#endif
+ layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar);
}
macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0);
} else {
@@ -393,7 +393,7 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar
return;
#if defined(QT_MAC_USE_COCOA)
- // toolbar will now become native (if not allready) since we need
+ // toolbar will now become native (if not already) since we need
// an nsview for it inside the corresponding NSToolbarItem.
// Setting isInUnifiedToolbar will (among other things) stop alien
// siblings from becoming native when this happends since the toolbar
diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h
index 2a44432..20aca61 100644
--- a/src/gui/widgets/qmainwindowlayout_p.h
+++ b/src/gui/widgets/qmainwindowlayout_p.h
@@ -70,12 +70,12 @@
//#define Q_DEBUG_MAINWINDOW_LAYOUT
-#ifdef Q_DEBUG_MAINWINDOW_LAYOUT
+#if defined(Q_DEBUG_MAINWINDOW_LAYOUT) && !defined(QT_NO_DOCKWIDGET)
QT_BEGIN_NAMESPACE
class QTextStream;
Q_GUI_EXPORT void qt_dumpLayout(QTextStream &qout, QMainWindow *window);
QT_END_NAMESPACE
-#endif // Q_DEBUG_MAINWINDOW_LAYOUT
+#endif // Q_DEBUG_MAINWINDOW_LAYOUT && !QT_NO_DOCKWIDGET
#ifdef Q_WS_MAC
// Forward defs to make avoid including Carbon.h (faster compile you know ;).
diff --git a/src/gui/widgets/qsplashscreen.cpp b/src/gui/widgets/qsplashscreen.cpp
index 75280cb..9c486bf 100644
--- a/src/gui/widgets/qsplashscreen.cpp
+++ b/src/gui/widgets/qsplashscreen.cpp
@@ -223,8 +223,8 @@ void QSplashScreen::finish(QWidget *mainWin)
{
if (mainWin) {
#if defined(Q_WS_X11)
- extern void qt_x11_wait_for_window_manager(QWidget *mainWin);
- qt_x11_wait_for_window_manager(mainWin);
+ extern void qt_x11_wait_for_window_manager(QWidget *mainWin, bool);
+ qt_x11_wait_for_window_manager(mainWin, false);
#endif
}
close();