summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qapplication_s60.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qapplication_s60.cpp')
-rw-r--r--src/gui/kernel/qapplication_s60.cpp132
1 files changed, 101 insertions, 31 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 1bbf332..220b222 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -63,10 +63,13 @@
#include "apgwgnam.h" // For CApaWindowGroupName
#include <MdaAudioTonePlayer.h> // For CMdaAudioToneUtility
-#if !defined(QT_NO_IM) && defined(Q_WS_S60)
-#include "qinputcontext.h"
-#include <private/qcoefepinputcontext_p.h>
-#endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
+#if defined(Q_WS_S60)
+# if !defined(QT_NO_IM)
+# include "qinputcontext.h"
+# include <private/qcoefepinputcontext_p.h>
+# endif
+# include <private/qs60mainapplication_p.h>
+#endif
#include "private/qstylesheetstyle_p.h"
@@ -347,21 +350,21 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons
QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons | Qt::RightButton;
QMouseEvent mEvent(QEvent::MouseButtonPress, alienWidget->mapFrom(qwidget, widgetPos), globalPos,
Qt::RightButton, QApplicationPrivate::mouse_buttons, Qt::NoModifier);
-
+
bool res = sendMouseEvent(alienWidget, &mEvent);
#if !defined(QT_NO_CONTEXTMENU)
QContextMenuEvent contextMenuEvent(QContextMenuEvent::Mouse, widgetPos, globalPos, mEvent.modifiers());
qt_sendSpontaneousEvent(alienWidget, &contextMenuEvent);
-#endif
-
+#endif
+
m_previousEventLongTap = true;
}
void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
{
m_longTapDetector->PointerEventL(pEvent);
- QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent));
+ QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent));
}
void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
@@ -396,15 +399,6 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
if (!alienWidget)
alienWidget = qwidget;
S60->mousePressTarget = alienWidget;
- //pointer grab
- SetGloballyCapturing(ETrue);
- SetPointerCapture(ETrue);
- }
- else if (type == QEvent::MouseButtonRelease)
- {
- //release pointer grab
- SetGloballyCapturing(EFalse);
- SetPointerCapture(EFalse);
}
alienWidget = S60->mousePressTarget;
@@ -724,6 +718,22 @@ TTypeUid::Ptr QSymbianControl::MopSupplyObject(TTypeUid id)
void qt_init(QApplicationPrivate * /* priv */, int)
{
+ if (!CCoeEnv::Static()) {
+ // The S60 framework has not been initalized. We need to do it.
+ TApaApplicationFactory factory(NewApplication);
+ CApaCommandLine* commandLine = 0;
+ TInt err = CApaCommandLine::GetCommandLineFromProcessEnvironment(commandLine);
+ // After this construction, CEikonEnv will be available from CEikonEnv::Static().
+ // (much like our qApp).
+ CEikonEnv* coe = new CEikonEnv;
+ QT_TRAP_THROWING(coe->ConstructAppFromCommandLineL(factory,*commandLine));
+ delete commandLine;
+
+ S60->qtOwnsS60Environment = true;
+ } else {
+ S60->qtOwnsS60Environment = false;
+ }
+
#ifdef QT_NO_DEBUG
if (!qgetenv("QT_S60_AUTO_FLUSH_WSERV").isEmpty())
#endif
@@ -775,6 +785,13 @@ void qt_cleanup()
// it dies.
delete QApplicationPrivate::inputContext;
QApplicationPrivate::inputContext = 0;
+
+ if (S60->qtOwnsS60Environment) {
+ CEikonEnv* coe = CEikonEnv::Static();
+ coe->PrepareToExit();
+ // The CEikonEnv itself is destroyed in here.
+ coe->DestroyEnvironment();
+ }
}
void QApplicationPrivate::initializeWidgetPaletteHash()
@@ -801,14 +818,27 @@ bool QApplicationPrivate::modalState()
void QApplicationPrivate::enterModal_sys(QWidget *widget)
{
+ if (widget) {
+ widget->effectiveWinId()->DrawableWindow()->FadeBehind(ETrue);
+ // Modal partial screen dialogs (like queries) capture pointer events.
+ // ### FixMe: Add specialized behaviour for fullscreen modal dialogs
+ widget->effectiveWinId()->SetGloballyCapturing(ETrue);
+ widget->effectiveWinId()->SetPointerCapture(ETrue);
+ }
if (!qt_modal_stack)
qt_modal_stack = new QWidgetList;
qt_modal_stack->insert(0, widget);
- app_do_modal = true;
+ app_do_modal = true;
}
void QApplicationPrivate::leaveModal_sys(QWidget *widget)
{
+ if (widget) {
+ widget->effectiveWinId()->DrawableWindow()->FadeBehind(EFalse);
+ // ### FixMe: Add specialized behaviour for fullscreen modal dialogs
+ widget->effectiveWinId()->SetGloballyCapturing(EFalse);
+ widget->effectiveWinId()->SetPointerCapture(EFalse);
+ }
if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
if (qt_modal_stack->isEmpty()) {
delete qt_modal_stack;
@@ -824,18 +854,31 @@ void QApplicationPrivate::openPopup(QWidget *popup)
QApplicationPrivate::popupWidgets = new QWidgetList;
QApplicationPrivate::popupWidgets->append(popup);
- if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()) {
+
+ // Cancel focus widget pointer capture and long tap timer
+ if (QApplication::focusWidget()) {
+ static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer();
+ QApplication::focusWidget()->effectiveWinId()->SetPointerCapture(false);
+ }
+
+ if (!qt_nograb()) {
+ // Cancel pointer capture and long tap timer for earlier popup
+ int popupCount = QApplicationPrivate::popupWidgets->count();
+ if (popupCount > 1) {
+ QWidget* prevPopup = QApplicationPrivate::popupWidgets->at(popupCount-2);
+ static_cast<QSymbianControl*>(prevPopup->effectiveWinId())->CancelLongTapTimer();
+ prevPopup->effectiveWinId()->SetPointerCapture(false);
+ }
+
+ // Enable pointer capture for this (topmost) popup
Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
WId id = popup->effectiveWinId();
id->SetPointerCapture(true);
- id->SetGloballyCapturing(true);
}
// popups are not focus-handled by the window system (the first
// popup grabbed the keyboard), so we have to do that manually: A
// new popup gets the focus
- if (QApplication::focusWidget())
- static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer();
QWidget *fw = popup->focusWidget();
if (fw) {
fw->setFocus(Qt::PopupFocusReason);
@@ -854,14 +897,16 @@ void QApplicationPrivate::closePopup(QWidget *popup)
return;
QApplicationPrivate::popupWidgets->removeAll(popup);
+ // Cancel pointer capture and long tap for this popup
+ WId id = popup->effectiveWinId();
+ id->SetPointerCapture(false);
+ static_cast<QSymbianControl*>(id)->CancelLongTapTimer();
+
if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
delete QApplicationPrivate::popupWidgets;
QApplicationPrivate::popupWidgets = 0;
if (!qt_nograb()) { // grabbing not disabled
Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
- WId id = popup->effectiveWinId();
- id->SetPointerCapture(false);
- id->SetGloballyCapturing(false);
if (QWidgetPrivate::mouseGrabber != 0)
QWidgetPrivate::mouseGrabber->grabMouse();
@@ -880,6 +925,7 @@ void QApplicationPrivate::closePopup(QWidget *popup)
}
}
} else {
+
// popups are not focus-handled by the window system (the
// first popup grabbed the keyboard), so we have to do that
// manually: A popup was closed, so the previous popup gets
@@ -889,6 +935,11 @@ void QApplicationPrivate::closePopup(QWidget *popup)
QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
q_func()->sendEvent(fw, &e);
}
+
+ // Enable pointer capture for previous popup
+ if (aw) {
+ aw->effectiveWinId()->SetPointerCapture(true);
+ }
}
}
@@ -972,11 +1023,14 @@ void QApplication::beep()
beep=NULL;
}
-/*! \fn int QApplication::s60ProcessEvent(TWsEvent *event)
- This function does the core processing of individual s60
- \a{event}s. It returns 1 if the event was handled, 0 if
+/*!
+ \warning This function is only available on Symbian.
+
+ This function processes an individual Symbian window server
+ \a event. It returns 1 if the event was handled, 0 if
the \a event was not handled, and -1 if the event was
- not handled because the event handle was not in the map.
+ not handled because the event handle (\c{TWsEvent::Handle()})
+ is not known to Qt.
*/
int QApplication::s60ProcessEvent(TWsEvent *event)
{
@@ -1065,7 +1119,16 @@ int QApplication::s60ProcessEvent(TWsEvent *event)
}
/*!
- Returns false. Does nothing with the TWsEvent \a aEvent.
+ \warning This virtual function is only available on Symbian.
+
+ If you create an application that inherits QApplication and reimplement
+ this function, you get direct access to events that the are received
+ from the Symbian window server. The events are passed in the TWsEvent
+ \a aEvent parameter.
+
+ Return true if you want to stop the event from being processed. Return
+ false for normal event dispatching. The default implementation
+ false, and does nothing with \a aEvent.
*/
bool QApplication::s60EventFilter(TWsEvent * /* aEvent */)
{
@@ -1073,9 +1136,11 @@ bool QApplication::s60EventFilter(TWsEvent * /* aEvent */)
}
/*!
+ \warning This function is only available on Symbian.
+
Handles \a{command}s which are typically handled by
CAknAppUi::HandleCommandL(). Qts Ui integration into Symbian is
- partially achieved by deriving from CAknAppUi. Currently, exit,
+ partially achieved by deriving from CAknAppUi. Currently, exit,
menu and softkey commands are handled.
\sa s60EventFilter(), s60ProcessEvent()
@@ -1107,7 +1172,12 @@ void QApplication::symbianHandleCommand(int command)
}
/*!
+ \warning This function is only available on Symbian.
+
Handles the resource change specified by \a type.
+
+ Currently, KEikDynamicLayoutVariantSwitch and
+ KAknsMessageSkinChange are handled.
*/
void QApplication::symbianResourceChange(int type)
{