Chromium Code Reviews| Index: chrome/browser/renderer_host/render_widget_host_view_mac.mm |
| =================================================================== |
| --- chrome/browser/renderer_host/render_widget_host_view_mac.mm (revision 95810) |
| +++ chrome/browser/renderer_host/render_widget_host_view_mac.mm (working copy) |
| @@ -52,6 +52,7 @@ |
| using WebKit::WebInputEventFactory; |
| using WebKit::WebMouseEvent; |
| using WebKit::WebMouseWheelEvent; |
| +using WebKit::WebGestureEvent; |
| static inline int ToWebKitModifiers(NSUInteger flags) { |
| int modifiers = 0; |
| @@ -75,7 +76,7 @@ |
| @end |
| // This API was published since 10.6. Provide the declaration so it can be |
| -// // called below when building with the 10.5 SDK. |
| +// called below when building with the 10.5 SDK. |
| #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 |
| @class NSTextInputContext; |
| @interface NSResponder (AppKitDetails) |
| @@ -83,6 +84,14 @@ |
| @end |
| #endif |
| +// Undocumented Lion method to get the pattern for the over scroll area. |
| +@interface NSColor (LionSekretAPI) |
| ++ (NSImage*)_linenPatternImage; |
| +@end |
| + |
| +// NSEvent subtype for scroll gestures events. |
| +static const short kIOHIDEventTypeScroll = 6; |
| + |
| namespace { |
| // Maximum number of characters we allow in a tooltip. |
| @@ -1209,6 +1218,38 @@ |
| renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); |
| } |
| +- (void)shortCircuitedEndGestureWithEvent:(NSEvent*)theEvent { |
| + if ([theEvent subtype] == kIOHIDEventTypeScroll) { |
| + WebGestureEvent event = WebInputEventFactory::gestureEvent(theEvent, self); |
| + |
| + if (renderWidgetHostView_->render_widget_host_) |
| + renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(event); |
| + |
| + if (endGestureMonitor_) { |
| + [NSEvent removeMonitor:endGestureMonitor_]; |
| + endGestureMonitor_ = nil; |
| + } |
| + } |
| +} |
| + |
| +- (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
|
| + if ([theEvent subtype] == kIOHIDEventTypeScroll) { |
| + WebGestureEvent event = WebInputEventFactory::gestureEvent(theEvent, self); |
| + |
| + if (renderWidgetHostView_->render_widget_host_) |
| + renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(event); |
| + |
| + if (!endGestureMonitor_) { |
| + endGestureMonitor_ = |
| + [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskEndGesture |
| + handler: ^(NSEvent *blockEvent) { |
| + [self shortCircuitedEndGestureWithEvent:blockEvent]; |
| + return blockEvent; |
| + }]; |
|
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
|
| + } |
| + } |
| +} |
| + |
| - (BOOL)performKeyEquivalent:(NSEvent*)theEvent { |
| // |performKeyEquivalent:| is sent to all views of a window, not only down the |
| // responder chain (cf. "Handling Key Equivalents" in |
| @@ -1564,6 +1605,94 @@ |
| } |
| } |
| +- (void)fillRect:(NSRect)rect withPattern:(NSImage*)patternImage { |
| + if (NSIsEmptyRect(rect)) |
| + return; |
| + |
| + NSColor* patternColor = [NSColor colorWithPatternImage:patternImage]; |
| + [patternColor set]; |
| + NSRectFill(rect); |
| +} |
| + |
| +- (void)drawShadow:(NSShadow*)shadow |
| + withRect:(NSRect)rect |
| + clip:(NSRect)clipRect { |
| + [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.
|
| + 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.
|
| + [shadow set]; |
| + [[NSColor blackColor] set]; |
| + [[NSBezierPath bezierPathWithRect:clipRect] addClip]; |
| + [drawingPath fill]; |
| + [NSGraphicsContext restoreGraphicsState]; |
| +} |
| + |
| +- (NSRect)computeVisibleContentRect { |
| + const RenderWidgetHost *rwh = renderWidgetHostView_->render_widget_host_; |
| + gfx::Point offset = rwh->last_scroll_offset(); |
| + gfx::Size size = rwh->contents_size(); |
| + NSRect contentRect = |
| + NSMakeRect(-offset.x(), -offset.y(), size.width(), size.height()); |
| + NSRect frameRect = [self frame]; |
| + frameRect.origin = NSMakePoint(0, 0); |
| + return NSIntersectionRect(frameRect, contentRect); |
| +} |
| + |
| +- (void)fillOverScrollAreas:(NSRect)dirtyRect { |
| + if (![NSColor respondsToSelector:@selector(_linenPatternImage)]) |
| + return; |
| + |
| + NSRect visibleContentRect = [self computeVisibleContentRect]; |
| + NSSize frameSize = [self frame].size; |
| + bool hasHorizontalOverflow = (NSWidth(visibleContentRect) < frameSize.width); |
| + bool hasVerticalOverflow = (NSHeight(visibleContentRect) < frameSize.height); |
| + |
| + if (!hasHorizontalOverflow && !hasVerticalOverflow) |
| + return; |
| + |
| + NSRect xRect = NSMakeRect(0, |
| + 0, |
| + frameSize.width - NSWidth(visibleContentRect), |
| + frameSize.height); |
| + NSRect yRect = NSMakeRect(0, |
| + 0, |
| + frameSize.width, |
| + frameSize.height - NSHeight(visibleContentRect)); |
| + NSImage* background = [NSColor _linenPatternImage]; |
| + scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]); |
| + [shadow.get() setShadowColor:[NSColor blackColor]]; |
| + [shadow setShadowBlurRadius:5]; |
| + |
| + if (hasHorizontalOverflow) { |
| + NSRect shadowRect; |
| + if (visibleContentRect.origin.x > 0) { |
| + shadowRect = xRect; |
| + shadowRect.origin.x += NSWidth(shadowRect); |
| + } else { |
| + xRect.origin.x = NSWidth(visibleContentRect); |
| + shadowRect = xRect; |
| + shadowRect.origin.x -= 1; |
| + } |
| + shadowRect.size.width = 1; |
| + NSRect intersectRect = NSIntersectionRect(dirtyRect, xRect); |
| + [self fillRect:intersectRect withPattern:background]; |
| + [self drawShadow:shadow.get() withRect:shadowRect clip:intersectRect]; |
| + } |
| + |
| + if (hasVerticalOverflow) { |
| + NSRect shadowRect = visibleContentRect; |
| + if (visibleContentRect.origin.y > 0) { |
| + yRect.origin.y = NSHeight(visibleContentRect); |
| + shadowRect.origin.y = yRect.origin.y - 1; |
| + } else { |
| + shadowRect.origin.y = yRect.origin.y + NSHeight(yRect); |
| + } |
| + shadowRect.size.height = 1; |
| + NSRect intersectRect = NSIntersectionRect(dirtyRect, yRect); |
| + [self fillRect:intersectRect withPattern:background]; |
| + [self drawShadow:shadow.get() withRect:shadowRect clip:intersectRect]; |
| + } |
| +} |
| + |
| - (void)drawRect:(NSRect)dirtyRect { |
| if (!renderWidgetHostView_->render_widget_host_) { |
| // TODO(shess): Consider using something more noticable? |
| @@ -1639,6 +1768,9 @@ |
| // Fill the remaining portion of the damagedRect with white |
| [self fillBottomRightRemainderOfRect:bitmapRect dirtyRect:damagedRect]; |
| + // Fill the over-scroll areas, if any, with the appropriate pattern. |
| + [self fillOverScrollAreas:dirtyRect]; |
| + |
| if (!renderWidgetHostView_->whiteout_start_time_.is_null()) { |
| base::TimeDelta whiteout_duration = base::TimeTicks::Now() - |
| renderWidgetHostView_->whiteout_start_time_; |
| @@ -1886,7 +2018,7 @@ |
| // Performs a right click copying WebKit's |
| // accessibilityPerformShowMenuAction. |
| NSPoint location = [self accessibilityPointInScreen:accessibility]; |
| -NSSize size = [[accessibility size] sizeValue]; |
| + NSSize size = [[accessibility size] sizeValue]; |
| location = [[self window] convertScreenToBase:location]; |
| location.x += size.width/2; |
| location.y += size.height/2; |