Commit 3ee17e4a authored by hyatt's avatar hyatt
Browse files

Event refactoring.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@16683 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 9f2e4b67
2006-09-30 Dave Hyatt <hyatt@apple.com>
Refactor subframe event handling to hide more of the Mac-specific logic from the cross-platform code.
Stub out a capturing API that mimics the way Web browsers capture events and route them to specific
subframes while the mouse is down.
Reviewed by mitzpettel
* bridge/mac/FrameMac.h:
* bridge/mac/FrameMac.mm:
(WebCore::FrameMac::passWidgetMouseDownEventToWidget):
(WebCore::FrameMac::passWheelEventToWidget):
* bridge/mac/FrameViewMac.mm:
(WebCore::FrameView::passMousePressEventToSubframe):
(WebCore::FrameView::passMouseMoveEventToSubframe):
(WebCore::FrameView::passMouseReleaseEventToSubframe):
(WebCore::FrameView::passWheelEventToSubframe):
* page/Frame.cpp:
* page/Frame.h:
* page/FrameView.cpp:
(WebCore::subframeForTargetNode):
(WebCore::FrameView::handleMousePressEvent):
(WebCore::FrameView::handleMouseDoubleClickEvent):
(WebCore::FrameView::handleMouseMoveEvent):
(WebCore::FrameView::handleMouseReleaseEvent):
(WebCore::FrameView::handleWheelEvent):
* page/FrameView.h:
* platform/ScrollBar.h:
(WebCore::ScrollBar::handleMouseMoveEvent):
(WebCore::ScrollBar::handleMouseOutEvent):
* platform/Widget.h:
(WebCore::Widget::handleMouseMoveEvent):
(WebCore::Widget::handleMouseReleaseEvent):
* platform/win/TemporaryLinkStubs.cpp:
(FrameView::passMousePressEventToSubframe):
(FrameView::passMouseMoveEventToSubframe):
(FrameView::passMouseReleaseEventToSubframe):
(FrameView::passWheelEventToSubframe):
(Widget::capturingMouse):
(Widget::setCapturingMouse):
(Widget::capturingTarget):
(Widget::capturingChild):
(Widget::setCapturingChild):
* rendering/RenderView.cpp:
(WebCore::RenderView::paintBoxDecorations):
2006-09-29 MorganL <morganl.webkit@yahoo.com>
 
Reviewed by Adele.
......@@ -226,9 +226,11 @@ public:
bool sendContextMenuEvent(NSEvent*);
virtual bool passMouseDownEventToWidget(Widget*);
virtual bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframePart);
virtual bool passWheelEventToChildWidget(Node*);
bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
bool passWidgetMouseDownEventToWidget(RenderWidget*);
bool passMouseDownEventToWidget(Widget*);
bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframePart);
bool passWheelEventToWidget(Widget*);
NSString* searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell);
NSString* searchForLabelsBeforeElement(NSArray* labels, Element* element);
......
......@@ -1401,6 +1401,32 @@ void FrameMac::handleMousePressEvent(const MouseEventWithHitTestResults& event)
}
}
bool FrameMac::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
{
// Figure out which view to send the event to.
RenderObject *target = event.targetNode() ? event.targetNode()->renderer() : 0;
if (!target)
return false;
Widget* widget = event.scrollbar();
if (!widget) {
if (!target->isWidget())
return false;
widget = static_cast<RenderWidget*>(target)->widget();
}
// Doubleclick events don't exist in Cocoa. Since passWidgetMouseDownEventToWidget will
// just pass _currentEvent down to the widget, we don't want to call it for events that
// don't correspond to Cocoa events. The mousedown/ups will have already been passed on as
// part of the pressed/released handling.
return passMouseDownEventToWidget(widget);
}
bool FrameMac::passWidgetMouseDownEventToWidget(RenderWidget *renderWidget)
{
return passMouseDownEventToWidget(renderWidget->widget());
}
bool FrameMac::passMouseDownEventToWidget(Widget* widget)
{
// FIXME: this method always returns true
......@@ -1916,20 +1942,13 @@ bool FrameMac::passSubframeEventToSubframe(MouseEventWithHitTestResults& event,
return false;
}
bool FrameMac::passWheelEventToChildWidget(Node *node)
bool FrameMac::passWheelEventToWidget(Widget* widget)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
if ([_currentEvent type] != NSScrollWheel || _sendingEventToSubview || !node)
if ([_currentEvent type] != NSScrollWheel || _sendingEventToSubview || !widget)
return false;
else {
RenderObject *renderer = node->renderer();
if (!renderer || !renderer->isWidget())
return false;
Widget *widget = static_cast<RenderWidget*>(renderer)->widget();
if (!widget)
return false;
NSView *nodeView = widget->getView();
ASSERT(nodeView);
ASSERT([nodeView superview]);
......
......@@ -52,4 +52,24 @@ void FrameView::updateDashboardRegions()
}
}
bool FrameView::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
{
return Mac(m_frame.get())->passSubframeEventToSubframe(mev, subframe);
}
bool FrameView::passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame*)
{
return Mac(m_frame.get())->passSubframeEventToSubframe(mev, subframe);
}
bool FrameView::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame*)
{
return Mac(m_frame.get())->passSubframeEventToSubframe(mev, subframe);
}
bool FrameView::passWheelEventToSubframe(PlatformWheelEvent&, Frame*)
{
return Mac(m_frame.get())->passWheelEventToWidget(subframe);
}
}
......@@ -3250,39 +3250,6 @@ bool Frame::canMouseDownStartSelect(Node* node)
return true;
}
void Frame::handleMouseReleaseDoubleClickEvent(const MouseEventWithHitTestResults& event)
{
passWidgetMouseDownEventToWidget(event, true);
}
bool Frame::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event, bool isDoubleClick)
{
// Figure out which view to send the event to.
RenderObject *target = event.targetNode() ? event.targetNode()->renderer() : 0;
if (!target)
return false;
Widget* widget = event.scrollbar();
if (!widget) {
if (!target->isWidget())
return false;
widget = static_cast<RenderWidget*>(target)->widget();
}
// Doubleclick events don't exist in Cocoa. Since passWidgetMouseDownEventToWidget will
// just pass _currentEvent down to the widget, we don't want to call it for events that
// don't correspond to Cocoa events. The mousedown/ups will have already been passed on as
// part of the pressed/released handling.
if (!isDoubleClick)
return passMouseDownEventToWidget(widget);
return true;
}
bool Frame::passWidgetMouseDownEventToWidget(RenderWidget *renderWidget)
{
return passMouseDownEventToWidget(renderWidget->widget());
}
void Frame::clearTimers(FrameView *view)
{
if (view) {
......
......@@ -521,7 +521,6 @@ public:
*/
KURL completeURL(const DeprecatedString& url);
virtual void handleMouseReleaseDoubleClickEvent(const MouseEventWithHitTestResults&);
virtual void handleMousePressEvent(const MouseEventWithHitTestResults&);
virtual void handleMouseMoveEvent(const MouseEventWithHitTestResults&);
virtual void handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
......@@ -579,8 +578,6 @@ public:
virtual void openURLRequest(const ResourceRequest&) = 0;
virtual void submitForm(const ResourceRequest&) = 0;
virtual void urlSelected(const ResourceRequest&) = 0;
virtual bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframePart = 0) = 0;
virtual bool passWheelEventToChildWidget(Node*) = 0;
virtual bool lastEventIsMouseUp() const = 0;
virtual String overrideMediaType() const = 0;
virtual void redirectDataToPlugin(Widget* pluginWidget) { }
......@@ -716,9 +713,6 @@ private:
bool scrollbarsVisible();
void scrollToAnchor(const KURL&);
bool canMouseDownStartSelect(Node*);
bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&, bool isDoubleClick);
bool passWidgetMouseDownEventToWidget(RenderWidget*);
virtual bool passMouseDownEventToWidget(Widget*) = 0;
void clearTimers();
static void clearTimers(FrameView*);
......
......@@ -551,12 +551,12 @@ void FrameView::layout(bool allowSubtree)
//
/////////////////
static Frame* subframeForEvent(const MouseEventWithHitTestResults& mev)
static Frame* subframeForTargetNode(Node* node)
{
if (!mev.targetNode())
if (!node)
return 0;
RenderObject* renderer = mev.targetNode()->renderer();
RenderObject* renderer = node->renderer();
if (!renderer || !renderer->isWidget())
return 0;
......@@ -584,7 +584,8 @@ void FrameView::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
MouseEventWithHitTestResults mev = prepareMouseEvent(false, true, false, mouseEvent);
if (m_frame->passSubframeEventToSubframe(mev)) {
Frame* subframe = subframeForTargetNode(mev.targetNode());
if (subframe && passMousePressEventToSubframe(mev, subframe)) {
invalidateClick();
return;
}
......@@ -623,6 +624,7 @@ void FrameView::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
}
}
// This method only exists for platforms that don't know how to deliver
void FrameView::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent)
{
if (!m_frame->document())
......@@ -635,8 +637,8 @@ void FrameView::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent
d->m_currentMousePosition = convertFromContainingWindow(mouseEvent.pos());
MouseEventWithHitTestResults mev = prepareMouseEvent(false, true, false, mouseEvent);
if (m_frame->passSubframeEventToSubframe(mev))
Frame* subframe = subframeForTargetNode(mev.targetNode());
if (subframe && passMousePressEventToSubframe(mev, subframe))
return;
d->clickCount = mouseEvent.clickCount();
......@@ -645,11 +647,8 @@ void FrameView::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent
if (mev.targetNode() == d->clickNode)
dispatchMouseEvent(clickEvent, mev.targetNode(), true, d->clickCount, mouseEvent, true);
// Qt delivers a release event AND a double click event.
if (!swallowEvent) {
if (!swallowEvent)
m_frame->handleMouseReleaseEvent(mev);
m_frame->handleMouseReleaseDoubleClickEvent(mev);
}
invalidateClick();
}
......@@ -783,14 +782,14 @@ void FrameView::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent)
d->mousePressed, true, mouseEvent);
if (d->oldSubframe && d->oldSubframe->tree()->isDescendantOf(m_frame.get()))
m_frame->passSubframeEventToSubframe(mev, d->oldSubframe.get());
passMouseMoveEventToSubframe(mev, d->oldSubframe.get());
bool swallowEvent = dispatchMouseEvent(mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true);
if (d->oldScrollBar != mev.scrollbar()) {
// Send mouse exited to the old scrollbar.
if (d->oldScrollBar)
d->oldScrollBar->mouseExited();
d->oldScrollBar->handleMouseOutEvent(mouseEvent);
d->oldScrollBar = mev.scrollbar();
}
......@@ -800,13 +799,12 @@ void FrameView::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent)
if (!swallowEvent)
m_frame->handleMouseMoveEvent(mev);
RefPtr<Frame> newSubframe = subframeForEvent(mev);
RefPtr<Frame> newSubframe = subframeForTargetNode(mev.targetNode());
if (newSubframe && d->oldSubframe != newSubframe)
m_frame->passSubframeEventToSubframe(mev, newSubframe.get());
passMouseMoveEventToSubframe(mev, newSubframe.get());
else {
if (mev.scrollbar() && !d->mousePressed)
mev.scrollbar()->mouseMoved(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
mev.scrollbar()->handleMouseMoveEvent(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
setCursor(selectCursor(mev, m_frame.get(), d->mousePressed));
}
......@@ -840,8 +838,8 @@ void FrameView::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
}
MouseEventWithHitTestResults mev = prepareMouseEvent(false, false, false, mouseEvent);
if (m_frame->passSubframeEventToSubframe(mev))
Frame* subframe = subframeForTargetNode(mev.targetNode());
if (subframe && passMouseReleaseEventToSubframe(mev, subframe))
return;
bool swallowEvent = dispatchMouseEvent(mouseupEvent, mev.targetNode(), true, d->clickCount, mouseEvent, false);
......@@ -1239,8 +1237,8 @@ void FrameView::handleWheelEvent(PlatformWheelEvent& e)
RenderObject::NodeInfo hitTestResult(true, false);
doc->renderer()->layer()->hitTest(hitTestResult, vPoint);
Node *node = hitTestResult.innerNode();
if (m_frame->passWheelEventToChildWidget(node)) {
Frame* subframe = subframeForTargetNode(node);
if (subframe && passWheelEventToSubframe(e, subframe)) {
e.accept();
return;
}
......
......@@ -136,10 +136,15 @@ public:
void handleMousePressEvent(const PlatformMouseEvent&);
void handleMouseDoubleClickEvent(const PlatformMouseEvent&);
void handleMouseMoveEvent(const PlatformMouseEvent&);
void handleMouseReleaseEvent(const PlatformMouseEvent&);
virtual void handleMouseMoveEvent(const PlatformMouseEvent&);
virtual void handleMouseReleaseEvent(const PlatformMouseEvent&);
void handleWheelEvent(PlatformWheelEvent&);
bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame*);
bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame*);
bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame*);
bool passWheelEventToSubframe(PlatformWheelEvent&, Frame*);
bool mousePressed();
void doAutoScroll();
......
......@@ -100,8 +100,8 @@ public:
// These methods are used for platform scrollbars to give :hover feedback. They will not get called
// when the mouse went down in a scrollbar, since it is assumed the scrollbar will start
// grabbing all events in that case anyway.
virtual void mouseMoved(const PlatformMouseEvent&) {};
virtual void mouseExited() {};
virtual void handleMouseMoveEvent(const PlatformMouseEvent&) {};
virtual void handleMouseOutEvent(const PlatformMouseEvent&) {};
protected:
virtual void updateThumbPosition() = 0;
......
......@@ -56,6 +56,7 @@ namespace WebCore {
class IntPoint;
class IntRect;
class IntSize;
class PlatformMouseEvent;
class WidgetClient;
class WidgetPrivate;
......@@ -147,6 +148,16 @@ namespace WebCore {
void setParent(Widget*);
Widget* parent() const;
bool capturingMouse() const;
void setCapturingMouse(bool);
Widget* capturingTarget();
Widget* capturingChild();
void setCapturingChild(Widget*);
// These methods will be called on a widget while it is capturing the mouse.
virtual void handleMouseMoveEvent(const PlatformMouseEvent&) {};
virtual void handleMouseReleaseEvent(const PlatformMouseEvent&) {};
#endif
#if PLATFORM(GDK)
......
......@@ -78,6 +78,10 @@ using namespace WebCore;
} while (0)
void FrameView::updateBorder() { notImplemented(); }
bool FrameView::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) { return true; }
bool FrameView::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) { return true; }
bool FrameView::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) { return true; }
bool FrameView::passWheelEventToSubframe(PlatformWheelEvent& e, Frame* subframe) { return false; }
void Widget::enableFlushDrawing() { notImplemented(); }
bool Widget::isEnabled() const { notImplemented(); return 0; }
......@@ -85,7 +89,12 @@ Widget::FocusPolicy Widget::focusPolicy() const { notImplemented(); return NoFoc
void Widget::disableFlushDrawing() { notImplemented(); }
GraphicsContext* Widget::lockDrawingFocus() { notImplemented(); return 0; }
void Widget::unlockDrawingFocus(GraphicsContext*) { notImplemented(); }
bool Widget::capturingMouse() const { return false; }
void Widget::setCapturingMouse(bool capturingMouse) { }
Widget* Widget::capturingTarget() { return this; }
Widget* Widget::capturingChild() { return 0; }
void Widget::setCapturingChild(Widget* w) {}
}
JavaAppletWidget::JavaAppletWidget(IntSize const&,Element*,WTF::HashMap<String,String> const&) { notImplemented(); }
void TextField::selectAll() { notImplemented(); }
......
......@@ -191,13 +191,13 @@ void RenderView::paintBoxDecorations(PaintInfo& i, int _tx, int _ty)
frameView()->setUseSlowRepaints();
}
if ((firstChild() && firstChild()->style()->visibility() == VISIBLE) || !view())
if (elt || (firstChild() && firstChild()->style()->visibility() == VISIBLE) || !view())
return;
// This code typically only executes if the root element's visibility has been set to hidden.
// Only fill with white if we're the root document, since iframes/frames with
// no background in the child document should show the parent's background.
if (elt || view()->isTransparent())
if (view()->isTransparent())
frameView()->setUseSlowRepaints(); // The parent must show behind the child.
else {
Color baseColor = frameView()->baseBackgroundColor();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment