util/src/gui/kernel/qwidget_s60.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qwidget_p.h"
       
    43 #include "qdesktopwidget.h"
       
    44 #include "qapplication.h"
       
    45 #include "qapplication_p.h"
       
    46 #include "private/qbackingstore_p.h"
       
    47 #include "qevent.h"
       
    48 #include "qt_s60_p.h"
       
    49 
       
    50 #include "qbitmap.h"
       
    51 #include "private/qwindowsurface_s60_p.h"
       
    52 
       
    53 #include <qinputcontext.h>
       
    54 
       
    55 #ifdef Q_WS_S60
       
    56 #include <aknappui.h>
       
    57 #endif
       
    58 
       
    59 // This is necessary in order to be able to perform delayed invokation on slots
       
    60 // which take arguments of type WId.  One example is
       
    61 // QWidgetPrivate::_q_delayedDestroy, which is used to delay destruction of
       
    62 // CCoeControl objects until after the CONE event handler has finished running.
       
    63 Q_DECLARE_METATYPE(WId)
       
    64 
       
    65 QT_BEGIN_NAMESPACE
       
    66 
       
    67 extern bool qt_nograb();
       
    68 
       
    69 QWidget *QWidgetPrivate::mouseGrabber = 0;
       
    70 QWidget *QWidgetPrivate::keyboardGrabber = 0;
       
    71 
       
    72 static bool isEqual(const QList<QAction*>& a, const QList<QAction*>& b)
       
    73 {
       
    74     if ( a.count() != b.count())
       
    75         return false;
       
    76     int index=0;
       
    77     while (index<a.count()) {
       
    78         if (a.at(index)->softKeyRole() != b.at(index)->softKeyRole())
       
    79             return false;
       
    80         if (a.at(index)->text().compare(b.at(index)->text())!=0)
       
    81             return false;
       
    82         index++;
       
    83     }
       
    84     return true;
       
    85 }
       
    86 
       
    87 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &)
       
    88 {
       
    89     // Note: based on x11 implementation
       
    90 
       
    91     static const int XCOORD_MAX = 16383;
       
    92     static const int WRECT_MAX = 16383;
       
    93 
       
    94     Q_Q(QWidget);
       
    95 
       
    96     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
    97 
       
    98     /*
       
    99       There are up to four different coordinate systems here:
       
   100       Qt coordinate system for this widget.
       
   101       Symbian coordinate system for this widget (relative to wrect).
       
   102       Qt coordinate system for parent
       
   103       Symbian coordinate system for parent (relative to parent's wrect).
       
   104      */
       
   105 
       
   106     QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
       
   107     QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
       
   108     QRect wrect;
       
   109     //xrect is the Symbian geometry of my widget. (starts out in parent's Qt coord sys, and ends up in parent's Symbian coord sys)
       
   110     QRect xrect = data.crect;
       
   111 
       
   112     const QWidget *const parent = q->parentWidget();
       
   113     QRect parentWRect = parent->data->wrect;
       
   114 
       
   115     if (parentWRect.isValid()) {
       
   116         // parent is clipped, and we have to clip to the same limit as parent
       
   117         if (!parentWRect.contains(xrect)) {
       
   118             xrect &= parentWRect;
       
   119             wrect = xrect;
       
   120             //translate from parent's to my Qt coord sys
       
   121             wrect.translate(-data.crect.topLeft());
       
   122         }
       
   123         //translate from parent's Qt coords to parent's X coords
       
   124         xrect.translate(-parentWRect.topLeft());
       
   125 
       
   126     } else {
       
   127         // parent is not clipped, we may or may not have to clip
       
   128 
       
   129         if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
       
   130             // This is where the main optimization is: we are already
       
   131             // clipped, and if our clip is still valid, we can just
       
   132             // move our window, and do not need to move or clip
       
   133             // children
       
   134 
       
   135             QRect vrect = xrect & parent->rect();
       
   136             vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords
       
   137             if (data.wrect.contains(vrect)) {
       
   138                 xrect = data.wrect;
       
   139                 xrect.translate(data.crect.topLeft());
       
   140                 if (data.winid)
       
   141                     data.winid->SetExtent(TPoint(xrect.x(), xrect.y()), TSize(xrect.width(), xrect.height()));
       
   142                 return;
       
   143             }
       
   144         }
       
   145 
       
   146         if (!validRange.contains(xrect)) {
       
   147             // we are too big, and must clip
       
   148             xrect &=wrectRange;
       
   149             wrect = xrect;
       
   150             wrect.translate(-data.crect.topLeft());
       
   151             //parent's X coord system is equal to parent's Qt coord
       
   152             //sys, so we don't need to map xrect.
       
   153         }
       
   154     }
       
   155 
       
   156     // unmap if we are outside the valid window system coord system
       
   157     bool outsideRange = !xrect.isValid();
       
   158     bool mapWindow = false;
       
   159     if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
       
   160         q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
       
   161         if (outsideRange) {
       
   162             if (data.winid)
       
   163                 data.winid->DrawableWindow()->SetVisible(EFalse);
       
   164             q->setAttribute(Qt::WA_Mapped, false);
       
   165         } else if (!q->isHidden()) {
       
   166             mapWindow = true;
       
   167         }
       
   168     }
       
   169 
       
   170     if (outsideRange)
       
   171         return;
       
   172 
       
   173     bool jump = (data.wrect != wrect);
       
   174     data.wrect = wrect;
       
   175 
       
   176     // and now recursively for all children...
       
   177     for (int i = 0; i < children.size(); ++i) {
       
   178         QObject *object = children.at(i);
       
   179         if (object->isWidgetType()) {
       
   180             QWidget *w = static_cast<QWidget *>(object);
       
   181             if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
       
   182                 w->d_func()->setWSGeometry(jump);
       
   183         }
       
   184     }
       
   185 
       
   186     if (data.winid) {
       
   187         // move ourselves to the new position and map (if necessary) after
       
   188         // the movement. Rationale: moving unmapped windows is much faster
       
   189         // than moving mapped windows
       
   190         if (!parent->internalWinId())
       
   191             xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0)));
       
   192 
       
   193         data.winid->SetExtent(TPoint(xrect.x(), xrect.y()), TSize(xrect.width(), xrect.height()));
       
   194     }
       
   195 
       
   196     if (mapWindow and !dontShow) {
       
   197         q->setAttribute(Qt::WA_Mapped);
       
   198         if (q->internalWinId())
       
   199             q->internalWinId()->DrawableWindow()->SetVisible(ETrue);
       
   200     }
       
   201 
       
   202     if  (jump && data.winid) {
       
   203         RWindow *const window = static_cast<RWindow *>(data.winid->DrawableWindow());
       
   204         window->Invalidate(TRect(0, 0, wrect.width(), wrect.height()));
       
   205     }
       
   206 }
       
   207 
       
   208 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
       
   209 {
       
   210     Q_Q(QWidget);
       
   211 
       
   212     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   213 
       
   214     if ((q->windowType() == Qt::Desktop))
       
   215         return;
       
   216 
       
   217     QPoint oldPos(q->pos());
       
   218     QSize oldSize(q->size());
       
   219     QRect oldGeom(data.crect);
       
   220 
       
   221     // Lose maximized status if deliberate resize
       
   222     if (w != oldSize.width() || h != oldSize.height())
       
   223         data.window_state &= ~Qt::WindowMaximized;
       
   224 
       
   225     if (extra) {                                // any size restrictions?
       
   226         w = qMin(w,extra->maxw);
       
   227         h = qMin(h,extra->maxh);
       
   228         w = qMax(w,extra->minw);
       
   229         h = qMax(h,extra->minh);
       
   230     }
       
   231 
       
   232     if (q->isWindow())
       
   233         topData()->normalGeometry = QRect(0, 0, -1, -1);
       
   234     else {
       
   235         uint s = data.window_state;
       
   236         s &= ~(Qt::WindowMaximized | Qt::WindowFullScreen);
       
   237         data.window_state = s;
       
   238     }
       
   239 
       
   240     bool isResize = w != oldSize.width() || h != oldSize.height();
       
   241     if (!isMove && !isResize)
       
   242         return;
       
   243 
       
   244     if (q->isWindow()) {
       
   245         if (w == 0 || h == 0) {
       
   246             q->setAttribute(Qt::WA_OutsideWSRange, true);
       
   247             if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
       
   248                 hide_sys();
       
   249             data.crect = QRect(x, y, w, h);
       
   250             data.window_state &= ~Qt::WindowFullScreen;
       
   251         } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
       
   252             q->setAttribute(Qt::WA_OutsideWSRange, false);
       
   253 
       
   254             // put the window in its place and show it
       
   255             q->internalWinId()->SetRect(TRect(TPoint(x, y), TSize(w, h)));
       
   256             data.crect.setRect(x, y, w, h);
       
   257             show_sys();
       
   258         } else {
       
   259             QRect r = QRect(x, y, w, h);
       
   260             data.crect = r;
       
   261             q->internalWinId()->SetRect(TRect(TPoint(x, y), TSize(w, h)));
       
   262             topData()->normalGeometry = data.crect;
       
   263         }
       
   264     } else {
       
   265         data.crect.setRect(x, y, w, h);
       
   266 
       
   267         QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
       
   268         const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false;
       
   269 
       
   270         if (q->isVisible() && (!inTopLevelResize || q->internalWinId())) {
       
   271             // Top-level resize optimization does not work for native child widgets;
       
   272             // disable it for this particular widget.
       
   273             if (inTopLevelResize)
       
   274                 tlwExtra->inTopLevelResize = false;
       
   275             if (!isResize && maybeBackingStore())
       
   276                 moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y());
       
   277             else
       
   278                 invalidateBuffer_resizeHelper(oldPos, oldSize);
       
   279 
       
   280             if (inTopLevelResize)
       
   281                 tlwExtra->inTopLevelResize = true;
       
   282         }
       
   283         if (q->testAttribute(Qt::WA_WState_Created))
       
   284             setWSGeometry();
       
   285     }
       
   286 
       
   287     if (q->isVisible()) {
       
   288         if (isMove && q->pos() != oldPos) {
       
   289             QMoveEvent e(q->pos(), oldPos);
       
   290             QApplication::sendEvent(q, &e);
       
   291         }
       
   292         if (isResize) {
       
   293             bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
       
   294             const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra
       
   295                                            && !extra->topextra->inTopLevelResize;
       
   296             if (setTopLevelResize)
       
   297                 extra->topextra->inTopLevelResize = true;
       
   298             QResizeEvent e(q->size(), oldSize);
       
   299             QApplication::sendEvent(q, &e);
       
   300             if (!q->testAttribute(Qt::WA_StaticContents) && q->internalWinId())
       
   301                 q->internalWinId()->DrawDeferred();
       
   302             if (setTopLevelResize)
       
   303                 extra->topextra->inTopLevelResize = false;
       
   304         }
       
   305     } else {
       
   306         if (isMove && q->pos() != oldPos)
       
   307             q->setAttribute(Qt::WA_PendingMoveEvent, true);
       
   308         if (isResize)
       
   309             q->setAttribute(Qt::WA_PendingResizeEvent, true);
       
   310     }
       
   311 }
       
   312 
       
   313 void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool destroyOldWindow)
       
   314 {
       
   315     Q_Q(QWidget);
       
   316 
       
   317     Qt::WindowType type = q->windowType();
       
   318     Qt::WindowFlags &flags = data.window_flags;
       
   319     QWidget *parentWidget = q->parentWidget();
       
   320 
       
   321     bool topLevel = (flags & Qt::Window);
       
   322     bool popup = (type == Qt::Popup);
       
   323     bool dialog = (type == Qt::Dialog
       
   324                    || type == Qt::Sheet
       
   325                    || (flags & Qt::MSWindowsFixedSizeDialogHint));
       
   326     bool desktop = (type == Qt::Desktop);
       
   327     //bool tool = (type == Qt::Tool || type == Qt::Drawer);
       
   328 
       
   329     if (popup)
       
   330         flags |= Qt::WindowStaysOnTopHint; // a popup stays on top
       
   331 
       
   332     TRect clientRect = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
       
   333     int sw = clientRect.Width();
       
   334     int sh = clientRect.Height();
       
   335 
       
   336     if (desktop) {
       
   337         TSize screenSize = S60->screenDevice()->SizeInPixels();
       
   338         data.crect.setRect(0, 0, screenSize.iWidth, screenSize.iHeight);
       
   339         q->setAttribute(Qt::WA_DontShowOnScreen);
       
   340     } else if (topLevel && !q->testAttribute(Qt::WA_Resized)){
       
   341         int width = sw;
       
   342         int height = sh;
       
   343         if (extra) {
       
   344             width = qMax(qMin(width, extra->maxw), extra->minw);
       
   345             height = qMax(qMin(height, extra->maxh), extra->minh);
       
   346         }
       
   347         data.crect.setSize(QSize(width, height));
       
   348     }
       
   349 
       
   350     CCoeControl *const destroyw = destroyOldWindow ? data.winid : 0;
       
   351 
       
   352     createExtra();
       
   353     if (window) {
       
   354         setWinId(window);
       
   355         TRect tr = window->Rect();
       
   356         data.crect.setRect(tr.iTl.iX, tr.iTl.iY, tr.Width(), tr.Height());
       
   357 
       
   358     } else if (topLevel) {
       
   359         if (!q->testAttribute(Qt::WA_Moved) && !q->testAttribute(Qt::WA_DontShowOnScreen))
       
   360             data.crect.moveTopLeft(QPoint(clientRect.iTl.iX, clientRect.iTl.iY));
       
   361 
       
   362         QScopedPointer<QSymbianControl> control( q_check_ptr(new QSymbianControl(q)) );
       
   363         QT_TRAP_THROWING(control->ConstructL(true, desktop));
       
   364         control->SetMopParent(static_cast<CEikAppUi*>(S60->appUi()));
       
   365 
       
   366         // Symbian windows are always created in an inactive state
       
   367         // 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
       
   369         // ancestors.
       
   370         extra->activated = 0;
       
   371 
       
   372         if (!desktop) {
       
   373             TInt stackingFlags;
       
   374             if ((q->windowType() & Qt::Popup) == Qt::Popup) {
       
   375                 stackingFlags = ECoeStackFlagRefusesAllKeys | ECoeStackFlagRefusesFocus;
       
   376             } else {
       
   377                 stackingFlags = ECoeStackFlagStandard;
       
   378             }
       
   379             control->MakeVisible(false);
       
   380             QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control.data(), ECoeStackPriorityDefault, stackingFlags));
       
   381             // Avoid keyboard focus to a hidden window.
       
   382             control->setFocusSafely(false);
       
   383 
       
   384             RDrawableWindow *const drawableWindow = control->DrawableWindow();
       
   385             // Request mouse move events.
       
   386             drawableWindow->PointerFilter(EPointerFilterEnterExit
       
   387                 | EPointerFilterMove | EPointerFilterDrag, 0);
       
   388             drawableWindow->EnableVisibilityChangeEvents();
       
   389 
       
   390             if (!isOpaque) {
       
   391                 RWindow *const window = static_cast<RWindow *>(drawableWindow);
       
   392 #ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
       
   393                 window->SetSurfaceTransparency(true);
       
   394 #else
       
   395                 const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
       
   396                 if (window->SetTransparencyAlphaChannel() == KErrNone)
       
   397                     window->SetBackgroundColor(TRgb(255, 255, 255, 0));
       
   398 #endif
       
   399             }
       
   400         }
       
   401 
       
   402         q->setAttribute(Qt::WA_WState_Created);
       
   403 
       
   404         int x, y, w, h;
       
   405         data.crect.getRect(&x, &y, &w, &h);
       
   406         control->SetRect(TRect(TPoint(x, y), TSize(w, h)));
       
   407 
       
   408         // We wait until the control is fully constructed before calling setWinId, because
       
   409         // this generates a WinIdChanged event.
       
   410         setWinId(control.take());
       
   411 
       
   412     } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create native child widget
       
   413 
       
   414         QScopedPointer<QSymbianControl> control( q_check_ptr(new QSymbianControl(q)) );
       
   415         QT_TRAP_THROWING(control->ConstructL(!parentWidget));
       
   416 
       
   417         // Symbian windows are always created in an inactive state
       
   418         // We perform this assignment for the case where the window is being re-created
       
   419         // as aa result of a call to setParent_sys, on either this widget or one of its
       
   420         // ancestors.
       
   421         extra->activated = 0;
       
   422 
       
   423         TInt stackingFlags;
       
   424         if ((q->windowType() & Qt::Popup) == Qt::Popup) {
       
   425             stackingFlags = ECoeStackFlagRefusesAllKeys | ECoeStackFlagRefusesFocus;
       
   426         } else {
       
   427             stackingFlags = ECoeStackFlagStandard;
       
   428         }
       
   429         control->MakeVisible(false);
       
   430         QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control.data(), ECoeStackPriorityDefault, stackingFlags));
       
   431         // Avoid keyboard focus to a hidden window.
       
   432         control->setFocusSafely(false);
       
   433 
       
   434         q->setAttribute(Qt::WA_WState_Created);
       
   435         int x, y, w, h;
       
   436         data.crect.getRect(&x, &y, &w, &h);
       
   437         control->SetRect(TRect(TPoint(x, y), TSize(w, h)));
       
   438 
       
   439         RDrawableWindow *const drawableWindow = control->DrawableWindow();
       
   440         // Request mouse move events.
       
   441         drawableWindow->PointerFilter(EPointerFilterEnterExit
       
   442             | EPointerFilterMove | EPointerFilterDrag, 0);
       
   443 
       
   444         if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) {
       
   445             activateSymbianWindow(control.data());
       
   446             control->MakeVisible(true);
       
   447         }
       
   448 
       
   449         // We wait until the control is fully constructed before calling setWinId, because
       
   450         // this generates a WinIdChanged event.
       
   451         setWinId(control.take());
       
   452     }
       
   453 
       
   454     if (destroyw) {
       
   455         destroyw->ControlEnv()->AppUi()->RemoveFromStack(destroyw);
       
   456 
       
   457         // Delay deletion of the control in case this function is called in the
       
   458         // context of a CONE event handler such as
       
   459         // CCoeControl::ProcessPointerEventL
       
   460         QMetaObject::invokeMethod(q, "_q_delayedDestroy",
       
   461             Qt::QueuedConnection, Q_ARG(WId, destroyw));
       
   462     }
       
   463 
       
   464     if (q->testAttribute(Qt::WA_AcceptTouchEvents))
       
   465         registerTouchWindow();
       
   466 }
       
   467 
       
   468 
       
   469 void QWidgetPrivate::show_sys()
       
   470 {
       
   471     Q_Q(QWidget);
       
   472 
       
   473     if (q->testAttribute(Qt::WA_OutsideWSRange))
       
   474         return;
       
   475 
       
   476     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   477 
       
   478     q->setAttribute(Qt::WA_Mapped);
       
   479 
       
   480     if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
       
   481         invalidateBuffer(q->rect());
       
   482         return;
       
   483     }
       
   484 
       
   485     if (q->internalWinId()) {
       
   486         if (!extra->activated)
       
   487              activateSymbianWindow();
       
   488 
       
   489          QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId());
       
   490 
       
   491         id->MakeVisible(true);
       
   492 
       
   493         if(q->isWindow())
       
   494             id->setFocusSafely(true);
       
   495     }
       
   496 
       
   497     invalidateBuffer(q->rect());
       
   498 }
       
   499 
       
   500 void QWidgetPrivate::activateSymbianWindow(WId wid)
       
   501 {
       
   502     Q_Q(QWidget);
       
   503 
       
   504     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   505     Q_ASSERT(q->testAttribute(Qt::WA_Mapped));
       
   506     Q_ASSERT(!extra->activated);
       
   507 
       
   508     if(!wid)
       
   509         wid = q->internalWinId();
       
   510 
       
   511     Q_ASSERT(wid);
       
   512 
       
   513     QT_TRAP_THROWING(wid->ActivateL());
       
   514     extra->activated = 1;
       
   515 }
       
   516 
       
   517 void QWidgetPrivate::hide_sys()
       
   518 {
       
   519     Q_Q(QWidget);
       
   520 
       
   521     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   522     deactivateWidgetCleanup();
       
   523     QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId());
       
   524 
       
   525     if (id) {
       
   526         //Incorrect optimisation - for popup windows, Qt's focus is moved before
       
   527         //hide_sys is called, resulting in the popup window keeping its elevated
       
   528         //position in the CONE control stack.
       
   529         //This can result in keyboard focus being in an invisible widget in some
       
   530         //conditions - e.g. QTBUG-4733
       
   531         //if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
       
   532             id->setFocusSafely(false);
       
   533         id->MakeVisible(false);
       
   534         if (QWidgetBackingStore *bs = maybeBackingStore())
       
   535             bs->releaseBuffer();
       
   536     } else {
       
   537         invalidateBuffer(q->rect());
       
   538     }
       
   539 
       
   540     q->setAttribute(Qt::WA_Mapped, false);
       
   541 }
       
   542 
       
   543 void QWidgetPrivate::setFocus_sys()
       
   544 {
       
   545     Q_Q(QWidget);
       
   546     if (q->testAttribute(Qt::WA_WState_Created) && q->window()->windowType() != Qt::Popup)
       
   547         if (!q->effectiveWinId()->IsFocused()) // Avoid unnecessry calls to FocusChanged()
       
   548             static_cast<QSymbianControl *>(q->effectiveWinId())->setFocusSafely(true);
       
   549 }
       
   550 
       
   551 void QWidgetPrivate::raise_sys()
       
   552 {
       
   553     Q_Q(QWidget);
       
   554 
       
   555     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   556     if (q->internalWinId()) {
       
   557         q->internalWinId()->DrawableWindow()->SetOrdinalPosition(0);
       
   558 
       
   559         // If toplevel widget, raise app to foreground
       
   560         if (q->isWindow())
       
   561             S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup().Identifier(), 0);
       
   562     }
       
   563 }
       
   564 
       
   565 void QWidgetPrivate::lower_sys()
       
   566 {
       
   567     Q_Q(QWidget);
       
   568 
       
   569     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   570     if (q->internalWinId()) {
       
   571         // If toplevel widget, lower app to background
       
   572         if (q->isWindow())
       
   573             S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup().Identifier(), -1);
       
   574         else
       
   575             q->internalWinId()->DrawableWindow()->SetOrdinalPosition(-1);
       
   576     }
       
   577 
       
   578     if (!q->isWindow())
       
   579         invalidateBuffer(q->rect());
       
   580 }
       
   581 
       
   582 void QWidgetPrivate::setModal_sys()
       
   583 {
       
   584 
       
   585 }
       
   586 
       
   587 void QWidgetPrivate::stackUnder_sys(QWidget* w)
       
   588 {
       
   589     Q_Q(QWidget);
       
   590     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   591 
       
   592     if (q->internalWinId() && w->internalWinId()) {
       
   593         RDrawableWindow *const thisWindow = q->internalWinId()->DrawableWindow();
       
   594         RDrawableWindow *const otherWindow = w->internalWinId()->DrawableWindow();
       
   595         thisWindow->SetOrdinalPosition(otherWindow->OrdinalPosition() + 1);
       
   596     }
       
   597 
       
   598     if (!q->isWindow() || !w->internalWinId())
       
   599         invalidateBuffer(q->rect());
       
   600 }
       
   601 
       
   602 void QWidgetPrivate::reparentChildren()
       
   603 {
       
   604     Q_Q(QWidget);
       
   605 
       
   606     QObjectList chlist = q->children();
       
   607     for (int i = 0; i < chlist.size(); ++i) { // reparent children
       
   608         QObject *obj = chlist.at(i);
       
   609         if (obj->isWidgetType()) {
       
   610             QWidget *w = (QWidget *)obj;
       
   611             if (!w->testAttribute(Qt::WA_WState_Created))
       
   612                 continue;
       
   613             if (!w->isWindow()) {
       
   614                 w->d_func()->invalidateBuffer(w->rect());
       
   615                 WId parent = q->effectiveWinId();
       
   616                 WId child = w->effectiveWinId();
       
   617                 if (parent != child) {
       
   618                     // Child widget is native.  Because Symbian windows cannot be
       
   619                     // re-parented, we must re-create the window.
       
   620                     const WId window = 0;
       
   621                     const bool initializeWindow = false;
       
   622                     const bool destroyOldWindow = true;
       
   623                     w->d_func()->create_sys(window, initializeWindow, destroyOldWindow);
       
   624                 }
       
   625                 // ### TODO: We probably also need to update the component array here
       
   626                 w->d_func()->reparentChildren();
       
   627             } else {
       
   628                 bool showIt = w->isVisible();
       
   629                 QPoint old_pos = w->pos();
       
   630                 w->setParent(q, w->windowFlags());
       
   631                 w->move(old_pos);
       
   632                 if (showIt)
       
   633                     w->show();
       
   634             }
       
   635         }
       
   636     }
       
   637 }
       
   638 
       
   639 void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
       
   640 {
       
   641     Q_Q(QWidget);
       
   642 
       
   643     bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
       
   644 
       
   645     if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
       
   646         q->parentWidget()->d_func()->invalidateBuffer(q->geometry());
       
   647 
       
   648     if (q->testAttribute(Qt::WA_DropSiteRegistered))
       
   649         q->setAttribute(Qt::WA_DropSiteRegistered, false);
       
   650 
       
   651     QSymbianControl *old_winid = static_cast<QSymbianControl *>(wasCreated ? data.winid : 0);
       
   652     if ((q->windowType() == Qt::Desktop))
       
   653         old_winid = 0;
       
   654     setWinId(0);
       
   655 
       
   656     // hide and reparent our own window away. Otherwise we might get
       
   657     // destroyed when emitting the child remove event below. See QWorkspace.
       
   658     if (wasCreated && old_winid) {
       
   659         old_winid->MakeVisible(false);
       
   660         if (old_winid->IsFocused()) // Avoid unnecessary calls to FocusChanged()
       
   661             old_winid->setFocusSafely(false);
       
   662         old_winid->SetParent(0);
       
   663     }
       
   664 
       
   665     QObjectPrivate::setParent_helper(parent);
       
   666     bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
       
   667 
       
   668     data.window_flags = f;
       
   669     data.fstrut_dirty = true;
       
   670     q->setAttribute(Qt::WA_WState_Created, false);
       
   671     q->setAttribute(Qt::WA_WState_Visible, false);
       
   672     q->setAttribute(Qt::WA_WState_Hidden, false);
       
   673     adjustFlags(data.window_flags, q);
       
   674     // keep compatibility with previous versions, we need to preserve the created state
       
   675     // (but we recreate the winId for the widget being reparented, again for compatibility)
       
   676     if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created)))
       
   677         createWinId();
       
   678     if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
       
   679         q->setAttribute(Qt::WA_WState_Hidden);
       
   680     q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
       
   681 
       
   682     if (wasCreated)
       
   683         reparentChildren();
       
   684 
       
   685     if (old_winid) {
       
   686         CBase::Delete(old_winid);
       
   687     }
       
   688 
       
   689     if (q->testAttribute(Qt::WA_AcceptDrops)
       
   690         || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)))
       
   691         q->setAttribute(Qt::WA_DropSiteRegistered, true);
       
   692 
       
   693     invalidateBuffer(q->rect());
       
   694 }
       
   695 
       
   696 void QWidgetPrivate::setConstraints_sys()
       
   697 {
       
   698 
       
   699 }
       
   700 
       
   701 
       
   702 void QWidgetPrivate::s60UpdateIsOpaque()
       
   703 {
       
   704     Q_Q(QWidget);
       
   705 
       
   706     if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground))
       
   707         return;
       
   708 
       
   709     if ((data.window_flags & Qt::FramelessWindowHint) == 0)
       
   710         return;
       
   711 
       
   712     RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow());
       
   713 
       
   714 #ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
       
   715     window->SetSurfaceTransparency(!isOpaque);
       
   716 #else
       
   717     if (!isOpaque) {
       
   718         const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
       
   719         if (window->SetTransparencyAlphaChannel() == KErrNone)
       
   720             window->SetBackgroundColor(TRgb(255, 255, 255, 0));
       
   721     } else
       
   722         window->SetTransparentRegion(TRegionFix<1>());
       
   723 #endif
       
   724 }
       
   725 
       
   726 void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
       
   727 {
       
   728 #ifdef Q_WS_S60
       
   729     Q_Q(QWidget);
       
   730 
       
   731     if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow() )
       
   732         return;
       
   733 
       
   734     QTLWExtra* topData = this->topData();
       
   735     if (topData->iconPixmap && !forceReset)
       
   736         // already been set
       
   737         return;
       
   738 
       
   739     TRect cPaneRect;
       
   740     TBool found = AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EContextPane, cPaneRect );
       
   741     CAknContextPane* contextPane = S60->contextPane();
       
   742     if (found && contextPane) { // We have context pane with valid metrics
       
   743         QIcon icon = q->windowIcon();
       
   744         if (!icon.isNull()) {
       
   745             // Valid icon -> set it as an context pane picture
       
   746             QSize size = icon.actualSize(QSize(cPaneRect.Size().iWidth, cPaneRect.Size().iHeight));
       
   747             QPixmap pm = icon.pixmap(size);
       
   748             QBitmap mask = pm.mask();
       
   749             if (mask.isNull()) {
       
   750                 mask = QBitmap(pm.size());
       
   751                 mask.fill(Qt::color1);
       
   752             }
       
   753 
       
   754             CFbsBitmap* nBitmap = pm.toSymbianCFbsBitmap();
       
   755             CFbsBitmap* nMask = mask.toSymbianCFbsBitmap();
       
   756             contextPane->SetPicture(nBitmap,nMask);
       
   757         } else {
       
   758             // Icon set to null -> set context pane picture to default
       
   759             QT_TRAP_THROWING(contextPane->SetPictureToDefaultL());
       
   760         }
       
   761     } else {
       
   762         // Context pane does not exist, try setting small icon to title pane
       
   763         TRect titlePaneRect;
       
   764         TBool found = AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::ETitlePane, titlePaneRect );
       
   765         CAknTitlePane* titlePane = S60->titlePane();
       
   766         if (found && titlePane) { // We have title pane with valid metrics
       
   767             // The API to get title_pane graphics size is not public -> assume square space based
       
   768             // on titlebar font height. CAknBitmap would be optimum, wihtout setting the size, since
       
   769             // then title pane would automatically scale the bitmap. Unfortunately it is not public API
       
   770             // Also this function is leaving, although it is not named as such.
       
   771             const CFont * font;
       
   772             QT_TRAP_THROWING(font = AknLayoutUtils::FontFromId(EAknLogicalFontTitleFont));
       
   773             TSize iconSize(font->HeightInPixels(), font->HeightInPixels());
       
   774 
       
   775             QIcon icon = q->windowIcon();
       
   776             if (!icon.isNull()) {
       
   777                 // Valid icon -> set it as an title pane small picture
       
   778                 QSize size = icon.actualSize(QSize(iconSize.iWidth, iconSize.iHeight));
       
   779                 QPixmap pm = icon.pixmap(size);
       
   780                 QBitmap mask = pm.mask();
       
   781                 if (mask.isNull()) {
       
   782                     mask = QBitmap(pm.size());
       
   783                     mask.fill(Qt::color1);
       
   784                 }
       
   785 
       
   786                 CFbsBitmap* nBitmap = pm.toSymbianCFbsBitmap();
       
   787                 CFbsBitmap* nMask = mask.toSymbianCFbsBitmap();
       
   788                 titlePane->SetSmallPicture( nBitmap, nMask, ETrue );
       
   789             } else {
       
   790                 // Icon set to null -> set context pane picture to default
       
   791                 titlePane->SetSmallPicture( NULL, NULL, EFalse );
       
   792             }
       
   793         }
       
   794     }
       
   795 
       
   796 #else
       
   797         Q_UNUSED(forceReset)
       
   798 #endif
       
   799 }
       
   800 
       
   801 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
       
   802 {
       
   803 #ifdef Q_WS_S60
       
   804     Q_Q(QWidget);
       
   805     if (q->isWindow()) {
       
   806         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   807         CAknTitlePane* titlePane = S60->titlePane();
       
   808         if (titlePane) {
       
   809             if (caption.isEmpty()) {
       
   810                 QT_TRAP_THROWING(titlePane->SetTextToDefaultL());
       
   811             } else {
       
   812                 QT_TRAP_THROWING(titlePane->SetTextL(qt_QString2TPtrC(caption)));
       
   813             }
       
   814         }
       
   815     }
       
   816 #else
       
   817     Q_UNUSED(caption)
       
   818 #endif
       
   819 }
       
   820 
       
   821 void QWidgetPrivate::setWindowIconText_sys(const QString & /*iconText */)
       
   822 {
       
   823 
       
   824 }
       
   825 
       
   826 void QWidgetPrivate::scroll_sys(int dx, int dy)
       
   827 {
       
   828     Q_Q(QWidget);
       
   829 
       
   830     scrollChildren(dx, dy);
       
   831     if (!paintOnScreen() || !q->internalWinId() || !q->internalWinId()->OwnsWindow()) {
       
   832         scrollRect(q->rect(), dx, dy);
       
   833     } else {
       
   834         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   835         RDrawableWindow *const window = q->internalWinId()->DrawableWindow();
       
   836         window->Scroll(TPoint(dx, dy));
       
   837     }
       
   838 }
       
   839 
       
   840 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
       
   841 {
       
   842     Q_Q(QWidget);
       
   843 
       
   844     if (!paintOnScreen() || !q->internalWinId() || !q->internalWinId()->OwnsWindow()) {
       
   845         scrollRect(r, dx, dy);
       
   846     } else {
       
   847         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   848         RDrawableWindow *const window = q->internalWinId()->DrawableWindow();
       
   849         window->Scroll(TPoint(dx, dy), qt_QRect2TRect(r));
       
   850     }
       
   851 }
       
   852 
       
   853 /*!
       
   854     For this function to work in the emulator, you must add:
       
   855        TRANSPARENCY
       
   856     To a line in the wsini.ini file.
       
   857 */
       
   858 void QWidgetPrivate::setWindowOpacity_sys(qreal)
       
   859 {
       
   860     // ### TODO: Implement uniform window transparency
       
   861 }
       
   862 
       
   863 void QWidgetPrivate::updateFrameStrut()
       
   864 {
       
   865 
       
   866 }
       
   867 
       
   868 void QWidgetPrivate::updateSystemBackground()
       
   869 {
       
   870 
       
   871 }
       
   872 
       
   873 void QWidgetPrivate::registerDropSite(bool /* on */)
       
   874 {
       
   875 
       
   876 }
       
   877 
       
   878 void QWidgetPrivate::createTLSysExtra()
       
   879 {
       
   880     extra->topextra->backingStore = 0;
       
   881     extra->topextra->inExpose = 0;
       
   882 }
       
   883 
       
   884 void QWidgetPrivate::deleteTLSysExtra()
       
   885 {
       
   886     delete extra->topextra->backingStore;
       
   887     extra->topextra->backingStore = 0;
       
   888 }
       
   889 
       
   890 void QWidgetPrivate::createSysExtra()
       
   891 {
       
   892     extra->activated = 0;
       
   893     extra->nativePaintMode = QWExtra::Default;
       
   894     extra->receiveNativePaintEvents = 0;
       
   895 }
       
   896 
       
   897 void QWidgetPrivate::deleteSysExtra()
       
   898 {
       
   899     // this should only be non-zero if destroy() has not run due to constructor fail
       
   900     if (data.winid) {
       
   901         data.winid->ControlEnv()->AppUi()->RemoveFromStack(data.winid);
       
   902         delete data.winid;
       
   903         data.winid = 0;
       
   904     }
       
   905 }
       
   906 
       
   907 QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
       
   908 {
       
   909     return new QS60WindowSurface(q_func());
       
   910 }
       
   911 
       
   912 void QWidgetPrivate::setMask_sys(const QRegion& /* region */)
       
   913 {
       
   914 
       
   915 }
       
   916 
       
   917 void QWidgetPrivate::registerTouchWindow()
       
   918 {
       
   919 #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
       
   920     Q_Q(QWidget);
       
   921     if (q->testAttribute(Qt::WA_WState_Created) && q->windowType() != Qt::Desktop) {
       
   922         RWindow *rwindow = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow());
       
   923         rwindow->EnableAdvancedPointers();
       
   924     }
       
   925 #endif
       
   926 }
       
   927 
       
   928 int QWidget::metric(PaintDeviceMetric m) const
       
   929 {
       
   930     Q_D(const QWidget);
       
   931     int val;
       
   932     if (m == PdmWidth) {
       
   933         val = data->crect.width();
       
   934     } else if (m == PdmHeight) {
       
   935         val = data->crect.height();
       
   936     } else {
       
   937         CWsScreenDevice *scr = S60->screenDevice();
       
   938         switch(m) {
       
   939         case PdmDpiX:
       
   940         case PdmPhysicalDpiX:
       
   941             if (d->extra && d->extra->customDpiX) {
       
   942                 val = d->extra->customDpiX;
       
   943             } else {
       
   944                 const QWidgetPrivate *p = d;
       
   945                 while (p->parent) {
       
   946                     p = static_cast<const QWidget *>(p->parent)->d_func();
       
   947                     if (p->extra && p->extra->customDpiX) {
       
   948                         val = p->extra->customDpiX;
       
   949                         break;
       
   950                     }
       
   951                 }
       
   952                 if (p == d || !(p->extra && p->extra->customDpiX))
       
   953                     val = S60->defaultDpiX;
       
   954             }
       
   955             break;
       
   956         case PdmDpiY:
       
   957         case PdmPhysicalDpiY:
       
   958             if (d->extra && d->extra->customDpiY) {
       
   959                 val = d->extra->customDpiY;
       
   960             } else {
       
   961                 const QWidgetPrivate *p = d;
       
   962                 while (p->parent) {
       
   963                     p = static_cast<const QWidget *>(p->parent)->d_func();
       
   964                     if (p->extra && p->extra->customDpiY) {
       
   965                         val = p->extra->customDpiY;
       
   966                         break;
       
   967                     }
       
   968                 }
       
   969                 if (p == d || !(p->extra && p->extra->customDpiY))
       
   970                     val = S60->defaultDpiY;
       
   971             }
       
   972             break;
       
   973         case PdmWidthMM:
       
   974         {
       
   975             TInt twips = scr->HorizontalPixelsToTwips(data->crect.width());
       
   976             val = (int)(twips * (25.4/KTwipsPerInch));
       
   977             break;
       
   978         }
       
   979         case PdmHeightMM:
       
   980         {
       
   981             TInt twips = scr->VerticalPixelsToTwips(data->crect.height());
       
   982             val = (int)(twips * (25.4/KTwipsPerInch));
       
   983             break;
       
   984         }
       
   985         case PdmNumColors:
       
   986             val = TDisplayModeUtils::NumDisplayModeColors(scr->DisplayMode());
       
   987             break;
       
   988         case PdmDepth:
       
   989             val = TDisplayModeUtils::NumDisplayModeBitsPerPixel(scr->DisplayMode());
       
   990             break;
       
   991         default:
       
   992             val = 0;
       
   993             qWarning("QWidget::metric: Invalid metric command");
       
   994         }
       
   995     }
       
   996     return val;
       
   997 }
       
   998 
       
   999 QPaintEngine *QWidget::paintEngine() const
       
  1000 {
       
  1001     return 0;
       
  1002 }
       
  1003 
       
  1004 QPoint QWidget::mapToGlobal(const QPoint &pos) const
       
  1005 {
       
  1006     Q_D(const QWidget);
       
  1007     if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
       
  1008 
       
  1009         QPoint p = pos + data->crect.topLeft();
       
  1010         return (isWindow() || !parentWidget()) ?  p : parentWidget()->mapToGlobal(p);
       
  1011 
       
  1012     } else if ((d->data.window_flags & Qt::Window) && internalWinId()) { //toplevel
       
  1013         QPoint tp = geometry().topLeft();
       
  1014         return pos + tp;
       
  1015     }
       
  1016 
       
  1017     // Native window case
       
  1018     const TPoint widgetScreenOffset = internalWinId()->PositionRelativeToScreen();
       
  1019     const QPoint globalPos = QPoint(widgetScreenOffset.iX, widgetScreenOffset.iY) + pos;
       
  1020     return globalPos;
       
  1021 }
       
  1022 
       
  1023 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
       
  1024 {
       
  1025     Q_D(const QWidget);
       
  1026     if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
       
  1027         QPoint p = (isWindow() || !parentWidget()) ?  pos : parentWidget()->mapFromGlobal(pos);
       
  1028         return p - data->crect.topLeft();
       
  1029     } else if ((d->data.window_flags & Qt::Window) && internalWinId()) { //toplevel
       
  1030         QPoint tp = geometry().topLeft();
       
  1031         return pos - tp;
       
  1032     }
       
  1033 
       
  1034     // Native window case
       
  1035     const TPoint widgetScreenOffset = internalWinId()->PositionRelativeToScreen();
       
  1036     const QPoint widgetPos = pos - QPoint(widgetScreenOffset.iX, widgetScreenOffset.iY);
       
  1037     return widgetPos;
       
  1038 }
       
  1039 
       
  1040 static Qt::WindowStates effectiveState(Qt::WindowStates state)
       
  1041 {
       
  1042     if (state & Qt::WindowMinimized)
       
  1043         return Qt::WindowMinimized;
       
  1044     else if (state & Qt::WindowFullScreen)
       
  1045         return Qt::WindowFullScreen;
       
  1046     else if (state & Qt::WindowMaximized)
       
  1047         return Qt::WindowMaximized;
       
  1048     return Qt::WindowNoState;
       
  1049 }
       
  1050 
       
  1051 void QWidget::setWindowState(Qt::WindowStates newstate)
       
  1052 {
       
  1053     Q_D(QWidget);
       
  1054 
       
  1055     Qt::WindowStates oldstate = windowState();
       
  1056 
       
  1057     const TBool isFullscreen = newstate & Qt::WindowFullScreen;
       
  1058     const TBool cbaRequested = windowFlags() & Qt::WindowSoftkeysVisibleHint;
       
  1059     const TBool cbaVisible = CEikButtonGroupContainer::Current() ? true : false;
       
  1060     const TBool softkeyVisibilityChange = isFullscreen && (cbaRequested != cbaVisible);
       
  1061 
       
  1062     if (oldstate == newstate && !softkeyVisibilityChange)
       
  1063         return;
       
  1064 
       
  1065     if (isWindow()) {
       
  1066         const bool wasResized = testAttribute(Qt::WA_Resized);
       
  1067         const bool wasMoved = testAttribute(Qt::WA_Moved);
       
  1068 
       
  1069         QSymbianControl *window = static_cast<QSymbianControl *>(effectiveWinId());
       
  1070         if (window && newstate & Qt::WindowMinimized) {
       
  1071             window->setFocusSafely(false);
       
  1072             window->MakeVisible(false);
       
  1073         } else if (window && oldstate & Qt::WindowMinimized) {
       
  1074             window->setFocusSafely(true);
       
  1075             window->MakeVisible(true);
       
  1076         }
       
  1077 
       
  1078 #ifdef Q_WS_S60
       
  1079         // Hide window decoration when switching to fullsccreen / minimized otherwise show decoration.
       
  1080         // The window decoration visibility has to be changed before doing actual window state
       
  1081         // change since in that order the availableGeometry will return directly the right size and
       
  1082         // we will avoid unnecessarty redraws
       
  1083         CEikStatusPane *statusPane = S60->statusPane();
       
  1084         CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
       
  1085         TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
       
  1086         if (statusPane)
       
  1087             statusPane->MakeVisible(visible);
       
  1088         if (buttonGroup) {
       
  1089             // Visibility
       
  1090             buttonGroup->MakeVisible(visible || (isFullscreen && cbaRequested));
       
  1091 
       
  1092             // Responsiviness
       
  1093             CEikCba *cba = static_cast<CEikCba *>( buttonGroup->ButtonGroup() ); // downcast from MEikButtonGroup
       
  1094             TUint cbaFlags = cba->ButtonGroupFlags();
       
  1095             if(windowFlags() & Qt::WindowSoftkeysRespondHint)
       
  1096                 cbaFlags |= EAknCBAFlagRespondWhenInvisible;
       
  1097             else
       
  1098                 cbaFlags &= ~EAknCBAFlagRespondWhenInvisible;
       
  1099             cba->SetButtonGroupFlags(cbaFlags);
       
  1100         }
       
  1101 #endif // Q_WS_S60
       
  1102 
       
  1103         createWinId();
       
  1104         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  1105         // Ensure the initial size is valid, since we store it as normalGeometry below.
       
  1106         if (!wasResized && !isVisible())
       
  1107             adjustSize();
       
  1108 
       
  1109         QTLWExtra *top = d->topData();
       
  1110         const QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry;
       
  1111 
       
  1112 
       
  1113         const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint;
       
  1114         if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint)
       
  1115             setGeometry(qApp->desktop()->screenGeometry(this));
       
  1116         else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint))
       
  1117             setGeometry(qApp->desktop()->availableGeometry(this));
       
  1118         else
       
  1119             setGeometry(normalGeometry);
       
  1120 
       
  1121         //restore normal geometry
       
  1122         top->normalGeometry = normalGeometry;
       
  1123 
       
  1124         // FixMe QTBUG-8977
       
  1125         // In some platforms, WA_Resized and WA_Moved are also not set when application window state is
       
  1126         // anything else than normal. In Symbian we can restore them only for normal window state since
       
  1127         // restoring for other modes, will make fluidlauncher to be launched in wrong size (200x100)
       
  1128         if (effectiveState(newstate) == Qt::WindowNoState) {
       
  1129             setAttribute(Qt::WA_Resized, wasResized);
       
  1130             setAttribute(Qt::WA_Moved, wasMoved);
       
  1131         }
       
  1132     }
       
  1133 
       
  1134     data->window_state = newstate;
       
  1135 
       
  1136     if (newstate & Qt::WindowActive)
       
  1137         activateWindow();
       
  1138 
       
  1139     QWindowStateChangeEvent e(oldstate);
       
  1140     QApplication::sendEvent(this, &e);
       
  1141 }
       
  1142 
       
  1143 
       
  1144 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
       
  1145 {
       
  1146     Q_D(QWidget);
       
  1147     if (!isWindow() && parentWidget())
       
  1148         parentWidget()->d_func()->invalidateBuffer(geometry());
       
  1149     d->deactivateWidgetCleanup();
       
  1150     QSymbianControl *id = static_cast<QSymbianControl *>(internalWinId());
       
  1151     if (testAttribute(Qt::WA_WState_Created)) {
       
  1152 
       
  1153 #ifndef QT_NO_IM
       
  1154         if (d->ic) {
       
  1155             delete d->ic;
       
  1156         } else {
       
  1157             QInputContext *ic = QApplicationPrivate::inputContext;
       
  1158             if (ic) {
       
  1159                 ic->widgetDestroyed(this);
       
  1160             }
       
  1161         }
       
  1162 #endif
       
  1163 
       
  1164         if (QWidgetPrivate::mouseGrabber == this)
       
  1165             releaseMouse();
       
  1166         if (QWidgetPrivate::keyboardGrabber == this)
       
  1167             releaseKeyboard();
       
  1168         setAttribute(Qt::WA_WState_Created, false);
       
  1169         QObjectList childList = children();
       
  1170         for (int i = 0; i < childList.size(); ++i) { // destroy all widget children
       
  1171             register QObject *obj = childList.at(i);
       
  1172             if (obj->isWidgetType())
       
  1173                 static_cast<QWidget*>(obj)->destroy(destroySubWindows,
       
  1174                                                     destroySubWindows);
       
  1175         }
       
  1176         if (destroyWindow && !(windowType() == Qt::Desktop) && id) {
       
  1177             if (id->IsFocused()) // Avoid unnecessry calls to FocusChanged()
       
  1178                 id->setFocusSafely(false);
       
  1179             id->ControlEnv()->AppUi()->RemoveFromStack(id);
       
  1180         }
       
  1181     }
       
  1182 
       
  1183     QT_TRY {
       
  1184         d->setWinId(0);
       
  1185     } QT_CATCH (const std::bad_alloc &) {
       
  1186         // swallow - destructors must not throw
       
  1187     }
       
  1188 
       
  1189     if (destroyWindow) {
       
  1190         delete id;
       
  1191         // At this point the backing store should already be destroyed
       
  1192         // so we flush the command buffer to ensure that the freeing of
       
  1193         // those resources and deleting the window can happen "atomically"
       
  1194         S60->wsSession().Flush();
       
  1195     }
       
  1196 }
       
  1197 
       
  1198 QWidget *QWidget::mouseGrabber()
       
  1199 {
       
  1200     return QWidgetPrivate::mouseGrabber;
       
  1201 }
       
  1202 
       
  1203 QWidget *QWidget::keyboardGrabber()
       
  1204 {
       
  1205     return QWidgetPrivate::keyboardGrabber;
       
  1206 }
       
  1207 
       
  1208 void QWidget::grabKeyboard()
       
  1209 {
       
  1210     if (!qt_nograb()) {
       
  1211         if (QWidgetPrivate::keyboardGrabber && QWidgetPrivate::keyboardGrabber != this)
       
  1212             QWidgetPrivate::keyboardGrabber->releaseKeyboard();
       
  1213 
       
  1214         // ### TODO: Native keyboard grab
       
  1215 
       
  1216         QWidgetPrivate::keyboardGrabber = this;
       
  1217     }
       
  1218 }
       
  1219 
       
  1220 void QWidget::releaseKeyboard()
       
  1221 {
       
  1222     if (!qt_nograb() && QWidgetPrivate::keyboardGrabber == this) {
       
  1223         // ### TODO: Native keyboard release
       
  1224         QWidgetPrivate::keyboardGrabber = 0;
       
  1225     }
       
  1226 }
       
  1227 
       
  1228 void QWidget::grabMouse()
       
  1229 {
       
  1230     if (isVisible() && !qt_nograb()) {
       
  1231         if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
       
  1232             QWidgetPrivate::mouseGrabber->releaseMouse();
       
  1233         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  1234         WId id = effectiveWinId();
       
  1235         id->SetPointerCapture(true);
       
  1236         QWidgetPrivate::mouseGrabber = this;
       
  1237 
       
  1238 #ifndef QT_NO_CURSOR
       
  1239         QApplication::setOverrideCursor(cursor());
       
  1240 #endif
       
  1241     }
       
  1242 }
       
  1243 
       
  1244 #ifndef QT_NO_CURSOR
       
  1245 void QWidget::grabMouse(const QCursor &cursor)
       
  1246 {
       
  1247     if (isVisible() && !qt_nograb()) {
       
  1248         if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
       
  1249             QWidgetPrivate::mouseGrabber->releaseMouse();
       
  1250         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  1251         WId id = effectiveWinId();
       
  1252         id->SetPointerCapture(true);
       
  1253         QWidgetPrivate::mouseGrabber = this;
       
  1254 
       
  1255         QApplication::setOverrideCursor(cursor);
       
  1256     }
       
  1257 }
       
  1258 #endif
       
  1259 
       
  1260 void QWidget::releaseMouse()
       
  1261 {
       
  1262     if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
       
  1263         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  1264         if(!window()->isModal()) {
       
  1265             WId id = effectiveWinId();
       
  1266             id->SetPointerCapture(false);
       
  1267         }
       
  1268         QWidgetPrivate::mouseGrabber = 0;
       
  1269 #ifndef QT_NO_CURSOR
       
  1270         QApplication::restoreOverrideCursor();
       
  1271 #endif
       
  1272     }
       
  1273 }
       
  1274 
       
  1275 void QWidget::activateWindow()
       
  1276 {
       
  1277     Q_D(QWidget);
       
  1278 
       
  1279     QWidget *tlw = window();
       
  1280     if (tlw->isVisible()) {
       
  1281         window()->createWinId();
       
  1282         QSymbianControl *id = static_cast<QSymbianControl *>(tlw->internalWinId());
       
  1283         id->setFocusSafely(true);
       
  1284     }
       
  1285 }
       
  1286 
       
  1287 #ifndef QT_NO_CURSOR
       
  1288 
       
  1289 void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
       
  1290 {
       
  1291     Q_UNUSED(cursor);
       
  1292     Q_Q(QWidget);
       
  1293     qt_symbian_set_cursor(q, false);
       
  1294 }
       
  1295 
       
  1296 void QWidgetPrivate::unsetCursor_sys()
       
  1297 {
       
  1298     Q_Q(QWidget);
       
  1299     qt_symbian_set_cursor(q, false);
       
  1300 }
       
  1301 #endif
       
  1302 
       
  1303 QT_END_NAMESPACE