| 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 "webkit/tools/test_shell/webwidget_host.h" | 5 #include "webkit/tools/test_shell/webwidget_host.h" |
| 6 | 6 |
| 7 #include <cairo/cairo.h> | 7 #include <cairo/cairo.h> |
| 8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "skia/ext/bitmap_platform_device.h" | 12 #include "skia/ext/bitmap_platform_device.h" |
| 13 #include "skia/ext/platform_canvas.h" | 13 #include "skia/ext/platform_canvas.h" |
| 14 #include "skia/ext/platform_device.h" | 14 #include "skia/ext/platform_device.h" |
| 15 #include "webkit/api/public/gtk/WebInputEventFactory.h" | 15 #include "webkit/api/public/gtk/WebInputEventFactory.h" |
| 16 #include "webkit/api/public/x11/WebScreenInfoFactory.h" | 16 #include "webkit/api/public/x11/WebScreenInfoFactory.h" |
| 17 #include "webkit/api/public/WebInputEvent.h" | 17 #include "webkit/api/public/WebInputEvent.h" |
| 18 #include "webkit/api/public/WebPopupMenu.h" |
| 18 #include "webkit/api/public/WebScreenInfo.h" | 19 #include "webkit/api/public/WebScreenInfo.h" |
| 19 #include "webkit/api/public/WebSize.h" | 20 #include "webkit/api/public/WebSize.h" |
| 20 #include "webkit/glue/webwidget.h" | |
| 21 #include "webkit/tools/test_shell/test_shell.h" | 21 #include "webkit/tools/test_shell/test_shell.h" |
| 22 #include "webkit/tools/test_shell/test_shell_x11.h" | 22 #include "webkit/tools/test_shell/test_shell_x11.h" |
| 23 | 23 |
| 24 using WebKit::WebInputEventFactory; | 24 using WebKit::WebInputEventFactory; |
| 25 using WebKit::WebKeyboardEvent; | 25 using WebKit::WebKeyboardEvent; |
| 26 using WebKit::WebMouseEvent; | 26 using WebKit::WebMouseEvent; |
| 27 using WebKit::WebMouseWheelEvent; | 27 using WebKit::WebMouseWheelEvent; |
| 28 using WebKit::WebPopupMenu; |
| 28 using WebKit::WebScreenInfo; | 29 using WebKit::WebScreenInfo; |
| 29 using WebKit::WebScreenInfoFactory; | 30 using WebKit::WebScreenInfoFactory; |
| 30 using WebKit::WebSize; | 31 using WebKit::WebSize; |
| 32 using WebKit::WebWidgetClient; |
| 31 | 33 |
| 32 namespace { | 34 namespace { |
| 33 | 35 |
| 34 // In response to an invalidation, we call into WebKit to do layout. On | 36 // In response to an invalidation, we call into WebKit to do layout. On |
| 35 // Windows, WM_PAINT is a virtual message so any extra invalidates that come up | 37 // Windows, WM_PAINT is a virtual message so any extra invalidates that come up |
| 36 // while it's doing layout are implicitly swallowed as soon as we actually do | 38 // while it's doing layout are implicitly swallowed as soon as we actually do |
| 37 // drawing via BeginPaint. | 39 // drawing via BeginPaint. |
| 38 // | 40 // |
| 39 // Though GTK does know how to collapse multiple paint requests, it won't erase | 41 // Though GTK does know how to collapse multiple paint requests, it won't erase |
| 40 // paint requests from the future when we start drawing. To avoid an infinite | 42 // paint requests from the future when we start drawing. To avoid an infinite |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 // The GdkWindow was destroyed. | 154 // The GdkWindow was destroyed. |
| 153 static gboolean HandleDestroy(GtkWidget* widget, WebWidgetHost* host) { | 155 static gboolean HandleDestroy(GtkWidget* widget, WebWidgetHost* host) { |
| 154 host->WindowDestroyed(); | 156 host->WindowDestroyed(); |
| 155 return FALSE; | 157 return FALSE; |
| 156 } | 158 } |
| 157 | 159 |
| 158 // Keyboard key pressed. | 160 // Keyboard key pressed. |
| 159 static gboolean HandleKeyPress(GtkWidget* widget, | 161 static gboolean HandleKeyPress(GtkWidget* widget, |
| 160 GdkEventKey* event, | 162 GdkEventKey* event, |
| 161 WebWidgetHost* host) { | 163 WebWidgetHost* host) { |
| 162 const WebKeyboardEvent& wke = WebInputEventFactory::keyboardEvent(event); | 164 host->webwidget()->handleInputEvent( |
| 163 host->webwidget()->HandleInputEvent(&wke); | 165 WebInputEventFactory::keyboardEvent(event)); |
| 164 | |
| 165 return FALSE; | 166 return FALSE; |
| 166 } | 167 } |
| 167 | 168 |
| 168 // Keyboard key released. | 169 // Keyboard key released. |
| 169 static gboolean HandleKeyRelease(GtkWidget* widget, | 170 static gboolean HandleKeyRelease(GtkWidget* widget, |
| 170 GdkEventKey* event, | 171 GdkEventKey* event, |
| 171 WebWidgetHost* host) { | 172 WebWidgetHost* host) { |
| 172 return HandleKeyPress(widget, event, host); | 173 return HandleKeyPress(widget, event, host); |
| 173 } | 174 } |
| 174 | 175 |
| 175 // This signal is called when arrow keys or tab is pressed. If we return | 176 // This signal is called when arrow keys or tab is pressed. If we return |
| 176 // true, we prevent focus from being moved to another widget. If we want to | 177 // true, we prevent focus from being moved to another widget. If we want to |
| 177 // allow focus to be moved outside of web contents, we need to implement | 178 // allow focus to be moved outside of web contents, we need to implement |
| 178 // WebViewDelegate::TakeFocus in the test webview delegate. | 179 // WebViewDelegate::TakeFocus in the test webview delegate. |
| 179 static gboolean HandleFocus(GtkWidget* widget, | 180 static gboolean HandleFocus(GtkWidget* widget, |
| 180 GdkEventFocus* focus, | 181 GdkEventFocus* focus, |
| 181 WebWidgetHost* host) { | 182 WebWidgetHost* host) { |
| 182 return TRUE; | 183 return TRUE; |
| 183 } | 184 } |
| 184 | 185 |
| 185 // Keyboard focus entered. | 186 // Keyboard focus entered. |
| 186 static gboolean HandleFocusIn(GtkWidget* widget, | 187 static gboolean HandleFocusIn(GtkWidget* widget, |
| 187 GdkEventFocus* focus, | 188 GdkEventFocus* focus, |
| 188 WebWidgetHost* host) { | 189 WebWidgetHost* host) { |
| 189 // Ignore focus calls in layout test mode so that tests don't mess with each | 190 // Ignore focus calls in layout test mode so that tests don't mess with each |
| 190 // other's focus when running in parallel. | 191 // other's focus when running in parallel. |
| 191 if (!TestShell::layout_test_mode()) | 192 if (!TestShell::layout_test_mode()) |
| 192 host->webwidget()->SetFocus(true); | 193 host->webwidget()->setFocus(true); |
| 193 return FALSE; | 194 return FALSE; |
| 194 } | 195 } |
| 195 | 196 |
| 196 // Keyboard focus left. | 197 // Keyboard focus left. |
| 197 static gboolean HandleFocusOut(GtkWidget* widget, | 198 static gboolean HandleFocusOut(GtkWidget* widget, |
| 198 GdkEventFocus* focus, | 199 GdkEventFocus* focus, |
| 199 WebWidgetHost* host) { | 200 WebWidgetHost* host) { |
| 200 // Ignore focus calls in layout test mode so that tests don't mess with each | 201 // Ignore focus calls in layout test mode so that tests don't mess with each |
| 201 // other's focus when running in parallel. | 202 // other's focus when running in parallel. |
| 202 if (!TestShell::layout_test_mode()) | 203 if (!TestShell::layout_test_mode()) |
| 203 host->webwidget()->SetFocus(false); | 204 host->webwidget()->setFocus(false); |
| 204 return FALSE; | 205 return FALSE; |
| 205 } | 206 } |
| 206 | 207 |
| 207 // Mouse button down. | 208 // Mouse button down. |
| 208 static gboolean HandleButtonPress(GtkWidget* widget, | 209 static gboolean HandleButtonPress(GtkWidget* widget, |
| 209 GdkEventButton* event, | 210 GdkEventButton* event, |
| 210 WebWidgetHost* host) { | 211 WebWidgetHost* host) { |
| 211 const WebMouseEvent& wme = WebInputEventFactory::mouseEvent(event); | 212 host->webwidget()->handleInputEvent( |
| 212 host->webwidget()->HandleInputEvent(&wme); | 213 WebInputEventFactory::mouseEvent(event)); |
| 213 return FALSE; | 214 return FALSE; |
| 214 } | 215 } |
| 215 | 216 |
| 216 // Mouse button up. | 217 // Mouse button up. |
| 217 static gboolean HandleButtonRelease(GtkWidget* widget, | 218 static gboolean HandleButtonRelease(GtkWidget* widget, |
| 218 GdkEventButton* event, | 219 GdkEventButton* event, |
| 219 WebWidgetHost* host) { | 220 WebWidgetHost* host) { |
| 220 return HandleButtonPress(widget, event, host); | 221 return HandleButtonPress(widget, event, host); |
| 221 } | 222 } |
| 222 | 223 |
| 223 // Mouse pointer movements. | 224 // Mouse pointer movements. |
| 224 static gboolean HandleMotionNotify(GtkWidget* widget, | 225 static gboolean HandleMotionNotify(GtkWidget* widget, |
| 225 GdkEventMotion* event, | 226 GdkEventMotion* event, |
| 226 WebWidgetHost* host) { | 227 WebWidgetHost* host) { |
| 227 const WebMouseEvent& wme = WebInputEventFactory::mouseEvent(event); | 228 host->webwidget()->handleInputEvent( |
| 228 host->webwidget()->HandleInputEvent(&wme); | 229 WebInputEventFactory::mouseEvent(event)); |
| 229 return FALSE; | 230 return FALSE; |
| 230 } | 231 } |
| 231 | 232 |
| 232 // Mouse scroll wheel. | 233 // Mouse scroll wheel. |
| 233 static gboolean HandleScroll(GtkWidget* widget, | 234 static gboolean HandleScroll(GtkWidget* widget, |
| 234 GdkEventScroll* event, | 235 GdkEventScroll* event, |
| 235 WebWidgetHost* host) { | 236 WebWidgetHost* host) { |
| 236 const WebMouseWheelEvent& wmwe = | 237 host->webwidget()->handleInputEvent( |
| 237 WebInputEventFactory::mouseWheelEvent(event); | 238 WebInputEventFactory::mouseWheelEvent(event)); |
| 238 host->webwidget()->HandleInputEvent(&wmwe); | |
| 239 return FALSE; | 239 return FALSE; |
| 240 } | 240 } |
| 241 | 241 |
| 242 DISALLOW_IMPLICIT_CONSTRUCTORS(WebWidgetHostGtkWidget); | 242 DISALLOW_IMPLICIT_CONSTRUCTORS(WebWidgetHostGtkWidget); |
| 243 }; | 243 }; |
| 244 | 244 |
| 245 } // namespace | 245 } // namespace |
| 246 | 246 |
| 247 // This is provided so that the webview can reuse the custom GTK window code. | 247 // This is provided so that the webview can reuse the custom GTK window code. |
| 248 // static | 248 // static |
| 249 gfx::NativeView WebWidgetHost::CreateWidget( | 249 gfx::NativeView WebWidgetHost::CreateWidget( |
| 250 gfx::NativeView parent_view, WebWidgetHost* host) { | 250 gfx::NativeView parent_view, WebWidgetHost* host) { |
| 251 return WebWidgetHostGtkWidget::CreateNewWidget(parent_view, host); | 251 return WebWidgetHostGtkWidget::CreateNewWidget(parent_view, host); |
| 252 } | 252 } |
| 253 | 253 |
| 254 // static | 254 // static |
| 255 WebWidgetHost* WebWidgetHost::Create(GtkWidget* parent_view, | 255 WebWidgetHost* WebWidgetHost::Create(GtkWidget* parent_view, |
| 256 WebWidgetDelegate* delegate) { | 256 WebWidgetClient* client) { |
| 257 WebWidgetHost* host = new WebWidgetHost(); | 257 WebWidgetHost* host = new WebWidgetHost(); |
| 258 host->view_ = CreateWidget(parent_view, host); | 258 host->view_ = CreateWidget(parent_view, host); |
| 259 host->webwidget_ = WebWidget::Create(delegate); | 259 host->webwidget_ = WebPopupMenu::create(client); |
| 260 // We manage our own double buffering because we need to be able to update | 260 // We manage our own double buffering because we need to be able to update |
| 261 // the expose area in an ExposeEvent within the lifetime of the event handler. | 261 // the expose area in an ExposeEvent within the lifetime of the event handler. |
| 262 gtk_widget_set_double_buffered(GTK_WIDGET(host->view_), false); | 262 gtk_widget_set_double_buffered(GTK_WIDGET(host->view_), false); |
| 263 | 263 |
| 264 return host; | 264 return host; |
| 265 } | 265 } |
| 266 | 266 |
| 267 void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) { | 267 void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) { |
| 268 paint_rect_ = paint_rect_.Union(rect); | 268 paint_rect_ = paint_rect_.Union(rect); |
| 269 } | 269 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 288 WebWidgetHost::WebWidgetHost() | 288 WebWidgetHost::WebWidgetHost() |
| 289 : view_(NULL), | 289 : view_(NULL), |
| 290 webwidget_(NULL), | 290 webwidget_(NULL), |
| 291 scroll_dx_(0), | 291 scroll_dx_(0), |
| 292 scroll_dy_(0), | 292 scroll_dy_(0), |
| 293 track_mouse_leave_(false) { | 293 track_mouse_leave_(false) { |
| 294 set_painting(false); | 294 set_painting(false); |
| 295 } | 295 } |
| 296 | 296 |
| 297 WebWidgetHost::~WebWidgetHost() { | 297 WebWidgetHost::~WebWidgetHost() { |
| 298 webwidget_->Close(); | 298 webwidget_->close(); |
| 299 } | 299 } |
| 300 | 300 |
| 301 void WebWidgetHost::Resize(const gfx::Size &newsize) { | 301 void WebWidgetHost::Resize(const gfx::Size &newsize) { |
| 302 // The pixel buffer backing us is now the wrong size | 302 // The pixel buffer backing us is now the wrong size |
| 303 canvas_.reset(); | 303 canvas_.reset(); |
| 304 | 304 |
| 305 webwidget_->Resize(gfx::Size(newsize.width(), newsize.height())); | 305 webwidget_->resize(newsize); |
| 306 } | 306 } |
| 307 | 307 |
| 308 void WebWidgetHost::Paint() { | 308 void WebWidgetHost::Paint() { |
| 309 int width = view_->allocation.width; | 309 int width = view_->allocation.width; |
| 310 int height = view_->allocation.height; | 310 int height = view_->allocation.height; |
| 311 gfx::Rect client_rect(width, height); | 311 gfx::Rect client_rect(width, height); |
| 312 | 312 |
| 313 // Allocate a canvas if necessary | 313 // Allocate a canvas if necessary |
| 314 if (!canvas_.get()) { | 314 if (!canvas_.get()) { |
| 315 ResetScrollRect(); | 315 ResetScrollRect(); |
| 316 paint_rect_ = client_rect; | 316 paint_rect_ = client_rect; |
| 317 canvas_.reset(new skia::PlatformCanvas(width, height, true)); | 317 canvas_.reset(new skia::PlatformCanvas(width, height, true)); |
| 318 if (!canvas_.get()) { | 318 if (!canvas_.get()) { |
| 319 // memory allocation failed, we can't paint. | 319 // memory allocation failed, we can't paint. |
| 320 LOG(ERROR) << "Failed to allocate memory for " << width << "x" << height; | 320 LOG(ERROR) << "Failed to allocate memory for " << width << "x" << height; |
| 321 return; | 321 return; |
| 322 } | 322 } |
| 323 } | 323 } |
| 324 | 324 |
| 325 // This may result in more invalidation | 325 // This may result in more invalidation |
| 326 webwidget_->Layout(); | 326 webwidget_->layout(); |
| 327 | 327 |
| 328 // Paint the canvas if necessary. Allow painting to generate extra rects the | 328 // Paint the canvas if necessary. Allow painting to generate extra rects the |
| 329 // first time we call it. This is necessary because some WebCore rendering | 329 // first time we call it. This is necessary because some WebCore rendering |
| 330 // objects update their layout only when painted. | 330 // objects update their layout only when painted. |
| 331 // Store the total area painted in total_paint. Then tell the gdk window | 331 // Store the total area painted in total_paint. Then tell the gdk window |
| 332 // to update that area after we're done painting it. | 332 // to update that area after we're done painting it. |
| 333 gfx::Rect total_paint; | 333 gfx::Rect total_paint; |
| 334 for (int i = 0; i < 2; ++i) { | 334 for (int i = 0; i < 2; ++i) { |
| 335 paint_rect_ = client_rect.Intersect(paint_rect_); | 335 paint_rect_ = client_rect.Intersect(paint_rect_); |
| 336 if (!paint_rect_.IsEmpty()) { | 336 if (!paint_rect_.IsEmpty()) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 return WebScreenInfoFactory::screenInfo(display, screen_num); | 374 return WebScreenInfoFactory::screenInfo(display, screen_num); |
| 375 } | 375 } |
| 376 | 376 |
| 377 void WebWidgetHost::ResetScrollRect() { | 377 void WebWidgetHost::ResetScrollRect() { |
| 378 // This method is only needed for optimized scroll painting, which we don't | 378 // This method is only needed for optimized scroll painting, which we don't |
| 379 // care about in the test shell, yet. | 379 // care about in the test shell, yet. |
| 380 } | 380 } |
| 381 | 381 |
| 382 void WebWidgetHost::PaintRect(const gfx::Rect& rect) { | 382 void WebWidgetHost::PaintRect(const gfx::Rect& rect) { |
| 383 set_painting(true); | 383 set_painting(true); |
| 384 webwidget_->Paint(canvas_.get(), rect); | 384 webwidget_->paint(canvas_.get(), rect); |
| 385 set_painting(false); | 385 set_painting(false); |
| 386 } | 386 } |
| 387 | 387 |
| 388 void WebWidgetHost::WindowDestroyed() { | 388 void WebWidgetHost::WindowDestroyed() { |
| 389 delete this; | 389 delete this; |
| 390 } | 390 } |
| OLD | NEW |