| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 #include <gdk/gdk.h> | 8 #include <gdk/gdk.h> |
| 9 #include <gdk/gdkkeysyms.h> |
| 9 #include <gdk/gdkx.h> | 10 #include <gdk/gdkx.h> |
| 10 #include <cairo/cairo.h> | 11 #include <cairo/cairo.h> |
| 11 | 12 |
| 12 #include "base/gfx/gtk_util.h" | 13 #include "base/gfx/gtk_util.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 15 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 16 #include "base/task.h" | 17 #include "base/task.h" |
| 17 #include "chrome/common/native_web_keyboard_event.h" | 18 #include "chrome/common/native_web_keyboard_event.h" |
| 18 #include "chrome/common/render_messages.h" | 19 #include "chrome/common/render_messages.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 | 89 |
| 89 static gboolean ExposeEvent(GtkWidget* widget, GdkEventExpose* expose, | 90 static gboolean ExposeEvent(GtkWidget* widget, GdkEventExpose* expose, |
| 90 RenderWidgetHostViewGtk* host_view) { | 91 RenderWidgetHostViewGtk* host_view) { |
| 91 const gfx::Rect damage_rect(expose->area); | 92 const gfx::Rect damage_rect(expose->area); |
| 92 host_view->Paint(damage_rect); | 93 host_view->Paint(damage_rect); |
| 93 return FALSE; | 94 return FALSE; |
| 94 } | 95 } |
| 95 | 96 |
| 96 static gboolean KeyPressReleaseEvent(GtkWidget* widget, GdkEventKey* event, | 97 static gboolean KeyPressReleaseEvent(GtkWidget* widget, GdkEventKey* event, |
| 97 RenderWidgetHostViewGtk* host_view) { | 98 RenderWidgetHostViewGtk* host_view) { |
| 98 NativeWebKeyboardEvent wke(event); | 99 if (host_view->parent_ && host_view->activatable() && |
| 99 host_view->GetRenderWidgetHost()->ForwardKeyboardEvent(wke); | 100 GDK_Escape == event->keyval) { |
| 101 // Force popups to close on Esc just in case the renderer is hung. This |
| 102 // allows us to release our keyboard grab. |
| 103 host_view->host_->Shutdown(); |
| 104 } else { |
| 105 NativeWebKeyboardEvent wke(event); |
| 106 host_view->GetRenderWidgetHost()->ForwardKeyboardEvent(wke); |
| 107 } |
| 100 // We return TRUE because we did handle the event. If it turns out webkit | 108 // We return TRUE because we did handle the event. If it turns out webkit |
| 101 // can't handle the event, we'll deal with it in | 109 // can't handle the event, we'll deal with it in |
| 102 // RenderView::UnhandledKeyboardEvent(). | 110 // RenderView::UnhandledKeyboardEvent(). |
| 103 return TRUE; | 111 return TRUE; |
| 104 } | 112 } |
| 105 | 113 |
| 106 static gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* focus, | 114 static gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* focus, |
| 107 RenderWidgetHostViewGtk* host_view) { | 115 RenderWidgetHostViewGtk* host_view) { |
| 108 host_view->ShowCurrentCursor(); | 116 host_view->ShowCurrentCursor(); |
| 109 host_view->GetRenderWidgetHost()->Focus(); | 117 host_view->GetRenderWidgetHost()->Focus(); |
| 110 return FALSE; | 118 return FALSE; |
| 111 } | 119 } |
| 112 | 120 |
| 113 static gboolean OnFocusOut(GtkWidget* widget, GdkEventFocus* focus, | 121 static gboolean OnFocusOut(GtkWidget* widget, GdkEventFocus* focus, |
| 114 RenderWidgetHostViewGtk* host_view) { | 122 RenderWidgetHostViewGtk* host_view) { |
| 115 // Whenever we lose focus, set the cursor back to that of our parent window, | 123 // Whenever we lose focus, set the cursor back to that of our parent window, |
| 116 // which should be the default arrow. | 124 // which should be the default arrow. |
| 117 gdk_window_set_cursor(widget->window, NULL); | 125 gdk_window_set_cursor(widget->window, NULL); |
| 118 host_view->GetRenderWidgetHost()->Blur(); | 126 host_view->GetRenderWidgetHost()->Blur(); |
| 119 return FALSE; | 127 return FALSE; |
| 120 } | 128 } |
| 121 | 129 |
| 122 static gboolean ButtonPressReleaseEvent( | 130 static gboolean ButtonPressReleaseEvent( |
| 123 GtkWidget* widget, GdkEventButton* event, | 131 GtkWidget* widget, GdkEventButton* event, |
| 124 RenderWidgetHostViewGtk* host_view) { | 132 RenderWidgetHostViewGtk* host_view) { |
| 125 // We want to translate the coordinates of events that do not originate | 133 // We want to translate the coordinates of events that do not originate |
| 126 // from this widget to be relative to the top left of the widget. | 134 // from this widget to be relative to the top left of the widget. |
| 127 GtkWidget* event_widget = gtk_get_event_widget((GdkEvent*)event); | 135 GtkWidget* event_widget = gtk_get_event_widget( |
| 136 reinterpret_cast<GdkEvent*>(event)); |
| 128 if (event_widget != widget) { | 137 if (event_widget != widget) { |
| 129 int x = 0; | 138 int x = 0; |
| 130 int y = 0; | 139 int y = 0; |
| 131 gtk_widget_get_pointer(widget, &x, &y); | 140 gtk_widget_get_pointer(widget, &x, &y); |
| 132 // If the mouse release happens outside our popup, force the popup to | 141 // If the mouse release happens outside our popup, force the popup to |
| 133 // close. We do this so a hung renderer doesn't prevent us from | 142 // close. We do this so a hung renderer doesn't prevent us from |
| 134 // releasing the x pointer grab. | 143 // releasing the x pointer grab. |
| 135 bool click_in_popup = x >= 0 && y >= 0 && x < widget->allocation.width && | 144 bool click_in_popup = x >= 0 && y >= 0 && x < widget->allocation.width && |
| 136 y < widget->allocation.height; | 145 y < widget->allocation.height; |
| 137 if (!host_view->is_popup_first_mouse_release_ && !click_in_popup) { | 146 if (!host_view->is_popup_first_mouse_release_ && !click_in_popup) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 150 if (event->type == GDK_BUTTON_PRESS && !GTK_WIDGET_HAS_FOCUS(widget)) | 159 if (event->type == GDK_BUTTON_PRESS && !GTK_WIDGET_HAS_FOCUS(widget)) |
| 151 gtk_widget_grab_focus(widget); | 160 gtk_widget_grab_focus(widget); |
| 152 | 161 |
| 153 return FALSE; | 162 return FALSE; |
| 154 } | 163 } |
| 155 | 164 |
| 156 static gboolean MouseMoveEvent(GtkWidget* widget, GdkEventMotion* event, | 165 static gboolean MouseMoveEvent(GtkWidget* widget, GdkEventMotion* event, |
| 157 RenderWidgetHostViewGtk* host_view) { | 166 RenderWidgetHostViewGtk* host_view) { |
| 158 // We want to translate the coordinates of events that do not originate | 167 // We want to translate the coordinates of events that do not originate |
| 159 // from this widget to be relative to the top left of the widget. | 168 // from this widget to be relative to the top left of the widget. |
| 160 GtkWidget* event_widget = gtk_get_event_widget((GdkEvent*)event); | 169 GtkWidget* event_widget = gtk_get_event_widget( |
| 170 reinterpret_cast<GdkEvent*>(event)); |
| 161 if (event_widget != widget) { | 171 if (event_widget != widget) { |
| 162 int x = 0; | 172 int x = 0; |
| 163 int y = 0; | 173 int y = 0; |
| 164 gtk_widget_get_pointer(widget, &x, &y); | 174 gtk_widget_get_pointer(widget, &x, &y); |
| 165 event->x = x; | 175 event->x = x; |
| 166 event->y = y; | 176 event->y = y; |
| 167 } | 177 } |
| 168 host_view->GetRenderWidgetHost()->ForwardMouseEvent( | 178 host_view->GetRenderWidgetHost()->ForwardMouseEvent( |
| 169 WebInputEventFactory::mouseEvent(event)); | 179 WebInputEventFactory::mouseEvent(event)); |
| 170 return FALSE; | 180 return FALSE; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 // Now grab all of X's input. | 233 // Now grab all of X's input. |
| 224 gdk_pointer_grab( | 234 gdk_pointer_grab( |
| 225 parent_->window, | 235 parent_->window, |
| 226 TRUE, // Only events outside of the window are reported with respect | 236 TRUE, // Only events outside of the window are reported with respect |
| 227 // to |parent_->window|. | 237 // to |parent_->window|. |
| 228 static_cast<GdkEventMask>(GDK_BUTTON_PRESS_MASK | | 238 static_cast<GdkEventMask>(GDK_BUTTON_PRESS_MASK | |
| 229 GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK), | 239 GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK), |
| 230 NULL, | 240 NULL, |
| 231 NULL, | 241 NULL, |
| 232 GDK_CURRENT_TIME); | 242 GDK_CURRENT_TIME); |
| 243 // We grab keyboard events too so things like alt+tab are eaten. |
| 244 gdk_keyboard_grab(parent_->window, TRUE, GDK_CURRENT_TIME); |
| 233 | 245 |
| 234 // Our parent widget actually keeps GTK focus within its window, but we have | 246 // Our parent widget actually keeps GTK focus within its window, but we have |
| 235 // to make the webkit selection box disappear to maintain appearances. | 247 // to make the webkit selection box disappear to maintain appearances. |
| 236 parent_host_view->Blur(); | 248 parent_host_view->Blur(); |
| 237 } | 249 } |
| 238 | 250 |
| 239 gtk_widget_set_size_request(view_.get(), pos.width(), pos.height()); | 251 gtk_widget_set_size_request(view_.get(), pos.width(), pos.height()); |
| 240 | 252 |
| 241 gtk_window_set_default_size(GTK_WINDOW(popup), -1, -1); | 253 gtk_window_set_default_size(GTK_WINDOW(popup), -1, -1); |
| 242 // Don't allow the window to be resized. This also forces the window to | 254 // Don't allow the window to be resized. This also forces the window to |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 Destroy(); | 381 Destroy(); |
| 370 } | 382 } |
| 371 | 383 |
| 372 void RenderWidgetHostViewGtk::Destroy() { | 384 void RenderWidgetHostViewGtk::Destroy() { |
| 373 // If |parent_| is non-null, we are a popup and we must disconnect from our | 385 // If |parent_| is non-null, we are a popup and we must disconnect from our |
| 374 // parent and destroy the popup window. | 386 // parent and destroy the popup window. |
| 375 if (parent_) { | 387 if (parent_) { |
| 376 if (activatable()) { | 388 if (activatable()) { |
| 377 GdkDisplay *display = gtk_widget_get_display(parent_); | 389 GdkDisplay *display = gtk_widget_get_display(parent_); |
| 378 gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME); | 390 gdk_display_pointer_ungrab(display, GDK_CURRENT_TIME); |
| 391 gdk_display_keyboard_ungrab(display, GDK_CURRENT_TIME); |
| 379 parent_host_view_->Focus(); | 392 parent_host_view_->Focus(); |
| 380 } | 393 } |
| 381 gtk_widget_destroy(gtk_widget_get_parent(view_.get())); | 394 gtk_widget_destroy(gtk_widget_get_parent(view_.get())); |
| 382 } | 395 } |
| 383 | 396 |
| 384 // Remove |view_| from all containers now, so nothing else can hold a | 397 // Remove |view_| from all containers now, so nothing else can hold a |
| 385 // reference to |view_|'s widget except possibly a gtk signal handler if | 398 // reference to |view_|'s widget except possibly a gtk signal handler if |
| 386 // this code is currently executing within the context of a gtk signal | 399 // this code is currently executing within the context of a gtk signal |
| 387 // handler. Note that |view_| is still alive after this call. It will be | 400 // handler. Note that |view_| is still alive after this call. It will be |
| 388 // deallocated in the destructor. | 401 // deallocated in the destructor. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 void RenderWidgetHostViewGtk::ReceivedSelectionText(GtkClipboard* clipboard, | 505 void RenderWidgetHostViewGtk::ReceivedSelectionText(GtkClipboard* clipboard, |
| 493 const gchar* text, gpointer userdata) { | 506 const gchar* text, gpointer userdata) { |
| 494 // If there's nothing to paste (|text| is NULL), do nothing. | 507 // If there's nothing to paste (|text| is NULL), do nothing. |
| 495 if (!text) | 508 if (!text) |
| 496 return; | 509 return; |
| 497 RenderWidgetHostViewGtk* host_view = | 510 RenderWidgetHostViewGtk* host_view = |
| 498 reinterpret_cast<RenderWidgetHostViewGtk*>(userdata); | 511 reinterpret_cast<RenderWidgetHostViewGtk*>(userdata); |
| 499 host_view->host_->Send(new ViewMsg_InsertText(host_view->host_->routing_id(), | 512 host_view->host_->Send(new ViewMsg_InsertText(host_view->host_->routing_id(), |
| 500 UTF8ToUTF16(text))); | 513 UTF8ToUTF16(text))); |
| 501 } | 514 } |
| OLD | NEW |