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_gtk.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_gtk.h" |
6 | 6 |
7 // If this gets included after the gtk headers, then a bunch of compiler | 7 // If this gets included after the gtk headers, then a bunch of compiler |
8 // errors happen because of a "#define Status int" in Xlib.h, which interacts | 8 // errors happen because of a "#define Status int" in Xlib.h, which interacts |
9 // badly with net::URLRequestStatus::Status. | 9 // badly with net::URLRequestStatus::Status. |
10 #include "content/common/view_messages.h" | 10 #include "content/common/view_messages.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "content/browser/renderer_host/render_view_host_impl.h" | 36 #include "content/browser/renderer_host/render_view_host_impl.h" |
37 #include "content/common/gpu/gpu_messages.h" | 37 #include "content/common/gpu/gpu_messages.h" |
38 #include "content/public/browser/native_web_keyboard_event.h" | 38 #include "content/public/browser/native_web_keyboard_event.h" |
39 #include "content/public/common/content_switches.h" | 39 #include "content/public/common/content_switches.h" |
40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
41 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" | 41 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" |
42 #include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFact
ory.h" | 42 #include "third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFact
ory.h" |
43 #include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFact
ory.h" | 43 #include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFact
ory.h" |
44 #include "ui/base/gtk/gtk_compat.h" | 44 #include "ui/base/gtk/gtk_compat.h" |
45 #include "ui/base/text/text_elider.h" | 45 #include "ui/base/text/text_elider.h" |
| 46 #include "ui/base/x/active_window_watcher_x.h" |
46 #include "ui/base/x/x11_util.h" | 47 #include "ui/base/x/x11_util.h" |
47 #include "ui/gfx/gtk_native_view_id_manager.h" | 48 #include "ui/gfx/gtk_native_view_id_manager.h" |
48 #include "ui/gfx/gtk_preserve_window.h" | 49 #include "ui/gfx/gtk_preserve_window.h" |
49 #include "webkit/glue/webcursor_gtk_data.h" | 50 #include "webkit/glue/webcursor_gtk_data.h" |
50 #include "webkit/plugins/npapi/webplugin.h" | 51 #include "webkit/plugins/npapi/webplugin.h" |
51 | 52 |
52 namespace { | 53 namespace { |
53 | 54 |
54 // Paint rects on Linux are bounded by the maximum size of a shared memory | 55 // Paint rects on Linux are bounded by the maximum size of a shared memory |
55 // region. By default that's 32MB, but many distros increase it significantly | 56 // region. By default that's 32MB, but many distros increase it significantly |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 content::RenderWidgetHost* widget_host) | 568 content::RenderWidgetHost* widget_host) |
568 : host_(RenderWidgetHostImpl::From(widget_host)), | 569 : host_(RenderWidgetHostImpl::From(widget_host)), |
569 about_to_validate_and_paint_(false), | 570 about_to_validate_and_paint_(false), |
570 is_hidden_(false), | 571 is_hidden_(false), |
571 is_loading_(false), | 572 is_loading_(false), |
572 parent_(NULL), | 573 parent_(NULL), |
573 is_popup_first_mouse_release_(true), | 574 is_popup_first_mouse_release_(true), |
574 was_imcontext_focused_before_grab_(false), | 575 was_imcontext_focused_before_grab_(false), |
575 do_x_grab_(false), | 576 do_x_grab_(false), |
576 is_fullscreen_(false), | 577 is_fullscreen_(false), |
| 578 made_active_(false), |
577 destroy_handler_id_(0), | 579 destroy_handler_id_(0), |
578 dragged_at_horizontal_edge_(0), | 580 dragged_at_horizontal_edge_(0), |
579 dragged_at_vertical_edge_(0), | 581 dragged_at_vertical_edge_(0), |
580 compositing_surface_(gfx::kNullPluginWindow), | 582 compositing_surface_(gfx::kNullPluginWindow), |
581 last_mouse_down_(NULL) { | 583 last_mouse_down_(NULL) { |
582 host_->SetView(this); | 584 host_->SetView(this); |
583 } | 585 } |
584 | 586 |
585 RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() { | 587 RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() { |
586 UnlockMouse(); | 588 UnlockMouse(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 } | 654 } |
653 | 655 |
654 void RenderWidgetHostViewGtk::InitAsFullscreen( | 656 void RenderWidgetHostViewGtk::InitAsFullscreen( |
655 RenderWidgetHostView* /*reference_host_view*/) { | 657 RenderWidgetHostView* /*reference_host_view*/) { |
656 DoSharedInit(); | 658 DoSharedInit(); |
657 | 659 |
658 is_fullscreen_ = true; | 660 is_fullscreen_ = true; |
659 GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); | 661 GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); |
660 gtk_window_set_decorated(window, FALSE); | 662 gtk_window_set_decorated(window, FALSE); |
661 gtk_window_fullscreen(window); | 663 gtk_window_fullscreen(window); |
662 g_signal_connect(GTK_WIDGET(window), | |
663 "window-state-event", | |
664 G_CALLBACK(&OnWindowStateEventThunk), | |
665 this); | |
666 destroy_handler_id_ = g_signal_connect(GTK_WIDGET(window), | 664 destroy_handler_id_ = g_signal_connect(GTK_WIDGET(window), |
667 "destroy", | 665 "destroy", |
668 G_CALLBACK(OnDestroyThunk), | 666 G_CALLBACK(OnDestroyThunk), |
669 this); | 667 this); |
670 gtk_container_add(GTK_CONTAINER(window), view_.get()); | 668 gtk_container_add(GTK_CONTAINER(window), view_.get()); |
671 | 669 |
672 // Try to move and resize the window to cover the screen in case the window | 670 // Try to move and resize the window to cover the screen in case the window |
673 // manager doesn't support _NET_WM_STATE_FULLSCREEN. | 671 // manager doesn't support _NET_WM_STATE_FULLSCREEN. |
674 GdkScreen* screen = gtk_window_get_screen(window); | 672 GdkScreen* screen = gtk_window_get_screen(window); |
675 gfx::Rect bounds( | 673 gfx::Rect bounds( |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 void RenderWidgetHostViewGtk::Blur() { | 757 void RenderWidgetHostViewGtk::Blur() { |
760 // TODO(estade): We should be clearing native focus as well, but I know of no | 758 // TODO(estade): We should be clearing native focus as well, but I know of no |
761 // way to do that without focusing another widget. | 759 // way to do that without focusing another widget. |
762 host_->Blur(); | 760 host_->Blur(); |
763 } | 761 } |
764 | 762 |
765 bool RenderWidgetHostViewGtk::HasFocus() const { | 763 bool RenderWidgetHostViewGtk::HasFocus() const { |
766 return gtk_widget_is_focus(view_.get()); | 764 return gtk_widget_is_focus(view_.get()); |
767 } | 765 } |
768 | 766 |
| 767 void RenderWidgetHostViewGtk::ActiveWindowChanged(GdkWindow *window) { |
| 768 GdkWindow* our_window = gtk_widget_get_parent_window(view_.get()); |
| 769 |
| 770 if (our_window == window) |
| 771 made_active_ = true; |
| 772 |
| 773 // If the window was previously active, but isn't active anymore, shut it |
| 774 // down. |
| 775 if (is_fullscreen_ && our_window != window && made_active_) |
| 776 host_->Shutdown(); |
| 777 } |
| 778 |
769 bool RenderWidgetHostViewGtk::IsSurfaceAvailableForCopy() const { | 779 bool RenderWidgetHostViewGtk::IsSurfaceAvailableForCopy() const { |
770 return !!host_->GetBackingStore(false); | 780 return !!host_->GetBackingStore(false); |
771 } | 781 } |
772 | 782 |
773 void RenderWidgetHostViewGtk::Show() { | 783 void RenderWidgetHostViewGtk::Show() { |
774 gtk_widget_show(view_.get()); | 784 gtk_widget_show(view_.get()); |
775 } | 785 } |
776 | 786 |
777 void RenderWidgetHostViewGtk::Hide() { | 787 void RenderWidgetHostViewGtk::Hide() { |
778 gtk_widget_hide(view_.get()); | 788 gtk_widget_hide(view_.get()); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 GdkDisplay* display = gtk_widget_get_display(parent_); | 879 GdkDisplay* display = gtk_widget_get_display(parent_); |
870 gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME); | 880 gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME); |
871 gdk_display_keyboard_ungrab(display, GDK_CURRENT_TIME); | 881 gdk_display_keyboard_ungrab(display, GDK_CURRENT_TIME); |
872 } | 882 } |
873 | 883 |
874 // If this is a popup or fullscreen widget, then we need to destroy the window | 884 // If this is a popup or fullscreen widget, then we need to destroy the window |
875 // that we created to hold it. | 885 // that we created to hold it. |
876 if (IsPopup() || is_fullscreen_) { | 886 if (IsPopup() || is_fullscreen_) { |
877 GtkWidget* window = gtk_widget_get_parent(view_.get()); | 887 GtkWidget* window = gtk_widget_get_parent(view_.get()); |
878 | 888 |
| 889 ui::ActiveWindowWatcherX::RemoveObserver(this); |
| 890 |
879 // Disconnect the destroy handler so that we don't try to shutdown twice. | 891 // Disconnect the destroy handler so that we don't try to shutdown twice. |
880 if (is_fullscreen_) | 892 if (is_fullscreen_) |
881 g_signal_handler_disconnect(window, destroy_handler_id_); | 893 g_signal_handler_disconnect(window, destroy_handler_id_); |
882 | 894 |
883 gtk_widget_destroy(window); | 895 gtk_widget_destroy(window); |
884 } | 896 } |
885 | 897 |
886 // Remove |view_| from all containers now, so nothing else can hold a | 898 // Remove |view_| from all containers now, so nothing else can hold a |
887 // reference to |view_|'s widget except possibly a gtk signal handler if | 899 // reference to |view_|'s widget except possibly a gtk signal handler if |
888 // this code is currently executing within the context of a gtk signal | 900 // this code is currently executing within the context of a gtk signal |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 } | 956 } |
945 | 957 |
946 GdkEventButton* RenderWidgetHostViewGtk::GetLastMouseDown() { | 958 GdkEventButton* RenderWidgetHostViewGtk::GetLastMouseDown() { |
947 return last_mouse_down_; | 959 return last_mouse_down_; |
948 } | 960 } |
949 | 961 |
950 gfx::NativeView RenderWidgetHostViewGtk::BuildInputMethodsGtkMenu() { | 962 gfx::NativeView RenderWidgetHostViewGtk::BuildInputMethodsGtkMenu() { |
951 return im_context_->BuildInputMethodsGtkMenu(); | 963 return im_context_->BuildInputMethodsGtkMenu(); |
952 } | 964 } |
953 | 965 |
954 gboolean RenderWidgetHostViewGtk::OnWindowStateEvent( | |
955 GtkWidget* widget, | |
956 GdkEventWindowState* event) { | |
957 if (is_fullscreen_) { | |
958 // If a fullscreen widget got unfullscreened (e.g. by the window manager), | |
959 // close it. | |
960 bool unfullscreened = | |
961 (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) && | |
962 !(event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN); | |
963 if (unfullscreened) { | |
964 host_->Shutdown(); | |
965 return TRUE; | |
966 } | |
967 } | |
968 | |
969 return FALSE; | |
970 } | |
971 | |
972 void RenderWidgetHostViewGtk::OnDestroy(GtkWidget* widget) { | 966 void RenderWidgetHostViewGtk::OnDestroy(GtkWidget* widget) { |
973 DCHECK(is_fullscreen_); | 967 DCHECK(is_fullscreen_); |
974 host_->Shutdown(); | 968 host_->Shutdown(); |
975 } | 969 } |
976 | 970 |
977 bool RenderWidgetHostViewGtk::NeedsInputGrab() { | 971 bool RenderWidgetHostViewGtk::NeedsInputGrab() { |
978 return popup_type_ == WebKit::WebPopupTypeSelect; | 972 return popup_type_ == WebKit::WebPopupTypeSelect; |
979 } | 973 } |
980 | 974 |
981 bool RenderWidgetHostViewGtk::IsPopup() const { | 975 bool RenderWidgetHostViewGtk::IsPopup() const { |
982 return popup_type_ != WebKit::WebPopupTypeNone; | 976 return popup_type_ != WebKit::WebPopupTypeNone; |
983 } | 977 } |
984 | 978 |
985 void RenderWidgetHostViewGtk::DoSharedInit() { | 979 void RenderWidgetHostViewGtk::DoSharedInit() { |
986 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); | 980 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); |
987 im_context_.reset(new GtkIMContextWrapper(this)); | 981 im_context_.reset(new GtkIMContextWrapper(this)); |
988 plugin_container_manager_.set_host_widget(view_.get()); | 982 plugin_container_manager_.set_host_widget(view_.get()); |
989 key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get())); | 983 key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get())); |
990 } | 984 } |
991 | 985 |
992 void RenderWidgetHostViewGtk::DoPopupOrFullscreenInit(GtkWindow* window, | 986 void RenderWidgetHostViewGtk::DoPopupOrFullscreenInit(GtkWindow* window, |
993 const gfx::Rect& bounds) { | 987 const gfx::Rect& bounds) { |
994 requested_size_.SetSize(std::min(bounds.width(), kMaxWindowWidth), | 988 requested_size_.SetSize(std::min(bounds.width(), kMaxWindowWidth), |
995 std::min(bounds.height(), kMaxWindowHeight)); | 989 std::min(bounds.height(), kMaxWindowHeight)); |
996 host_->WasResized(); | 990 host_->WasResized(); |
997 | 991 |
| 992 ui::ActiveWindowWatcherX::AddObserver(this); |
| 993 |
998 // Don't set the size when we're going fullscreen. This can confuse the | 994 // Don't set the size when we're going fullscreen. This can confuse the |
999 // window manager into thinking we're resizing a fullscreen window and | 995 // window manager into thinking we're resizing a fullscreen window and |
1000 // therefore not fullscreen anymore. | 996 // therefore not fullscreen anymore. |
1001 if (!is_fullscreen_) { | 997 if (!is_fullscreen_) { |
1002 gtk_widget_set_size_request( | 998 gtk_widget_set_size_request( |
1003 view_.get(), requested_size_.width(), requested_size_.height()); | 999 view_.get(), requested_size_.width(), requested_size_.height()); |
1004 | 1000 |
1005 // Don't allow the window to be resized. This also forces the window to | 1001 // Don't allow the window to be resized. This also forces the window to |
1006 // shrink down to the size of its child contents. | 1002 // shrink down to the size of its child contents. |
1007 gtk_window_set_resizable(window, FALSE); | 1003 gtk_window_set_resizable(window, FALSE); |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1510 parent, | 1506 parent, |
1511 static_cast<content::AccessibilityNodeData::State>(0), | 1507 static_cast<content::AccessibilityNodeData::State>(0), |
1512 this)); | 1508 this)); |
1513 } | 1509 } |
1514 BrowserAccessibilityGtk* root = | 1510 BrowserAccessibilityGtk* root = |
1515 browser_accessibility_manager_->GetRoot()->ToBrowserAccessibilityGtk(); | 1511 browser_accessibility_manager_->GetRoot()->ToBrowserAccessibilityGtk(); |
1516 | 1512 |
1517 atk_object_set_role(root->GetAtkObject(), ATK_ROLE_HTML_CONTAINER); | 1513 atk_object_set_role(root->GetAtkObject(), ATK_ROLE_HTML_CONTAINER); |
1518 return root->GetAtkObject(); | 1514 return root->GetAtkObject(); |
1519 } | 1515 } |
OLD | NEW |