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

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_mac.mm

Issue 1327743002: Avoid sync IPCs for firstRectForCharacterRange/attributedSubstringForProposedRange. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 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 unified diff | Download patch
OLDNEW
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
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/callback_helpers.h" 13 #include "base/callback_helpers.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/debug/crash_logging.h" 15 #include "base/debug/crash_logging.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/mac/mac_util.h" 17 #include "base/mac/mac_util.h"
18 #include "base/mac/scoped_cftyperef.h" 18 #include "base/mac/scoped_cftyperef.h"
19 #import "base/mac/scoped_nsobject.h" 19 #import "base/mac/scoped_nsobject.h"
20 #include "base/mac/sdk_forward_declarations.h" 20 #include "base/mac/sdk_forward_declarations.h"
21 #include "base/message_loop/message_loop.h" 21 #include "base/message_loop/message_loop.h"
22 #include "base/metrics/histogram.h" 22 #include "base/metrics/histogram.h"
23 #include "base/numerics/safe_conversions.h"
23 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
24 #include "base/strings/stringprintf.h" 25 #include "base/strings/stringprintf.h"
25 #include "base/strings/sys_string_conversions.h" 26 #include "base/strings/sys_string_conversions.h"
26 #include "base/strings/utf_string_conversions.h" 27 #include "base/strings/utf_string_conversions.h"
27 #include "base/sys_info.h" 28 #include "base/sys_info.h"
28 #include "base/trace_event/trace_event.h" 29 #include "base/trace_event/trace_event.h"
29 #import "content/browser/accessibility/browser_accessibility_cocoa.h" 30 #import "content/browser/accessibility/browser_accessibility_cocoa.h"
30 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" 31 #include "content/browser/accessibility/browser_accessibility_manager_mac.h"
31 #include "content/browser/bad_message.h" 32 #include "content/browser/bad_message.h"
32 #import "content/browser/cocoa/system_hotkey_helper_mac.h" 33 #import "content/browser/cocoa/system_hotkey_helper_mac.h"
(...skipping 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 [cocoa_view_ setMarkedRange:range.ToNSRange()]; 1220 [cocoa_view_ setMarkedRange:range.ToNSRange()];
1220 } 1221 }
1221 1222
1222 RenderWidgetHostViewBase::SelectionChanged(text, offset, range); 1223 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
1223 } 1224 }
1224 1225
1225 void RenderWidgetHostViewMac::SelectionBoundsChanged( 1226 void RenderWidgetHostViewMac::SelectionBoundsChanged(
1226 const ViewHostMsg_SelectionBounds_Params& params) { 1227 const ViewHostMsg_SelectionBounds_Params& params) {
1227 if (params.anchor_rect == params.focus_rect) 1228 if (params.anchor_rect == params.focus_rect)
1228 caret_rect_ = params.anchor_rect; 1229 caret_rect_ = params.anchor_rect;
1230 first_selection_rect_ = params.anchor_rect;
1229 } 1231 }
1230 1232
1231 void RenderWidgetHostViewMac::SetShowingContextMenu(bool showing) { 1233 void RenderWidgetHostViewMac::SetShowingContextMenu(bool showing) {
1232 RenderWidgetHostViewBase::SetShowingContextMenu(showing); 1234 RenderWidgetHostViewBase::SetShowingContextMenu(showing);
1233 1235
1234 // Create a fake mouse event to inform the render widget that the mouse 1236 // Create a fake mouse event to inform the render widget that the mouse
1235 // left or entered. 1237 // left or entered.
1236 NSWindow* window = [cocoa_view_ window]; 1238 NSWindow* window = [cocoa_view_ window];
1237 // TODO(asvitkine): If the location outside of the event stream doesn't 1239 // TODO(asvitkine): If the location outside of the event stream doesn't
1238 // correspond to the current event (due to delayed event processing), then 1240 // correspond to the current event (due to delayed event processing), then
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 1441
1440 bool RenderWidgetHostViewMac::GetCachedFirstRectForCharacterRange( 1442 bool RenderWidgetHostViewMac::GetCachedFirstRectForCharacterRange(
1441 NSRange range, 1443 NSRange range,
1442 NSRect* rect, 1444 NSRect* rect,
1443 NSRange* actual_range) { 1445 NSRange* actual_range) {
1444 DCHECK(rect); 1446 DCHECK(rect);
1445 // This exists to make IMEs more responsive, see http://crbug.com/115920 1447 // This exists to make IMEs more responsive, see http://crbug.com/115920
1446 TRACE_EVENT0("browser", 1448 TRACE_EVENT0("browser",
1447 "RenderWidgetHostViewMac::GetFirstRectForCharacterRange"); 1449 "RenderWidgetHostViewMac::GetFirstRectForCharacterRange");
1448 1450
1451 const gfx::Range requested_range(range);
1449 // If requested range is same as caret location, we can just return it. 1452 // If requested range is same as caret location, we can just return it.
1450 if (selection_range_.is_empty() && gfx::Range(range) == selection_range_) { 1453 if (selection_range_.is_empty() && requested_range == selection_range_) {
1451 if (actual_range) 1454 if (actual_range)
1452 *actual_range = range; 1455 *actual_range = range;
1453 *rect = NSRectFromCGRect(caret_rect_.ToCGRect()); 1456 *rect = NSRectFromCGRect(caret_rect_.ToCGRect());
1454 return true; 1457 return true;
1455 } 1458 }
1456 1459
1460 if (composition_range_.is_empty()) {
1461 if (!selection_range_.Contains(requested_range))
1462 return false;
1463 if (actual_range)
1464 *actual_range = selection_range_.ToNSRange();
1465 *rect = NSRectFromCGRect(first_selection_rect_.ToCGRect());
1466 return true;
1467 }
1468
1457 const gfx::Range request_range_in_composition = 1469 const gfx::Range request_range_in_composition =
1458 ConvertCharacterRangeToCompositionRange(gfx::Range(range)); 1470 ConvertCharacterRangeToCompositionRange(requested_range);
1459 if (request_range_in_composition == gfx::Range::InvalidRange()) 1471 if (request_range_in_composition == gfx::Range::InvalidRange())
1460 return false; 1472 return false;
1461 1473
1462 // If firstRectForCharacterRange in WebFrame is failed in renderer, 1474 // If firstRectForCharacterRange in WebFrame is failed in renderer,
1463 // ImeCompositionRangeChanged will be sent with empty vector. 1475 // ImeCompositionRangeChanged will be sent with empty vector.
1464 if (composition_bounds_.empty()) 1476 if (composition_bounds_.empty())
1465 return false; 1477 return false;
1466 DCHECK_EQ(composition_bounds_.size(), composition_range_.length()); 1478 DCHECK_EQ(composition_bounds_.size(), composition_range_.length());
1467 1479
1468 gfx::Range ui_actual_range; 1480 gfx::Range ui_actual_range;
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after
2888 // there. (When this method returns an empty range, the input method doesn't 2900 // there. (When this method returns an empty range, the input method doesn't
2889 // call the setMarkedText method.) 2901 // call the setMarkedText method.)
2890 return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0); 2902 return hasMarkedText_ ? markedRange_ : NSMakeRange(NSNotFound, 0);
2891 } 2903 }
2892 2904
2893 - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range 2905 - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range
2894 actualRange:(NSRangePointer)actualRange { 2906 actualRange:(NSRangePointer)actualRange {
2895 // TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery. 2907 // TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery.
2896 if (actualRange) 2908 if (actualRange)
2897 *actualRange = range; 2909 *actualRange = range;
2898 NSAttributedString* str = 2910
2899 TextInputClientMac::GetInstance()->GetAttributedSubstringFromRange( 2911 const gfx::Range requested_range(range);
2900 renderWidgetHostView_->render_widget_host_, range); 2912 if (requested_range.is_reversed())
2901 return str; 2913 return nil;
2914 size_t requested_len = requested_range.length();
2915 // Avoid integer overflow.
palmer 2015/09/03 23:03:59 This check is OK, but it's easy for people to get
Shu Chen 2015/09/04 01:36:47 Done.
2916 if (requested_len > NSUIntegerMax / sizeof(base::char16))
2917 return nil;
2918
2919 gfx::Range expected_range;
2920 const base::string16* expected_text;
2921
2922 if (!renderWidgetHostView_->composition_range().is_empty()) {
2923 expected_text = &markedText_;
2924 expected_range = renderWidgetHostView_->composition_range();
2925 } else {
2926 expected_text = &renderWidgetHostView_->selection_text();
2927 size_t offset = renderWidgetHostView_->selection_text_offset();
2928 expected_range = gfx::Range(offset, offset + expected_text->size());
2929 }
2930
2931 if (!expected_range.Contains(requested_range))
2932 return nil;
2933
2934 // Gets the raw bytes to avoid unnecessary string copies for generating
2935 // NSString.
2936 const base::char16* bytes =
2937 &(*expected_text)[requested_range.start() - expected_range.start()];
2938 NSUInteger bytes_len = base::strict_cast<NSUInteger, size_t>(
2939 requested_len * sizeof(base::char16));
2940 base::scoped_nsobject<NSString> ns_string(
2941 [[NSString alloc] initWithBytes:bytes
2942 length:bytes_len
2943 encoding:NSUTF16LittleEndianStringEncoding]);
2944 return [[[NSAttributedString alloc] initWithString:ns_string] autorelease];
2902 } 2945 }
2903 2946
2904 - (NSInteger)conversationIdentifier { 2947 - (NSInteger)conversationIdentifier {
2905 return reinterpret_cast<NSInteger>(self); 2948 return reinterpret_cast<NSInteger>(self);
2906 } 2949 }
2907 2950
2908 // Each RenderWidgetHostViewCocoa has its own input context, but we return 2951 // 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 2952 // nil when the caret is in non-editable content or password box to avoid
2910 // making input methods do their work. 2953 // making input methods do their work.
2911 - (NSTextInputContext *)inputContext { 2954 - (NSTextInputContext *)inputContext {
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
3323 3366
3324 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding 3367 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding
3325 // regions that are not draggable. (See ControlRegionView in 3368 // regions that are not draggable. (See ControlRegionView in
3326 // native_app_window_cocoa.mm). This requires the render host view to be 3369 // native_app_window_cocoa.mm). This requires the render host view to be
3327 // draggable by default. 3370 // draggable by default.
3328 - (BOOL)mouseDownCanMoveWindow { 3371 - (BOOL)mouseDownCanMoveWindow {
3329 return YES; 3372 return YES;
3330 } 3373 }
3331 3374
3332 @end 3375 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698