OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |