1f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick/*
2f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * Copyright (C) 2010 Google Inc. All rights reserved.
3f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *
4f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * Redistribution and use in source and binary forms, with or without
5f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * modification, are permitted provided that the following conditions are
6f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * met:
7f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *
8f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *     * Redistributions of source code must retain the above copyright
9f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * notice, this list of conditions and the following disclaimer.
10f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *     * Redistributions in binary form must reproduce the above
11f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * copyright notice, this list of conditions and the following disclaimer
12f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * in the documentation and/or other materials provided with the
13f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * distribution.
14f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *     * Neither the name of Google Inc. nor the names of its
15f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * contributors may be used to endorse or promote products derived from
16f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * this software without specific prior written permission.
17f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *
18f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick */
30f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
31f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include "config.h"
32f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
33f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <gdk/gdk.h>
34f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <gtest/gtest.h>
35f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
36f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include "WebInputEvent.h"
37f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include "WebInputEventFactory.h"
38f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
39f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickusing WebKit::WebMouseEvent;
40f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickusing WebKit::WebInputEventFactory;
41f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
42f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricknamespace {
43f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
44f486d19d62f1bc33246748b14b14a9dfa617b57fIain MerrickTEST(WebInputEventFactoryTest, DoubleClick)
45f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{
46f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    GdkEventButton firstClick;
47f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.type = GDK_BUTTON_PRESS;
48f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.window = static_cast<GdkWindow*>(GINT_TO_POINTER(1));
49f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.x = firstClick.y = firstClick.x_root = firstClick.y_root = 100;
50f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.state = 0;
51f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.time = 0;
52f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.button = 1;
53f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
54f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Single click works.
55f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    WebMouseEvent firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
56f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(1, firstClickEvent.clickCount);
57f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
58f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Make sure double click works.
59f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    GdkEventButton secondClick = firstClick;
60f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick.time = firstClick.time + 100;
61f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    WebMouseEvent secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
62f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(2, secondClickEvent.clickCount);
63f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
64f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Reset the click count.
65f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.time += 10000;
66f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
67f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(1, firstClickEvent.clickCount);
68f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
69f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Two clicks with a long gap in between aren't counted as a double click.
70f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick = firstClick;
71f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick.time = firstClick.time + 1000;
72f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
73f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(1, secondClickEvent.clickCount);
74f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
75f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Reset the click count.
76f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.time += 10000;
77f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
78f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(1, firstClickEvent.clickCount);
79f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
80f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Two clicks far apart (horizontally) aren't counted as a double click.
81f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick = firstClick;
82f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick.time = firstClick.time + 1;
83f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick.x = firstClick.x + 100;
84f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
85f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(1, secondClickEvent.clickCount);
86f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
87f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Reset the click count.
88f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.time += 10000;
89f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
90f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(1, firstClickEvent.clickCount);
91f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
92f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Two clicks far apart (vertically) aren't counted as a double click.
93f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick = firstClick;
94f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick.time = firstClick.time + 1;
95f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick.x = firstClick.y + 100;
96f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
97f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(1, secondClickEvent.clickCount);
98f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
99f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Reset the click count.
100f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClick.time += 10000;
101f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
102f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(1, firstClickEvent.clickCount);
103f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
104f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // Two clicks on different windows aren't a double click.
105f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick = firstClick;
106f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick.time = firstClick.time + 1;
107f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClick.window = static_cast<GdkWindow*>(GINT_TO_POINTER(2));
108f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
109f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    EXPECT_EQ(1, secondClickEvent.clickCount);
110f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick}
111f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
11254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve BlockTEST(WebInputEventFactoryTest, MouseUpClickCount)
11354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block{
11454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    GdkEventButton mouseDown;
11554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    memset(&mouseDown, 0, sizeof(mouseDown));
11654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDown.type = GDK_BUTTON_PRESS;
11754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDown.window = static_cast<GdkWindow*>(GINT_TO_POINTER(1));
11854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDown.x = mouseDown.y = mouseDown.x_root = mouseDown.y_root = 100;
11954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDown.time = 0;
12054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDown.button = 1;
12154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
12254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // Properly set the last click time, so that the internal state won't be affected by previous tests.
12354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    WebInputEventFactory::mouseEvent(&mouseDown);
12454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
12554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDown.time += 10000;
12654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    GdkEventButton mouseUp = mouseDown;
12754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseUp.type = GDK_BUTTON_RELEASE;
12854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    WebMouseEvent mouseDownEvent;
12954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    WebMouseEvent mouseUpEvent;
13054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
13154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // Click for three times.
13254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    for (int i = 1; i < 4; ++i) {
13354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        mouseDown.time += 100;
13454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        mouseDownEvent = WebInputEventFactory::mouseEvent(&mouseDown);
13554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        EXPECT_EQ(i, mouseDownEvent.clickCount);
13654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
13754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        mouseUp.time = mouseDown.time + 50;
13854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        mouseUpEvent = WebInputEventFactory::mouseEvent(&mouseUp);
13954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        EXPECT_EQ(i, mouseUpEvent.clickCount);
14054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    }
14154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
14254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // Reset the click count.
14354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDown.time += 10000;
14454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDownEvent = WebInputEventFactory::mouseEvent(&mouseDown);
14554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    EXPECT_EQ(1, mouseDownEvent.clickCount);
14654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
14754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // Moving the cursor for a significant distance will reset the click count to 0.
14854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    GdkEventMotion mouseMove;
14954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    memset(&mouseMove, 0, sizeof(mouseMove));
15054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseMove.type = GDK_MOTION_NOTIFY;
15154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseMove.window = mouseDown.window;
15254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseMove.time = mouseDown.time;
15354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseMove.x = mouseMove.y = mouseMove.x_root = mouseMove.y_root = mouseDown.x + 100;
15454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    WebInputEventFactory::mouseEvent(&mouseMove);
15554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
15654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseUp.time = mouseDown.time + 50;
15754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseUpEvent = WebInputEventFactory::mouseEvent(&mouseUp);
15854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    EXPECT_EQ(0, mouseUpEvent.clickCount);
15954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
16054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // Reset the click count.
16154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDown.time += 10000;
16254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseDownEvent = WebInputEventFactory::mouseEvent(&mouseDown);
16354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    EXPECT_EQ(1, mouseDownEvent.clickCount);
16454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
16554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    // Moving the cursor with a significant delay will reset the click count to 0.
16654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseMove.time = mouseDown.time + 1000;
16754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseMove.x = mouseMove.y = mouseMove.x_root = mouseMove.y_root = mouseDown.x;
16854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    WebInputEventFactory::mouseEvent(&mouseMove);
16954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
17054cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseUp.time = mouseMove.time + 50;
17154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    mouseUpEvent = WebInputEventFactory::mouseEvent(&mouseUp);
17254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    EXPECT_EQ(0, mouseUpEvent.clickCount);
17354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block}
17454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
175f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} // anonymous namespace
176