Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(616)

Side by Side Diff: chrome/browser/renderer_host/render_widget_host_view_mac.mm

Issue 7582009: [Mac] Rubber-banding on Lion. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <QuartzCore/QuartzCore.h> 5 #include <QuartzCore/QuartzCore.h>
6 6
7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" 7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h"
8 8
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 26 matching lines...) Expand all
37 #include "content/common/gpu/gpu_messages.h" 37 #include "content/common/gpu/gpu_messages.h"
38 #include "content/common/native_web_keyboard_event.h" 38 #include "content/common/native_web_keyboard_event.h"
39 #include "content/common/plugin_messages.h" 39 #include "content/common/plugin_messages.h"
40 #include "content/common/view_messages.h" 40 #include "content/common/view_messages.h"
41 #include "skia/ext/platform_canvas.h" 41 #include "skia/ext/platform_canvas.h"
42 #import "third_party/mozilla/ComplexTextInputPanel.h" 42 #import "third_party/mozilla/ComplexTextInputPanel.h"
43 #include "third_party/skia/include/core/SkColor.h" 43 #include "third_party/skia/include/core/SkColor.h"
44 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFact ory.h" 44 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFact ory.h"
45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" 45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
46 #include "ui/gfx/point.h" 46 #include "ui/gfx/point.h"
47 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
47 #include "ui/gfx/surface/io_surface_support_mac.h" 48 #include "ui/gfx/surface/io_surface_support_mac.h"
48 #include "webkit/glue/webaccessibility.h" 49 #include "webkit/glue/webaccessibility.h"
49 #include "webkit/plugins/npapi/webplugin.h" 50 #include "webkit/plugins/npapi/webplugin.h"
50 51
51 using WebKit::WebInputEvent; 52 using WebKit::WebInputEvent;
52 using WebKit::WebInputEventFactory; 53 using WebKit::WebInputEventFactory;
53 using WebKit::WebMouseEvent; 54 using WebKit::WebMouseEvent;
54 using WebKit::WebMouseWheelEvent; 55 using WebKit::WebMouseWheelEvent;
56 using WebKit::WebGestureEvent;
55 57
56 static inline int ToWebKitModifiers(NSUInteger flags) { 58 static inline int ToWebKitModifiers(NSUInteger flags) {
57 int modifiers = 0; 59 int modifiers = 0;
58 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; 60 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey;
59 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; 61 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey;
60 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; 62 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey;
61 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; 63 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey;
62 return modifiers; 64 return modifiers;
63 } 65 }
64 66
65 // Private methods: 67 // Private methods:
66 @interface RenderWidgetHostViewCocoa () 68 @interface RenderWidgetHostViewCocoa ()
67 @property(nonatomic, assign) NSRange selectedRange; 69 @property(nonatomic, assign) NSRange selectedRange;
68 @property(nonatomic, assign) NSRange markedRange; 70 @property(nonatomic, assign) NSRange markedRange;
69 71
70 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; 72 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event;
71 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; 73 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r;
72 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv; 74 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv;
73 - (void)cancelChildPopups; 75 - (void)cancelChildPopups;
74 - (void)checkForPluginImeCancellation; 76 - (void)checkForPluginImeCancellation;
75 @end 77 @end
76 78
77 // This API was published since 10.6. Provide the declaration so it can be 79 // This API was published since 10.6. Provide the declaration so it can be
78 // // called below when building with the 10.5 SDK. 80 // called below when building with the 10.5 SDK.
79 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 81 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
80 @class NSTextInputContext; 82 @class NSTextInputContext;
81 @interface NSResponder (AppKitDetails) 83 @interface NSResponder (AppKitDetails)
82 - (NSTextInputContext *)inputContext; 84 - (NSTextInputContext *)inputContext;
83 @end 85 @end
84 #endif 86 #endif
85 87
88 // Undocumented Lion method to get the pattern for the over-scroll area.
89 @interface NSColor (LionSekretAPI)
90 + (NSImage*)_linenPatternImage;
91 @end
92
93 // NSEvent subtype for scroll gestures events.
94 static const short kIOHIDEventTypeScroll = 6;
95
86 namespace { 96 namespace {
87 97
88 // Maximum number of characters we allow in a tooltip. 98 // Maximum number of characters we allow in a tooltip.
89 const size_t kMaxTooltipLength = 1024; 99 const size_t kMaxTooltipLength = 1024;
90 100
91 // TODO(suzhe): Upstream this function. 101 // TODO(suzhe): Upstream this function.
92 WebKit::WebColor WebColorFromNSColor(NSColor *color) { 102 WebKit::WebColor WebColorFromNSColor(NSColor *color) {
93 CGFloat r, g, b, a; 103 CGFloat r, g, b, a;
94 [color getRed:&r green:&g blue:&b alpha:&a]; 104 [color getRed:&r green:&g blue:&b alpha:&a];
95 105
(...skipping 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 [self confirmComposition]; 1212 [self confirmComposition];
1203 } 1213 }
1204 1214
1205 const WebMouseEvent& event = 1215 const WebMouseEvent& event =
1206 WebInputEventFactory::mouseEvent(theEvent, self); 1216 WebInputEventFactory::mouseEvent(theEvent, self);
1207 1217
1208 if (renderWidgetHostView_->render_widget_host_) 1218 if (renderWidgetHostView_->render_widget_host_)
1209 renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); 1219 renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event);
1210 } 1220 }
1211 1221
1222 - (void)shortCircuitedEndGestureWithEvent:(NSEvent*)theEvent {
1223 if ([theEvent subtype] == kIOHIDEventTypeScroll) {
Nico 2011/08/08 19:44:59 can you DCHECK this instead?
Alexei Svitkine (slow) 2011/08/08 20:06:29 I don't think so, since there might be other types
Nico 2011/08/08 20:11:27 Isn't they only called the one in beginGestureWith
1224 WebGestureEvent event = WebInputEventFactory::gestureEvent(theEvent, self);
1225
1226 if (renderWidgetHostView_->render_widget_host_)
1227 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(event);
1228
1229 if (endGestureMonitor_) {
1230 [NSEvent removeMonitor:endGestureMonitor_];
1231 endGestureMonitor_ = nil;
1232 }
1233 }
1234 }
1235
1236 - (void)beginGestureWithEvent:(NSEvent*)theEvent {
1237 if ([theEvent subtype] == kIOHIDEventTypeScroll) {
1238 WebGestureEvent event = WebInputEventFactory::gestureEvent(theEvent, self);
1239
1240 if (renderWidgetHostView_->render_widget_host_)
1241 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(event);
1242
1243 if (!endGestureMonitor_) {
1244 endGestureMonitor_ =
1245 [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskEndGesture
1246 handler: ^(NSEvent *blockEvent) {
1247 [self shortCircuitedEndGestureWithEvent:blockEvent];
1248 return blockEvent;
1249 }];
1250 }
1251 }
1252
1253 // Forward the gesture event to the next responder so that the browser window
1254 // controller has a chance to act on back/forward gesture events.
1255 [[self nextResponder] beginGestureWithEvent:theEvent];
1256 }
1257
1212 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { 1258 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent {
1213 // |performKeyEquivalent:| is sent to all views of a window, not only down the 1259 // |performKeyEquivalent:| is sent to all views of a window, not only down the
1214 // responder chain (cf. "Handling Key Equivalents" in 1260 // responder chain (cf. "Handling Key Equivalents" in
1215 // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Event Overview/HandlingKeyEvents/HandlingKeyEvents.html 1261 // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Event Overview/HandlingKeyEvents/HandlingKeyEvents.html
1216 // ). We only want to handle key equivalents if we're first responder. 1262 // ). We only want to handle key equivalents if we're first responder.
1217 if ([[self window] firstResponder] != self) 1263 if ([[self window] firstResponder] != self)
1218 return NO; 1264 return NO;
1219 1265
1220 // If we return |NO| from this function, cocoa will send the key event to 1266 // If we return |NO| from this function, cocoa will send the key event to
1221 // the menu and only if the menu does not process the event to |keyDown:|. We 1267 // the menu and only if the menu does not process the event to |keyDown:|. We
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 y += height; 1603 y += height;
1558 height = -height; 1604 height = -height;
1559 } 1605 }
1560 1606
1561 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; 1607 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)];
1562 [[NSColor whiteColor] set]; 1608 [[NSColor whiteColor] set];
1563 NSRectFill(r); 1609 NSRectFill(r);
1564 } 1610 }
1565 } 1611 }
1566 1612
1613 - (void)fillRect:(NSRect)rect withPattern:(NSImage*)patternImage {
1614 if (NSIsEmptyRect(rect))
1615 return;
1616
1617 NSColor* patternColor = [NSColor colorWithPatternImage:patternImage];
1618 [patternColor set];
1619 NSRectFill(rect);
1620 }
1621
1622 - (void)drawShadow:(NSShadow*)shadow
1623 withRect:(NSRect)rect
1624 clip:(NSRect)clipRect {
1625 gfx::ScopedNSGraphicsContextSaveGState scopedGState;
1626 NSBezierPath* drawingPath = [NSBezierPath bezierPathWithRect:rect];
1627 [shadow set];
1628 [[NSColor blackColor] set];
1629 [[NSBezierPath bezierPathWithRect:clipRect] addClip];
1630 [drawingPath fill];
1631 }
1632
1633 - (NSRect)computeVisibleContentRect {
1634 const RenderWidgetHost* rwh = renderWidgetHostView_->render_widget_host_;
1635 gfx::Point offset = rwh->last_scroll_offset();
1636 gfx::Size size = rwh->contents_size();
1637 NSRect contentRect =
1638 NSMakeRect(-offset.x(), -offset.y(), size.width(), size.height());
1639 NSRect frameRect = [self frame];
1640 frameRect.origin = NSMakePoint(0, 0);
1641 return NSIntersectionRect(frameRect, contentRect);
1642 }
1643
1644 - (void)fillOverScrollAreas:(NSRect)dirtyRect {
1645 if (![NSColor respondsToSelector:@selector(_linenPatternImage)])
1646 return;
1647
1648 NSRect visibleContentRect = [self computeVisibleContentRect];
1649 NSSize frameSize = [self frame].size;
1650 bool hasHorizontalOverflow = (NSWidth(visibleContentRect) < frameSize.width);
1651 bool hasVerticalOverflow = (NSHeight(visibleContentRect) < frameSize.height);
1652
1653 if (!hasHorizontalOverflow && !hasVerticalOverflow)
1654 return;
1655
1656 NSRect xRect = NSMakeRect(0,
1657 0,
1658 frameSize.width - NSWidth(visibleContentRect),
1659 frameSize.height);
1660 NSRect yRect = NSMakeRect(0,
1661 0,
1662 frameSize.width,
1663 frameSize.height - NSHeight(visibleContentRect));
1664 NSImage* background = [NSColor _linenPatternImage];
1665 scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
1666 [shadow.get() setShadowColor:[NSColor blackColor]];
1667 [shadow setShadowBlurRadius:5];
1668
1669 if (hasHorizontalOverflow) {
1670 NSRect shadowRect;
1671 if (visibleContentRect.origin.x > 0) {
1672 shadowRect = xRect;
1673 shadowRect.origin.x += NSWidth(shadowRect);
1674 } else {
1675 xRect.origin.x = NSWidth(visibleContentRect);
1676 shadowRect = xRect;
1677 shadowRect.origin.x -= 1;
1678 }
1679 shadowRect.size.width = 1;
1680 NSRect intersectRect = NSIntersectionRect(dirtyRect, xRect);
1681 [self fillRect:intersectRect withPattern:background];
1682 [self drawShadow:shadow.get() withRect:shadowRect clip:intersectRect];
1683 }
1684
1685 if (hasVerticalOverflow) {
1686 NSRect shadowRect = visibleContentRect;
1687 if (visibleContentRect.origin.y > 0) {
1688 yRect.origin.y = NSHeight(visibleContentRect);
1689 shadowRect.origin.y = yRect.origin.y - 1;
1690 } else {
1691 shadowRect.origin.y = yRect.origin.y + NSHeight(yRect);
1692 }
1693 shadowRect.size.height = 1;
1694 NSRect intersectRect = NSIntersectionRect(dirtyRect, yRect);
1695 [self fillRect:intersectRect withPattern:background];
1696 [self drawShadow:shadow.get() withRect:shadowRect clip:intersectRect];
1697 }
1698 }
1699
1567 - (void)drawRect:(NSRect)dirtyRect { 1700 - (void)drawRect:(NSRect)dirtyRect {
1568 if (!renderWidgetHostView_->render_widget_host_) { 1701 if (!renderWidgetHostView_->render_widget_host_) {
1569 // TODO(shess): Consider using something more noticable? 1702 // TODO(shess): Consider using something more noticable?
1570 [[NSColor whiteColor] set]; 1703 [[NSColor whiteColor] set];
1571 NSRectFill(dirtyRect); 1704 NSRectFill(dirtyRect);
1572 return; 1705 return;
1573 } 1706 }
1574 1707
1575 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); 1708 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]);
1576 1709
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1632 CGBitmapContextCreateImage(backingStore->cg_bitmap())); 1765 CGBitmapContextCreateImage(backingStore->cg_bitmap()));
1633 CGRect imageRect = bitmapRect.ToCGRect(); 1766 CGRect imageRect = bitmapRect.ToCGRect();
1634 imageRect.origin.y = yOffset; 1767 imageRect.origin.y = yOffset;
1635 CGContextDrawImage(context, imageRect, image); 1768 CGContextDrawImage(context, imageRect, image);
1636 } 1769 }
1637 } 1770 }
1638 1771
1639 // Fill the remaining portion of the damagedRect with white 1772 // Fill the remaining portion of the damagedRect with white
1640 [self fillBottomRightRemainderOfRect:bitmapRect dirtyRect:damagedRect]; 1773 [self fillBottomRightRemainderOfRect:bitmapRect dirtyRect:damagedRect];
1641 1774
1775 // Fill the over-scroll areas, if any, with the appropriate pattern.
1776 [self fillOverScrollAreas:dirtyRect];
1777
1642 if (!renderWidgetHostView_->whiteout_start_time_.is_null()) { 1778 if (!renderWidgetHostView_->whiteout_start_time_.is_null()) {
1643 base::TimeDelta whiteout_duration = base::TimeTicks::Now() - 1779 base::TimeDelta whiteout_duration = base::TimeTicks::Now() -
1644 renderWidgetHostView_->whiteout_start_time_; 1780 renderWidgetHostView_->whiteout_start_time_;
1645 UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration); 1781 UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration);
1646 1782
1647 // Reset the start time to 0 so that we start recording again the next 1783 // Reset the start time to 0 so that we start recording again the next
1648 // time the backing store is NULL... 1784 // time the backing store is NULL...
1649 renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks(); 1785 renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks();
1650 } 1786 }
1651 if (!renderWidgetHostView_->tab_switch_paint_time_.is_null()) { 1787 if (!renderWidgetHostView_->tab_switch_paint_time_.is_null()) {
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1879 RenderWidgetHost* rwh = renderWidgetHostView_->render_widget_host_; 2015 RenderWidgetHost* rwh = renderWidgetHostView_->render_widget_host_;
1880 rwh->Send(new ViewMsg_SetAccessibilityFocus( 2016 rwh->Send(new ViewMsg_SetAccessibilityFocus(
1881 rwh->routing_id(), accessibilityObjectId)); 2017 rwh->routing_id(), accessibilityObjectId));
1882 } 2018 }
1883 } 2019 }
1884 2020
1885 - (void)performShowMenuAction:(BrowserAccessibilityCocoa*)accessibility { 2021 - (void)performShowMenuAction:(BrowserAccessibilityCocoa*)accessibility {
1886 // Performs a right click copying WebKit's 2022 // Performs a right click copying WebKit's
1887 // accessibilityPerformShowMenuAction. 2023 // accessibilityPerformShowMenuAction.
1888 NSPoint location = [self accessibilityPointInScreen:accessibility]; 2024 NSPoint location = [self accessibilityPointInScreen:accessibility];
1889 NSSize size = [[accessibility size] sizeValue]; 2025 NSSize size = [[accessibility size] sizeValue];
1890 location = [[self window] convertScreenToBase:location]; 2026 location = [[self window] convertScreenToBase:location];
1891 location.x += size.width/2; 2027 location.x += size.width/2;
1892 location.y += size.height/2; 2028 location.y += size.height/2;
1893 2029
1894 NSEvent* fakeRightClick = [NSEvent 2030 NSEvent* fakeRightClick = [NSEvent
1895 mouseEventWithType:NSRightMouseDown 2031 mouseEventWithType:NSRightMouseDown
1896 location:location 2032 location:location
1897 modifierFlags:nil 2033 modifierFlags:nil
1898 timestamp:0 2034 timestamp:0
1899 windowNumber:[[self window] windowNumber] 2035 windowNumber:[[self window] windowNumber]
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
2625 if (!string) return NO; 2761 if (!string) return NO;
2626 2762
2627 // If the user is currently using an IME, confirm the IME input, 2763 // If the user is currently using an IME, confirm the IME input,
2628 // and then insert the text from the service, the same as TextEdit and Safari. 2764 // and then insert the text from the service, the same as TextEdit and Safari.
2629 [self confirmComposition]; 2765 [self confirmComposition];
2630 [self insertText:string]; 2766 [self insertText:string];
2631 return YES; 2767 return YES;
2632 } 2768 }
2633 2769
2634 @end 2770 @end
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/render_widget_host_view_mac.h ('k') | content/browser/renderer_host/render_widget_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698