1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/browser/renderer_host/input/web_input_event_builders_gtk.h" 6 7 #include <gdk/gdk.h> 8 #include <gdk/gdkkeysyms.h> 9 10 #include "testing/gtest/include/gtest/gtest.h" 11 #include "third_party/WebKit/public/web/WebInputEvent.h" 12 #include "ui/events/keycodes/keyboard_code_conversion_gtk.h" 13 14 using blink::WebInputEvent; 15 using blink::WebKeyboardEvent; 16 using blink::WebMouseEvent; 17 using content::WebMouseEventBuilder; 18 using content::WebKeyboardEventBuilder; 19 20 namespace { 21 22 TEST(WebMouseEventBuilderTest, DoubleClick) { 23 GdkEventButton first_click; 24 first_click.type = GDK_BUTTON_PRESS; 25 first_click.window = static_cast<GdkWindow*>(GINT_TO_POINTER(1)); 26 first_click.x = first_click.y = first_click.x_root = first_click.y_root = 100; 27 first_click.state = 0; 28 first_click.time = 0; 29 first_click.button = 1; 30 31 // Single click works. 32 WebMouseEvent first_click_events = 33 WebMouseEventBuilder::Build(&first_click); 34 EXPECT_EQ(1, first_click_events.clickCount); 35 36 // Make sure double click works. 37 GdkEventButton second_click = first_click; 38 second_click.time = first_click.time + 100; 39 WebMouseEvent second_click_events = 40 WebMouseEventBuilder::Build(&second_click); 41 EXPECT_EQ(2, second_click_events.clickCount); 42 43 // Reset the click count. 44 first_click.time += 10000; 45 first_click_events = WebMouseEventBuilder::Build(&first_click); 46 EXPECT_EQ(1, first_click_events.clickCount); 47 48 // Two clicks with a long gap in between aren't counted as a double click. 49 second_click = first_click; 50 second_click.time = first_click.time + 1000; 51 second_click_events = WebMouseEventBuilder::Build(&second_click); 52 EXPECT_EQ(1, second_click_events.clickCount); 53 54 // Reset the click count. 55 first_click.time += 10000; 56 first_click_events = WebMouseEventBuilder::Build(&first_click); 57 EXPECT_EQ(1, first_click_events.clickCount); 58 59 // Two clicks far apart (horizontally) aren't counted as a double click. 60 second_click = first_click; 61 second_click.time = first_click.time + 1; 62 second_click.x = first_click.x + 100; 63 second_click_events = WebMouseEventBuilder::Build(&second_click); 64 EXPECT_EQ(1, second_click_events.clickCount); 65 66 // Reset the click count. 67 first_click.time += 10000; 68 first_click_events = WebMouseEventBuilder::Build(&first_click); 69 EXPECT_EQ(1, first_click_events.clickCount); 70 71 // Two clicks far apart (vertically) aren't counted as a double click. 72 second_click = first_click; 73 second_click.time = first_click.time + 1; 74 second_click.x = first_click.y + 100; 75 second_click_events = WebMouseEventBuilder::Build(&second_click); 76 EXPECT_EQ(1, second_click_events.clickCount); 77 78 // Reset the click count. 79 first_click.time += 10000; 80 first_click_events = WebMouseEventBuilder::Build(&first_click); 81 EXPECT_EQ(1, first_click_events.clickCount); 82 83 // Two clicks on different windows aren't a double click. 84 second_click = first_click; 85 second_click.time = first_click.time + 1; 86 second_click.window = static_cast<GdkWindow*>(GINT_TO_POINTER(2)); 87 second_click_events = WebMouseEventBuilder::Build(&second_click); 88 EXPECT_EQ(1, second_click_events.clickCount); 89 } 90 91 TEST(WebMouseEventBuilderTest, MouseUpClickCount) { 92 GdkEventButton mouse_down; 93 memset(&mouse_down, 0, sizeof(mouse_down)); 94 mouse_down.type = GDK_BUTTON_PRESS; 95 mouse_down.window = static_cast<GdkWindow*>(GINT_TO_POINTER(1)); 96 mouse_down.x = mouse_down.y = mouse_down.x_root = mouse_down.y_root = 100; 97 mouse_down.time = 0; 98 mouse_down.button = 1; 99 100 // Properly set the last click time, so that the internal state won't be 101 // affected by previous tests. 102 WebMouseEventBuilder::Build(&mouse_down); 103 104 mouse_down.time += 10000; 105 GdkEventButton mouse_up = mouse_down; 106 mouse_up.type = GDK_BUTTON_RELEASE; 107 WebMouseEvent mouse_down_event; 108 WebMouseEvent mouse_up_event; 109 110 // Click for three times. 111 for (int i = 1; i < 4; ++i) { 112 mouse_down.time += 100; 113 mouse_down_event = WebMouseEventBuilder::Build(&mouse_down); 114 EXPECT_EQ(i, mouse_down_event.clickCount); 115 116 mouse_up.time = mouse_down.time + 50; 117 mouse_up_event = WebMouseEventBuilder::Build(&mouse_up); 118 EXPECT_EQ(i, mouse_up_event.clickCount); 119 } 120 121 // Reset the click count. 122 mouse_down.time += 10000; 123 mouse_down_event = WebMouseEventBuilder::Build(&mouse_down); 124 EXPECT_EQ(1, mouse_down_event.clickCount); 125 126 // Moving the cursor for a significant distance will reset the click count to 127 // 0. 128 GdkEventMotion mouse_move; 129 memset(&mouse_move, 0, sizeof(mouse_move)); 130 mouse_move.type = GDK_MOTION_NOTIFY; 131 mouse_move.window = mouse_down.window; 132 mouse_move.time = mouse_down.time; 133 mouse_move.x = mouse_move.y = mouse_move.x_root = mouse_move.y_root = 134 mouse_down.x + 100; 135 WebMouseEventBuilder::Build(&mouse_move); 136 137 mouse_up.time = mouse_down.time + 50; 138 mouse_up_event = WebMouseEventBuilder::Build(&mouse_up); 139 EXPECT_EQ(0, mouse_up_event.clickCount); 140 141 // Reset the click count. 142 mouse_down.time += 10000; 143 mouse_down_event = WebMouseEventBuilder::Build(&mouse_down); 144 EXPECT_EQ(1, mouse_down_event.clickCount); 145 146 // Moving the cursor with a significant delay will reset the click count to 0. 147 mouse_move.time = mouse_down.time + 1000; 148 mouse_move.x = mouse_move.y = mouse_move.x_root = mouse_move.y_root = 149 mouse_down.x; 150 WebMouseEventBuilder::Build(&mouse_move); 151 152 mouse_up.time = mouse_move.time + 50; 153 mouse_up_event = WebMouseEventBuilder::Build(&mouse_up); 154 EXPECT_EQ(0, mouse_up_event.clickCount); 155 } 156 157 TEST(WebKeyboardEventBuilderTest, NumPadConversion) { 158 // Construct a GDK input event for the numpad "5" key. 159 char five[] = "5"; 160 GdkEventKey gdk_event; 161 memset(&gdk_event, 0, sizeof(GdkEventKey)); 162 gdk_event.type = GDK_KEY_PRESS; 163 gdk_event.keyval = GDK_KP_5; 164 gdk_event.string = five; 165 166 // Numpad flag should be set on the WebKeyboardEvent. 167 WebKeyboardEvent web_event = WebKeyboardEventBuilder::Build(&gdk_event); 168 EXPECT_TRUE(web_event.modifiers & WebInputEvent::IsKeyPad); 169 } 170 171 } // anonymous namespace 172