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

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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
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/surface/io_surface_support_mac.h" 47 #include "ui/gfx/surface/io_surface_support_mac.h"
48 #include "webkit/glue/webaccessibility.h" 48 #include "webkit/glue/webaccessibility.h"
49 #include "webkit/plugins/npapi/webplugin.h" 49 #include "webkit/plugins/npapi/webplugin.h"
50 50
51 using WebKit::WebInputEvent; 51 using WebKit::WebInputEvent;
52 using WebKit::WebInputEventFactory; 52 using WebKit::WebInputEventFactory;
53 using WebKit::WebMouseEvent; 53 using WebKit::WebMouseEvent;
54 using WebKit::WebMouseWheelEvent; 54 using WebKit::WebMouseWheelEvent;
55 using WebKit::WebGestureEvent;
55 56
56 static inline int ToWebKitModifiers(NSUInteger flags) { 57 static inline int ToWebKitModifiers(NSUInteger flags) {
57 int modifiers = 0; 58 int modifiers = 0;
58 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; 59 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey;
59 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey; 60 if (flags & NSShiftKeyMask) modifiers |= WebInputEvent::ShiftKey;
60 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey; 61 if (flags & NSAlternateKeyMask) modifiers |= WebInputEvent::AltKey;
61 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey; 62 if (flags & NSCommandKeyMask) modifiers |= WebInputEvent::MetaKey;
62 return modifiers; 63 return modifiers;
63 } 64 }
64 65
65 // Private methods: 66 // Private methods:
66 @interface RenderWidgetHostViewCocoa () 67 @interface RenderWidgetHostViewCocoa ()
67 @property(nonatomic, assign) NSRange selectedRange; 68 @property(nonatomic, assign) NSRange selectedRange;
68 @property(nonatomic, assign) NSRange markedRange; 69 @property(nonatomic, assign) NSRange markedRange;
69 70
70 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; 71 + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event;
71 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; 72 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r;
72 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv; 73 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv;
73 - (void)cancelChildPopups; 74 - (void)cancelChildPopups;
74 - (void)checkForPluginImeCancellation; 75 - (void)checkForPluginImeCancellation;
75 @end 76 @end
76 77
77 // This API was published since 10.6. Provide the declaration so it can be 78 // This API was published since 10.6. Provide the declaration so it can be
78 // // called below when building with the 10.5 SDK. 79 // called below when building with the 10.5 SDK.
79 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 80 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
80 @class NSTextInputContext; 81 @class NSTextInputContext;
81 @interface NSResponder (AppKitDetails) 82 @interface NSResponder (AppKitDetails)
82 - (NSTextInputContext *)inputContext; 83 - (NSTextInputContext *)inputContext;
83 @end 84 @end
84 #endif 85 #endif
85 86
87 // Undocumented Lion method to get the pattern for the over scroll area.
88 @interface NSColor (LionSekretAPI)
89 + (NSImage*)_linenPatternImage;
90 @end
91
92 // NSEvent subtype for scroll gestures events.
93 static const short kIOHIDEventTypeScroll = 6;
94
86 namespace { 95 namespace {
87 96
88 // Maximum number of characters we allow in a tooltip. 97 // Maximum number of characters we allow in a tooltip.
89 const size_t kMaxTooltipLength = 1024; 98 const size_t kMaxTooltipLength = 1024;
90 99
91 // TODO(suzhe): Upstream this function. 100 // TODO(suzhe): Upstream this function.
92 WebKit::WebColor WebColorFromNSColor(NSColor *color) { 101 WebKit::WebColor WebColorFromNSColor(NSColor *color) {
93 CGFloat r, g, b, a; 102 CGFloat r, g, b, a;
94 [color getRed:&r green:&g blue:&b alpha:&a]; 103 [color getRed:&r green:&g blue:&b alpha:&a];
95 104
(...skipping 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 [self confirmComposition]; 1211 [self confirmComposition];
1203 } 1212 }
1204 1213
1205 const WebMouseEvent& event = 1214 const WebMouseEvent& event =
1206 WebInputEventFactory::mouseEvent(theEvent, self); 1215 WebInputEventFactory::mouseEvent(theEvent, self);
1207 1216
1208 if (renderWidgetHostView_->render_widget_host_) 1217 if (renderWidgetHostView_->render_widget_host_)
1209 renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); 1218 renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event);
1210 } 1219 }
1211 1220
1221 - (void)shortCircuitedEndGestureWithEvent:(NSEvent*)theEvent {
1222 if ([theEvent subtype] == kIOHIDEventTypeScroll) {
1223 WebGestureEvent event = WebInputEventFactory::gestureEvent(theEvent, self);
1224
1225 if (renderWidgetHostView_->render_widget_host_)
1226 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(event);
1227
1228 if (endGestureMonitor_) {
1229 [NSEvent removeMonitor:endGestureMonitor_];
1230 endGestureMonitor_ = nil;
1231 }
1232 }
1233 }
1234
1235 - (void)beginGestureWithEvent:(NSEvent*)theEvent {
Nico 2011/08/08 17:30:53 s/theEvent/event/ This override means the same ov
Alexei Svitkine (slow) 2011/08/08 20:06:29 I've fixed this by also forwarding it to the next
1236 if ([theEvent subtype] == kIOHIDEventTypeScroll) {
1237 WebGestureEvent event = WebInputEventFactory::gestureEvent(theEvent, self);
1238
1239 if (renderWidgetHostView_->render_widget_host_)
1240 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(event);
1241
1242 if (!endGestureMonitor_) {
1243 endGestureMonitor_ =
1244 [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskEndGesture
1245 handler: ^(NSEvent *blockEvent) {
1246 [self shortCircuitedEndGestureWithEvent:blockEvent];
1247 return blockEvent;
1248 }];
Nico 2011/08/08 17:30:53 do you want to retain the monitor?
Alexei Svitkine (slow) 2011/08/08 18:31:31 Apple's examples don't do it: http://developer.ap
Nico 2011/08/08 18:49:15 Did you check if that example is built with garbag
1249 }
1250 }
1251 }
1252
1212 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { 1253 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent {
1213 // |performKeyEquivalent:| is sent to all views of a window, not only down the 1254 // |performKeyEquivalent:| is sent to all views of a window, not only down the
1214 // responder chain (cf. "Handling Key Equivalents" in 1255 // responder chain (cf. "Handling Key Equivalents" in
1215 // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Event Overview/HandlingKeyEvents/HandlingKeyEvents.html 1256 // 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. 1257 // ). We only want to handle key equivalents if we're first responder.
1217 if ([[self window] firstResponder] != self) 1258 if ([[self window] firstResponder] != self)
1218 return NO; 1259 return NO;
1219 1260
1220 // If we return |NO| from this function, cocoa will send the key event to 1261 // 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 1262 // 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; 1598 y += height;
1558 height = -height; 1599 height = -height;
1559 } 1600 }
1560 1601
1561 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; 1602 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)];
1562 [[NSColor whiteColor] set]; 1603 [[NSColor whiteColor] set];
1563 NSRectFill(r); 1604 NSRectFill(r);
1564 } 1605 }
1565 } 1606 }
1566 1607
1608 - (void)fillRect:(NSRect)rect withPattern:(NSImage*)patternImage {
1609 if (NSIsEmptyRect(rect))
1610 return;
1611
1612 NSColor* patternColor = [NSColor colorWithPatternImage:patternImage];
1613 [patternColor set];
1614 NSRectFill(rect);
1615 }
1616
1617 - (void)drawShadow:(NSShadow*)shadow
1618 withRect:(NSRect)rect
1619 clip:(NSRect)clipRect {
1620 [NSGraphicsContext saveGraphicsState];
Nico 2011/08/08 17:30:53 We have a ScopedSaveNSGraphicsState somewhere in b
Alexei Svitkine (slow) 2011/08/08 18:31:31 Done.
1621 NSBezierPath *drawingPath = [NSBezierPath bezierPathWithRect:rect];
Nico 2011/08/08 17:30:53 space after *, not before
Alexei Svitkine (slow) 2011/08/08 18:31:31 Done.
1622 [shadow set];
1623 [[NSColor blackColor] set];
1624 [[NSBezierPath bezierPathWithRect:clipRect] addClip];
1625 [drawingPath fill];
1626 [NSGraphicsContext restoreGraphicsState];
1627 }
1628
1629 - (NSRect)computeVisibleContentRect {
1630 const RenderWidgetHost *rwh = renderWidgetHostView_->render_widget_host_;
1631 gfx::Point offset = rwh->last_scroll_offset();
1632 gfx::Size size = rwh->contents_size();
1633 NSRect contentRect =
1634 NSMakeRect(-offset.x(), -offset.y(), size.width(), size.height());
1635 NSRect frameRect = [self frame];
1636 frameRect.origin = NSMakePoint(0, 0);
1637 return NSIntersectionRect(frameRect, contentRect);
1638 }
1639
1640 - (void)fillOverScrollAreas:(NSRect)dirtyRect {
1641 if (![NSColor respondsToSelector:@selector(_linenPatternImage)])
1642 return;
1643
1644 NSRect visibleContentRect = [self computeVisibleContentRect];
1645 NSSize frameSize = [self frame].size;
1646 bool hasHorizontalOverflow = (NSWidth(visibleContentRect) < frameSize.width);
1647 bool hasVerticalOverflow = (NSHeight(visibleContentRect) < frameSize.height);
1648
1649 if (!hasHorizontalOverflow && !hasVerticalOverflow)
1650 return;
1651
1652 NSRect xRect = NSMakeRect(0,
1653 0,
1654 frameSize.width - NSWidth(visibleContentRect),
1655 frameSize.height);
1656 NSRect yRect = NSMakeRect(0,
1657 0,
1658 frameSize.width,
1659 frameSize.height - NSHeight(visibleContentRect));
1660 NSImage* background = [NSColor _linenPatternImage];
1661 scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
1662 [shadow.get() setShadowColor:[NSColor blackColor]];
1663 [shadow setShadowBlurRadius:5];
1664
1665 if (hasHorizontalOverflow) {
1666 NSRect shadowRect;
1667 if (visibleContentRect.origin.x > 0) {
1668 shadowRect = xRect;
1669 shadowRect.origin.x += NSWidth(shadowRect);
1670 } else {
1671 xRect.origin.x = NSWidth(visibleContentRect);
1672 shadowRect = xRect;
1673 shadowRect.origin.x -= 1;
1674 }
1675 shadowRect.size.width = 1;
1676 NSRect intersectRect = NSIntersectionRect(dirtyRect, xRect);
1677 [self fillRect:intersectRect withPattern:background];
1678 [self drawShadow:shadow.get() withRect:shadowRect clip:intersectRect];
1679 }
1680
1681 if (hasVerticalOverflow) {
1682 NSRect shadowRect = visibleContentRect;
1683 if (visibleContentRect.origin.y > 0) {
1684 yRect.origin.y = NSHeight(visibleContentRect);
1685 shadowRect.origin.y = yRect.origin.y - 1;
1686 } else {
1687 shadowRect.origin.y = yRect.origin.y + NSHeight(yRect);
1688 }
1689 shadowRect.size.height = 1;
1690 NSRect intersectRect = NSIntersectionRect(dirtyRect, yRect);
1691 [self fillRect:intersectRect withPattern:background];
1692 [self drawShadow:shadow.get() withRect:shadowRect clip:intersectRect];
1693 }
1694 }
1695
1567 - (void)drawRect:(NSRect)dirtyRect { 1696 - (void)drawRect:(NSRect)dirtyRect {
1568 if (!renderWidgetHostView_->render_widget_host_) { 1697 if (!renderWidgetHostView_->render_widget_host_) {
1569 // TODO(shess): Consider using something more noticable? 1698 // TODO(shess): Consider using something more noticable?
1570 [[NSColor whiteColor] set]; 1699 [[NSColor whiteColor] set];
1571 NSRectFill(dirtyRect); 1700 NSRectFill(dirtyRect);
1572 return; 1701 return;
1573 } 1702 }
1574 1703
1575 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); 1704 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]);
1576 1705
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1632 CGBitmapContextCreateImage(backingStore->cg_bitmap())); 1761 CGBitmapContextCreateImage(backingStore->cg_bitmap()));
1633 CGRect imageRect = bitmapRect.ToCGRect(); 1762 CGRect imageRect = bitmapRect.ToCGRect();
1634 imageRect.origin.y = yOffset; 1763 imageRect.origin.y = yOffset;
1635 CGContextDrawImage(context, imageRect, image); 1764 CGContextDrawImage(context, imageRect, image);
1636 } 1765 }
1637 } 1766 }
1638 1767
1639 // Fill the remaining portion of the damagedRect with white 1768 // Fill the remaining portion of the damagedRect with white
1640 [self fillBottomRightRemainderOfRect:bitmapRect dirtyRect:damagedRect]; 1769 [self fillBottomRightRemainderOfRect:bitmapRect dirtyRect:damagedRect];
1641 1770
1771 // Fill the over-scroll areas, if any, with the appropriate pattern.
1772 [self fillOverScrollAreas:dirtyRect];
1773
1642 if (!renderWidgetHostView_->whiteout_start_time_.is_null()) { 1774 if (!renderWidgetHostView_->whiteout_start_time_.is_null()) {
1643 base::TimeDelta whiteout_duration = base::TimeTicks::Now() - 1775 base::TimeDelta whiteout_duration = base::TimeTicks::Now() -
1644 renderWidgetHostView_->whiteout_start_time_; 1776 renderWidgetHostView_->whiteout_start_time_;
1645 UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration); 1777 UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration);
1646 1778
1647 // Reset the start time to 0 so that we start recording again the next 1779 // Reset the start time to 0 so that we start recording again the next
1648 // time the backing store is NULL... 1780 // time the backing store is NULL...
1649 renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks(); 1781 renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks();
1650 } 1782 }
1651 if (!renderWidgetHostView_->tab_switch_paint_time_.is_null()) { 1783 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_; 2011 RenderWidgetHost* rwh = renderWidgetHostView_->render_widget_host_;
1880 rwh->Send(new ViewMsg_SetAccessibilityFocus( 2012 rwh->Send(new ViewMsg_SetAccessibilityFocus(
1881 rwh->routing_id(), accessibilityObjectId)); 2013 rwh->routing_id(), accessibilityObjectId));
1882 } 2014 }
1883 } 2015 }
1884 2016
1885 - (void)performShowMenuAction:(BrowserAccessibilityCocoa*)accessibility { 2017 - (void)performShowMenuAction:(BrowserAccessibilityCocoa*)accessibility {
1886 // Performs a right click copying WebKit's 2018 // Performs a right click copying WebKit's
1887 // accessibilityPerformShowMenuAction. 2019 // accessibilityPerformShowMenuAction.
1888 NSPoint location = [self accessibilityPointInScreen:accessibility]; 2020 NSPoint location = [self accessibilityPointInScreen:accessibility];
1889 NSSize size = [[accessibility size] sizeValue]; 2021 NSSize size = [[accessibility size] sizeValue];
1890 location = [[self window] convertScreenToBase:location]; 2022 location = [[self window] convertScreenToBase:location];
1891 location.x += size.width/2; 2023 location.x += size.width/2;
1892 location.y += size.height/2; 2024 location.y += size.height/2;
1893 2025
1894 NSEvent* fakeRightClick = [NSEvent 2026 NSEvent* fakeRightClick = [NSEvent
1895 mouseEventWithType:NSRightMouseDown 2027 mouseEventWithType:NSRightMouseDown
1896 location:location 2028 location:location
1897 modifierFlags:nil 2029 modifierFlags:nil
1898 timestamp:0 2030 timestamp:0
1899 windowNumber:[[self window] windowNumber] 2031 windowNumber:[[self window] windowNumber]
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
2625 if (!string) return NO; 2757 if (!string) return NO;
2626 2758
2627 // If the user is currently using an IME, confirm the IME input, 2759 // 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. 2760 // and then insert the text from the service, the same as TextEdit and Safari.
2629 [self confirmComposition]; 2761 [self confirmComposition];
2630 [self insertText:string]; 2762 [self insertText:string];
2631 return YES; 2763 return YES;
2632 } 2764 }
2633 2765
2634 @end 2766 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698