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 "chrome/browser/renderer_host/render_widget_host_view_gtk.h" | 5 #include "chrome/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 URLRequestStatus::Status. | 9 // badly with URLRequestStatus::Status. |
10 #include "chrome/common/render_messages.h" | 10 #include "chrome/common/render_messages.h" |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 | 504 |
505 #if defined(OS_CHROMEOS) | 505 #if defined(OS_CHROMEOS) |
506 tooltip_window_.reset(new views::TooltipWindowGtk(view_.get())); | 506 tooltip_window_.reset(new views::TooltipWindowGtk(view_.get())); |
507 #endif // defined(OS_CHROMEOS) | 507 #endif // defined(OS_CHROMEOS) |
508 | 508 |
509 gtk_widget_show(view_.get()); | 509 gtk_widget_show(view_.get()); |
510 } | 510 } |
511 | 511 |
512 void RenderWidgetHostViewGtk::InitAsPopup( | 512 void RenderWidgetHostViewGtk::InitAsPopup( |
513 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { | 513 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { |
514 parent_host_view_ = parent_host_view; | 514 DoInitAsPopup(parent_host_view, GTK_WINDOW_POPUP, pos, false); |
515 parent_ = parent_host_view->GetNativeView(); | 515 } |
516 GtkWidget* popup = gtk_window_new(GTK_WINDOW_POPUP); | |
517 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); | |
518 // |im_context_| must be created after creating |view_| widget. | |
519 im_context_.reset(new GtkIMContextWrapper(this)); | |
520 // |key_bindings_handler_| must be created after creating |view_| widget. | |
521 key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get())); | |
522 plugin_container_manager_.set_host_widget(view_.get()); | |
523 | 516 |
524 #if defined(OS_CHROMEOS) | 517 void RenderWidgetHostViewGtk::InitAsFullscreen( |
525 tooltip_window_.reset(new views::TooltipWindowGtk(view_.get())); | 518 RenderWidgetHostView* parent_host_view) { |
526 #endif // defined(OS_CHROMEOS) | 519 DoInitAsPopup(parent_host_view, GTK_WINDOW_TOPLEVEL, gfx::Rect(), true); |
527 | |
528 gtk_container_add(GTK_CONTAINER(popup), view_.get()); | |
529 | |
530 requested_size_ = gfx::Size(std::min(pos.width(), kMaxWindowWidth), | |
531 std::min(pos.height(), kMaxWindowHeight)); | |
532 host_->WasResized(); | |
533 gtk_widget_set_size_request(view_.get(), requested_size_.width(), | |
534 requested_size_.height()); | |
535 | |
536 gtk_window_set_default_size(GTK_WINDOW(popup), -1, -1); | |
537 // Don't allow the window to be resized. This also forces the window to | |
538 // shrink down to the size of its child contents. | |
539 gtk_window_set_resizable(GTK_WINDOW(popup), FALSE); | |
540 gtk_window_move(GTK_WINDOW(popup), pos.x(), pos.y()); | |
541 gtk_widget_show_all(popup); | |
542 | |
543 // If we are not activatable, we don't want to grab keyboard input, | |
544 // and webkit will manage our destruction. | |
545 // For unknown reason, calling gtk_grab_add() before realizing the widget may | |
546 // cause an assertion failure. See http://crbug.com/51834. So we do it after | |
547 // showing the popup. | |
548 if (NeedsInputGrab()) { | |
549 // Grab all input for the app. If a click lands outside the bounds of the | |
550 // popup, WebKit will notice and destroy us. Before doing this we need | |
551 // to ensure that the the popup is added to the browser's window group, | |
552 // to allow for the grabs to work correctly. | |
553 gtk_window_group_add_window(gtk_window_get_group( | |
554 GTK_WINDOW(gtk_widget_get_toplevel(parent_))), GTK_WINDOW(popup)); | |
555 gtk_grab_add(view_.get()); | |
556 | |
557 // We need for the application to do an X grab as well. However if the app | |
558 // already has an X grab (as in the case of extension popup), an app grab | |
559 // will suffice. | |
560 do_x_grab_ = !gdk_pointer_is_grabbed(); | |
561 | |
562 // Now grab all of X's input. | |
563 if (do_x_grab_) { | |
564 gdk_pointer_grab( | |
565 parent_->window, | |
566 TRUE, // Only events outside of the window are reported with respect | |
567 // to |parent_->window|. | |
568 static_cast<GdkEventMask>(GDK_BUTTON_PRESS_MASK | | |
569 GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK), | |
570 NULL, | |
571 NULL, | |
572 GDK_CURRENT_TIME); | |
573 // We grab keyboard events too so things like alt+tab are eaten. | |
574 gdk_keyboard_grab(parent_->window, TRUE, GDK_CURRENT_TIME); | |
575 } | |
576 } | |
577 | |
578 // TODO(brettw) possibly enable out-of-process painting here as well | |
579 // (see InitAsChild). | |
580 } | 520 } |
581 | 521 |
582 void RenderWidgetHostViewGtk::DidBecomeSelected() { | 522 void RenderWidgetHostViewGtk::DidBecomeSelected() { |
583 if (!is_hidden_) | 523 if (!is_hidden_) |
584 return; | 524 return; |
585 | 525 |
586 if (tab_switch_paint_time_.is_null()) | 526 if (tab_switch_paint_time_.is_null()) |
587 tab_switch_paint_time_ = base::TimeTicks::Now(); | 527 tab_switch_paint_time_ = base::TimeTicks::Now(); |
588 is_hidden_ = false; | 528 is_hidden_ = false; |
589 host_->WasRestored(); | 529 host_->WasRestored(); |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 default: | 967 default: |
1028 gdk_cursor = gtk_util::GetCursor( | 968 gdk_cursor = gtk_util::GetCursor( |
1029 static_cast<GdkCursorType>(current_cursor_.GetCursorType())); | 969 static_cast<GdkCursorType>(current_cursor_.GetCursorType())); |
1030 } | 970 } |
1031 gdk_window_set_cursor(view_.get()->window, gdk_cursor); | 971 gdk_window_set_cursor(view_.get()->window, gdk_cursor); |
1032 // The window now owns the cursor. | 972 // The window now owns the cursor. |
1033 if (gdk_cursor) | 973 if (gdk_cursor) |
1034 gdk_cursor_unref(gdk_cursor); | 974 gdk_cursor_unref(gdk_cursor); |
1035 } | 975 } |
1036 | 976 |
| 977 void RenderWidgetHostViewGtk::DoInitAsPopup( |
| 978 RenderWidgetHostView* parent_host_view, |
| 979 GtkWindowType window_type, |
| 980 const gfx::Rect& pos, |
| 981 bool is_fullscreen) { |
| 982 // If we are not a popup, then popup will be leaked. |
| 983 DCHECK(IsPopup()); |
| 984 |
| 985 parent_host_view_ = parent_host_view; |
| 986 parent_ = parent_host_view->GetNativeView(); |
| 987 GtkWidget* popup = gtk_window_new(window_type); |
| 988 gtk_window_set_decorated(GTK_WINDOW(popup), FALSE); |
| 989 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); |
| 990 // |im_context_| must be created after creating |view_| widget. |
| 991 im_context_.reset(new GtkIMContextWrapper(this)); |
| 992 // |key_bindings_handler_| must be created after creating |view_| widget. |
| 993 key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get())); |
| 994 plugin_container_manager_.set_host_widget(view_.get()); |
| 995 |
| 996 #if defined(OS_CHROMEOS) |
| 997 tooltip_window_.reset(new views::TooltipWindowGtk(view_.get())); |
| 998 #endif // defined(OS_CHROMEOS) |
| 999 |
| 1000 gtk_container_add(GTK_CONTAINER(popup), view_.get()); |
| 1001 |
| 1002 if (is_fullscreen) { |
| 1003 // Set the request size to the size of the screen. |
| 1004 // TODO(boliu): Make sure this works for multi-monitor set ups and move this |
| 1005 // to some utility function. |
| 1006 GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(popup)); |
| 1007 requested_size_ = gfx::Size( |
| 1008 std::min(gdk_screen_get_width(screen), kMaxWindowWidth), |
| 1009 std::min(gdk_screen_get_height(screen), kMaxWindowHeight)); |
| 1010 } else { |
| 1011 requested_size_ = gfx::Size(std::min(pos.width(), kMaxWindowWidth), |
| 1012 std::min(pos.height(), kMaxWindowHeight)); |
| 1013 } |
| 1014 host_->WasResized(); |
| 1015 |
| 1016 gtk_widget_set_size_request(view_.get(), requested_size_.width(), |
| 1017 requested_size_.height()); |
| 1018 // Don't allow the window to be resized. This also forces the window to |
| 1019 // shrink down to the size of its child contents. |
| 1020 gtk_window_set_resizable(GTK_WINDOW(popup), FALSE); |
| 1021 gtk_window_set_default_size(GTK_WINDOW(popup), -1, -1); |
| 1022 gtk_window_move(GTK_WINDOW(popup), pos.x(), pos.y()); |
| 1023 if (is_fullscreen) { |
| 1024 gtk_window_fullscreen(GTK_WINDOW(popup)); |
| 1025 } |
| 1026 |
| 1027 gtk_widget_show_all(popup); |
| 1028 |
| 1029 // If we are not activatable, we don't want to grab keyboard input, |
| 1030 // and webkit will manage our destruction. |
| 1031 // For unknown reason, calling gtk_grab_add() before realizing the widget may |
| 1032 // cause an assertion failure. See http://crbug.com/51834. So we do it after |
| 1033 // showing the popup. |
| 1034 if (NeedsInputGrab()) { |
| 1035 // Grab all input for the app. If a click lands outside the bounds of the |
| 1036 // popup, WebKit will notice and destroy us. Before doing this we need |
| 1037 // to ensure that the the popup is added to the browser's window group, |
| 1038 // to allow for the grabs to work correctly. |
| 1039 gtk_window_group_add_window(gtk_window_get_group( |
| 1040 GTK_WINDOW(gtk_widget_get_toplevel(parent_))), GTK_WINDOW(popup)); |
| 1041 gtk_grab_add(view_.get()); |
| 1042 |
| 1043 // We need for the application to do an X grab as well. However if the app |
| 1044 // already has an X grab (as in the case of extension popup), an app grab |
| 1045 // will suffice. |
| 1046 do_x_grab_ = !gdk_pointer_is_grabbed(); |
| 1047 |
| 1048 // Now grab all of X's input. |
| 1049 if (do_x_grab_) { |
| 1050 gdk_pointer_grab( |
| 1051 parent_->window, |
| 1052 TRUE, // Only events outside of the window are reported with respect |
| 1053 // to |parent_->window|. |
| 1054 static_cast<GdkEventMask>(GDK_BUTTON_PRESS_MASK | |
| 1055 GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK), |
| 1056 NULL, |
| 1057 NULL, |
| 1058 GDK_CURRENT_TIME); |
| 1059 // We grab keyboard events too so things like alt+tab are eaten. |
| 1060 gdk_keyboard_grab(parent_->window, TRUE, GDK_CURRENT_TIME); |
| 1061 } |
| 1062 } |
| 1063 } |
| 1064 |
1037 void RenderWidgetHostViewGtk::CreatePluginContainer( | 1065 void RenderWidgetHostViewGtk::CreatePluginContainer( |
1038 gfx::PluginWindowHandle id) { | 1066 gfx::PluginWindowHandle id) { |
1039 plugin_container_manager_.CreatePluginContainer(id); | 1067 plugin_container_manager_.CreatePluginContainer(id); |
1040 } | 1068 } |
1041 | 1069 |
1042 void RenderWidgetHostViewGtk::DestroyPluginContainer( | 1070 void RenderWidgetHostViewGtk::DestroyPluginContainer( |
1043 gfx::PluginWindowHandle id) { | 1071 gfx::PluginWindowHandle id) { |
1044 plugin_container_manager_.DestroyPluginContainer(id); | 1072 plugin_container_manager_.DestroyPluginContainer(id); |
1045 } | 1073 } |
1046 | 1074 |
(...skipping 27 matching lines...) Expand all Loading... |
1074 } | 1102 } |
1075 | 1103 |
1076 // static | 1104 // static |
1077 RenderWidgetHostView* | 1105 RenderWidgetHostView* |
1078 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( | 1106 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( |
1079 gfx::NativeView widget) { | 1107 gfx::NativeView widget) { |
1080 gpointer user_data = g_object_get_data(G_OBJECT(widget), | 1108 gpointer user_data = g_object_get_data(G_OBJECT(widget), |
1081 kRenderWidgetHostViewKey); | 1109 kRenderWidgetHostViewKey); |
1082 return reinterpret_cast<RenderWidgetHostView*>(user_data); | 1110 return reinterpret_cast<RenderWidgetHostView*>(user_data); |
1083 } | 1111 } |
OLD | NEW |