1 // Copyright (c) 2012 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.
5 #include "ui/base/win/foreground_helper.h"
7 #include "base/logging.h"
8 #include "base/profiler/scoped_tracker.h"
9 #include "ui/gfx/win/window_impl.h"
14 HRESULT
ForegroundHelper::SetForeground(HWND window
) {
15 DCHECK(::IsWindow(window
));
16 ForegroundHelper foreground_helper
;
17 return foreground_helper
.ForegroundHotKey(window
);
20 HRESULT
ForegroundHelper::ForegroundHotKey(HWND window
) {
21 // This implementation registers a hot key (F22) and then
22 // triggers the hot key. When receiving the hot key, we'll
23 // be in the foreground and allowed to move the target window
24 // into the foreground too.
26 set_window_style(WS_POPUP
);
27 Init(NULL
, gfx::Rect());
29 static const int kHotKeyId
= 0x0000baba;
30 static const int kHotKeyWaitTimeout
= 2000;
32 // Store the target window into our USERDATA for use in our
35 RegisterHotKey(hwnd(), kHotKeyId
, 0, VK_F22
);
37 // If the calling thread is not yet a UI thread, call PeekMessage
38 // to ensure creation of its message queue.
40 PeekMessage(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
44 hotkey
.type
= INPUT_KEYBOARD
;
45 hotkey
.ki
.wVk
= VK_F22
;
46 if (1 != SendInput(1, &hotkey
, sizeof(hotkey
))) {
47 LOG(WARNING
) << "Failed to send input; GetLastError(): " << GetLastError();
51 // There are scenarios where the WM_HOTKEY is not dispatched by the
52 // the corresponding foreground thread. To prevent us from indefinitely
53 // waiting for the hotkey, we set a timer and exit the loop.
54 SetTimer(hwnd(), kHotKeyId
, kHotKeyWaitTimeout
, NULL
);
56 // Loop until we get the key or the timer fires.
57 while (GetMessage(&msg
, NULL
, 0, 0)) {
58 TranslateMessage(&msg
);
59 DispatchMessage(&msg
);
61 if (WM_HOTKEY
== msg
.message
)
63 if (WM_TIMER
== msg
.message
) {
64 SetForegroundWindow(window
);
69 UnregisterHotKey(hwnd(), kHotKeyId
);
70 KillTimer(hwnd(), kHotKeyId
);
71 DestroyWindow(hwnd());
76 // Handle the registered Hotkey being pressed.
77 void ForegroundHelper::OnHotKey(int id
, UINT vcode
, UINT modifiers
) {
78 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
79 tracked_objects::ScopedTracker
tracking_profile(
80 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 ForegroundHelper::OnHotKey"));
82 SetForegroundWindow(window_
);