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

Side by Side Diff: chrome/browser/ui/views/status_icons/status_tray_win.cc

Issue 110693004: Moves the notification icon out of the status area overflow. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup + address some comments Created 6 years, 8 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/status_icons/status_tray_win.h" 5 #include "chrome/browser/ui/views/status_icons/status_tray_win.h"
6 6
7 #include <commctrl.h> 7 #include <commctrl.h>
8 8
9 #include "base/bind.h"
10 #include "base/threading/thread.h"
9 #include "base/win/wrapped_window_proc.h" 11 #include "base/win/wrapped_window_proc.h"
10 #include "chrome/browser/ui/views/status_icons/status_icon_win.h" 12 #include "chrome/browser/ui/views/status_icons/status_icon_win.h"
13 #include "chrome/browser/ui/views/status_icons/status_tray_state_changer_win.h"
11 #include "chrome/common/chrome_constants.h" 14 #include "chrome/common/chrome_constants.h"
12 #include "ui/gfx/screen.h" 15 #include "ui/gfx/screen.h"
13 #include "ui/gfx/win/hwnd_util.h" 16 #include "ui/gfx/win/hwnd_util.h"
14 #include "win8/util/win8_util.h" 17 #include "win8/util/win8_util.h"
15 18
16 static const UINT kStatusIconMessage = WM_APP + 1; 19 static const UINT kStatusIconMessage = WM_APP + 1;
17 20
18 namespace { 21 namespace {
19 // |kBaseIconId| is 2 to avoid conflicts with plugins that hard-code id 1. 22 // |kBaseIconId| is 2 to avoid conflicts with plugins that hard-code id 1.
20 const UINT kBaseIconId = 2; 23 const UINT kBaseIconId = 2;
21 24
22 UINT ReservedIconId(StatusTray::StatusIconType type) { 25 UINT ReservedIconId(StatusTray::StatusIconType type) {
23 return kBaseIconId + static_cast<UINT>(type); 26 return kBaseIconId + static_cast<UINT>(type);
24 } 27 }
25 } // namespace 28 } // namespace
26 29
30 class StatusTrayStateChangerProxyImpl : public StatusTrayStateChangerProxy {
31 public:
32 StatusTrayStateChangerProxyImpl()
33 : pending_requests_(0),
34 worker_thread_("StatusIconCOMWorkerThread"),
35 weak_factory_(this) {
36 worker_thread_.init_com_with_mta(false);
37 }
38
39 virtual void EnqueueChange(UINT icon_id, HWND window) {
40 if (pending_requests_ == 0) {
41 worker_thread_.Start();
42 }
43
44 ++pending_requests_;
45 worker_thread_.message_loop_proxy()->PostTaskAndReply(
46 FROM_HERE,
47 base::Bind(
48 &StatusTrayStateChangerProxyImpl::EnqueueChangeOnWorkerThread,
49 icon_id,
50 window),
51 base::Bind(&StatusTrayStateChangerProxyImpl::ChangeDone,
52 weak_factory_.GetWeakPtr()));
53 }
54
55 private:
56 // Must be called only on |worker_thread_|, to ensure the correct COM
57 // apartment.
58 static void EnqueueChangeOnWorkerThread(UINT icon_id, HWND window) {
59 // It appears that IUnknowns are coincidentally compatible with
cpu_(ooo_6.6-7.5) 2014/04/04 18:04:16 please add a CHECK() to make sure you are in the c
dewittj 2014/04/04 21:05:51 How can you do that in a static method? I can't f
60 // scoped_refptr. Normally I wouldn't depend on that but it seems that
61 // base::win::IUnknownImpl itself depends on that coincidence so it's
62 // already being assumed elsewhere.
63 scoped_refptr<StatusTrayStateChangerWin> status_tray_state_changer(
64 new StatusTrayStateChangerWin(icon_id, window));
65 status_tray_state_changer->EnsureTrayIconVisible();
66 }
67
68 // Called on UI thread.
69 void ChangeDone() {
70 DCHECK_GT(pending_requests_, 0);
71
72 if (--pending_requests_ == 0) {
73 worker_thread_.Stop();
cpu_(ooo_6.6-7.5) 2014/04/04 18:04:16 remind me, does Stop() kill the actual native thre
dewittj 2014/04/04 21:05:51 Stop() calls QuitWhenIdle on the worker thread, an
74 }
75 }
76
77 private:
78 int pending_requests_;
79
cpu_(ooo_6.6-7.5) 2014/04/04 18:04:16 remove the spaces 79, 81 unless this is a common s
dewittj 2014/04/04 21:05:51 Done.
80 base::Thread worker_thread_;
81
82 base::WeakPtrFactory<StatusTrayStateChangerProxyImpl> weak_factory_;
83
84 DISALLOW_COPY_AND_ASSIGN(StatusTrayStateChangerProxyImpl);
85 };
86
27 StatusTrayWin::StatusTrayWin() 87 StatusTrayWin::StatusTrayWin()
28 : next_icon_id_(1), 88 : next_icon_id_(1),
29 atom_(0), 89 atom_(0),
30 instance_(NULL), 90 instance_(NULL),
31 window_(NULL) { 91 window_(NULL) {
32 // Register our window class 92 // Register our window class
33 WNDCLASSEX window_class; 93 WNDCLASSEX window_class;
34 base::win::InitializeWindowClass( 94 base::win::InitializeWindowClass(
35 chrome::kStatusTrayWindowClass, 95 chrome::kStatusTrayWindowClass,
36 &base::win::WrappedWindowProc<StatusTrayWin::WndProcStatic>, 96 &base::win::WrappedWindowProc<StatusTrayWin::WndProcStatic>,
(...skipping 10 matching lines...) Expand all
47 // Create an offscreen window for handling messages for the status icons. We 107 // Create an offscreen window for handling messages for the status icons. We
48 // create a hidden WS_POPUP window instead of an HWND_MESSAGE window, because 108 // create a hidden WS_POPUP window instead of an HWND_MESSAGE window, because
49 // only top-level windows such as popups can receive broadcast messages like 109 // only top-level windows such as popups can receive broadcast messages like
50 // "TaskbarCreated". 110 // "TaskbarCreated".
51 window_ = CreateWindow(MAKEINTATOM(atom_), 111 window_ = CreateWindow(MAKEINTATOM(atom_),
52 0, WS_POPUP, 0, 0, 0, 0, 0, 0, instance_, 0); 112 0, WS_POPUP, 0, 0, 0, 0, 0, 0, instance_, 0);
53 gfx::CheckWindowCreated(window_); 113 gfx::CheckWindowCreated(window_);
54 gfx::SetWindowUserData(window_, this); 114 gfx::SetWindowUserData(window_, this);
55 } 115 }
56 116
117 StatusTrayWin::~StatusTrayWin() {
118 if (window_)
119 DestroyWindow(window_);
120
121 if (atom_)
122 UnregisterClass(MAKEINTATOM(atom_), instance_);
123 }
124
125 void StatusTrayWin::UpdateIconVisibilityInBackground(
126 StatusIconWin* status_icon) {
127 if (!state_changer_proxy_.get()) {
128 state_changer_proxy_.reset(new StatusTrayStateChangerProxyImpl);
129 }
130
131 state_changer_proxy_->EnqueueChange(status_icon->icon_id(),
132 status_icon->window());
133 }
134
57 LRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd, 135 LRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd,
58 UINT message, 136 UINT message,
59 WPARAM wparam, 137 WPARAM wparam,
60 LPARAM lparam) { 138 LPARAM lparam) {
61 StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>( 139 StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>(
62 GetWindowLongPtr(hwnd, GWLP_USERDATA)); 140 GetWindowLongPtr(hwnd, GWLP_USERDATA));
63 if (msg_wnd) 141 if (msg_wnd)
64 return msg_wnd->WndProc(hwnd, message, wparam, lparam); 142 return msg_wnd->WndProc(hwnd, message, wparam, lparam);
65 else 143 else
66 return ::DefWindowProc(hwnd, message, wparam, lparam); 144 return ::DefWindowProc(hwnd, message, wparam, lparam);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 // HandleClickEvent() method. 188 // HandleClickEvent() method.
111 gfx::Point cursor_pos( 189 gfx::Point cursor_pos(
112 gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); 190 gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
113 win_icon->HandleClickEvent(cursor_pos, lparam == WM_LBUTTONDOWN); 191 win_icon->HandleClickEvent(cursor_pos, lparam == WM_LBUTTONDOWN);
114 return TRUE; 192 return TRUE;
115 } 193 }
116 } 194 }
117 return ::DefWindowProc(hwnd, message, wparam, lparam); 195 return ::DefWindowProc(hwnd, message, wparam, lparam);
118 } 196 }
119 197
120 StatusTrayWin::~StatusTrayWin() {
121 if (window_)
122 DestroyWindow(window_);
123
124 if (atom_)
125 UnregisterClass(MAKEINTATOM(atom_), instance_);
126 }
127
128 StatusIcon* StatusTrayWin::CreatePlatformStatusIcon( 198 StatusIcon* StatusTrayWin::CreatePlatformStatusIcon(
129 StatusTray::StatusIconType type, 199 StatusTray::StatusIconType type,
130 const gfx::ImageSkia& image, 200 const gfx::ImageSkia& image,
131 const base::string16& tool_tip) { 201 const base::string16& tool_tip) {
132 UINT next_icon_id; 202 UINT next_icon_id;
133 if (type == StatusTray::OTHER_ICON) 203 if (type == StatusTray::OTHER_ICON)
134 next_icon_id = NextIconId(); 204 next_icon_id = NextIconId();
135 else 205 else
136 next_icon_id = ReservedIconId(type); 206 next_icon_id = ReservedIconId(type);
137 207
138 StatusIcon* icon = NULL; 208 StatusIcon* icon = NULL;
139 if (win8::IsSingleWindowMetroMode()) 209 if (win8::IsSingleWindowMetroMode())
140 icon = new StatusIconMetro(next_icon_id); 210 icon = new StatusIconMetro(next_icon_id);
141 else 211 else
142 icon = new StatusIconWin(next_icon_id, window_, kStatusIconMessage); 212 icon = new StatusIconWin(this, next_icon_id, window_, kStatusIconMessage);
143 213
144 icon->SetImage(image); 214 icon->SetImage(image);
145 icon->SetToolTip(tool_tip); 215 icon->SetToolTip(tool_tip);
146 return icon; 216 return icon;
147 } 217 }
148 218
149 UINT StatusTrayWin::NextIconId() { 219 UINT StatusTrayWin::NextIconId() {
150 UINT icon_id = next_icon_id_++; 220 UINT icon_id = next_icon_id_++;
151 return kBaseIconId + static_cast<UINT>(NAMED_STATUS_ICON_COUNT) + icon_id; 221 return kBaseIconId + static_cast<UINT>(NAMED_STATUS_ICON_COUNT) + icon_id;
152 } 222 }
153 223
224 void StatusTrayWin::SetStatusTrayStateChangerProxyForTest(
225 scoped_ptr<StatusTrayStateChangerProxy> proxy) {
226 state_changer_proxy_ = proxy.Pass();
227 }
228
154 StatusTray* StatusTray::Create() { 229 StatusTray* StatusTray::Create() {
155 return new StatusTrayWin(); 230 return new StatusTrayWin();
156 } 231 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698