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