src/gui/kernel/qwidget_s60.cpp
branchRCL_3
changeset 7 3f74d0d4af4c
parent 4 3b1da2848fc7
child 11 25a739ee40f4
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
   876 }
   876 }
   877 
   877 
   878 void QWidgetPrivate::createTLSysExtra()
   878 void QWidgetPrivate::createTLSysExtra()
   879 {
   879 {
   880     extra->topextra->backingStore = 0;
   880     extra->topextra->backingStore = 0;
       
   881     extra->topextra->inExpose = 0;
   881 }
   882 }
   882 
   883 
   883 void QWidgetPrivate::deleteTLSysExtra()
   884 void QWidgetPrivate::deleteTLSysExtra()
   884 {
   885 {
       
   886     delete extra->topextra->backingStore;
       
   887     extra->topextra->backingStore = 0;
   885 }
   888 }
   886 
   889 
   887 void QWidgetPrivate::createSysExtra()
   890 void QWidgetPrivate::createSysExtra()
   888 {
   891 {
   889     extra->activated = 0;
   892     extra->activated = 0;
   890     extra->nativePaintMode = QWExtra::Default;
   893     extra->nativePaintMode = QWExtra::Default;
   891     extra->receiveNativePaintEvents = 0;
   894     extra->receiveNativePaintEvents = 0;
   892     extra->inExpose = 0;
       
   893 }
   895 }
   894 
   896 
   895 void QWidgetPrivate::deleteSysExtra()
   897 void QWidgetPrivate::deleteSysExtra()
   896 {
   898 {
   897     // this should only be non-zero if destroy() has not run due to constructor fail
   899     // this should only be non-zero if destroy() has not run due to constructor fail
   898     if (data.winid) {
   900     if (data.winid) {
   899         data.winid->ControlEnv()->AppUi()->RemoveFromStack(data.winid);
   901         data.winid->ControlEnv()->AppUi()->RemoveFromStack(data.winid);
   900         // We need to delete the backing store here before the CCoeControl and RWindow is deleted.
       
   901         // The reason is that the backing store may be an EGL surface and if we delete the window
       
   902         // before we delete the surface, the implementation may try to access to the window and raise
       
   903         // a WSERV 3 panic.
       
   904         if (extra && extra->topextra) {
       
   905             delete extra->topextra->backingStore;
       
   906             extra->topextra->backingStore = 0;
       
   907         }
       
   908         delete data.winid;
   902         delete data.winid;
   909         data.winid = 0;
   903         data.winid = 0;
   910     }
   904     }
   911 }
   905 }
   912 
   906 
  1041     const TPoint widgetScreenOffset = internalWinId()->PositionRelativeToScreen();
  1035     const TPoint widgetScreenOffset = internalWinId()->PositionRelativeToScreen();
  1042     const QPoint widgetPos = pos - QPoint(widgetScreenOffset.iX, widgetScreenOffset.iY);
  1036     const QPoint widgetPos = pos - QPoint(widgetScreenOffset.iX, widgetScreenOffset.iY);
  1043     return widgetPos;
  1037     return widgetPos;
  1044 }
  1038 }
  1045 
  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 
  1046 void QWidget::setWindowState(Qt::WindowStates newstate)
  1051 void QWidget::setWindowState(Qt::WindowStates newstate)
  1047 {
  1052 {
  1048     Q_D(QWidget);
  1053     Q_D(QWidget);
  1049 
  1054 
  1050     Qt::WindowStates oldstate = windowState();
  1055     Qt::WindowStates oldstate = windowState();
  1051     if (oldstate == newstate)
  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)
  1052         return;
  1063         return;
  1053 
  1064 
  1054     if (isWindow()) {
  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 
  1055 #ifdef Q_WS_S60
  1078 #ifdef Q_WS_S60
  1056         // Change window decoration visibility if switching to or from fullsccreen
  1079         // Hide window decoration when switching to fullsccreen / minimized otherwise show decoration.
  1057         // In addition decoration visibility is changed when the initial has been
  1080         // The window decoration visibility has to be changed before doing actual window state
  1058         // WindowNoState.
  1081         // change since in that order the availableGeometry will return directly the right size and
  1059         // The window decoration visibility has to be changed before doing actual
  1082         // we will avoid unnecessarty redraws
  1060         // window state change since in that order the availableGeometry will return
  1083         CEikStatusPane *statusPane = S60->statusPane();
  1061         // directly the right size and we will avoid unnecessarty redraws
  1084         CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
  1062         if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) ||
  1085         TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
  1063             oldstate == Qt::WindowNoState) {
  1086         if (statusPane)
  1064             CEikStatusPane* statusPane = S60->statusPane();
  1087             statusPane->MakeVisible(visible);
  1065             CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
  1088         if (buttonGroup) {
  1066             if (newstate & Qt::WindowFullScreen) {
  1089             // Visibility
  1067                 if (statusPane)
  1090             buttonGroup->MakeVisible(visible || (isFullscreen && cbaRequested));
  1068                     statusPane->MakeVisible(false);
  1091 
  1069                 if (buttonGroup)
  1092             // Responsiviness
  1070                     buttonGroup->MakeVisible(false);
  1093             CEikCba *cba = static_cast<CEikCba *>( buttonGroup->ButtonGroup() ); // downcast from MEikButtonGroup
  1071             } else {
  1094             TUint cbaFlags = cba->ButtonGroupFlags();
  1072                 if (statusPane)
  1095             if(windowFlags() & Qt::WindowSoftkeysRespondHint)
  1073                     statusPane->MakeVisible(true);
  1096                 cbaFlags |= EAknCBAFlagRespondWhenInvisible;
  1074                 if (buttonGroup)
  1097             else
  1075                     buttonGroup->MakeVisible(true);
  1098                 cbaFlags &= ~EAknCBAFlagRespondWhenInvisible;
  1076             }
  1099             cba->SetButtonGroupFlags(cbaFlags);
  1077 
       
  1078         }
  1100         }
  1079 #endif // Q_WS_S60
  1101 #endif // Q_WS_S60
  1080 
  1102 
  1081         createWinId();
  1103         createWinId();
  1082         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
  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 
  1083         QTLWExtra *top = d->topData();
  1109         QTLWExtra *top = d->topData();
  1084 
  1110         const QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry;
  1085         // Ensure the initial size is valid, since we store it as normalGeometry below.
  1111 
  1086         if (!testAttribute(Qt::WA_Resized) && !isVisible())
  1112 
  1087             adjustSize();
  1113         const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint;
  1088 
  1114         if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint)
  1089         if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
  1115             setGeometry(qApp->desktop()->screenGeometry(this));
  1090             if ((newstate & Qt::WindowMaximized)) {
  1116         else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint))
  1091                 const QRect normalGeometry = geometry();
  1117             setGeometry(qApp->desktop()->availableGeometry(this));
  1092 
  1118         else
  1093                 const QRect r = top->normalGeometry;
  1119             setGeometry(normalGeometry);
  1094                 setGeometry(qApp->desktop()->availableGeometry(this));
  1120 
  1095                 top->normalGeometry = r;
  1121         //restore normal geometry
  1096 
  1122         top->normalGeometry = normalGeometry;
  1097                 if (top->normalGeometry.width() < 0)
  1123 
  1098                     top->normalGeometry = normalGeometry;
  1124         // FixMe QTBUG-8977
  1099             } else {
  1125         // In some platforms, WA_Resized and WA_Moved are also not set when application window state is
  1100                 // restore original geometry
  1126         // anything else than normal. In Symbian we can restore them only for normal window state since
  1101                 setGeometry(top->normalGeometry);
  1127         // restoring for other modes, will make fluidlauncher to be launched in wrong size (200x100)
  1102             }
  1128         if (effectiveState(newstate) == Qt::WindowNoState) {
  1103         }
  1129             setAttribute(Qt::WA_Resized, wasResized);
  1104         if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
  1130             setAttribute(Qt::WA_Moved, wasMoved);
  1105             if (newstate & Qt::WindowFullScreen) {
       
  1106                 const QRect normalGeometry = geometry();
       
  1107                 const QRect r = top->normalGeometry;
       
  1108                 setGeometry(qApp->desktop()->screenGeometry(this));
       
  1109 
       
  1110                 top->normalGeometry = r;
       
  1111                 if (top->normalGeometry.width() < 0)
       
  1112                     top->normalGeometry = normalGeometry;
       
  1113             } else {
       
  1114                 if (newstate & Qt::WindowMaximized) {
       
  1115                     const QRect r = top->normalGeometry;
       
  1116                     setGeometry(qApp->desktop()->availableGeometry(this));
       
  1117                     top->normalGeometry = r;
       
  1118                 } else {
       
  1119                     setGeometry(top->normalGeometry);
       
  1120                 }
       
  1121             }
       
  1122         }
       
  1123         if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
       
  1124             if (newstate & Qt::WindowMinimized) {
       
  1125                 if (isVisible()) {
       
  1126                     QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId());
       
  1127                     if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
       
  1128                         id->setFocusSafely(false);
       
  1129                     id->MakeVisible(false);
       
  1130                 }
       
  1131             } else {
       
  1132                 if (isVisible()) {
       
  1133                     QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId());
       
  1134                     id->MakeVisible(true);
       
  1135                     if (!id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
       
  1136                         id->setFocusSafely(true);
       
  1137                 }
       
  1138                 const QRect normalGeometry = geometry();
       
  1139                 const QRect r = top->normalGeometry;
       
  1140                 top->normalGeometry = r;
       
  1141                 if (top->normalGeometry.width() < 0)
       
  1142                     top->normalGeometry = normalGeometry;
       
  1143             }
       
  1144         }
  1131         }
  1145     }
  1132     }
  1146 
  1133 
  1147     data->window_state = newstate;
  1134     data->window_state = newstate;
  1148 
  1135 
  1198     } QT_CATCH (const std::bad_alloc &) {
  1185     } QT_CATCH (const std::bad_alloc &) {
  1199         // swallow - destructors must not throw
  1186         // swallow - destructors must not throw
  1200     }
  1187     }
  1201 
  1188 
  1202     if (destroyWindow) {
  1189     if (destroyWindow) {
  1203         d->deleteSysExtra(); // deletes backingstore + window
  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();
  1204     }
  1195     }
  1205 }
  1196 }
  1206 
  1197 
  1207 QWidget *QWidget::mouseGrabber()
  1198 QWidget *QWidget::mouseGrabber()
  1208 {
  1199 {
  1268 
  1259 
  1269 void QWidget::releaseMouse()
  1260 void QWidget::releaseMouse()
  1270 {
  1261 {
  1271     if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
  1262     if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
  1272         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
  1263         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
  1273         WId id = effectiveWinId();
  1264         if(!window()->isModal()) {
  1274         id->SetPointerCapture(false);
  1265             WId id = effectiveWinId();
       
  1266             id->SetPointerCapture(false);
       
  1267         }
  1275         QWidgetPrivate::mouseGrabber = 0;
  1268         QWidgetPrivate::mouseGrabber = 0;
  1276 #ifndef QT_NO_CURSOR
  1269 #ifndef QT_NO_CURSOR
  1277         QApplication::restoreOverrideCursor();
  1270         QApplication::restoreOverrideCursor();
  1278 #endif
  1271 #endif
  1279     }
  1272     }