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 #include <QuartzCore/QuartzCore.h> | 7 #include <QuartzCore/QuartzCore.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 20 matching lines...) Expand all Loading... | |
31 #include "content/browser/renderer_host/render_process_host_impl.h" | 31 #include "content/browser/renderer_host/render_process_host_impl.h" |
32 #include "content/browser/renderer_host/render_view_host_impl.h" | 32 #include "content/browser/renderer_host/render_view_host_impl.h" |
33 #import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_h elper.h" | 33 #import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_h elper.h" |
34 #import "content/browser/renderer_host/text_input_client_mac.h" | 34 #import "content/browser/renderer_host/text_input_client_mac.h" |
35 #include "content/common/accessibility_messages.h" | 35 #include "content/common/accessibility_messages.h" |
36 #include "content/common/edit_command.h" | 36 #include "content/common/edit_command.h" |
37 #include "content/common/gpu/gpu_messages.h" | 37 #include "content/common/gpu/gpu_messages.h" |
38 #include "content/common/plugin_messages.h" | 38 #include "content/common/plugin_messages.h" |
39 #include "content/common/view_messages.h" | 39 #include "content/common/view_messages.h" |
40 #include "content/public/browser/browser_thread.h" | 40 #include "content/public/browser/browser_thread.h" |
41 #import "content/public/browser/event_hook_application_mac.h" | |
41 #include "content/public/browser/native_web_keyboard_event.h" | 42 #include "content/public/browser/native_web_keyboard_event.h" |
42 #import "content/public/browser/render_widget_host_view_mac_delegate.h" | 43 #import "content/public/browser/render_widget_host_view_mac_delegate.h" |
44 #include "content/public/browser/web_contents_view_delegate.h" | |
43 #include "skia/ext/platform_canvas.h" | 45 #include "skia/ext/platform_canvas.h" |
44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" | 47 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" |
46 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFact ory.h" | 48 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFact ory.h" |
47 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebScreenInfoFact ory.h" | 49 #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebScreenInfoFact ory.h" |
48 #import "third_party/mozilla/ComplexTextInputPanel.h" | 50 #import "third_party/mozilla/ComplexTextInputPanel.h" |
49 #include "third_party/skia/include/core/SkColor.h" | 51 #include "third_party/skia/include/core/SkColor.h" |
50 #import "ui/base/cocoa/fullscreen_window_manager.h" | 52 #import "ui/base/cocoa/fullscreen_window_manager.h" |
51 #import "ui/base/cocoa/underlay_opengl_hosting_window.h" | 53 #import "ui/base/cocoa/underlay_opengl_hosting_window.h" |
52 #include "ui/base/keycodes/keyboard_codes.h" | 54 #include "ui/base/keycodes/keyboard_codes.h" |
53 #include "ui/base/layout.h" | 55 #include "ui/base/layout.h" |
54 #include "ui/gfx/point.h" | 56 #include "ui/gfx/point.h" |
55 #include "ui/gfx/rect_conversions.h" | 57 #include "ui/gfx/rect_conversions.h" |
56 #include "ui/gfx/size_conversions.h" | 58 #include "ui/gfx/size_conversions.h" |
57 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" | 59 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
60 #include "ui/gfx/native_widget_types.h" | |
58 #include "ui/surface/io_surface_support_mac.h" | 61 #include "ui/surface/io_surface_support_mac.h" |
59 #include "webkit/plugins/npapi/webplugin.h" | 62 #include "webkit/plugins/npapi/webplugin.h" |
60 | 63 |
61 using content::BackingStoreMac; | 64 using content::BackingStoreMac; |
62 using content::BrowserAccessibility; | 65 using content::BrowserAccessibility; |
63 using content::BrowserAccessibilityManager; | 66 using content::BrowserAccessibilityManager; |
64 using content::EditCommand; | 67 using content::EditCommand; |
65 using content::NativeWebKeyboardEvent; | 68 using content::NativeWebKeyboardEvent; |
66 using content::RenderViewHostImpl; | 69 using content::RenderViewHostImpl; |
67 using content::RenderWidgetHostImpl; | 70 using content::RenderWidgetHostImpl; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 - (BOOL)canBecomeKeyWindow { | 163 - (BOOL)canBecomeKeyWindow { |
161 return YES; | 164 return YES; |
162 } | 165 } |
163 | 166 |
164 - (BOOL)canBecomeMainWindow { | 167 - (BOOL)canBecomeMainWindow { |
165 return YES; | 168 return YES; |
166 } | 169 } |
167 | 170 |
168 @end | 171 @end |
169 | 172 |
173 @interface RenderWidgetPopupWindow : NSWindow<EventHookProtocol> | |
174 @end | |
175 | |
176 @implementation RenderWidgetPopupWindow | |
177 | |
178 - (id)initWithContentRect:(NSRect)contentRect | |
179 styleMask:(NSUInteger)windowStyle | |
180 backing:(NSBackingStoreType)bufferingType | |
181 defer:(BOOL)deferCreation { | |
182 if (self = [super initWithContentRect:contentRect | |
183 styleMask:windowStyle | |
184 backing:bufferingType | |
185 defer:deferCreation]) { | |
186 [self setOpaque:NO]; | |
187 [self setBackgroundColor:[NSColor clearColor]]; | |
188 [self startObservingClick]; | |
189 } | |
190 return self; | |
191 } | |
192 | |
193 - (void)close { | |
194 [self stopObservingClick]; | |
195 [super close]; | |
196 } | |
197 | |
198 // Gets called for all events in application. Watching for a click outside the | |
199 // window so we can close. | |
200 - (void)hookForEvent:(NSEvent*)theEvent { | |
201 if ([theEvent window] == self) | |
202 return; | |
203 NSEventType eventType = [theEvent type]; | |
204 if (eventType == NSLeftMouseDown || eventType == NSRightMouseDown) { | |
205 [self close]; | |
206 } | |
207 } | |
208 | |
209 // Gets called when the menubar is clicked. | |
210 // Needed because the hookForEvent method doesn't see the click on the menubar. | |
211 - (void)begunTracking:(NSNotification *)notification { | |
212 [self close]; | |
213 } | |
214 | |
215 // Install the callback. | |
216 - (void)startObservingClick { | |
217 EventHookApplication* app = static_cast<EventHookApplication*>( | |
218 [EventHookApplication sharedApplication]); | |
219 [app addEventHook:self]; | |
220 | |
221 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; | |
222 [nc addObserver:self | |
223 selector:@selector(begunTracking:) | |
224 name:NSMenuDidBeginTrackingNotification | |
225 object:[NSApp mainMenu]]; | |
226 } | |
227 | |
228 // Remove the callback. | |
229 - (void)stopObservingClick { | |
230 EventHookApplication* app = static_cast<EventHookApplication*>( | |
231 [EventHookApplication sharedApplication]); | |
232 [app removeEventHook:self]; | |
233 | |
234 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; | |
235 [nc removeObserver:self | |
236 name:NSMenuDidBeginTrackingNotification | |
237 object:[NSApp mainMenu]]; | |
238 } | |
239 | |
240 @end | |
241 | |
170 namespace { | 242 namespace { |
171 | 243 |
172 // Maximum number of characters we allow in a tooltip. | 244 // Maximum number of characters we allow in a tooltip. |
173 const size_t kMaxTooltipLength = 1024; | 245 const size_t kMaxTooltipLength = 1024; |
174 | 246 |
175 // TODO(suzhe): Upstream this function. | 247 // TODO(suzhe): Upstream this function. |
176 WebKit::WebColor WebColorFromNSColor(NSColor *color) { | 248 WebKit::WebColor WebColorFromNSColor(NSColor *color) { |
177 CGFloat r, g, b, a; | 249 CGFloat r, g, b, a; |
178 [color getRed:&r green:&g blue:&b alpha:&a]; | 250 [color getRed:&r green:&g blue:&b alpha:&a]; |
179 | 251 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 } | 394 } |
323 | 395 |
324 /////////////////////////////////////////////////////////////////////////////// | 396 /////////////////////////////////////////////////////////////////////////////// |
325 // RenderWidgetHostViewMac, RenderWidgetHostView implementation: | 397 // RenderWidgetHostViewMac, RenderWidgetHostView implementation: |
326 | 398 |
327 void RenderWidgetHostViewMac::InitAsChild( | 399 void RenderWidgetHostViewMac::InitAsChild( |
328 gfx::NativeView parent_view) { | 400 gfx::NativeView parent_view) { |
329 } | 401 } |
330 | 402 |
331 void RenderWidgetHostViewMac::InitAsPopup( | 403 void RenderWidgetHostViewMac::InitAsPopup( |
332 RenderWidgetHostView* parent_host_view, | 404 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { |
333 const gfx::Rect& pos) { | |
334 bool activatable = popup_type_ == WebKit::WebPopupTypeNone; | 405 bool activatable = popup_type_ == WebKit::WebPopupTypeNone; |
335 [cocoa_view_ setCloseOnDeactivate:YES]; | 406 [cocoa_view_ setCloseOnDeactivate:YES]; |
336 [cocoa_view_ setCanBeKeyView:activatable ? YES : NO]; | 407 [cocoa_view_ setCanBeKeyView:activatable ? YES : NO]; |
337 [parent_host_view->GetNativeView() addSubview:cocoa_view_]; | 408 [parent_host_view->GetNativeView() addSubview:cocoa_view_]; |
338 | 409 |
339 NSPoint origin_global = NSPointFromCGPoint(pos.origin().ToCGPoint()); | 410 NSPoint origin_global = NSPointFromCGPoint(pos.origin().ToCGPoint()); |
340 if ([[NSScreen screens] count] > 0) { | 411 if ([[NSScreen screens] count] > 0) { |
341 origin_global.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - | 412 origin_global.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - |
342 pos.height() - origin_global.y; | 413 pos.height() - origin_global.y; |
343 } | 414 } |
344 NSPoint origin_window = | 415 |
345 [[cocoa_view_ window] convertScreenToBase:origin_global]; | 416 popup_window_.reset([[RenderWidgetPopupWindow alloc] |
346 NSPoint origin_view = | 417 initWithContentRect:NSMakeRect(origin_global.x, origin_global.y, |
347 [cocoa_view_ convertPoint:origin_window fromView:nil]; | 418 pos.width(), pos.height()) |
348 NSRect initial_frame = NSMakeRect(origin_view.x, | 419 styleMask:NSBorderlessWindowMask |
349 origin_view.y, | 420 backing:NSBackingStoreBuffered |
350 pos.width(), | 421 defer:NO]); |
351 pos.height()); | 422 [popup_window_ setLevel:NSPopUpMenuWindowLevel]; |
352 [cocoa_view_ setFrame:initial_frame]; | 423 [popup_window_ setReleasedWhenClosed:NO]; |
424 [popup_window_ makeKeyAndOrderFront:nil]; | |
425 [[popup_window_ contentView] addSubview:cocoa_view_]; | |
426 [cocoa_view_ setFrame:[[popup_window_ contentView] bounds]]; | |
427 [cocoa_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; | |
428 [popup_window_ setParentWindow:[parent_host_view->GetNativeView() window]]; | |
429 [[NSNotificationCenter defaultCenter] | |
430 addObserver:cocoa_view_ | |
431 selector:@selector(popupWindowWillClose:) | |
432 name:NSWindowWillCloseNotification | |
433 object:popup_window_]; | |
353 } | 434 } |
354 | 435 |
355 // This function creates the fullscreen window and hides the dock and menubar if | 436 // This function creates the fullscreen window and hides the dock and menubar if |
356 // necessary. Note, this codepath is only used for pepper flash when | 437 // necessary. Note, this codepath is only used for pepper flash when |
357 // pp::FlashFullScreen::SetFullscreen() is called. If | 438 // pp::FlashFullScreen::SetFullscreen() is called. If |
358 // pp::FullScreen::SetFullscreen() is called then the entire browser window | 439 // pp::FullScreen::SetFullscreen() is called then the entire browser window |
359 // will enter fullscreen instead. | 440 // will enter fullscreen instead. |
360 void RenderWidgetHostViewMac::InitAsFullscreen( | 441 void RenderWidgetHostViewMac::InitAsFullscreen( |
361 RenderWidgetHostView* reference_host_view) { | 442 RenderWidgetHostView* reference_host_view) { |
362 fullscreen_parent_host_view_ = | 443 fullscreen_parent_host_view_ = |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
451 if (rect.size().IsEmpty()) | 532 if (rect.size().IsEmpty()) |
452 return; | 533 return; |
453 | 534 |
454 // Ignore the position of |rect| for non-popup rwhvs. This is because | 535 // Ignore the position of |rect| for non-popup rwhvs. This is because |
455 // background tabs do not have a window, but the window is required for the | 536 // background tabs do not have a window, but the window is required for the |
456 // coordinate conversions. Popups are always for a visible tab. | 537 // coordinate conversions. Popups are always for a visible tab. |
457 if (IsPopup()) { | 538 if (IsPopup()) { |
458 // The position of |rect| is screen coordinate system and we have to | 539 // The position of |rect| is screen coordinate system and we have to |
459 // consider Cocoa coordinate system is upside-down and also multi-screen. | 540 // consider Cocoa coordinate system is upside-down and also multi-screen. |
460 NSPoint origin_global = NSPointFromCGPoint(rect.origin().ToCGPoint()); | 541 NSPoint origin_global = NSPointFromCGPoint(rect.origin().ToCGPoint()); |
542 NSSize size = NSMakeSize(rect.width(), rect.height()); | |
543 size = [cocoa_view_ convertSize:size toView:nil]; | |
461 if ([[NSScreen screens] count] > 0) { | 544 if ([[NSScreen screens] count] > 0) { |
462 NSSize size = NSMakeSize(rect.width(), rect.height()); | |
463 size = [cocoa_view_ convertSize:size toView:nil]; | |
464 NSScreen* screen = | 545 NSScreen* screen = |
465 static_cast<NSScreen*>([[NSScreen screens] objectAtIndex:0]); | 546 static_cast<NSScreen*>([[NSScreen screens] objectAtIndex:0]); |
466 origin_global.y = | 547 origin_global.y = |
467 NSHeight([screen frame]) - size.height - origin_global.y; | 548 NSHeight([screen frame]) - size.height - origin_global.y; |
468 } | 549 } |
469 | 550 [popup_window_ setFrame:NSMakeRect(origin_global.x, origin_global.y, |
470 // Then |origin_global| is converted to client coordinate system. | 551 size.width, size.height) |
471 DCHECK([cocoa_view_ window]); | 552 display:YES]; |
Avi (use Gerrit)
2012/12/11 21:59:37
Yes, I like this.
| |
472 NSPoint origin_window = | |
473 [[cocoa_view_ window] convertScreenToBase:origin_global]; | |
474 NSPoint origin_view = | |
475 [[cocoa_view_ superview] convertPoint:origin_window fromView:nil]; | |
476 NSRect frame = NSMakeRect(origin_view.x, origin_view.y, | |
477 rect.width(), rect.height()); | |
478 [cocoa_view_ setFrame:frame]; | |
479 } else { | 553 } else { |
480 DCHECK([[cocoa_view_ superview] isKindOfClass:[BaseView class]]); | 554 DCHECK([[cocoa_view_ superview] isKindOfClass:[BaseView class]]); |
481 BaseView* superview = static_cast<BaseView*>([cocoa_view_ superview]); | 555 BaseView* superview = static_cast<BaseView*>([cocoa_view_ superview]); |
482 gfx::Rect rect2 = [superview flipNSRectToRect:[cocoa_view_ frame]]; | 556 gfx::Rect rect2 = [superview flipNSRectToRect:[cocoa_view_ frame]]; |
483 rect2.set_width(rect.width()); | 557 rect2.set_width(rect.width()); |
484 rect2.set_height(rect.height()); | 558 rect2.set_height(rect.height()); |
485 [cocoa_view_ setFrame:[superview flipRectToNSRect:rect2]]; | 559 [cocoa_view_ setFrame:[superview flipRectToNSRect:rect2]]; |
486 } | 560 } |
487 } | 561 } |
488 | 562 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
723 [static_cast<AcceleratedPluginView*>(subview) | 797 [static_cast<AcceleratedPluginView*>(subview) |
724 onRenderWidgetHostViewGone]; | 798 onRenderWidgetHostViewGone]; |
725 } | 799 } |
726 } | 800 } |
727 | 801 |
728 // We've been told to destroy. | 802 // We've been told to destroy. |
729 [cocoa_view_ retain]; | 803 [cocoa_view_ retain]; |
730 [cocoa_view_ removeFromSuperview]; | 804 [cocoa_view_ removeFromSuperview]; |
731 [cocoa_view_ autorelease]; | 805 [cocoa_view_ autorelease]; |
732 | 806 |
807 [popup_window_ close]; | |
808 popup_window_.autorelease(); | |
809 | |
733 [fullscreen_window_manager_ exitFullscreenMode]; | 810 [fullscreen_window_manager_ exitFullscreenMode]; |
734 fullscreen_window_manager_.reset(); | 811 fullscreen_window_manager_.reset(); |
735 [pepper_fullscreen_window_ close]; | 812 [pepper_fullscreen_window_ close]; |
736 | 813 |
737 // This can be called as part of processing the window's responder | 814 // This can be called as part of processing the window's responder |
738 // chain, for instance |-performKeyEquivalent:|. In that case the | 815 // chain, for instance |-performKeyEquivalent:|. In that case the |
739 // object needs to survive until the stack unwinds. | 816 // object needs to survive until the stack unwinds. |
740 pepper_fullscreen_window_.autorelease(); | 817 pepper_fullscreen_window_.autorelease(); |
741 | 818 |
742 // We get this call just before |render_widget_host_| deletes | 819 // We get this call just before |render_widget_host_| deletes |
(...skipping 2603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3346 } | 3423 } |
3347 | 3424 |
3348 - (void)updateCursor:(NSCursor*)cursor { | 3425 - (void)updateCursor:(NSCursor*)cursor { |
3349 if (currentCursor_ == cursor) | 3426 if (currentCursor_ == cursor) |
3350 return; | 3427 return; |
3351 | 3428 |
3352 currentCursor_.reset(cursor, base::scoped_policy::RETAIN); | 3429 currentCursor_.reset(cursor, base::scoped_policy::RETAIN); |
3353 [[self window] invalidateCursorRectsForView:self]; | 3430 [[self window] invalidateCursorRectsForView:self]; |
3354 } | 3431 } |
3355 | 3432 |
3433 - (void)popupWindowWillClose:(NSNotification *)notification { | |
3434 [self resignFirstResponder]; | |
3435 } | |
3436 | |
3356 @end | 3437 @end |
3357 | 3438 |
3358 // | 3439 // |
3359 // Supporting application services | 3440 // Supporting application services |
3360 // | 3441 // |
3361 @implementation RenderWidgetHostViewCocoa(NSServicesRequests) | 3442 @implementation RenderWidgetHostViewCocoa(NSServicesRequests) |
3362 | 3443 |
3363 - (BOOL)writeSelectionToPasteboard:(NSPasteboard*)pboard | 3444 - (BOOL)writeSelectionToPasteboard:(NSPasteboard*)pboard |
3364 types:(NSArray*)types { | 3445 types:(NSArray*)types { |
3365 const std::string& str = renderWidgetHostView_->selected_text(); | 3446 const std::string& str = renderWidgetHostView_->selected_text(); |
(...skipping 11 matching lines...) Expand all Loading... | |
3377 if (!string) return NO; | 3458 if (!string) return NO; |
3378 | 3459 |
3379 // If the user is currently using an IME, confirm the IME input, | 3460 // If the user is currently using an IME, confirm the IME input, |
3380 // and then insert the text from the service, the same as TextEdit and Safari. | 3461 // and then insert the text from the service, the same as TextEdit and Safari. |
3381 [self confirmComposition]; | 3462 [self confirmComposition]; |
3382 [self insertText:string]; | 3463 [self insertText:string]; |
3383 return YES; | 3464 return YES; |
3384 } | 3465 } |
3385 | 3466 |
3386 @end | 3467 @end |
OLD | NEW |