1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 33 #include <gdk/gdk.h> 34 #include <gtest/gtest.h> 35 36 #include "WebInputEvent.h" 37 #include "WebInputEventFactory.h" 38 39 using WebKit::WebMouseEvent; 40 using WebKit::WebInputEventFactory; 41 42 namespace { 43 44 TEST(WebInputEventFactoryTest, DoubleClick) 45 { 46 GdkEventButton firstClick; 47 firstClick.type = GDK_BUTTON_PRESS; 48 firstClick.window = static_cast<GdkWindow*>(GINT_TO_POINTER(1)); 49 firstClick.x = firstClick.y = firstClick.x_root = firstClick.y_root = 100; 50 firstClick.state = 0; 51 firstClick.time = 0; 52 firstClick.button = 1; 53 54 // Single click works. 55 WebMouseEvent firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick); 56 EXPECT_EQ(1, firstClickEvent.clickCount); 57 58 // Make sure double click works. 59 GdkEventButton secondClick = firstClick; 60 secondClick.time = firstClick.time + 100; 61 WebMouseEvent secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick); 62 EXPECT_EQ(2, secondClickEvent.clickCount); 63 64 // Reset the click count. 65 firstClick.time += 10000; 66 firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick); 67 EXPECT_EQ(1, firstClickEvent.clickCount); 68 69 // Two clicks with a long gap in between aren't counted as a double click. 70 secondClick = firstClick; 71 secondClick.time = firstClick.time + 1000; 72 secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick); 73 EXPECT_EQ(1, secondClickEvent.clickCount); 74 75 // Reset the click count. 76 firstClick.time += 10000; 77 firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick); 78 EXPECT_EQ(1, firstClickEvent.clickCount); 79 80 // Two clicks far apart (horizontally) aren't counted as a double click. 81 secondClick = firstClick; 82 secondClick.time = firstClick.time + 1; 83 secondClick.x = firstClick.x + 100; 84 secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick); 85 EXPECT_EQ(1, secondClickEvent.clickCount); 86 87 // Reset the click count. 88 firstClick.time += 10000; 89 firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick); 90 EXPECT_EQ(1, firstClickEvent.clickCount); 91 92 // Two clicks far apart (vertically) aren't counted as a double click. 93 secondClick = firstClick; 94 secondClick.time = firstClick.time + 1; 95 secondClick.x = firstClick.y + 100; 96 secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick); 97 EXPECT_EQ(1, secondClickEvent.clickCount); 98 99 // Reset the click count. 100 firstClick.time += 10000; 101 firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick); 102 EXPECT_EQ(1, firstClickEvent.clickCount); 103 104 // Two clicks on different windows aren't a double click. 105 secondClick = firstClick; 106 secondClick.time = firstClick.time + 1; 107 secondClick.window = static_cast<GdkWindow*>(GINT_TO_POINTER(2)); 108 secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick); 109 EXPECT_EQ(1, secondClickEvent.clickCount); 110 } 111 112 TEST(WebInputEventFactoryTest, MouseUpClickCount) 113 { 114 GdkEventButton mouseDown; 115 memset(&mouseDown, 0, sizeof(mouseDown)); 116 mouseDown.type = GDK_BUTTON_PRESS; 117 mouseDown.window = static_cast<GdkWindow*>(GINT_TO_POINTER(1)); 118 mouseDown.x = mouseDown.y = mouseDown.x_root = mouseDown.y_root = 100; 119 mouseDown.time = 0; 120 mouseDown.button = 1; 121 122 // Properly set the last click time, so that the internal state won't be affected by previous tests. 123 WebInputEventFactory::mouseEvent(&mouseDown); 124 125 mouseDown.time += 10000; 126 GdkEventButton mouseUp = mouseDown; 127 mouseUp.type = GDK_BUTTON_RELEASE; 128 WebMouseEvent mouseDownEvent; 129 WebMouseEvent mouseUpEvent; 130 131 // Click for three times. 132 for (int i = 1; i < 4; ++i) { 133 mouseDown.time += 100; 134 mouseDownEvent = WebInputEventFactory::mouseEvent(&mouseDown); 135 EXPECT_EQ(i, mouseDownEvent.clickCount); 136 137 mouseUp.time = mouseDown.time + 50; 138 mouseUpEvent = WebInputEventFactory::mouseEvent(&mouseUp); 139 EXPECT_EQ(i, mouseUpEvent.clickCount); 140 } 141 142 // Reset the click count. 143 mouseDown.time += 10000; 144 mouseDownEvent = WebInputEventFactory::mouseEvent(&mouseDown); 145 EXPECT_EQ(1, mouseDownEvent.clickCount); 146 147 // Moving the cursor for a significant distance will reset the click count to 0. 148 GdkEventMotion mouseMove; 149 memset(&mouseMove, 0, sizeof(mouseMove)); 150 mouseMove.type = GDK_MOTION_NOTIFY; 151 mouseMove.window = mouseDown.window; 152 mouseMove.time = mouseDown.time; 153 mouseMove.x = mouseMove.y = mouseMove.x_root = mouseMove.y_root = mouseDown.x + 100; 154 WebInputEventFactory::mouseEvent(&mouseMove); 155 156 mouseUp.time = mouseDown.time + 50; 157 mouseUpEvent = WebInputEventFactory::mouseEvent(&mouseUp); 158 EXPECT_EQ(0, mouseUpEvent.clickCount); 159 160 // Reset the click count. 161 mouseDown.time += 10000; 162 mouseDownEvent = WebInputEventFactory::mouseEvent(&mouseDown); 163 EXPECT_EQ(1, mouseDownEvent.clickCount); 164 165 // Moving the cursor with a significant delay will reset the click count to 0. 166 mouseMove.time = mouseDown.time + 1000; 167 mouseMove.x = mouseMove.y = mouseMove.x_root = mouseMove.y_root = mouseDown.x; 168 WebInputEventFactory::mouseEvent(&mouseMove); 169 170 mouseUp.time = mouseMove.time + 50; 171 mouseUpEvent = WebInputEventFactory::mouseEvent(&mouseUp); 172 EXPECT_EQ(0, mouseUpEvent.clickCount); 173 } 174 175 } // anonymous namespace 176