| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/browser_dialogs.h" | 5 #include "chrome/browser/ui/browser_dialogs.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) && !defined(USE_AURA) |
| 8 #include <windows.h> |
| 9 #endif |
| 10 |
| 7 #include "base/i18n/rtl.h" | 11 #include "base/i18n/rtl.h" |
| 8 #include "base/memory/scoped_vector.h" | 12 #include "base/memory/scoped_vector.h" |
| 13 #include "base/process_util.h" |
| 9 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 10 #include "chrome/browser/favicon/favicon_tab_helper.h" | 15 #include "chrome/browser/favicon/favicon_tab_helper.h" |
| 16 #include "chrome/browser/platform_util.h" |
| 11 #include "chrome/browser/ui/browser_list.h" | 17 #include "chrome/browser/ui/browser_list.h" |
| 12 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" | 18 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" |
| 13 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| 14 #include "chrome/common/chrome_constants.h" | 20 #include "chrome/common/chrome_constants.h" |
| 15 #include "chrome/common/logging_chrome.h" | 21 #include "chrome/common/logging_chrome.h" |
| 16 #include "content/browser/renderer_host/render_view_host.h" | 22 #include "content/browser/renderer_host/render_view_host.h" |
| 17 #include "content/public/browser/render_process_host.h" | 23 #include "content/public/browser/render_process_host.h" |
| 18 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
| 19 #include "content/public/common/result_codes.h" | 25 #include "content/public/common/result_codes.h" |
| 20 #include "grit/chromium_strings.h" | 26 #include "grit/chromium_strings.h" |
| 21 #include "grit/generated_resources.h" | 27 #include "grit/generated_resources.h" |
| 22 #include "grit/theme_resources.h" | 28 #include "grit/theme_resources.h" |
| 23 #include "ui/base/l10n/l10n_util.h" | 29 #include "ui/base/l10n/l10n_util.h" |
| 24 #include "ui/base/resource/resource_bundle.h" | 30 #include "ui/base/resource/resource_bundle.h" |
| 25 #include "ui/gfx/canvas.h" | 31 #include "ui/gfx/canvas.h" |
| 26 #include "ui/views/controls/button/text_button.h" | 32 #include "ui/views/controls/button/text_button.h" |
| 27 #include "ui/views/controls/image_view.h" | 33 #include "ui/views/controls/image_view.h" |
| 28 #include "ui/views/controls/label.h" | 34 #include "ui/views/controls/label.h" |
| 29 #include "ui/views/controls/table/group_table_model.h" | 35 #include "ui/views/controls/table/group_table_model.h" |
| 30 #include "ui/views/controls/table/group_table_view.h" | 36 #include "ui/views/controls/table/group_table_view.h" |
| 31 #include "ui/views/layout/grid_layout.h" | 37 #include "ui/views/layout/grid_layout.h" |
| 32 #include "ui/views/layout/layout_constants.h" | 38 #include "ui/views/layout/layout_constants.h" |
| 33 #include "ui/views/widget/widget.h" | 39 #include "ui/views/widget/widget.h" |
| 34 #include "ui/views/window/client_view.h" | 40 #include "ui/views/window/client_view.h" |
| 35 #include "ui/views/window/dialog_delegate.h" | 41 #include "ui/views/window/dialog_delegate.h" |
| 36 | 42 |
| 43 #if defined(USE_AURA) |
| 44 #include "ui/aura/window.h" |
| 45 #endif |
| 46 |
| 37 class HungRendererDialogView; | 47 class HungRendererDialogView; |
| 38 | 48 |
| 39 using content::WebContents; | 49 using content::WebContents; |
| 40 | 50 |
| 41 namespace { | 51 namespace { |
| 42 // We only support showing one of these at a time per app. | 52 // We only support showing one of these at a time per app. |
| 43 HungRendererDialogView* g_instance = NULL; | 53 HungRendererDialogView* g_instance = NULL; |
| 44 } | 54 } |
| 45 | 55 |
| 46 /////////////////////////////////////////////////////////////////////////////// | 56 /////////////////////////////////////////////////////////////////////////////// |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 HungRendererDialogView::~HungRendererDialogView() { | 333 HungRendererDialogView::~HungRendererDialogView() { |
| 324 hung_pages_table_->SetModel(NULL); | 334 hung_pages_table_->SetModel(NULL); |
| 325 } | 335 } |
| 326 | 336 |
| 327 void HungRendererDialogView::ShowForWebContents(WebContents* contents) { | 337 void HungRendererDialogView::ShowForWebContents(WebContents* contents) { |
| 328 DCHECK(contents && GetWidget()); | 338 DCHECK(contents && GetWidget()); |
| 329 | 339 |
| 330 // Don't show the warning unless the foreground window is the frame, or this | 340 // Don't show the warning unless the foreground window is the frame, or this |
| 331 // window (but still invisible). If the user has another window or | 341 // window (but still invisible). If the user has another window or |
| 332 // application selected, activating ourselves is rude. | 342 // application selected, activating ourselves is rude. |
| 333 HWND frame_hwnd = GetAncestor(contents->GetNativeView(), GA_ROOT); | 343 gfx::NativeView frame_view = |
| 334 HWND foreground_window = GetForegroundWindow(); | 344 platform_util::GetTopLevel(contents->GetNativeView()); |
| 335 if (foreground_window != frame_hwnd && | 345 if (!platform_util::IsWindowActive(frame_view) && |
| 336 foreground_window != GetWidget()->GetNativeWindow()) { | 346 !platform_util::IsWindowActive(GetWidget()->GetNativeWindow())) { |
| 337 return; | 347 return; |
| 338 } | 348 } |
| 339 | 349 |
| 340 if (!GetWidget()->IsActive()) { | 350 if (!GetWidget()->IsActive()) { |
| 341 gfx::Rect bounds = GetDisplayBounds(contents); | 351 gfx::Rect bounds = GetDisplayBounds(contents); |
| 342 views::Widget* insert_after = | 352 views::Widget* insert_after = |
| 343 views::Widget::GetWidgetForNativeView(frame_hwnd); | 353 views::Widget::GetWidgetForNativeView(frame_view); |
| 344 GetWidget()->SetBoundsConstrained(bounds); | 354 GetWidget()->SetBoundsConstrained(bounds); |
| 345 if (insert_after) | 355 if (insert_after) |
| 346 GetWidget()->StackAboveWidget(insert_after); | 356 GetWidget()->StackAboveWidget(insert_after); |
| 347 | 357 |
| 348 // We only do this if the window isn't active (i.e. hasn't been shown yet, | 358 // We only do this if the window isn't active (i.e. hasn't been shown yet, |
| 349 // or is currently shown but deactivated for another WebContents). This is | 359 // or is currently shown but deactivated for another WebContents). This is |
| 350 // because this window is a singleton, and it's possible another active | 360 // because this window is a singleton, and it's possible another active |
| 351 // renderer may hang while this one is showing, and we don't want to reset | 361 // renderer may hang while this one is showing, and we don't want to reset |
| 352 // the list of hung pages for a potentially unrelated renderer while this | 362 // the list of hung pages for a potentially unrelated renderer while this |
| 353 // one is showing. | 363 // one is showing. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 | 425 |
| 416 views::View* HungRendererDialogView::GetContentsView() { | 426 views::View* HungRendererDialogView::GetContentsView() { |
| 417 return this; | 427 return this; |
| 418 } | 428 } |
| 419 | 429 |
| 420 /////////////////////////////////////////////////////////////////////////////// | 430 /////////////////////////////////////////////////////////////////////////////// |
| 421 // HungRendererDialogView, views::ButtonListener implementation: | 431 // HungRendererDialogView, views::ButtonListener implementation: |
| 422 | 432 |
| 423 void HungRendererDialogView::ButtonPressed( | 433 void HungRendererDialogView::ButtonPressed( |
| 424 views::Button* sender, const views::Event& event) { | 434 views::Button* sender, const views::Event& event) { |
| 425 if (sender == kill_button_) { | 435 if (sender == kill_button_ && |
| 426 if (hung_pages_table_model_->GetRenderProcessHost()) { | 436 hung_pages_table_model_->GetRenderProcessHost()) { |
| 427 // Kill the process. | 437 // Kill the process. |
| 428 TerminateProcess( | 438 base::KillProcess( |
| 429 hung_pages_table_model_->GetRenderProcessHost()->GetHandle(), | 439 hung_pages_table_model_->GetRenderProcessHost()->GetHandle(), |
| 430 content::RESULT_CODE_HUNG); | 440 content::RESULT_CODE_HUNG, false); |
| 431 } | |
| 432 } | 441 } |
| 433 } | 442 } |
| 434 | 443 |
| 435 /////////////////////////////////////////////////////////////////////////////// | 444 /////////////////////////////////////////////////////////////////////////////// |
| 436 // HungRendererDialogView, HungPagesTableModel::Delegate overrides: | 445 // HungRendererDialogView, HungPagesTableModel::Delegate overrides: |
| 437 | 446 |
| 438 void HungRendererDialogView::TabDestroyed() { | 447 void HungRendererDialogView::TabDestroyed() { |
| 439 GetWidget()->Close(); | 448 GetWidget()->Close(); |
| 440 } | 449 } |
| 441 | 450 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 460 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER)); | 469 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER)); |
| 461 info_label_->SetMultiLine(true); | 470 info_label_->SetMultiLine(true); |
| 462 info_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | 471 info_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 463 | 472 |
| 464 hung_pages_table_model_.reset(new HungPagesTableModel(this)); | 473 hung_pages_table_model_.reset(new HungPagesTableModel(this)); |
| 465 std::vector<ui::TableColumn> columns; | 474 std::vector<ui::TableColumn> columns; |
| 466 columns.push_back(ui::TableColumn()); | 475 columns.push_back(ui::TableColumn()); |
| 467 hung_pages_table_ = new views::GroupTableView( | 476 hung_pages_table_ = new views::GroupTableView( |
| 468 hung_pages_table_model_.get(), columns, views::ICON_AND_TEXT, true, | 477 hung_pages_table_model_.get(), columns, views::ICON_AND_TEXT, true, |
| 469 false, true, false); | 478 false, true, false); |
| 470 hung_pages_table_->SetPreferredSize( | |
| 471 gfx::Size(kTableViewWidth, kTableViewHeight)); | |
| 472 | 479 |
| 473 CreateKillButtonView(); | 480 CreateKillButtonView(); |
| 474 | 481 |
| 475 using views::GridLayout; | 482 using views::GridLayout; |
| 476 using views::ColumnSet; | 483 using views::ColumnSet; |
| 477 | 484 |
| 478 GridLayout* layout = GridLayout::CreatePanel(this); | 485 GridLayout* layout = GridLayout::CreatePanel(this); |
| 479 SetLayoutManager(layout); | 486 SetLayoutManager(layout); |
| 480 | 487 |
| 481 const int double_column_set_id = 0; | 488 const int double_column_set_id = 0; |
| 482 ColumnSet* column_set = layout->AddColumnSet(double_column_set_id); | 489 ColumnSet* column_set = layout->AddColumnSet(double_column_set_id); |
| 483 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, | 490 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, |
| 484 GridLayout::FIXED, frozen_icon_->width(), 0); | 491 GridLayout::FIXED, frozen_icon_->width(), 0); |
| 485 column_set->AddPaddingColumn( | 492 column_set->AddPaddingColumn( |
| 486 0, views::kUnrelatedControlLargeHorizontalSpacing); | 493 0, views::kUnrelatedControlLargeHorizontalSpacing); |
| 487 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | 494 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
| 488 GridLayout::USE_PREF, 0, 0); | 495 GridLayout::USE_PREF, 0, 0); |
| 489 | 496 |
| 490 layout->StartRow(0, double_column_set_id); | 497 layout->StartRow(0, double_column_set_id); |
| 491 layout->AddView(frozen_icon_view_, 1, 3); | 498 layout->AddView(frozen_icon_view_, 1, 3); |
| 492 layout->AddView(info_label_); | 499 layout->AddView(info_label_); |
| 493 | 500 |
| 494 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | 501 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); |
| 495 | 502 |
| 496 layout->StartRow(0, double_column_set_id); | 503 layout->StartRow(0, double_column_set_id); |
| 497 layout->SkipColumns(1); | 504 layout->SkipColumns(1); |
| 498 layout->AddView(hung_pages_table_); | 505 layout->AddView(hung_pages_table_->CreateParentIfNecessary(), 1, 1, |
| 506 views::GridLayout::FILL, |
| 507 views::GridLayout::FILL, kTableViewWidth, kTableViewHeight); |
| 499 | 508 |
| 500 initialized_ = true; | 509 initialized_ = true; |
| 501 } | 510 } |
| 502 | 511 |
| 503 void HungRendererDialogView::CreateKillButtonView() { | 512 void HungRendererDialogView::CreateKillButtonView() { |
| 504 kill_button_ = new views::NativeTextButton(this, UTF16ToWide( | 513 kill_button_ = new views::NativeTextButton(this, |
| 505 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END))); | 514 l10n_util::GetStringUTF16(IDS_BROWSER_HANGMONITOR_RENDERER_END)); |
| 506 | 515 |
| 507 kill_button_container_ = new View; | 516 kill_button_container_ = new View; |
| 508 | 517 |
| 509 using views::GridLayout; | 518 using views::GridLayout; |
| 510 using views::ColumnSet; | 519 using views::ColumnSet; |
| 511 | 520 |
| 512 GridLayout* layout = new GridLayout(kill_button_container_); | 521 GridLayout* layout = new GridLayout(kill_button_container_); |
| 513 kill_button_container_->SetLayoutManager(layout); | 522 kill_button_container_->SetLayoutManager(layout); |
| 514 | 523 |
| 515 const int single_column_set_id = 0; | 524 const int single_column_set_id = 0; |
| 516 ColumnSet* column_set = layout->AddColumnSet(single_column_set_id); | 525 ColumnSet* column_set = layout->AddColumnSet(single_column_set_id); |
| 517 column_set->AddPaddingColumn(0, frozen_icon_->width() + | 526 column_set->AddPaddingColumn(0, frozen_icon_->width() + |
| 518 views::kPanelHorizMargin + views::kUnrelatedControlHorizontalSpacing); | 527 views::kPanelHorizMargin + views::kUnrelatedControlHorizontalSpacing); |
| 519 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, | 528 column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0, |
| 520 GridLayout::USE_PREF, 0, 0); | 529 GridLayout::USE_PREF, 0, 0); |
| 521 | 530 |
| 522 layout->StartRow(0, single_column_set_id); | 531 layout->StartRow(0, single_column_set_id); |
| 523 layout->AddView(kill_button_); | 532 layout->AddView(kill_button_); |
| 524 } | 533 } |
| 525 | 534 |
| 526 gfx::Rect HungRendererDialogView::GetDisplayBounds( | 535 gfx::Rect HungRendererDialogView::GetDisplayBounds( |
| 527 WebContents* contents) { | 536 WebContents* contents) { |
| 537 #if defined(USE_AURA) |
| 538 gfx::Rect contents_bounds(contents->GetNativeView()->GetScreenBounds()); |
| 539 #elif defined(OS_WIN) |
| 528 HWND contents_hwnd = contents->GetNativeView(); | 540 HWND contents_hwnd = contents->GetNativeView(); |
| 529 RECT contents_bounds_rect; | 541 RECT contents_bounds_rect; |
| 530 GetWindowRect(contents_hwnd, &contents_bounds_rect); | 542 GetWindowRect(contents_hwnd, &contents_bounds_rect); |
| 531 gfx::Rect contents_bounds(contents_bounds_rect); | 543 gfx::Rect contents_bounds(contents_bounds_rect); |
| 544 #endif |
| 532 gfx::Rect window_bounds = GetWidget()->GetWindowScreenBounds(); | 545 gfx::Rect window_bounds = GetWidget()->GetWindowScreenBounds(); |
| 533 | 546 |
| 534 int window_x = contents_bounds.x() + | 547 int window_x = contents_bounds.x() + |
| 535 (contents_bounds.width() - window_bounds.width()) / 2; | 548 (contents_bounds.width() - window_bounds.width()) / 2; |
| 536 int window_y = contents_bounds.y() + kOverlayContentsOffsetY; | 549 int window_y = contents_bounds.y() + kOverlayContentsOffsetY; |
| 537 return gfx::Rect(window_x, window_y, window_bounds.width(), | 550 return gfx::Rect(window_x, window_y, window_bounds.width(), |
| 538 window_bounds.height()); | 551 window_bounds.height()); |
| 539 } | 552 } |
| 540 | 553 |
| 541 // static | 554 // static |
| (...skipping 21 matching lines...) Expand all Loading... |
| 563 g_instance->ShowForWebContents(contents); | 576 g_instance->ShowForWebContents(contents); |
| 564 } | 577 } |
| 565 } | 578 } |
| 566 | 579 |
| 567 void HideNativeHungRendererDialog(WebContents* contents) { | 580 void HideNativeHungRendererDialog(WebContents* contents) { |
| 568 if (!logging::DialogsAreSuppressed() && g_instance) | 581 if (!logging::DialogsAreSuppressed() && g_instance) |
| 569 g_instance->EndForWebContents(contents); | 582 g_instance->EndForWebContents(contents); |
| 570 } | 583 } |
| 571 | 584 |
| 572 } // namespace browser | 585 } // namespace browser |
| OLD | NEW |