OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/renderer_host/render_widget_host_view_mac.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" |
6 | 6 |
7 #import <objc/runtime.h> | 7 #import <objc/runtime.h> |
8 #include <OpenGL/gl.h> | 8 #include <OpenGL/gl.h> |
9 #include <QuartzCore/QuartzCore.h> | 9 #include <QuartzCore/QuartzCore.h> |
10 | 10 |
(...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1219 [cocoa_view_ setMarkedRange:range.ToNSRange()]; | 1219 [cocoa_view_ setMarkedRange:range.ToNSRange()]; |
1220 } | 1220 } |
1221 | 1221 |
1222 RenderWidgetHostViewBase::SelectionChanged(text, offset, range); | 1222 RenderWidgetHostViewBase::SelectionChanged(text, offset, range); |
1223 } | 1223 } |
1224 | 1224 |
1225 void RenderWidgetHostViewMac::SelectionBoundsChanged( | 1225 void RenderWidgetHostViewMac::SelectionBoundsChanged( |
1226 const ViewHostMsg_SelectionBounds_Params& params) { | 1226 const ViewHostMsg_SelectionBounds_Params& params) { |
1227 if (params.anchor_rect == params.focus_rect) | 1227 if (params.anchor_rect == params.focus_rect) |
1228 caret_rect_ = params.anchor_rect; | 1228 caret_rect_ = params.anchor_rect; |
1229 first_selection_rect_ = params.anchor_rect; | |
1229 } | 1230 } |
1230 | 1231 |
1231 void RenderWidgetHostViewMac::SetShowingContextMenu(bool showing) { | 1232 void RenderWidgetHostViewMac::SetShowingContextMenu(bool showing) { |
1232 RenderWidgetHostViewBase::SetShowingContextMenu(showing); | 1233 RenderWidgetHostViewBase::SetShowingContextMenu(showing); |
1233 | 1234 |
1234 // Create a fake mouse event to inform the render widget that the mouse | 1235 // Create a fake mouse event to inform the render widget that the mouse |
1235 // left or entered. | 1236 // left or entered. |
1236 NSWindow* window = [cocoa_view_ window]; | 1237 NSWindow* window = [cocoa_view_ window]; |
1237 // TODO(asvitkine): If the location outside of the event stream doesn't | 1238 // TODO(asvitkine): If the location outside of the event stream doesn't |
1238 // correspond to the current event (due to delayed event processing), then | 1239 // correspond to the current event (due to delayed event processing), then |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1439 | 1440 |
1440 bool RenderWidgetHostViewMac::GetCachedFirstRectForCharacterRange( | 1441 bool RenderWidgetHostViewMac::GetCachedFirstRectForCharacterRange( |
1441 NSRange range, | 1442 NSRange range, |
1442 NSRect* rect, | 1443 NSRect* rect, |
1443 NSRange* actual_range) { | 1444 NSRange* actual_range) { |
1444 DCHECK(rect); | 1445 DCHECK(rect); |
1445 // This exists to make IMEs more responsive, see http://crbug.com/115920 | 1446 // This exists to make IMEs more responsive, see http://crbug.com/115920 |
1446 TRACE_EVENT0("browser", | 1447 TRACE_EVENT0("browser", |
1447 "RenderWidgetHostViewMac::GetFirstRectForCharacterRange"); | 1448 "RenderWidgetHostViewMac::GetFirstRectForCharacterRange"); |
1448 | 1449 |
1450 const gfx::Range requested_range(range); | |
1449 // If requested range is same as caret location, we can just return it. | 1451 // If requested range is same as caret location, we can just return it. |
1450 if (selection_range_.is_empty() && gfx::Range(range) == selection_range_) { | 1452 if (selection_range_.is_empty() && requested_range == selection_range_) { |
1451 if (actual_range) | 1453 if (actual_range) |
1452 *actual_range = range; | 1454 *actual_range = range; |
1453 *rect = NSRectFromCGRect(caret_rect_.ToCGRect()); | 1455 *rect = NSRectFromCGRect(caret_rect_.ToCGRect()); |
1454 return true; | 1456 return true; |
1455 } | 1457 } |
1456 | 1458 |
1459 if (composition_range_.is_empty()) { | |
1460 if (!selection_range_.Contains(requested_range)) | |
1461 return false; | |
1462 if (actual_range) | |
1463 *actual_range = selection_range_.ToNSRange(); | |
1464 *rect = NSRectFromCGRect(first_selection_rect_.ToCGRect()); | |
1465 return true; | |
1466 } | |
1467 | |
1457 const gfx::Range request_range_in_composition = | 1468 const gfx::Range request_range_in_composition = |
1458 ConvertCharacterRangeToCompositionRange(gfx::Range(range)); | 1469 ConvertCharacterRangeToCompositionRange(requested_range); |
1459 if (request_range_in_composition == gfx::Range::InvalidRange()) | 1470 if (request_range_in_composition == gfx::Range::InvalidRange()) |
1460 return false; | 1471 return false; |
1461 | 1472 |
1462 // If firstRectForCharacterRange in WebFrame is failed in renderer, | 1473 // If firstRectForCharacterRange in WebFrame is failed in renderer, |
1463 // ImeCompositionRangeChanged will be sent with empty vector. | 1474 // ImeCompositionRangeChanged will be sent with empty vector. |
1464 if (composition_bounds_.empty()) | 1475 if (composition_bounds_.empty()) |
1465 return false; | 1476 return false; |
1466 DCHECK_EQ(composition_bounds_.size(), composition_range_.length()); | 1477 DCHECK_EQ(composition_bounds_.size(), composition_range_.length()); |
1467 | 1478 |
1468 gfx::Range ui_actual_range; | 1479 gfx::Range ui_actual_range; |
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2348 | 2359 |
2349 - (void)smartMagnifyWithEvent:(NSEvent*)event { | 2360 - (void)smartMagnifyWithEvent:(NSEvent*)event { |
2350 const WebGestureEvent& smartMagnifyEvent = | 2361 const WebGestureEvent& smartMagnifyEvent = |
2351 WebInputEventFactory::gestureEvent(event, self); | 2362 WebInputEventFactory::gestureEvent(event, self); |
2352 if (renderWidgetHostView_ && renderWidgetHostView_->render_widget_host_) { | 2363 if (renderWidgetHostView_ && renderWidgetHostView_->render_widget_host_) { |
2353 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent( | 2364 renderWidgetHostView_->render_widget_host_->ForwardGestureEvent( |
2354 smartMagnifyEvent); | 2365 smartMagnifyEvent); |
2355 } | 2366 } |
2356 } | 2367 } |
2357 | 2368 |
2358 // This is invoked only on 10.8 or newer when the user taps a word using | 2369 - (void) ShowLookUpDictionary:(NSPoint)point { |
2359 // three fingers. | |
2360 - (void)quickLookWithEvent:(NSEvent*)event { | |
2361 NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil]; | |
2362 TextInputClientMac::GetInstance()->GetStringAtPoint( | 2370 TextInputClientMac::GetInstance()->GetStringAtPoint( |
2363 renderWidgetHostView_->render_widget_host_, | 2371 renderWidgetHostView_->render_widget_host_, |
2364 gfx::Point(point.x, NSHeight([self frame]) - point.y), | 2372 gfx::Point(point.x, NSHeight([self frame]) - point.y), |
2365 ^(NSAttributedString* string, NSPoint baselinePoint) { | 2373 ^(NSAttributedString* string, NSPoint baselinePoint) { |
2366 if (string && [string length] > 0) { | 2374 if (string && [string length] > 0) { |
2367 dispatch_async(dispatch_get_main_queue(), ^{ | 2375 dispatch_async(dispatch_get_main_queue(), ^{ |
2368 [self showDefinitionForAttributedString:string | 2376 [self showDefinitionForAttributedString:string |
2369 atPoint:baselinePoint]; | 2377 atPoint:baselinePoint]; |
2370 }); | 2378 }); |
2371 } | 2379 } |
2372 } | 2380 } |
2373 ); | 2381 ); |
2374 } | 2382 } |
2375 | 2383 |
2384 // This is invoked only on 10.8 or newer when the user taps a word using | |
2385 // three fingers. | |
2386 - (void)quickLookWithEvent:(NSEvent*)event { | |
Alexei Svitkine (slow)
2015/09/01 16:27:03
Please separate the dictionary logic change into i
Shu Chen
2015/09/02 03:35:42
Done.
| |
2387 NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil]; | |
2388 [self ShowLookUpDictionary:point]; | |
2389 } | |
2390 | |
2376 // This method handles 2 different types of hardware events. | 2391 // This method handles 2 different types of hardware events. |
2377 // (Apple does not distinguish between them). | 2392 // (Apple does not distinguish between them). |
2378 // a. Scrolling the middle wheel of a mouse. | 2393 // a. Scrolling the middle wheel of a mouse. |
2379 // b. Swiping on the track pad. | 2394 // b. Swiping on the track pad. |
2380 // | 2395 // |
2381 // This method is responsible for 2 types of behavior: | 2396 // This method is responsible for 2 types of behavior: |
2382 // a. Scrolling the content of window. | 2397 // a. Scrolling the content of window. |
2383 // b. Navigating forwards/backwards in history. | 2398 // b. Navigating forwards/backwards in history. |
2384 // | 2399 // |
2385 // This is a brief description of the logic: | 2400 // This is a brief description of the logic: |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2888 // there. (When this method returns an empty range, the input method doesn't | 2903 // there. (When this method returns an empty range, the input method doesn't |
2889 // call the setMarkedText method.) | 2904 // call the setMarkedText method.) |
2890 return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0); | 2905 return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0); |
2891 } | 2906 } |
2892 | 2907 |
2893 - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range | 2908 - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range |
2894 actualRange:(NSRangePointer)actualRange { | 2909 actualRange:(NSRangePointer)actualRange { |
2895 // TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery. | 2910 // TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery. |
2896 if (actualRange) | 2911 if (actualRange) |
2897 *actualRange = range; | 2912 *actualRange = range; |
2898 NSAttributedString* str = | 2913 |
2899 TextInputClientMac::GetInstance()->GetAttributedSubstringFromRange( | 2914 const gfx::Range requested_range(range); |
2900 renderWidgetHostView_->render_widget_host_, range); | 2915 if (requested_range.is_reversed()) |
2901 return str; | 2916 return nil; |
2917 | |
2918 gfx::Range expected_range; | |
2919 const base::string16* expected_text; | |
2920 | |
2921 if (!renderWidgetHostView_->composition_range().is_empty()) { | |
2922 expected_text = &markedText_; | |
2923 expected_range = renderWidgetHostView_->composition_range(); | |
2924 } else { | |
2925 expected_text = &renderWidgetHostView_->selection_text(); | |
2926 size_t offset = renderWidgetHostView_->selection_text_offset(); | |
2927 expected_range = gfx::Range(offset, offset + expected_text->size()); | |
palmer
2015/09/01 18:59:11
How do you know this range is valid? Can offset +
| |
2928 } | |
2929 | |
2930 if (!expected_range.Contains(requested_range)) | |
2931 return nil; | |
2932 | |
2933 // Gets the raw bytes to avoid unnecessary string copies for generating | |
2934 // NSString. | |
2935 const base::char16* bytes = | |
2936 &(*expected_text)[requested_range.start() - expected_range.start()]; | |
palmer
2015/09/01 18:59:12
I don't understand this code. What is going on?
W
| |
2937 NSUInteger bytes_len = requested_range.length() * sizeof(base::char16); | |
palmer
2015/09/01 18:59:12
Is NSUInteger guaranteed to have the same range as
| |
2938 base::scoped_nsobject<NSString> ns_string( | |
2939 [[NSString alloc] initWithBytes:bytes | |
2940 length:bytes_len | |
2941 encoding:NSUTF16LittleEndianStringEncoding]); | |
2942 return [[[NSAttributedString alloc] initWithString:ns_string] autorelease]; | |
2902 } | 2943 } |
2903 | 2944 |
2904 - (NSInteger)conversationIdentifier { | 2945 - (NSInteger)conversationIdentifier { |
2905 return reinterpret_cast<NSInteger>(self); | 2946 return reinterpret_cast<NSInteger>(self); |
2906 } | 2947 } |
2907 | 2948 |
2908 // Each RenderWidgetHostViewCocoa has its own input context, but we return | 2949 // Each RenderWidgetHostViewCocoa has its own input context, but we return |
2909 // nil when the caret is in non-editable content or password box to avoid | 2950 // nil when the caret is in non-editable content or password box to avoid |
2910 // making input methods do their work. | 2951 // making input methods do their work. |
2911 - (NSTextInputContext *)inputContext { | 2952 - (NSTextInputContext *)inputContext { |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3323 | 3364 |
3324 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding | 3365 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding |
3325 // regions that are not draggable. (See ControlRegionView in | 3366 // regions that are not draggable. (See ControlRegionView in |
3326 // native_app_window_cocoa.mm). This requires the render host view to be | 3367 // native_app_window_cocoa.mm). This requires the render host view to be |
3327 // draggable by default. | 3368 // draggable by default. |
3328 - (BOOL)mouseDownCanMoveWindow { | 3369 - (BOOL)mouseDownCanMoveWindow { |
3329 return YES; | 3370 return YES; |
3330 } | 3371 } |
3331 | 3372 |
3332 @end | 3373 @end |
OLD | NEW |