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

Side by Side Diff: chrome/browser/ui/panels/auto_hiding_desktop_bar_win.cc

Issue 7646003: Support auto-hide taskbar for panels on Windows. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/ui/panels/auto_hiding_desktop_bar.h"
6
7 #include <shellapi.h>
8 #include <windows.h>
9
10 #include "base/compiler_specific.h"
11 #include "base/logging.h"
12 #include "base/timer.h"
13 #include "ui/gfx/rect.h"
14 #include "views/widget/monitor_win.h"
15
16 namespace {
17
18 // Maximum number of taskbars we're interested in: bottom, left, and right.
19 const int kMaxTaskbars = 3;
20
21 // The thickness of the area of an auto-hiding taskbar that is still visible
22 // when the taskbar becomes hidden.
23 const int kAutoHideTaskbarThickness = 2;
jennb 2011/08/26 20:41:57 kHiddenAutoHideTaskbarThickness? kAutoHideTaskbarT
jianli 2011/08/26 22:18:52 Done.
24
25 // The polling interval to check auto-hiding taskbars.
26 const int kCheckTaskbarPollingIntervalMs = 500;
27
28 struct Taskbar {
29 HWND window;
30 AutoHidingDesktopBar::Visibility visibility;
31 int thickness;
32 };
33
34 class AutoHidingDesktopBarWin : public AutoHidingDesktopBar {
35 public:
36 explicit AutoHidingDesktopBarWin(Observer* observer);
37 virtual ~AutoHidingDesktopBarWin();
38
39 // Overridden from AutoHidingDesktopBar:
40 virtual void UpdateWorkArea(const gfx::Rect& work_area) OVERRIDE;
41 virtual bool IsEnabled(Alignment alignment) OVERRIDE;
42 virtual int GetThickness(Alignment alignment) const OVERRIDE;
43 virtual Visibility GetVisibility(Alignment alignment) const OVERRIDE;
44
45 private:
46 // Callback to perform periodic check for taskbar changes.
47 void OnPollingTimer();
48
49 // Returns true if there is at least one auto-hiding taskbar found.
50 bool CheckTaskbars(bool notify_observer);
51
52 gfx::Rect GetBounds(Alignment alignment) const;
53 int GetThicknessFromBounds(
54 Alignment alignment, const gfx::Rect& bounds) const;
55 Visibility GetVisibilityFromBounds(
56 Alignment alignment, const gfx::Rect& bounds) const;
57
58 Observer* observer_;
59 gfx::Rect work_area_;
60 HMONITOR monitor_;
61 Taskbar taskbars_[kMaxTaskbars];
62 base::RepeatingTimer<AutoHidingDesktopBarWin> polling_timer_;
63
64 DISALLOW_COPY_AND_ASSIGN(AutoHidingDesktopBarWin);
65 };
66
67 AutoHidingDesktopBarWin::AutoHidingDesktopBarWin(Observer* observer)
68 : observer_(observer) {
69 DCHECK(observer);
70 memset(taskbars_, 0, sizeof(taskbars_));
71 }
72
73 AutoHidingDesktopBarWin::~AutoHidingDesktopBarWin() {
74 }
75
76 void AutoHidingDesktopBarWin::UpdateWorkArea(const gfx::Rect& work_area) {
77 if (work_area_ == work_area)
78 return;
79 work_area_ = work_area;
80
81 RECT rect = work_area_.ToRECT();
82 monitor_ = ::MonitorFromRect(&rect, MONITOR_DEFAULTTOPRIMARY);
83 DCHECK(monitor_);
84
85 bool exists_taskbar = CheckTaskbars(false);
jennb 2011/08/26 20:41:57 s/exists_taskbar/taskbar_exists ?
jianli 2011/08/26 22:18:52 Done.
86
87 // If not any auto-hiding taskbar exists, we do not need to start the polling
jennb 2011/08/26 20:41:57 s/not any/no
jianli 2011/08/26 22:18:52 Done.
88 // timer. If a taskbar is then set to auto-hiding, UpdateWorkArea will be
89 // called due to the work area change.
90 if (exists_taskbar) {
91 if (!polling_timer_.IsRunning()) {
92 polling_timer_.Start(
93 base::TimeDelta::FromMilliseconds(kCheckTaskbarPollingIntervalMs),
94 this,
95 &AutoHidingDesktopBarWin::OnPollingTimer);
96 }
97 } else {
98 if (polling_timer_.IsRunning())
99 polling_timer_.Stop();
100 }
101 }
102
103 bool AutoHidingDesktopBarWin::IsEnabled(
104 AutoHidingDesktopBar::Alignment alignment) {
105 CheckTaskbars(false);
106 return taskbars_[static_cast<int>(alignment)].window != NULL;
107 }
108
109 int AutoHidingDesktopBarWin::GetThickness(
110 AutoHidingDesktopBar::Alignment alignment) const {
111 return GetThicknessFromBounds(alignment, GetBounds(alignment));
112 }
113
114 AutoHidingDesktopBar::Visibility AutoHidingDesktopBarWin::GetVisibility(
115 AutoHidingDesktopBar::Alignment alignment) const {
116 return GetVisibilityFromBounds(alignment, GetBounds(alignment));
117 }
118
119 gfx::Rect AutoHidingDesktopBarWin::GetBounds(
120 AutoHidingDesktopBar::Alignment alignment) const {
121 HWND taskbar_window = taskbars_[static_cast<int>(alignment)].window;
122 if (!taskbar_window)
123 return gfx::Rect();
124
125 RECT rect;
126 if (!::GetWindowRect(taskbar_window, &rect))
127 return gfx::Rect();
128 return gfx::Rect(rect);
129 }
130
131 int AutoHidingDesktopBarWin::GetThicknessFromBounds(
132 AutoHidingDesktopBar::Alignment alignment, const gfx::Rect& bounds) const {
133 switch (alignment) {
134 case AutoHidingDesktopBar::ALIGN_BOTTOM:
135 return bounds.height();
136 case AutoHidingDesktopBar::ALIGN_LEFT:
137 case AutoHidingDesktopBar::ALIGN_RIGHT:
138 return bounds.width();
139 default:
140 NOTREACHED();
141 return 0;
142 }
143 }
144
145 AutoHidingDesktopBar::Visibility
146 AutoHidingDesktopBarWin::GetVisibilityFromBounds(
jennb 2011/08/26 20:41:57 Can you write a unittest that just tests this one
jianli 2011/08/26 22:18:52 Done.
147 AutoHidingDesktopBar::Alignment alignment, const gfx::Rect& bounds) const {
jennb 2011/08/26 20:41:57 Might help to rename bounds to taskbar_bounds. I k
jianli 2011/08/26 22:18:52 Done.
148 switch (alignment) {
149 case AutoHidingDesktopBar::ALIGN_BOTTOM:
150 if (bounds.bottom() <= work_area_.bottom())
151 return VISIBLE;
152 else if (bounds.y() > work_area_.bottom() - kAutoHideTaskbarThickness)
jennb 2011/08/26 20:41:57 Should be >= ?
jianli 2011/08/26 22:18:52 Done.
153 return HIDDEN;
154 else
155 return ANIMATING;
156
157 case AutoHidingDesktopBar::ALIGN_LEFT:
158 if (bounds.x() >= work_area_.x())
159 return VISIBLE;
160 else if (bounds.x() > work_area_.x() + kAutoHideTaskbarThickness)
jennb 2011/08/26 20:41:57 Should this be bounds.right() <= work_area_.x() +
jianli 2011/08/26 22:18:52 Done.
161 return HIDDEN;
162 else
163 return ANIMATING;
164
165 case AutoHidingDesktopBar::ALIGN_RIGHT:
166 if (bounds.right() <= work_area_.right())
167 return VISIBLE;
168 else if (bounds.x() > work_area_.right() - kAutoHideTaskbarThickness)
jennb 2011/08/26 20:41:57 Should be >= ?
jianli 2011/08/26 22:18:52 Done.
169 return HIDDEN;
170 else
171 return ANIMATING;
172
173 default:
174 NOTREACHED();
175 return VISIBLE;
176 }
177 }
178
179 void AutoHidingDesktopBarWin::OnPollingTimer() {
180 CheckTaskbars(true);
181 }
182
183 bool AutoHidingDesktopBarWin::CheckTaskbars(bool notify_observer) {
184 bool exists_taskbar = false;
jennb 2011/08/26 20:41:57 s/exists_taskbar/taskbar_exists
jianli 2011/08/26 22:18:52 Done.
185 UINT edges[] = { ABE_BOTTOM, ABE_LEFT, ABE_RIGHT };
186 for (size_t i = 0; i < kMaxTaskbars; ++i) {
187 taskbars_[i].window =
188 views::GetTopmostAutoHideTaskbarForEdge(edges[i], monitor_);
189 if (taskbars_[i].window)
190 exists_taskbar = true;
191 }
192 if (!exists_taskbar) {
jennb 2011/08/26 20:41:57 Maybe we should skip this if-clause and let the co
jianli 2011/08/26 22:18:52 As mentioned above, this is taken care of by work
193 for (size_t i = 0; i < kMaxTaskbars; ++i) {
194 taskbars_[i].thickness = 0;
195 taskbars_[i].visibility = AutoHidingDesktopBar::HIDDEN;
196 }
197 return false;
198 }
199
200 bool thickness_changed = false;
201 for (size_t i = 0; i < kMaxTaskbars; ++i) {
202 AutoHidingDesktopBar::Alignment alignment = static_cast<Alignment>(i);
203
204 gfx::Rect bounds = GetBounds(alignment);
205
206 // Check the thickness change.
207 int thickness = GetThicknessFromBounds(alignment, bounds);
208 if (thickness != taskbars_[i].thickness) {
209 taskbars_[i].thickness = thickness;
210 thickness_changed = true;
211 }
212
213 // Check and notify the visibility change.
214 AutoHidingDesktopBar::Visibility visibility =
215 GetVisibilityFromBounds(alignment, bounds);
216 if (visibility != taskbars_[i].visibility) {
217 taskbars_[i].visibility = visibility;
218 if (notify_observer) {
219 observer_->OnAutoHidingDesktopBarVisibilityChanged(alignment,
220 visibility);
221 }
222 }
223 }
224
225 // Notify the thickness change if needed.
226 if (thickness_changed && notify_observer)
227 observer_->OnAutoHidingDesktopBarThicknessChanged();
228
229 return true;
230 }
231
232 } // namespace
233
234 // static
235 AutoHidingDesktopBar* AutoHidingDesktopBar::Create(Observer* observer) {
236 return new AutoHidingDesktopBarWin(observer);
237 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698