summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/panels/panel_mouse_watcher_win.cc
blob: f07088517f0f1d421fd7e9845e0f74bc857b8716 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// 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/panel_mouse_watcher_win.h"

#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/ui/panels/panel.h"
#include "chrome/browser/ui/panels/panel_manager.h"

#include <windows.h>

namespace {

HMODULE GetModuleHandleFromAddress(void *address) {
  MEMORY_BASIC_INFORMATION mbi;
  SIZE_T result = ::VirtualQuery(address, &mbi, sizeof(mbi));
  return static_cast<HMODULE>(mbi.AllocationBase);
}


// Gets the handle to the currently executing module.
HMODULE GetCurrentModuleHandle() {
  return ::GetModuleHandleFromAddress(GetCurrentModuleHandle);
}

class PanelMouseWatcherWin {
 public:
  PanelMouseWatcherWin();
  ~PanelMouseWatcherWin();

 private:
  static LRESULT CALLBACK MouseHookProc(int code, WPARAM wparam, LPARAM lparam);

  void OnMouseAction(int mouse_x, int mouse_y);

  HHOOK mouse_hook_;
  bool bring_up_titlebar_;

  DISALLOW_COPY_AND_ASSIGN(PanelMouseWatcherWin);
};

scoped_ptr<PanelMouseWatcherWin> mouse_watcher;

PanelMouseWatcherWin::PanelMouseWatcherWin()
    : mouse_hook_(NULL),
      bring_up_titlebar_(false) {
  mouse_hook_ = ::SetWindowsHookEx(
      WH_MOUSE_LL, MouseHookProc, GetCurrentModuleHandle(), 0);
  DCHECK(mouse_hook_);
}

PanelMouseWatcherWin::~PanelMouseWatcherWin() {
  ::UnhookWindowsHookEx(mouse_hook_);
}

LRESULT CALLBACK PanelMouseWatcherWin::MouseHookProc(int code,
                                                     WPARAM wparam,
                                                     LPARAM lparam) {
  if (code == HC_ACTION) {
    MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lparam);
    if (hook_struct)
      mouse_watcher->OnMouseAction(hook_struct->pt.x, hook_struct->pt.y);
  }
  return ::CallNextHookEx(NULL, code, wparam, lparam);
}

void PanelMouseWatcherWin::OnMouseAction(int mouse_x, int mouse_y) {
  PanelManager* panel_manager = PanelManager::GetInstance();

  bool bring_up_titlebar =
      panel_manager->ShouldBringUpTitleBarForAllMinimizedPanels(
          mouse_x, mouse_y);
  if (bring_up_titlebar == bring_up_titlebar_)
    return;
  bring_up_titlebar_ = bring_up_titlebar;

  panel_manager->BringUpOrDownTitleBarForAllMinimizedPanels(bring_up_titlebar);
}

}

void EnsureMouseWatcherStarted() {
  if (!mouse_watcher.get())
    mouse_watcher.reset(new PanelMouseWatcherWin());
}

void StopMouseWatcher() {
  mouse_watcher.reset(NULL);
}

bool IsMouseWatcherStarted() {
  return mouse_watcher.get() != NULL;
}