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

Unified 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 side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698