Bug 547261 - Improve focus handling on Qt. r=dougt
authorSteffen Imhof <steffen.imhof@googlemail.com>
Thu, 25 Feb 2010 10:58:19 -0800
changeset 38708 e0819ee45f5b3b74f17eebf9dd02d750235f8d4a
parent 38707 e75531fda63ec5edc1ab86727244ddbb03949556
child 38709 d38a004893a540fa7169201da019c7632895e18f
push id11812
push userdougt@mozilla.com
push dateThu, 25 Feb 2010 19:04:58 +0000
treeherderautoland@e0819ee45f5b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougt
bugs547261
milestone1.9.3a2pre
Bug 547261 - Improve focus handling on Qt. r=dougt
widget/src/qt/mozqwidget.cpp
widget/src/qt/mozqwidget.h
widget/src/qt/nsWindow.cpp
--- a/widget/src/qt/mozqwidget.cpp
+++ b/widget/src/qt/mozqwidget.cpp
@@ -13,32 +13,39 @@
 #include <QtCore/QEvent>
 #include <QtCore/QVariant>
 
 
 MozQWidget::MozQWidget(nsWindow* aReceiver, QGraphicsItem* aParent)
     : QGraphicsWidget(aParent),
       mReceiver(aReceiver)
 {
-    setFlag(QGraphicsItem::ItemIsFocusable);
-
-    setFocusPolicy(Qt::WheelFocus);
 }
 
 MozQWidget::~MozQWidget()
 {
     if (mReceiver)
         mReceiver->QWidgetDestroyed();
 }
 
 void MozQWidget::paint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption, QWidget* aWidget /*= 0*/)
 {
     mReceiver->DoPaint(aPainter, aOption);
 }
 
+void MozQWidget::activate()
+{
+    mReceiver->DispatchActivateEvent();
+}
+
+void MozQWidget::deactivate()
+{
+    mReceiver->DispatchDeactivateEvent();
+}
+
 void MozQWidget::resizeEvent(QGraphicsSceneResizeEvent* aEvent)
 {
     mReceiver->OnResizeEvent(aEvent);
 }
 
 void MozQWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent* aEvent)
 {
     mReceiver->contextMenuEvent(aEvent);
@@ -114,27 +121,16 @@ void MozQWidget::mousePressEvent(QGraphi
     mReceiver->OnButtonPressEvent(aEvent);
 }
 
 void MozQWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent* aEvent)
 {
     mReceiver->OnButtonReleaseEvent(aEvent);
 }
 
-bool MozQWidget::sceneEvent(QEvent* aEvent)
-{
-    if (QEvent::WindowActivate == aEvent->type()) {
-        mReceiver->OnFocusInEvent(aEvent);
-    } else if (QEvent::WindowDeactivate == aEvent->type()) {
-        mReceiver->OnFocusOutEvent(aEvent);
-    }
-
-    return QGraphicsWidget::sceneEvent(aEvent);
-}
-
 void MozQWidget::wheelEvent(QGraphicsSceneWheelEvent* aEvent)
 {
     mReceiver->OnScrollEvent(aEvent);
 }
 
 void MozQWidget::closeEvent(QCloseEvent* aEvent)
 {
     mReceiver->OnCloseEvent(aEvent);
--- a/widget/src/qt/mozqwidget.h
+++ b/widget/src/qt/mozqwidget.h
@@ -24,16 +24,19 @@ public:
     /**
      * Mozilla helper.
      */
     void setModal(bool);
     bool SetCursor(nsCursor aCursor);
     void dropReceiver() { mReceiver = 0x0; };
     nsWindow* getReceiver() { return mReceiver; };
 
+    void activate();
+    void deactivate();
+
 protected:
     virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* aEvent);
     virtual void dragEnterEvent(QGraphicsSceneDragDropEvent* aEvent);
     virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent* aEvent);
     virtual void dragMoveEvent(QGraphicsSceneDragDropEvent* aEvent);
     virtual void dropEvent(QGraphicsSceneDragDropEvent* aEvent);
     virtual void focusInEvent(QFocusEvent* aEvent);
     virtual void focusOutEvent(QFocusEvent* aEvent);
@@ -48,17 +51,16 @@ protected:
     virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* aEvent);
  
     virtual void wheelEvent(QGraphicsSceneWheelEvent* aEvent);
     virtual void paint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption, QWidget* aWidget = 0);
     virtual void resizeEvent(QGraphicsSceneResizeEvent* aEvent);
     virtual void closeEvent(QCloseEvent* aEvent);
     virtual void hideEvent(QHideEvent* aEvent);
     virtual void showEvent(QShowEvent* aEvent);
-    virtual bool sceneEvent(QEvent* aEvent);
  
     bool SetCursor(const QPixmap& aPixmap, int, int);
 
 private:
     nsWindow *mReceiver;
 };
 
 /**
@@ -77,16 +79,32 @@ public:
     { }
 
     void setTopLevel(MozQWidget* aTopLevel)
     {
         mTopLevelWidget = aTopLevel;
     }
 
 protected:
+
+    virtual bool event(QEvent* aEvent)
+    {
+        if (aEvent->type() == QEvent::WindowActivate) {
+            if (mTopLevelWidget)
+                mTopLevelWidget->activate();
+        }
+
+        if (aEvent->type() == QEvent::WindowDeactivate) {
+            if (mTopLevelWidget)
+                mTopLevelWidget->deactivate();
+        }
+
+        return QGraphicsView::event(aEvent);
+    }
+
     virtual void resizeEvent(QResizeEvent* aEvent)
     {
         if (mTopLevelWidget) {
             // transfer new size to graphics widget
             mTopLevelWidget->setGeometry( 0.0, 0.0,
                 static_cast<qreal>(aEvent->size().width()),
                 static_cast<qreal>(aEvent->size().height()));
         }
--- a/widget/src/qt/nsWindow.cpp
+++ b/widget/src/qt/nsWindow.cpp
@@ -571,18 +571,21 @@ nsWindow::SetFocus(PRBool aRaise)
     // invisible, we look up the chain, for the lowest visible
     // parent and focus that one
     QGraphicsItem* realFocusItem = nsnull;
     find_first_visible_parent(mWidget, realFocusItem);
 
     if (!realFocusItem || realFocusItem->hasFocus())
         return NS_OK;
 
-    if (aRaise)
+    if (aRaise) {
+        // the raising has to happen on the view widget
+        GetViewWidget()->raise();
         realFocusItem->setFocus(Qt::ActiveWindowFocusReason);
+    }
     else
         realFocusItem->setFocus(Qt::OtherFocusReason);
 
     DispatchActivateEvent();
 
     return NS_OK;
 }
 
@@ -1922,16 +1925,22 @@ nsWindow::createQWidget(MozQWidget *pare
         windowName = "paintArea";
         break;
     }
 
     MozQWidget * widget = new MozQWidget(this, parent);
     if (!widget)
         return nsnull;
 
+    // make only child and plugin windows focusable
+    if (eWindowType_child == mWindowType || eWindowType_plugin == mWindowType) {
+        widget->setFlag(QGraphicsItem::ItemIsFocusable);
+        widget->setFocusPolicy(Qt::WheelFocus);
+    }
+
     // create a QGraphicsView if this is a new toplevel window
     MozQGraphicsView* newView = 0;
 
     if (eWindowType_dialog == mWindowType ||
         eWindowType_toplevel == mWindowType)
     {
         mScene = new QGraphicsScene();
         if (!mScene) {