Bug 31711 - Fake drag example does not work properly
Summary: Fake drag example does not work properly
Status: RESOLVED DUPLICATE of bug 56213
Alias: None
Product: WebKit
Classification: Unclassified
Component: HTML Editing (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Linux
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks: 28153
  Show dependency treegraph
 
Reported: 2009-11-20 00:57 PST by Alejandro G. Castro
Modified: 2011-03-12 01:43 PST (History)
5 users (show)

See Also:


Attachments
Example showing the problem (740 bytes, text/html)
2009-11-20 00:57 PST, Alejandro G. Castro
no flags Details
Patch proposed to fix the problem (3.45 KB, patch)
2009-11-20 03:15 PST, Alejandro G. Castro
no flags Details | Formatted Diff | Diff
Added the Changelog comments (4.24 KB, patch)
2009-11-20 03:21 PST, Alejandro G. Castro
no flags Details | Formatted Diff | Diff
Modified the test to avoid using the offsetWidth (4.70 KB, patch)
2009-11-20 09:02 PST, Alejandro G. Castro
no flags Details | Formatted Diff | Diff
New patch proposal (4.70 KB, patch)
2009-12-02 00:06 PST, Alejandro G. Castro
eric: review-
eric: commit-queue-
Details | Formatted Diff | Diff
A webpage test case that exposes the bug in an user-facing way. (1.11 KB, text/html)
2010-09-27 20:12 PDT, yeechengc
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alejandro G. Castro 2009-11-20 00:57:27 PST
Created attachment 43563 [details]
Example showing the problem

In this example the result should be a selection and the result is a caret position. The problem seems the first move event position is not considered when selecting due to this code:

EventHandler.cpp:555

    if (!m_beganSelectingText) {
        m_beganSelectingText = true;
        newSelection = VisibleSelection(targetPosition);
    }

I'm creating a patch setting m_beganSelectingText in the handleMousePressEventSingleClick method to true in any case.
Comment 1 Alejandro G. Castro 2009-11-20 03:15:25 PST
Created attachment 43568 [details]
Patch proposed to fix the problem

This is the proposed solution, we had to modify the expected result of the fake drag because the previous solution did not considered the first moveTo for the selection which is the same problem. The patch sets m_beganSelectingText in the EventHandler::handleMousePressEventSingleClick, which means we will use that selection object as start, not the one created in the first movement. Could someone knowing the code better than me check the modification, maybe I'm missing a situation when we create that selection that we do not want to use it.

I've run the editing tests and all of them have the same result, except the fake drag but it was wrong before because we do not get all the selected text from the click.
Comment 2 Alejandro G. Castro 2009-11-20 03:21:53 PST
Created attachment 43569 [details]
Added the Changelog comments
Comment 3 Alejandro G. Castro 2009-11-20 03:24:16 PST
Adding people to the CC so they can comment about the bug.
Comment 4 Alejandro G. Castro 2009-11-20 09:02:58 PST
Created attachment 43584 [details]
Modified the test to avoid using the offsetWidth
Comment 5 Alexey Proskuryakov 2009-11-20 12:41:26 PST
I can't figure out from bug description what the problem is. When I click in the text and move the mouse, text gets selected, which looks like correct behavior. Could you please explain the issue in more detail?
Comment 6 Alejandro G. Castro 2009-11-20 12:56:40 PST
(In reply to comment #5)
> I can't figure out from bug description what the problem is. When I click in
> the text and move the mouse, text gets selected, which looks like correct
> behavior. Could you please explain the issue in more detail?

Checking the code in the example you can see we are moving to a position, pressing the button, moving the mouse again and releasing the button:

    eventSender.mouseMoveTo(x, y);
    eventSender.mouseDown();
    eventSender.mouseMoveTo(x + target.offsetWidth / 2, y);
    eventSender.mouseUp();

This code is not going to cause a selection because the button press position is discarded and a new selection is created with the target in the second moveTo:

EventHandler.cpp:555

    if (!m_beganSelectingText) {
        m_beganSelectingText = true;
        newSelection = VisibleSelection(targetPosition);
    }

And in the next line we set the extent to the target again:

EventHandler.cpp:561

    newSelection.setExtent(targetPosition);

If you want to select something we would have to use code like this:

    eventSender.mouseDown();
    eventSender.mouseMoveTo(x, y);
    eventSender.mouseMoveTo(x + target.offsetWidth / 2, y);
    eventSender.mouseUp();

The first move sets the initial position of the selection and the second one the target because m_beganSelectingText is true. This basically means that if you click with the mouse and move fast enough to get a motion notify far from the press the selection will start there, not in the button press.

It is easy to reproduce with DRT events but in the  browser is difficult to reproduce because you get a lot of motion events but if you move the mouse fast enough when clicking and you print the press and motion positions, you could check you will be losing selection range.

Hope this helps.
Comment 7 Alexey Proskuryakov 2009-11-20 13:35:32 PST
I'm as confused as I was before. Could you provide steps to reproduce this bug? Something like:
1. Open the first attachment in this bug.
2. Click inside the first "Select" word.
3. Without releasing mouse button, move mouse pointer to the right.
4. Release mouse button.
Expected results: <...>.
Actual results: <...>.

For me, actual results for the above steps are that a selection is made.
Comment 8 Alejandro G. Castro 2009-11-20 16:29:41 PST
(In reply to comment #7)
> I'm as confused as I was before. Could you provide steps to reproduce this bug?
> Something like:
> 1. Open the first attachment in this bug.
> 2. Click inside the first "Select" word.
> 3. Without releasing mouse button, move mouse pointer to the right.
> 4. Release mouse button.
> Expected results: <...>.
> Actual results: <...>.
> 

The steps are these:

1. Execute the first attachment in this bug with the DRT
2. The expected result is selection (check the expected file in the last attachment), something like:

selection start: position 0 of child 0 {#text} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
selection end:   position 31 of child 0 {#text} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document

3. Actual result is a caret

caret: ...
Comment 9 Alexey Proskuryakov 2009-11-20 16:34:44 PST
So, this has no user-visible effect in a browser at all?
Comment 10 Alejandro G. Castro 2009-11-22 12:15:53 PST
(In reply to comment #9)
> So, this has no user-visible effect in a browser at all?

I did not check it in the browser before, because the problem comes from the fake drag test I was implementing in bug 28153. In theory we are losing the selection from the press to the first move event, but usually they are very close so you are still over the same character, and if they move fast users could think it was just their fault not clicking in the right position when moving too fast, it is unlikely it could be easily detected.

Anyway, this is a log of one session with epiphany-webkit and slashdot.org, I was selecting moving the mouse fast. Check the m_offset of the VisiblePositions, the first one is newSelection.visibleStart() the second one is targetPosition. Initially the web was loading and apparently the gap between the first position and the second is a little bit bigger, after loading is more difficult to reproduce it.

Breakpoint 1, WebCore::EventHandler::updateSelectionForMouseDrag (this=0xb59778, targetNode=0x23e9a10, localPoint=...) at WebCore/page/EventHandler.cpp:557
557	        newSelection = VisibleSelection(targetPosition);
$152 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 20, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}
$153 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 36, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}

Breakpoint 1, WebCore::EventHandler::updateSelectionForMouseDrag (this=0xb59778, targetNode=0x23e9a10, localPoint=...) at WebCore/page/EventHandler.cpp:557
557	        newSelection = VisibleSelection(targetPosition);
$154 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 17, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}
$155 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 18, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}

Breakpoint 1, WebCore::EventHandler::updateSelectionForMouseDrag (this=0xb59778, targetNode=0x23e9a10, localPoint=...) at WebCore/page/EventHandler.cpp:557
557	        newSelection = VisibleSelection(targetPosition);
$156 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 20, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}
$157 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 21, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}

Breakpoint 1, WebCore::EventHandler::updateSelectionForMouseDrag (this=0xb59778, targetNode=0x23e9a10, localPoint=...) at WebCore/page/EventHandler.cpp:557
557	        newSelection = VisibleSelection(targetPosition);
$158 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 17, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}
$159 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 17, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}

Breakpoint 1, WebCore::EventHandler::updateSelectionForMouseDrag (this=0xb59778, targetNode=0x23e9a10, localPoint=...) at WebCore/page/EventHandler.cpp:557
557	        newSelection = VisibleSelection(targetPosition);
$160 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 11, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}
$161 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 12, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}

Breakpoint 1, WebCore::EventHandler::updateSelectionForMouseDrag (this=0xb59778, targetNode=0x23e9a10, localPoint=...) at WebCore/page/EventHandler.cpp:557
557	        newSelection = VisibleSelection(targetPosition);
$162 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 12, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}
$163 = {m_deepPosition = {m_anchorNode = {<WTF::FastAllocBase> = {<No data fields>}, m_ptr = 0x23e9a10}, m_offset = 12, m_anchorType = 0, m_isLegacyEditingPosition = true}, 
  m_affinity = WebCore::DOWNSTREAM}
Comment 11 Adam Barth 2009-11-30 12:33:56 PST
style-queue successfully ran check-webkit-style on attachment 43584 [details] without any errors
Comment 12 Darin Adler 2009-12-01 16:05:28 PST
Comment on attachment 43584 [details]
Modified the test to avoid using the offsetWidth

The ChangeLog in this patch has tabs in it.

Won't this change behavior when you click without dragging?
Comment 13 Adam Barth 2009-12-01 16:13:31 PST
> The ChangeLog in this patch has tabs in it.

style-queue false negative filed:
https://bugs.webkit.org/show_bug.cgi?id=32039
Comment 14 Alejandro G. Castro 2009-12-01 23:57:07 PST
(In reply to comment #12)
> (From update of attachment 43584 [details])
> The ChangeLog in this patch has tabs in it.
>

Oops, thanks for the review I'll fix it.

> Won't this change behavior when you click without dragging?

Not completely sure, that is why I would like someone with more experience in the handle_event code could review it. My analysis is this: m_beganSelectingText it is assigned in various places but it is used just in two places in the code, the first one is the one we want to modify the behaviour:

EventHandler.cpp:555

    if (!m_beganSelectingText) {
        m_beganSelectingText = true;
        newSelection = VisibleSelection(targetPosition);
    }

And the second one is in the release handler:

EventHandler.cpp:611

    if (m_mouseDownWasSingleClickInSelection && !m_beganSelectingText
#if ENABLE(DRAG_SUPPORT)
            && m_dragStartPos == event.event().pos()
#endif
            && m_frame->selection()->isRange()
            && event.event().button() != RightButton) {

This case is caused when m_mouseDownWasSingleClickInSelection is true which just can happen if the code where we have added the assignation of m_beganSelectingText was not executed due to the return false after the assignation:

EventHandler.cpp:320

        if (!extendSelection && m_frame->selection()->contains(vPoint)) {
            m_mouseDownWasSingleClickInSelection = true;
            return false;
        }

We added the assignation in the same method after these lines.

I hope it clarifies the rationale. I'll upload the new patch with Changelog fixed.

Thanks again for the review :).
Comment 15 Alejandro G. Castro 2009-12-02 00:06:46 PST
Created attachment 44131 [details]
New patch proposal

Fixed ChangeLog style
Comment 16 Eric Seidel (no email) 2009-12-02 00:09:40 PST
Patches require both an r+ and a cq+ if you want them committed by the bot.  So you'll need to mark this r? as well.
Comment 17 WebKit Review Bot 2009-12-02 00:20:33 PST
style-queue ran check-webkit-style on attachment 44131 [details] without any errors.
Comment 18 Eric Seidel (no email) 2010-01-05 14:17:54 PST
Comment on attachment 44131 [details]
New patch proposal

This will cause other platforms to fail since it only has gtk results.

Does this really need render tree results, or can this be made into a dumpAsText test?
Comment 19 Eric Seidel (no email) 2010-01-26 15:07:55 PST
Comment on attachment 44131 [details]
New patch proposal

Looks like this patch was abandoned.  Please answer my question and reflag/repost as necessary.
Comment 20 Alejandro G. Castro 2010-01-29 01:57:13 PST
(In reply to comment #18)
> (From update of attachment 44131 [details])
> This will cause other platforms to fail since it only has gtk results.
> 
> Does this really need render tree results, or can this be made into a
> dumpAsText test?

Sorry Eric, I forgot about this because we added the workaround in the test. All these tests that check if the selection we did is correct can be done with the dumpAsText checking the string selected instead of the positions but in the end we have the same problem because we depend on the font AFAIK.

Anyway I think we can review the patch to avoid changing the boolean in that part of the code and just avoid overwriting the position if someone is interested in this modification.
Comment 21 yeechengc 2010-09-27 20:12:57 PDT
Created attachment 69013 [details]
A webpage test case that exposes the bug in an user-facing way.

I just ran into this bug in WebKit/Safari and found this online. Seems like a problem with it is the lack of a good user-facing test so I made a webpage to show it. Basically it tries to run a long loop when the user tries to select text in a text box to make this behavior more apparent. Just try to drag and select text in the webpage and you should notice some part of the selection is missing.
Comment 22 Darin Adler 2010-09-28 10:03:10 PDT
This bug needs a new title. What does “fake drag” have to do with it at this point?
Comment 23 Alejandro G. Castro 2011-03-12 01:43:53 PST

*** This bug has been marked as a duplicate of bug 56213 ***