// Copyright 2013 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 "ui/views/win/appbar.h" #include #include "base/auto_reset.h" #include "base/bind.h" #include "base/location.h" #include "base/threading/worker_pool.h" #include "base/win/scoped_com_initializer.h" #include "ui/views/widget/monitor_win.h" namespace views { namespace { void GetEdgesOnWorkerThread(HMONITOR monitor, int* edge) { base::win::ScopedCOMInitializer com_initializer; *edge = 0; if (GetTopmostAutoHideTaskbarForEdge(ABE_LEFT, monitor)) *edge = Appbar::EDGE_LEFT; if (GetTopmostAutoHideTaskbarForEdge(ABE_TOP, monitor)) *edge = Appbar::EDGE_TOP; if (GetTopmostAutoHideTaskbarForEdge(ABE_RIGHT, monitor)) *edge = Appbar::EDGE_RIGHT; if (GetTopmostAutoHideTaskbarForEdge(ABE_BOTTOM, monitor)) *edge = Appbar::EDGE_BOTTOM; } } // static Appbar* Appbar::instance() { static Appbar* appbar = NULL; if (!appbar) appbar = new Appbar(); return appbar; } int Appbar::GetAutohideEdges(HMONITOR monitor, const base::Closure& callback) { // Initialize the map with EDGE_BOTTOM. This is important, as if we return an // initial value of 0 (no auto-hide edges) then we'll go fullscreen and // windows will automatically remove WS_EX_TOPMOST from the appbar resulting // in us thinking there is no auto-hide edges. By returning at least one edge // we don't initially go fullscreen until we figure out the real auto-hide // edges. if (edge_map_.find(monitor) == edge_map_.end()) edge_map_[monitor] = Appbar::EDGE_BOTTOM; if (!in_callback_) { int* edge = new int; base::WorkerPool::PostTaskAndReply( FROM_HERE, base::Bind(&GetEdgesOnWorkerThread, monitor, base::Unretained(edge)), base::Bind(&Appbar::OnGotEdges, weak_factory_.GetWeakPtr(), callback, monitor, edge_map_[monitor], base::Owned(edge)), false); } return edge_map_[monitor]; } Appbar::Appbar() : weak_factory_(this), in_callback_(false) { } Appbar::~Appbar() { } void Appbar::OnGotEdges(const base::Closure& callback, HMONITOR monitor, int returned_edges, int* edges) { edge_map_[monitor] = *edges; if (returned_edges == *edges) return; base::AutoReset in_callback_setter(&in_callback_, true); callback.Run(); } } // namespace views