| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "app/app_switches.h" | 9 #include "app/app_switches.h" |
| 10 #include "app/surface/io_surface_support_mac.h" | 10 #include "app/surface/io_surface_support_mac.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 #include "chrome/common/native_web_keyboard_event.h" | 34 #include "chrome/common/native_web_keyboard_event.h" |
| 35 #include "chrome/common/edit_command.h" | 35 #include "chrome/common/edit_command.h" |
| 36 #include "chrome/common/plugin_messages.h" | 36 #include "chrome/common/plugin_messages.h" |
| 37 #include "chrome/common/render_messages.h" | 37 #include "chrome/common/render_messages.h" |
| 38 #include "skia/ext/platform_canvas.h" | 38 #include "skia/ext/platform_canvas.h" |
| 39 #include "third_party/skia/include/core/SkColor.h" | 39 #include "third_party/skia/include/core/SkColor.h" |
| 40 #include "third_party/WebKit/WebKit/chromium/public/mac/WebInputEventFactory.h" | 40 #include "third_party/WebKit/WebKit/chromium/public/mac/WebInputEventFactory.h" |
| 41 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" | 41 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" |
| 42 #include "webkit/glue/plugins/webplugin.h" | 42 #include "webkit/glue/plugins/webplugin.h" |
| 43 #include "webkit/glue/webaccessibility.h" | 43 #include "webkit/glue/webaccessibility.h" |
| 44 #include "webkit/glue/webmenurunner_mac.h" | |
| 45 #import "third_party/mozilla/ComplexTextInputPanel.h" | 44 #import "third_party/mozilla/ComplexTextInputPanel.h" |
| 46 | 45 |
| 47 using WebKit::WebInputEvent; | 46 using WebKit::WebInputEvent; |
| 48 using WebKit::WebInputEventFactory; | 47 using WebKit::WebInputEventFactory; |
| 49 using WebKit::WebMouseEvent; | 48 using WebKit::WebMouseEvent; |
| 50 using WebKit::WebMouseWheelEvent; | 49 using WebKit::WebMouseWheelEvent; |
| 51 | 50 |
| 52 static inline int ToWebKitModifiers(NSUInteger flags) { | 51 static inline int ToWebKitModifiers(NSUInteger flags) { |
| 53 int modifiers = 0; | 52 int modifiers = 0; |
| 54 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; | 53 if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey; |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 /////////////////////////////////////////////////////////////////////////////// | 430 /////////////////////////////////////////////////////////////////////////////// |
| 432 // RenderWidgetHostViewMac, public: | 431 // RenderWidgetHostViewMac, public: |
| 433 | 432 |
| 434 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) | 433 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
| 435 : render_widget_host_(widget), | 434 : render_widget_host_(widget), |
| 436 about_to_validate_and_paint_(false), | 435 about_to_validate_and_paint_(false), |
| 437 call_set_needs_display_in_rect_pending_(false), | 436 call_set_needs_display_in_rect_pending_(false), |
| 438 text_input_type_(WebKit::WebTextInputTypeNone), | 437 text_input_type_(WebKit::WebTextInputTypeNone), |
| 439 is_loading_(false), | 438 is_loading_(false), |
| 440 is_hidden_(false), | 439 is_hidden_(false), |
| 441 is_popup_menu_(false), | 440 shutdown_factory_(this) { |
| 442 shutdown_factory_(this), | |
| 443 parent_view_(NULL) { | |
| 444 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| goes away. | 441 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| goes away. |
| 445 // Since we autorelease it, our caller must put |native_view()| into the view | 442 // Since we autorelease it, our caller must put |native_view()| into the view |
| 446 // hierarchy right after calling us. | 443 // hierarchy right after calling us. |
| 447 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 444 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
| 448 initWithRenderWidgetHostViewMac:this] autorelease]; | 445 initWithRenderWidgetHostViewMac:this] autorelease]; |
| 449 render_widget_host_->set_view(this); | 446 render_widget_host_->set_view(this); |
| 450 | 447 |
| 451 // Turn on accessibility only if VoiceOver is running. | 448 // Turn on accessibility only if VoiceOver is running. |
| 452 if (IsVoiceOverRunning()) { | 449 if (IsVoiceOverRunning()) { |
| 453 Singleton<BrowserAccessibilityState>()->OnScreenReaderDetected(); | 450 Singleton<BrowserAccessibilityState>()->OnScreenReaderDetected(); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 | 722 |
| 726 void RenderWidgetHostViewMac::Destroy() { | 723 void RenderWidgetHostViewMac::Destroy() { |
| 727 // On Windows, popups are implemented with a popup window style, so that when | 724 // On Windows, popups are implemented with a popup window style, so that when |
| 728 // an event comes in that would "cancel" it, it receives the OnCancelMode | 725 // an event comes in that would "cancel" it, it receives the OnCancelMode |
| 729 // message and can kill itself. Alas, on the Mac, views cannot capture events | 726 // message and can kill itself. Alas, on the Mac, views cannot capture events |
| 730 // outside of themselves. On Windows, if Destroy is being called on a view, | 727 // outside of themselves. On Windows, if Destroy is being called on a view, |
| 731 // then the event causing the destroy had also cancelled any popups by the | 728 // then the event causing the destroy had also cancelled any popups by the |
| 732 // time Destroy() was called. On the Mac we have to destroy all the popups | 729 // time Destroy() was called. On the Mac we have to destroy all the popups |
| 733 // ourselves. | 730 // ourselves. |
| 734 | 731 |
| 735 if (!is_popup_menu_) { | 732 // Depth-first destroy all popups. Use ShutdownHost() to enforce |
| 736 // Depth-first destroy all popups. Use ShutdownHost() to enforce | 733 // deepest-first ordering. |
| 737 // deepest-first ordering. | 734 for (NSView* subview in [cocoa_view_ subviews]) { |
| 738 for (NSView* subview in [cocoa_view_ subviews]) { | 735 if ([subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) { |
| 739 if ([subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) { | 736 [static_cast<RenderWidgetHostViewCocoa*>(subview) |
| 740 [static_cast<RenderWidgetHostViewCocoa*>(subview) | 737 renderWidgetHostViewMac]->ShutdownHost(); |
| 741 renderWidgetHostViewMac]->ShutdownHost(); | 738 } else if ([subview isKindOfClass:[AcceleratedPluginView class]]) { |
| 742 } else if ([subview isKindOfClass:[AcceleratedPluginView class]]) { | 739 [static_cast<AcceleratedPluginView*>(subview) |
| 743 [static_cast<AcceleratedPluginView*>(subview) | 740 onRenderWidgetHostViewGone]; |
| 744 onRenderWidgetHostViewGone]; | |
| 745 } | |
| 746 } | 741 } |
| 742 } |
| 747 | 743 |
| 748 // We've been told to destroy. | 744 // We've been told to destroy. |
| 749 [cocoa_view_ retain]; | 745 [cocoa_view_ retain]; |
| 750 [cocoa_view_ removeFromSuperview]; | 746 [cocoa_view_ removeFromSuperview]; |
| 751 [cocoa_view_ autorelease]; | 747 [cocoa_view_ autorelease]; |
| 752 } else { | |
| 753 // From the renderer's perspective, the pop-up menu is represented by a | |
| 754 // RenderWidget. The actual Mac implementation uses a native pop-up menu | |
| 755 // and doesn't actually make use of the RenderWidgetHostViewCocoa that | |
| 756 // was allocated to own it in its constructor. When the pop-up menu goes | |
| 757 // away, free the RenderWidgetHostViewCocoa. Its deallocation will result | |
| 758 // in this object's destruction. | |
| 759 | |
| 760 DCHECK([[cocoa_view_ subviews] count] == 0); | |
| 761 DCHECK([cocoa_view_ superview] == nil); | |
| 762 | |
| 763 [cocoa_view_ autorelease]; | |
| 764 } | |
| 765 | 748 |
| 766 // We get this call just before |render_widget_host_| deletes | 749 // We get this call just before |render_widget_host_| deletes |
| 767 // itself. But we are owned by |cocoa_view_|, which may be retained | 750 // itself. But we are owned by |cocoa_view_|, which may be retained |
| 768 // by some other code. Examples are TabContentsViewMac's | 751 // by some other code. Examples are TabContentsViewMac's |
| 769 // |latent_focus_view_| and TabWindowController's | 752 // |latent_focus_view_| and TabWindowController's |
| 770 // |cachedContentView_|. | 753 // |cachedContentView_|. |
| 771 render_widget_host_ = NULL; | 754 render_widget_host_ = NULL; |
| 772 } | 755 } |
| 773 | 756 |
| 774 // Called from the renderer to tell us what the tooltip text should be. It | 757 // Called from the renderer to tell us what the tooltip text should be. It |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 const gfx::Size& size) { | 791 const gfx::Size& size) { |
| 809 NOTIMPLEMENTED(); | 792 NOTIMPLEMENTED(); |
| 810 return NULL; | 793 return NULL; |
| 811 } | 794 } |
| 812 | 795 |
| 813 // Sets whether or not to accept first responder status. | 796 // Sets whether or not to accept first responder status. |
| 814 void RenderWidgetHostViewMac::SetTakesFocusOnlyOnMouseDown(bool flag) { | 797 void RenderWidgetHostViewMac::SetTakesFocusOnlyOnMouseDown(bool flag) { |
| 815 [cocoa_view_ setTakesFocusOnlyOnMouseDown:flag]; | 798 [cocoa_view_ setTakesFocusOnlyOnMouseDown:flag]; |
| 816 } | 799 } |
| 817 | 800 |
| 818 // Display a popup menu for WebKit using Cocoa widgets. | |
| 819 void RenderWidgetHostViewMac::ShowPopupWithItems( | |
| 820 gfx::Rect bounds, | |
| 821 int item_height, | |
| 822 double item_font_size, | |
| 823 int selected_item, | |
| 824 const std::vector<WebMenuItem>& items, | |
| 825 bool right_aligned) { | |
| 826 is_popup_menu_ = true; | |
| 827 | |
| 828 // Retain the Cocoa view for the duration of the pop-up so that it can't | |
| 829 // be dealloced if my Destroy() method is called while the pop-up's up | |
| 830 // (which would in turn delete me, causing a crash once the -runMenuInView | |
| 831 // call returns. That's what was happening in <http://crbug.com/33250>). | |
| 832 scoped_nsobject<RenderWidgetHostViewCocoa> retainedCocoaView | |
| 833 ([cocoa_view_ retain]); | |
| 834 | |
| 835 NSRect view_rect = [cocoa_view_ bounds]; | |
| 836 NSRect parent_rect = [parent_view_ bounds]; | |
| 837 int y_offset = bounds.y() + bounds.height(); | |
| 838 NSRect position = NSMakeRect(bounds.x(), parent_rect.size.height - y_offset, | |
| 839 bounds.width(), bounds.height()); | |
| 840 | |
| 841 // Display the menu. | |
| 842 scoped_nsobject<WebMenuRunner> menu_runner; | |
| 843 menu_runner.reset([[WebMenuRunner alloc] initWithItems:items | |
| 844 fontSize:item_font_size | |
| 845 rightAligned:right_aligned]); | |
| 846 | |
| 847 { | |
| 848 // Make sure events can be pumped while the menu is up. | |
| 849 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); | |
| 850 | |
| 851 // One of the events that could be pumped is |window.close()|. | |
| 852 // User-initiated event-tracking loops protect against this by | |
| 853 // setting flags in -[CrApplication sendEvent:], but since | |
| 854 // web-content menus are initiated by IPC message the setup has to | |
| 855 // be done manually. | |
| 856 chrome_application_mac::ScopedSendingEvent sendingEventScoper; | |
| 857 | |
| 858 // Now run a SYNCHRONOUS NESTED EVENT LOOP until the pop-up is finished. | |
| 859 [menu_runner runMenuInView:parent_view_ | |
| 860 withBounds:position | |
| 861 initialIndex:selected_item]; | |
| 862 } | |
| 863 | |
| 864 if (!render_widget_host_) { | |
| 865 // Bad news -- my Destroy() was called while I was off running the menu. | |
| 866 // Return ASAP, and the release of retainedCocoaView will dealloc my NSView, | |
| 867 // which will delete me (whew). | |
| 868 return; | |
| 869 } | |
| 870 | |
| 871 int window_num = [[parent_view_ window] windowNumber]; | |
| 872 NSEvent* event = | |
| 873 webkit_glue::EventWithMenuAction([menu_runner menuItemWasChosen], | |
| 874 window_num, item_height, | |
| 875 [menu_runner indexOfSelectedItem], | |
| 876 position, view_rect); | |
| 877 | |
| 878 if ([menu_runner menuItemWasChosen]) { | |
| 879 // Simulate a menu selection event. | |
| 880 const WebMouseEvent& mouse_event = | |
| 881 WebInputEventFactory::mouseEvent(event, cocoa_view_); | |
| 882 render_widget_host_->ForwardMouseEvent(mouse_event); | |
| 883 } else { | |
| 884 // Simulate a menu dismiss event. | |
| 885 NativeWebKeyboardEvent keyboard_event(event); | |
| 886 render_widget_host_->ForwardKeyboardEvent(keyboard_event); | |
| 887 } | |
| 888 } | |
| 889 | |
| 890 void RenderWidgetHostViewMac::KillSelf() { | 801 void RenderWidgetHostViewMac::KillSelf() { |
| 891 if (shutdown_factory_.empty()) { | 802 if (shutdown_factory_.empty()) { |
| 892 [cocoa_view_ setHidden:YES]; | 803 [cocoa_view_ setHidden:YES]; |
| 893 MessageLoop::current()->PostTask(FROM_HERE, | 804 MessageLoop::current()->PostTask(FROM_HERE, |
| 894 shutdown_factory_.NewRunnableMethod( | 805 shutdown_factory_.NewRunnableMethod( |
| 895 &RenderWidgetHostViewMac::ShutdownHost)); | 806 &RenderWidgetHostViewMac::ShutdownHost)); |
| 896 } | 807 } |
| 897 } | 808 } |
| 898 | 809 |
| 899 void RenderWidgetHostViewMac::SetPluginImeEnabled(bool enabled, int plugin_id) { | 810 void RenderWidgetHostViewMac::SetPluginImeEnabled(bool enabled, int plugin_id) { |
| (...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2597 if (!string) return NO; | 2508 if (!string) return NO; |
| 2598 | 2509 |
| 2599 // If the user is currently using an IME, confirm the IME input, | 2510 // If the user is currently using an IME, confirm the IME input, |
| 2600 // and then insert the text from the service, the same as TextEdit and Safari. | 2511 // and then insert the text from the service, the same as TextEdit and Safari. |
| 2601 [self confirmComposition]; | 2512 [self confirmComposition]; |
| 2602 [self insertText:string]; | 2513 [self insertText:string]; |
| 2603 return YES; | 2514 return YES; |
| 2604 } | 2515 } |
| 2605 | 2516 |
| 2606 @end | 2517 @end |
| OLD | NEW |