summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
authorasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-11 14:39:18 +0000
committerasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-11 14:39:18 +0000
commit68bd80aa66da73d9aa2fb6662592bd530ce7b7f0 (patch)
tree91ab5ce0eaaacb0dbf79fe8167189a633486058b /chrome/browser/renderer_host
parent84534f2f224cdc018dcdae07e251b98baf5d41a3 (diff)
downloadchromium_src-68bd80aa66da73d9aa2fb6662592bd530ce7b7f0.zip
chromium_src-68bd80aa66da73d9aa2fb6662592bd530ce7b7f0.tar.gz
chromium_src-68bd80aa66da73d9aa2fb6662592bd530ce7b7f0.tar.bz2
[Mac] Rubber-banding on Lion.
BUG=88353 TEST=On Lion, scroll past the edge of the web content area and see textured over-scroll area. Review URL: http://codereview.chromium.org/7582009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96387 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm135
1 files changed, 132 insertions, 3 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index 28bbb7a..c38d88b 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -8,6 +8,7 @@
#include "base/debug/trace_event.h"
#include "base/logging.h"
+#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#import "base/mac/scoped_nsautorelease_pool.h"
#include "base/metrics/histogram.h"
@@ -44,6 +45,7 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFactory.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "ui/gfx/point.h"
+#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include "ui/gfx/surface/io_surface_support_mac.h"
#include "webkit/glue/webaccessibility.h"
#include "webkit/plugins/npapi/webplugin.h"
@@ -52,6 +54,7 @@ using WebKit::WebInputEvent;
using WebKit::WebInputEventFactory;
using WebKit::WebMouseEvent;
using WebKit::WebMouseWheelEvent;
+using WebKit::WebGestureEvent;
static inline int ToWebKitModifiers(NSUInteger flags) {
int modifiers = 0;
@@ -75,14 +78,24 @@ static inline int ToWebKitModifiers(NSUInteger flags) {
@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)
- (NSTextInputContext *)inputContext;
+- (void)beginGestureWithEvent:(NSEvent*)event;
+- (void)endGestureWithEvent:(NSEvent*)event;
@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.
@@ -1211,6 +1224,32 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event);
}
+- (void)beginGestureWithEvent:(NSEvent*)event {
+ if (base::mac::IsOSLionOrLater() &&
+ [event subtype] == kIOHIDEventTypeScroll &&
+ renderWidgetHostView_->render_widget_host_) {
+ WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self);
+ renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent);
+ }
+
+ // Forward the gesture event to the next responder so that the browser window
+ // controller has a chance to act on back/forward gestures.
+ [[self nextResponder] beginGestureWithEvent:event];
+}
+
+- (void)endGestureWithEvent:(NSEvent*)event {
+ if (base::mac::IsOSLionOrLater() &&
+ [event subtype] == kIOHIDEventTypeScroll &&
+ renderWidgetHostView_->render_widget_host_) {
+ WebGestureEvent webEvent = WebInputEventFactory::gestureEvent(event, self);
+ renderWidgetHostView_->render_widget_host_->ForwardGestureEvent(webEvent);
+ }
+
+ // Forward the gesture event to the next responder so that the browser window
+ // controller has a chance to act on back/forward gestures.
+ [[self nextResponder] endGestureWithEvent:event];
+}
+
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent {
// |performKeyEquivalent:| is sent to all views of a window, not only down the
// responder chain (cf. "Handling Key Equivalents" in
@@ -1247,7 +1286,7 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
// to us instead of doing key view loop control, ctrl-left/right get handled
// correctly, etc.
// (However, there are still some keys that Cocoa swallows, e.g. the key
- // equivalent that Cocoa uses for toggling the input langauge. In this case,
+ // equivalent that Cocoa uses for toggling the input language. In this case,
// that's actually a good thing, though -- see http://crbug.com/26115 .)
return YES;
}
@@ -1566,6 +1605,93 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
}
}
+- (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 {
+ gfx::ScopedNSGraphicsContextSaveGState scopedGState;
+ NSBezierPath* drawingPath = [NSBezierPath bezierPathWithRect:rect];
+ [shadow set];
+ [[NSColor blackColor] set];
+ [[NSBezierPath bezierPathWithRect:clipRect] addClip];
+ [drawingPath fill];
+}
+
+- (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?
@@ -1641,6 +1767,9 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
// 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_;
@@ -1888,7 +2017,7 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
// 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;