src/gui/kernel/qapplication_s60.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 19 fcece45ef507
equal deleted inserted replaced
3:41300fa6a67c 18:2f34d5167611
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtGui module of the Qt Toolkit.
     7 ** This file is part of the QtGui module of the Qt Toolkit.
     8 **
     8 **
    69 # if !defined(QT_NO_IM)
    69 # if !defined(QT_NO_IM)
    70 #  include "qinputcontext.h"
    70 #  include "qinputcontext.h"
    71 #  include <private/qcoefepinputcontext_p.h>
    71 #  include <private/qcoefepinputcontext_p.h>
    72 # endif
    72 # endif
    73 # include <private/qs60mainapplication_p.h>
    73 # include <private/qs60mainapplication_p.h>
       
    74 # include <centralrepository.h>
    74 #endif
    75 #endif
    75 
    76 
    76 #include "private/qstylesheetstyle_p.h"
    77 #include "private/qstylesheetstyle_p.h"
    77 
    78 
    78 #include <hal.h>
    79 #include <hal.h>
   805 }
   806 }
   806 #endif
   807 #endif
   807 
   808 
   808 void QSymbianControl::Draw(const TRect& controlRect) const
   809 void QSymbianControl::Draw(const TRect& controlRect) const
   809 {
   810 {
       
   811     // Set flag to avoid calling DrawNow in window surface
       
   812     QWidget *window = qwidget->window();
       
   813     Q_ASSERT(window);
       
   814     QTLWExtra *topExtra = window->d_func()->maybeTopData();
       
   815     Q_ASSERT(topExtra);
       
   816     if (!topExtra->inExpose) {
       
   817         topExtra->inExpose = true;
       
   818         QRect exposeRect = qt_TRect2QRect(controlRect);
       
   819         qwidget->d_func()->syncBackingStore(exposeRect);
       
   820         topExtra->inExpose = false;
       
   821     }
       
   822 
   810     QWindowSurface *surface = qwidget->windowSurface();
   823     QWindowSurface *surface = qwidget->windowSurface();
   811     QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL;
   824     QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL;
   812 
   825 
   813     if (!engine)
   826     if (!engine)
   814         return;
   827         return;
   853             break;
   866             break;
   854 
   867 
   855         default:
   868         default:
   856             Q_ASSERT(false);
   869             Q_ASSERT(false);
   857         }
   870         }
   858     } else {
       
   859         surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint());
       
   860     }
   871     }
   861 
   872 
   862     if (sendNativePaintEvents) {
   873     if (sendNativePaintEvents) {
   863         const QRect r = qt_TRect2QRect(controlRect);
   874         const QRect r = qt_TRect2QRect(controlRect);
   864         // The draw ops aren't actually sent to WSERV until the graphics
   875         // The draw ops aren't actually sent to WSERV until the graphics
   914     if (oldPos != newPos) {
   925     if (oldPos != newPos) {
   915         QRect cr = qwidget->geometry();
   926         QRect cr = qwidget->geometry();
   916         cr.moveTopLeft(newPos);
   927         cr.moveTopLeft(newPos);
   917         qwidget->data->crect = cr;
   928         qwidget->data->crect = cr;
   918         QTLWExtra *top = qwidget->d_func()->maybeTopData();
   929         QTLWExtra *top = qwidget->d_func()->maybeTopData();
   919         if (top)
   930         if (top && (qwidget->windowState() & (~Qt::WindowActive)) == Qt::WindowNoState)
   920             top->normalGeometry = cr;
   931             top->normalGeometry.moveTopLeft(newPos);
   921         if (qwidget->isVisible()) {
   932         if (qwidget->isVisible()) {
   922             QMoveEvent e(newPos, oldPos);
   933             QMoveEvent e(newPos, oldPos);
   923             qt_sendSpontaneousEvent(qwidget, &e);
   934             qt_sendSpontaneousEvent(qwidget, &e);
   924         } else {
   935         } else {
   925             QMoveEvent * e = new QMoveEvent(newPos, oldPos);
   936             QMoveEvent * e = new QMoveEvent(newPos, oldPos);
   928     }
   939     }
   929 }
   940 }
   930 
   941 
   931 void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
   942 void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
   932 {
   943 {
   933     if (m_ignoreFocusChanged)
   944     if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop)
   934         return;
   945         return;
   935 
   946 
   936     // Popups never get focused, but still receive the FocusChanged when they are hidden.
   947     // Popups never get focused, but still receive the FocusChanged when they are hidden.
   937     if (QApplicationPrivate::popupWidgets != 0
   948     if (QApplicationPrivate::popupWidgets != 0
   938             || (qwidget->windowType() & Qt::Popup) == Qt::Popup)
   949             || (qwidget->windowType() & Qt::Popup) == Qt::Popup)
   950 
   961 
   951         QApplication::setActiveWindow(qwidget->window());
   962         QApplication::setActiveWindow(qwidget->window());
   952         qwidget->d_func()->setWindowIcon_sys(true);
   963         qwidget->d_func()->setWindowIcon_sys(true);
   953         qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
   964         qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
   954 #ifdef Q_WS_S60
   965 #ifdef Q_WS_S60
   955         // If widget is fullscreen, hide status pane and button container
   966         // If widget is fullscreen/minimized, hide status pane and button container otherwise show them.
   956         // otherwise show them.
       
   957         CEikStatusPane* statusPane = S60->statusPane();
   967         CEikStatusPane* statusPane = S60->statusPane();
   958         CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
   968         CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
   959         bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
   969         TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
   960         if (statusPane && (bool)statusPane->IsVisible() == isFullscreen)
   970         if (statusPane)
   961             statusPane->MakeVisible(!isFullscreen);
   971             statusPane->MakeVisible(visible);
   962         if (buttonGroup && (bool)buttonGroup->IsVisible() == isFullscreen)
   972         if (buttonGroup)
   963             buttonGroup->MakeVisible(!isFullscreen);
   973             buttonGroup->MakeVisible(visible);
   964 #endif
   974 #endif
   965     } else if (QApplication::activeWindow() == qwidget->window()) {
   975     } else if (QApplication::activeWindow() == qwidget->window()) {
   966         if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) {
   976         if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) {
   967             QWidget *fw = QApplication::focusWidget();
   977             QWidget *fw = QApplication::focusWidget();
   968             if (fw) {
   978             if (fw) {
  1133 
  1143 
  1134 #ifdef QT_NO_DEBUG
  1144 #ifdef QT_NO_DEBUG
  1135     if (!qgetenv("QT_S60_AUTO_FLUSH_WSERV").isEmpty())
  1145     if (!qgetenv("QT_S60_AUTO_FLUSH_WSERV").isEmpty())
  1136 #endif
  1146 #endif
  1137         S60->wsSession().SetAutoFlush(ETrue);
  1147         S60->wsSession().SetAutoFlush(ETrue);
       
  1148 
       
  1149 #ifdef Q_SYMBIAN_WINDOW_SIZE_CACHE
       
  1150     TRAP_IGNORE(S60->wsSession().EnableWindowSizeCacheL());
       
  1151 #endif
  1138 
  1152 
  1139     S60->updateScreenSize();
  1153     S60->updateScreenSize();
  1140 
  1154 
  1141 
  1155 
  1142     TDisplayMode mode = S60->screenDevice()->DisplayMode();
  1156     TDisplayMode mode = S60->screenDevice()->DisplayMode();
  1195     else {
  1209     else {
  1196         S60->hasTouchscreen = true;
  1210         S60->hasTouchscreen = true;
  1197         S60->virtualMouseRequired = false;
  1211         S60->virtualMouseRequired = false;
  1198     }
  1212     }
  1199 
  1213 
       
  1214     S60->avkonComponentsSupportTransparency = false;
       
  1215 
       
  1216 #ifdef Q_WS_S60
       
  1217     TUid KCRUidAvkon = { 0x101F876E };
       
  1218     TUint32 KAknAvkonTransparencyEnabled = 0x0000000D;
       
  1219 
       
  1220     CRepository* repository = 0;
       
  1221     TRAP(err, repository = CRepository::NewL(KCRUidAvkon));
       
  1222 
       
  1223     if(err == KErrNone) {
       
  1224         TInt value = 0;
       
  1225         err = repository->Get(KAknAvkonTransparencyEnabled, value);
       
  1226         if(err == KErrNone) {
       
  1227             S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
       
  1228         }
       
  1229     }
       
  1230 #endif    
       
  1231 
  1200     if (touch) {
  1232     if (touch) {
  1201         QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
  1233         QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
  1202     } else {
  1234     } else {
  1203         QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
  1235         QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
  1204     }
  1236     }
  1519     }
  1551     }
  1520     if (qt_S60Beep)
  1552     if (qt_S60Beep)
  1521         qt_S60Beep->Play();
  1553         qt_S60Beep->Play();
  1522 }
  1554 }
  1523 
  1555 
       
  1556 static inline bool callSymbianEventFilters(const QSymbianEvent *event)
       
  1557 {
       
  1558     long unused;
       
  1559     return qApp->filterEvent(const_cast<QSymbianEvent *>(event), &unused);
       
  1560 }
       
  1561 
  1524 /*!
  1562 /*!
  1525     \warning This function is only available on Symbian.
  1563     \warning This function is only available on Symbian.
  1526     \since 4.6
  1564     \since 4.6
  1527 
  1565 
  1528     This function processes an individual Symbian event
  1566     This function processes an individual Symbian event
  1535 {
  1573 {
  1536     Q_D(QApplication);
  1574     Q_D(QApplication);
  1537 
  1575 
  1538     QScopedLoopLevelCounter counter(d->threadData);
  1576     QScopedLoopLevelCounter counter(d->threadData);
  1539 
  1577 
       
  1578     if (d->eventDispatcher->filterEvent(const_cast<QSymbianEvent *>(event)))
       
  1579         return 1;
       
  1580 
  1540     QWidget *w = qApp ? qApp->focusWidget() : 0;
  1581     QWidget *w = qApp ? qApp->focusWidget() : 0;
  1541     if (w) {
  1582     if (w) {
  1542         QInputContext *ic = w->inputContext();
  1583         QInputContext *ic = w->inputContext();
  1543         if (ic && ic->symbianFilterEvent(w, event))
  1584         if (ic && ic->symbianFilterEvent(w, event))
  1544             return 1;
  1585             return 1;
  1547     if (symbianEventFilter(event))
  1588     if (symbianEventFilter(event))
  1548         return 1;
  1589         return 1;
  1549 
  1590 
  1550     switch (event->type()) {
  1591     switch (event->type()) {
  1551     case QSymbianEvent::WindowServerEvent:
  1592     case QSymbianEvent::WindowServerEvent:
  1552         return d->symbianProcessWsEvent(event->windowServerEvent());
  1593         return d->symbianProcessWsEvent(event);
  1553     case QSymbianEvent::CommandEvent:
  1594     case QSymbianEvent::CommandEvent:
  1554         return d->symbianHandleCommand(event->command());
  1595         return d->symbianHandleCommand(event);
  1555     case QSymbianEvent::ResourceChangeEvent:
  1596     case QSymbianEvent::ResourceChangeEvent:
  1556         return d->symbianResourceChange(event->resourceChangeType());
  1597         return d->symbianResourceChange(event);
  1557     default:
  1598     default:
  1558         return -1;
  1599         return -1;
  1559     }
  1600     }
  1560 }
  1601 }
  1561 
  1602 
  1562 int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
  1603 int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent)
  1563 {
  1604 {
  1564     // Qt event handling. Handle some events regardless of if the handle is in our
  1605     // Qt event handling. Handle some events regardless of if the handle is in our
  1565     // widget map or not.
  1606     // widget map or not.
       
  1607     const TWsEvent *event = symbianEvent->windowServerEvent();
  1566     CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle());
  1608     CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle());
  1567     const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control);
  1609     const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control);
  1568     switch (event->Type()) {
  1610     switch (event->Type()) {
  1569     case EEventPointerEnter:
  1611     case EEventPointerEnter:
  1570         if (controlInMap)
  1612         if (controlInMap) {
       
  1613             callSymbianEventFilters(symbianEvent);
  1571             return 1; // Qt::Enter will be generated in HandlePointerL
  1614             return 1; // Qt::Enter will be generated in HandlePointerL
       
  1615         }
  1572         break;
  1616         break;
  1573     case EEventPointerExit:
  1617     case EEventPointerExit:
  1574         if (controlInMap) {
  1618         if (controlInMap) {
       
  1619             if (callSymbianEventFilters(symbianEvent))
       
  1620                 return 1;
  1575             if (S60) {
  1621             if (S60) {
  1576                 // mouseEvent outside our window, send leave event to last focused widget
  1622                 // mouseEvent outside our window, send leave event to last focused widget
  1577                 QMouseEvent mEvent(QEvent::Leave, S60->lastPointerEventPos, S60->lastCursorPos,
  1623                 QMouseEvent mEvent(QEvent::Leave, S60->lastPointerEventPos, S60->lastCursorPos,
  1578                     Qt::NoButton, QApplicationPrivate::mouse_buttons, Qt::NoModifier);
  1624                     Qt::NoButton, QApplicationPrivate::mouse_buttons, Qt::NoModifier);
  1579                 if (S60->lastPointerEventTarget)
  1625                 if (S60->lastPointerEventTarget)
  1582             }
  1628             }
  1583             return 1;
  1629             return 1;
  1584         }
  1630         }
  1585         break;
  1631         break;
  1586     case EEventScreenDeviceChanged:
  1632     case EEventScreenDeviceChanged:
       
  1633         if (callSymbianEventFilters(symbianEvent))
       
  1634             return 1;
  1587         if (S60)
  1635         if (S60)
  1588             S60->updateScreenSize();
  1636             S60->updateScreenSize();
  1589         if (qt_desktopWidget) {
  1637         if (qt_desktopWidget) {
  1590             QSize oldSize = qt_desktopWidget->size();
  1638             QSize oldSize = qt_desktopWidget->size();
  1591             qt_desktopWidget->data->crect.setWidth(S60->screenWidthInPixels);
  1639             qt_desktopWidget->data->crect.setWidth(S60->screenWidthInPixels);
  1594             QApplication::sendEvent(qt_desktopWidget, &e);
  1642             QApplication::sendEvent(qt_desktopWidget, &e);
  1595         }
  1643         }
  1596         return 0; // Propagate to CONE
  1644         return 0; // Propagate to CONE
  1597     case EEventWindowVisibilityChanged:
  1645     case EEventWindowVisibilityChanged:
  1598         if (controlInMap) {
  1646         if (controlInMap) {
       
  1647             if (callSymbianEventFilters(symbianEvent))
       
  1648                 return 1;
  1599             const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
  1649             const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
  1600             QWidget *w = QWidgetPrivate::mapper->value(control);
  1650             QWidget *w = QWidgetPrivate::mapper->value(control);
  1601             if (!w->d_func()->maybeTopData())
  1651             if (!w->d_func()->maybeTopData())
  1602                 break;
  1652                 break;
  1603             if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
  1653             if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
  1604                 delete w->d_func()->topData()->backingStore;
  1654                 delete w->d_func()->topData()->backingStore;
  1605                 w->d_func()->topData()->backingStore = 0;
  1655                 w->d_func()->topData()->backingStore = 0;
  1606                 // :QTP:QT-2506:remove this when QT-2506 is fixed
  1656                 // In order to ensure that any resources used by the window surface
  1607                 if (S60)
  1657                 // are immediately freed, we flush the WSERV command buffer.
  1608                     S60->wsSession().Flush();
  1658                 S60->wsSession().Flush();
  1609             } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
  1659             } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
  1610                        && !w->d_func()->maybeBackingStore()) {
  1660                        && !w->d_func()->maybeBackingStore()) {
  1611                 w->d_func()->topData()->backingStore = new QWidgetBackingStore(w);
  1661                 w->d_func()->topData()->backingStore = new QWidgetBackingStore(w);
  1612                 w->d_func()->invalidateBuffer(w->rect());
  1662                 w->d_func()->invalidateBuffer(w->rect());
  1613                 w->repaint();
  1663                 w->repaint();
  1614             }
  1664             }
  1615             return 1;
  1665             return 1;
  1616         }
  1666         }
  1617         break;
  1667         break;
  1618     case EEventFocusGained:
  1668     case EEventFocusGained:
       
  1669         if (callSymbianEventFilters(symbianEvent))
       
  1670             return 1;
  1619 #ifndef QT_NO_CURSOR
  1671 #ifndef QT_NO_CURSOR
  1620         //re-enable mouse interaction
  1672         //re-enable mouse interaction
  1621         if (S60->mouseInteractionEnabled) {
  1673         if (S60->mouseInteractionEnabled) {
  1622 #ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
  1674 #ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
  1623             if (S60->brokenPointerCursors)
  1675             if (S60->brokenPointerCursors)
  1627                 S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
  1679                 S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
  1628         }
  1680         }
  1629 #endif
  1681 #endif
  1630         break;
  1682         break;
  1631     case EEventFocusLost:
  1683     case EEventFocusLost:
       
  1684         if (callSymbianEventFilters(symbianEvent))
       
  1685             return 1;
  1632 #ifndef QT_NO_CURSOR
  1686 #ifndef QT_NO_CURSOR
  1633         //disable mouse as may be moving to application that does not support it
  1687         //disable mouse as may be moving to application that does not support it
  1634         if (S60->mouseInteractionEnabled) {
  1688         if (S60->mouseInteractionEnabled) {
  1635 #ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
  1689 #ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
  1636             if (S60->brokenPointerCursors)
  1690             if (S60->brokenPointerCursors)
  1678   partially achieved by deriving from CAknAppUi. Currently, exit,
  1732   partially achieved by deriving from CAknAppUi. Currently, exit,
  1679   menu and softkey commands are handled.
  1733   menu and softkey commands are handled.
  1680 
  1734 
  1681   \sa s60EventFilter(), s60ProcessEvent()
  1735   \sa s60EventFilter(), s60ProcessEvent()
  1682 */
  1736 */
  1683 int QApplicationPrivate::symbianHandleCommand(int command)
  1737 int QApplicationPrivate::symbianHandleCommand(const QSymbianEvent *symbianEvent)
  1684 {
  1738 {
  1685     Q_Q(QApplication);
  1739     Q_Q(QApplication);
  1686     int ret = 0;
  1740     int ret = 0;
       
  1741 
       
  1742     if (callSymbianEventFilters(symbianEvent))
       
  1743         return 1;
       
  1744 
       
  1745     int command = symbianEvent->command();
  1687 
  1746 
  1688     switch (command) {
  1747     switch (command) {
  1689 #ifdef Q_WS_S60
  1748 #ifdef Q_WS_S60
  1690     case EAknSoftkeyExit: {
  1749     case EAknSoftkeyExit: {
  1691         QCloseEvent ev;
  1750         QCloseEvent ev;
  1722   Handles the resource change specified by \a type.
  1781   Handles the resource change specified by \a type.
  1723 
  1782 
  1724   Currently, KEikDynamicLayoutVariantSwitch and
  1783   Currently, KEikDynamicLayoutVariantSwitch and
  1725   KAknsMessageSkinChange are handled.
  1784   KAknsMessageSkinChange are handled.
  1726  */
  1785  */
  1727 int QApplicationPrivate::symbianResourceChange(int type)
  1786 int QApplicationPrivate::symbianResourceChange(const QSymbianEvent *symbianEvent)
  1728 {
  1787 {
  1729     int ret = 0;
  1788     int ret = 0;
       
  1789 
       
  1790     int type = symbianEvent->resourceChangeType();
  1730 
  1791 
  1731     switch (type) {
  1792     switch (type) {
  1732 #ifdef Q_WS_S60
  1793 #ifdef Q_WS_S60
  1733     case KEikDynamicLayoutVariantSwitch:
  1794     case KEikDynamicLayoutVariantSwitch:
  1734         {
  1795         {
       
  1796         if (callSymbianEventFilters(symbianEvent))
       
  1797             return 1;
  1735         if (S60)
  1798         if (S60)
  1736             S60->updateScreenSize();
  1799             S60->updateScreenSize();
  1737 
  1800 
  1738 #ifndef QT_NO_STYLE_S60
  1801 #ifndef QT_NO_STYLE_S60
  1739         QS60Style *s60Style = 0;
  1802         QS60Style *s60Style = 0;
  1754         }
  1817         }
  1755         break;
  1818         break;
  1756 
  1819 
  1757 #ifndef QT_NO_STYLE_S60
  1820 #ifndef QT_NO_STYLE_S60
  1758     case KAknsMessageSkinChange:
  1821     case KAknsMessageSkinChange:
       
  1822         if (callSymbianEventFilters(symbianEvent))
       
  1823             return 1;
  1759         if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) {
  1824         if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) {
  1760             s60Style->d_func()->handleSkinChange();
  1825             s60Style->d_func()->handleSkinChange();
  1761             ret = 1;
  1826             ret = 1;
  1762         }
  1827         }
  1763         break;
  1828         break;