Fix focus chain handling and cycling through focusable objects (links) using tab...
authorhausmann@webkit.org <hausmann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Jan 2008 10:40:53 +0000 (10:40 +0000)
committerhausmann@webkit.org <hausmann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Jan 2008 10:40:53 +0000 (10:40 +0000)
* Fix GraphicsContext::drawFocusRing to also draw single focus rects.
* Implemented QWebPage::focusNextPrevChild by sending fake tab/shift-tab events
  and make the return value depend on whether we successfully determined a focusable
  node or not.
* Changed QWebView::focusNextPrevChild() to call the base QWidget implementation correctly
  if we could not handle the focus chain ourselves.
* Changed the focus policy of QWebView to correctly use WheelFocus instead of ClickFocus.
* Made ChromeClientQt::canTakeFocus() and takeFocus() dummy method since they are only
  used to control the situation of stepping out of the focus chain inside the page.
* Made inclusion of links in the focus chain configurable through QWebSettings::LinksIncludedInFocusChain.
  The layout tests expect this to be disabled but for the user it seems sensible to have it
  on by default, hence the default in qwebsettings.cpp

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@29689 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/platform/graphics/qt/GraphicsContextQt.cpp
WebKit/qt/Api/qwebpage.cpp
WebKit/qt/Api/qwebsettings.cpp
WebKit/qt/Api/qwebsettings.h
WebKit/qt/Api/qwebview.cpp
WebKit/qt/ChangeLog
WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
WebKitTools/ChangeLog
WebKitTools/DumpRenderTree/qt/DumpRenderTree.cpp

index eb555b2..32b57b8 100644 (file)
@@ -2,6 +2,28 @@
 
         Reviewed by Holger.
 
+        Fix focus chain handling and cycling through focusable objects (links) using tab/backtab.
+        
+        * Fix GraphicsContext::drawFocusRing to also draw single focus rects.
+        * Implemented QWebPage::focusNextPrevChild by sending fake tab/shift-tab events
+        and make the return value depend on whether we successfully determined a focusable
+        node or not.
+        * Changed QWebView::focusNextPrevChild() to call the base QWidget implementation correctly
+        if we could not handle the focus chain ourselves.
+        * Changed the focus policy of QWebView to correctly use WheelFocus instead of ClickFocus.
+        * Made ChromeClientQt::canTakeFocus() and takeFocus() dummy method since they are only
+        used to control the situation of stepping out of the focus chain inside the page.
+        * Made inclusion of links in the focus chain configurable through QWebSettings::LinksIncludedInFocusChain.
+        The layout tests expect this to be disabled but for the user it seems sensible to have it
+        on by default, hence the default in qwebsettings.cpp
+
+        * platform/graphics/qt/GraphicsContextQt.cpp:
+        (WebCore::GraphicsContext::drawFocusRing):
+
+2008-01-21  Simon Hausmann  <hausmann@webkit.org>
+
+        Reviewed by Holger.
+
         Fix access key support and fast/forms/legend-access-key.html
 
         SVN revision 26664 changed the default access key for the non-mac build to Alt
index 314e09c..4dee681 100644 (file)
@@ -536,28 +536,32 @@ void GraphicsContext::drawFocusRing(const Color& color)
     const Vector<IntRect>& rects = focusRingRects();
     unsigned rectCount = rects.size();
 
-    if (rects.size() > 1)
-    {
-        QPainterPath path;
-        for (int i = 0; i < rectCount; ++i)
-            path.addRect(QRectF(rects[i]));
-        QPainter *p = m_data->p();
-        p->save();
-        QPen nPen = p->pen();
-        nPen.setColor(color);
-        p->setBrush(Qt::NoBrush);
-        nPen.setStyle(Qt::DotLine);
-        p->setPen(nPen);
+    if (rects.size() == 0)
+        return;
+
+    QPainterPath path;
+    for (int i = 0; i < rectCount; ++i)
+        path.addRect(QRectF(rects[i]));
+    QPainter *p = m_data->p();
+
+    const QPen oldPen = p->pen();
+    const QBrush oldBrush = p->brush();
+
+    QPen nPen = p->pen();
+    nPen.setColor(color);
+    p->setBrush(Qt::NoBrush);
+    nPen.setStyle(Qt::DotLine);
+    p->setPen(nPen);
 #if 0
-        // FIXME How do we do a bounding outline with Qt?
-        QPainterPathStroker stroker;
-        QPainterPath newPath = stroker.createStroke(path);
-        p->strokePath(newPath, nPen);
+    // FIXME How do we do a bounding outline with Qt?
+    QPainterPathStroker stroker;
+    QPainterPath newPath = stroker.createStroke(path);
+    p->strokePath(newPath, nPen);
 #else
-        p->drawRect(path.boundingRect());
+    p->drawRect(path.boundingRect());
 #endif
-        p->restore();
-    }
+    p->setPen(oldPen);
+    p->setBrush(oldBrush);
 }
 
 void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
index a8027ce..351c816 100644 (file)
@@ -1312,8 +1312,16 @@ bool QWebPage::event(QEvent *ev)
 */
 bool QWebPage::focusNextPrevChild(bool next)
 {
-    Q_UNUSED(next)
-    return false;
+    QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
+    d->keyPressEvent(&ev);
+    bool hasFocusedNode = false;
+    Frame *frame = d->page->focusController()->focusedFrame();
+    if (frame) {
+        Document *document = frame->document();
+        hasFocusedNode = document && document->focusedNode();
+    }
+    //qDebug() << "focusNextPrevChild(" << next << ") =" << ev.isAccepted() << "focusedNode?" << hasFocusedNode;
+    return hasFocusedNode;
 }
 
 /*!
index 9ff5df6..916c674 100644 (file)
@@ -179,6 +179,7 @@ QWebSettings::QWebSettings()
 
     d->attributes.insert(QWebSettings::AutoLoadImages, true);
     d->attributes.insert(QWebSettings::JavascriptEnabled, true);
+    d->attributes.insert(QWebSettings::LinksIncludedInFocusChain, true);
 }
 
 /*!
index 18ddcaa..c071e51 100644 (file)
@@ -57,7 +57,8 @@ public:
         PrivateBrowsingEnabled,
         JavascriptCanOpenWindows,
         JavascriptCanAccessClipboard,
-        DeveloperExtrasEnabled
+        DeveloperExtrasEnabled,
+        LinksIncludedInFocusChain
     };
     enum WebGraphic {
         MissingImageGraphic,
index 4d4a459..0aafe23 100644 (file)
@@ -55,7 +55,7 @@ QWebView::QWebView(QWidget *parent)
     setAcceptDrops(true);
 
     setMouseTracking(true);
-    setFocusPolicy(Qt::ClickFocus);
+    setFocusPolicy(Qt::WheelFocus);
 }
 
 /*!
@@ -544,8 +544,8 @@ void QWebView::dropEvent(QDropEvent* ev)
 */
 bool QWebView::focusNextPrevChild(bool next)
 {
-    if (d->page)
-        return d->page->focusNextPrevChild(next);
+    if (d->page && d->page->focusNextPrevChild(next))
+        return true;
     return QWidget::focusNextPrevChild(next);
 }
 
index 36941d4..b4d1ff1 100644 (file)
@@ -1,3 +1,35 @@
+2008-01-21  Simon Hausmann  <hausmann@webkit.org>
+
+        Reviewed by Holger.
+
+        Fix focus chain handling and cycling through focusable objects (links) using tab/backtab.
+        
+        * Fix GraphicsContext::drawFocusRing to also draw single focus rects.
+        * Implemented QWebPage::focusNextPrevChild by sending fake tab/shift-tab events
+        and make the return value depend on whether we successfully determined a focusable
+        node or not.
+        * Changed QWebView::focusNextPrevChild() to call the base QWidget implementation correctly
+        if we could not handle the focus chain ourselves.
+        * Changed the focus policy of QWebView to correctly use WheelFocus instead of ClickFocus.
+        * Made ChromeClientQt::canTakeFocus() and takeFocus() dummy method since they are only
+        used to control the situation of stepping out of the focus chain inside the page.
+        * Made inclusion of links in the focus chain configurable through QWebSettings::LinksIncludedInFocusChain.
+        The layout tests expect this to be disabled but for the user it seems sensible to have it
+        on by default, hence the default in qwebsettings.cpp
+        
+
+        * Api/qwebpage.cpp:
+        (QWebPage::focusNextPrevChild):
+        * Api/qwebsettings.cpp:
+        (QWebSettings::QWebSettings):
+        * Api/qwebsettings.h:
+        * Api/qwebview.cpp:
+        (QWebView::QWebView):
+        (QWebView::focusNextPrevChild):
+        * WebCoreSupport/ChromeClientQt.cpp:
+        (WebCore::ChromeClientQt::canTakeFocus):
+        (WebCore::ChromeClientQt::takeFocus):
+
 2008-01-18  Simon Hausmann  <hausmann@webkit.org>
 
         Reviewed by Holger.
index a408e92..9bfc7b1 100644 (file)
@@ -116,22 +116,18 @@ void ChromeClientQt::unfocus()
 
 bool ChromeClientQt::canTakeFocus(FocusDirection)
 {
-    if (!m_webPage)
-        return false;
-    QWidget* view = m_webPage->view();
-    if (!view)
-        return false;
-    return view->focusPolicy() != Qt::NoFocus;
+    // This is called when cycling through links/focusable objects and we
+    // reach the last focusable object. Then we want to claim that we can
+    // take the focus to avoid wrapping.
+    return true;
 }
 
 void ChromeClientQt::takeFocus(FocusDirection)
 {
-    if (!m_webPage)
-        return;
-    QWidget* view = m_webPage->view();
-    if (!view)
-        return;
-    view->clearFocus();
+    // don't do anything. This is only called when cycling to links/focusable objects,
+    // which in turn is called from focusNextPrevChild. We let focusNextPrevChild
+    // call QWidget::focusNextPrevChild accordingly, so there is no need to do anything
+    // here.
 }
 
 
@@ -289,7 +285,7 @@ bool ChromeClientQt::shouldInterruptJavaScript()
 
 bool ChromeClientQt::tabsToLinks() const
 {
-    return false;
+    return m_webPage->settings()->testAttribute(QWebSettings::LinksIncludedInFocusChain);
 }
 
 IntRect ChromeClientQt::windowResizerRect() const
index 6d8e04f..13595c8 100644 (file)
@@ -1,3 +1,26 @@
+2008-01-21  Simon Hausmann  <hausmann@webkit.org>
+
+        Reviewed by Holger.
+
+        Fix focus chain handling and cycling through focusable objects (links) using tab/backtab.
+        
+        * Fix GraphicsContext::drawFocusRing to also draw single focus rects.
+        * Implemented QWebPage::focusNextPrevChild by sending fake tab/shift-tab events
+        and make the return value depend on whether we successfully determined a focusable
+        node or not.
+        * Changed QWebView::focusNextPrevChild() to call the base QWidget implementation correctly
+        if we could not handle the focus chain ourselves.
+        * Changed the focus policy of QWebView to correctly use WheelFocus instead of ClickFocus.
+        * Made ChromeClientQt::canTakeFocus() and takeFocus() dummy method since they are only
+        used to control the situation of stepping out of the focus chain inside the page.
+        * Made inclusion of links in the focus chain configurable through QWebSettings::LinksIncludedInFocusChain.
+        The layout tests expect this to be disabled but for the user it seems sensible to have it
+        on by default, hence the default in qwebsettings.cpp
+        
+
+        * DumpRenderTree/qt/DumpRenderTree.cpp:
+        (WebCore::WebPage::WebPage):
+
 2008-01-19  Mark Rowe  <mrowe@apple.com>
 
         Reviewed by Alp Toker.
index 8c53c79..5df8a38 100644 (file)
@@ -84,6 +84,7 @@ WebPage::WebPage(QWidget *parent, DumpRenderTree *drt)
 {
     settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
     settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true);
+    settings()->setAttribute(QWebSettings::LinksIncludedInFocusChain, false);
     connect(this, SIGNAL(geometryChangeRequest(const QRect &)),
             this, SLOT(setViewGeometry(const QRect & )));
 }