Commit 95130fcc authored by darin@apple.com's avatar darin@apple.com

Change cursor to hand over missing plug-in message

https://bugs.webkit.org/show_bug.cgi?id=69312

Reviewed by Sam Weinig.

No tests because we currently don't have any test machinery for cursors.

* page/EventHandler.cpp:
(WebCore::OptionalCursor::OptionalCursor): Added. Construct an object
to represent either a cursor, or no cursor change.
(WebCore::OptionalCursor::isCursorChange): Added.
(WebCore::OptionalCursor::cursor): Added.
(WebCore::EventHandler::selectCursor): Changed return type to OptionalCursor,
moved some special cases from handleMouseMoveEvent in here. Moved the logic
for plug-ins and framesets into the specific renderer classes for those.
Added a call to the new getCursor virtual function.
(WebCore::EventHandler::handleMouseMoveEvent): Changed cursor setting code to
just be a call to selectCursor and then setCursor. Plug-in-specific code is now
in RenderWidget.

* page/EventHandler.h: Changed return type of selectCursor.

* page/MouseEventWithHitTestResults.cpp: Made some functions be inline.
* page/MouseEventWithHitTestResults.h:
(WebCore::MouseEventWithHitTestResults::localPoint): Made this inline.
(WebCore::MouseEventWithHitTestResults::scrollbar): Made this inline.
Yes, this has nothing to do with the rest of the patch, but it's good.

* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::getReplacementTextGeometry): Made const.
(WebCore::RenderEmbeddedObject::isInMissingPluginIndicator): Made const.
Overloaded so it can be called with a point rather than an event.
(WebCore::shouldMissingPluginMessageBeButton): Added. Helps streamline
the logic below.
(WebCore::RenderEmbeddedObject::handleMissingPluginIndicatorEvent):
Changed to use shouldMissingPluginMessageBeButton.
(WebCore::RenderEmbeddedObject::getCursor): Added. Sets the cursor to
a hand when over the missing plug-in message.
* rendering/RenderEmbeddedObject.h: Added getCursor override. Also updated
for other changes above.

* rendering/RenderFrameSet.cpp:
(WebCore::RenderFrameSet::getCursor): Added. Contains the logic that used
to be hardcoded in EventHandler::selectCursor about cursors when over
resizable frame borders.
* rendering/RenderFrameSet.h: Added getCursor.

* rendering/RenderObject.cpp:
(WebCore::RenderObject::getCursor): Added. Returns SetCursorBasedOnStyle.
* rendering/RenderObject.h: Added getCursor.

* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::getCursor): Added. Contains the logic that used
to be hardcoded in EventHandler::handleMouseMoveEvent to prevent setting
the cursor when the pointer is over a plug-in. This new code is much better,
because it only kicks in when there is actually a plug-in present. The old
was based on the HTML tag!
* rendering/RenderWidget.h: Added getCursor.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96566 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 414abf8c
2011-10-03 Darin Adler <darin@apple.com>
Change cursor to hand over missing plug-in message
https://bugs.webkit.org/show_bug.cgi?id=69312
Reviewed by Sam Weinig.
No tests because we currently don't have any test machinery for cursors.
* page/EventHandler.cpp:
(WebCore::OptionalCursor::OptionalCursor): Added. Construct an object
to represent either a cursor, or no cursor change.
(WebCore::OptionalCursor::isCursorChange): Added.
(WebCore::OptionalCursor::cursor): Added.
(WebCore::EventHandler::selectCursor): Changed return type to OptionalCursor,
moved some special cases from handleMouseMoveEvent in here. Moved the logic
for plug-ins and framesets into the specific renderer classes for those.
Added a call to the new getCursor virtual function.
(WebCore::EventHandler::handleMouseMoveEvent): Changed cursor setting code to
just be a call to selectCursor and then setCursor. Plug-in-specific code is now
in RenderWidget.
* page/EventHandler.h: Changed return type of selectCursor.
* page/MouseEventWithHitTestResults.cpp: Made some functions be inline.
* page/MouseEventWithHitTestResults.h:
(WebCore::MouseEventWithHitTestResults::localPoint): Made this inline.
(WebCore::MouseEventWithHitTestResults::scrollbar): Made this inline.
Yes, this has nothing to do with the rest of the patch, but it's good.
* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::getReplacementTextGeometry): Made const.
(WebCore::RenderEmbeddedObject::isInMissingPluginIndicator): Made const.
Overloaded so it can be called with a point rather than an event.
(WebCore::shouldMissingPluginMessageBeButton): Added. Helps streamline
the logic below.
(WebCore::RenderEmbeddedObject::handleMissingPluginIndicatorEvent):
Changed to use shouldMissingPluginMessageBeButton.
(WebCore::RenderEmbeddedObject::getCursor): Added. Sets the cursor to
a hand when over the missing plug-in message.
* rendering/RenderEmbeddedObject.h: Added getCursor override. Also updated
for other changes above.
* rendering/RenderFrameSet.cpp:
(WebCore::RenderFrameSet::getCursor): Added. Contains the logic that used
to be hardcoded in EventHandler::selectCursor about cursors when over
resizable frame borders.
* rendering/RenderFrameSet.h: Added getCursor.
* rendering/RenderObject.cpp:
(WebCore::RenderObject::getCursor): Added. Returns SetCursorBasedOnStyle.
* rendering/RenderObject.h: Added getCursor.
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::getCursor): Added. Contains the logic that used
to be hardcoded in EventHandler::handleMouseMoveEvent to prevent setting
the cursor when the pointer is over a plug-in. This new code is much better,
because it only kicks in when there is actually a plug-in present. The old
was based on the HTML tag!
* rendering/RenderWidget.h: Added getCursor.
2011-10-03 Anders Carlsson <andersca@apple.com>
Work towards making PlatformWheelEvent immutable
......@@ -127,6 +127,21 @@ const double autoscrollInterval = 0.05;
const double fakeMouseMoveInterval = 0.1;
enum NoCursorChangeType { NoCursorChange };
class OptionalCursor {
public:
OptionalCursor(NoCursorChangeType) : m_isCursorChange(false) { }
OptionalCursor(const Cursor& cursor) : m_isCursorChange(true), m_cursor(cursor) { }
bool isCursorChange() const { return m_isCursorChange; }
const Cursor& cursor() const { return m_cursor; }
private:
bool m_isCursorChange;
Cursor m_cursor;
};
static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Node** stopNode)
{
if (!delta)
......@@ -1150,12 +1165,20 @@ static bool nodeIsNotBeingEdited(Node* node, Frame* frame)
return frame->selection()->rootEditableElement() != node->rootEditableElement();
}
Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scrollbar* scrollbar)
OptionalCursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scrollbar* scrollbar)
{
if (m_resizeLayer && m_resizeLayer->inResizeMode())
return NoCursorChange;
Page* page = m_frame->page();
if (!page)
return NoCursorChange;
if (page->mainFrame()->eventHandler()->m_panScrollInProgress)
return NoCursorChange;
Node* node = targetNode(event);
RenderObject* renderer = node ? node->renderer() : 0;
RenderStyle* style = renderer ? renderer->style() : 0;
bool horizontalText = !style || style->isHorizontalWritingMode();
const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();
......@@ -1164,12 +1187,16 @@ Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scr
if (m_mousePressed && m_mouseDownMayStartSelect && m_frame->selection()->isCaretOrRange() && !m_capturingMouseEventsNode)
return iBeam;
if (renderer && renderer->isFrameSet()) {
RenderFrameSet* frameSetRenderer = toRenderFrameSet(renderer);
if (frameSetRenderer->canResizeRow(event.localPoint()))
return rowResizeCursor();
if (frameSetRenderer->canResizeColumn(event.localPoint()))
return columnResizeCursor();
if (renderer) {
Cursor overrideCursor;
switch (renderer->getCursor(event.localPoint(), overrideCursor)) {
case SetCursorBasedOnStyle:
break;
case SetCursor:
return overrideCursor;
case DoNotSetCursor:
return NoCursorChange;
}
}
if (style && style->cursors()) {
......@@ -1629,21 +1656,10 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
} else {
if (scrollbar && !m_mousePressed)
scrollbar->mouseMoved(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
if (Page* page = m_frame->page()) {
if ((!m_resizeLayer || !m_resizeLayer->inResizeMode()) && !page->mainFrame()->eventHandler()->m_panScrollInProgress) {
// Plugins set cursor on their own. The only case WebKit intervenes is resetting cursor to arrow on mouse enter,
// in case the particular plugin doesn't manipulate cursor at all. Thus, even a CSS cursor set on body has no
// effect on plugins (which matches Firefox).
bool overPluginElement = false;
if (targetNode(mev) && targetNode(mev)->isHTMLElement()) {
HTMLElement* el = toHTMLElement(targetNode(mev));
overPluginElement = el->hasTagName(appletTag) || el->hasTagName(objectTag) || el->hasTagName(embedTag);
}
if (!overPluginElement) {
if (FrameView* view = m_frame->view())
view->setCursor(selectCursor(mev, scrollbar));
}
}
if (FrameView* view = m_frame->view()) {
OptionalCursor optionalCursor = selectCursor(mev, scrollbar);
if (optionalCursor.isCursorChange())
view->setCursor(optionalCursor.cursor());
}
}
......
......@@ -50,7 +50,6 @@ class NSView;
namespace WebCore {
class Clipboard;
class Cursor;
class Event;
class EventTarget;
class FloatPoint;
......@@ -62,6 +61,7 @@ class HitTestResult;
class KeyboardEvent;
class MouseEventWithHitTestResults;
class Node;
class OptionalCursor;
class PlatformKeyboardEvent;
class PlatformTouchEvent;
class PlatformWheelEvent;
......@@ -238,7 +238,7 @@ private:
#endif
bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
Cursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
OptionalCursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
#if ENABLE(PAN_SCROLLING)
void updatePanScrollState();
#endif
......
......@@ -33,16 +33,6 @@ MouseEventWithHitTestResults::MouseEventWithHitTestResults(const PlatformMouseEv
{
}
const LayoutPoint MouseEventWithHitTestResults::localPoint() const
{
return m_hitTestResult.localPoint();
}
Scrollbar* MouseEventWithHitTestResults::scrollbar() const
{
return m_hitTestResult.scrollbar();
}
bool MouseEventWithHitTestResults::isOverLink() const
{
return m_hitTestResult.URLElement() && m_hitTestResult.URLElement()->isLink();
......
......@@ -34,8 +34,8 @@ public:
const PlatformMouseEvent& event() const { return m_event; }
const HitTestResult& hitTestResult() const { return m_hitTestResult; }
const LayoutPoint localPoint() const;
Scrollbar* scrollbar() const;
LayoutPoint localPoint() const { return m_hitTestResult.localPoint(); }
Scrollbar* scrollbar() const { return m_hitTestResult.scrollbar(); }
bool isOverLink() const;
bool isOverWidget() const { return m_hitTestResult.isOverWidget(); }
......
......@@ -26,6 +26,7 @@
#include "Chrome.h"
#include "ChromeClient.h"
#include "Cursor.h"
#include "CSSValueKeywords.h"
#include "Font.h"
#include "FontSelector.h"
......@@ -180,7 +181,7 @@ void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint
context->drawBidiText(font, run, FloatPoint(labelX, labelY));
}
bool RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path& path, FloatRect& replacementTextRect, Font& font, TextRun& run, float& textWidth)
bool RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path& path, FloatRect& replacementTextRect, Font& font, TextRun& run, float& textWidth) const
{
contentRect = contentBoxRect();
contentRect.moveBy(accumulatedOffset);
......@@ -249,7 +250,7 @@ void RenderEmbeddedObject::viewCleared()
}
}
bool RenderEmbeddedObject::isInMissingPluginIndicator(MouseEvent* event)
bool RenderEmbeddedObject::isInMissingPluginIndicator(const LayoutPoint& point) const
{
FloatRect contentRect;
Path path;
......@@ -257,18 +258,25 @@ bool RenderEmbeddedObject::isInMissingPluginIndicator(MouseEvent* event)
Font font;
TextRun run("");
float textWidth;
if (!getReplacementTextGeometry(IntPoint(), contentRect, path, replacementTextRect, font, run, textWidth))
return false;
return path.contains(absoluteToLocal(event->absoluteLocation(), false, true));
return getReplacementTextGeometry(IntPoint(), contentRect, path, replacementTextRect, font, run, textWidth)
&& path.contains(point);
}
bool RenderEmbeddedObject::isInMissingPluginIndicator(MouseEvent* event) const
{
return isInMissingPluginIndicator(roundedLayoutPoint(absoluteToLocal(event->absoluteLocation(), false, true)));
}
static bool shouldMissingPluginMessageBeButton(Document* document)
{
Page* page = document->page();
return page && page->chrome()->client()->shouldMissingPluginMessageBeButton();
}
void RenderEmbeddedObject::handleMissingPluginIndicatorEvent(Event* event)
{
if (Page* page = document()->page()) {
if (!page->chrome()->client()->shouldMissingPluginMessageBeButton())
return;
}
if (!shouldMissingPluginMessageBeButton(document()))
return;
if (!event->isMouseEvent())
return;
......@@ -307,4 +315,13 @@ void RenderEmbeddedObject::handleMissingPluginIndicatorEvent(Event* event)
}
}
CursorDirective RenderEmbeddedObject::getCursor(const LayoutPoint& point, Cursor& cursor) const
{
if (m_showsMissingPluginIndicator && shouldMissingPluginMessageBeButton(document()) && isInMissingPluginIndicator(point)) {
cursor = handCursor();
return SetCursor;
}
return RenderPart::getCursor(point, cursor);
}
}
......@@ -58,6 +58,7 @@ private:
virtual void paintReplaced(PaintInfo&, const LayoutPoint&);
virtual void paint(PaintInfo&, const LayoutPoint&);
virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
#if USE(ACCELERATED_COMPOSITING)
virtual bool requiresLayer() const;
......@@ -67,8 +68,9 @@ private:
virtual void viewCleared();
void setMissingPluginIndicatorIsPressed(bool);
bool isInMissingPluginIndicator(MouseEvent*);
bool getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path&, FloatRect& replacementTextRect, Font&, TextRun&, float& textWidth);
bool isInMissingPluginIndicator(MouseEvent*) const;
bool isInMissingPluginIndicator(const LayoutPoint&) const;
bool getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path&, FloatRect& replacementTextRect, Font&, TextRun&, float& textWidth) const;
String m_replacementText;
bool m_hasFallbackContent; // FIXME: This belongs on HTMLObjectElement.
......
......@@ -24,6 +24,7 @@
#include "config.h"
#include "RenderFrameSet.h"
#include "Cursor.h"
#include "Document.h"
#include "EventHandler.h"
#include "EventNames.h"
......@@ -799,4 +800,17 @@ bool RenderFrameSet::isChildAllowed(RenderObject* child, RenderStyle*) const
return child->isFrame() || child->isFrameSet();
}
CursorDirective RenderFrameSet::getCursor(const LayoutPoint& point, Cursor& cursor) const
{
if (canResizeRow(point)) {
cursor = rowResizeCursor();
return SetCursor;
}
if (canResizeColumn(point)) {
cursor = columnResizeCursor();
return SetCursor;
}
return RenderBox::getCursor(point, cursor);
}
} // namespace WebCore
......@@ -68,8 +68,8 @@ public:
bool isResizingRow() const;
bool isResizingColumn() const;
bool canResizeRow(const IntPoint&) const;
bool canResizeColumn(const IntPoint&) const;
bool canResizeRow(const LayoutPoint&) const;
bool canResizeColumn(const LayoutPoint&) const;
void notifyFrameEdgeInfoChanged();
......@@ -99,6 +99,7 @@ private:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
virtual void paint(PaintInfo&, const LayoutPoint&);
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
inline HTMLFrameSetElement* frameSet() const;
......
......@@ -2690,7 +2690,13 @@ VisiblePosition RenderObject::createVisiblePosition(const Position& position)
return createVisiblePosition(0, DOWNSTREAM);
}
CursorDirective RenderObject::getCursor(const LayoutPoint&, Cursor&) const
{
return SetCursorBasedOnStyle;
}
#if ENABLE(SVG)
RenderSVGResourceContainer* RenderObject::toRenderSVGResourceContainer()
{
ASSERT_NOT_REACHED();
......
......@@ -46,6 +46,7 @@ namespace WebCore {
class AffineTransform;
class AnimationController;
class Cursor;
class HitTestResult;
class InlineBox;
class InlineFlowBox;
......@@ -66,6 +67,12 @@ class RenderSVGResourceContainer;
struct PaintInfo;
enum CursorDirective {
SetCursorBasedOnStyle,
SetCursor,
DoNotSetCursor
};
enum HitTestFilter {
HitTestAll,
HitTestSelf,
......@@ -658,8 +665,9 @@ public:
// This is typically only relevant when repainting.
virtual RenderStyle* outlineStyleForRepaint() const { return style(); }
void getTextDecorationColors(int decorations, Color& underline, Color& overline,
Color& linethrough, bool quirksMode = false);
virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
void getTextDecorationColors(int decorations, Color& underline, Color& overline, Color& linethrough, bool quirksMode = false);
// Return the RenderBox in the container chain which is responsible for painting this object, or 0
// if painting is root-relative. This is the container that should be passed to the 'forRepaint'
......
......@@ -385,4 +385,13 @@ bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& res
return inside;
}
CursorDirective RenderWidget::getCursor(const LayoutPoint& point, Cursor& cursor) const
{
if (widget() && widget()->isPluginViewBase()) {
// A plug-in is responsible for setting the cursor when the pointer is over it.
return DoNotSetCursor;
}
return RenderReplaced::getCursor(point, cursor);
}
} // namespace WebCore
......@@ -59,6 +59,7 @@ protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void layout();
virtual void paint(PaintInfo&, const LayoutPoint&);
virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
private:
virtual bool isWidget() const { return true; }
......
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