Skip to content


Browse files Browse the repository at this point in the history
Incorrect behavior of "cursor: auto" over links

Reviewed by Simon Fraser.

* LayoutTests/imported/w3c/web-platform-tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/mouse-cursor-imagemap-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/no-help-cursor-on-links.historical-expected.txt:
* Source/WebCore/css/html.css:
hand cursor (pointer) should not be rendered through 'auto' behavior of agent.
* Source/WebCore/page/EventHandler.cpp:
Removing hand cursor calculation from 'auto' case. Auto should just result in default or text cursors.
We are now using computedStyle instead of renderer->style() because we still need to access style
for elements without a renderer, like <area>.
* Source/WebCore/page/EventHandler.h:
Since we don't handle hand cursor anymore on selectCursor, selectCursor and updateCursor
no longer need to receive shiftKey.

Canonical link:
  • Loading branch information
vitorroriz authored and nt1m committed Aug 23, 2022
1 parent a98a145 commit 3a4722b
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 17 deletions.
Expand Up @@ -2,5 +2,5 @@
An unclickable (non-link) area should not show the link cursor when hovered.

FAIL Only clickable areas should show the link cursor. assert_equals: expected "pointer" but got "auto"
PASS Only clickable areas should show the link cursor.

@@ -1,4 +1,4 @@

FAIL Unvisited help links must have pointer cursor, not help cursor assert_equals: expected "pointer" but got "auto"
FAIL Visited help links must have pointer cursor, not help cursor assert_equals: expected "pointer" but got "auto"
PASS Unvisited help links must have pointer cursor, not help cursor
PASS Visited help links must have pointer cursor, not help cursor
unvisited will be visited
10 changes: 9 additions & 1 deletion Source/WebCore/css/html.css
Expand Up @@ -1290,13 +1290,21 @@ input[type="file"]:focus::file-selector-button {
a:any-link {
color: -webkit-link;
text-decoration: underline;
cursor: auto;
cursor: pointer;

a:any-link:active {
color: -webkit-activelink;

a:any-link:read-write {
cursor: text;

area:any-link {
cursor: pointer;

/* HTML5 ruby elements */

ruby, rt {
Expand Down
18 changes: 8 additions & 10 deletions Source/WebCore/page/EventHandler.cpp
Expand Up @@ -1420,18 +1420,18 @@ void EventHandler::updateCursor()
HitTestResult result(view->windowToContents(*m_lastKnownMousePosition));
document->hitTest(hitType, result);

updateCursor(*view, result, shiftKey);
updateCursor(*view, result);

void EventHandler::updateCursor(FrameView& view, const HitTestResult& result, bool shiftKey)
void EventHandler::updateCursor(FrameView& view, const HitTestResult& result)
if (auto optionalCursor = selectCursor(result, shiftKey)) {
if (auto optionalCursor = selectCursor(result)) {
m_currentMouseCursor = WTFMove(optionalCursor.value());

std::optional<Cursor> EventHandler::selectCursor(const HitTestResult& result, bool shiftKey)
std::optional<Cursor> EventHandler::selectCursor(const HitTestResult& result)
if (m_resizeLayer && m_resizeLayer->inResizeMode())
return std::nullopt;
Expand All @@ -1458,8 +1458,8 @@ std::optional<Cursor> EventHandler::selectCursor(const HitTestResult& result, bo
if (!node)
return std::nullopt;

auto renderer = node->renderer();
auto* style = renderer ? &renderer->style() : nullptr;
// We are using the node's computed style instead of renderer()->style because we need style info for nodes without a renderer, e.g.: <area>
auto* style = node->computedStyle();
bool horizontalText = !style || style->isHorizontalWritingMode();
const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();

Expand All @@ -1470,6 +1470,7 @@ std::optional<Cursor> EventHandler::selectCursor(const HitTestResult& result, bo

auto* renderer = node->renderer();
if (renderer) {
Cursor overrideCursor;
switch (renderer->getCursor(roundedIntPoint(result.localPoint()), overrideCursor)) {
Expand Down Expand Up @@ -1537,9 +1538,6 @@ std::optional<Cursor> EventHandler::selectCursor(const HitTestResult& result, bo

bool editable = node->hasEditableStyle();

if (useHandCursor(node.get(), result.isOverLink(), shiftKey))
return handCursor();

bool inResizer = false;
if (renderer && renderer->hasLayer()) {
// FIXME: With right-aligned text in a box, the renderer here is usually a RenderText, which prevents showing the resize cursor:
Expand Down Expand Up @@ -2044,7 +2042,7 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE

if (!newSubframe || mouseEvent.scrollbar()) {
if (RefPtr view = m_frame.view())
updateCursor(*view, mouseEvent.hitTestResult(), platformMouseEvent.shiftKey());
updateCursor(*view, mouseEvent.hitTestResult());

m_lastMouseMoveEventSubframe = newSubframe;
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/page/EventHandler.h
Expand Up @@ -343,7 +343,7 @@ class EventHandler {
WEBCORE_EXPORT void cancelSelectionAutoscroll();

WEBCORE_EXPORT std::optional<Cursor> selectCursor(const HitTestResult&, bool shiftKey);
WEBCORE_EXPORT std::optional<Cursor> selectCursor(const HitTestResult&);

std::optional<WheelScrollGestureState> wheelScrollGestureState() const { return m_wheelScrollGestureState; }
Expand Down Expand Up @@ -403,7 +403,7 @@ class EventHandler {

bool internalKeyEvent(const PlatformKeyboardEvent&);

void updateCursor(FrameView&, const HitTestResult&, bool shiftKey);
void updateCursor(FrameView&, const HitTestResult&);

void hoverTimerFired();

Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit/WebProcess/WebPage/ios/
Expand Up @@ -3245,7 +3245,7 @@ static void populateCaretContext(const HitTestResult& hitTestResult, const Inter

auto hitTestResult = eventHandler.hitTestResultAtPoint(request.point, hitTestRequestTypes);
if (auto* hitFrame = hitTestResult.innerNodeFrame()) {
info.cursor = hitFrame->eventHandler().selectCursor(hitTestResult, false);
info.cursor = hitFrame->eventHandler().selectCursor(hitTestResult);
if (request.includeCaretContext)
populateCaretContext(hitTestResult, request, info);
Expand Down

0 comments on commit 3a4722b

Please sign in to comment.