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

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) {
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 {
Nico 2011/08/08 19:44:59 DCHECK(IsOnSnowLeopardOrLater())
Alexei Svitkine (slow) 2011/08/08 20:06:29 In browser_window_controller.mm there's a comment
Nico 2011/08/08 20:10:09 Ah, then you need to add that to the if I think? a
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
1212 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { 1254 - (BOOL)performKeyEquivalent:(NSEvent*)theEvent {
1213 // |performKeyEquivalent:| is sent to all views of a window, not only down the 1255 // |performKeyEquivalent:| is sent to all views of a window, not only down the
1214 // responder chain (cf. "Handling Key Equivalents" in 1256 // responder chain (cf. "Handling Key Equivalents" in
1215 // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Event Overview/HandlingKeyEvents/HandlingKeyEvents.html 1257 // 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. 1258 // ). We only want to handle key equivalents if we're first responder.
1217 if ([[self window] firstResponder] != self) 1259 if ([[self window] firstResponder] != self)
1218 return NO; 1260 return NO;
1219 1261
1220 // If we return |NO| from this function, cocoa will send the key event to 1262 // 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 1263 // 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; 1599 y += height;
1558 height = -height; 1600 height = -height;
1559 } 1601 }
1560 1602
1561 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; 1603 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)];
1562 [[NSColor whiteColor] set]; 1604 [[NSColor whiteColor] set];
1563 NSRectFill(r); 1605 NSRectFill(r);
1564 } 1606 }
1565 } 1607 }
1566 1608
1609 - (void)fillRect:(NSRect)rect withPattern:(NSImage*)patternImage {
1610 if (NSIsEmptyRect(rect))
1611 return;
1612
1613 NSColor* patternColor = [NSColor colorWithPatternImage:patternImage];
1614 [patternColor set];
1615 NSRectFill(rect);
1616 }
1617
1618 - (void)drawShadow:(NSShadow*)shadow
1619 withRect:(NSRect)rect
1620 clip:(NSRect)clipRect {
1621 gfx::ScopedNSGraphicsContextSaveGState scopedGState;
1622 NSBezierPath* drawingPath = [NSBezierPath bezierPathWithRect:rect];
1623 [shadow set];
1624 [[NSColor blackColor] set];
1625 [[NSBezierPath bezierPathWithRect:clipRect] addClip];
1626 [drawingPath fill];
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);
Nico 2011/08/08 19:44:59 (does all this work in HighDPI mode? Just curious,
Alexei Svitkine (slow) 2011/08/08 20:06:29 How would I test that?
Nico 2011/08/08 20:10:09 Open Quartz Debug, hit cmd-2, check the checkbox,
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
« 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