diff options
Diffstat (limited to 'src/gui/kernel')
26 files changed, 535 insertions, 298 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 052da6a..08852af 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5313,6 +5313,7 @@ bool QApplication::keypadNavigationEnabled() \sa QCoreApplication::instance() */ +#ifndef QT_NO_IM // ************************************************************************ // Input Method support // ************************************************************************ @@ -5378,6 +5379,7 @@ QInputContext *QApplication::inputContext() const #endif return d->inputContext; } +#endif // QT_NO_IM //Returns the current platform used by keyBindings uint QApplicationPrivate::currentPlatform(){ @@ -5808,10 +5810,12 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, #ifndef QT_NO_GESTURES QGestureManager* QGestureManager::instance() { - QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - if (!qAppPriv->gestureManager) - qAppPriv->gestureManager = new QGestureManager(qApp); - return qAppPriv->gestureManager; + if (QApplicationPrivate *qAppPriv = QApplicationPrivate::instance()) { + if (!qAppPriv->gestureManager) + qAppPriv->gestureManager = new QGestureManager(qApp); + return qAppPriv->gestureManager; + } + return 0; } #endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index d31d9e5..799d4c2 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -267,8 +267,11 @@ public: virtual void commitData(QSessionManager& sm); virtual void saveState(QSessionManager& sm); #endif + +#ifndef QT_NO_IM void setInputContext(QInputContext *); QInputContext *inputContext() const; +#endif static QLocale keyboardInputLocale(); static Qt::LayoutDirection keyboardInputDirection(); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 933e0ab..44aa20a 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -645,7 +645,7 @@ private: #endif #ifdef Q_OS_SYMBIAN - static QHash<TInt, TUint> scanCodeCache; + QHash<TInt, TUint> scanCodeCache; #endif static QApplicationPrivate *self; diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 0d65811..f8734b2 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -112,6 +112,25 @@ QS60Data* qGlobalS60Data() return qt_s60Data(); } +#ifdef Q_WS_S60 +void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible) +{ + bool buttonGroupVisibilityChanged = false; + if (CEikButtonGroupContainer *const b = buttonGroupContainer()) { + buttonGroupVisibilityChanged = (b->IsVisible() != buttonGroupVisible); + b->MakeVisible(buttonGroupVisible); + } + bool statusPaneVisibilityChanged = false; + if (CEikStatusPane *const s = statusPane()) { + statusPaneVisibilityChanged = (s->IsVisible() != statusPaneVisible); + s->MakeVisible(statusPaneVisible); + } + if (buttonGroupVisibilityChanged && !statusPaneVisibilityChanged) + // Ensure that control rectangle is updated + static_cast<QSymbianControl *>(QApplication::activeWindow()->winId())->handleClientAreaChange(); +} +#endif + bool qt_nograb() // application no-grab option { #if defined(QT_DEBUG) @@ -207,8 +226,6 @@ void QS60Beep::MatoPlayComplete(TInt aError) } -QHash<TInt, TUint> QApplicationPrivate::scanCodeCache; - static Qt::KeyboardModifiers mapToQtModifiers(TUint s60Modifiers) { Qt::KeyboardModifiers result = Qt::NoModifier; @@ -382,6 +399,10 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop) QSymbianControl::~QSymbianControl() { + // Ensure backing store is deleted before the top-level + // window is destroyed + qt_widget_private(qwidget)->topData()->backingStore.destroy(); + if (S60->curWin == this) S60->curWin = 0; if (!QApplicationPrivate::is_app_closing) { @@ -621,251 +642,302 @@ TKeyResponse QSymbianControl::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCo TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCode type) { - switch (type) { - //case EEventKeyDown: // <-- Intentionally left out. See below. - case EEventKeyUp: - case EEventKey: - { + /* + S60 has a confusing way of delivering key events. There are three types of + events: EEventKey, EEventKeyDown and EEventKeyUp. When a key is pressed, + EEventKeyDown is first generated, followed by EEventKey. Then, when the key is + released, EEventKeyUp is generated. + However, it is possible that only the EEventKey is generated alone, typically + in relation to virtual keyboards. In that case we need to take care to + generate both press and release events in Qt, since applications expect that. + We do this by having three states for each used scan code, depending on the + events received. See the switch below for what happens in each state + transition. + */ + + if (type != EEventKeyDown) + if (handleVirtualMouse(keyEvent, type) == EKeyWasConsumed) + return EKeyWasConsumed; + + TKeyResponse ret = EKeyWasNotConsumed; +#define GET_RETURN(x) (ret = ((x) == EKeyWasConsumed) ? EKeyWasConsumed : ret) + + // This top level switch corresponds to the states, and the inner switches + // correspond to the transitions. + QS60Data::ScanCodeState &scanCodeState = S60->scanCodeStates[keyEvent.iScanCode]; + switch (scanCodeState) { + case QS60Data::Unpressed: + switch (type) { + case EEventKeyDown: + scanCodeState = QS60Data::KeyDown; + break; + case EEventKey: + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress)); + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease)); + break; + case EEventKeyUp: + // No action. + break; + } + break; + case QS60Data::KeyDown: + switch (type) { + case EEventKeyDown: + // This should never happen, just stay in this state to be safe. + break; + case EEventKey: + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress)); + scanCodeState = QS60Data::KeyDownAndKey; + break; + case EEventKeyUp: + scanCodeState = QS60Data::Unpressed; + break; + } + break; + case QS60Data::KeyDownAndKey: + switch (type) { + case EEventKeyDown: + // This should never happen, just stay in this state to be safe. + break; + case EEventKey: + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease)); + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress)); + break; + case EEventKeyUp: + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease)); + scanCodeState = QS60Data::Unpressed; + break; + } + break; + } + return ret; + +#undef GET_RETURN +} + +TKeyResponse QSymbianControl::sendSymbianKeyEvent(const TKeyEvent &keyEvent, QEvent::Type type) +{ + // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp + // events, we need to cache the keysyms from the EKeyEvent events. This is what + // resolveS60ScanCode does. + TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode, + keyEvent.iCode); + int keyCode; + if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used + keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode); + } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) { + // Normal characters keys. + keyCode = s60Keysym; + } else { + // Special S60 keys. + keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym); + } + + Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers); + QKeyEventEx qKeyEvent(type, keyCode, mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods), + (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers); + QWidget *widget; + widget = QWidget::keyboardGrabber(); + if (!widget) { + if (QApplicationPrivate::popupWidgets != 0) { + widget = QApplication::activePopupWidget()->focusWidget(); + if (!widget) { + widget = QApplication::activePopupWidget(); + } + } else { + widget = QApplicationPrivate::focus_widget; + if (!widget) { + widget = qwidget; + } + } + } + + QEventDispatcherS60 *dispatcher; + // It is theoretically possible for someone to install a different event dispatcher. + if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widget->d_func()->threadData->eventDispatcher)) != 0) { + if (dispatcher->excludeUserInputEvents()) { + dispatcher->saveInputEvent(this, widget, new QKeyEventEx(qKeyEvent)); + return EKeyWasConsumed; + } + } + return sendKeyEvent(widget, &qKeyEvent); +} + +TKeyResponse QSymbianControl::handleVirtualMouse(const TKeyEvent& keyEvent,TEventCode type) +{ #ifndef QT_NO_CURSOR - if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) { - //translate keys to pointer - if ((keyEvent.iScanCode >= EStdKeyLeftArrow && keyEvent.iScanCode <= EStdKeyDownArrow) || + if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) { + //translate keys to pointer + if ((keyEvent.iScanCode >= EStdKeyLeftArrow && keyEvent.iScanCode <= EStdKeyDownArrow) || (keyEvent.iScanCode >= EStdKeyDevice10 && keyEvent.iScanCode <= EStdKeyDevice13) || keyEvent.iScanCode == EStdKeyDevice3) { - QPoint pos = QCursor::pos(); - TPointerEvent fakeEvent; - fakeEvent.iType = (TPointerEvent::TType)(-1); - fakeEvent.iModifiers = keyEvent.iModifiers; - TInt x = pos.x(); - TInt y = pos.y(); - if (type == EEventKeyUp) { - S60->virtualMouseAccelTimeout.start(); - switch (keyEvent.iScanCode) { - case EStdKeyLeftArrow: - S60->virtualMousePressedKeys &= ~QS60Data::Left; - break; - case EStdKeyRightArrow: - S60->virtualMousePressedKeys &= ~QS60Data::Right; - break; - case EStdKeyUpArrow: - S60->virtualMousePressedKeys &= ~QS60Data::Up; - break; - case EStdKeyDownArrow: - S60->virtualMousePressedKeys &= ~QS60Data::Down; - break; - // diagonal keys (named aliases don't exist in 3.1 SDK) - case EStdKeyDevice10: - S60->virtualMousePressedKeys &= ~QS60Data::LeftUp; - break; - case EStdKeyDevice11: - S60->virtualMousePressedKeys &= ~QS60Data::RightUp; - break; - case EStdKeyDevice12: - S60->virtualMousePressedKeys &= ~QS60Data::RightDown; - break; - case EStdKeyDevice13: - S60->virtualMousePressedKeys &= ~QS60Data::LeftDown; - break; - case EStdKeyDevice3: //select - if (S60->virtualMousePressedKeys & QS60Data::Select) - fakeEvent.iType = TPointerEvent::EButton1Up; - S60->virtualMousePressedKeys &= ~QS60Data::Select; - break; - } + QPoint pos = QCursor::pos(); + TPointerEvent fakeEvent; + fakeEvent.iType = (TPointerEvent::TType)(-1); + fakeEvent.iModifiers = keyEvent.iModifiers; + TInt x = pos.x(); + TInt y = pos.y(); + if (type == EEventKeyUp) { + S60->virtualMouseAccelTimeout.start(); + switch (keyEvent.iScanCode) { + case EStdKeyLeftArrow: + S60->virtualMousePressedKeys &= ~QS60Data::Left; + break; + case EStdKeyRightArrow: + S60->virtualMousePressedKeys &= ~QS60Data::Right; + break; + case EStdKeyUpArrow: + S60->virtualMousePressedKeys &= ~QS60Data::Up; + break; + case EStdKeyDownArrow: + S60->virtualMousePressedKeys &= ~QS60Data::Down; + break; + // diagonal keys (named aliases don't exist in 3.1 SDK) + case EStdKeyDevice10: + S60->virtualMousePressedKeys &= ~QS60Data::LeftUp; + break; + case EStdKeyDevice11: + S60->virtualMousePressedKeys &= ~QS60Data::RightUp; + break; + case EStdKeyDevice12: + S60->virtualMousePressedKeys &= ~QS60Data::RightDown; + break; + case EStdKeyDevice13: + S60->virtualMousePressedKeys &= ~QS60Data::LeftDown; + break; + case EStdKeyDevice3: //select + if (S60->virtualMousePressedKeys & QS60Data::Select) + fakeEvent.iType = TPointerEvent::EButton1Up; + S60->virtualMousePressedKeys &= ~QS60Data::Select; + break; } - else if (type == EEventKey) { - int dx = 0; - int dy = 0; - if (keyEvent.iScanCode != EStdKeyDevice3) { - m_doubleClickTimer.invalidate(); - //reset mouse accelleration after a short time with no moves - const int maxTimeBetweenKeyEventsMs = 500; - if (S60->virtualMouseAccelTimeout.isValid() && + } + else if (type == EEventKey) { + int dx = 0; + int dy = 0; + if (keyEvent.iScanCode != EStdKeyDevice3) { + m_doubleClickTimer.invalidate(); + //reset mouse accelleration after a short time with no moves + const int maxTimeBetweenKeyEventsMs = 500; + if (S60->virtualMouseAccelTimeout.isValid() && S60->virtualMouseAccelTimeout.hasExpired(maxTimeBetweenKeyEventsMs)) { - S60->virtualMouseAccelDX = 0; - S60->virtualMouseAccelDY = 0; - } - S60->virtualMouseAccelTimeout.invalidate(); + S60->virtualMouseAccelDX = 0; + S60->virtualMouseAccelDY = 0; } - switch (keyEvent.iScanCode) { - case EStdKeyLeftArrow: - S60->virtualMousePressedKeys |= QS60Data::Left; - dx = -1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyRightArrow: - S60->virtualMousePressedKeys |= QS60Data::Right; - dx = 1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyUpArrow: - S60->virtualMousePressedKeys |= QS60Data::Up; - dy = -1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDownArrow: - S60->virtualMousePressedKeys |= QS60Data::Down; - dy = 1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice10: - S60->virtualMousePressedKeys |= QS60Data::LeftUp; - dx = -1; - dy = -1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice11: - S60->virtualMousePressedKeys |= QS60Data::RightUp; - dx = 1; - dy = -1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice12: - S60->virtualMousePressedKeys |= QS60Data::RightDown; - dx = 1; - dy = 1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice13: - S60->virtualMousePressedKeys |= QS60Data::LeftDown; - dx = -1; - dy = 1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice3: - // Platform bug. If you start pressing several keys simultaneously (for - // example for drag'n'drop), Symbian starts producing spurious up and - // down messages for some keys. Therefore, make sure we have a clean slate - // of pressed keys before starting a new button press. - if (S60->virtualMousePressedKeys & QS60Data::Select) { - return EKeyWasConsumed; - } else { - S60->virtualMousePressedKeys |= QS60Data::Select; - fakeEvent.iType = TPointerEvent::EButton1Down; - if (m_doubleClickTimer.isValid() + S60->virtualMouseAccelTimeout.invalidate(); + } + switch (keyEvent.iScanCode) { + case EStdKeyLeftArrow: + S60->virtualMousePressedKeys |= QS60Data::Left; + dx = -1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyRightArrow: + S60->virtualMousePressedKeys |= QS60Data::Right; + dx = 1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyUpArrow: + S60->virtualMousePressedKeys |= QS60Data::Up; + dy = -1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDownArrow: + S60->virtualMousePressedKeys |= QS60Data::Down; + dy = 1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice10: + S60->virtualMousePressedKeys |= QS60Data::LeftUp; + dx = -1; + dy = -1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice11: + S60->virtualMousePressedKeys |= QS60Data::RightUp; + dx = 1; + dy = -1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice12: + S60->virtualMousePressedKeys |= QS60Data::RightDown; + dx = 1; + dy = 1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice13: + S60->virtualMousePressedKeys |= QS60Data::LeftDown; + dx = -1; + dy = 1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice3: + // Platform bug. If you start pressing several keys simultaneously (for + // example for drag'n'drop), Symbian starts producing spurious up and + // down messages for some keys. Therefore, make sure we have a clean slate + // of pressed keys before starting a new button press. + if (S60->virtualMousePressedKeys & QS60Data::Select) { + return EKeyWasConsumed; + } else { + S60->virtualMousePressedKeys |= QS60Data::Select; + fakeEvent.iType = TPointerEvent::EButton1Down; + if (m_doubleClickTimer.isValid() && !m_doubleClickTimer.hasExpired(QApplication::doubleClickInterval())) { - fakeEvent.iModifiers |= EModifierDoubleClick; - m_doubleClickTimer.invalidate(); - } else { - m_doubleClickTimer.start(); - } + fakeEvent.iModifiers |= EModifierDoubleClick; + m_doubleClickTimer.invalidate(); + } else { + m_doubleClickTimer.start(); } - break; - } - if (dx) { - int cdx = S60->virtualMouseAccelDX; - //reset accel on change of sign, else double accel - if (dx * cdx <= 0) - cdx = dx; - else - cdx *= 4; - //cap accelleration - if (dx * cdx > S60->virtualMouseMaxAccel) - cdx = dx * S60->virtualMouseMaxAccel; - //move mouse position - x += cdx; - S60->virtualMouseAccelDX = cdx; } - - if (dy) { - int cdy = S60->virtualMouseAccelDY; - if (dy * cdy <= 0) - cdy = dy; - else - cdy *= 4; - if (dy * cdy > S60->virtualMouseMaxAccel) - cdy = dy * S60->virtualMouseMaxAccel; - y += cdy; - S60->virtualMouseAccelDY = cdy; - } - } - //clip to screen size (window server allows a sprite hotspot to be outside the screen) - if (x < 0) - x = 0; - else if (x >= S60->screenWidthInPixels) - x = S60->screenWidthInPixels - 1; - if (y < 0) - y = 0; - else if (y >= S60->screenHeightInPixels) - y = S60->screenHeightInPixels - 1; - TPoint epos(x, y); - TPoint cpos = epos - PositionRelativeToScreen(); - fakeEvent.iPosition = cpos; - fakeEvent.iParentPosition = epos; - if(fakeEvent.iType != -1) - HandlePointerEvent(fakeEvent); - return EKeyWasConsumed; - } - } -#endif - // S60 has a confusing way of delivering key events. There are three types of - // events: EKeyEvent, EKeyEventDown and EKeyEventUp. When a key is pressed, the - // two first events are generated. When releasing the key, the last one is - // generated. - // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp events, - // we need to do some special tricks to map it to the Qt way. First, we completely - // discard EKeyEventDown events, since they are redundant. Second, since - // EKeyEventUp does not give us a keysym, we need to cache the keysyms from - // the EKeyEvent events. This is what resolveS60ScanCode does. - - - // ### hackish way to send Qt application to background when pressing right softkey - /* - if( keyEvent.iScanCode == EStdKeyDevice1 ) { - S60->window_group->SetOrdinalPosition(-1); - qApp->setActiveWindow(0); - return EKeyWasNotConsumed; - } - */ - - TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode, - keyEvent.iCode); - int keyCode; - if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used - keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode); - } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) { - // Normal characters keys. - keyCode = s60Keysym; - } else { - // Special S60 keys. - keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym); - } - - Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers); - QKeyEventEx qKeyEvent(type == EEventKeyUp ? QEvent::KeyRelease : QEvent::KeyPress, keyCode, - mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods), - (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers); -// WId wid = reinterpret_cast<RWindowGroup *>(keyEvent.Handle())->Child(); -// if (!wid) -// Could happen if window isn't shown yet. -// return EKeyWasNotConsumed; - QWidget *widget; - widget = QWidget::keyboardGrabber(); - if (!widget) { - if (QApplicationPrivate::popupWidgets != 0) { - widget = QApplication::activePopupWidget()->focusWidget(); - if (!widget) { - widget = QApplication::activePopupWidget(); + break; } - } else { - widget = QApplicationPrivate::focus_widget; - if (!widget) { - widget = qwidget; + if (dx) { + int cdx = S60->virtualMouseAccelDX; + //reset accel on change of sign, else double accel + if (dx * cdx <= 0) + cdx = dx; + else + cdx *= 4; + //cap accelleration + if (dx * cdx > S60->virtualMouseMaxAccel) + cdx = dx * S60->virtualMouseMaxAccel; + //move mouse position + x += cdx; + S60->virtualMouseAccelDX = cdx; } - } - } - QEventDispatcherS60 *dispatcher; - // It is theoretically possible for someone to install a different event dispatcher. - if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widget->d_func()->threadData->eventDispatcher)) != 0) { - if (dispatcher->excludeUserInputEvents()) { - dispatcher->saveInputEvent(this, widget, new QKeyEventEx(qKeyEvent)); - return EKeyWasConsumed; + if (dy) { + int cdy = S60->virtualMouseAccelDY; + if (dy * cdy <= 0) + cdy = dy; + else + cdy *= 4; + if (dy * cdy > S60->virtualMouseMaxAccel) + cdy = dy * S60->virtualMouseMaxAccel; + y += cdy; + S60->virtualMouseAccelDY = cdy; + } } + //clip to screen size (window server allows a sprite hotspot to be outside the screen) + if (x < 0) + x = 0; + else if (x >= S60->screenWidthInPixels) + x = S60->screenWidthInPixels - 1; + if (y < 0) + y = 0; + else if (y >= S60->screenHeightInPixels) + y = S60->screenHeightInPixels - 1; + TPoint epos(x, y); + TPoint cpos = epos - PositionRelativeToScreen(); + fakeEvent.iPosition = cpos; + fakeEvent.iParentPosition = epos; + if(fakeEvent.iType != -1) + HandlePointerEvent(fakeEvent); + return EKeyWasConsumed; } - return sendKeyEvent(widget, &qKeyEvent); - } } +#endif + return EKeyWasNotConsumed; } @@ -1096,17 +1168,12 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle()); #ifdef Q_WS_S60 // If widget is fullscreen/minimized, hide status pane and button container otherwise show them. - CEikStatusPane *statusPane = S60->statusPane(); - CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer(); - TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); - if (statusPane) - statusPane->MakeVisible(visible); - if (buttonGroup) { - // Visibility - const TBool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen; - const TBool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint; - buttonGroup->MakeVisible(visible || (isFullscreen && cbaVisibilityHint)); - } + const bool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool statusPaneVisibility = visible; + const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen; + const bool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint; + const bool buttonGroupVisibility = (visible || (isFullscreen && cbaVisibilityHint)); + S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); #endif } else if (QApplication::activeWindow() == qwidget->window()) { if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) { @@ -1456,6 +1523,8 @@ void qt_cleanup() qt_S60Beep = 0; } QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles + QPixmapCache::clear(); // Has to happen now, since QS60PixmapData has FBS handles + qt_cleanup_symbianFontDatabaseExtras(); // S60 structure and window server session are freed in eventdispatcher destructor as they are needed there @@ -2076,13 +2145,18 @@ void QApplication::setEffectEnabled(Qt::UIEffect /* effect */, bool /* enable */ TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym) { + if (!scanCode) + return keysym; + + QApplicationPrivate *d = QApplicationPrivate::instance(); + if (keysym) { // If keysym is specified, cache it. - scanCodeCache.insert(scanCode, keysym); + d->scanCodeCache.insert(scanCode, keysym); return keysym; } else { // If not, retrieve the cached version. - return scanCodeCache[scanCode]; + return d->scanCodeCache[scanCode]; } } diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 9e8a128..ec26e81 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -2485,7 +2485,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa if (OkCommand) QApplication::postEvent(widget, new QEvent(QEvent::OkRequest)); if (CancelCommand) - QApplication::postEvent(widget, new QEvent(QEvent::Close)); + widget->showMinimized(); else #ifndef QT_NO_MENUBAR QMenuBar::wceCommands(LOWORD(wParam)); diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index 5dcf613..7a9dc70 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -196,7 +196,6 @@ static void cleanupCocoaApplicationDelegate() qAppInstance()->quit(); startedQuit = false; } - return NSTerminateNow; } if (qtPrivate->threadData->eventLoops.size() == 0) { diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index 8652816..6795149 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -85,6 +85,8 @@ QT_END_NAMESPACE - (BOOL)canBecomeKeyWindow { QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)]; + if (!widget) + return NO; // This should happen only for qt_root_win bool isToolTip = (widget->windowType() == Qt::ToolTip); bool isPopup = (widget->windowType() == Qt::Popup); @@ -94,6 +96,8 @@ QT_END_NAMESPACE - (BOOL)canBecomeMainWindow { QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)]; + if (!widget) + return NO; // This should happen only for qt_root_win bool isToolTip = (widget->windowType() == Qt::ToolTip); bool isPopup = (widget->windowType() == Qt::Popup); diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 5c90e2e..a552ce7 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -269,6 +269,28 @@ static int qCocoaViewCount = 0; dropData = new QCocoaDropData(dropPasteboard); } +- (void)changeDraggingCursor:(NSDragOperation)newOperation +{ + static SEL action = nil; + static bool operationSupported = false; + if (action == nil) { + action = NSSelectorFromString(@"operationNotAllowedCursor"); + if ([NSCursor respondsToSelector:action]) { + operationSupported = true; + } + } + if (operationSupported) { + NSCursor *notAllowedCursor = [NSCursor performSelector:action]; + bool isNotAllowedCursor = ([NSCursor currentCursor] == notAllowedCursor); + if (newOperation == NSDragOperationNone && !isNotAllowedCursor) { + [notAllowedCursor push]; + } else if (newOperation != NSDragOperationNone && isNotAllowedCursor) { + [notAllowedCursor pop]; + } + + } +} + - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender { // NB: This function is called from QCoocaWindow/QCocoaPanel rather than directly @@ -300,6 +322,7 @@ static int qCocoaViewCount = 0; if (!qDEEvent.isAccepted()) { // widget is not interested in this drag, so ignore this drop data. [self removeDropData]; + [self changeDraggingCursor:NSDragOperationNone]; return NSDragOperationNone; } else { // save the mouse position, used by draggingExited handler. @@ -321,6 +344,7 @@ static int qCocoaViewCount = 0; nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDMEvent.dropAction()); } QT_PREPEND_NAMESPACE(qt_mac_copy_answer_rect)(qDMEvent); + [self changeDraggingCursor:nsActions]; return nsActions; } } @@ -335,16 +359,21 @@ static int qCocoaViewCount = 0; if (dragEnterSequence != [sender draggingSequenceNumber]) [self draggingEntered:sender]; // drag enter event was rejected, so ignore the move event. - if (dropData == 0) + if (dropData == 0) { + [self changeDraggingCursor:NSDragOperationNone]; return NSDragOperationNone; + } // return last value, if we are still in the answerRect. NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint]; NSPoint localPoint = [self convertPoint:windowPoint fromView:nil]; NSDragOperation nsActions = [sender draggingSourceOperationMask]; QPoint posDrag(localPoint.x, localPoint.y); if (qt_mac_mouse_inside_answer_rect(posDrag) - && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions) - return QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction)); + && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions) { + NSDragOperation operation = QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction)); + [self changeDraggingCursor:operation]; + return operation; + } // send drag move event to the widget QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions; Qt::DropActions qtAllowed = QT_PREPEND_NAMESPACE(qt_mac_mapNSDragOperations)(nsActions); @@ -361,7 +390,10 @@ static int qCocoaViewCount = 0; if (QDragManager::self()->source()) mimeData = QDragManager::self()->dragPrivate()->data; QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers); - qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction); + if (QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction != Qt::IgnoreAction + && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).buttons == qDMEvent.mouseButtons() + && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).modifiers == qDMEvent.keyboardModifiers()) + qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction); qDMEvent.accept(); QApplication::sendEvent(qwidget, &qDMEvent); @@ -373,6 +405,7 @@ static int qCocoaViewCount = 0; qDMEvent.setDropAction(Qt::IgnoreAction); } qt_mac_copy_answer_rect(qDMEvent); + [self changeDraggingCursor:operation]; return operation; } @@ -388,6 +421,8 @@ static int qCocoaViewCount = 0; QApplication::sendEvent(qwidget, &de); [self removeDropData]; } + [self changeDraggingCursor:NSDragOperationEvery]; + } - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index 33aaa24..b6b63ca 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -106,6 +106,7 @@ Q_GUI_EXPORT - (void) qt_clearQWidget; - (BOOL)qt_leftButtonIsRightButton; - (void)qt_setLeftButtonIsRightButton:(BOOL)isSwapped; +- (void)changeDraggingCursor:(NSDragOperation)newOperation; + (DnDParams*)currentMouseEvent; @end diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index 2b9cf85..ffba6c2 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -394,5 +394,25 @@ static void cleanupCocoaWindowDelegate() } return NO; } + +- (void)syncContentViewFrame: (NSNotification *)notification +{ + NSView *cView = [notification object]; + if (cView) { + NSWindow *window = [cView window]; + QWidget *qwidget = m_windowHash->value(window); + if (qwidget) { + QWidgetData *widgetData = qt_qwidget_data(qwidget); + NSRect rect = [cView frame]; + const QSize newSize(rect.size.width, rect.size.height); + const QSize &oldSize = widgetData->crect.size(); + if (newSize != oldSize) { + [self syncSizeForWidget:qwidget toSize:newSize fromSize:oldSize]; + } + } + + } +} + @end #endif// QT_MAC_USE_COCOA diff --git a/src/gui/kernel/qcocoawindowdelegate_mac_p.h b/src/gui/kernel/qcocoawindowdelegate_mac_p.h index de9c946..2ca9b13 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac_p.h +++ b/src/gui/kernel/qcocoawindowdelegate_mac_p.h @@ -105,5 +105,6 @@ QT_FORWARD_DECLARE_CLASS(QWidgetData) - (NSSize)closestAcceptableSizeForWidget:(QWidget *)qwidget window:(NSWindow *)window withNewSize:(NSSize)proposedSize; - (QWidget *)qt_qwidgetForWindow:(NSWindow *)window; +- (void)syncContentViewFrame: (NSNotification *)notification; @end #endif diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/gui/kernel/qdesktopwidget_s60.cpp index e4d0bf3..a07f4a7 100644 --- a/src/gui/kernel/qdesktopwidget_s60.cpp +++ b/src/gui/kernel/qdesktopwidget_s60.cpp @@ -103,6 +103,10 @@ void QDesktopWidgetPrivate::init(QDesktopWidget *that) rects->resize(QDesktopWidgetPrivate::screenCount); workrects->resize(QDesktopWidgetPrivate::screenCount); + + (*rects)[0].setRect(0, 0, S60->screenWidthInPixels, S60->screenHeightInPixels); + QRect wr = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()); + (*workrects)[0].setRect(wr.x(), wr.y(), wr.width(), wr.height()); } void QDesktopWidgetPrivate::cleanup() @@ -146,17 +150,23 @@ QWidget *QDesktopWidget::screen(int /* screen */) return this; } -const QRect QDesktopWidget::availableGeometry(int /* screen */) const +const QRect QDesktopWidget::availableGeometry(int screen) const { - TRect clientRect = static_cast<CEikAppUi*>(S60->appUi())->ClientRect(); - return qt_TRect2QRect(clientRect); + Q_D(const QDesktopWidget); + if (screen < 0 || screen >= d->screenCount) + screen = d->primaryScreen; + + return d->workrects->at(screen); } -const QRect QDesktopWidget::screenGeometry(int /* screen */) const +const QRect QDesktopWidget::screenGeometry(int screen) const { Q_D(const QDesktopWidget); - return QRect(0, 0, S60->screenWidthInPixels, S60->screenHeightInPixels); - } + if (screen < 0 || screen >= d->screenCount) + screen = d->primaryScreen; + + return d->rects->at(screen); +} int QDesktopWidget::screenNumber(const QWidget * /* widget */) const { diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 92eed33..bbc9e0b 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3627,7 +3627,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) \brief The QTouchEvent class contains parameters that describe a touch event. \since 4.6 \ingroup events - \ingroup multitouch + \ingroup touch \section1 Enabling Touch Events @@ -3641,7 +3641,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) Similarly to QMouseEvent, Qt automatically grabs each touch point on the first press inside a widget, and the widget will receive all updates for the touch point until it is released. - Note that it is possible for a widget to receive events for multiple touch points, and that + Note that it is possible for a widget to receive events for numerous touch points, and that multiple widgets may be receiving touch events at the same time. \section1 Event Handling @@ -3717,7 +3717,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) \i As mentioned above, enabling touch events means multiple widgets can be receiving touch events simultaneously. Combined with the default QWidget::event() handling for QTouchEvents, - this gives you great flexibility in designing multi-touch user interfaces. Be aware of the + this gives you great flexibility in designing touch user interfaces. Be aware of the implications. For example, it is possible that the user is moving a QSlider with one finger and pressing a QPushButton with another. The signals emitted by these widgets will be interleaved. @@ -3729,7 +3729,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) \i QTouchEvents are not affected by a \l{QWidget::grabMouse()}{mouse grab} or an \l{QApplication::activePopupWidget()}{active pop-up widget}. The behavior of QTouchEvents is - undefined when opening a pop-up or grabbing the mouse while there are multiple active touch + undefined when opening a pop-up or grabbing the mouse while there are more than one active touch points. \endlist diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index f5688f4..4a4452a 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -41,6 +41,7 @@ #include "qgesture.h" #include "private/qgesture_p.h" +#include "private/qstandardgestures_p.h" #ifndef QT_NO_GESTURES @@ -305,10 +306,10 @@ void QPanGesture::setAcceleration(qreal value) \class QPinchGesture \since 4.6 \brief The QPinchGesture class describes a pinch gesture made my the user. - \ingroup multitouch + \ingroup touch \ingroup gestures - A pinch gesture is a form of multitouch user input in which the user typically + A pinch gesture is a form of touch user input in which the user typically touches two points on the input device with a thumb and finger, before moving them closer together or further apart to change the scale factor, zoom, or level of detail of the user interface. @@ -388,7 +389,7 @@ void QPanGesture::setAcceleration(qreal value) \brief the current scale factor The scale factor measures the scale factor associated with the distance - between two of the user's inputs on a multitouch device. + between two of the user's inputs on a touch device. \sa totalScaleFactor, lastScaleFactor */ @@ -726,6 +727,34 @@ void QTapAndHoldGesture::setPosition(const QPointF &value) d_func()->position = value; } +/*! + Set the timeout, in milliseconds, before the gesture triggers. + + The recognizer will detect a touch down and and if \a msecs + later the touch is still down, it will trigger the QTapAndHoldGesture. + The default value is 700 milliseconds. +*/ +// static +void QTapAndHoldGesture::setTimeout(int msecs) +{ + QTapAndHoldGesturePrivate::Timeout = msecs; +} + +/*! + Gets the timeout, in milliseconds, before the gesture triggers. + + The recognizer will detect a touch down and and if timeout() + later the touch is still down, it will trigger the QTapAndHoldGesture. + The default value is 700 milliseconds. +*/ +// static +int QTapAndHoldGesture::timeout() +{ + return QTapAndHoldGesturePrivate::Timeout; +} + +int QTapAndHoldGesturePrivate::Timeout = 700; // in ms + QT_END_NAMESPACE #endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index 8c10895..dcb0264 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -134,6 +134,7 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture { Q_OBJECT Q_DECLARE_PRIVATE(QPinchGesture) + Q_FLAGS(ChangeFlags ChangeFlag) public: enum ChangeFlag { @@ -191,6 +192,8 @@ public: friend class QPinchGestureRecognizer; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QPinchGesture::ChangeFlags) + QT_END_NAMESPACE Q_DECLARE_METATYPE(QPinchGesture::ChangeFlags) @@ -252,6 +255,9 @@ public: QPointF position() const; void setPosition(const QPointF &pos); + static void setTimeout(int msecs); + static int timeout(); + friend class QTapAndHoldGestureRecognizer; }; diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index f5474c1..29b923e 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -177,6 +177,7 @@ public: QPointF position; int timerId; + static int Timeout; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index e43a560..fe9dd8a 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE QGestureManager::QGestureManager(QObject *parent) - : QObject(parent), state(NotGesture), m_lastCustomGestureId(0) + : QObject(parent), state(NotGesture), m_lastCustomGestureId(Qt::CustomGesture) { qRegisterMetaType<Qt::GestureState>(); @@ -119,7 +119,7 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r if (type == Qt::CustomGesture) { // generate a new custom gesture id ++m_lastCustomGestureId; - type = Qt::GestureType(Qt::CustomGesture + m_lastCustomGestureId); + type = Qt::GestureType(m_lastCustomGestureId); } m_recognizers.insertMulti(type, recognizer); delete dummy; diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/gui/kernel/qguifunctions_wince.cpp index f5004b0..377dfe3 100644 --- a/src/gui/kernel/qguifunctions_wince.cpp +++ b/src/gui/kernel/qguifunctions_wince.cpp @@ -76,6 +76,10 @@ struct AygSIPINFO #define SHIDIF_SIZEDLGFULLSCREEN 0x0004 #endif +#ifndef SHDB_HIDE +#define SHDB_HIDE 0x0002 +#endif + #ifndef SHFS_SHOWTASKBAR #define SHFS_SHOWTASKBAR 0x0001 #endif @@ -112,10 +116,12 @@ struct AygSIPINFO typedef BOOL (*AygInitDialog)(AygSHINITDLGINFO*); typedef BOOL (*AygFullScreen)(HWND, DWORD); typedef BOOL (*AygSHSipInfo)(UINT, UINT, PVOID, UINT); +typedef BOOL (*AygSHDoneButton)(HWND, DWORD); static AygInitDialog ptrAygInitDialog = 0; static AygFullScreen ptrAygFullScreen = 0; static AygSHSipInfo ptrAygSHSipInfo = 0; +static AygSHDoneButton ptrAygSHDoneButton = 0; static bool aygResolved = false; static void resolveAygLibs() @@ -128,18 +134,10 @@ static void resolveAygLibs() ptrAygInitDialog = (AygInitDialog) ayglib.resolve("SHInitDialog"); ptrAygFullScreen = (AygFullScreen) ayglib.resolve("SHFullScreen"); ptrAygSHSipInfo = (AygSHSipInfo) ayglib.resolve("SHSipInfo"); + ptrAygSHDoneButton = (AygSHDoneButton) ayglib.resolve("SHDoneButton"); } } -struct DIBINFO : public BITMAPINFO -{ - RGBQUAD arColors[255]; - - operator LPBITMAPINFO() { return (LPBITMAPINFO) this; } - operator LPBITMAPINFOHEADER() { return &bmiHeader; } - RGBQUAD* ColorTable() { return bmiColors; } -}; - int qt_wince_GetDIBits(HDC /*hdc*/ , HBITMAP hSourceBitmap, uint, uint, LPVOID lpvBits, LPBITMAPINFO, uint) { if (!lpvBits) { @@ -323,6 +321,8 @@ void qt_wince_maximize(QWidget *widget) shidi.dwFlags |= SHIDIF_CANCELBUTTON; if (widget->windowFlags() & Qt::WindowOkButtonHint) shidi.dwFlags |= SHIDIF_DONEBUTTON; + if (!(widget->windowFlags() & (Qt::WindowCancelButtonHint | Qt::WindowOkButtonHint))) + shidi.dwFlags |= SHIDIF_CANCELBUTTON; resolveAygLibs(); if (ptrAygInitDialog) ptrAygInitDialog(&shidi); @@ -334,6 +334,16 @@ void qt_wince_maximize(QWidget *widget) } } +void qt_wince_unmaximize(QWidget *widget) +{ + if (ptrAygSHDoneButton && qt_wince_is_mobile() + && !(widget->windowFlags() & (Qt::WindowCancelButtonHint | Qt::WindowOkButtonHint))) + { + // Hide the [X] button, we've added in qt_wince_maximize. + ptrAygSHDoneButton(widget->winId(), SHDB_HIDE); + } +} + void qt_wince_minimize(HWND hwnd) { #ifdef Q_OS_WINCE_WM diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index 98e8f66..38ec806 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -868,11 +868,21 @@ void QPalette::detach() Returns true (slowly) if this palette is different from \a p; otherwise returns false (usually quickly). + + \note The current ColorGroup is not taken into account when + comparing palettes + + \sa operator== */ /*! Returns true (usually quickly) if this palette is equal to \a p; otherwise returns false (slowly). + + \note The current ColorGroup is not taken into account when + comparing palettes + + \sa operator!= */ bool QPalette::operator==(const QPalette &p) const { diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 62d8a53..127e150 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -515,34 +515,39 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object, const QTouchEvent *ev = static_cast<const QTouchEvent *>(event); const QMouseEvent *me = static_cast<const QMouseEvent *>(event); +#ifndef QT_NO_GRAPHICSVIEW const QGraphicsSceneMouseEvent *gsme = static_cast<const QGraphicsSceneMouseEvent *>(event); +#endif - enum { TimerInterval = 2000 }; enum { TapRadius = 40 }; switch (event->type()) { +#ifndef QT_NO_GRAPHICSVIEW case QEvent::GraphicsSceneMousePress: d->position = gsme->screenPos(); q->setHotSpot(d->position); if (d->timerId) q->killTimer(d->timerId); - d->timerId = q->startTimer(TimerInterval); + d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout); return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout +#endif case QEvent::MouseButtonPress: d->position = me->globalPos(); q->setHotSpot(d->position); if (d->timerId) q->killTimer(d->timerId); - d->timerId = q->startTimer(TimerInterval); + d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout); return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout case QEvent::TouchBegin: d->position = ev->touchPoints().at(0).startScreenPos(); q->setHotSpot(d->position); if (d->timerId) q->killTimer(d->timerId); - d->timerId = q->startTimer(TimerInterval); + d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout); return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout +#ifndef QT_NO_GRAPHICSVIEW case QEvent::GraphicsSceneMouseRelease: +#endif case QEvent::MouseButtonRelease: case QEvent::TouchEnd: return QGestureRecognizer::CancelGesture; // get out of the MayBeGesture state @@ -560,12 +565,14 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object, return QGestureRecognizer::MayBeGesture; return QGestureRecognizer::CancelGesture; } +#ifndef QT_NO_GRAPHICSVIEW case QEvent::GraphicsSceneMouseMove: { QPoint delta = gsme->screenPos() - d->position.toPoint(); if (d->timerId && delta.manhattanLength() <= TapRadius) return QGestureRecognizer::MayBeGesture; return QGestureRecognizer::CancelGesture; } +#endif default: return QGestureRecognizer::Ignore; } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index d8ef67d..7f0c99e 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -143,6 +143,14 @@ public: int menuBeingConstructed : 1; int memoryLimitForHwRendering; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type + + enum ScanCodeState { + Unpressed, + KeyDown, + KeyDownAndKey + }; + QHash<TInt, ScanCodeState> scanCodeStates; + static inline void updateScreenSize(); inline RWsSession& wsSession(); static inline RWindowGroup& windowGroup(); @@ -155,6 +163,7 @@ public: static inline CAknTitlePane* titlePane(); static inline CAknContextPane* contextPane(); static inline CEikButtonGroupContainer* buttonGroupContainer(); + static void setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible); #endif #ifdef Q_OS_SYMBIAN @@ -223,7 +232,9 @@ protected: private: void HandlePointerEvent(const TPointerEvent& aPointerEvent); TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType); + TKeyResponse sendSymbianKeyEvent(const TKeyEvent &keyEvent, QEvent::Type type); TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent); + TKeyResponse handleVirtualMouse(const TKeyEvent& keyEvent,TEventCode type); bool sendMouseEvent(QWidget *widget, QMouseEvent *mEvent); void sendMouseEvent( QWidget *receiver, @@ -236,6 +247,8 @@ private: #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); #endif + +public: void handleClientAreaChange(); private: diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index c236c60..9946d5d 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -343,8 +343,10 @@ QInputContext *QWidgetPrivate::inputContext() const #ifndef QT_NO_IM if (ic) return ic; -#endif return qApp->inputContext(); +#else + return 0; +#endif } /*! @@ -12071,8 +12073,8 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) { Q_D(QWidget); if (d->gestureContext.remove(gesture)) { - QGestureManager *manager = QGestureManager::instance(); - manager->cleanupCachedGestures(this, gesture); + if (QGestureManager *manager = QGestureManager::instance()) + manager->cleanupCachedGestures(this, gesture); } } #endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index e57ec77..8ae6a99 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -1599,12 +1599,14 @@ void QWidgetPrivate::toggleDrawers(bool visible) continue; QWidget *widget = static_cast<QWidget*>(object); if(qt_mac_is_macdrawer(widget)) { + bool oldState = widget->testAttribute(Qt::WA_WState_ExplicitShowHide); if(visible) { if (!widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) widget->show(); } else { widget->hide(); - widget->setAttribute(Qt::WA_WState_ExplicitShowHide, false); + if(!oldState) + widget->setAttribute(Qt::WA_WState_ExplicitShowHide, false); } } } @@ -4389,6 +4391,13 @@ void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isM data.window_state = data.window_state & ~Qt::WindowMaximized; const bool visible = q->isVisible(); + // Apply size restrictions, applicable for Windows & Widgets. + if (QWExtra *extra = extraData()) { + w = qMin(w, extra->maxw); + h = qMin(h, extra->maxh); + w = qMax(w, extra->minw); + h = qMax(h, extra->minh); + } data.crect = QRect(x, y, w, h); if (realWindow) { diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 2818d88..56349ad 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -1113,15 +1113,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate) // The window decoration visibility has to be changed before doing actual window state // change since in that order the availableGeometry will return directly the right size and // we will avoid unnecessarty redraws - CEikStatusPane *statusPane = S60->statusPane(); - CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer(); - TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); - if (statusPane) - statusPane->MakeVisible(visible); - if (buttonGroup) { - // Visibility - buttonGroup->MakeVisible(visible || (isFullscreen && cbaRequested)); - } + const bool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool statusPaneVisibility = visible; + const bool buttonGroupVisibility = (visible || (isFullscreen && cbaRequested)); + S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); #endif // Q_WS_S60 // Ensure the initial size is valid, since we store it as normalGeometry below. @@ -1133,8 +1128,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate) const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint; if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint) { + setAttribute(Qt::WA_OutsideWSRange, false); window->SetExtentToWholeScreen(); } else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint)) { + setAttribute(Qt::WA_OutsideWSRange, false); TRect maxExtent = qt_QRect2TRect(qApp->desktop()->availableGeometry(this)); window->SetExtent(maxExtent.iTl, maxExtent.Size()); } else { @@ -1143,7 +1140,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) // accurate because it did not consider the status pane. This means that when returning // normal mode after showing the status pane, the geometry would overlap so we should // move it if it never had an explicit position. - if (!wasMoved && statusPane && visible) { + if (!wasMoved && S60->statusPane() && visible) { TPoint tl = static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl; normalGeometry.setTopLeft(QPoint(tl.iX, tl.iY)); } diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 0f05c6b..23f57da 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -70,6 +70,7 @@ #include "qguifunctions_wince.h" QT_USE_NAMESPACE extern void qt_wince_maximize(QWidget *widget); //defined in qguifunctions_wince.cpp +extern void qt_wince_unmaximize(QWidget *widget); //defined in qguifunctions_wince.cpp extern void qt_wince_minimize(HWND hwnd); //defined in qguifunctions_wince.cpp extern void qt_wince_full_screen(HWND hwnd, bool fullScreen, UINT swpf); //defined in qguifunctions_wince.cpp extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp index fc1e52c..76532ed 100644 --- a/src/gui/kernel/qwidget_wince.cpp +++ b/src/gui/kernel/qwidget_wince.cpp @@ -498,6 +498,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) int style = GetWindowLong(internalWinId(), GWL_STYLE) | WS_BORDER | WS_POPUP | WS_CAPTION; SetWindowLong(internalWinId(), GWL_STYLE, style); SetWindowLong(internalWinId(), GWL_EXSTYLE, GetWindowLong (internalWinId(), GWL_EXSTYLE) & ~ WS_EX_NODRAG); + qt_wince_unmaximize(this); } if (isVisible() && newstate & Qt::WindowMaximized) qt_wince_maximize(this); |