Chromium Code Reviews
|
| OLD | NEW |
|---|---|
| (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/panel_manager_win.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "chrome/browser/ui/panels/panel.h" | |
| 9 #include "chrome/browser/ui/panels/panel_browser_frame_view.h" | |
| 10 #include "chrome/browser/ui/panels/panel_browser_view.h" | |
| 11 | |
| 12 #include <windows.h> | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 HMODULE GetModuleHandleFromAddress(void *address) { | |
| 17 MEMORY_BASIC_INFORMATION mbi; | |
| 18 SIZE_T result = VirtualQuery(address, &mbi, sizeof(mbi)); | |
|
dcheng
2011/06/24 08:13:18
Nit: :: -- I'm actually indifferent about this, bu
jianli
2011/06/29 01:28:12
Done.
| |
| 19 return static_cast<HMODULE>(mbi.AllocationBase); | |
| 20 } | |
| 21 | |
| 22 | |
| 23 // Gets the handle to the currently executing module. | |
| 24 HMODULE GetCurrentModuleHandle() { | |
| 25 return GetModuleHandleFromAddress(GetCurrentModuleHandle); | |
|
dcheng
2011/06/24 08:13:18
Nite: ::
jianli
2011/06/29 01:28:12
Done.
| |
| 26 } | |
| 27 | |
| 28 } | |
| 29 | |
| 30 class PanelManagerMouseWatcher { | |
| 31 public: | |
| 32 PanelManagerMouseWatcher(int height_to_watch_on_mouse_enter, | |
| 33 int height_to_watch_on_mouse_exit, | |
| 34 PanelManagerWin* panel_manager); | |
| 35 ~PanelManagerMouseWatcher(); | |
| 36 | |
| 37 private: | |
| 38 static LRESULT CALLBACK MouseHookProc(int code, WPARAM wparam, LPARAM lparam); | |
| 39 | |
| 40 void OnMouseAction(int y); | |
| 41 | |
| 42 int height_to_watch_on_mouse_enter_; | |
| 43 int height_to_watch_on_mouse_exit_; | |
| 44 PanelManagerWin* panel_manager_; | |
| 45 HHOOK mouse_hook_; | |
| 46 bool mouse_in_bottom_area_; | |
| 47 }; | |
| 48 | |
| 49 static PanelManagerMouseWatcher* mouse_watcher_ = NULL; | |
| 50 | |
| 51 PanelManagerMouseWatcher::PanelManagerMouseWatcher( | |
| 52 int height_to_watch_on_mouse_enter, | |
| 53 int height_to_watch_on_mouse_exit, | |
| 54 PanelManagerWin* panel_manager) | |
| 55 : height_to_watch_on_mouse_enter_(height_to_watch_on_mouse_enter), | |
| 56 height_to_watch_on_mouse_exit_(height_to_watch_on_mouse_exit), | |
| 57 panel_manager_(panel_manager), | |
| 58 mouse_hook_(NULL), | |
| 59 mouse_in_bottom_area_(false) { | |
| 60 DCHECK(!mouse_watcher_); | |
| 61 mouse_watcher_ = this; | |
| 62 | |
| 63 mouse_hook_ = ::SetWindowsHookEx( | |
| 64 WH_MOUSE_LL, MouseHookProc,GetCurrentModuleHandle(), 0); | |
|
dcheng
2011/06/24 08:13:18
Nit: space.
jianli
2011/06/29 01:28:12
Done.
| |
| 65 DCHECK(mouse_hook_); | |
| 66 } | |
| 67 | |
| 68 PanelManagerMouseWatcher::~PanelManagerMouseWatcher() { | |
| 69 mouse_watcher_ = NULL; | |
| 70 UnhookWindowsHookEx(mouse_hook_); | |
|
dcheng
2011/06/24 08:13:18
Nit: ::
jianli
2011/06/29 01:28:12
Done.
| |
| 71 } | |
| 72 | |
| 73 void PanelManagerMouseWatcher::OnMouseAction(int y) { | |
| 74 int height_to_watch = mouse_in_bottom_area_ ? height_to_watch_on_mouse_exit_ | |
| 75 : height_to_watch_on_mouse_enter_; | |
| 76 bool mouse_in_bottom_area = | |
| 77 y > (panel_manager_->work_area_.bottom() - height_to_watch); | |
|
dcheng
2011/06/24 08:13:18
How will this interact with multiple monitors?
jianli
2011/06/29 01:28:12
We're only showing panels in primary monitor.
| |
| 78 if (mouse_in_bottom_area == mouse_in_bottom_area_) | |
| 79 return; | |
| 80 mouse_in_bottom_area_ = mouse_in_bottom_area; | |
| 81 | |
| 82 if (mouse_in_bottom_area) | |
| 83 panel_manager_->BringUpTitleBarForAllMinimizedPanels(); | |
| 84 else | |
| 85 panel_manager_->BringDownTitleBarForAllMinimizedPanels(); | |
| 86 } | |
| 87 | |
| 88 LRESULT CALLBACK PanelManagerMouseWatcher::MouseHookProc(int code, | |
| 89 WPARAM wparam, | |
| 90 LPARAM lparam) { | |
| 91 if (code == HC_ACTION) { | |
| 92 MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lparam); | |
| 93 if (hook_struct) | |
| 94 mouse_watcher_->OnMouseAction(hook_struct->pt.y); | |
| 95 } | |
| 96 return CallNextHookEx(NULL, code, wparam, lparam); | |
|
dcheng
2011/06/24 08:13:18
Nit: ::
jianli
2011/06/29 01:28:12
Done.
| |
| 97 } | |
| 98 | |
| 99 // static | |
| 100 PanelManager* PanelManager::Create() { | |
| 101 return new PanelManagerWin(); | |
| 102 } | |
| 103 | |
| 104 PanelManagerWin::PanelManagerWin() { | |
| 105 } | |
| 106 | |
| 107 PanelManagerWin::~PanelManagerWin() { | |
| 108 } | |
| 109 | |
| 110 void PanelManagerWin::Remove(Panel* panel) { | |
| 111 PanelManager::Remove(panel); | |
| 112 | |
| 113 // If the removed panel is the only panel that is not fully restored, we need | |
| 114 // to check for this and stop the mouse watcher. | |
| 115 StopMouseWatchIfNotNeeded(); | |
| 116 } | |
| 117 | |
| 118 void PanelManagerWin::Minimize(Panel* panel) { | |
| 119 PanelManager::Minimize(panel); | |
| 120 | |
| 121 // Starts the global mouse watch so that we can bring up or down the titlebar | |
| 122 // when the mouse is entering or leaving the bottom 3-pixel area. | |
| 123 EnsureMouseWatchStarted( | |
| 124 panel->GetBounds().height(), | |
| 125 static_cast<PanelBrowserView*>(panel->native_panel_)-> | |
| 126 GetFrameView()->NonClientTopBorderHeight()); | |
| 127 } | |
| 128 | |
| 129 void PanelManagerWin::Restore(Panel* panel, bool titlebar_only) { | |
| 130 PanelManager::Restore(panel, titlebar_only); | |
| 131 | |
| 132 // If this panel is not fully restored, we still need to keep the mouse | |
| 133 // watcher running. | |
| 134 if (titlebar_only) | |
| 135 return; | |
| 136 | |
| 137 StopMouseWatchIfNotNeeded(); | |
| 138 } | |
| 139 | |
| 140 void PanelManagerWin::EnsureMouseWatchStarted( | |
| 141 int height_to_watch_on_mouse_enter, int height_to_watch_on_mouse_exit) { | |
| 142 if (!mouse_watcher_.get()) { | |
| 143 mouse_watcher_.reset( | |
| 144 new PanelManagerMouseWatcher(height_to_watch_on_mouse_enter, | |
| 145 height_to_watch_on_mouse_exit, this)); | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 void PanelManagerWin::StopMouseWatchIfNotNeeded() { | |
| 150 // If all panels are fully restored, stop the global mouse watch. | |
| 151 for (ActivePanels::const_iterator iter = active_panels_.begin(); | |
| 152 iter != active_panels_.end(); ++iter) { | |
| 153 PanelBrowserView* panel_browser_view = | |
| 154 static_cast<PanelBrowserView*>((*iter)->native_panel_); | |
| 155 if (panel_browser_view->expand_state() != PanelBrowserView::FULLY_RESTORED) | |
| 156 return; | |
| 157 } | |
| 158 | |
| 159 mouse_watcher_.reset(); | |
| 160 } | |
| 161 | |
| 162 void PanelManagerWin::BringUpTitleBarForAllMinimizedPanels() { | |
| 163 for (ActivePanels::const_iterator iter = active_panels_.begin(); | |
| 164 iter != active_panels_.end(); ++iter) { | |
| 165 PanelBrowserView* panel_browser_view = | |
| 166 static_cast<PanelBrowserView*>((*iter)->native_panel_); | |
| 167 if (panel_browser_view->expand_state() == PanelBrowserView::FULLY_MINIMIZED) | |
| 168 Restore((*iter), true); | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 void PanelManagerWin::BringDownTitleBarForAllMinimizedPanels() { | |
| 173 for (ActivePanels::const_iterator iter = active_panels_.begin(); | |
| 174 iter != active_panels_.end(); ++iter) { | |
| 175 PanelBrowserView* panel_browser_view = | |
| 176 static_cast<PanelBrowserView*>((*iter)->native_panel_); | |
| 177 if (panel_browser_view->expand_state() == | |
| 178 PanelBrowserView::TITLEBAR_RESTORED) { | |
| 179 Minimize((*iter)); | |
| 180 } | |
| 181 } | |
| 182 } | |
| OLD | NEW |