summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qwidget_s60.cpp
diff options
context:
space:
mode:
authorRohan McGovern <rohan.mcgovern@nokia.com>2011-03-24 05:05:43 (GMT)
committerRohan McGovern <rohan.mcgovern@nokia.com>2011-03-24 05:06:59 (GMT)
commit24bfb5cfc80966b15a58be6ef8dc5514d3318af1 (patch)
tree153879a8a41148a45c0f66ee74acd4b972bbca50 /src/gui/kernel/qwidget_s60.cpp
parent774a3536b00c4d6e4c4c10b708e31b4373a338e3 (diff)
parentf5812ae1b669daa921eeabc903ec0eafcfe0c030 (diff)
downloadQt-24bfb5cfc80966b15a58be6ef8dc5514d3318af1.zip
Qt-24bfb5cfc80966b15a58be6ef8dc5514d3318af1.tar.gz
Qt-24bfb5cfc80966b15a58be6ef8dc5514d3318af1.tar.bz2
Merge qt/qt.git master into qa-team-master
Diffstat (limited to 'src/gui/kernel/qwidget_s60.cpp')
-rw-r--r--src/gui/kernel/qwidget_s60.cpp108
1 files changed, 88 insertions, 20 deletions
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index c544215..b031936 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -63,6 +63,19 @@
// CCoeControl objects until after the CONE event handler has finished running.
Q_DECLARE_METATYPE(WId)
+// Workaround for the fact that S60 SDKs 3.x do not contain the akntoolbar.h
+// header, even though the documentation says that it should be there, and indeed
+// it is present in the library.
+class CAknToolbar : public CAknControl,
+ public MCoeControlObserver,
+ public MCoeControlBackground,
+ public MEikCommandObserver,
+ public MAknFadedComponent
+{
+public:
+ IMPORT_C void SetToolbarVisibility(const TBool visible);
+};
+
QT_BEGIN_NAMESPACE
extern bool qt_nograb();
@@ -71,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())
@@ -336,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);
@@ -488,6 +509,7 @@ void QWidgetPrivate::show_sys()
QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId());
const bool isFullscreen = q->windowState() & Qt::WindowFullScreen;
+ const TBool cbaRequested = q->windowFlags() & Qt::WindowSoftkeysVisibleHint;
#ifdef Q_WS_S60
// Lazily initialize the S60 screen furniture when the first window is shown.
@@ -507,11 +529,25 @@ void QWidgetPrivate::show_sys()
CEikButtonGroupContainer *cba = CEikButtonGroupContainer::NewL(CEikButtonGroupContainer::ECba,
CEikButtonGroupContainer::EHorizontal,ui,R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+ if (isFullscreen && !cbaRequested)
+ cba->MakeVisible(false);
CEikButtonGroupContainer *oldCba = factory->SwapButtonGroup(cba);
Q_ASSERT(!oldCba);
S60->setButtonGroupContainer(cba);
+ // If the creation of the first widget is delayed, for example by doing it
+ // inside the event loop, S60 somehow "forgets" to set the visibility of the
+ // toolbar (the three middle softkeys) when you flip the phone over, so we
+ // need to do it ourselves to avoid a "hole" in the application, even though
+ // Qt itself does not use the toolbar directly..
+ CAknAppUi *appui = dynamic_cast<CAknAppUi *>(CEikonEnv::Static()->AppUi());
+ if (appui) {
+ CAknToolbar *toolbar = appui->PopupToolbar();
+ if (toolbar && !toolbar->IsVisible())
+ toolbar->SetToolbarVisibility(ETrue);
+ }
+
CEikMenuBar *menuBar = new(ELeave) CEikMenuBar;
menuBar->ConstructL(ui, 0, R_AVKON_MENUPANE_EMPTY);
menuBar->SetMenuType(CEikMenuBar::EMenuOptions);
@@ -616,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);
}
}
@@ -628,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);
}
@@ -698,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())
@@ -768,28 +809,43 @@ 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")
+ || 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);
+ extra->topextra->backingStore.registerWidget(q);
+ }
}
} else if (extra->topextra->nativeWindowTransparencyEnabled) {
window->SetTransparentRegion(TRegionFix<1>());
extra->topextra->nativeWindowTransparencyEnabled = 0;
}
-#endif
}
void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
@@ -1005,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:
@@ -1152,14 +1208,17 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
}
#ifdef Q_WS_S60
- // Hide window decoration when switching to fullsccreen / minimized otherwise show decoration.
- // The window decoration visibility has to be changed before doing actual window state
- // change since in that order the availableGeometry will return directly the right size and
- // we will avoid unnecessarty redraws
- const bool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
- const bool statusPaneVisibility = visible;
- const bool buttonGroupVisibility = (visible || (isFullscreen && cbaRequested));
- S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility);
+ bool decorationsVisible(false);
+ if (!parentWidget()) { // Only top level native windows have control over cba/status pane
+ // Hide window decoration when switching to fullscreen / minimized otherwise show decoration.
+ // The window decoration visibility has to be changed before doing actual window state
+ // change since in that order the availableGeometry will return directly the right size and
+ // we will avoid unnecessary redraws
+ decorationsVisible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
+ const bool statusPaneVisibility = decorationsVisible;
+ const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaRequested));
+ S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility);
+ }
#endif // Q_WS_S60
// Ensure the initial size is valid, since we store it as normalGeometry below.
@@ -1172,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));
@@ -1183,7 +1251,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
// accurate because it did not consider the status pane. This means that when returning
// normal mode after showing the status pane, the geometry would overlap so we should
// move it if it never had an explicit position.
- if (!wasMoved && S60->statusPane() && visible) {
+ if (!wasMoved && S60->statusPane() && decorationsVisible) {
TPoint tl = static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl;
normalGeometry.setTopLeft(QPoint(tl.iX, tl.iY));
}