1 // Copyright 2013 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 "ui/views/win/appbar.h" 6 7 #include <shellapi.h> 8 9 #include "base/auto_reset.h" 10 #include "base/bind.h" 11 #include "base/location.h" 12 #include "base/threading/worker_pool.h" 13 #include "base/win/scoped_com_initializer.h" 14 #include "ui/views/widget/monitor_win.h" 15 16 namespace views { 17 18 namespace { 19 20 void GetEdgesOnWorkerThread(HMONITOR monitor, int* edge) { 21 base::win::ScopedCOMInitializer com_initializer; 22 *edge = 0; 23 if (GetTopmostAutoHideTaskbarForEdge(ABE_LEFT, monitor)) 24 *edge = Appbar::EDGE_LEFT; 25 if (GetTopmostAutoHideTaskbarForEdge(ABE_TOP, monitor)) 26 *edge = Appbar::EDGE_TOP; 27 if (GetTopmostAutoHideTaskbarForEdge(ABE_RIGHT, monitor)) 28 *edge = Appbar::EDGE_RIGHT; 29 if (GetTopmostAutoHideTaskbarForEdge(ABE_BOTTOM, monitor)) 30 *edge = Appbar::EDGE_BOTTOM; 31 } 32 33 } 34 35 // static 36 Appbar* Appbar::instance() { 37 static Appbar* appbar = NULL; 38 if (!appbar) 39 appbar = new Appbar(); 40 return appbar; 41 } 42 43 int Appbar::GetAutohideEdges(HMONITOR monitor, const base::Closure& callback) { 44 // Initialize the map with EDGE_BOTTOM. This is important, as if we return an 45 // initial value of 0 (no auto-hide edges) then we'll go fullscreen and 46 // windows will automatically remove WS_EX_TOPMOST from the appbar resulting 47 // in us thinking there is no auto-hide edges. By returning at least one edge 48 // we don't initially go fullscreen until we figure out the real auto-hide 49 // edges. 50 if (edge_map_.find(monitor) == edge_map_.end()) 51 edge_map_[monitor] = Appbar::EDGE_BOTTOM; 52 if (!in_callback_) { 53 int* edge = new int; 54 base::WorkerPool::PostTaskAndReply( 55 FROM_HERE, 56 base::Bind(&GetEdgesOnWorkerThread, 57 monitor, 58 base::Unretained(edge)), 59 base::Bind(&Appbar::OnGotEdges, 60 weak_factory_.GetWeakPtr(), 61 callback, 62 monitor, 63 edge_map_[monitor], 64 base::Owned(edge)), 65 false); 66 } 67 return edge_map_[monitor]; 68 } 69 70 Appbar::Appbar() : weak_factory_(this), in_callback_(false) { 71 } 72 73 Appbar::~Appbar() { 74 } 75 76 void Appbar::OnGotEdges(const base::Closure& callback, 77 HMONITOR monitor, 78 int returned_edges, 79 int* edges) { 80 edge_map_[monitor] = *edges; 81 if (returned_edges == *edges) 82 return; 83 84 base::AutoReset<bool> in_callback_setter(&in_callback_, true); 85 callback.Run(); 86 } 87 88 } // namespace views 89