Bug 14344

Summary: Changing cursor style has no effect until the mouse moves
Product: WebKit Reporter: Gérard Talbot <browserbugs2>
Component: CSSAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: ap, bugs, darin, deanm, estade, evan, jiyuluna, matt11ag-webkitbugs, mjs, rniwa, scherkus, schmidt.christian, simon.fraser
Priority: P2 Keywords: InRadar
Version: 523.x (Safari 3)   
Hardware: All   
OS: All   
URL: http://www.gtalbot.org/DHTMLSection/Positioning.html
Bug Depends on: 53280    
Bug Blocks:    
Attachments:
Description Flags
Patch none

Description Gérard Talbot 2007-06-23 14:26:42 PDT
Steps to reproduce:
1. Load provided URL
2. Mousedown over the "Position" pseudo-titlebar of the form and hold the mousedown without moving the mouse

Actual results: 
You see a custom hand-grab cursor which displays an open hand with 5 fingers

Expected results: 
The custom hand-grab cursor displaying an open hand with 5 fingers should become, should change into a custom hand-grabbing cursor which display a closed hand


Relevant code involved:
<body onload="init();">
(...)
<div id="idTitlePosition" title="You can drag and move this position control box form">Position<img (...)></div>

function init()
{
if (document.addEventListener)
	{
	document.getElementById("idTitlePosition").addEventListener("mousedown", Activate, false);

(...)

In Position.css (around line 43):
#idTitlePosition
		{
		(...)
		cursor: url("../GRAPHICS/ICO/grab.cur"), move;
		}

In Position.js (around line 230):
function Activate (evt)
{
	TextBoxToBeMoved = (evt) ? evt.currentTarget : window.event ? event.srcElement : null;
	TextBoxToBeMoved.style.cursor = "url('../GRAPHICS/ICO/grabbing.cur'), -moz-grabbing";

Notes: 
- the provided URL is not a reduced testcase.
- MSIE 6, MSIE 7, Firefox 2.0.0.4 get the expected results.
- Mozilla used to have a similar bug:
Mozilla-Bug 293510
dynamic changes of 'cursor' property don't work until mouse moves
https://bugzilla.mozilla.org/show_bug.cgi?id=293510
Comment 1 Alexey Proskuryakov 2007-06-24 02:17:37 PDT
Confirmed on Mac OS, so moving to All/All. The Mac version has an even worse behavior, since it cannot display most .cur cursors, but the described problem appears to occur, too.
Comment 2 Darin Adler 2009-01-13 09:53:20 PST
*** Bug 19925 has been marked as a duplicate of this bug. ***
Comment 3 Darin Adler 2009-01-13 09:53:25 PST
*** Bug 22296 has been marked as a duplicate of this bug. ***
Comment 4 Darin Adler 2009-01-13 09:53:32 PST
*** Bug 23079 has been marked as a duplicate of this bug. ***
Comment 5 Darin Adler 2009-01-13 09:54:26 PST
Duplicates have examples and, I think, some slightly better explanations.
Comment 6 Evan Stade 2010-02-05 15:30:38 PST
this also occurs for non-custom cursors. For example, see http://code.google.com/p/chromium/issues/detail?id=34075 (changing zoom level doesn't change the zoom icon until after a mouse move event)
Comment 7 Alexey Proskuryakov 2010-03-04 11:02:27 PST
<rdar://problem/7563712>
Comment 8 Darin Adler 2011-01-25 10:47:51 PST
If we address the basic problem here, we probably still won’t resolve the case where the mouse is down, which would be needed to make the closed-hand example work.

Generally speaking we make no cursor adjustments while the mouse is down. We don’t want to change the cursor based on what the mouse is over as you drag with the mouse down. It would be interesting to see how the other browsers behave. Do they adjust the cursor based on style changes in the element you were over when the mouse went down?
Comment 9 Evan Martin 2011-01-25 11:01:30 PST
In Firefox 3.6 on Linux, dragging the map gives me the hand cursor.  As soon as I drag from there over another HTML element (including the floating map controls) the cursor changes to the cursor used by that control.  Dragging outside of the map also resets the cursor.  And in all cases, dragging back into the map after the cursor changing puts the cursor back into the dragging-hand cursor.

So from that I guess that maps changes the cursor of the map widget to the custom cursor on mouse down, and Firefox obeys the cursor of whatever the mouse is currently over, regardless of the mouse down state.

More common uses of dragging, like dragging a link, use browser-level support for drag icons etc so the mouse cursor is unaffected by the page.

http://panic.com/goods is another site that uses dnd heavily.  There, they have no custom mouse cursor but I do notice that when I drag an item over a link I have the normal arrow cursor throughout, not the hand cursor, because the simulated drag icon is beneath the cursor.  If I mouse-wheel *while* dragging, their simulated drag icon gets out of position and I can see my mouse cursor change to the hand when I hover a link.

(Weirdly, maps loses my mouse drag if I drag out the left or right side of the window, but not the bottom or top!  There could be other bugs here in both maps and Firefox's Linux support, so it is probably worth testing in a more popular browser.  panic.com didn't have this problem.)
Comment 10 Gérard Talbot 2011-01-26 06:16:22 PST
> Generally speaking we make no cursor adjustments while the mouse is down. We don’t want to change the cursor based on what the mouse is over as you drag with the mouse down. 

In my DHTML demo page, the cursor once Activated is over, remains over that <div id="idTitlePosition">... pseudo-title-bar as it dynamically moves to match cursor position.

> It would be interesting to see how the other browsers behave. 

If I understand correctly your question here, then, yes, other browsers change the cursor based on what the mouse is over as you drag with the mouse down. 

{
Steps: in this very page, mousedown the left button and then move the cursor
Actual (with Firefox 3.6.13): all the text become selected/highlighted and the cursor has the I-beam shape. But when the cursor is over a link, then the cursor changes to pointer (a pointing hand).
Actual (with Chrome 8.0.552.237): all the text become selected/highlighted and the cursor has the I-beam shape. When the cursor is over a link, then the cursor remains a text (I-beam shape) cursor.
}

{
Steps: I load
http://www.gtalbot.org/DHTMLSection/Cursors.html#CSS2
and then mousedown the left button and then move the cursor in the "Notes" column (from auto row at the top to <URI> row at the bottom).
Actual (with Firefox 3.6.13): all the text in the first 3 columns become selected, highlighted while the cursor changes accordingly to become the cursor name given in the first column
Actual (with Chrome 8.0.552.237): all the text in the first 3 columns become selected, highlighted while the cursor becomes and remains a text (I-beam shape) cursor.
}

> Do they adjust the cursor based on style changes in the element you were over when the mouse went down?

Yes with Firefox 3.6.13. No with Chrome 8.0.552.237. I can check with IE8 later if you want.

------------

FWIW, 2 Drag-n-drop HTML5 demos (using dragstart, dragover, dragenter, dragleave events):

http://html5demos.com/drag

http://html5demos.com/drag-anything

regards, Gérard
Comment 11 Gérard Talbot 2011-01-26 08:52:50 PST
> Do they adjust the cursor based on style changes in the element you were over when the mouse went down?

While following the steps given before for the 2 urls...

Yes with Firefox 3.6.13 (under Linux) and Opera 11.0 (build 1156; under Windows XP). 

No with IE8 (under Windows XP) and Chrome 8.0.552.237 (under Linux).

Gérard
Comment 12 Gérard Talbot 2011-01-26 10:12:08 PST
> Do they adjust the cursor based on style changes in the element you were over when the mouse went down?

While following the steps given in #c10 for the 2 urls...

Yes with Konqueror 4.5.5 (Qt 4.7.0, i686, Linux 2.6.35-24-generic-pae;).

Gérard
Comment 13 Darin Adler 2011-01-27 14:55:10 PST
There are multiple things wrong:

    1) Changing CSS cursor style won’t trigger a cursor change until the mouse moves.

    2) If an element’s position change affects the cursor because it moves under the cursor our moves out from under the cursor the cursor won’t change until the mouse moves.

    3) Hover effects also don’t change in cases like (2).

    4) Changing CSS cursor style doesn’t have any effect while the mouse is down.

I am going to post a patch that fixes only (1). We should use separate patches for the other issues.
Comment 14 Darin Adler 2011-01-27 14:58:47 PST
(In reply to comment #13)
> We should use separate patches for the other issues.

I mean separate bug reports.
Comment 15 Darin Adler 2011-01-27 15:04:17 PST
Created attachment 80368 [details]
Patch
Comment 16 Simon Fraser (smfr) 2011-01-27 15:27:46 PST
Comment on attachment 80368 [details]
Patch

I don't think this handle the case where an element's cursor style doesn't change, but layout moves the element under the cursor.
Comment 17 Darin Adler 2011-01-27 16:20:37 PST
(In reply to comment #16)
> I don't think this handle the case where an element's cursor style doesn't change, but layout moves the element under the cursor.

Yes, correct.

As I said above, my patch fixes only issue (1) above and you are citing my issue (2) above. I discussed this with Mitz and Hyatt, and Mitz pointed out (3) above and Hyatt thought we should fix cursors and hover at the same time.
Comment 18 Andrew Scherkus 2011-01-27 17:58:50 PST
interested in the fix for (1) since I hacked up a hide-the-cursor-over-video-playback demo!  cool!!
Comment 19 Darin Adler 2011-01-27 18:12:48 PST
Committed r76891: <http://trac.webkit.org/changeset/76891>
Comment 20 Maciej Stachowiak 2011-01-27 19:28:31 PST
Reopening because the patch caused all the layout tests to crash on SnowLeopard.
Comment 21 Darin Adler 2011-01-28 15:13:59 PST
Re-landed with missing null check: <http://trac.webkit.org/changeset/76999>.

We can either close this bug or re-purpose it to cover (4) since the test case in this bug requires (4). Even clearer would be to close this and file new separate bugs for (2), (3), and (4).
Comment 22 Simon Fraser (smfr) 2011-01-28 15:46:12 PST
Filed bug 53340, bug 53341, bug 53342.
Comment 23 Ryosuke Niwa 2011-01-28 17:31:37 PST
Did you forget to make areNonIdenticalCursorListsEqual inline or was it intentional?  It's only called by areCursorsEqual, which is declared static inline.

http://trac.webkit.org/changeset/76999/trunk/Source/WebCore/rendering/RenderObject.cpp
Comment 24 Darin Adler 2011-01-28 17:58:07 PST
(In reply to comment #23)
> Did you forget to make areNonIdenticalCursorListsEqual inline or was it intentional?

It was intentional and in fact it’s the reason there are two functions. Since almost no objects have cursor lists, I wanted to put the much less hot code behind a function call. Probably not obvious so I should have put in a comment.