summaryrefslogtreecommitdiffstats
path: root/ui/base/win/foreground_helper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/base/win/foreground_helper.cc')
-rw-r--r--ui/base/win/foreground_helper.cc84
1 files changed, 84 insertions, 0 deletions
diff --git a/ui/base/win/foreground_helper.cc b/ui/base/win/foreground_helper.cc
new file mode 100644
index 0000000..0b03582
--- /dev/null
+++ b/ui/base/win/foreground_helper.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2012 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/base/win/foreground_helper.h"
+
+#include "base/logging.h"
+#include "ui/base/win/window_impl.h"
+
+namespace ui {
+
+// static
+HRESULT ForegroundHelper::SetForeground(HWND window) {
+ DCHECK(::IsWindow(window));
+ ForegroundHelper foreground_helper;
+ return foreground_helper.ForegroundHotKey(window);
+}
+
+HRESULT ForegroundHelper::ForegroundHotKey(HWND window) {
+ // This implementation registers a hot key (F22) and then
+ // triggers the hot key. When receiving the hot key, we'll
+ // be in the foreground and allowed to move the target window
+ // into the foreground too.
+
+ set_window_style(WS_POPUP);
+ Init(NULL, gfx::Rect());
+
+ static const int kHotKeyId = 0x0000baba;
+ static const int kHotKeyWaitTimeout = 2000;
+
+ // Store the target window into our USERDATA for use in our
+ // HotKey handler.
+ window_ = window;
+ RegisterHotKey(hwnd(), kHotKeyId, 0, VK_F22);
+
+ // If the calling thread is not yet a UI thread, call PeekMessage
+ // to ensure creation of its message queue.
+ MSG msg = {0};
+ PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
+
+ // Send the Hotkey.
+ INPUT hotkey = {0};
+ hotkey.type = INPUT_KEYBOARD;
+ hotkey.ki.wVk = VK_F22;
+ if (1 != SendInput(1, &hotkey, sizeof(hotkey))) {
+ LOG(WARNING) << "Failed to send input";
+ return E_FAIL;
+ }
+
+ // There are scenarios where the WM_HOTKEY is not dispatched by the
+ // the corresponding foreground thread. To prevent us from indefinitely
+ // waiting for the hotkey, we set a timer and exit the loop.
+ SetTimer(hwnd(), kHotKeyId, kHotKeyWaitTimeout, NULL);
+
+ // Loop until we get the key or the timer fires.
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+
+ if (WM_HOTKEY == msg.message)
+ break;
+ if (WM_TIMER == msg.message) {
+ SetForegroundWindow(window);
+ break;
+ }
+ }
+
+ UnregisterHotKey(hwnd(), kHotKeyId);
+ KillTimer(hwnd(), kHotKeyId);
+ DestroyWindow(hwnd());
+
+ return S_OK;
+}
+
+ // Handle the registered Hotkey being pressed.
+LRESULT ForegroundHelper::OnHotKey(UINT message,
+ WPARAM wparam,
+ LPARAM lparam,
+ BOOL& handled) {
+ SetForegroundWindow(window_);
+ return 1;
+}
+
+} // namespace ui