| Index: chrome/browser/ui/panels/auto_hide_bottom_bar_win.cc
|
| ===================================================================
|
| --- chrome/browser/ui/panels/auto_hide_bottom_bar_win.cc (revision 0)
|
| +++ chrome/browser/ui/panels/auto_hide_bottom_bar_win.cc (revision 0)
|
| @@ -0,0 +1,191 @@
|
| +// 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_hide_bottom_bar.h"
|
| +
|
| +#include <windows.h>
|
| +#include <shellapi.h>
|
| +
|
| +#include "base/compiler_specific.h"
|
| +#include "base/logging.h"
|
| +#include "base/timer.h"
|
| +#include "ui/gfx/rect.h"
|
| +
|
| +namespace {
|
| +
|
| +// The thickness of the top area of an auto-hide taskbar that is still visible
|
| +// when the taskbar is hidden.
|
| +const int kAutoHideTaskbarThicknessPx = 2;
|
| +
|
| +// The polling interval to check auto-hide taskbar.
|
| +const int kCheckTaskbarPollingIntervalMs = 500;
|
| +
|
| +class AutoHideBottomBarWin : public AutoHideBottomBar {
|
| + public:
|
| + explicit AutoHideBottomBarWin(Observer* observer);
|
| + virtual ~AutoHideBottomBarWin();
|
| +
|
| + virtual void UpdateWorkArea(const gfx::Rect& work_area) OVERRIDE;
|
| + virtual bool Exists() OVERRIDE;
|
| + virtual int GetHeight() OVERRIDE;
|
| + virtual Visibility GetVisibility() OVERRIDE;
|
| +
|
| + private:
|
| + void ValidateAndGetWindow();
|
| + HWND GetAutoHideWindowOnScreenEdge(UINT edge) const;
|
| + gfx::Rect GetBounds();
|
| + int GetHeightFromBounds(const gfx::Rect& bounds) const;
|
| + Visibility GetVisibilityFromBounds(const gfx::Rect& bounds) const;
|
| + void CheckTaskbar();
|
| +
|
| + Observer* observer_;
|
| + gfx::Rect work_area_;
|
| + HMONITOR monitor_;
|
| + HWND window_;
|
| + bool aligned_to_bottom_;
|
| + Visibility visibility_;
|
| + int height_;
|
| + base::RepeatingTimer<AutoHideBottomBarWin> polling_timer_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(AutoHideBottomBarWin);
|
| +};
|
| +
|
| +AutoHideBottomBarWin::AutoHideBottomBarWin(Observer* observer)
|
| + : observer_(observer),
|
| + window_(NULL),
|
| + aligned_to_bottom_(false),
|
| + visibility_(VISIBLE),
|
| + height_(0) {
|
| + DCHECK(observer);
|
| +}
|
| +
|
| +AutoHideBottomBarWin::~AutoHideBottomBarWin() {
|
| +}
|
| +
|
| +void AutoHideBottomBarWin::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_);
|
| +
|
| + ValidateAndGetWindow();
|
| +
|
| + if (window_) {
|
| + visibility_ = GetVisibility();
|
| + height_ = GetHeight();
|
| +
|
| + if (!polling_timer_.IsRunning()) {
|
| + polling_timer_.Start(
|
| + base::TimeDelta::FromMilliseconds(kCheckTaskbarPollingIntervalMs),
|
| + this,
|
| + &AutoHideBottomBarWin::CheckTaskbar);
|
| + }
|
| + } else {
|
| + if (polling_timer_.IsRunning())
|
| + polling_timer_.Stop();
|
| + }
|
| +}
|
| +
|
| +bool AutoHideBottomBarWin::Exists() {
|
| + ValidateAndGetWindow();
|
| + return window_ != NULL && aligned_to_bottom_;
|
| +}
|
| +
|
| +int AutoHideBottomBarWin::GetHeight() {
|
| + return GetHeightFromBounds(GetBounds());
|
| +}
|
| +
|
| +AutoHideBottomBar::Visibility AutoHideBottomBarWin::GetVisibility() {
|
| + return GetVisibilityFromBounds(GetBounds());
|
| +}
|
| +
|
| +void AutoHideBottomBarWin::ValidateAndGetWindow() {
|
| + // Make sure |window_| is still valid since Shell might be restarted.
|
| + if (window_) {
|
| + if (::IsWindow(window_)) {
|
| + // Re-check the edge alignment.
|
| + aligned_to_bottom_ = window_ == GetAutoHideWindowOnScreenEdge(ABE_BOTTOM);
|
| + return;
|
| + }
|
| +
|
| + window_ = NULL;
|
| + }
|
| +
|
| + // Otherwise, find the auto-hide taskbar window that could appear in any edge
|
| + // of the work area. Note that we have to check all edges because the user
|
| + // might move the taskbar from non-bottom edge to bottom edge.
|
| + UINT edges[] = { ABE_BOTTOM, ABE_RIGHT, ABE_LEFT, ABE_TOP };
|
| + for (size_t i = 0; i < arraysize(edges); ++i) {
|
| + window_ = GetAutoHideWindowOnScreenEdge(edges[i]);
|
| + if (window_) {
|
| + aligned_to_bottom_ = edges[i] == ABE_BOTTOM;
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| +HWND AutoHideBottomBarWin::GetAutoHideWindowOnScreenEdge(UINT edge) const {
|
| + APPBARDATA taskbar_data = { 0 };
|
| + taskbar_data.cbSize = sizeof APPBARDATA;
|
| + taskbar_data.uEdge = edge;
|
| + HWND window = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR,
|
| + &taskbar_data));
|
| + return (::IsWindow(window) &&
|
| + (::MonitorFromWindow(window, MONITOR_DEFAULTTONULL) == monitor_) &&
|
| + (::GetWindowLong(window, GWL_EXSTYLE) & WS_EX_TOPMOST)) ?
|
| + window : NULL;
|
| +}
|
| +
|
| +gfx::Rect AutoHideBottomBarWin::GetBounds() {
|
| + ValidateAndGetWindow();
|
| + if (!window_ || !aligned_to_bottom_)
|
| + return gfx::Rect();
|
| +
|
| + RECT rect;
|
| + if (!::GetWindowRect(window_, &rect))
|
| + return gfx::Rect();
|
| + return gfx::Rect(rect);
|
| +}
|
| +
|
| +int AutoHideBottomBarWin::GetHeightFromBounds(const gfx::Rect& bounds) const {
|
| + return bounds.height();
|
| +}
|
| +
|
| +AutoHideBottomBar::Visibility AutoHideBottomBarWin::GetVisibilityFromBounds(
|
| + const gfx::Rect& bounds) const {
|
| + if (bounds.bottom() <= work_area_.bottom())
|
| + return VISIBLE;
|
| + else if (bounds.y() >= work_area_.bottom() - kAutoHideTaskbarThicknessPx)
|
| + return HIDDEN;
|
| + else
|
| + return ANIMATING;
|
| +}
|
| +
|
| +void AutoHideBottomBarWin::CheckTaskbar() {
|
| + gfx::Rect bounds = GetBounds();
|
| +
|
| + // Check and notify the visibility change.
|
| + Visibility visibility = GetVisibilityFromBounds(bounds);
|
| + if (visibility != visibility_) {
|
| + visibility_ = visibility;
|
| + observer_->OnAutoHideBottomBarVisibilityChanged(visibility);
|
| + }
|
| +
|
| + // Check and notify the height change.
|
| + int height = GetHeightFromBounds(bounds);
|
| + if (height != height_) {
|
| + height_ = height;
|
| + observer_->OnAutoHideBottomBarHeightChanged(height);
|
| + }
|
| +}
|
| +
|
| +}
|
| +
|
| +// static
|
| +AutoHideBottomBar* AutoHideBottomBar::Create(Observer* observer) {
|
| + return new AutoHideBottomBarWin(observer);
|
| +}
|
|
|
| Property changes on: chrome\browser\ui\panels\auto_hide_bottom_bar_win.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|