OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" | |
6 | |
5 #include <QuartzCore/QuartzCore.h> | 7 #include <QuartzCore/QuartzCore.h> |
6 | 8 |
7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" | 9 #include <cmath> |
8 | 10 |
9 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 12 #include "base/logging.h" |
11 #include "base/mac/mac_util.h" | 13 #include "base/mac/mac_util.h" |
12 #include "base/mac/scoped_cftyperef.h" | 14 #include "base/mac/scoped_cftyperef.h" |
13 #import "base/mac/scoped_nsautorelease_pool.h" | 15 #import "base/mac/scoped_nsautorelease_pool.h" |
14 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
15 #import "base/memory/scoped_nsobject.h" | 17 #import "base/memory/scoped_nsobject.h" |
16 #include "base/string_util.h" | 18 #include "base/string_util.h" |
17 #include "base/sys_info.h" | 19 #include "base/sys_info.h" |
18 #include "base/sys_string_conversions.h" | 20 #include "base/sys_string_conversions.h" |
19 #include "chrome/browser/browser_trial.h" | 21 #include "chrome/browser/browser_trial.h" |
22 #include "chrome/browser/mac/closure_blocks_leopard_compat.h" | |
20 #import "chrome/browser/renderer_host/accelerated_plugin_view_mac.h" | 23 #import "chrome/browser/renderer_host/accelerated_plugin_view_mac.h" |
21 #import "chrome/browser/renderer_host/text_input_client_mac.h" | 24 #import "chrome/browser/renderer_host/text_input_client_mac.h" |
22 #include "chrome/browser/spellchecker/spellchecker_platform_engine.h" | 25 #include "chrome/browser/spellchecker/spellchecker_platform_engine.h" |
26 #include "chrome/browser/ui/browser.h" | |
27 #include "chrome/browser/ui/browser_list.h" | |
23 #import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h" | 28 #import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h" |
24 #import "chrome/browser/ui/cocoa/view_id_util.h" | 29 #import "chrome/browser/ui/cocoa/view_id_util.h" |
25 #include "chrome/common/render_messages.h" | 30 #include "chrome/common/render_messages.h" |
26 #include "chrome/common/spellcheck_messages.h" | 31 #include "chrome/common/spellcheck_messages.h" |
27 #import "content/browser/accessibility/browser_accessibility_cocoa.h" | 32 #import "content/browser/accessibility/browser_accessibility_cocoa.h" |
28 #include "content/browser/browser_thread.h" | 33 #include "content/browser/browser_thread.h" |
29 #include "content/browser/gpu/gpu_process_host.h" | 34 #include "content/browser/gpu/gpu_process_host.h" |
30 #include "content/browser/gpu/gpu_process_host_ui_shim.h" | 35 #include "content/browser/gpu/gpu_process_host_ui_shim.h" |
31 #include "content/browser/plugin_process_host.h" | 36 #include "content/browser/plugin_process_host.h" |
32 #include "content/browser/renderer_host/backing_store_mac.h" | 37 #include "content/browser/renderer_host/backing_store_mac.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
49 #include "ui/gfx/surface/io_surface_support_mac.h" | 54 #include "ui/gfx/surface/io_surface_support_mac.h" |
50 #include "webkit/glue/webaccessibility.h" | 55 #include "webkit/glue/webaccessibility.h" |
51 #include "webkit/plugins/npapi/webplugin.h" | 56 #include "webkit/plugins/npapi/webplugin.h" |
52 | 57 |
53 using WebKit::WebInputEvent; | 58 using WebKit::WebInputEvent; |
54 using WebKit::WebInputEventFactory; | 59 using WebKit::WebInputEventFactory; |
55 using WebKit::WebMouseEvent; | 60 using WebKit::WebMouseEvent; |
56 using WebKit::WebMouseWheelEvent; | 61 using WebKit::WebMouseWheelEvent; |
57 using WebKit::WebGestureEvent; | 62 using WebKit::WebGestureEvent; |
58 | 63 |
64 // Forward-declare symbols that are part of the 10.7 SDK. | |
Mark Mentovai
2011/08/15 16:55:36
These are just declarations. Not too much about th
Nico
2011/08/15 17:05:30
Removed "Forward-".
| |
65 #if !defined(MAC_OS_X_VERSION_10_7) || \ | |
66 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | |
67 | |
68 enum { | |
69 NSEventPhaseNone = 0, // event not associated with a phase. | |
70 NSEventPhaseBegan = 0x1 << 0, | |
71 NSEventPhaseStationary = 0x1 << 1, | |
72 NSEventPhaseChanged = 0x1 << 2, | |
73 NSEventPhaseEnded = 0x1 << 3, | |
74 NSEventPhaseCancelled = 0x1 << 4, | |
75 }; | |
76 typedef NSUInteger NSEventPhase; | |
77 | |
78 enum { | |
79 NSEventSwipeTrackingLockDirection = 0x1 << 0, | |
80 NSEventSwipeTrackingClampGestureAmount = 0x1 << 1 | |
81 }; | |
82 typedef NSUInteger NSEventSwipeTrackingOptions; | |
83 | |
84 | |
85 @interface NSEvent (LionAPI) | |
86 + (BOOL)isSwipeTrackingFromScrollEventsEnabled; | |
87 | |
88 - (NSEventPhase)phase; | |
89 - (CGFloat)scrollingDeltaX; | |
90 - (CGFloat)scrollingDeltaY; | |
91 - (void)trackSwipeEventWithOptions:(NSEventSwipeTrackingOptions)options | |
92 dampenAmountThresholdMin:(CGFloat)minDampenThreshold | |
93 max:(CGFloat)maxDampenThreshold | |
94 usingHandler:(void (^)(CGFloat gestureAmount, | |
95 NSEventPhase phase, | |
96 BOOL isComplete, | |
97 BOOL *stop))trackingHandler; | |
98 @end | |
99 | |
100 #endif // 10.7 | |
101 | |
59 static inline int ToWebKitModifiers(NSUInteger flags) { | 102 static inline int ToWebKitModifiers(NSUInteger flags) { |
60 int modifiers = 0; | 103 int modifiers = 0; |
61 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; | 104 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; |
62 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; | 105 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; |
63 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; | 106 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; |
64 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; | 107 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; |
65 return modifiers; | 108 return modifiers; |
66 } | 109 } |
67 | 110 |
68 // Private methods: | 111 // Private methods: |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1011 | 1054 |
1012 void RenderWidgetHostViewMac::ForceTextureReload() { | 1055 void RenderWidgetHostViewMac::ForceTextureReload() { |
1013 plugin_container_manager_.ForceTextureReload(); | 1056 plugin_container_manager_.ForceTextureReload(); |
1014 } | 1057 } |
1015 | 1058 |
1016 void RenderWidgetHostViewMac::SetVisuallyDeemphasized(const SkColor* color, | 1059 void RenderWidgetHostViewMac::SetVisuallyDeemphasized(const SkColor* color, |
1017 bool animate) { | 1060 bool animate) { |
1018 // This is not used on mac. | 1061 // This is not used on mac. |
1019 } | 1062 } |
1020 | 1063 |
1064 void RenderWidgetHostViewMac::UnhandledWheelEvent( | |
1065 const WebKit::WebMouseWheelEvent& event) { | |
1066 [cocoa_view_ setGotUnhandledWheelEvent:YES]; | |
1067 } | |
1068 | |
1069 void RenderWidgetHostViewMac::SetHasHorizontalScrollbar( | |
1070 bool has_horizontal_scrollbar) { | |
1071 [cocoa_view_ setHasHorizontalScrollbar:has_horizontal_scrollbar]; | |
1072 } | |
1073 | |
1074 void RenderWidgetHostViewMac::SetScrollOffsetPinning( | |
1075 bool is_pinned_to_left, bool is_pinned_to_right) { | |
1076 [cocoa_view_ setPinnedLeft:is_pinned_to_left]; | |
1077 [cocoa_view_ setPinnedRight:is_pinned_to_right]; | |
1078 } | |
1079 | |
1021 void RenderWidgetHostViewMac::ShutdownHost() { | 1080 void RenderWidgetHostViewMac::ShutdownHost() { |
1022 shutdown_factory_.RevokeAll(); | 1081 shutdown_factory_.RevokeAll(); |
1023 render_widget_host_->Shutdown(); | 1082 render_widget_host_->Shutdown(); |
1024 // Do not touch any members at this point, |this| has been deleted. | 1083 // Do not touch any members at this point, |this| has been deleted. |
1025 } | 1084 } |
1026 | 1085 |
1027 gfx::Rect RenderWidgetHostViewMac::GetViewCocoaBounds() const { | 1086 gfx::Rect RenderWidgetHostViewMac::GetViewCocoaBounds() const { |
1028 return gfx::Rect(NSRectToCGRect([cocoa_view_ bounds])); | 1087 return gfx::Rect(NSRectToCGRect([cocoa_view_ bounds])); |
1029 } | 1088 } |
1030 | 1089 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1094 DisablePasswordInput(); | 1153 DisablePasswordInput(); |
1095 } | 1154 } |
1096 } | 1155 } |
1097 | 1156 |
1098 // RenderWidgetHostViewCocoa --------------------------------------------------- | 1157 // RenderWidgetHostViewCocoa --------------------------------------------------- |
1099 | 1158 |
1100 @implementation RenderWidgetHostViewCocoa | 1159 @implementation RenderWidgetHostViewCocoa |
1101 | 1160 |
1102 @synthesize selectedRange = selectedRange_; | 1161 @synthesize selectedRange = selectedRange_; |
1103 @synthesize markedRange = markedRange_; | 1162 @synthesize markedRange = markedRange_; |
1163 @synthesize gotUnhandledWheelEvent = gotUnhandledWheelEvent_; | |
1164 @synthesize isPinnedLeft = isPinnedLeft_; | |
1165 @synthesize isPinnedRight = isPinnedRight_; | |
1166 @synthesize hasHorizontalScrollbar = hasHorizontalScrollbar_; | |
1104 | 1167 |
1105 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 1168 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
1106 self = [super initWithFrame:NSZeroRect]; | 1169 self = [super initWithFrame:NSZeroRect]; |
1107 if (self) { | 1170 if (self) { |
1108 editCommand_helper_.reset(new RWHVMEditCommandHelper); | 1171 editCommand_helper_.reset(new RWHVMEditCommandHelper); |
1109 editCommand_helper_->AddEditingSelectorsToClass([self class]); | 1172 editCommand_helper_->AddEditingSelectorsToClass([self class]); |
1110 | 1173 |
1111 renderWidgetHostView_.reset(r); | 1174 renderWidgetHostView_.reset(r); |
1112 canBeKeyView_ = YES; | 1175 canBeKeyView_ = YES; |
1113 focusedPluginIdentifier_ = -1; | 1176 focusedPluginIdentifier_ = -1; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1224 renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); | 1287 renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); |
1225 } | 1288 } |
1226 | 1289 |
1227 - (void)beginGestureWithEvent:(NSEvent*)event { | 1290 - (void)beginGestureWithEvent:(NSEvent*)event { |
1228 if (base::mac::IsOSLionOrLater() && | 1291 if (base::mac::IsOSLionOrLater() && |
1229 [event subtype] == kIOHIDEventTypeScroll && | 1292 [event subtype] == kIOHIDEventTypeScroll && |
1230 renderWidgetHostView_->render_widget_host_) { | 1293 renderWidgetHostView_->render_widget_host_) { |
1231 WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); | 1294 WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); |
1232 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); | 1295 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); |
1233 } | 1296 } |
1234 | |
1235 // Forward the gesture event to the next responder so that the browser window | |
1236 // controller has a chance to act on back/forward gestures. | |
1237 [[self nextResponder] beginGestureWithEvent:event]; | |
Mark Mentovai
2011/08/15 16:55:36
Nice subtraction. Thanks to Alexei for catching it
| |
1238 } | 1297 } |
1239 | 1298 |
1240 - (void)endGestureWithEvent:(NSEvent*)event { | 1299 - (void)endGestureWithEvent:(NSEvent*)event { |
1241 if (base::mac::IsOSLionOrLater() && | 1300 if (base::mac::IsOSLionOrLater() && |
1242 [event subtype] == kIOHIDEventTypeScroll && | 1301 [event subtype] == kIOHIDEventTypeScroll && |
1243 renderWidgetHostView_->render_widget_host_) { | 1302 renderWidgetHostView_->render_widget_host_) { |
1244 WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); | 1303 WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self); |
1245 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); | 1304 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent); |
1246 } | 1305 } |
1247 | |
1248 // Forward the gesture event to the next responder so that the browser window | |
1249 // controller has a chance to act on back/forward gestures. | |
1250 [[self nextResponder] endGestureWithEvent:event]; | |
1251 } | 1306 } |
1252 | 1307 |
1253 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { | 1308 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { |
1254 // |performKeyEquivalent:| is sent to all views of a window, not only down the | 1309 // |performKeyEquivalent:| is sent to all views of a window, not only down the |
1255 // responder chain (cf. "Handling Key Equivalents" in | 1310 // responder chain (cf. "Handling Key Equivalents" in |
1256 // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Event Overview/HandlingKeyEvents/HandlingKeyEvents.html | 1311 // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Event Overview/HandlingKeyEvents/HandlingKeyEvents.html |
1257 // ). We only want to handle key equivalents if we're first responder. | 1312 // ). We only want to handle key equivalents if we're first responder. |
1258 if ([[self window] firstResponder] != self) | 1313 if ([[self window] firstResponder] != self) |
1259 return NO; | 1314 return NO; |
1260 | 1315 |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1490 event.skip_in_browser = true; | 1545 event.skip_in_browser = true; |
1491 widgetHost->ForwardKeyboardEvent(event); | 1546 widgetHost->ForwardKeyboardEvent(event); |
1492 } | 1547 } |
1493 } | 1548 } |
1494 | 1549 |
1495 // Possibly autohide the cursor. | 1550 // Possibly autohide the cursor. |
1496 if ([RenderWidgetHostViewCocoa shouldAutohideCursorForEvent:theEvent]) | 1551 if ([RenderWidgetHostViewCocoa shouldAutohideCursorForEvent:theEvent]) |
1497 [NSCursor setHiddenUntilMouseMoves:YES]; | 1552 [NSCursor setHiddenUntilMouseMoves:YES]; |
1498 } | 1553 } |
1499 | 1554 |
1500 - (void)scrollWheel:(NSEvent *)theEvent { | 1555 - (BOOL)maybeHandleHistorySwiping:(NSEvent*)theEvent { |
Mark Mentovai
2011/08/15 16:55:36
Since you don’t declare this in an @interface, you
Nico
2011/08/15 17:05:30
Done.
| |
1556 BOOL canUseLionApis = [theEvent respondsToSelector:@selector(phase)]; | |
1557 if (!canUseLionApis) | |
1558 return NO; | |
1559 | |
1560 // Scroll events always go to the web first, and can only trigger history | |
1561 // swiping if they come back unhandled. | |
1562 if ([theEvent phase] == NSEventPhaseBegan) { | |
1563 totalScrollDelta_ = NSZeroSize; | |
1564 gotUnhandledWheelEvent_ = false; | |
1565 } | |
1566 | |
1567 if (gotUnhandledWheelEvent_ && | |
1568 [NSEvent isSwipeTrackingFromScrollEventsEnabled] && | |
1569 [theEvent phase] == NSEventPhaseChanged) { | |
1570 totalScrollDelta_.width += [theEvent scrollingDeltaX]; | |
1571 totalScrollDelta_.height += [theEvent scrollingDeltaY]; | |
1572 | |
1573 bool isHorizontalGesture = | |
1574 std::abs(totalScrollDelta_.width) > std::abs(totalScrollDelta_.height); | |
Mark Mentovai
2011/08/15 16:55:36
Are the |abs| calls helpful here at all? Can’t we
Nico
2011/08/15 17:05:30
Yes, width and height can be both positive or nega
Mark Mentovai
2011/08/15 17:58:24
Nico wrote:
| |
1575 | |
1576 bool isRightScroll = [theEvent scrollingDeltaX] < 0; | |
1577 bool goForward = isRightScroll; | |
1578 | |
1579 if (isHorizontalGesture && | |
1580 // If "forward" is inactive and the user rubber-bands to the right, | |
1581 // "isPinnedLeft" will be false. When the user then rubber-bands to | |
1582 // the left in the same gesture, that should trigger history | |
1583 // immediately if there's no scrollbar, hence the check for | |
1584 // hasHorizontalScrollbar_. | |
1585 (!hasHorizontalScrollbar_ || | |
1586 // One would think we have to check canGoBack / canGoForward here, but | |
1587 // that's actually done in the renderer | |
1588 // (ChromeClientImpl::shouldRubberBand()), when it decides if it should | |
1589 // rubberband or send back an event unhandled. | |
1590 (isPinnedLeft_ && !isRightScroll) || | |
1591 (isPinnedRight_ && isRightScroll))) { | |
1592 // The way this api works: gestureAmount is between -1 and 1 (float). If | |
1593 // the user does the gesture for more than about 25% (i.e. < -0.25 or > | |
1594 // 0.25) and then lets go, it is accepted, we get a NSEventPhaseEnded, | |
1595 // and after that the block is called with amounts animating towards 1 | |
1596 // (or -1, depending on the direction). If the user lets go below that | |
1597 // threshold, we get NSEventPhaseCancelled, and the amount animates | |
1598 // toward 0. | |
1599 [theEvent trackSwipeEventWithOptions:0 | |
1600 dampenAmountThresholdMin:-1 | |
1601 max:1 | |
1602 usingHandler:^(CGFloat gestureAmount, | |
1603 NSEventPhase phase, | |
1604 BOOL isComplete, | |
1605 BOOL *stop) { | |
1606 // |gestureAmount| obeys -[NSEvent isDirectionInvertedFromDevice] | |
1607 // automatically. | |
1608 // TODO(thakis): UI. | |
1609 Browser* browser = BrowserList::GetLastActive(); | |
1610 if (phase == NSEventPhaseEnded && browser) { | |
1611 if (goForward) | |
1612 browser->GoForward(CURRENT_TAB); | |
1613 else | |
1614 browser->GoBack(CURRENT_TAB); | |
1615 } | |
1616 }]; | |
1617 return YES; | |
1618 } | |
1619 } | |
1620 return NO; | |
1621 } | |
1622 | |
1623 - (void)scrollWheel:(NSEvent*)theEvent { | |
1501 [self cancelChildPopups]; | 1624 [self cancelChildPopups]; |
1502 | 1625 |
1626 if ([self maybeHandleHistorySwiping:theEvent]) | |
1627 return; | |
1628 | |
1503 const WebMouseWheelEvent& event = | 1629 const WebMouseWheelEvent& event = |
1504 WebInputEventFactory::mouseWheelEvent(theEvent, self); | 1630 WebInputEventFactory::mouseWheelEvent(theEvent, self); |
1505 if (renderWidgetHostView_->render_widget_host_) | 1631 if (renderWidgetHostView_->render_widget_host_) |
1506 renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(event); | 1632 renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(event); |
1507 } | 1633 } |
1508 | 1634 |
1509 // See the comment in RenderWidgetHostViewMac::Destroy() about cancellation | 1635 // See the comment in RenderWidgetHostViewMac::Destroy() about cancellation |
1510 // events. On the Mac we must kill popups on outside events, thus this lovely | 1636 // events. On the Mac we must kill popups on outside events, thus this lovely |
1511 // case of filicide caused by events on parent views. | 1637 // case of filicide caused by events on parent views. |
1512 - (void)cancelChildPopups { | 1638 - (void)cancelChildPopups { |
(...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2761 if (!string) return NO; | 2887 if (!string) return NO; |
2762 | 2888 |
2763 // If the user is currently using an IME, confirm the IME input, | 2889 // If the user is currently using an IME, confirm the IME input, |
2764 // and then insert the text from the service, the same as TextEdit and Safari. | 2890 // and then insert the text from the service, the same as TextEdit and Safari. |
2765 [self confirmComposition]; | 2891 [self confirmComposition]; |
2766 [self insertText:string]; | 2892 [self insertText:string]; |
2767 return YES; | 2893 return YES; |
2768 } | 2894 } |
2769 | 2895 |
2770 @end | 2896 @end |
OLD | NEW |