From 92d6d1c974206bac7520101ad26ca93eb0b4d977 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 27 Jul 2010 16:23:52 +0100 Subject: Ensure that window rectangle is updated when CBA visibility changes In S60, there are two pieces of screen furniture, changes in whose visibility or size can affect the size of the Qt application window. These are the status pane, at the top of the screen, and the CBA at the bottom. QSymbianControl listens for changes in status pane visibility and size by implementing MEikStatusPaneObserver. Notifications received via this interface trigger a call to QSymbianControl::handleClientAreaChange() which resizes the control. There is no corresponding interface through which to receive notifications of changes in CBA visibility. This patch introduces a utility function for setting the visibility of both the status pane and CBA, which ensures that the control's rectangle is updated when either one changes. Task-number: QTBUG-5320 Reviewed-by: Jason Barron --- src/gui/kernel/qapplication_s60.cpp | 36 +++++++++++++++++++++++++----------- src/gui/kernel/qt_s60_p.h | 3 +++ src/gui/kernel/qwidget_s60.cpp | 15 +++++---------- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 1c06100..e8ee2e4 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -112,6 +112,25 @@ QS60Data* qGlobalS60Data() return qt_s60Data(); } +#ifdef Q_WS_S60 +void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible) +{ + bool buttonGroupVisibilityChanged = false; + if (CEikButtonGroupContainer *const b = buttonGroupContainer()) { + buttonGroupVisibilityChanged = (b->IsVisible() != buttonGroupVisible); + b->MakeVisible(buttonGroupVisible); + } + bool statusPaneVisibilityChanged = false; + if (CEikStatusPane *const s = statusPane()) { + statusPaneVisibilityChanged = (s->IsVisible() != statusPaneVisible); + s->MakeVisible(statusPaneVisible); + } + if (buttonGroupVisibilityChanged && !statusPaneVisibilityChanged) + // Ensure that control rectangle is updated + static_cast(QApplication::activeWindow()->winId())->handleClientAreaChange(); +} +#endif + bool qt_nograb() // application no-grab option { #if defined(QT_DEBUG) @@ -1100,17 +1119,12 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle()); #ifdef Q_WS_S60 // If widget is fullscreen/minimized, hide status pane and button container otherwise show them. - CEikStatusPane *statusPane = S60->statusPane(); - CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer(); - TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); - if (statusPane) - statusPane->MakeVisible(visible); - if (buttonGroup) { - // Visibility - const TBool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen; - const TBool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint; - buttonGroup->MakeVisible(visible || (isFullscreen && cbaVisibilityHint)); - } + const bool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool statusPaneVisibility = visible; + const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen; + const bool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint; + const bool buttonGroupVisibility = (visible || (isFullscreen && cbaVisibilityHint)); + S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); #endif } else if (QApplication::activeWindow() == qwidget->window()) { if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) { diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index d8ef67d..6be9bbc 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -155,6 +155,7 @@ public: static inline CAknTitlePane* titlePane(); static inline CAknContextPane* contextPane(); static inline CEikButtonGroupContainer* buttonGroupContainer(); + static void setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible); #endif #ifdef Q_OS_SYMBIAN @@ -236,6 +237,8 @@ private: #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); #endif + +public: void handleClientAreaChange(); private: diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 75a11ee..56349ad 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -1113,15 +1113,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate) // 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 - CEikStatusPane *statusPane = S60->statusPane(); - CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer(); - TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); - if (statusPane) - statusPane->MakeVisible(visible); - if (buttonGroup) { - // Visibility - buttonGroup->MakeVisible(visible || (isFullscreen && cbaRequested)); - } + const bool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool statusPaneVisibility = visible; + const bool buttonGroupVisibility = (visible || (isFullscreen && cbaRequested)); + S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); #endif // Q_WS_S60 // Ensure the initial size is valid, since we store it as normalGeometry below. @@ -1145,7 +1140,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 && statusPane && visible) { + if (!wasMoved && S60->statusPane() && visible) { TPoint tl = static_cast(S60->appUi())->ClientRect().iTl; normalGeometry.setTopLeft(QPoint(tl.iX, tl.iY)); } -- cgit v0.12