summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/global/qnamespace.h2
-rw-r--r--src/corelib/global/qnamespace.qdoc1
-rw-r--r--src/gui/kernel/qapplication_s60.cpp159
-rw-r--r--src/gui/kernel/qt_s60_p.h15
-rw-r--r--src/gui/kernel/qwidget_s60.cpp2
5 files changed, 132 insertions, 47 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 4d70744..15cc809 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -526,6 +526,8 @@ public:
WA_X11DoNotAcceptFocus = 132,
+ WA_SymbianNoSystemRotation = 133,
+
// Add new attributes before this line
WA_AttributeCount
};
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 22ad83b..f03fb25 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -1244,6 +1244,7 @@
\omitvalue WA_SetWindowModality
\omitvalue WA_WState_WindowOpacitySet
\omitvalue WA_WState_AcceptedTouchBeginEvent
+ \omitvalue WA_SymbianNoSystemRotation
*/
/*! \typedef Qt::HANDLE
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index f80b657..d37845d 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -546,11 +546,52 @@ void QSymbianControl::setWidget(QWidget *w)
{
qwidget = w;
}
+
+QPoint QSymbianControl::translatePointForFixedNativeOrientation(const TPoint &pointerEventPos) const
+{
+ QPoint pos(pointerEventPos.iX, pointerEventPos.iY);
+ if (qwidget->d_func()->fixNativeOrientationCalled) {
+ QSize wsize = qwidget->size();
+ TSize size = Size();
+ if (size.iWidth == wsize.height() && size.iHeight == wsize.width()) {
+ qreal x = pos.x();
+ qreal y = pos.y();
+ pos.setX(size.iHeight - y);
+ pos.setY(x);
+ }
+ }
+ return pos;
+}
+
+TRect QSymbianControl::translateRectForFixedNativeOrientation(const TRect &controlRect) const
+{
+ TRect rect = controlRect;
+ if (qwidget->d_func()->fixNativeOrientationCalled) {
+ QPoint a = translatePointForFixedNativeOrientation(rect.iTl);
+ QPoint b = translatePointForFixedNativeOrientation(rect.iBr);
+ if (a.x() < b.x()) {
+ rect.iTl.iX = a.x();
+ rect.iBr.iX = b.x();
+ } else {
+ rect.iTl.iX = b.x();
+ rect.iBr.iX = a.x();
+ }
+ if (a.y() < b.y()) {
+ rect.iTl.iY = a.y();
+ rect.iBr.iY = b.y();
+ } else {
+ rect.iTl.iY = b.y();
+ rect.iBr.iY = a.y();
+ }
+ }
+ return rect;
+}
+
void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation )
{
QWidget *alienWidget;
- QPoint widgetPos = QPoint(aPenEventLocation.iX, aPenEventLocation.iY);
- QPoint globalPos = QPoint(aPenEventScreenLocation.iX,aPenEventScreenLocation.iY);
+ QPoint widgetPos = translatePointForFixedNativeOrientation(aPenEventLocation);
+ QPoint globalPos = translatePointForFixedNativeOrientation(aPenEventScreenLocation);
alienWidget = qwidget->childAt(widgetPos);
if (!alienWidget)
alienWidget = qwidget;
@@ -565,7 +606,7 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons
void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event)
{
QApplicationPrivate *d = QApplicationPrivate::instance();
- QPointF screenPos = qwidget->mapToGlobal(QPoint(event->iPosition.iX, event->iPosition.iY));
+ QPointF screenPos = qwidget->mapToGlobal(translatePointForFixedNativeOrientation(event->iPosition));
qreal pressure;
if(d->pressureSupported
&& event->Pressure() > 0) //workaround for misconfigured HAL
@@ -666,7 +707,7 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
mapS60MouseEventTypeToQt(&type, &button, &pEvent);
Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers);
- QPoint widgetPos = QPoint(pEvent.iPosition.iX, pEvent.iPosition.iY);
+ QPoint widgetPos = translatePointForFixedNativeOrientation(pEvent.iPosition);
TPoint controlScreenPos = PositionRelativeToScreen();
QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
S60->lastCursorPos = globalPos;
@@ -1132,6 +1173,9 @@ void QSymbianControl::Draw(const TRect& controlRect) const
Q_ASSERT(window);
QTLWExtra *topExtra = window->d_func()->maybeTopData();
Q_ASSERT(topExtra);
+
+ TRect wcontrolRect = translateRectForFixedNativeOrientation(controlRect);
+
if (!topExtra->inExpose) {
topExtra->inExpose = true;
if (!qwidget->isWindow()) {
@@ -1142,7 +1186,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
gc.SetBrushColor(TRgb(0, 0, 0, 0));
gc.Clear(controlRect);
}
- QRect exposeRect = qt_TRect2QRect(controlRect);
+ QRect exposeRect = qt_TRect2QRect(wcontrolRect);
qwidget->d_func()->syncBackingStore(exposeRect);
topExtra->inExpose = false;
}
@@ -1155,7 +1199,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents;
if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(controlRect);
+ const QRect r = qt_TRect2QRect(wcontrolRect);
QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r));
}
@@ -1210,7 +1254,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
}
if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(controlRect);
+ const QRect r = qt_TRect2QRect(wcontrolRect);
// The draw ops aren't actually sent to WSERV until the graphics
// context is deactivated, which happens in the function calling
// this one. We therefore delay the delivery of endNativePaintEvent,
@@ -1223,14 +1267,45 @@ void QSymbianControl::Draw(const TRect& controlRect) const
}
}
+void QSymbianControl::qwidgetResize_helper(const QSize &newSize)
+{
+ QRect cr = qwidget->geometry();
+ QSize oldSize(cr.size());
+ cr.setSize(newSize);
+ qwidget->data->crect = cr;
+ if (qwidget->isVisible()) {
+ QTLWExtra *tlwExtra = qwidget->d_func()->maybeTopData();
+ bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
+ if (!slowResize && tlwExtra)
+ tlwExtra->inTopLevelResize = true;
+ QResizeEvent e(newSize, oldSize);
+ qt_sendSpontaneousEvent(qwidget, &e);
+ if (!qwidget->testAttribute(Qt::WA_StaticContents))
+ qwidget->d_func()->syncBackingStore();
+ if (!slowResize && tlwExtra)
+ tlwExtra->inTopLevelResize = false;
+ } else {
+ if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
+ QResizeEvent *e = new QResizeEvent(newSize, oldSize);
+ QApplication::postEvent(qwidget, e);
+ }
+ }
+}
+
void QSymbianControl::SizeChanged()
{
CCoeControl::SizeChanged();
+ // When FixNativeOrientation had been called, the RWindow/CCoeControl size
+ // and the surface/QWidget size have nothing to do with each other.
+ if (qwidget->d_func()->fixNativeOrientationCalled)
+ return;
+
QSize oldSize = qwidget->size();
QSize newSize(Size().iWidth, Size().iHeight);
if (oldSize != newSize) {
+ // Enforce the proper size for fullscreen widgets on the secondary screen.
const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
const int screenNumber = S60->screenNumberForWidget(qwidget);
if (!m_inExternalScreenOverride && isFullscreen && screenNumber > 0) {
@@ -1243,26 +1318,8 @@ void QSymbianControl::SizeChanged()
return;
}
}
- QRect cr = qwidget->geometry();
- cr.setSize(newSize);
- qwidget->data->crect = cr;
- if (qwidget->isVisible()) {
- QTLWExtra *tlwExtra = qwidget->d_func()->maybeTopData();
- bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = true;
- QResizeEvent e(newSize, oldSize);
- qt_sendSpontaneousEvent(qwidget, &e);
- if (!qwidget->testAttribute(Qt::WA_StaticContents))
- qwidget->d_func()->syncBackingStore();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = false;
- } else {
- if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
- QResizeEvent *e = new QResizeEvent(newSize, oldSize);
- QApplication::postEvent(qwidget, e);
- }
- }
+
+ qwidgetResize_helper(newSize);
}
m_inExternalScreenOverride = false;
@@ -1513,29 +1570,49 @@ bool QSymbianControl::isControlActive()
void QSymbianControl::ensureFixNativeOrientation()
{
#if defined(Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION)
- // Call FixNativeOrientation() for fullscreen QDeclarativeViews that
- // have a locked orientation matching the native orientation of the device.
- // This avoids unnecessary window rotation on wserv level.
- if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop
- || !qwidget->inherits("QDeclarativeView")
- || S60->screenNumberForWidget(qwidget) > 0)
+ if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop)
+ return;
+ if (S60->screenNumberForWidget(qwidget) > 0)
return;
- const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen);
const bool isFixed = qwidget->d_func()->fixNativeOrientationCalled;
- const bool matchesNative = qwidget->testAttribute(
- S60->nativeOrientationIsPortrait ? Qt::WA_LockPortraitOrientation
- : Qt::WA_LockLandscapeOrientation);
- if (isFullScreen && matchesNative) {
- if (!isFixed) {
- Window().FixNativeOrientation();
- qwidget->d_func()->fixNativeOrientationCalled = true;
+ const bool isFixEnabled = qwidget->testAttribute(Qt::WA_SymbianNoSystemRotation);
+ const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen);
+ if (isFullScreen && isFixEnabled) {
+ const bool surfaceBasedGs =
+ QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
+ || QApplicationPrivate::graphics_system_name == QLatin1String("opengl");
+ if (!surfaceBasedGs)
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ if (!isFixed && surfaceBasedGs) {
+ if (Window().FixNativeOrientation() == KErrNone) {
+ qwidget->d_func()->fixNativeOrientationCalled = true;
+ // The EGL window surface is now fixed to the native orientation
+ // of the device, no matter what size we pass when creating it.
+ // Enforce the same size for the QWidget too. For the underlying
+ // CCoeControl and RWindow it is up to the system to resize them
+ // when the standard auto-rotation mechanism is in use, we must not
+ // change that behavior by forcing any size for those. In practice
+ // this means that the QWidget and the underlying native control
+ // dimensions will be out of sync when FixNativeOrientation was
+ // called and the device is turned to the non-native (typically
+ // landscape) orientation. The pointer event handling and certain
+ // functions like Draw() will need to compensate for this.
+ QSize newSize(S60->nativeScreenWidthInPixels, S60->nativeScreenHeightInPixels);
+ if (qwidget->size() != newSize)
+ qwidgetResize_helper(newSize);
+ } else {
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ }
}
} else if (isFixed) {
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
qwidget->d_func()->fixNativeOrientationCalled = false;
qwidget->hide();
qwidget->d_func()->create_sys(0, false, true);
qwidget->show();
}
+#else
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
#endif
}
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index c48bf63..e24405c 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -191,7 +191,8 @@ public:
int screenWidthInTwipsForScreen[qt_symbian_max_screens];
int screenHeightInTwipsForScreen[qt_symbian_max_screens];
- bool nativeOrientationIsPortrait;
+ int nativeScreenWidthInPixels;
+ int nativeScreenHeightInPixels;
};
Q_AUTOTEST_EXPORT QS60Data* qGlobalS60Data();
@@ -237,6 +238,8 @@ public:
bool isControlActive();
void ensureFixNativeOrientation();
+ QPoint translatePointForFixedNativeOrientation(const TPoint &pointerEventPos) const;
+ TRect translateRectForFixedNativeOrientation(const TRect &controlRect) const;
#ifdef Q_WS_S60
void FadeBehindPopup(bool fade){ popupFader.FadeBehindPopup( this, this, fade); }
@@ -256,6 +259,9 @@ protected:
void PositionChanged();
void FocusChanged(TDrawNow aDrawNow);
+protected:
+ void qwidgetResize_helper(const QSize &newSize);
+
private:
void HandlePointerEvent(const TPointerEvent& aPointerEvent);
TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType);
@@ -363,18 +369,15 @@ inline void QS60Data::updateScreenSize()
// Look for a screen mode with rotation 0
// in order to decide what the native orientation is.
- int nativeScreenWidthInPixels = 0;
- int nativeScreenHeightInPixels = 0;
for (mode = 0; mode < screenModeCount; ++mode) {
TPixelsAndRotation sizeAndRotation;
dev->GetScreenModeSizeAndRotation(mode, sizeAndRotation);
if (sizeAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationNormal) {
- nativeScreenWidthInPixels = sizeAndRotation.iPixelSize.iWidth;
- nativeScreenHeightInPixels = sizeAndRotation.iPixelSize.iHeight;
+ S60->nativeScreenWidthInPixels = sizeAndRotation.iPixelSize.iWidth;
+ S60->nativeScreenHeightInPixels = sizeAndRotation.iPixelSize.iHeight;
break;
}
}
- S60->nativeOrientationIsPortrait = nativeScreenWidthInPixels <= nativeScreenHeightInPixels;
}
inline RWsSession& QS60Data::wsSession()
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 10bb98b..d55e1ad 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -838,6 +838,8 @@ void QWidgetPrivate::s60UpdateIsOpaque()
// recreate backing store to get translucent surface (raster surface).
extra->topextra->backingStore.create(q);
extra->topextra->backingStore.registerWidget(q);
+ // FixNativeOrientation() will not work without an EGL surface.
+ q->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
}
}
} else if (extra->topextra->nativeWindowTransparencyEnabled) {