summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/kernel/qapplication_s60.cpp203
-rw-r--r--src/gui/kernel/qt_s60_p.h13
2 files changed, 138 insertions, 78 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index ea5c14c..fa07b1a 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -590,57 +590,12 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
case EEventKeyUp:
case EEventKey:
{
- // 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);
- }
-
#ifndef QT_NO_CURSOR
if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) {
//translate keys to pointer
- if (keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down || keyCode == Qt::Key_Select) {
- /*Explanation about virtualMouseAccel:
- Tapping an arrow key allows precise pixel positioning
- Holding an arrow key down, acceleration is applied to allow cursor
- to be quickly moved to another part of the screen by key repeats.
- */
- if (S60->virtualMouseLastKey == keyCode) {
- S60->virtualMouseAccel *= 2;
- if (S60->virtualMouseAccel > S60->virtualMouseMaxAccel)
- S60->virtualMouseAccel = S60->virtualMouseMaxAccel;
- }
- else
- S60->virtualMouseAccel = 1;
- S60->virtualMouseLastKey = keyCode;
-
+ 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);
@@ -648,54 +603,100 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
TInt x = pos.x();
TInt y = pos.y();
if (type == EEventKeyUp) {
- if (keyCode == Qt::Key_Select &&
- (S60->virtualMousePressedKeys & QS60Data::Select))
- fakeEvent.iType = TPointerEvent::EButton1Up;
- S60->virtualMouseAccel = 1;
- S60->virtualMouseLastKey = 0;
- switch (keyCode) {
- case Qt::Key_Left:
+ S60->virtualMouseAccelTimeout.start();
+ switch (keyEvent.iScanCode) {
+ case EStdKeyLeftArrow:
S60->virtualMousePressedKeys &= ~QS60Data::Left;
break;
- case Qt::Key_Right:
+ case EStdKeyRightArrow:
S60->virtualMousePressedKeys &= ~QS60Data::Right;
break;
- case Qt::Key_Up:
+ case EStdKeyUpArrow:
S60->virtualMousePressedKeys &= ~QS60Data::Up;
break;
- case Qt::Key_Down:
+ case EStdKeyDownArrow:
S60->virtualMousePressedKeys &= ~QS60Data::Down;
break;
- case Qt::Key_Select:
+ // 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) {
- if (keyCode != Qt::Key_Select)
+ int dx = 0;
+ int dy = 0;
+ if (keyEvent.iScanCode != EStdKeyDevice3) {
m_doubleClickTimer.invalidate();
- switch (keyCode) {
- case Qt::Key_Left:
+ //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();
+ }
+ switch (keyEvent.iScanCode) {
+ case EStdKeyLeftArrow:
S60->virtualMousePressedKeys |= QS60Data::Left;
- x -= S60->virtualMouseAccel;
+ dx = -1;
fakeEvent.iType = TPointerEvent::EMove;
break;
- case Qt::Key_Right:
+ case EStdKeyRightArrow:
S60->virtualMousePressedKeys |= QS60Data::Right;
- x += S60->virtualMouseAccel;
+ dx = 1;
fakeEvent.iType = TPointerEvent::EMove;
break;
- case Qt::Key_Up:
+ case EStdKeyUpArrow:
S60->virtualMousePressedKeys |= QS60Data::Up;
- y -= S60->virtualMouseAccel;
+ dy = -1;
fakeEvent.iType = TPointerEvent::EMove;
break;
- case Qt::Key_Down:
+ case EStdKeyDownArrow:
S60->virtualMousePressedKeys |= QS60Data::Down;
- y += S60->virtualMouseAccel;
+ dy = 1;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case EStdKeyDevice10:
+ S60->virtualMousePressedKeys |= QS60Data::LeftUp;
+ dx = -1;
+ dy = -1;
fakeEvent.iType = TPointerEvent::EMove;
break;
- case Qt::Key_Select:
+ 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
@@ -715,6 +716,32 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
}
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)
@@ -733,12 +760,40 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
HandlePointerEvent(fakeEvent);
return EKeyWasConsumed;
}
- else {
- S60->virtualMouseLastKey = keyCode;
- S60->virtualMouseAccel = 1;
- }
}
#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,
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 1af8eeb..f560458 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -103,16 +103,21 @@ public:
int defaultDpiX;
int defaultDpiY;
WId curWin;
- int virtualMouseLastKey;
enum PressedKeys {
Select = 0x1,
Right = 0x2,
Down = 0x4,
Left = 0x8,
- Up = 0x10
+ Up = 0x10,
+ LeftUp = 0x20,
+ RightUp = 0x40,
+ RightDown = 0x80,
+ LeftDown = 0x100
};
int virtualMousePressedKeys; // of the above type, but avoids casting problems
- int virtualMouseAccel;
+ int virtualMouseAccelDX;
+ int virtualMouseAccelDY;
+ QElapsedTimer virtualMouseAccelTimeout;
int virtualMouseMaxAccel;
#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
int brokenPointerCursors : 1;
@@ -248,7 +253,7 @@ inline void QS60Data::updateScreenSize()
S60->screenWidthInTwips = params.iTwipsSize.iWidth;
S60->screenHeightInTwips = params.iTwipsSize.iHeight;
- S60->virtualMouseMaxAccel = qMax(S60->screenHeightInPixels, S60->screenWidthInPixels) / 20;
+ S60->virtualMouseMaxAccel = qMax(S60->screenHeightInPixels, S60->screenWidthInPixels) / 10;
TReal inches = S60->screenHeightInTwips / (TReal)KTwipsPerInch;
S60->defaultDpiY = S60->screenHeightInPixels / inches;