Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / views / controls / menu / menu_message_pump_dispatcher_win.cc
blobb7f5b37e9feb3f5d0380e8c5fd40a604c7a58225
1 // Copyright 2014 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/views/controls/menu/menu_message_pump_dispatcher_win.h"
7 #include <windowsx.h>
9 #include "ui/events/event_utils.h"
10 #include "ui/events/keycodes/keyboard_code_conversion.h"
11 #include "ui/events/keycodes/keyboard_codes.h"
12 #include "ui/views/controls/menu/menu_controller.h"
13 #include "ui/views/controls/menu/menu_item_view.h"
15 namespace views {
16 namespace internal {
18 MenuMessagePumpDispatcher::MenuMessagePumpDispatcher(MenuController* controller)
19 : menu_controller_(controller) {}
21 MenuMessagePumpDispatcher::~MenuMessagePumpDispatcher() {}
23 uint32_t MenuMessagePumpDispatcher::Dispatch(const MSG& msg) {
24 DCHECK(menu_controller_->IsBlockingRun());
26 bool should_quit = false;
27 bool should_perform_default = true;
28 if (menu_controller_->exit_type() == MenuController::EXIT_ALL ||
29 menu_controller_->exit_type() == MenuController::EXIT_DESTROYED) {
30 should_quit = true;
31 } else {
32 // NOTE: we don't get WM_ACTIVATE or anything else interesting in here.
33 switch (msg.message) {
34 case WM_CONTEXTMENU: {
35 MenuItemView* item = menu_controller_->pending_state_.item;
36 if (item && item->GetRootMenuItem() != item) {
37 gfx::Point screen_loc(0, item->height());
38 View::ConvertPointToScreen(item, &screen_loc);
39 ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE;
40 if (GET_X_LPARAM(msg.lParam) == -1 && GET_Y_LPARAM(msg.lParam) == -1)
41 source_type = ui::MENU_SOURCE_KEYBOARD;
42 item->GetDelegate()->ShowContextMenu(
43 item, item->GetCommand(), screen_loc, source_type);
45 should_perform_default = false;
46 break;
49 // NOTE: focus wasn't changed when the menu was shown. As such, don't
50 // dispatch key events otherwise the focused window will get the events.
51 case WM_KEYDOWN: {
52 menu_controller_->OnKeyDown(ui::KeyboardCodeFromNative(msg));
53 TranslateMessage(&msg);
54 should_perform_default = false;
55 break;
57 case WM_CHAR: {
58 menu_controller_->SelectByChar(static_cast<base::char16>(msg.wParam));
59 should_perform_default = false;
60 break;
62 case WM_KEYUP:
63 case WM_SYSKEYUP:
64 // We may have been shown on a system key, as such don't do anything
65 // here. If another system key is pushed we'll get a WM_SYSKEYDOWN and
66 // close the menu.
67 should_perform_default = false;
68 break;
70 case WM_CANCELMODE:
71 case WM_SYSKEYDOWN:
72 // Exit immediately on system keys.
73 menu_controller_->Cancel(MenuController::EXIT_ALL);
74 should_quit = true;
75 should_perform_default = false;
76 break;
78 default:
79 break;
83 if (should_quit || menu_controller_->exit_type() != MenuController::EXIT_NONE)
84 menu_controller_->TerminateNestedMessageLoop();
85 return should_perform_default ? POST_DISPATCH_PERFORM_DEFAULT
86 : POST_DISPATCH_NONE;
89 } // namespace internal
90 } // namespace views