| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. |
| 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
| 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 #include "sky/engine/platform/geometry/FloatPoint.h" | 62 #include "sky/engine/platform/geometry/FloatPoint.h" |
| 63 #include "sky/engine/platform/graphics/Image.h" | 63 #include "sky/engine/platform/graphics/Image.h" |
| 64 #include "sky/engine/platform/heap/Handle.h" | 64 #include "sky/engine/platform/heap/Handle.h" |
| 65 #include "sky/engine/wtf/Assertions.h" | 65 #include "sky/engine/wtf/Assertions.h" |
| 66 #include "sky/engine/wtf/CurrentTime.h" | 66 #include "sky/engine/wtf/CurrentTime.h" |
| 67 #include "sky/engine/wtf/StdLibExtras.h" | 67 #include "sky/engine/wtf/StdLibExtras.h" |
| 68 #include "sky/engine/wtf/TemporaryChange.h" | 68 #include "sky/engine/wtf/TemporaryChange.h" |
| 69 | 69 |
| 70 namespace blink { | 70 namespace blink { |
| 71 | 71 |
| 72 // The amount of time to wait for a cursor update on style and layout changes | |
| 73 // Set to 50Hz, no need to be faster than common screen refresh rate | |
| 74 static const double cursorUpdateInterval = 0.02; | |
| 75 | |
| 76 static const int maximumCursorSize = 128; | |
| 77 | |
| 78 // It's pretty unlikely that a scale of less than one would ever be used. But al
l we really | |
| 79 // need to ensure here is that the scale isn't so small that integer overflow ca
n occur when | |
| 80 // dividing cursor sizes (limited above) by the scale. | |
| 81 static const double minimumCursorScale = 0.001; | |
| 82 | |
| 83 enum NoCursorChangeType { NoCursorChange }; | |
| 84 | |
| 85 class OptionalCursor { | |
| 86 public: | |
| 87 OptionalCursor(NoCursorChangeType) : m_isCursorChange(false) { } | |
| 88 OptionalCursor(const Cursor& cursor) : m_isCursorChange(true), m_cursor(curs
or) { } | |
| 89 | |
| 90 bool isCursorChange() const { return m_isCursorChange; } | |
| 91 const Cursor& cursor() const { ASSERT(m_isCursorChange); return m_cursor; } | |
| 92 | |
| 93 private: | |
| 94 bool m_isCursorChange; | |
| 95 Cursor m_cursor; | |
| 96 }; | |
| 97 | |
| 98 class MaximumDurationTracker { | 72 class MaximumDurationTracker { |
| 99 public: | 73 public: |
| 100 explicit MaximumDurationTracker(double *maxDuration) | 74 explicit MaximumDurationTracker(double *maxDuration) |
| 101 : m_maxDuration(maxDuration) | 75 : m_maxDuration(maxDuration) |
| 102 , m_start(monotonicallyIncreasingTime()) | 76 , m_start(monotonicallyIncreasingTime()) |
| 103 { | 77 { |
| 104 } | 78 } |
| 105 | 79 |
| 106 ~MaximumDurationTracker() | 80 ~MaximumDurationTracker() |
| 107 { | 81 { |
| 108 *m_maxDuration = max(*m_maxDuration, monotonicallyIncreasingTime() - m_s
tart); | 82 *m_maxDuration = max(*m_maxDuration, monotonicallyIncreasingTime() - m_s
tart); |
| 109 } | 83 } |
| 110 | 84 |
| 111 private: | 85 private: |
| 112 double* m_maxDuration; | 86 double* m_maxDuration; |
| 113 double m_start; | 87 double m_start; |
| 114 }; | 88 }; |
| 115 | 89 |
| 116 EventHandler::EventHandler(LocalFrame* frame) | 90 EventHandler::EventHandler(LocalFrame* frame) |
| 117 : m_frame(frame) | 91 : m_frame(frame) |
| 118 , m_capturesDragging(false) | 92 , m_capturesDragging(false) |
| 119 , m_selectionInitiationState(HaveNotStartedSelection) | 93 , m_selectionInitiationState(HaveNotStartedSelection) |
| 120 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired) | |
| 121 , m_clickCount(0) | 94 , m_clickCount(0) |
| 122 , m_shouldOnlyFireDragOverEvent(false) | 95 , m_shouldOnlyFireDragOverEvent(false) |
| 123 , m_didStartDrag(false) | 96 , m_didStartDrag(false) |
| 124 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) | 97 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) |
| 125 , m_lastShowPressTimestamp(0) | 98 , m_lastShowPressTimestamp(0) |
| 126 { | 99 { |
| 127 } | 100 } |
| 128 | 101 |
| 129 EventHandler::~EventHandler() | 102 EventHandler::~EventHandler() |
| 130 { | 103 { |
| 131 } | 104 } |
| 132 | 105 |
| 133 void EventHandler::clear() | 106 void EventHandler::clear() |
| 134 { | 107 { |
| 135 m_cursorUpdateTimer.stop(); | |
| 136 m_activeIntervalTimer.stop(); | 108 m_activeIntervalTimer.stop(); |
| 137 m_clickCount = 0; | 109 m_clickCount = 0; |
| 138 m_clickNode = nullptr; | 110 m_clickNode = nullptr; |
| 139 m_dragTarget = nullptr; | 111 m_dragTarget = nullptr; |
| 140 m_shouldOnlyFireDragOverEvent = false; | 112 m_shouldOnlyFireDragOverEvent = false; |
| 141 m_capturesDragging = false; | 113 m_capturesDragging = false; |
| 142 m_didStartDrag = false; | 114 m_didStartDrag = false; |
| 143 m_lastShowPressTimestamp = 0; | 115 m_lastShowPressTimestamp = 0; |
| 144 m_lastDeferredTapElement = nullptr; | 116 m_lastDeferredTapElement = nullptr; |
| 145 } | 117 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 172 if (!m_frame->contentRenderer() || !m_frame->view() || !m_frame->view()->did
FirstLayout()) | 144 if (!m_frame->contentRenderer() || !m_frame->view() || !m_frame->view()->did
FirstLayout()) |
| 173 return result; | 145 return result; |
| 174 | 146 |
| 175 // hitTestResultAtPoint is specifically used to hitTest into all frames, thu
s it always allows child frame content. | 147 // hitTestResultAtPoint is specifically used to hitTest into all frames, thu
s it always allows child frame content. |
| 176 HitTestRequest request(hitType); | 148 HitTestRequest request(hitType); |
| 177 m_frame->contentRenderer()->hitTest(request, result); | 149 m_frame->contentRenderer()->hitTest(request, result); |
| 178 | 150 |
| 179 return result; | 151 return result; |
| 180 } | 152 } |
| 181 | 153 |
| 182 void EventHandler::cursorUpdateTimerFired(Timer<EventHandler>*) | |
| 183 { | |
| 184 ASSERT(m_frame); | |
| 185 ASSERT(m_frame->document()); | |
| 186 | |
| 187 updateCursor(); | |
| 188 } | |
| 189 | |
| 190 void EventHandler::updateCursor() | |
| 191 { | |
| 192 } | |
| 193 | |
| 194 OptionalCursor EventHandler::selectCursor(const HitTestResult& result) | |
| 195 { | |
| 196 Page* page = m_frame->page(); | |
| 197 if (!page) | |
| 198 return NoCursorChange; | |
| 199 | |
| 200 Node* node = result.innerPossiblyPseudoNode(); | |
| 201 if (!node) | |
| 202 return selectAutoCursor(result, node); | |
| 203 | |
| 204 RenderObject* renderer = node->renderer(); | |
| 205 RenderStyle* style = renderer ? renderer->style() : 0; | |
| 206 | |
| 207 if (renderer) { | |
| 208 Cursor overrideCursor; | |
| 209 switch (renderer->getCursor(roundedIntPoint(result.localPoint()), overri
deCursor)) { | |
| 210 case SetCursorBasedOnStyle: | |
| 211 break; | |
| 212 case SetCursor: | |
| 213 return overrideCursor; | |
| 214 case DoNotSetCursor: | |
| 215 return NoCursorChange; | |
| 216 } | |
| 217 } | |
| 218 | |
| 219 if (style && style->cursors()) { | |
| 220 const CursorList* cursors = style->cursors(); | |
| 221 for (unsigned i = 0; i < cursors->size(); ++i) { | |
| 222 StyleImage* styleImage = (*cursors)[i].image(); | |
| 223 if (!styleImage) | |
| 224 continue; | |
| 225 ImageResource* cachedImage = styleImage->cachedImage(); | |
| 226 if (!cachedImage) | |
| 227 continue; | |
| 228 float scale = styleImage->imageScaleFactor(); | |
| 229 // Get hotspot and convert from logical pixels to physical pixels. | |
| 230 IntPoint hotSpot = (*cursors)[i].hotSpot(); | |
| 231 hotSpot.scale(scale, scale); | |
| 232 IntSize size = cachedImage->imageForRenderer(renderer)->size(); | |
| 233 if (cachedImage->errorOccurred()) | |
| 234 continue; | |
| 235 // Limit the size of cursors (in UI pixels) so that they cannot be | |
| 236 // used to cover UI elements in chrome. | |
| 237 size.scale(1 / scale); | |
| 238 if (size.width() > maximumCursorSize || size.height() > maximumCurso
rSize) | |
| 239 continue; | |
| 240 | |
| 241 Image* image = cachedImage->imageForRenderer(renderer); | |
| 242 // Ensure no overflow possible in calculations above. | |
| 243 if (scale < minimumCursorScale) | |
| 244 continue; | |
| 245 return Cursor(image, hotSpot, scale); | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 switch (style ? style->cursor() : CURSOR_AUTO) { | |
| 250 case CURSOR_AUTO: { | |
| 251 return selectAutoCursor(result, node); | |
| 252 } | |
| 253 case CURSOR_CROSS: | |
| 254 return crossCursor(); | |
| 255 case CURSOR_POINTER: | |
| 256 return handCursor(); | |
| 257 case CURSOR_MOVE: | |
| 258 return moveCursor(); | |
| 259 case CURSOR_ALL_SCROLL: | |
| 260 return moveCursor(); | |
| 261 case CURSOR_E_RESIZE: | |
| 262 return eastResizeCursor(); | |
| 263 case CURSOR_W_RESIZE: | |
| 264 return westResizeCursor(); | |
| 265 case CURSOR_N_RESIZE: | |
| 266 return northResizeCursor(); | |
| 267 case CURSOR_S_RESIZE: | |
| 268 return southResizeCursor(); | |
| 269 case CURSOR_NE_RESIZE: | |
| 270 return northEastResizeCursor(); | |
| 271 case CURSOR_SW_RESIZE: | |
| 272 return southWestResizeCursor(); | |
| 273 case CURSOR_NW_RESIZE: | |
| 274 return northWestResizeCursor(); | |
| 275 case CURSOR_SE_RESIZE: | |
| 276 return southEastResizeCursor(); | |
| 277 case CURSOR_NS_RESIZE: | |
| 278 return northSouthResizeCursor(); | |
| 279 case CURSOR_EW_RESIZE: | |
| 280 return eastWestResizeCursor(); | |
| 281 case CURSOR_NESW_RESIZE: | |
| 282 return northEastSouthWestResizeCursor(); | |
| 283 case CURSOR_NWSE_RESIZE: | |
| 284 return northWestSouthEastResizeCursor(); | |
| 285 case CURSOR_COL_RESIZE: | |
| 286 return columnResizeCursor(); | |
| 287 case CURSOR_ROW_RESIZE: | |
| 288 return rowResizeCursor(); | |
| 289 case CURSOR_TEXT: | |
| 290 return iBeamCursor(); | |
| 291 case CURSOR_WAIT: | |
| 292 return waitCursor(); | |
| 293 case CURSOR_HELP: | |
| 294 return helpCursor(); | |
| 295 case CURSOR_VERTICAL_TEXT: | |
| 296 return verticalTextCursor(); | |
| 297 case CURSOR_CELL: | |
| 298 return cellCursor(); | |
| 299 case CURSOR_CONTEXT_MENU: | |
| 300 return contextMenuCursor(); | |
| 301 case CURSOR_PROGRESS: | |
| 302 return progressCursor(); | |
| 303 case CURSOR_NO_DROP: | |
| 304 return noDropCursor(); | |
| 305 case CURSOR_ALIAS: | |
| 306 return aliasCursor(); | |
| 307 case CURSOR_COPY: | |
| 308 return copyCursor(); | |
| 309 case CURSOR_NONE: | |
| 310 return noneCursor(); | |
| 311 case CURSOR_NOT_ALLOWED: | |
| 312 return notAllowedCursor(); | |
| 313 case CURSOR_DEFAULT: | |
| 314 return pointerCursor(); | |
| 315 case CURSOR_ZOOM_IN: | |
| 316 return zoomInCursor(); | |
| 317 case CURSOR_ZOOM_OUT: | |
| 318 return zoomOutCursor(); | |
| 319 case CURSOR_WEBKIT_GRAB: | |
| 320 return grabCursor(); | |
| 321 case CURSOR_WEBKIT_GRABBING: | |
| 322 return grabbingCursor(); | |
| 323 } | |
| 324 return pointerCursor(); | |
| 325 } | |
| 326 | |
| 327 OptionalCursor EventHandler::selectAutoCursor(const HitTestResult& result, Node*
node) | |
| 328 { | |
| 329 RenderObject* renderer = node ? node->renderer() : 0; | |
| 330 if (!node || !renderer) | |
| 331 return pointerCursor(); | |
| 332 if (node->hasEditableStyle() || (renderer->isText() && node->canStartSelecti
on())) | |
| 333 return iBeamCursor(); | |
| 334 return pointerCursor(); | |
| 335 } | |
| 336 | |
| 337 void EventHandler::invalidateClick() | 154 void EventHandler::invalidateClick() |
| 338 { | 155 { |
| 339 m_clickCount = 0; | 156 m_clickCount = 0; |
| 340 m_clickNode = nullptr; | 157 m_clickNode = nullptr; |
| 341 } | 158 } |
| 342 | 159 |
| 343 void EventHandler::scheduleCursorUpdate() | |
| 344 { | |
| 345 if (!m_cursorUpdateTimer.isActive()) | |
| 346 m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, FROM_HERE); | |
| 347 } | |
| 348 | |
| 349 bool EventHandler::isCursorVisible() const | |
| 350 { | |
| 351 return m_frame->page()->isCursorVisible(); | |
| 352 } | |
| 353 | |
| 354 void EventHandler::activeIntervalTimerFired(Timer<EventHandler>*) | 160 void EventHandler::activeIntervalTimerFired(Timer<EventHandler>*) |
| 355 { | 161 { |
| 356 m_activeIntervalTimer.stop(); | 162 m_activeIntervalTimer.stop(); |
| 357 m_lastDeferredTapElement = nullptr; | 163 m_lastDeferredTapElement = nullptr; |
| 358 } | 164 } |
| 359 | 165 |
| 360 void EventHandler::notifyElementActivated() | 166 void EventHandler::notifyElementActivated() |
| 361 { | 167 { |
| 362 // Since another element has been set to active, stop current timer and clea
r reference. | 168 // Since another element has been set to active, stop current timer and clea
r reference. |
| 363 if (m_activeIntervalTimer.isActive()) | 169 if (m_activeIntervalTimer.isActive()) |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 | 297 |
| 492 void EventHandler::focusDocumentView() | 298 void EventHandler::focusDocumentView() |
| 493 { | 299 { |
| 494 Page* page = m_frame->page(); | 300 Page* page = m_frame->page(); |
| 495 if (!page) | 301 if (!page) |
| 496 return; | 302 return; |
| 497 page->focusController().focusDocumentView(m_frame); | 303 page->focusController().focusDocumentView(m_frame); |
| 498 } | 304 } |
| 499 | 305 |
| 500 } // namespace blink | 306 } // namespace blink |
| OLD | NEW |