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_win.h" | 5 #include "chrome/browser/renderer_host/render_widget_host_view_win.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/gfx/gdi_util.h" | 8 #include "base/gfx/gdi_util.h" |
9 #include "base/gfx/rect.h" | 9 #include "base/gfx/rect.h" |
10 #include "base/histogram.h" | 10 #include "base/histogram.h" |
11 #include "base/win_util.h" | 11 #include "base/win_util.h" |
12 #include "chrome/browser/browser_accessibility.h" | 12 #include "chrome/browser/browser_accessibility.h" |
13 #include "chrome/browser/browser_accessibility_manager.h" | 13 #include "chrome/browser/browser_accessibility_manager.h" |
14 #include "chrome/browser/browser_trial.h" | 14 #include "chrome/browser/browser_trial.h" |
15 #include "chrome/browser/renderer_host/backing_store.h" | 15 #include "chrome/browser/renderer_host/backing_store.h" |
16 #include "chrome/browser/renderer_host/render_process_host.h" | 16 #include "chrome/browser/renderer_host/render_process_host.h" |
17 #include "chrome/browser/renderer_host/render_widget_host.h" | 17 #include "chrome/browser/renderer_host/render_widget_host.h" |
18 #include "chrome/common/chrome_constants.h" | 18 #include "chrome/common/chrome_constants.h" |
19 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
20 #include "chrome/common/l10n_util.h" | 20 #include "chrome/common/l10n_util.h" |
21 #include "chrome/common/plugin_messages.h" | 21 #include "chrome/common/plugin_messages.h" |
22 #include "chrome/common/render_messages.h" | 22 #include "chrome/common/render_messages.h" |
| 23 #include "chrome/common/resource_bundle.h" |
23 #include "chrome/common/win_util.h" | 24 #include "chrome/common/win_util.h" |
24 // Included for views::kReflectedMessage - TODO(beng): move this to win_util.h! | 25 // Included for views::kReflectedMessage - TODO(beng): move this to win_util.h! |
25 #include "chrome/views/widget_win.h" | 26 #include "chrome/views/widget_win.h" |
26 #include "webkit/glue/plugins/plugin_constants_win.h" | 27 #include "webkit/glue/plugins/plugin_constants_win.h" |
27 #include "webkit/glue/plugins/webplugin_delegate_impl.h" | 28 #include "webkit/glue/plugins/webplugin_delegate_impl.h" |
28 #include "webkit/glue/webcursor.h" | 29 #include "webkit/glue/webcursor.h" |
| 30 #include "webkit_resources.h" |
| 31 |
29 | 32 |
30 using base::TimeDelta; | 33 using base::TimeDelta; |
31 using base::TimeTicks; | 34 using base::TimeTicks; |
32 | 35 |
33 namespace { | 36 namespace { |
34 | 37 |
35 // Tooltips will wrap after this width. Yes, wrap. Imagine that! | 38 // Tooltips will wrap after this width. Yes, wrap. Imagine that! |
36 const int kTooltipMaxWidthPixels = 300; | 39 const int kTooltipMaxWidthPixels = 300; |
37 | 40 |
38 // Maximum number of characters we allow in a tooltip. | 41 // Maximum number of characters we allow in a tooltip. |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 GetWindowRect(&window_rect); | 239 GetWindowRect(&window_rect); |
237 return gfx::Rect(window_rect); | 240 return gfx::Rect(window_rect); |
238 } | 241 } |
239 | 242 |
240 void RenderWidgetHostViewWin::UpdateCursor(const WebCursor& cursor) { | 243 void RenderWidgetHostViewWin::UpdateCursor(const WebCursor& cursor) { |
241 current_cursor_ = cursor; | 244 current_cursor_ = cursor; |
242 UpdateCursorIfOverSelf(); | 245 UpdateCursorIfOverSelf(); |
243 } | 246 } |
244 | 247 |
245 void RenderWidgetHostViewWin::UpdateCursorIfOverSelf() { | 248 void RenderWidgetHostViewWin::UpdateCursorIfOverSelf() { |
| 249 static HCURSOR kCursorResizeRight = LoadCursor(NULL, IDC_SIZENWSE); |
| 250 static HCURSOR kCursorResizeLeft = LoadCursor(NULL, IDC_SIZENESW); |
246 static HCURSOR kCursorArrow = LoadCursor(NULL, IDC_ARROW); | 251 static HCURSOR kCursorArrow = LoadCursor(NULL, IDC_ARROW); |
247 static HCURSOR kCursorAppStarting = LoadCursor(NULL, IDC_APPSTARTING); | 252 static HCURSOR kCursorAppStarting = LoadCursor(NULL, IDC_APPSTARTING); |
248 static HINSTANCE module_handle = | 253 static HINSTANCE module_handle = |
249 GetModuleHandle(chrome::kBrowserResourcesDll); | 254 GetModuleHandle(chrome::kBrowserResourcesDll); |
250 | 255 |
251 // We cannot pass in NULL as the module handle as this would only work for | |
252 // standard win32 cursors. We can also receive cursor types which are defined | |
253 // as webkit resources. We need to specify the module handle of chrome.dll | |
254 // while loading these cursors. | |
255 HCURSOR display_cursor = current_cursor_.GetCursor(module_handle); | |
256 | |
257 // If a page is in the loading state, we want to show the Arrow+Hourglass | |
258 // cursor only when the current cursor is the ARROW cursor. In all other | |
259 // cases we should continue to display the current cursor. | |
260 if (is_loading_ && display_cursor == kCursorArrow) | |
261 display_cursor = kCursorAppStarting; | |
262 | |
263 // If the mouse is over our HWND, then update the cursor state immediately. | 256 // If the mouse is over our HWND, then update the cursor state immediately. |
264 CPoint pt; | 257 CPoint pt; |
265 GetCursorPos(&pt); | 258 GetCursorPos(&pt); |
266 if (WindowFromPoint(pt) == m_hWnd) | 259 if (WindowFromPoint(pt) == m_hWnd) { |
267 SetCursor(display_cursor); | 260 BOOL result = ::ScreenToClient(m_hWnd, &pt); |
| 261 DCHECK(result); |
| 262 if (render_widget_host_->GetRootWindowResizerRect().Contains(pt.x, pt.y)) { |
| 263 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) |
| 264 SetCursor(kCursorResizeLeft); |
| 265 else |
| 266 SetCursor(kCursorResizeRight); |
| 267 } else { |
| 268 // We cannot pass in NULL as the module handle as this would only work for |
| 269 // standard win32 cursors. We can also receive cursor types which are |
| 270 // defined as webkit resources. We need to specify the module handle of |
| 271 // chrome.dll while loading these cursors. |
| 272 HCURSOR display_cursor = current_cursor_.GetCursor(module_handle); |
| 273 |
| 274 // If a page is in the loading state, we want to show the Arrow+Hourglass |
| 275 // cursor only when the current cursor is the ARROW cursor. In all other |
| 276 // cases we should continue to display the current cursor. |
| 277 if (is_loading_ && display_cursor == kCursorArrow) |
| 278 display_cursor = kCursorAppStarting; |
| 279 |
| 280 SetCursor(display_cursor); |
| 281 } |
| 282 } |
268 } | 283 } |
269 | 284 |
270 void RenderWidgetHostViewWin::SetIsLoading(bool is_loading) { | 285 void RenderWidgetHostViewWin::SetIsLoading(bool is_loading) { |
271 is_loading_ = is_loading; | 286 is_loading_ = is_loading; |
272 UpdateCursorIfOverSelf(); | 287 UpdateCursorIfOverSelf(); |
273 } | 288 } |
274 | 289 |
275 void RenderWidgetHostViewWin::IMEUpdateStatus(int control, | 290 void RenderWidgetHostViewWin::IMEUpdateStatus(int control, |
276 const gfx::Rect& caret_rect) { | 291 const gfx::Rect& caret_rect) { |
277 if (control == IME_DISABLE) { | 292 if (control == IME_DISABLE) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 | 330 |
316 // Send the invalid rect in screen coordinates. | 331 // Send the invalid rect in screen coordinates. |
317 gfx::Rect screen_rect = GetViewBounds(); | 332 gfx::Rect screen_rect = GetViewBounds(); |
318 gfx::Rect invalid_screen_rect = rect; | 333 gfx::Rect invalid_screen_rect = rect; |
319 invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y()); | 334 invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y()); |
320 | 335 |
321 LPARAM lparam = reinterpret_cast<LPARAM>(&invalid_screen_rect); | 336 LPARAM lparam = reinterpret_cast<LPARAM>(&invalid_screen_rect); |
322 EnumChildWindows(m_hWnd, EnumChildProc, lparam); | 337 EnumChildWindows(m_hWnd, EnumChildProc, lparam); |
323 } | 338 } |
324 | 339 |
| 340 void RenderWidgetHostViewWin::DrawResizeCorner(const gfx::Rect& paint_rect, |
| 341 HDC dc) { |
| 342 gfx::Rect resize_corner_rect = |
| 343 render_widget_host_->GetRootWindowResizerRect(); |
| 344 if (!paint_rect.Intersect(resize_corner_rect).IsEmpty()) { |
| 345 SkBitmap* bitmap = ResourceBundle::GetSharedInstance(). |
| 346 GetBitmapNamed(IDR_TEXTAREA_RESIZER); |
| 347 ChromeCanvas canvas(bitmap->width(), bitmap->height(), false); |
| 348 // TODO(jcampan): This const_cast should not be necessary once the |
| 349 // SKIA API has been changed to return a non-const bitmap. |
| 350 const_cast<SkBitmap&>(canvas.getDevice()->accessBitmap(true)). |
| 351 eraseARGB(0, 0, 0, 0); |
| 352 int x = resize_corner_rect.x() + resize_corner_rect.width() - |
| 353 bitmap->width(); |
| 354 bool rtl_dir = (l10n_util::GetTextDirection() == |
| 355 l10n_util::RIGHT_TO_LEFT); |
| 356 if (rtl_dir) { |
| 357 canvas.TranslateInt(bitmap->width(), 0); |
| 358 canvas.ScaleInt(-1, 1); |
| 359 canvas.save(); |
| 360 x = 0; |
| 361 } |
| 362 canvas.DrawBitmapInt(*bitmap, 0, 0); |
| 363 canvas.getTopPlatformDevice().drawToHDC(dc, x, |
| 364 resize_corner_rect.y() + resize_corner_rect.height() - |
| 365 bitmap->height(), NULL); |
| 366 if (rtl_dir) |
| 367 canvas.restore(); |
| 368 } |
| 369 } |
| 370 |
325 void RenderWidgetHostViewWin::DidPaintRect(const gfx::Rect& rect) { | 371 void RenderWidgetHostViewWin::DidPaintRect(const gfx::Rect& rect) { |
326 if (is_hidden_) | 372 if (is_hidden_) |
327 return; | 373 return; |
328 | 374 |
329 Redraw(rect); | 375 Redraw(rect); |
330 } | 376 } |
331 | 377 |
332 void RenderWidgetHostViewWin::DidScrollRect( | 378 void RenderWidgetHostViewWin::DidScrollRect( |
333 const gfx::Rect& rect, int dx, int dy) { | 379 const gfx::Rect& rect, int dx, int dy) { |
334 if (is_hidden_) | 380 if (is_hidden_) |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 BackingStore* backing_store = render_widget_host_->GetBackingStore(); | 473 BackingStore* backing_store = render_widget_host_->GetBackingStore(); |
428 | 474 |
429 if (backing_store) { | 475 if (backing_store) { |
430 gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint); | 476 gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint); |
431 | 477 |
432 gfx::Rect bitmap_rect( | 478 gfx::Rect bitmap_rect( |
433 0, 0, backing_store->size().width(), backing_store->size().height()); | 479 0, 0, backing_store->size().width(), backing_store->size().height()); |
434 | 480 |
435 gfx::Rect paint_rect = bitmap_rect.Intersect(damaged_rect); | 481 gfx::Rect paint_rect = bitmap_rect.Intersect(damaged_rect); |
436 if (!paint_rect.IsEmpty()) { | 482 if (!paint_rect.IsEmpty()) { |
| 483 DrawResizeCorner(paint_rect, backing_store->hdc()); |
437 BitBlt(paint_dc.m_hDC, | 484 BitBlt(paint_dc.m_hDC, |
438 paint_rect.x(), | 485 paint_rect.x(), |
439 paint_rect.y(), | 486 paint_rect.y(), |
440 paint_rect.width(), | 487 paint_rect.width(), |
441 paint_rect.height(), | 488 paint_rect.height(), |
442 backing_store->hdc(), | 489 backing_store->hdc(), |
443 paint_rect.x(), | 490 paint_rect.x(), |
444 paint_rect.y(), | 491 paint_rect.y(), |
445 SRCCOPY); | 492 SRCCOPY); |
446 } | 493 } |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 // WebContents first in the case of popups. If we do, we would need to | 762 // WebContents first in the case of popups. If we do, we would need to |
716 // convert the click from the popup window coordinates to the WebContents' | 763 // convert the click from the popup window coordinates to the WebContents' |
717 // window coordinates. For now we don't forward the message in that case to | 764 // window coordinates. For now we don't forward the message in that case to |
718 // address bug #907474. | 765 // address bug #907474. |
719 // Note: GetParent() on popup windows returns the top window and not the | 766 // Note: GetParent() on popup windows returns the top window and not the |
720 // parent the window was created with (the parent and the owner of the popup | 767 // parent the window was created with (the parent and the owner of the popup |
721 // is the first non-child view of the view that was specified to the create | 768 // is the first non-child view of the view that was specified to the create |
722 // call). So the WebContents window would have to be specified to the | 769 // call). So the WebContents window would have to be specified to the |
723 // RenderViewHostHWND as there is no way to retrieve it from the HWND. | 770 // RenderViewHostHWND as there is no way to retrieve it from the HWND. |
724 if (!close_on_deactivate_) { // Don't forward if the container is a popup. | 771 if (!close_on_deactivate_) { // Don't forward if the container is a popup. |
| 772 if (message == WM_LBUTTONDOWN) { |
| 773 // If we get clicked on, where the resize corner is drawn, we delegate the |
| 774 // message to the root window, with the proper HTBOTTOMXXX wparam so that |
| 775 // Windows can take care of the resizing for us. |
| 776 if (render_widget_host_->GetRootWindowResizerRect(). |
| 777 Contains(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam))) { |
| 778 WPARAM wparam = HTBOTTOMRIGHT; |
| 779 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) |
| 780 wparam = HTBOTTOMLEFT; |
| 781 HWND root_hwnd = ::GetAncestor(m_hWnd, GA_ROOT); |
| 782 if (SendMessage(root_hwnd, WM_NCLBUTTONDOWN, wparam, lparam) == 0) |
| 783 return 0; |
| 784 } |
| 785 } |
725 switch (message) { | 786 switch (message) { |
726 case WM_LBUTTONDOWN: | 787 case WM_LBUTTONDOWN: |
727 case WM_MBUTTONDOWN: | 788 case WM_MBUTTONDOWN: |
728 case WM_MOUSEMOVE: | 789 case WM_MOUSEMOVE: |
729 case WM_MOUSELEAVE: | 790 case WM_MOUSELEAVE: |
730 case WM_RBUTTONDOWN: { | 791 case WM_RBUTTONDOWN: { |
731 // Give the WebContents first crack at the message. It may want to | 792 // Give the WebContents first crack at the message. It may want to |
732 // prevent forwarding to the renderer if some higher level browser | 793 // prevent forwarding to the renderer if some higher level browser |
733 // functionality is invoked. | 794 // functionality is invoked. |
734 if (SendMessage(GetParent(), message, wparam, lparam) != 0) | 795 if (SendMessage(GetParent(), message, wparam, lparam) != 0) |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 // WM_LBUTTONDOWN. | 1033 // WM_LBUTTONDOWN. |
973 SetFocus(); | 1034 SetFocus(); |
974 } | 1035 } |
975 } | 1036 } |
976 | 1037 |
977 void RenderWidgetHostViewWin::ShutdownHost() { | 1038 void RenderWidgetHostViewWin::ShutdownHost() { |
978 shutdown_factory_.RevokeAll(); | 1039 shutdown_factory_.RevokeAll(); |
979 render_widget_host_->Shutdown(); | 1040 render_widget_host_->Shutdown(); |
980 // Do not touch any members at this point, |this| has been deleted. | 1041 // Do not touch any members at this point, |this| has been deleted. |
981 } | 1042 } |
OLD | NEW |