[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

kocienda kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:59:52 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 5fc13d6ea3b957550590a73505a918004ccd6f59
Author: kocienda <kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Oct 7 22:23:57 2003 +0000

            Reviewed by Darin
    
    	Fix for these bugs:
    
    	<rdar://problem/3443296>: REGRESSION: pop-up menu gets focus, but once it has
    	focus doesn't work right
    	<rdar://problem/3444873>: Select widgets that use list views do not take part in tab order
    	<rdar://problem/3446306>: Text area form widgets do not accept DOM focus correctly
    	<rdar://problem/3446323>: Using keyboard to work popup button select form
    	widget causes a crash
    
    	The intention of this patch is to add keyboard navigation support for
    	HTML form select widgets. This includes the two visual representations
    	for these widgets: popup buttons and lists. Many keyboard, focus, and
    	tabbing fixes are included in this work, as indicated below.
    
            * khtml/html/html_formimpl.cpp:
            (HTMLSelectElementImpl::defaultEventHandler): Added. Submit form when
    	return or enter key is pressed when focused on a select widget.
            * khtml/html/html_formimpl.h: Make HTMLSelectElementImpl a friend class
    	of HTMLInputElementImpl. This is done so that an HTMLSelectElementImpl
    	can call the private method which simulates a form submit.
    	Also add declaration of defaultEventHandler function.
            * kwq/KWQButton.h: Clean up focusPolicy declaration.
            * kwq/KWQComboBox.h: Add focusPolicy declaration.
            * kwq/KWQComboBox.mm:
            (QComboBox::focusPolicy): Added. Widget will focus if full keyboard
    	access is on.
            (-[KWQPopUpButtonCell trackMouse:inRect:ofView:untilMouseUp:]): Now
    	calls sendFakeEventsAfterWidgetTracking instead of
    	doFakeMouseUpAfterWidgetTracking now that name has changed.
            (-[KWQPopUpButton becomeFirstResponder]): Added. Needed for setting
    	focus correctly.
            (-[KWQPopUpButton resignFirstResponder]): Ditto.
            (-[KWQPopUpButton nextKeyView]): Added. Makes tabbing work correctly
    	for this widget.
            (-[KWQPopUpButton previousKeyView]): Ditto.
            (-[KWQPopUpButton nextValidKeyView]): Ditto.
            (-[KWQPopUpButton previousValidKeyView]): Ditto.
            * kwq/KWQKHTMLPart.h: Change name of doFakeMouseUpAfterWidgetTracking
    	to sendFakeEventsAfterWidgetTracking now that it handles key events
    	as well.
            * kwq/KWQKHTMLPart.mm:
            (KWQKHTMLPart::sendFakeEventsAfterWidgetTracking): Name change as
    	noted above. Also handles sending simulated key up events.
            * kwq/KWQLineEdit.h:
            (QLineEdit::checksDescendantsForFocus): Added. This is a big
    	part of the fiz for <rdar://problem/3446306>.
            * kwq/KWQListBox.h:
            (QListBox::checksDescendantsForFocus): Ditto. Yes for this widget.
            * kwq/KWQListBox.mm:
            (QListBox::focusPolicy): Added. Widget will focus if full keyboard
            access is on.
            (-[KWQListBoxScrollView becomeFirstResponder]): Added. Needed for setting
            focus correctly. This sets the focus to its document view.
            (-[KWQTableView becomeFirstResponder]): Added. Needed for setting
            focus correctly.
            (-[KWQTableView resignFirstResponder]): Added. Needed for setting
            focus correctly.
            (-[KWQTableView nextKeyView]): Added. Makes tabbing work correctly
            for this widget.
            (-[KWQTableView previousKeyView]): Ditto.
            (-[KWQTableView nextValidKeyView]): Ditto.
            (-[KWQTableView previousValidKeyView]): Ditto.
            (-[KWQTableView _KWQ_setKeyboardFocusRingNeedsDisplay]): Added.
            * kwq/KWQTextArea.mm:
            (-[KWQTextAreaTextView becomeFirstResponder]): Other part of fix for
    	<rdar://problem/3446306>. The recursion guards were bad and wrong.
    	The checksDescendantsForFocus improvement prevents the erroneous
    	recursion from happening.
            * kwq/KWQTextEdit.h:
            (QTextEdit::checksDescendantsForFocus): Added. Yes for this widget.
            * kwq/KWQWidget.h:
            (QWidget::checksDescendantsForFocus): Added. No by default.
            * kwq/KWQWidget.mm:
            (QWidget::hasFocus): Now uses checksDescendantsForFocus to perform
    	proper checks for views that may have a subview which is first
    	responder.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@5145 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 5c187dc..ef4d6c2 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,84 @@
+2003-10-07  Ken Kocienda  <kocienda at apple.com>
+
+        Reviewed by Darin
+
+	Fix for these bugs:
+
+	<rdar://problem/3443296>: REGRESSION: pop-up menu gets focus, but once it has 	
+	focus doesn't work right
+	<rdar://problem/3444873>: Select widgets that use list views do not take part in tab order
+	<rdar://problem/3446306>: Text area form widgets do not accept DOM focus correctly
+	<rdar://problem/3446323>: Using keyboard to work popup button select form 
+	widget causes a crash
+
+	The intention of this patch is to add keyboard navigation support for
+	HTML form select widgets. This includes the two visual representations
+	for these widgets: popup buttons and lists. Many keyboard, focus, and
+	tabbing fixes are included in this work, as indicated below.
+
+        * khtml/html/html_formimpl.cpp:
+        (HTMLSelectElementImpl::defaultEventHandler): Added. Submit form when
+	return or enter key is pressed when focused on a select widget.
+        * khtml/html/html_formimpl.h: Make HTMLSelectElementImpl a friend class
+	of HTMLInputElementImpl. This is done so that an HTMLSelectElementImpl
+	can call the private method which simulates a form submit.
+	Also add declaration of defaultEventHandler function.
+        * kwq/KWQButton.h: Clean up focusPolicy declaration.
+        * kwq/KWQComboBox.h: Add focusPolicy declaration.
+        * kwq/KWQComboBox.mm:
+        (QComboBox::focusPolicy): Added. Widget will focus if full keyboard
+	access is on.
+        (-[KWQPopUpButtonCell trackMouse:inRect:ofView:untilMouseUp:]): Now
+	calls sendFakeEventsAfterWidgetTracking instead of 
+	doFakeMouseUpAfterWidgetTracking now that name has changed.
+        (-[KWQPopUpButton becomeFirstResponder]): Added. Needed for setting
+	focus correctly.
+        (-[KWQPopUpButton resignFirstResponder]): Ditto.
+        (-[KWQPopUpButton nextKeyView]): Added. Makes tabbing work correctly
+	for this widget.
+        (-[KWQPopUpButton previousKeyView]): Ditto.
+        (-[KWQPopUpButton nextValidKeyView]): Ditto.
+        (-[KWQPopUpButton previousValidKeyView]): Ditto.
+        * kwq/KWQKHTMLPart.h: Change name of doFakeMouseUpAfterWidgetTracking
+	to sendFakeEventsAfterWidgetTracking now that it handles key events
+	as well.
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::sendFakeEventsAfterWidgetTracking): Name change as
+	noted above. Also handles sending simulated key up events.
+        * kwq/KWQLineEdit.h:
+        (QLineEdit::checksDescendantsForFocus): Added. This is a big
+	part of the fiz for <rdar://problem/3446306>.
+        * kwq/KWQListBox.h:
+        (QListBox::checksDescendantsForFocus): Ditto. Yes for this widget.
+        * kwq/KWQListBox.mm:
+        (QListBox::focusPolicy): Added. Widget will focus if full keyboard
+        access is on.
+        (-[KWQListBoxScrollView becomeFirstResponder]): Added. Needed for setting
+        focus correctly. This sets the focus to its document view.
+        (-[KWQTableView becomeFirstResponder]): Added. Needed for setting
+        focus correctly.
+        (-[KWQTableView resignFirstResponder]): Added. Needed for setting
+        focus correctly.
+        (-[KWQTableView nextKeyView]): Added. Makes tabbing work correctly
+        for this widget.
+        (-[KWQTableView previousKeyView]): Ditto.
+        (-[KWQTableView nextValidKeyView]): Ditto.
+        (-[KWQTableView previousValidKeyView]): Ditto.
+        (-[KWQTableView _KWQ_setKeyboardFocusRingNeedsDisplay]): Added.
+        * kwq/KWQTextArea.mm:
+        (-[KWQTextAreaTextView becomeFirstResponder]): Other part of fix for
+	<rdar://problem/3446306>. The recursion guards were bad and wrong.
+	The checksDescendantsForFocus improvement prevents the erroneous
+	recursion from happening.
+        * kwq/KWQTextEdit.h:
+        (QTextEdit::checksDescendantsForFocus): Added. Yes for this widget.
+        * kwq/KWQWidget.h:
+        (QWidget::checksDescendantsForFocus): Added. No by default.
+        * kwq/KWQWidget.mm:
+        (QWidget::hasFocus): Now uses checksDescendantsForFocus to perform
+	proper checks for views that may have a subview which is first
+	responder.
+
 2003-10-07  David Hyatt  <hyatt at apple.com>
 
 	Fix for 3363421, event handlers could be triggered for content outside an overflow:hidden
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 5c187dc..ef4d6c2 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,84 @@
+2003-10-07  Ken Kocienda  <kocienda at apple.com>
+
+        Reviewed by Darin
+
+	Fix for these bugs:
+
+	<rdar://problem/3443296>: REGRESSION: pop-up menu gets focus, but once it has 	
+	focus doesn't work right
+	<rdar://problem/3444873>: Select widgets that use list views do not take part in tab order
+	<rdar://problem/3446306>: Text area form widgets do not accept DOM focus correctly
+	<rdar://problem/3446323>: Using keyboard to work popup button select form 
+	widget causes a crash
+
+	The intention of this patch is to add keyboard navigation support for
+	HTML form select widgets. This includes the two visual representations
+	for these widgets: popup buttons and lists. Many keyboard, focus, and
+	tabbing fixes are included in this work, as indicated below.
+
+        * khtml/html/html_formimpl.cpp:
+        (HTMLSelectElementImpl::defaultEventHandler): Added. Submit form when
+	return or enter key is pressed when focused on a select widget.
+        * khtml/html/html_formimpl.h: Make HTMLSelectElementImpl a friend class
+	of HTMLInputElementImpl. This is done so that an HTMLSelectElementImpl
+	can call the private method which simulates a form submit.
+	Also add declaration of defaultEventHandler function.
+        * kwq/KWQButton.h: Clean up focusPolicy declaration.
+        * kwq/KWQComboBox.h: Add focusPolicy declaration.
+        * kwq/KWQComboBox.mm:
+        (QComboBox::focusPolicy): Added. Widget will focus if full keyboard
+	access is on.
+        (-[KWQPopUpButtonCell trackMouse:inRect:ofView:untilMouseUp:]): Now
+	calls sendFakeEventsAfterWidgetTracking instead of 
+	doFakeMouseUpAfterWidgetTracking now that name has changed.
+        (-[KWQPopUpButton becomeFirstResponder]): Added. Needed for setting
+	focus correctly.
+        (-[KWQPopUpButton resignFirstResponder]): Ditto.
+        (-[KWQPopUpButton nextKeyView]): Added. Makes tabbing work correctly
+	for this widget.
+        (-[KWQPopUpButton previousKeyView]): Ditto.
+        (-[KWQPopUpButton nextValidKeyView]): Ditto.
+        (-[KWQPopUpButton previousValidKeyView]): Ditto.
+        * kwq/KWQKHTMLPart.h: Change name of doFakeMouseUpAfterWidgetTracking
+	to sendFakeEventsAfterWidgetTracking now that it handles key events
+	as well.
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::sendFakeEventsAfterWidgetTracking): Name change as
+	noted above. Also handles sending simulated key up events.
+        * kwq/KWQLineEdit.h:
+        (QLineEdit::checksDescendantsForFocus): Added. This is a big
+	part of the fiz for <rdar://problem/3446306>.
+        * kwq/KWQListBox.h:
+        (QListBox::checksDescendantsForFocus): Ditto. Yes for this widget.
+        * kwq/KWQListBox.mm:
+        (QListBox::focusPolicy): Added. Widget will focus if full keyboard
+        access is on.
+        (-[KWQListBoxScrollView becomeFirstResponder]): Added. Needed for setting
+        focus correctly. This sets the focus to its document view.
+        (-[KWQTableView becomeFirstResponder]): Added. Needed for setting
+        focus correctly.
+        (-[KWQTableView resignFirstResponder]): Added. Needed for setting
+        focus correctly.
+        (-[KWQTableView nextKeyView]): Added. Makes tabbing work correctly
+        for this widget.
+        (-[KWQTableView previousKeyView]): Ditto.
+        (-[KWQTableView nextValidKeyView]): Ditto.
+        (-[KWQTableView previousValidKeyView]): Ditto.
+        (-[KWQTableView _KWQ_setKeyboardFocusRingNeedsDisplay]): Added.
+        * kwq/KWQTextArea.mm:
+        (-[KWQTextAreaTextView becomeFirstResponder]): Other part of fix for
+	<rdar://problem/3446306>. The recursion guards were bad and wrong.
+	The checksDescendantsForFocus improvement prevents the erroneous
+	recursion from happening.
+        * kwq/KWQTextEdit.h:
+        (QTextEdit::checksDescendantsForFocus): Added. Yes for this widget.
+        * kwq/KWQWidget.h:
+        (QWidget::checksDescendantsForFocus): Added. No by default.
+        * kwq/KWQWidget.mm:
+        (QWidget::hasFocus): Now uses checksDescendantsForFocus to perform
+	proper checks for views that may have a subview which is first
+	responder.
+
 2003-10-07  David Hyatt  <hyatt at apple.com>
 
 	Fix for 3363421, event handlers could be triggered for content outside an overflow:hidden
diff --git a/WebCore/khtml/html/html_formimpl.cpp b/WebCore/khtml/html/html_formimpl.cpp
index 3f76c43..31e42b8 100644
--- a/WebCore/khtml/html/html_formimpl.cpp
+++ b/WebCore/khtml/html/html_formimpl.cpp
@@ -2269,6 +2269,35 @@ void HTMLSelectElementImpl::notifyOptionSelected(HTMLOptionElementImpl *selected
     setChanged(true);
 }
 
+#if APPLE_CHANGES
+void HTMLSelectElementImpl::defaultEventHandler(EventImpl *evt)
+{
+    // Use key press event here since sending simulated mouse events
+    // on key down blocks the proper sending of the key press event.
+    if (evt->id() == EventImpl::KHTML_KEYPRESS_EVENT) {
+    
+        if (!m_form || !m_render || !evt->isKeyboardEvent())
+            return;
+        
+        unsigned long keyVal = static_cast<KeyEventImpl *>(evt)->keyVal();
+        
+        if (keyVal == '\r' || keyVal == 0x3) {
+            QPtrListIterator<HTMLGenericFormElementImpl> it(m_form->formElements);
+            for (; it.current(); ++it) {
+                if (it.current()->id() == ID_INPUT) {
+                    HTMLInputElementImpl *element = static_cast<HTMLInputElementImpl *>(it.current());
+                    if (element->isSuccessfulSubmitButton()) {
+                        element->simulateButtonClickForEvent(evt);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    HTMLGenericFormElementImpl::defaultEventHandler(evt);
+}
+#endif
+
 // -------------------------------------------------------------------------
 
 HTMLKeygenElementImpl::HTMLKeygenElementImpl(DocumentPtr* doc, HTMLFormElementImpl* f)
diff --git a/WebCore/khtml/html/html_formimpl.h b/WebCore/khtml/html/html_formimpl.h
index 38a1308..bf57e80 100644
--- a/WebCore/khtml/html/html_formimpl.h
+++ b/WebCore/khtml/html/html_formimpl.h
@@ -248,6 +248,10 @@ class HTMLInputElementImpl : public HTMLGenericFormElementImpl
     friend class khtml::RenderRadioButton;
     friend class khtml::RenderFileButton;
 
+#if APPLE_CHANGES
+    friend class HTMLSelectElementImpl;
+#endif
+
 public:
     // do not change the order!
     enum typeEnum {
@@ -442,6 +446,10 @@ public:
     virtual void reset();
     void notifyOptionSelected(HTMLOptionElementImpl *selectedOption, bool selected);
 
+#if APPLE_CHANGES
+    virtual void defaultEventHandler(EventImpl *evt);
+#endif
+
 private:
     void recalcListItems();
 
diff --git a/WebCore/kwq/KWQButton.h b/WebCore/kwq/KWQButton.h
index 8309e5b..11c8d4f 100644
--- a/WebCore/kwq/KWQButton.h
+++ b/WebCore/kwq/KWQButton.h
@@ -44,7 +44,7 @@ public:
     // QWidget overrides
     virtual void setFont(const QFont &);
 
-    virtual QWidget::FocusPolicy QButton::focusPolicy() const;
+    virtual FocusPolicy focusPolicy() const;
 
 private:
     KWQSignal m_clicked;
diff --git a/WebCore/kwq/KWQButton.mm b/WebCore/kwq/KWQButton.mm
index 61ffa62..b0bb6b4 100644
--- a/WebCore/kwq/KWQButton.mm
+++ b/WebCore/kwq/KWQButton.mm
@@ -85,11 +85,11 @@
 {
     BOOL become = [super becomeFirstResponder];
     if (become) {
-        QFocusEvent event(QEvent::FocusIn);
-        const_cast<QObject *>(button->eventFilterObject())->eventFilter(button, &event);
         if (!KWQKHTMLPart::currentEventIsMouseDownInWidget(button)) {
             [self _KWQ_scrollFrameToVisible];
         }
+        QFocusEvent event(QEvent::FocusIn);
+        const_cast<QObject *>(button->eventFilterObject())->eventFilter(button, &event);
     }
     return become;
 }
diff --git a/WebCore/kwq/KWQComboBox.h b/WebCore/kwq/KWQComboBox.h
index 440e506..5da8159 100644
--- a/WebCore/kwq/KWQComboBox.h
+++ b/WebCore/kwq/KWQComboBox.h
@@ -57,6 +57,8 @@ public:
     void setFont(const QFont &);
 
     void itemSelected();
+    
+    virtual FocusPolicy focusPolicy() const;
 
 private:
     bool updateCurrentItem() const;
diff --git a/WebCore/kwq/KWQComboBox.mm b/WebCore/kwq/KWQComboBox.mm
index 7e89097..96ec7ae 100644
--- a/WebCore/kwq/KWQComboBox.mm
+++ b/WebCore/kwq/KWQComboBox.mm
@@ -28,6 +28,7 @@
 #import "KWQButton.h"
 #import "KWQView.h"
 #import "KWQKHTMLPart.h"
+#import "KWQNSViewExtras.h"
 #import "WebCoreBridge.h"
 
 #import "khtmlview.h"
@@ -61,6 +62,9 @@ enum {
 @end
 
 @interface KWQPopUpButton : NSPopUpButton <KWQWidgetHolder>
+{
+    BOOL inNextValidKeyView;
+}
 @end
 
 QComboBox::QComboBox()
@@ -222,6 +226,17 @@ const int *QComboBox::dimensions() const
     return w[[[button cell] controlSize]];
 }
 
+QWidget::FocusPolicy QComboBox::focusPolicy() const
+{
+    // Add an additional check here.
+    // For now, selects are only focused when full
+    // keyboard access is turned on.
+    if ([KWQKHTMLPart::bridgeForWidget(this) keyboardUIMode] != WebCoreFullKeyboardAccess)
+        return NoFocus;
+
+    return QWidget::focusPolicy();
+}
+
 @implementation KWQComboBoxAdapter
 
 - initWithQComboBox:(QComboBox *)b
@@ -274,7 +289,7 @@ const int *QComboBox::dimensions() const
         // Give khtml a chance to fix up its event state, since the popup eats all the
         // events during tracking.  [NSApp currentEvent] is still the original mouseDown
         // at this point!
-        [bridge part]->doFakeMouseUpAfterWidgetTracking(event);
+        [bridge part]->sendFakeEventsAfterWidgetTracking(event);
     }
     [bridge release];
     return result;
@@ -294,4 +309,61 @@ const int *QComboBox::dimensions() const
     return [(KWQPopUpButtonCell *)[self cell] widget];
 }
 
+- (BOOL)becomeFirstResponder
+{
+    BOOL become = [super becomeFirstResponder];
+    if (become) {
+        QWidget *widget = [self widget];
+        if (!KWQKHTMLPart::currentEventIsMouseDownInWidget(widget)) {
+            [self _KWQ_scrollFrameToVisible];
+        }
+        QFocusEvent event(QEvent::FocusIn);
+        const_cast<QObject *>(widget->eventFilterObject())->eventFilter(widget, &event);
+    }
+    return become;
+}
+
+- (BOOL)resignFirstResponder
+{
+    BOOL resign = [super resignFirstResponder];
+    if (resign) {
+        QWidget *widget = [self widget];
+        QFocusEvent event(QEvent::FocusOut);
+        const_cast<QObject *>(widget->eventFilterObject())->eventFilter(widget, &event);
+    }
+    return resign;
+}
+
+-(NSView *)nextKeyView
+{
+    QWidget *widget = [self widget];
+    return widget && inNextValidKeyView
+        ? KWQKHTMLPart::nextKeyViewForWidget(widget, KWQSelectingNext)
+        : [super nextKeyView];
+}
+
+-(NSView *)previousKeyView
+{
+    QWidget *widget = [self widget];
+    return widget && inNextValidKeyView
+        ? KWQKHTMLPart::nextKeyViewForWidget(widget, KWQSelectingPrevious)
+        : [super previousKeyView];
+}
+
+-(NSView *)nextValidKeyView
+{
+    inNextValidKeyView = YES;
+    NSView *view = [super nextValidKeyView];
+    inNextValidKeyView = NO;
+    return view;
+}
+
+-(NSView *)previousValidKeyView
+{
+    inNextValidKeyView = YES;
+    NSView *view = [super previousValidKeyView];
+    inNextValidKeyView = NO;
+    return view;
+}
+
 @end
diff --git a/WebCore/kwq/KWQKHTMLPart.h b/WebCore/kwq/KWQKHTMLPart.h
index c98d40e..c2c89f9 100644
--- a/WebCore/kwq/KWQKHTMLPart.h
+++ b/WebCore/kwq/KWQKHTMLPart.h
@@ -186,7 +186,7 @@ public:
     void mouseDown(NSEvent *);
     void mouseDragged(NSEvent *);
     void mouseUp(NSEvent *);
-    void doFakeMouseUpAfterWidgetTracking(NSEvent *downEvent);
+    void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
     void mouseMoved(NSEvent *);
     bool keyEvent(NSEvent *);
     bool lastEventIsMouseUp();
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index 395bad7..36e3cec 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -1800,33 +1800,53 @@ void KWQKHTMLPart::mouseUp(NSEvent *event)
 /*
  A hack for the benefit of AK's PopUpButton, which uses the Carbon menu manager, which thus
  eats all subsequent events after it is starts its modal tracking loop.  After the interaction
- is done, this routine is used to fix things up.  We post a fake mouse up to balance the
- mouse down we started with.  In addition, we post a fake mouseMoved to get the cursor in sync
- with whatever we happen to be over after the tracking is done.
+ is done, this routine is used to fix things up.  When a mouse down started us tracking in
+ the widget, we post a fake mouse up to balance the mouse down we started with. When a 
+ key down started us tracking in the widget, we post a fake key up to balance things out.
+ In addition, we post a fake mouseMoved to get the cursor in sync with whatever we happen to 
+ be over after the tracking is done.
  */
-void KWQKHTMLPart::doFakeMouseUpAfterWidgetTracking(NSEvent *downEvent)
+void KWQKHTMLPart::sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent)
 {
     _sendingEventToSubview = false;
-    ASSERT([downEvent type] == NSLeftMouseDown);
-    NSEvent *fakeEvent = [NSEvent mouseEventWithType:NSLeftMouseUp
-                                            location:[downEvent locationInWindow]
-                                       modifierFlags:[downEvent modifierFlags]
-                                           timestamp:[downEvent timestamp]
-                                        windowNumber:[downEvent windowNumber]
-                                             context:[downEvent context]
-                                         eventNumber:[downEvent eventNumber]
-                                          clickCount:[downEvent clickCount]
-                                            pressure:[downEvent pressure]];
-    mouseUp(fakeEvent);
+    int eventType = [initiatingEvent type];
+    ASSERT(eventType == NSLeftMouseDown || eventType == NSKeyDown);
+    NSEvent *fakeEvent = nil;
+    if (eventType == NSLeftMouseDown) {
+        fakeEvent = [NSEvent mouseEventWithType:NSLeftMouseUp
+                                location:[initiatingEvent locationInWindow]
+                            modifierFlags:[initiatingEvent modifierFlags]
+                                timestamp:[initiatingEvent timestamp]
+                            windowNumber:[initiatingEvent windowNumber]
+                                    context:[initiatingEvent context]
+                                eventNumber:[initiatingEvent eventNumber]
+                                clickCount:[initiatingEvent clickCount]
+                                pressure:[initiatingEvent pressure]];
+    
+        mouseUp(fakeEvent);
+    }
+    else { // eventType == NSKeyDown
+        fakeEvent = [NSEvent keyEventWithType:NSKeyUp
+                                location:[initiatingEvent locationInWindow]
+                           modifierFlags:[initiatingEvent modifierFlags]
+                               timestamp:[initiatingEvent timestamp]
+                            windowNumber:[initiatingEvent windowNumber]
+                                 context:[initiatingEvent context]
+                              characters:[initiatingEvent characters] 
+             charactersIgnoringModifiers:[initiatingEvent charactersIgnoringModifiers] 
+                               isARepeat:[initiatingEvent isARepeat] 
+                                 keyCode:[initiatingEvent keyCode]];
+        keyEvent(fakeEvent);
+    }
     // FIXME:  We should really get the current modifierFlags here, but there's no way to poll
     // them in Cocoa, and because the event stream was stolen by the Carbon menu code we have
     // no up-to-date cache of them anywhere.
     fakeEvent = [NSEvent mouseEventWithType:NSMouseMoved
                                    location:[[_bridge window] convertScreenToBase:[NSEvent mouseLocation]]
-                              modifierFlags:[downEvent modifierFlags]
-                                  timestamp:[downEvent timestamp]
-                               windowNumber:[downEvent windowNumber]
-                                    context:[downEvent context]
+                              modifierFlags:[initiatingEvent modifierFlags]
+                                  timestamp:[initiatingEvent timestamp]
+                               windowNumber:[initiatingEvent windowNumber]
+                                    context:[initiatingEvent context]
                                 eventNumber:0
                                  clickCount:0
                                    pressure:0];
diff --git a/WebCore/kwq/KWQLineEdit.h b/WebCore/kwq/KWQLineEdit.h
index 1c40547..977fd16 100644
--- a/WebCore/kwq/KWQLineEdit.h
+++ b/WebCore/kwq/KWQLineEdit.h
@@ -65,6 +65,9 @@ public:
     void textChanged() { m_textChanged.call(text()); }
 
     void clicked();
+    
+    virtual bool checksDescendantsForFocus() const;
+
 private:
     KWQSignal m_returnPressed;
     KWQSignal m_textChanged;
diff --git a/WebCore/kwq/KWQLineEdit.mm b/WebCore/kwq/KWQLineEdit.mm
index f069755..5e5983f 100644
--- a/WebCore/kwq/KWQLineEdit.mm
+++ b/WebCore/kwq/KWQLineEdit.mm
@@ -176,3 +176,8 @@ void QLineEdit::setAlignment(AlignmentFlags alignment)
     KWQTextField *textField = getView();
     [textField setAlignment:(alignment == AlignRight ? NSRightTextAlignment : NSLeftTextAlignment)];
 }
+
+bool QLineEdit::checksDescendantsForFocus() const
+{
+    return true;
+}
diff --git a/WebCore/kwq/KWQListBox.h b/WebCore/kwq/KWQListBox.h
index 1c2c27d..b7ab5a1 100644
--- a/WebCore/kwq/KWQListBox.h
+++ b/WebCore/kwq/KWQListBox.h
@@ -67,6 +67,9 @@ public:
     void clicked() { _clicked.call(); }
     void selectionChanged() { _selectionChanged.call(); }
 
+    virtual FocusPolicy focusPolicy() const;
+    virtual bool checksDescendantsForFocus() const;
+    
 private:
     void insertItem(NSObject *, unsigned index);
 
diff --git a/WebCore/kwq/KWQListBox.mm b/WebCore/kwq/KWQListBox.mm
index f8bfd05..3c15e3a 100644
--- a/WebCore/kwq/KWQListBox.mm
+++ b/WebCore/kwq/KWQListBox.mm
@@ -27,6 +27,7 @@
 
 #import "KWQAssertions.h"
 #import "KWQKHTMLPart.h"
+#import "KWQNSViewExtras.h"
 #import "KWQView.h"
 #import "WebCoreBridge.h"
 #import "WebCoreScrollView.h"
@@ -34,8 +35,6 @@
 #define MIN_LINES 4 /* ensures we have a scroll bar */
 
 @interface KWQListBoxScrollView : WebCoreScrollView
-{
-}
 @end
 
 @interface KWQTableView : NSTableView <KWQWidgetHolder>
@@ -44,8 +43,11 @@
     NSArray *_items;
     BOOL processingMouseEvent;
     BOOL clickedDuringMouseEvent;
+    BOOL inNextValidKeyView;
 }
 - initWithListBox:(QListBox *)b items:(NSArray *)items;
+-(void)_KWQ_setKeyboardFocusRingNeedsDisplay;
+- (QWidget *)widget;
 @end
 
 QListBox::QListBox(QWidget *parent)
@@ -238,6 +240,22 @@ QSize QListBox::sizeForNumberOfLines(int lines) const
     return QSize(size);
 }
 
+QWidget::FocusPolicy QListBox::focusPolicy() const
+{
+    // Add an additional check here.
+    // For now, selects are only focused when full
+    // keyboard access is turned on.
+    if ([KWQKHTMLPart::bridgeForWidget(this) keyboardUIMode] != WebCoreFullKeyboardAccess)
+        return NoFocus;
+
+    return QScrollView::focusPolicy();
+}
+
+bool QListBox::checksDescendantsForFocus() const
+{
+    return true;
+}
+
 @implementation KWQListBoxScrollView
 
 - (void)setFrameSize:(NSSize)size
@@ -249,6 +267,14 @@ QSize QListBox::sizeForNumberOfLines(int lines) const
     [column setMaxWidth:[self contentSize].width];
 }
 
+- (BOOL)becomeFirstResponder
+{
+    KWQTableView *documentView = [self documentView];
+    QWidget *widget = [documentView widget];
+    [KWQKHTMLPart::bridgeForWidget(widget) makeFirstResponder:documentView];
+    return YES;
+}
+
 @end
 
 @implementation KWQTableView
@@ -311,8 +337,12 @@ QSize QListBox::sizeForNumberOfLines(int lines) const
 - (BOOL)becomeFirstResponder
 {
     BOOL become = [super becomeFirstResponder];
-
+    
     if (become) {
+        if (!KWQKHTMLPart::currentEventIsMouseDownInWidget(_box)) {
+            [self _KWQ_scrollFrameToVisible];
+        }        
+	[self _KWQ_setKeyboardFocusRingNeedsDisplay];
 	QFocusEvent event(QEvent::FocusIn);
 	const_cast<QObject *>(_box->eventFilterObject())->eventFilter(_box, &event);
     }
@@ -320,6 +350,46 @@ QSize QListBox::sizeForNumberOfLines(int lines) const
     return become;
 }
 
+- (BOOL)resignFirstResponder
+{
+    BOOL resign = [super resignFirstResponder];
+    if (resign) {
+        QFocusEvent event(QEvent::FocusOut);
+        const_cast<QObject *>(_box->eventFilterObject())->eventFilter(_box, &event);
+    }
+    return resign;
+}
+
+-(NSView *)nextKeyView
+{
+    return _box && inNextValidKeyView
+        ? KWQKHTMLPart::nextKeyViewForWidget(_box, KWQSelectingNext)
+        : [super nextKeyView];
+}
+
+-(NSView *)previousKeyView
+{
+    return _box && inNextValidKeyView
+        ? KWQKHTMLPart::nextKeyViewForWidget(_box, KWQSelectingPrevious)
+        : [super previousKeyView];
+}
+
+-(NSView *)nextValidKeyView
+{
+    inNextValidKeyView = YES;
+    NSView *view = [super nextValidKeyView];
+    inNextValidKeyView = NO;
+    return view;
+}
+
+-(NSView *)previousValidKeyView
+{
+    inNextValidKeyView = YES;
+    NSView *view = [super previousValidKeyView];
+    inNextValidKeyView = NO;
+    return view;
+}
+
 - (int)numberOfRowsInTableView:(NSTableView *)tableView
 {
     return [_items count];
@@ -358,6 +428,11 @@ QSize QListBox::sizeForNumberOfLines(int lines) const
     [(NSCell *)cell setEnabled:_box->isEnabled()];
 }
 
+- (void)_KWQ_setKeyboardFocusRingNeedsDisplay
+{
+    [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]];
+}
+
 - (QWidget *)widget
 {
     return _box;
diff --git a/WebCore/kwq/KWQTextArea.mm b/WebCore/kwq/KWQTextArea.mm
index fa2e14b..7b13bf4 100644
--- a/WebCore/kwq/KWQTextArea.mm
+++ b/WebCore/kwq/KWQTextArea.mm
@@ -52,7 +52,6 @@
 @interface KWQTextAreaTextView : NSTextView <KWQWidgetHolder>
 {
     QTextEdit *widget;
-    BOOL inBecomeFirstResponder;
 }
 - (void)setWidget:(QTextEdit *)widget;
 @end
@@ -553,12 +552,7 @@ static NSString *WebContinuousSpellCheckingEnabled = @"WebContinuousSpellCheckin
 {
     BOOL become = [super becomeFirstResponder];
     
-    if (inBecomeFirstResponder) 
-        return become;
-
     if (become) {
-        inBecomeFirstResponder = YES;
-
         // Select all the text if we are tabbing in, but otherwise preserve/remember
         // the selection from last time we had focus (to match WinIE).
         if ([[self window] keyViewSelectionDirection] != NSDirectSelection) {
@@ -570,8 +564,6 @@ static NSString *WebContinuousSpellCheckingEnabled = @"WebContinuousSpellCheckin
 	[self _KWQ_setKeyboardFocusRingNeedsDisplay];
 	QFocusEvent event(QEvent::FocusIn);
 	const_cast<QObject *>(widget->eventFilterObject())->eventFilter(widget, &event);
-
-        inBecomeFirstResponder = NO;
     }
 
     return become;
diff --git a/WebCore/kwq/KWQTextEdit.h b/WebCore/kwq/KWQTextEdit.h
index b382bf0..762fe73 100644
--- a/WebCore/kwq/KWQTextEdit.h
+++ b/WebCore/kwq/KWQTextEdit.h
@@ -73,6 +73,8 @@ class QTextEdit : public QScrollView
 
     void clicked();
 
+    virtual bool checksDescendantsForFocus() const;
+
   private:
     KWQSignal _clicked;
     KWQSignal _textChanged;
diff --git a/WebCore/kwq/KWQTextEdit.mm b/WebCore/kwq/KWQTextEdit.mm
index 6fa2a26..195709f 100644
--- a/WebCore/kwq/KWQTextEdit.mm
+++ b/WebCore/kwq/KWQTextEdit.mm
@@ -130,3 +130,9 @@ QSize QTextEdit::sizeWithColumnsAndRows(int numColumns, int numRows) const
     NSSize size = [textArea sizeWithColumns:numColumns rows:numRows];
     return QSize((int)ceil(size.width), (int)ceil(size.height));
 }
+
+bool QTextEdit::checksDescendantsForFocus() const
+{
+    return true;
+}
+
diff --git a/WebCore/kwq/KWQWidget.h b/WebCore/kwq/KWQWidget.h
index 93af5e7..0ef41aa 100644
--- a/WebCore/kwq/KWQWidget.h
+++ b/WebCore/kwq/KWQWidget.h
@@ -100,6 +100,7 @@ public:
     bool hasFocus() const;
     void setFocus();
     void clearFocus();
+    virtual bool checksDescendantsForFocus() const;
     
     virtual FocusPolicy focusPolicy() const;
     void setFocusPolicy(FocusPolicy) {};
diff --git a/WebCore/kwq/KWQWidget.mm b/WebCore/kwq/KWQWidget.mm
index 23481d0..e69beab 100644
--- a/WebCore/kwq/KWQWidget.mm
+++ b/WebCore/kwq/KWQWidget.mm
@@ -182,14 +182,19 @@ bool QWidget::hasFocus() const
     if (firstResponder == view) {
         return true;
     }
-    // The following check handles both text field editors and the secure text field
-    // that goes inside the KWQTextField (and its editor). We have to check the class
-    // of the view because we don't want to be fooled by subviews of NSScrollView, for example.
-    if ([view isKindOfClass:[NSTextField class]]
-            && [firstResponder isKindOfClass:[NSView class]]
-            && [firstResponder isDescendantOf:view]) {
+
+    // Some widgets, like text fields, secure text fields, text areas, and selects
+    // (when displayed using a list box) may have a descendent widget that is
+    // first responder. This checksDescendantsForFocus() check, turned on for the 
+    // four widget types listed, enables the additional check which makes this 
+    // function work correctly for the above-mentioned widget types.
+    if (checksDescendantsForFocus() && 
+        [firstResponder isKindOfClass:[NSView class]] && 
+        [(NSView *)firstResponder isDescendantOf:view]) {
+        // Return true when the first responder is a subview of this widget's view
         return true;
     }
+
     return false;
 }
 
@@ -228,6 +233,11 @@ void QWidget::clearFocus()
     KWQKHTMLPart::clearDocumentFocus(this);
 }
 
+bool QWidget::checksDescendantsForFocus() const
+{
+    return false;
+}
+
 QWidget::FocusPolicy QWidget::focusPolicy() const
 {
     // This provides support for controlling the widgets that take 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list