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

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

Issue 252513004: Reland r265807: "Moves the notification icon out of th..." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Disable tray size test on Vista since it won't have any effect on a new icon. 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/non_thread_safe.h"
11 #include "base/threading/thread.h"
9 #include "base/win/wrapped_window_proc.h" 12 #include "base/win/wrapped_window_proc.h"
10 #include "chrome/browser/ui/views/status_icons/status_icon_win.h" 13 #include "chrome/browser/ui/views/status_icons/status_icon_win.h"
14 #include "chrome/browser/ui/views/status_icons/status_tray_state_changer_win.h"
11 #include "chrome/common/chrome_constants.h" 15 #include "chrome/common/chrome_constants.h"
12 #include "ui/gfx/screen.h" 16 #include "ui/gfx/screen.h"
13 #include "ui/gfx/win/hwnd_util.h" 17 #include "ui/gfx/win/hwnd_util.h"
14 18
15 static const UINT kStatusIconMessage = WM_APP + 1; 19 static const UINT kStatusIconMessage = WM_APP + 1;
16 20
17 namespace { 21 namespace {
18 // |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.
19 const UINT kBaseIconId = 2; 23 const UINT kBaseIconId = 2;
20 24
21 UINT ReservedIconId(StatusTray::StatusIconType type) { 25 UINT ReservedIconId(StatusTray::StatusIconType type) {
22 return kBaseIconId + static_cast<UINT>(type); 26 return kBaseIconId + static_cast<UINT>(type);
23 } 27 }
24 } // namespace 28 } // namespace
25 29
30 // Default implementation for StatusTrayStateChanger that communicates to
31 // Exporer.exe via COM. It spawns a background thread with a fresh COM
32 // apartment and requests that the visibility be increased unless the user
33 // has explicitly set the icon to be hidden.
34 class StatusTrayStateChangerProxyImpl : public StatusTrayStateChangerProxy,
35 public base::NonThreadSafe {
36 public:
37 StatusTrayStateChangerProxyImpl()
38 : pending_requests_(0),
39 worker_thread_("StatusIconCOMWorkerThread"),
40 weak_factory_(this) {
41 worker_thread_.init_com_with_mta(false);
42 }
43
44 virtual void EnqueueChange(UINT icon_id, HWND window) OVERRIDE {
45 DCHECK(CalledOnValidThread());
46 if (pending_requests_ == 0)
47 worker_thread_.Start();
48
49 ++pending_requests_;
50 worker_thread_.message_loop_proxy()->PostTaskAndReply(
51 FROM_HERE,
52 base::Bind(
53 &StatusTrayStateChangerProxyImpl::EnqueueChangeOnWorkerThread,
54 icon_id,
55 window),
56 base::Bind(&StatusTrayStateChangerProxyImpl::ChangeDone,
57 weak_factory_.GetWeakPtr()));
58 }
59
60 private:
61 // Must be called only on |worker_thread_|, to ensure the correct COM
62 // apartment.
63 static void EnqueueChangeOnWorkerThread(UINT icon_id, HWND window) {
64 // It appears that IUnknowns are coincidentally compatible with
65 // scoped_refptr. Normally I wouldn't depend on that but it seems that
66 // base::win::IUnknownImpl itself depends on that coincidence so it's
67 // already being assumed elsewhere.
68 scoped_refptr<StatusTrayStateChangerWin> status_tray_state_changer(
69 new StatusTrayStateChangerWin(icon_id, window));
70 status_tray_state_changer->EnsureTrayIconVisible();
71 }
72
73 // Called on UI thread.
74 void ChangeDone() {
75 DCHECK(CalledOnValidThread());
76 DCHECK_GT(pending_requests_, 0);
77
78 if (--pending_requests_ == 0)
79 worker_thread_.Stop();
80 }
81
82 private:
83 int pending_requests_;
84 base::Thread worker_thread_;
85 base::WeakPtrFactory<StatusTrayStateChangerProxyImpl> weak_factory_;
86
87 DISALLOW_COPY_AND_ASSIGN(StatusTrayStateChangerProxyImpl);
88 };
89
26 StatusTrayWin::StatusTrayWin() 90 StatusTrayWin::StatusTrayWin()
27 : next_icon_id_(1), 91 : next_icon_id_(1),
28 atom_(0), 92 atom_(0),
29 instance_(NULL), 93 instance_(NULL),
30 window_(NULL) { 94 window_(NULL) {
31 // Register our window class 95 // Register our window class
32 WNDCLASSEX window_class; 96 WNDCLASSEX window_class;
33 base::win::InitializeWindowClass( 97 base::win::InitializeWindowClass(
34 chrome::kStatusTrayWindowClass, 98 chrome::kStatusTrayWindowClass,
35 &base::win::WrappedWindowProc<StatusTrayWin::WndProcStatic>, 99 &base::win::WrappedWindowProc<StatusTrayWin::WndProcStatic>,
(...skipping 10 matching lines...) Expand all
46 // Create an offscreen window for handling messages for the status icons. We 110 // Create an offscreen window for handling messages for the status icons. We
47 // create a hidden WS_POPUP window instead of an HWND_MESSAGE window, because 111 // create a hidden WS_POPUP window instead of an HWND_MESSAGE window, because
48 // only top-level windows such as popups can receive broadcast messages like 112 // only top-level windows such as popups can receive broadcast messages like
49 // "TaskbarCreated". 113 // "TaskbarCreated".
50 window_ = CreateWindow(MAKEINTATOM(atom_), 114 window_ = CreateWindow(MAKEINTATOM(atom_),
51 0, WS_POPUP, 0, 0, 0, 0, 0, 0, instance_, 0); 115 0, WS_POPUP, 0, 0, 0, 0, 0, 0, instance_, 0);
52 gfx::CheckWindowCreated(window_); 116 gfx::CheckWindowCreated(window_);
53 gfx::SetWindowUserData(window_, this); 117 gfx::SetWindowUserData(window_, this);
54 } 118 }
55 119
120 StatusTrayWin::~StatusTrayWin() {
121 if (window_)
122 DestroyWindow(window_);
123
124 if (atom_)
125 UnregisterClass(MAKEINTATOM(atom_), instance_);
126 }
127
128 void StatusTrayWin::UpdateIconVisibilityInBackground(
129 StatusIconWin* status_icon) {
130 if (!state_changer_proxy_.get())
131 state_changer_proxy_.reset(new StatusTrayStateChangerProxyImpl);
132
133 state_changer_proxy_->EnqueueChange(status_icon->icon_id(),
134 status_icon->window());
135 }
136
56 LRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd, 137 LRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd,
57 UINT message, 138 UINT message,
58 WPARAM wparam, 139 WPARAM wparam,
59 LPARAM lparam) { 140 LPARAM lparam) {
60 StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>( 141 StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>(
61 GetWindowLongPtr(hwnd, GWLP_USERDATA)); 142 GetWindowLongPtr(hwnd, GWLP_USERDATA));
62 if (msg_wnd) 143 if (msg_wnd)
63 return msg_wnd->WndProc(hwnd, message, wparam, lparam); 144 return msg_wnd->WndProc(hwnd, message, wparam, lparam);
64 else 145 else
65 return ::DefWindowProc(hwnd, message, wparam, lparam); 146 return ::DefWindowProc(hwnd, message, wparam, lparam);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 // HandleClickEvent() method. 190 // HandleClickEvent() method.
110 gfx::Point cursor_pos( 191 gfx::Point cursor_pos(
111 gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); 192 gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
112 win_icon->HandleClickEvent(cursor_pos, lparam == WM_LBUTTONDOWN); 193 win_icon->HandleClickEvent(cursor_pos, lparam == WM_LBUTTONDOWN);
113 return TRUE; 194 return TRUE;
114 } 195 }
115 } 196 }
116 return ::DefWindowProc(hwnd, message, wparam, lparam); 197 return ::DefWindowProc(hwnd, message, wparam, lparam);
117 } 198 }
118 199
119 StatusTrayWin::~StatusTrayWin() {
120 if (window_)
121 DestroyWindow(window_);
122
123 if (atom_)
124 UnregisterClass(MAKEINTATOM(atom_), instance_);
125 }
126
127 StatusIcon* StatusTrayWin::CreatePlatformStatusIcon( 200 StatusIcon* StatusTrayWin::CreatePlatformStatusIcon(
128 StatusTray::StatusIconType type, 201 StatusTray::StatusIconType type,
129 const gfx::ImageSkia& image, 202 const gfx::ImageSkia& image,
130 const base::string16& tool_tip) { 203 const base::string16& tool_tip) {
131 UINT next_icon_id; 204 UINT next_icon_id;
132 if (type == StatusTray::OTHER_ICON) 205 if (type == StatusTray::OTHER_ICON)
133 next_icon_id = NextIconId(); 206 next_icon_id = NextIconId();
134 else 207 else
135 next_icon_id = ReservedIconId(type); 208 next_icon_id = ReservedIconId(type);
136 209
137 StatusIcon* icon = 210 StatusIcon* icon =
138 new StatusIconWin(next_icon_id, window_, kStatusIconMessage); 211 new StatusIconWin(this, next_icon_id, window_, kStatusIconMessage);
139 212
140 icon->SetImage(image); 213 icon->SetImage(image);
141 icon->SetToolTip(tool_tip); 214 icon->SetToolTip(tool_tip);
142 return icon; 215 return icon;
143 } 216 }
144 217
145 UINT StatusTrayWin::NextIconId() { 218 UINT StatusTrayWin::NextIconId() {
146 UINT icon_id = next_icon_id_++; 219 UINT icon_id = next_icon_id_++;
147 return kBaseIconId + static_cast<UINT>(NAMED_STATUS_ICON_COUNT) + icon_id; 220 return kBaseIconId + static_cast<UINT>(NAMED_STATUS_ICON_COUNT) + icon_id;
148 } 221 }
149 222
223 void StatusTrayWin::SetStatusTrayStateChangerProxyForTest(
224 scoped_ptr<StatusTrayStateChangerProxy> proxy) {
225 state_changer_proxy_ = proxy.Pass();
226 }
227
150 StatusTray* StatusTray::Create() { 228 StatusTray* StatusTray::Create() {
151 return new StatusTrayWin(); 229 return new StatusTrayWin();
152 } 230 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698