| Index: chrome/browser/renderer_host/render_widget_host_view_gtk.cc
|
| diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
|
| index 2526816da26ed403a6d282186dc29ba6bb793dec..7fce046571bbb7f4eff565fb57ce9cd425c68144 100644
|
| --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
|
| +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
|
| @@ -489,11 +489,11 @@ RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost* widget_host)
|
| is_showing_context_menu_(false),
|
| overlay_color_(0),
|
| overlay_animation_(this),
|
| - parent_host_view_(NULL),
|
| parent_(NULL),
|
| is_popup_first_mouse_release_(true),
|
| was_focused_before_grab_(false),
|
| do_x_grab_(false),
|
| + is_fullscreen_(false),
|
| dragged_at_horizontal_edge_(0),
|
| dragged_at_vertical_edge_(0) {
|
| host_->set_view(this);
|
| @@ -504,31 +504,71 @@ RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() {
|
| }
|
|
|
| void RenderWidgetHostViewGtk::InitAsChild() {
|
| - view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this));
|
| - // |im_context_| must be created after creating |view_| widget.
|
| - im_context_.reset(new GtkIMContextWrapper(this));
|
| - // |key_bindings_handler_| must be created after creating |view_| widget.
|
| - key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get()));
|
| - plugin_container_manager_.set_host_widget(view_.get());
|
| -
|
| -#if defined(OS_CHROMEOS)
|
| - tooltip_window_.reset(new views::TooltipWindowGtk(view_.get()));
|
| -#endif // defined(OS_CHROMEOS)
|
| -
|
| + DoSharedInit();
|
| overlay_animation_.SetDuration(kFadeEffectDuration);
|
| overlay_animation_.SetSlideDuration(kFadeEffectDuration);
|
| -
|
| gtk_widget_show(view_.get());
|
| }
|
|
|
| void RenderWidgetHostViewGtk::InitAsPopup(
|
| RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
|
| - DoInitAsPopup(parent_host_view, GTK_WINDOW_POPUP, pos, false);
|
| + // If we aren't a popup, then |window| will be leaked.
|
| + DCHECK(IsPopup());
|
| +
|
| + DoSharedInit();
|
| + parent_ = parent_host_view->GetNativeView();
|
| + GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_POPUP));
|
| + gtk_container_add(GTK_CONTAINER(window), view_.get());
|
| + DoPopupOrFullscreenInit(window, pos);
|
| +
|
| + // The underlying X window needs to be created and mapped by the above code
|
| + // before we can grab the input devices.
|
| + if (NeedsInputGrab()) {
|
| + // Grab all input for the app. If a click lands outside the bounds of the
|
| + // popup, WebKit will notice and destroy us. Before doing this we need
|
| + // to ensure that the the popup is added to the browser's window group,
|
| + // to allow for the grabs to work correctly.
|
| + gtk_window_group_add_window(gtk_window_get_group(
|
| + GTK_WINDOW(gtk_widget_get_toplevel(parent_))), window);
|
| + gtk_grab_add(view_.get());
|
| +
|
| + // We need for the application to do an X grab as well. However if the app
|
| + // already has an X grab (as in the case of extension popup), an app grab
|
| + // will suffice.
|
| + do_x_grab_ = !gdk_pointer_is_grabbed();
|
| +
|
| + // Now grab all of X's input.
|
| + if (do_x_grab_) {
|
| + gdk_pointer_grab(
|
| + parent_->window,
|
| + TRUE, // Only events outside of the window are reported with respect
|
| + // to |parent_->window|.
|
| + static_cast<GdkEventMask>(GDK_BUTTON_PRESS_MASK |
|
| + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK),
|
| + NULL,
|
| + NULL,
|
| + GDK_CURRENT_TIME);
|
| + // We grab keyboard events too so things like alt+tab are eaten.
|
| + gdk_keyboard_grab(parent_->window, TRUE, GDK_CURRENT_TIME);
|
| + }
|
| + }
|
| }
|
|
|
| -void RenderWidgetHostViewGtk::InitAsFullscreen(
|
| - RenderWidgetHostView* parent_host_view) {
|
| - DoInitAsPopup(parent_host_view, GTK_WINDOW_TOPLEVEL, gfx::Rect(), true);
|
| +void RenderWidgetHostViewGtk::InitAsFullscreen() {
|
| + DoSharedInit();
|
| +
|
| + is_fullscreen_ = true;
|
| + GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
| + gtk_window_set_decorated(window, FALSE);
|
| + gtk_window_fullscreen(window);
|
| + gtk_container_add(GTK_CONTAINER(window), view_.get());
|
| +
|
| + // Try to move and resize the window to cover the screen in case the window
|
| + // manager doesn't support _NET_WM_STATE_FULLSCREEN.
|
| + GdkScreen* screen = gtk_window_get_screen(window);
|
| + gfx::Rect bounds(
|
| + 0, 0, gdk_screen_get_width(screen), gdk_screen_get_height(screen));
|
| + DoPopupOrFullscreenInit(window, bounds);
|
| }
|
|
|
| RenderWidgetHost* RenderWidgetHostViewGtk::GetRenderWidgetHost() const {
|
| @@ -692,16 +732,18 @@ void RenderWidgetHostViewGtk::RenderViewGone(base::TerminationStatus status,
|
| }
|
|
|
| void RenderWidgetHostViewGtk::Destroy() {
|
| - if (IsPopup()) {
|
| - if (do_x_grab_) {
|
| - // Undo the X grab.
|
| - GdkDisplay* display = gtk_widget_get_display(parent_);
|
| - gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME);
|
| - gdk_display_keyboard_ungrab(display, GDK_CURRENT_TIME);
|
| - }
|
| - gtk_widget_destroy(gtk_widget_get_parent(view_.get()));
|
| + if (do_x_grab_) {
|
| + // Undo the X grab.
|
| + GdkDisplay* display = gtk_widget_get_display(parent_);
|
| + gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME);
|
| + gdk_display_keyboard_ungrab(display, GDK_CURRENT_TIME);
|
| }
|
|
|
| + // If this is a popup or fullscreen widget, then we need to destroy the window
|
| + // that we created to hold it.
|
| + if (IsPopup() || is_fullscreen_)
|
| + gtk_widget_destroy(gtk_widget_get_parent(view_.get()));
|
| +
|
| // Remove |view_| from all containers now, so nothing else can hold a
|
| // reference to |view_|'s widget except possibly a gtk signal handler if
|
| // this code is currently executing within the context of a gtk signal
|
| @@ -759,10 +801,39 @@ bool RenderWidgetHostViewGtk::NeedsInputGrab() {
|
| return popup_type_ == WebKit::WebPopupTypeSelect;
|
| }
|
|
|
| -bool RenderWidgetHostViewGtk::IsPopup() {
|
| +bool RenderWidgetHostViewGtk::IsPopup() const {
|
| return popup_type_ != WebKit::WebPopupTypeNone;
|
| }
|
|
|
| +void RenderWidgetHostViewGtk::DoSharedInit() {
|
| + view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this));
|
| + im_context_.reset(new GtkIMContextWrapper(this));
|
| + key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get()));
|
| + plugin_container_manager_.set_host_widget(view_.get());
|
| +#if defined(OS_CHROMEOS)
|
| + tooltip_window_.reset(new views::TooltipWindowGtk(view_.get()));
|
| +#endif
|
| +}
|
| +
|
| +void RenderWidgetHostViewGtk::DoPopupOrFullscreenInit(GtkWindow* window,
|
| + const gfx::Rect& bounds) {
|
| + requested_size_ = bounds.size();
|
| + host_->WasResized();
|
| +
|
| + gtk_widget_set_size_request(
|
| + view_.get(),
|
| + std::min(requested_size_.width(), kMaxWindowWidth),
|
| + std::min(requested_size_.height(), kMaxWindowHeight));
|
| +
|
| + // Don't allow the window to be resized. This also forces the window to
|
| + // shrink down to the size of its child contents.
|
| + gtk_window_set_resizable(window, FALSE);
|
| + gtk_window_set_default_size(window, -1, -1);
|
| + gtk_window_move(window, bounds.x(), bounds.y());
|
| +
|
| + gtk_widget_show_all(GTK_WIDGET(window));
|
| +}
|
| +
|
| BackingStore* RenderWidgetHostViewGtk::AllocBackingStore(
|
| const gfx::Size& size) {
|
| return new BackingStoreX(host_, size,
|
| @@ -957,94 +1028,6 @@ void RenderWidgetHostViewGtk::ShowCurrentCursor() {
|
| gdk_cursor_unref(gdk_cursor);
|
| }
|
|
|
| -void RenderWidgetHostViewGtk::DoInitAsPopup(
|
| - RenderWidgetHostView* parent_host_view,
|
| - GtkWindowType window_type,
|
| - const gfx::Rect& pos,
|
| - bool is_fullscreen) {
|
| - // If we are not a popup, then popup will be leaked.
|
| - DCHECK(IsPopup());
|
| -
|
| - parent_host_view_ = parent_host_view;
|
| - parent_ = parent_host_view->GetNativeView();
|
| - GtkWidget* popup = gtk_window_new(window_type);
|
| - gtk_window_set_decorated(GTK_WINDOW(popup), FALSE);
|
| - view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this));
|
| - // |im_context_| must be created after creating |view_| widget.
|
| - im_context_.reset(new GtkIMContextWrapper(this));
|
| - // |key_bindings_handler_| must be created after creating |view_| widget.
|
| - key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get()));
|
| - plugin_container_manager_.set_host_widget(view_.get());
|
| -
|
| -#if defined(OS_CHROMEOS)
|
| - tooltip_window_.reset(new views::TooltipWindowGtk(view_.get()));
|
| -#endif // defined(OS_CHROMEOS)
|
| -
|
| - gtk_container_add(GTK_CONTAINER(popup), view_.get());
|
| -
|
| - if (is_fullscreen) {
|
| - // Set the request size to the size of the screen.
|
| - // TODO(boliu): Make sure this works for multi-monitor set ups and move this
|
| - // to some utility function.
|
| - GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(popup));
|
| - requested_size_ = gfx::Size(
|
| - std::min(gdk_screen_get_width(screen), kMaxWindowWidth),
|
| - std::min(gdk_screen_get_height(screen), kMaxWindowHeight));
|
| - } else {
|
| - requested_size_ = gfx::Size(std::min(pos.width(), kMaxWindowWidth),
|
| - std::min(pos.height(), kMaxWindowHeight));
|
| - }
|
| - host_->WasResized();
|
| -
|
| - gtk_widget_set_size_request(view_.get(), requested_size_.width(),
|
| - requested_size_.height());
|
| - // Don't allow the window to be resized. This also forces the window to
|
| - // shrink down to the size of its child contents.
|
| - gtk_window_set_resizable(GTK_WINDOW(popup), FALSE);
|
| - gtk_window_set_default_size(GTK_WINDOW(popup), -1, -1);
|
| - gtk_window_move(GTK_WINDOW(popup), pos.x(), pos.y());
|
| - if (is_fullscreen) {
|
| - gtk_window_fullscreen(GTK_WINDOW(popup));
|
| - }
|
| -
|
| - gtk_widget_show_all(popup);
|
| -
|
| - // If we are not activatable, we don't want to grab keyboard input,
|
| - // and webkit will manage our destruction.
|
| - // For unknown reason, calling gtk_grab_add() before realizing the widget may
|
| - // cause an assertion failure. See http://crbug.com/51834. So we do it after
|
| - // showing the popup.
|
| - if (NeedsInputGrab()) {
|
| - // Grab all input for the app. If a click lands outside the bounds of the
|
| - // popup, WebKit will notice and destroy us. Before doing this we need
|
| - // to ensure that the the popup is added to the browser's window group,
|
| - // to allow for the grabs to work correctly.
|
| - gtk_window_group_add_window(gtk_window_get_group(
|
| - GTK_WINDOW(gtk_widget_get_toplevel(parent_))), GTK_WINDOW(popup));
|
| - gtk_grab_add(view_.get());
|
| -
|
| - // We need for the application to do an X grab as well. However if the app
|
| - // already has an X grab (as in the case of extension popup), an app grab
|
| - // will suffice.
|
| - do_x_grab_ = !gdk_pointer_is_grabbed();
|
| -
|
| - // Now grab all of X's input.
|
| - if (do_x_grab_) {
|
| - gdk_pointer_grab(
|
| - parent_->window,
|
| - TRUE, // Only events outside of the window are reported with respect
|
| - // to |parent_->window|.
|
| - static_cast<GdkEventMask>(GDK_BUTTON_PRESS_MASK |
|
| - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK),
|
| - NULL,
|
| - NULL,
|
| - GDK_CURRENT_TIME);
|
| - // We grab keyboard events too so things like alt+tab are eaten.
|
| - gdk_keyboard_grab(parent_->window, TRUE, GDK_CURRENT_TIME);
|
| - }
|
| - }
|
| -}
|
| -
|
| void RenderWidgetHostViewGtk::CreatePluginContainer(
|
| gfx::PluginWindowHandle id) {
|
| plugin_container_manager_.CreatePluginContainer(id);
|
|
|