Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: chrome/browser/task_manager_win.cc

Issue 140044: Reorganize the way the task manager is constructed.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/task_manager_unittest.cc ('k') | chrome/browser/views/browser_dialogs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/task_manager.h"
6
7 #include "app/l10n_util.h"
8 #include "app/table_model_observer.h"
9 #include "base/stats_table.h"
10 #include "chrome/app/chrome_dll_resource.h"
11 #include "chrome/browser/browser_list.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/browser_window.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/common/pref_service.h"
16 #include "grit/chromium_strings.h"
17 #include "grit/generated_resources.h"
18 #include "grit/theme_resources.h"
19 #include "views/accelerator.h"
20 #include "views/background.h"
21 #include "views/controls/button/native_button.h"
22 #include "views/controls/link.h"
23 #include "views/controls/menu/menu.h"
24 #include "views/controls/table/group_table_view.h"
25 #include "views/controls/table/table_view_observer.h"
26 #include "views/standard_layout.h"
27 #include "views/widget/widget.h"
28 #include "views/window/dialog_delegate.h"
29 #include "views/window/window.h"
30
31 // The task manager window default size.
32 static const int kDefaultWidth = 460;
33 static const int kDefaultHeight = 270;
34
35 // An id for the most important column, made sufficiently large so as not to
36 // collide with anything else.
37 static const int64 kNuthMagicNumber = 1737350766;
38 static const int kBitMask = 0x7FFFFFFF;
39 static const int kGoatsTeleportedColumn =
40 (94024 * kNuthMagicNumber) & kBitMask;
41
42 namespace {
43
44 ////////////////////////////////////////////////////////////////////////////////
45 // TaskManagerTableModel class
46 ////////////////////////////////////////////////////////////////////////////////
47
48 class TaskManagerTableModel : public views::GroupTableModel,
49 public TaskManagerModelObserver {
50 public:
51 explicit TaskManagerTableModel(TaskManagerModel* model)
52 : model_(model),
53 observer_(NULL) {
54 model->SetObserver(this);
55 }
56 ~TaskManagerTableModel() {}
57
58 // GroupTableModel.
59 int RowCount();
60 std::wstring GetText(int row, int column);
61 SkBitmap GetIcon(int row);
62 void GetGroupRangeForItem(int item, views::GroupRange* range);
63 void SetObserver(TableModelObserver* observer);
64 virtual int CompareValues(int row1, int row2, int column_id);
65
66 // TaskManagerModelObserver.
67 virtual void OnModelChanged();
68 virtual void OnItemsChanged(int start, int length);
69 virtual void OnItemsAdded(int start, int length);
70 virtual void OnItemsRemoved(int start, int length);
71
72 private:
73 const TaskManagerModel* model_;
74 TableModelObserver* observer_;
75 };
76
77 int TaskManagerTableModel::RowCount() {
78 return model_->ResourceCount();
79 }
80
81 std::wstring TaskManagerTableModel::GetText(int row, int col_id) {
82 switch (col_id) {
83 case IDS_TASK_MANAGER_PAGE_COLUMN: // Process
84 return model_->GetResourceTitle(row);
85
86 case IDS_TASK_MANAGER_NET_COLUMN: // Net
87 return model_->GetResourceNetworkUsage(row);
88
89 case IDS_TASK_MANAGER_CPU_COLUMN: // CPU
90 if (!model_->IsResourceFirstInGroup(row))
91 return std::wstring();
92 return model_->GetResourceCPUUsage(row);
93
94 case IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN: // Memory
95 if (!model_->IsResourceFirstInGroup(row))
96 return std::wstring();
97 return model_->GetResourcePrivateMemory(row);
98
99 case IDS_TASK_MANAGER_SHARED_MEM_COLUMN: // Memory
100 if (!model_->IsResourceFirstInGroup(row))
101 return std::wstring();
102 return model_->GetResourceSharedMemory(row);
103
104 case IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN: // Memory
105 if (!model_->IsResourceFirstInGroup(row))
106 return std::wstring();
107 return model_->GetResourcePhysicalMemory(row);
108
109 case IDS_TASK_MANAGER_PROCESS_ID_COLUMN:
110 if (!model_->IsResourceFirstInGroup(row))
111 return std::wstring();
112 return model_->GetResourceProcessId(row);
113
114 case kGoatsTeleportedColumn: // Goats Teleported!
115 return model_->GetResourceGoatsTeleported(row);
116
117 default:
118 return model_->GetResourceStatsValue(row, col_id);
119 }
120 }
121
122 SkBitmap TaskManagerTableModel::GetIcon(int row) {
123 return model_->GetResourceIcon(row);
124 }
125
126 void TaskManagerTableModel::GetGroupRangeForItem(int item,
127 views::GroupRange* range) {
128 std::pair<int, int> range_pair = model_->GetGroupRangeForResource(item);
129 range->start = range_pair.first;
130 range->length = range_pair.second;
131 }
132
133 void TaskManagerTableModel::SetObserver(TableModelObserver* observer) {
134 observer_ = observer;
135 }
136
137 int TaskManagerTableModel::CompareValues(int row1, int row2, int column_id) {
138 return model_->CompareValues(row1, row2, column_id);
139 }
140
141 void TaskManagerTableModel::OnModelChanged() {
142 if (observer_)
143 observer_->OnModelChanged();
144 }
145
146 void TaskManagerTableModel::OnItemsChanged(int start, int length) {
147 if (observer_)
148 observer_->OnItemsChanged(start, length);
149 }
150
151 void TaskManagerTableModel::OnItemsAdded(int start, int length) {
152 if (observer_)
153 observer_->OnItemsAdded(start, length);
154 }
155
156 void TaskManagerTableModel::OnItemsRemoved(int start, int length) {
157 if (observer_)
158 observer_->OnItemsRemoved(start, length);
159 }
160
161 ////////////////////////////////////////////////////////////////////////////////
162 // TaskManagerViewImpl class
163 //
164 // The view containing the different widgets.
165 //
166 ////////////////////////////////////////////////////////////////////////////////
167
168 class TaskManagerViewImpl : public TaskManagerView,
169 public views::View,
170 public views::ButtonListener,
171 public views::DialogDelegate,
172 public views::TableViewObserver,
173 public views::LinkController,
174 public views::ContextMenuController,
175 public views::Menu::Delegate {
176 public:
177 TaskManagerViewImpl(TaskManager* task_manager,
178 TaskManagerModel* model);
179 virtual ~TaskManagerViewImpl();
180
181 void Init();
182 virtual void Layout();
183 virtual gfx::Size GetPreferredSize();
184 virtual void ViewHierarchyChanged(bool is_add, views::View* parent,
185 views::View* child);
186
187 // TaskManagerView
188 virtual void GetSelection(std::vector<int>* selection);
189 virtual void GetFocused(std::vector<int>* focused);
190 virtual void OpenWindow();
191 virtual void ActivateWindow();
192 virtual void CloseWindow();
193
194 // ButtonListener implementation.
195 virtual void ButtonPressed(views::Button* sender);
196
197 // views::DialogDelegate
198 virtual bool CanResize() const;
199 virtual bool CanMaximize() const;
200 virtual bool ExecuteWindowsCommand(int command_id);
201 virtual std::wstring GetWindowTitle() const;
202 virtual std::wstring GetWindowName() const;
203 virtual int GetDialogButtons() const;
204 virtual void WindowClosing();
205 virtual void DeleteDelegate();
206 virtual views::View* GetContentsView();
207
208 // views::TableViewObserver implementation.
209 virtual void OnSelectionChanged();
210 virtual void OnDoubleClick();
211 virtual void OnKeyDown(unsigned short virtual_keycode);
212
213 // views::LinkController implementation.
214 virtual void LinkActivated(views::Link* source, int event_flags);
215
216 // Called by the column picker to pick up any new stat counters that
217 // may have appeared since last time.
218 void UpdateStatsCounters();
219
220 // Menu::Delegate
221 virtual void ShowContextMenu(views::View* source,
222 int x,
223 int y,
224 bool is_mouse_gesture);
225 virtual bool IsItemChecked(int id) const;
226 virtual void ExecuteCommand(int id);
227
228 private:
229 // Initializes the state of the always-on-top setting as the window is shown.
230 void InitAlwaysOnTopState();
231
232 // Adds an always on top item to the window's system menu.
233 void AddAlwaysOnTopSystemMenuItem();
234
235 // Restores saved always on top state from a previous session.
236 bool GetSavedAlwaysOnTopState(bool* always_on_top) const;
237
238 views::NativeButton* kill_button_;
239 views::Link* about_memory_link_;
240 views::GroupTableView* tab_table_;
241
242 TaskManager* task_manager_;
243
244 TaskManagerModel* model_;
245
246 // all possible columns, not necessarily visible
247 std::vector<TableColumn> columns_;
248
249 scoped_ptr<TaskManagerTableModel> table_model_;
250
251 // True when the Task Manager window should be shown on top of other windows.
252 bool is_always_on_top_;
253
254 // We need to own the text of the menu, the Windows API does not copy it.
255 std::wstring always_on_top_menu_text_;
256
257 DISALLOW_COPY_AND_ASSIGN(TaskManagerViewImpl);
258 };
259
260 TaskManagerViewImpl::TaskManagerViewImpl(TaskManager* task_manager,
261 TaskManagerModel* model)
262 : task_manager_(task_manager),
263 model_(model),
264 is_always_on_top_(false) {
265 Init();
266 }
267
268 TaskManagerViewImpl::~TaskManagerViewImpl() {
269 // Delete child views now, while our table model still exists.
270 RemoveAllChildViews(true);
271
272 // Prevent the table from accessing the model as part of its destruction, as
273 // the model might already be destroyed.
274 tab_table_->SetModel(NULL);
275 }
276
277 void TaskManagerViewImpl::Init() {
278 table_model_.reset(new TaskManagerTableModel(model_));
279
280 columns_.push_back(TableColumn(IDS_TASK_MANAGER_PAGE_COLUMN,
281 TableColumn::LEFT, -1, 1));
282 columns_.back().sortable = true;
283 columns_.push_back(TableColumn(IDS_TASK_MANAGER_PHYSICAL_MEM_COLUMN,
284 TableColumn::RIGHT, -1, 0));
285 columns_.back().sortable = true;
286 columns_.push_back(TableColumn(IDS_TASK_MANAGER_SHARED_MEM_COLUMN,
287 TableColumn::RIGHT, -1, 0));
288 columns_.back().sortable = true;
289 columns_.push_back(TableColumn(IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN,
290 TableColumn::RIGHT, -1, 0));
291 columns_.back().sortable = true;
292 columns_.push_back(TableColumn(IDS_TASK_MANAGER_CPU_COLUMN,
293 TableColumn::RIGHT, -1, 0));
294 columns_.back().sortable = true;
295 columns_.push_back(TableColumn(IDS_TASK_MANAGER_NET_COLUMN,
296 TableColumn::RIGHT, -1, 0));
297 columns_.back().sortable = true;
298 columns_.push_back(TableColumn(IDS_TASK_MANAGER_PROCESS_ID_COLUMN,
299 TableColumn::RIGHT, -1, 0));
300 columns_.back().sortable = true;
301
302 tab_table_ = new views::GroupTableView(table_model_.get(), columns_,
303 views::ICON_AND_TEXT, false, true,
304 true);
305 tab_table_->SetParentOwned(false);
306
307 // Hide some columns by default
308 tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_PROCESS_ID_COLUMN, false);
309 tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_SHARED_MEM_COLUMN, false);
310 tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_PRIVATE_MEM_COLUMN, false);
311
312 UpdateStatsCounters();
313 TableColumn col(kGoatsTeleportedColumn, L"Goats Teleported",
314 TableColumn::RIGHT, -1, 0);
315 col.sortable = true;
316 columns_.push_back(col);
317 tab_table_->AddColumn(col);
318 tab_table_->SetObserver(this);
319 SetContextMenuController(this);
320 kill_button_ = new views::NativeButton(
321 this, l10n_util::GetString(IDS_TASK_MANAGER_KILL));
322 kill_button_->AddAccelerator(views::Accelerator('E', false, false, false));
323 kill_button_->SetAccessibleKeyboardShortcut(L"E");
324 about_memory_link_ = new views::Link(
325 l10n_util::GetString(IDS_TASK_MANAGER_ABOUT_MEMORY_LINK));
326 about_memory_link_->SetController(this);
327
328 // Makes sure our state is consistent.
329 OnSelectionChanged();
330 }
331
332 void TaskManagerViewImpl::UpdateStatsCounters() {
333 StatsTable* stats = StatsTable::current();
334 if (stats != NULL) {
335 int max = stats->GetMaxCounters();
336 // skip the first row (it's header data)
337 for (int i = 1; i < max; i++) {
338 const char* row = stats->GetRowName(i);
339 if (row != NULL && row[0] != '\0' && !tab_table_->HasColumn(i)) {
340 // TODO(erikkay): Use l10n to get display names for stats. Right
341 // now we're just displaying the internal counter name. Perhaps
342 // stat names not in the string table would be filtered out.
343 // TODO(erikkay): Width is hard-coded right now, so many column
344 // names are clipped.
345 TableColumn col(i, ASCIIToWide(row), TableColumn::RIGHT, 90, 0);
346 col.sortable = true;
347 columns_.push_back(col);
348 tab_table_->AddColumn(col);
349 }
350 }
351 }
352 }
353
354 void TaskManagerViewImpl::ViewHierarchyChanged(bool is_add,
355 views::View* parent,
356 views::View* child) {
357 // Since we want the Kill button and the Memory Details link to show up in
358 // the same visual row as the close button, which is provided by the
359 // framework, we must add the buttons to the non-client view, which is the
360 // parent of this view. Similarly, when we're removed from the view
361 // hierarchy, we must take care to clean up those items as well.
362 if (child == this) {
363 if (is_add) {
364 parent->AddChildView(kill_button_);
365 parent->AddChildView(about_memory_link_);
366 AddChildView(tab_table_);
367 } else {
368 parent->RemoveChildView(kill_button_);
369 parent->RemoveChildView(about_memory_link_);
370 }
371 }
372 }
373
374 void TaskManagerViewImpl::Layout() {
375 // kPanelHorizMargin is too big.
376 const int kTableButtonSpacing = 12;
377
378 gfx::Size size = kill_button_->GetPreferredSize();
379 int prefered_width = size.width();
380 int prefered_height = size.height();
381
382 tab_table_->SetBounds(x() + kPanelHorizMargin,
383 y() + kPanelVertMargin,
384 width() - 2 * kPanelHorizMargin,
385 height() - 2 * kPanelVertMargin - prefered_height);
386
387 // y-coordinate of button top left.
388 gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false);
389 int y_buttons = parent_bounds.bottom() - prefered_height - kButtonVEdgeMargin;
390
391 kill_button_->SetBounds(x() + width() - prefered_width - kPanelHorizMargin,
392 y_buttons,
393 prefered_width,
394 prefered_height);
395
396 size = about_memory_link_->GetPreferredSize();
397 int link_prefered_width = size.width();
398 int link_prefered_height = size.height();
399 // center between the two buttons horizontally, and line up with
400 // bottom of buttons vertically.
401 int link_y_offset = std::max(0, prefered_height - link_prefered_height) / 2;
402 about_memory_link_->SetBounds(
403 x() + kPanelHorizMargin,
404 y_buttons + prefered_height - link_prefered_height - link_y_offset,
405 link_prefered_width,
406 link_prefered_height);
407 }
408
409 gfx::Size TaskManagerViewImpl::GetPreferredSize() {
410 return gfx::Size(kDefaultWidth, kDefaultHeight);
411 }
412
413 void TaskManagerViewImpl::GetSelection(std::vector<int>* selection) {
414 DCHECK(selection);
415 for (views::TableSelectionIterator iter = tab_table_->SelectionBegin();
416 iter != tab_table_->SelectionEnd(); ++iter) {
417 // The TableView returns the selection starting from the end.
418 selection->insert(selection->begin(), *iter);
419 }
420 }
421
422 void TaskManagerViewImpl::GetFocused(std::vector<int>* focused) {
423 DCHECK(focused);
424 int row_count = tab_table_->RowCount();
425 for (int i = 0; i < row_count; ++i) {
426 // The TableView returns the selection starting from the end.
427 if (tab_table_->ItemHasTheFocus(i))
428 focused->insert(focused->begin(), i);
429 }
430 }
431
432 void TaskManagerViewImpl::OpenWindow() {
433 DCHECK(!window());
434 views::Window::CreateChromeWindow(NULL, gfx::Rect(), this);
435 InitAlwaysOnTopState();
436 model_->StartUpdating();
437 window()->Show();
438 }
439
440 void TaskManagerViewImpl::ActivateWindow() {
441 DCHECK(window());
442 window()->Activate();
443 }
444
445 void TaskManagerViewImpl::CloseWindow() {
446 if (!window())
447 return;
448 // TODO(phajdan.jr): Destroy the window, not just hide it.
449 window()->HideWindow();
450 }
451
452 // ButtonListener implementation.
453 void TaskManagerViewImpl::ButtonPressed(views::Button* sender) {
454 if (sender == kill_button_)
455 task_manager_->KillSelectedProcesses();
456 }
457
458 // DialogDelegate implementation.
459 bool TaskManagerViewImpl::CanResize() const {
460 return true;
461 }
462
463 bool TaskManagerViewImpl::CanMaximize() const {
464 return true;
465 }
466
467 bool TaskManagerViewImpl::ExecuteWindowsCommand(int command_id) {
468 if (command_id == IDC_ALWAYS_ON_TOP) {
469 is_always_on_top_ = !is_always_on_top_;
470
471 // Change the menu check state.
472 HMENU system_menu = GetSystemMenu(GetWindow()->GetNativeWindow(), FALSE);
473 MENUITEMINFO menu_info;
474 memset(&menu_info, 0, sizeof(MENUITEMINFO));
475 menu_info.cbSize = sizeof(MENUITEMINFO);
476 BOOL r = GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP,
477 FALSE, &menu_info);
478 DCHECK(r);
479 menu_info.fMask = MIIM_STATE;
480 if (is_always_on_top_)
481 menu_info.fState = MFS_CHECKED;
482 r = SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info);
483
484 // Now change the actual window's behavior.
485 window()->SetIsAlwaysOnTop(is_always_on_top_);
486
487 // Save the state.
488 if (g_browser_process->local_state()) {
489 DictionaryValue* window_preferences =
490 g_browser_process->local_state()->GetMutableDictionary(
491 GetWindowName().c_str());
492 window_preferences->SetBoolean(L"always_on_top", is_always_on_top_);
493 }
494 return true;
495 }
496 return false;
497 }
498
499 std::wstring TaskManagerViewImpl::GetWindowTitle() const {
500 return l10n_util::GetString(IDS_TASK_MANAGER_TITLE);
501 }
502
503 std::wstring TaskManagerViewImpl::GetWindowName() const {
504 return prefs::kTaskManagerWindowPlacement;
505 }
506
507 int TaskManagerViewImpl::GetDialogButtons() const {
508 return MessageBoxFlags::DIALOGBUTTON_NONE;
509 }
510
511 void TaskManagerViewImpl::WindowClosing() {
512 task_manager_->OnWindowClosed();
513 }
514
515 void TaskManagerViewImpl::DeleteDelegate() {
516 ReleaseWindow();
517 }
518
519 views::View* TaskManagerViewImpl::GetContentsView() {
520 return this;
521 }
522
523 // views::TableViewObserver implementation.
524 void TaskManagerViewImpl::OnSelectionChanged() {
525 kill_button_->SetEnabled(!task_manager_->BrowserProcessIsSelected() &&
526 tab_table_->SelectedRowCount() > 0);
527 }
528
529 void TaskManagerViewImpl::OnDoubleClick() {
530 task_manager_->ActivateFocusedTab();
531 }
532
533 void TaskManagerViewImpl::OnKeyDown(unsigned short virtual_keycode) {
534 if (virtual_keycode == VK_RETURN)
535 task_manager_->ActivateFocusedTab();
536 }
537
538 // views::LinkController implementation
539 void TaskManagerViewImpl::LinkActivated(views::Link* source,
540 int event_flags) {
541 DCHECK(source == about_memory_link_);
542 Browser* browser = BrowserList::GetLastActive();
543 DCHECK(browser);
544 browser->OpenURL(GURL("about:memory"), GURL(), NEW_FOREGROUND_TAB,
545 PageTransition::LINK);
546 // In case the browser window is minimzed, show it. If this is an application
547 // or popup, we can only have one tab, hence we need to process this in a
548 // tabbed browser window. Currently, |browser| is pointing to the application,
549 // popup window. Therefore, we have to retrieve the last active tab again,
550 // since a new window has been used.
551 if (browser->type() & Browser::TYPE_APP_POPUP) {
552 browser = BrowserList::GetLastActive();
553 DCHECK(browser);
554 }
555 browser->window()->Show();
556 }
557
558 void TaskManagerViewImpl::ShowContextMenu(views::View* source,
559 int x,
560 int y,
561 bool is_mouse_gesture) {
562 UpdateStatsCounters();
563 scoped_ptr<views::Menu> menu(views::Menu::Create(
564 this, views::Menu::TOPLEFT, source->GetWidget()->GetNativeView()));
565 for (std::vector<TableColumn>::iterator i =
566 columns_.begin(); i != columns_.end(); ++i) {
567 menu->AppendMenuItem(i->id, i->title, views::Menu::CHECKBOX);
568 }
569 menu->RunMenuAt(x, y);
570 }
571
572 bool TaskManagerViewImpl::IsItemChecked(int id) const {
573 return tab_table_->IsColumnVisible(id);
574 }
575
576 void TaskManagerViewImpl::ExecuteCommand(int id) {
577 tab_table_->SetColumnVisibility(id, !tab_table_->IsColumnVisible(id));
578 }
579
580 void TaskManagerViewImpl::InitAlwaysOnTopState() {
581 is_always_on_top_ = false;
582 if (GetSavedAlwaysOnTopState(&is_always_on_top_))
583 window()->SetIsAlwaysOnTop(is_always_on_top_);
584 AddAlwaysOnTopSystemMenuItem();
585 }
586
587 void TaskManagerViewImpl::AddAlwaysOnTopSystemMenuItem() {
588 // The Win32 API requires that we own the text.
589 always_on_top_menu_text_ = l10n_util::GetString(IDS_ALWAYS_ON_TOP);
590
591 // Let's insert a menu to the window.
592 HMENU system_menu = ::GetSystemMenu(GetWindow()->GetNativeWindow(), FALSE);
593 int index = ::GetMenuItemCount(system_menu) - 1;
594 if (index < 0) {
595 // Paranoia check.
596 NOTREACHED();
597 index = 0;
598 }
599 // First we add the separator.
600 MENUITEMINFO menu_info;
601 memset(&menu_info, 0, sizeof(MENUITEMINFO));
602 menu_info.cbSize = sizeof(MENUITEMINFO);
603 menu_info.fMask = MIIM_FTYPE;
604 menu_info.fType = MFT_SEPARATOR;
605 ::InsertMenuItem(system_menu, index, TRUE, &menu_info);
606
607 // Then the actual menu.
608 menu_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_STATE;
609 menu_info.fType = MFT_STRING;
610 menu_info.fState = MFS_ENABLED;
611 if (is_always_on_top_)
612 menu_info.fState |= MFS_CHECKED;
613 menu_info.wID = IDC_ALWAYS_ON_TOP;
614 menu_info.dwTypeData = const_cast<wchar_t*>(always_on_top_menu_text_.c_str());
615 ::InsertMenuItem(system_menu, index, TRUE, &menu_info);
616 }
617
618 bool TaskManagerViewImpl::GetSavedAlwaysOnTopState(bool* always_on_top) const {
619 if (!g_browser_process->local_state())
620 return false;
621
622 const DictionaryValue* dictionary =
623 g_browser_process->local_state()->GetDictionary(GetWindowName().c_str());
624 return dictionary &&
625 dictionary->GetBoolean(L"always_on_top", always_on_top) && always_on_top;
626 }
627
628 } // namespace
629
630 void TaskManager::CreateView() {
631 DCHECK(!view_);
632 view_ = new TaskManagerViewImpl(this, model_.get());
633 }
OLDNEW
« no previous file with comments | « chrome/browser/task_manager_unittest.cc ('k') | chrome/browser/views/browser_dialogs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698