Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/kernel/qwidget_s60.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5555#ifdef Q_WS_S60
    5656#include <aknappui.h>
     57#include <eikbtgpc.h>
    5758#endif
    5859
    59 // This is necessary in order to be able to perform delayed invokation on slots
     60// This is necessary in order to be able to perform delayed invocation on slots
    6061// which take arguments of type WId.  One example is
    6162// QWidgetPrivate::_q_delayedDestroy, which is used to delay destruction of
     
    6364Q_DECLARE_METATYPE(WId)
    6465
     66// Workaround for the fact that S60 SDKs 3.x do not contain the akntoolbar.h
     67// header, even though the documentation says that it should be there, and indeed
     68// it is present in the library.
     69class CAknToolbar : public CAknControl,
     70                    public MCoeControlObserver,
     71                    public MCoeControlBackground,
     72                    public MEikCommandObserver,
     73                    public MAknFadedComponent
     74{
     75public:
     76    IMPORT_C void SetToolbarVisibility(const TBool visible);
     77};
     78
    6579QT_BEGIN_NAMESPACE
    6680
     
    6983QWidget *QWidgetPrivate::mouseGrabber = 0;
    7084QWidget *QWidgetPrivate::keyboardGrabber = 0;
     85CEikButtonGroupContainer *QS60Data::cba = 0;
    7186
    7287static bool isEqual(const QList<QAction*>& a, const QList<QAction*>& b)
     
    366381        // Symbian windows are always created in an inactive state
    367382        // We perform this assignment for the case where the window is being re-created
    368         // as aa result of a call to setParent_sys, on either this widget or one of its
     383        // as a result of a call to setParent_sys, on either this widget or one of its
    369384        // ancestors.
    370385        extra->activated = 0;
     
    410425        // Symbian windows are always created in an inactive state
    411426        // We perform this assignment for the case where the window is being re-created
    412         // as aa result of a call to setParent_sys, on either this widget or one of its
     427        // as a result of a call to setParent_sys, on either this widget or one of its
    413428        // ancestors.
    414429        extra->activated = 0;
     
    434449        drawableWindow->PointerFilter(EPointerFilterEnterExit
    435450            | EPointerFilterMove | EPointerFilterDrag, 0);
     451        drawableWindow->EnableVisibilityChangeEvents();
    436452
    437453        if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) {
     
    481497
    482498         QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId());
     499         const bool isFullscreen = q->windowState() & Qt::WindowFullScreen;
     500         const TBool cbaRequested = q->windowFlags() & Qt::WindowSoftkeysVisibleHint;
    483501
    484502#ifdef Q_WS_S60
    485503        // Lazily initialize the S60 screen furniture when the first window is shown.
    486         if (!QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)
     504        if (q->isWindow() && !QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)
    487505                && !S60->buttonGroupContainer() && !S60->statusPane()) {
    488 
    489             bool isFullscreen = q->windowState() & Qt::WindowFullScreen;
    490506
    491507            if (!q->testAttribute(Qt::WA_DontShowOnScreen)) {
     
    494510                CEikAppUi *ui = static_cast<CEikAppUi *>(S60->appUi());
    495511                MEikAppUiFactory *factory = CEikonEnv::Static()->AppUiFactory();
    496                 TRAP_IGNORE(factory->ReadAppInfoResourceL(0, ui));
    497                 if (S60->buttonGroupContainer())
    498                     S60->buttonGroupContainer()->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
     512
     513                QT_TRAP_THROWING(
     514                    factory->CreateResourceIndependentFurnitureL(ui);
     515
     516                    TRect boundingRect = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
     517
     518                    CEikButtonGroupContainer *cba = CEikButtonGroupContainer::NewL(CEikButtonGroupContainer::ECba,
     519                        CEikButtonGroupContainer::EHorizontal,ui,R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
     520                    if (isFullscreen && !cbaRequested)
     521                        cba->MakeVisible(false);
     522
     523                    CEikButtonGroupContainer *oldCba = factory->SwapButtonGroup(cba);
     524                    Q_ASSERT(!oldCba);
     525                    S60->setButtonGroupContainer(cba);
     526
     527                    // If the creation of the first widget is delayed, for example by doing it
     528                    // inside the event loop, S60 somehow "forgets" to set the visibility of the
     529                    // toolbar (the three middle softkeys) when you flip the phone over, so we
     530                    // need to do it ourselves to avoid a "hole" in the application, even though
     531                    // Qt itself does not use the toolbar directly..
     532                    CAknAppUi *appui = dynamic_cast<CAknAppUi *>(CEikonEnv::Static()->AppUi());
     533                    if (appui) {
     534                        CAknToolbar *toolbar = appui->PopupToolbar();
     535                        if (toolbar && !toolbar->IsVisible())
     536                            toolbar->SetToolbarVisibility(ETrue);
     537                    }
     538
     539                    CEikMenuBar *menuBar = new(ELeave) CEikMenuBar;
     540                    menuBar->ConstructL(ui, 0, R_AVKON_MENUPANE_EMPTY);
     541                    menuBar->SetMenuType(CEikMenuBar::EMenuOptions);
     542                    S60->appUi()->AddToStackL(menuBar,ECoeStackPriorityMenu,ECoeStackFlagRefusesFocus);
     543
     544                    CEikMenuBar *oldMenu = factory->SwapMenuBar(menuBar);
     545                    Q_ASSERT(!oldMenu);
     546                )
    499547
    500548                if (S60->statusPane()) {
     
    503551                    QSymbianControl *desktopControl = static_cast<QSymbianControl *>(QApplication::desktop()->winId());
    504552                    S60->statusPane()->SetObserver(desktopControl);
    505 
    506                     // Hide the status pane if fullscreen OR
    507                     // Fill client area if maximized OR
    508                     // Put window below status pane unless the window has an explicit position.
    509553                    if (isFullscreen) {
    510                         S60->statusPane()->MakeVisible(false);
    511                     } else if (q->windowState() & Qt::WindowMaximized) {
    512                         TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
    513                         id->SetExtent(r.iTl, r.Size());
    514                     } else if (!q->testAttribute(Qt::WA_Moved)) {
    515                         id->SetPosition(static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl);
     554                        const bool cbaVisible = S60->buttonGroupContainer() && S60->buttonGroupContainer()->IsVisible();
     555                        S60->setStatusPaneAndButtonGroupVisibility(false, cbaVisible);
    516556                    }
    517557                }
     
    520560#endif
    521561
     562        // Fill client area if maximized OR
     563        // Put window below status pane unless the window has an explicit position.
     564        if (!isFullscreen) {
     565            if (q->windowState() & Qt::WindowMaximized) {
     566                TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
     567                id->SetExtent(r.iTl, r.Size());
     568            } else if (!q->testAttribute(Qt::WA_Moved) && q->windowType() != Qt::Dialog) {
     569                id->SetPosition(static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl);
     570            }
     571        }
     572
    522573        id->MakeVisible(true);
    523574
    524         if(q->isWindow())
     575        if(q->isWindow()&&!q->testAttribute(Qt::WA_ShowWithoutActivating))
    525576            id->setFocusSafely(true);
    526577    }
     
    555606
    556607    if (id) {
    557         //Incorrect optimisation - for popup windows, Qt's focus is moved before
     608        //Incorrect optimization - for popup windows, Qt's focus is moved before
    558609        //hide_sys is called, resulting in the popup window keeping its elevated
    559610        //position in the CONE control stack.
     
    683734    if ((q->windowType() == Qt::Desktop))
    684735        old_winid = 0;
     736
     737    // old_winid may not have received a 'not visible' visibility
     738    // changed event before being destroyed; make sure that it is
     739    // removed from the backing store's list of visible windows.
     740    if (old_winid)
     741        S60->controlVisibilityChanged(old_winid, false);
     742
    685743    setWinId(0);
    686744
     
    738796        return;
    739797
    740     if ((data.window_flags & Qt::FramelessWindowHint) == 0)
    741         return;
     798    createTLExtra();
    742799
    743800    RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow());
     
    745802#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
    746803    window->SetSurfaceTransparency(!isOpaque);
     804    extra->topextra->nativeWindowTransparencyEnabled = !isOpaque;
    747805#else
    748806    if (!isOpaque) {
    749807        const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
    750         if (window->SetTransparencyAlphaChannel() == KErrNone)
     808        if (window->SetTransparencyAlphaChannel() == KErrNone) {
    751809            window->SetBackgroundColor(TRgb(255, 255, 255, 0));
    752     } else
     810            extra->topextra->nativeWindowTransparencyEnabled = 1;
     811
     812            if (extra->topextra->backingStore.data() &&
     813                    QApplicationPrivate::graphics_system_name == QLatin1String("openvg")) {
     814                // Semi-transparent EGL surfaces aren't supported. We need to
     815                // recreate backing store to get translucent surface (raster surface).
     816                extra->topextra->backingStore.create(q);
     817                extra->topextra->backingStore.registerWidget(q);
     818            }
     819        }
     820    } else if (extra->topextra->nativeWindowTransparencyEnabled) {
    753821        window->SetTransparentRegion(TRegionFix<1>());
     822        extra->topextra->nativeWindowTransparencyEnabled = 0;
     823    }
    754824#endif
    755825}
     
    909979void QWidgetPrivate::createTLSysExtra()
    910980{
    911     extra->topextra->backingStore = 0;
    912981    extra->topextra->inExpose = 0;
     982    extra->topextra->nativeWindowTransparencyEnabled = 0;
    913983}
    914984
    915985void QWidgetPrivate::deleteTLSysExtra()
    916986{
    917     delete extra->topextra->backingStore;
    918     extra->topextra->backingStore = 0;
     987    extra->topextra->backingStore.destroy();
    919988}
    920989
     
    9521021    if (q->testAttribute(Qt::WA_WState_Created) && q->windowType() != Qt::Desktop) {
    9531022        RWindow *rwindow = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow());
    954         rwindow->EnableAdvancedPointers();
     1023        QSymbianControl *window = static_cast<QSymbianControl *>(q->effectiveWinId());
     1024        //Enabling advanced pointer events for controls that already have active windows causes a panic.
     1025        if (!window->isControlActive())
     1026            rwindow->EnableAdvancedPointers();
    9551027    }
    9561028#endif
     
    10871159
    10881160    const TBool isFullscreen = newstate & Qt::WindowFullScreen;
     1161#ifdef Q_WS_S60
    10891162    const TBool cbaRequested = windowFlags() & Qt::WindowSoftkeysVisibleHint;
    10901163    const TBool cbaVisible = CEikButtonGroupContainer::Current() ? true : false;
     
    10931166    if (oldstate == newstate && !softkeyVisibilityChange)
    10941167        return;
     1168#endif // Q_WS_S60
    10951169
    10961170    if (isWindow()) {
     
    11111185
    11121186#ifdef Q_WS_S60
    1113         // Hide window decoration when switching to fullsccreen / minimized otherwise show decoration.
    1114         // The window decoration visibility has to be changed before doing actual window state
    1115         // change since in that order the availableGeometry will return directly the right size and
    1116         // we will avoid unnecessarty redraws
    1117         CEikStatusPane *statusPane = S60->statusPane();
    1118         CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
    1119         TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
    1120         if (statusPane)
    1121             statusPane->MakeVisible(visible);
    1122         if (buttonGroup) {
    1123             // Visibility
    1124             buttonGroup->MakeVisible(visible || (isFullscreen && cbaRequested));
     1187        bool decorationsVisible(false);
     1188        if (!parentWidget()) { // Only top level native windows have control over cba/status pane
     1189            // Hide window decoration when switching to fullscreen / minimized otherwise show decoration.
     1190            // The window decoration visibility has to be changed before doing actual window state
     1191            // change since in that order the availableGeometry will return directly the right size and
     1192            // we will avoid unnecessary redraws
     1193            decorationsVisible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
     1194            const bool statusPaneVisibility = decorationsVisible;
     1195            const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaRequested));
     1196            S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility);
    11251197        }
    11261198#endif // Q_WS_S60
     
    11351207        const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint;
    11361208        if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint) {
     1209            setAttribute(Qt::WA_OutsideWSRange, false);
    11371210            window->SetExtentToWholeScreen();
    11381211        } else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint)) {
     1212            setAttribute(Qt::WA_OutsideWSRange, false);
    11391213            TRect maxExtent = qt_QRect2TRect(qApp->desktop()->availableGeometry(this));
    11401214            window->SetExtent(maxExtent.iTl, maxExtent.Size());
     
    11451219            // normal mode after showing the status pane, the geometry would overlap so we should
    11461220            // move it if it never had an explicit position.
    1147             if (!wasMoved && statusPane && visible) {
     1221            if (!wasMoved && S60->statusPane() && decorationsVisible) {
    11481222                TPoint tl = static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl;
    11491223                normalGeometry.setTopLeft(QPoint(tl.iX, tl.iY));
     
    11791253{
    11801254    Q_D(QWidget);
     1255    d->aboutToDestroy();
    11811256    if (!isWindow() && parentWidget())
    11821257        parentWidget()->d_func()->invalidateBuffer(geometry());
     
    12261301        // so we flush the command buffer to ensure that the freeing of
    12271302        // those resources and deleting the window can happen "atomically"
    1228         S60->wsSession().Flush();
     1303        if (qApp)
     1304            S60->wsSession().Flush();
    12291305    }
    12301306}
Note: See TracChangeset for help on using the changeset viewer.