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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/panels/auto_hiding_desktop_bar_win.cc
===================================================================
--- chrome/browser/ui/panels/auto_hiding_desktop_bar_win.cc (revision 0)
+++ chrome/browser/ui/panels/auto_hiding_desktop_bar_win.cc (revision 0)
@@ -0,0 +1,237 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/panels/auto_hiding_desktop_bar.h"
+
+#include <shellapi.h>
+#include <windows.h>
+
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/timer.h"
+#include "ui/gfx/rect.h"
+#include "views/widget/monitor_win.h"
+
+namespace {
+
+// Maximum number of taskbars we're interested in: bottom, left, and right.
+const int kMaxTaskbars = 3;
+
+// The thickness of the area of an auto-hiding taskbar that is still visible
+// when the taskbar becomes hidden.
+const int kAutoHideTaskbarThickness = 2;
jennb 2011/08/26 20:41:57 kHiddenAutoHideTaskbarThickness? kAutoHideTaskbarT
jianli 2011/08/26 22:18:52 Done.
+
+// The polling interval to check auto-hiding taskbars.
+const int kCheckTaskbarPollingIntervalMs = 500;
+
+struct Taskbar {
+ HWND window;
+ AutoHidingDesktopBar::Visibility visibility;
+ int thickness;
+};
+
+class AutoHidingDesktopBarWin : public AutoHidingDesktopBar {
+ public:
+ explicit AutoHidingDesktopBarWin(Observer* observer);
+ virtual ~AutoHidingDesktopBarWin();
+
+ // Overridden from AutoHidingDesktopBar:
+ virtual void UpdateWorkArea(const gfx::Rect& work_area) OVERRIDE;
+ virtual bool IsEnabled(Alignment alignment) OVERRIDE;
+ virtual int GetThickness(Alignment alignment) const OVERRIDE;
+ virtual Visibility GetVisibility(Alignment alignment) const OVERRIDE;
+
+ private:
+ // Callback to perform periodic check for taskbar changes.
+ void OnPollingTimer();
+
+ // Returns true if there is at least one auto-hiding taskbar found.
+ bool CheckTaskbars(bool notify_observer);
+
+ gfx::Rect GetBounds(Alignment alignment) const;
+ int GetThicknessFromBounds(
+ Alignment alignment, const gfx::Rect& bounds) const;
+ Visibility GetVisibilityFromBounds(
+ Alignment alignment, const gfx::Rect& bounds) const;
+
+ Observer* observer_;
+ gfx::Rect work_area_;
+ HMONITOR monitor_;
+ Taskbar taskbars_[kMaxTaskbars];
+ base::RepeatingTimer<AutoHidingDesktopBarWin> polling_timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutoHidingDesktopBarWin);
+};
+
+AutoHidingDesktopBarWin::AutoHidingDesktopBarWin(Observer* observer)
+ : observer_(observer) {
+ DCHECK(observer);
+ memset(taskbars_, 0, sizeof(taskbars_));
+}
+
+AutoHidingDesktopBarWin::~AutoHidingDesktopBarWin() {
+}
+
+void AutoHidingDesktopBarWin::UpdateWorkArea(const gfx::Rect& work_area) {
+ if (work_area_ == work_area)
+ return;
+ work_area_ = work_area;
+
+ RECT rect = work_area_.ToRECT();
+ monitor_ = ::MonitorFromRect(&rect, MONITOR_DEFAULTTOPRIMARY);
+ DCHECK(monitor_);
+
+ 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.
+
+ // 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.
+ // timer. If a taskbar is then set to auto-hiding, UpdateWorkArea will be
+ // called due to the work area change.
+ if (exists_taskbar) {
+ if (!polling_timer_.IsRunning()) {
+ polling_timer_.Start(
+ base::TimeDelta::FromMilliseconds(kCheckTaskbarPollingIntervalMs),
+ this,
+ &AutoHidingDesktopBarWin::OnPollingTimer);
+ }
+ } else {
+ if (polling_timer_.IsRunning())
+ polling_timer_.Stop();
+ }
+}
+
+bool AutoHidingDesktopBarWin::IsEnabled(
+ AutoHidingDesktopBar::Alignment alignment) {
+ CheckTaskbars(false);
+ return taskbars_[static_cast<int>(alignment)].window != NULL;
+}
+
+int AutoHidingDesktopBarWin::GetThickness(
+ AutoHidingDesktopBar::Alignment alignment) const {
+ return GetThicknessFromBounds(alignment, GetBounds(alignment));
+}
+
+AutoHidingDesktopBar::Visibility AutoHidingDesktopBarWin::GetVisibility(
+ AutoHidingDesktopBar::Alignment alignment) const {
+ return GetVisibilityFromBounds(alignment, GetBounds(alignment));
+}
+
+gfx::Rect AutoHidingDesktopBarWin::GetBounds(
+ AutoHidingDesktopBar::Alignment alignment) const {
+ HWND taskbar_window = taskbars_[static_cast<int>(alignment)].window;
+ if (!taskbar_window)
+ return gfx::Rect();
+
+ RECT rect;
+ if (!::GetWindowRect(taskbar_window, &rect))
+ return gfx::Rect();
+ return gfx::Rect(rect);
+}
+
+int AutoHidingDesktopBarWin::GetThicknessFromBounds(
+ AutoHidingDesktopBar::Alignment alignment, const gfx::Rect& bounds) const {
+ switch (alignment) {
+ case AutoHidingDesktopBar::ALIGN_BOTTOM:
+ return bounds.height();
+ case AutoHidingDesktopBar::ALIGN_LEFT:
+ case AutoHidingDesktopBar::ALIGN_RIGHT:
+ return bounds.width();
+ default:
+ NOTREACHED();
+ return 0;
+ }
+}
+
+AutoHidingDesktopBar::Visibility
+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.
+ 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.
+ switch (alignment) {
+ case AutoHidingDesktopBar::ALIGN_BOTTOM:
+ if (bounds.bottom() <= work_area_.bottom())
+ return VISIBLE;
+ 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.
+ return HIDDEN;
+ else
+ return ANIMATING;
+
+ case AutoHidingDesktopBar::ALIGN_LEFT:
+ if (bounds.x() >= work_area_.x())
+ return VISIBLE;
+ 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.
+ return HIDDEN;
+ else
+ return ANIMATING;
+
+ case AutoHidingDesktopBar::ALIGN_RIGHT:
+ if (bounds.right() <= work_area_.right())
+ return VISIBLE;
+ 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.
+ return HIDDEN;
+ else
+ return ANIMATING;
+
+ default:
+ NOTREACHED();
+ return VISIBLE;
+ }
+}
+
+void AutoHidingDesktopBarWin::OnPollingTimer() {
+ CheckTaskbars(true);
+}
+
+bool AutoHidingDesktopBarWin::CheckTaskbars(bool notify_observer) {
+ bool exists_taskbar = false;
jennb 2011/08/26 20:41:57 s/exists_taskbar/taskbar_exists
jianli 2011/08/26 22:18:52 Done.
+ UINT edges[] = { ABE_BOTTOM, ABE_LEFT, ABE_RIGHT };
+ for (size_t i = 0; i < kMaxTaskbars; ++i) {
+ taskbars_[i].window =
+ views::GetTopmostAutoHideTaskbarForEdge(edges[i], monitor_);
+ if (taskbars_[i].window)
+ exists_taskbar = true;
+ }
+ 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
+ for (size_t i = 0; i < kMaxTaskbars; ++i) {
+ taskbars_[i].thickness = 0;
+ taskbars_[i].visibility = AutoHidingDesktopBar::HIDDEN;
+ }
+ return false;
+ }
+
+ bool thickness_changed = false;
+ for (size_t i = 0; i < kMaxTaskbars; ++i) {
+ AutoHidingDesktopBar::Alignment alignment = static_cast<Alignment>(i);
+
+ gfx::Rect bounds = GetBounds(alignment);
+
+ // Check the thickness change.
+ int thickness = GetThicknessFromBounds(alignment, bounds);
+ if (thickness != taskbars_[i].thickness) {
+ taskbars_[i].thickness = thickness;
+ thickness_changed = true;
+ }
+
+ // Check and notify the visibility change.
+ AutoHidingDesktopBar::Visibility visibility =
+ GetVisibilityFromBounds(alignment, bounds);
+ if (visibility != taskbars_[i].visibility) {
+ taskbars_[i].visibility = visibility;
+ if (notify_observer) {
+ observer_->OnAutoHidingDesktopBarVisibilityChanged(alignment,
+ visibility);
+ }
+ }
+ }
+
+ // Notify the thickness change if needed.
+ if (thickness_changed && notify_observer)
+ observer_->OnAutoHidingDesktopBarThicknessChanged();
+
+ return true;
+}
+
+} // namespace
+
+// static
+AutoHidingDesktopBar* AutoHidingDesktopBar::Create(Observer* observer) {
+ return new AutoHidingDesktopBarWin(observer);
+}
Property changes on: chrome\browser\ui\panels\auto_hiding_desktop_bar_win.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698