Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / views / controls / menu / menu_message_pump_dispatcher_win.cc
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.
4
5 #include "ui/views/controls/menu/menu_message_pump_dispatcher_win.h"
6
7 #include <windowsx.h>
8
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"
14
15 namespace views {
16 namespace internal {
17
18 MenuMessagePumpDispatcher::MenuMessagePumpDispatcher(MenuController* controller)
19     : menu_controller_(controller) {}
20
21 MenuMessagePumpDispatcher::~MenuMessagePumpDispatcher() {}
22
23 uint32_t MenuMessagePumpDispatcher::Dispatch(const MSG& msg) {
24   DCHECK(menu_controller_->IsBlockingRun());
25
26   if (menu_controller_->exit_type() == MenuController::EXIT_ALL ||
27       menu_controller_->exit_type() == MenuController::EXIT_DESTROYED)
28     return (POST_DISPATCH_QUIT_LOOP | POST_DISPATCH_PERFORM_DEFAULT);
29
30   // NOTE: we don't get WM_ACTIVATE or anything else interesting in here.
31   switch (msg.message) {
32     case WM_CONTEXTMENU: {
33       MenuItemView* item = menu_controller_->pending_state_.item;
34       if (item && item->GetRootMenuItem() != item) {
35         gfx::Point screen_loc(0, item->height());
36         View::ConvertPointToScreen(item, &screen_loc);
37         ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE;
38         if (GET_X_LPARAM(msg.lParam) == -1 && GET_Y_LPARAM(msg.lParam) == -1)
39           source_type = ui::MENU_SOURCE_KEYBOARD;
40         item->GetDelegate()->ShowContextMenu(
41             item, item->GetCommand(), screen_loc, source_type);
42       }
43       return POST_DISPATCH_NONE;
44     }
45
46     // NOTE: focus wasn't changed when the menu was shown. As such, don't
47     // dispatch key events otherwise the focused window will get the events.
48     case WM_KEYDOWN: {
49       bool result =
50           menu_controller_->OnKeyDown(ui::KeyboardCodeFromNative(msg));
51       TranslateMessage(&msg);
52       return result ? POST_DISPATCH_NONE : POST_DISPATCH_QUIT_LOOP;
53     }
54     case WM_CHAR: {
55       bool should_exit =
56           menu_controller_->SelectByChar(static_cast<base::char16>(msg.wParam));
57       return should_exit ? POST_DISPATCH_QUIT_LOOP : POST_DISPATCH_NONE;
58     }
59     case WM_KEYUP:
60       return POST_DISPATCH_NONE;
61
62     case WM_SYSKEYUP:
63       // We may have been shown on a system key, as such don't do anything
64       // here. If another system key is pushed we'll get a WM_SYSKEYDOWN and
65       // close the menu.
66       return POST_DISPATCH_NONE;
67
68     case WM_CANCELMODE:
69     case WM_SYSKEYDOWN:
70       // Exit immediately on system keys.
71       menu_controller_->Cancel(MenuController::EXIT_ALL);
72       return POST_DISPATCH_QUIT_LOOP;
73
74     default:
75       break;
76   }
77   return POST_DISPATCH_PERFORM_DEFAULT |
78          (menu_controller_->exit_type() == MenuController::EXIT_NONE
79               ? POST_DISPATCH_NONE
80               : POST_DISPATCH_QUIT_LOOP);
81 }
82
83 }  // namespace internal
84 }  // namespace views