task_manager_view.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/task_manager/task_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/stats_table.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/memory_purger.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/pref_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/scoped_user_pref_update.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/browser_dialogs.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accelerators/accelerator.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/table_model_observer.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/background.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/context_menu_controller.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/text_button.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link_listener.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/table/group_table_model.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/table/group_table_view.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/table/table_view_observer.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/layout_constants.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/window/dialog_delegate.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/metro.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The task manager window default size.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDefaultWidth = 460;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDefaultHeight = 270;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Yellow highlight used when highlighting background resources.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const SkColor kBackgroundResourceHighlight =
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xff, 0xf1, 0xcd);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TaskManagerTableModel class
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TaskManagerTableModel : public views::GroupTableModel,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              public TaskManagerModelObserver {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TaskManagerTableModel(TaskManagerModel* model)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : model_(model),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        observer_(NULL) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model_->AddObserver(this);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~TaskManagerTableModel() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model_->RemoveObserver(this);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GroupTableModel.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int RowCount() OVERRIDE;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 GetText(int row, int column) OVERRIDE;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia GetIcon(int row) OVERRIDE;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GetGroupRangeForItem(int item, views::GroupRange* range) OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetObserver(ui::TableModelObserver* observer) OVERRIDE;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int CompareValues(int row1, int row2, int column_id) OVERRIDE;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TaskManagerModelObserver.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnModelChanged();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnItemsChanged(int start, int length);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnItemsAdded(int start, int length);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnItemsRemoved(int start, int length);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if resource corresponding to |row| is a background resource.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsBackgroundResource(int row);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TaskManagerModel* model_;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::TableModelObserver* observer_;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerTableModel::RowCount() {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return model_->ResourceCount();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerTableModel::GetText(int row, int col_id) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (col_id) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_TASK_COLUMN:  // Process
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceTitle(row);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_PROFILE_NAME_COLUMN:  // Profile Name
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceProfileName(row);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_NET_COLUMN:  // Net
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceNetworkUsage(row);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_CPU_COLUMN:  // CPU
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceCPUUsage(row);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN:  // Memory
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourcePrivateMemory(row);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_SHARED_MEM_COLUMN:  // Memory
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceSharedMemory(row);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN:  // Memory
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourcePhysicalMemory(row);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceProcessId(row);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN:  // Goats Teleported!
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceGoatsTeleported(row);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceWebCoreImageCacheSize(row);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceWebCoreScriptsCacheSize(row);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN:
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceWebCoreCSSCacheSize(row);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_FPS_COLUMN:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceFPS(row);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceVideoMemory(row);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN:
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceSqliteMemoryUsed(row);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!model_->IsResourceFirstInGroup(row))
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return string16();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return model_->GetResourceV8MemoryAllocatedSize(row);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return string16();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia TaskManagerTableModel::GetIcon(int row) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return model_->GetResourceIcon(row);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerTableModel::GetGroupRangeForItem(int item,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 views::GroupRange* range) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TaskManagerModel::GroupRange range_pair =
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_->GetGroupRangeForResource(item);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  range->start = range_pair.first;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  range->length = range_pair.second;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerTableModel::SetObserver(ui::TableModelObserver* observer) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_ = observer;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerTableModel::CompareValues(int row1, int row2, int column_id) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return model_->CompareValues(row1, row2, column_id);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerTableModel::OnModelChanged() {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnModelChanged();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerTableModel::OnItemsChanged(int start, int length) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnItemsChanged(start, length);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerTableModel::OnItemsAdded(int start, int length) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnItemsAdded(start, length);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There's a bug in the Windows ListView where inserting items with groups
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enabled puts them in the wrong position, so we will need to rebuild the
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // list view in this case.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (see: http://connect.microsoft.com/VisualStudio/feedback/details/115345/).
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Turns out, forcing a list view rebuild causes http://crbug.com/69391
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because items are added to the ListView one-at-a-time when initially
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // displaying the TaskManager, resulting in many ListView rebuilds. So we are
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no longer forcing a rebuild for now because the current UI doesn't use
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // groups - if we are going to add groups in the upcoming TaskManager UI
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // revamp, we'll need to re-enable this call to OnModelChanged() and also add
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // code to avoid doing multiple rebuilds on startup (maybe just generate a
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // single OnModelChanged() call after the initial population).
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OnModelChanged();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerTableModel::OnItemsRemoved(int start, int length) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnItemsRemoved(start, length);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We may need to change the indentation of some items if the topmost item
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the group was removed, so update the view.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnModelChanged();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManagerTableModel::IsBackgroundResource(int row) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return model_->IsBackgroundResource(row);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Thin wrapper around GroupTableView to enable setting the background
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// resource highlight color.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BackgroundColorGroupTableView : public views::GroupTableView {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackgroundColorGroupTableView(TaskManagerTableModel* model,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::vector<ui::TableColumn>& columns,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bool highlight_background_resources)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : views::GroupTableView(model, columns, views::ICON_AND_TEXT,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              false, true, true, true),
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        model_(model) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetCustomColorsEnabled(highlight_background_resources);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~BackgroundColorGroupTableView() {}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetCellColors(int model_row,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int column,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ItemColor* foreground,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ItemColor* background,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             LOGFONT* logfont) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!model_->IsBackgroundResource(model_row))
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Render background resources with a yellow highlight.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    background->color_is_set = true;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    background->color = kBackgroundResourceHighlight;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foreground->color_is_set = false;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TaskManagerTableModel* model_;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Task manager UI container.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TaskManagerView : public views::ButtonListener,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        public views::DialogDelegateView,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        public views::TableViewObserver,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        public views::LinkListener,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        public views::ContextMenuController,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        public views::Menu::Delegate {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TaskManagerView(bool highlight_background_resources);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TaskManagerView();
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shows the Task manager window, or re-activates an existing one. If
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |highlight_background_resources| is true, highlights the background
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resources in the resource display.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Show(bool highlight_background_resources);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::View:
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Layout() OVERRIDE;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() OVERRIDE;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ViewHierarchyChanged(bool is_add, views::View* parent,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    views::View* child) OVERRIDE;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::ButtonListener:
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ButtonPressed(views::Button* sender,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const ui::Event& event) OVERRIDE;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::DialogDelegateView:
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanResize() const OVERRIDE;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanMaximize() const OVERRIDE;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ExecuteWindowsCommand(int command_id) OVERRIDE;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual string16 GetWindowTitle() const OVERRIDE;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual std::string GetWindowName() const OVERRIDE;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetDialogButtons() const OVERRIDE;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WindowClosing() OVERRIDE;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual views::View* GetContentsView() OVERRIDE;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::TableViewObserver:
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSelectionChanged() OVERRIDE;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnDoubleClick() OVERRIDE;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnKeyDown(ui::KeyboardCode keycode) OVERRIDE;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::LinkListener:
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by the column picker to pick up any new stat counters that
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // may have appeared since last time.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateStatsCounters();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::ContextMenuController:
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowContextMenuForView(views::View* source,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const gfx::Point& point) OVERRIDE;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::Menu::Delegate:
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsItemChecked(int id) const OVERRIDE;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ExecuteCommand(int id) OVERRIDE;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates the child controls.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init();
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the state of the always-on-top setting as the window is shown.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitAlwaysOnTopState();
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Activates the tab associated with the focused row.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ActivateFocusedTab();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds an always on top item to the window's system menu.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddAlwaysOnTopSystemMenuItem();
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restores saved always on top state from a previous session.
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetSavedAlwaysOnTopState(bool* always_on_top) const;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::TextButton* purge_memory_button_;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::TextButton* kill_button_;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Link* about_memory_link_;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::GroupTableView* tab_table_;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TaskManager* task_manager_;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TaskManagerModel* model_;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all possible columns, not necessarily visible
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ui::TableColumn> columns_;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TaskManagerTableModel> table_model_;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True when the Task Manager window should be shown on top of other windows.
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_always_on_top_;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True when the Task Manager should highlight background resources.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool highlight_background_resources_;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need to own the text of the menu, the Windows API does not copy it.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 always_on_top_menu_text_;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An open Task manager window. There can only be one open at a time. This
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is reset to NULL when the window is closed.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TaskManagerView* instance_;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TaskManagerView);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManagerView* TaskManagerView::instance_ = NULL;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManagerView::TaskManagerView(bool highlight_background_resources)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : purge_memory_button_(NULL),
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      task_manager_(TaskManager::GetInstance()),
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model_(TaskManager::GetInstance()->model()),
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_always_on_top_(false),
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      highlight_background_resources_(highlight_background_resources) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Init();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TaskManagerView::~TaskManagerView() {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete child views now, while our table model still exists.
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveAllChildViews(true);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::Init() {
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  table_model_.reset(new TaskManagerTableModel(model_));
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Page column has no header label.
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_TASK_COLUMN,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::LEFT, -1, 1));
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_PROFILE_NAME_COLUMN,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::LEFT, -1, 0));
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_SHARED_MEM_COLUMN,
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_CPU_COLUMN,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_NET_COLUMN,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_PROCESS_ID_COLUMN,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::TableColumn::RIGHT, -1, 0));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::TableColumn::RIGHT, -1, 0));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_FPS_COLUMN,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN,
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ui::TableColumn::RIGHT, -1, 0));
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.push_back(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::TableColumn(IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      ui::TableColumn::RIGHT, -1, 0));
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  columns_.back().sortable = true;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_ = new BackgroundColorGroupTableView(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      table_model_.get(), columns_, highlight_background_resources_);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hide some columns by default
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_PROFILE_NAME_COLUMN, false);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_PROCESS_ID_COLUMN, false);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_SHARED_MEM_COLUMN, false);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN, false);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  false);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  false);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  false);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  false);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  false);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN, false);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN,
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  false);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateStatsCounters();
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetObserver(this);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->set_context_menu_controller(this);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_context_menu_controller(this);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we're running with --purge-memory-button, add a "Purge memory" button.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kPurgeMemoryButton)) {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    purge_memory_button_ = new views::NativeTextButton(this,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_TASK_MANAGER_PURGE_MEMORY));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kill_button_ = new views::NativeTextButton(
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, l10n_util::GetStringUTF16(IDS_TASK_MANAGER_KILL));
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kill_button_->AddAccelerator(ui::Accelerator(ui::VKEY_E, ui::EF_NONE));
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kill_button_->SetAccessibleKeyboardShortcut(L"E");
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kill_button_->set_prefix_type(views::TextButtonBase::PREFIX_SHOW);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  about_memory_link_ = new views::Link(
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_TASK_MANAGER_ABOUT_MEMORY_LINK));
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  about_memory_link_->set_listener(this);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes sure our state is consistent.
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnSelectionChanged();
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::UpdateStatsCounters() {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::StatsTable* stats = base::StatsTable::current();
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stats != NULL) {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max = stats->GetMaxCounters();
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // skip the first row (it's header data)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 1; i < max; i++) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char* row = stats->GetRowName(i);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (row != NULL && row[0] != '\0' && !tab_table_->HasColumn(i)) {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // TODO(erikkay): Use l10n to get display names for stats.  Right
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // now we're just displaying the internal counter name.  Perhaps
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // stat names not in the string table would be filtered out.
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // TODO(erikkay): Width is hard-coded right now, so many column
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // names are clipped.
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ui::TableColumn col(i, ASCIIToUTF16(row), ui::TableColumn::RIGHT, 90,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            0);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        col.sortable = true;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        columns_.push_back(col);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tab_table_->AddColumn(col);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::ViewHierarchyChanged(bool is_add,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           views::View* parent,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           views::View* child) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we want the Kill button and the Memory Details link to show up in
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the same visual row as the close button, which is provided by the
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // framework, we must add the buttons to the non-client view, which is the
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parent of this view. Similarly, when we're removed from the view
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hierarchy, we must take care to clean up those items as well.
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (child == this) {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_add) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent->AddChildView(about_memory_link_);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (purge_memory_button_)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        parent->AddChildView(purge_memory_button_);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent->AddChildView(kill_button_);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddChildView(tab_table_);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent->RemoveChildView(kill_button_);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (purge_memory_button_)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        parent->RemoveChildView(purge_memory_button_);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent->RemoveChildView(about_memory_link_);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::Layout() {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::kPanelHorizMargin is too big.
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kTableButtonSpacing = 12;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size size = kill_button_->GetPreferredSize();
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int prefered_width = size.width();
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int prefered_height = size.height();
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetBounds(
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      x() + views::kPanelHorizMargin,
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y() + views::kPanelVertMargin,
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width() - 2 * views::kPanelHorizMargin,
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height() - 2 * views::kPanelVertMargin - prefered_height);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // y-coordinate of button top left.
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect parent_bounds = parent()->GetContentsBounds();
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int y_buttons =
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent_bounds.bottom() - prefered_height - views::kButtonVEdgeMargin;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kill_button_->SetBounds(
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      x() + width() - prefered_width - views::kPanelHorizMargin,
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y_buttons,
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefered_width,
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefered_height);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (purge_memory_button_) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size = purge_memory_button_->GetPreferredSize();
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    purge_memory_button_->SetBounds(
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kill_button_->x() - size.width() -
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            views::kUnrelatedControlHorizontalSpacing,
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        y_buttons, size.width(), size.height());
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = about_memory_link_->GetPreferredSize();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int link_prefered_width = size.width();
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int link_prefered_height = size.height();
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // center between the two buttons horizontally, and line up with
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bottom of buttons vertically.
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int link_y_offset = std::max(0, prefered_height - link_prefered_height) / 2;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  about_memory_link_->SetBounds(
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      x() + views::kPanelHorizMargin,
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y_buttons + prefered_height - link_prefered_height - link_y_offset,
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      link_prefered_width,
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      link_prefered_height);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size TaskManagerView::GetPreferredSize() {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(kDefaultWidth, kDefaultHeight);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::Show(bool highlight_background_resources) {
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In Windows Metro it's not good to open this native window.
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!base::win::IsMetroProcess());
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (instance_) {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (instance_->highlight_background_resources_ !=
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        highlight_background_resources) {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->GetWidget()->Close();
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If there's a Task manager window open already, just activate it.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->GetWidget()->Activate();
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_ = new TaskManagerView(highlight_background_resources);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget::CreateWindow(instance_);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_->InitAlwaysOnTopState();
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_->model_->StartUpdating();
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instance_->GetWidget()->Show();
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the initial focus to the list of tasks.
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::FocusManager* focus_manager = instance_->GetFocusManager();
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (focus_manager)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    focus_manager->SetFocusedView(instance_->tab_table_);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ButtonListener implementation.
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::ButtonPressed(
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::Button* sender, const ui::Event& event) {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (purge_memory_button_ && (sender == purge_memory_button_)) {
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MemoryPurger::PurgeAll();
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(kill_button_, sender);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (views::TableSelectionIterator iter  = tab_table_->SelectionBegin();
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         iter != tab_table_->SelectionEnd(); ++iter)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      task_manager_->KillProcess(*iter);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DialogDelegate implementation.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManagerView::CanResize() const {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManagerView::CanMaximize() const {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManagerView::ExecuteWindowsCommand(int command_id) {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_id == IDC_ALWAYS_ON_TOP) {
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_always_on_top_ = !is_always_on_top_;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Change the menu check state.
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HMENU system_menu = GetSystemMenu(GetWidget()->GetNativeWindow(), FALSE);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MENUITEMINFO menu_info;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(&menu_info, 0, sizeof(MENUITEMINFO));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    menu_info.cbSize = sizeof(MENUITEMINFO);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BOOL r = GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP,
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             FALSE, &menu_info);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(r);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    menu_info.fMask = MIIM_STATE;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_always_on_top_)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      menu_info.fState = MFS_CHECKED;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    r = SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now change the actual window's behavior.
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetWidget()->SetAlwaysOnTop(is_always_on_top_);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save the state.
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (g_browser_process->local_state()) {
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DictionaryPrefUpdate update(g_browser_process->local_state(),
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  GetWindowName().c_str());
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DictionaryValue* window_preferences = update.Get();
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_preferences->SetBoolean("always_on_top", is_always_on_top_);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 TaskManagerView::GetWindowTitle() const {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_TITLE);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TaskManagerView::GetWindowName() const {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return prefs::kTaskManagerWindowPlacement;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TaskManagerView::GetDialogButtons() const {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui::DIALOG_BUTTON_NONE;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::WindowClosing() {
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the window is closed, we can allow a new one to be opened.
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (WindowClosing comes in asynchronously from the call to Close() and we
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // may have already opened a new instance).
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (instance_ == this)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instance_ = NULL;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_manager_->OnWindowClosed();
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* TaskManagerView::GetContentsView() {
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// views::TableViewObserver implementation.
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::OnSelectionChanged() {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool selection_contains_browser_process = false;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (views::TableSelectionIterator iter  = tab_table_->SelectionBegin();
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != tab_table_->SelectionEnd(); ++iter) {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (task_manager_->IsBrowserProcess(*iter)) {
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      selection_contains_browser_process = true;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kill_button_->SetEnabled(!selection_contains_browser_process &&
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           tab_table_->SelectedRowCount() > 0);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::OnDoubleClick() {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ActivateFocusedTab();
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::OnKeyDown(ui::KeyboardCode keycode) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (keycode == ui::VKEY_RETURN)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ActivateFocusedTab();
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::LinkClicked(views::Link* source, int event_flags) {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(about_memory_link_, source);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_manager_->OpenAboutMemory();
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::ShowContextMenuForView(views::View* source,
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const gfx::Point& point) {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateStatsCounters();
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<views::Menu> menu(views::Menu::Create(
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, views::Menu::TOPLEFT, source->GetWidget()->GetNativeView()));
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<ui::TableColumn>::iterator i(columns_.begin());
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != columns_.end(); ++i) {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    menu->AppendMenuItem(i->id, l10n_util::GetStringUTF16(i->id),
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        views::Menu::CHECKBOX);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu->RunMenuAt(point.x(), point.y());
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManagerView::IsItemChecked(int id) const {
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return tab_table_->IsColumnVisible(id);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::ExecuteCommand(int id) {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_table_->SetColumnVisibility(id, !tab_table_->IsColumnVisible(id));
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::InitAlwaysOnTopState() {
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_always_on_top_ = false;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetSavedAlwaysOnTopState(&is_always_on_top_))
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetWidget()->SetAlwaysOnTop(is_always_on_top_);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAlwaysOnTopSystemMenuItem();
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::ActivateFocusedTab() {
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int row_count = tab_table_->RowCount();
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < row_count; ++i) {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tab_table_->ItemHasTheFocus(i)) {
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      task_manager_->ActivateProcess(i);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TaskManagerView::AddAlwaysOnTopSystemMenuItem() {
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The Win32 API requires that we own the text.
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  always_on_top_menu_text_ = l10n_util::GetStringUTF16(IDS_ALWAYS_ON_TOP);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's insert a menu to the window.
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HMENU system_menu = ::GetSystemMenu(GetWidget()->GetNativeWindow(), FALSE);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int index = ::GetMenuItemCount(system_menu) - 1;
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index < 0) {
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Paranoia check.
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    index = 0;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First we add the separator.
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MENUITEMINFO menu_info;
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&menu_info, 0, sizeof(MENUITEMINFO));
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_info.cbSize = sizeof(MENUITEMINFO);
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_info.fMask = MIIM_FTYPE;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_info.fType = MFT_SEPARATOR;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::InsertMenuItem(system_menu, index, TRUE, &menu_info);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then the actual menu.
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_STATE;
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_info.fType = MFT_STRING;
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_info.fState = MFS_ENABLED;
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_always_on_top_)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    menu_info.fState |= MFS_CHECKED;
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_info.wID = IDC_ALWAYS_ON_TOP;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_info.dwTypeData = const_cast<wchar_t*>(always_on_top_menu_text_.c_str());
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::InsertMenuItem(system_menu, index, TRUE, &menu_info);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TaskManagerView::GetSavedAlwaysOnTopState(bool* always_on_top) const {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_browser_process->local_state())
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DictionaryValue* dictionary =
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g_browser_process->local_state()->GetDictionary(GetWindowName().c_str());
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dictionary &&
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dictionary->GetBoolean("always_on_top", always_on_top) && always_on_top;
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Declared in browser_dialogs.h so others don't need to depend on our header.
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowTaskManager() {
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TaskManagerView::Show(false);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowBackgroundPages() {
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TaskManagerView::Show(true);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
817