Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/controls/menu/menu_controller.h" | 5 #include "ui/views/controls/menu/menu_controller.h" |
| 6 | 6 |
| 7 #include "base/i18n/case_conversion.h" | 7 #include "base/i18n/case_conversion.h" |
| 8 #include "base/i18n/rtl.h" | 8 #include "base/i18n/rtl.h" |
| 9 #include "base/time.h" | 9 #include "base/time.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| 11 #include "ui/base/dragdrop/os_exchange_data.h" | 11 #include "ui/base/dragdrop/os_exchange_data.h" |
| 12 #include "ui/base/events.h" | 12 #include "ui/base/events.h" |
| 13 #include "ui/base/keycodes/keyboard_codes.h" | 13 #include "ui/base/keycodes/keyboard_codes.h" |
| 14 #include "ui/base/l10n/l10n_util.h" | 14 #include "ui/base/l10n/l10n_util.h" |
| 15 #include "ui/gfx/canvas_skia.h" | 15 #include "ui/gfx/canvas_skia.h" |
| 16 #include "ui/gfx/screen.h" | 16 #include "ui/gfx/screen.h" |
| 17 #include "ui/views/controls/button/menu_button.h" | 17 #include "ui/views/controls/button/menu_button.h" |
| 18 #include "ui/views/controls/menu/menu_controller_delegate.h" | 18 #include "ui/views/controls/menu/menu_controller_delegate.h" |
| 19 #include "ui/views/controls/menu/menu_scroll_view_container.h" | 19 #include "ui/views/controls/menu/menu_scroll_view_container.h" |
| 20 #include "ui/views/controls/menu/submenu_view.h" | 20 #include "ui/views/controls/menu/submenu_view.h" |
| 21 #include "ui/views/drag_utils.h" | 21 #include "ui/views/drag_utils.h" |
| 22 #include "ui/views/view_constants.h" | 22 #include "ui/views/view_constants.h" |
| 23 #include "ui/views/views_delegate.h" | 23 #include "ui/views/views_delegate.h" |
| 24 #include "ui/views/widget/root_view.h" | 24 #include "ui/views/widget/root_view.h" |
| 25 #include "ui/views/widget/widget.h" | 25 #include "ui/views/widget/widget.h" |
| 26 | 26 |
| 27 #if defined(USE_AURA) | 27 #if defined(USE_AURA) |
| 28 #include "ui/aura/client/accelerator_client.h" | |
| 28 #include "ui/aura/root_window.h" | 29 #include "ui/aura/root_window.h" |
| 29 #elif defined(TOOLKIT_USES_GTK) | 30 #elif defined(TOOLKIT_USES_GTK) |
| 30 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" | 31 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" |
| 31 #endif | 32 #endif |
| 32 | 33 |
| 33 using base::Time; | 34 using base::Time; |
| 34 using base::TimeDelta; | 35 using base::TimeDelta; |
| 35 using ui::OSExchangeData; | 36 using ui::OSExchangeData; |
| 36 | 37 |
| 37 // Period of the scroll timer (in milliseconds). | 38 // Period of the scroll timer (in milliseconds). |
| 38 static const int kScrollTimerMS = 30; | 39 static const int kScrollTimerMS = 30; |
| 39 | 40 |
| 40 // Delay, in ms, between when menus are selected are moused over and the menu | 41 // Delay, in ms, between when menus are selected are moused over and the menu |
| 41 // appears. | 42 // appears. |
| 42 static const int kShowDelay = 400; | 43 static const int kShowDelay = 400; |
| 43 | 44 |
| 44 // Amount of time from when the drop exits the menu and the menu is hidden. | 45 // Amount of time from when the drop exits the menu and the menu is hidden. |
| 45 static const int kCloseOnExitTime = 1200; | 46 static const int kCloseOnExitTime = 1200; |
| 46 | 47 |
| 47 // Amount to inset submenus. | 48 // Amount to inset submenus. |
| 48 static const int kSubmenuHorizontalInset = 3; | 49 static const int kSubmenuHorizontalInset = 3; |
| 49 | 50 |
| 50 namespace views { | 51 namespace views { |
| 51 | 52 |
| 52 namespace { | 53 namespace { |
| 53 | 54 |
| 55 const int kModifierMask = (ui::EF_SHIFT_DOWN | | |
| 56 ui::EF_CONTROL_DOWN | | |
| 57 ui::EF_ALT_DOWN); | |
| 58 | |
| 54 // Returns true if the mnemonic of |menu| matches key. | 59 // Returns true if the mnemonic of |menu| matches key. |
| 55 bool MatchesMnemonic(MenuItemView* menu, char16 key) { | 60 bool MatchesMnemonic(MenuItemView* menu, char16 key) { |
| 56 return menu->GetMnemonic() == key; | 61 return menu->GetMnemonic() == key; |
| 57 } | 62 } |
| 58 | 63 |
| 59 // Returns true if |menu| doesn't have a mnemonic and first character of the its | 64 // Returns true if |menu| doesn't have a mnemonic and first character of the its |
| 60 // title is |key|. | 65 // title is |key|. |
| 61 bool TitleMatchesMnemonic(MenuItemView* menu, char16 key) { | 66 bool TitleMatchesMnemonic(MenuItemView* menu, char16 key) { |
| 62 if (menu->GetMnemonic()) | 67 if (menu->GetMnemonic()) |
| 63 return false; | 68 return false; |
| (...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 856 return true; | 861 return true; |
| 857 } | 862 } |
| 858 | 863 |
| 859 // NOTE: focus wasn't changed when the menu was shown. As such, don't | 864 // NOTE: focus wasn't changed when the menu was shown. As such, don't |
| 860 // dispatch key events otherwise the focused window will get the events. | 865 // dispatch key events otherwise the focused window will get the events. |
| 861 case WM_KEYDOWN: { | 866 case WM_KEYDOWN: { |
| 862 bool result = OnKeyDown(ui::KeyboardCodeFromNative(msg)); | 867 bool result = OnKeyDown(ui::KeyboardCodeFromNative(msg)); |
| 863 TranslateMessage(&msg); | 868 TranslateMessage(&msg); |
| 864 return result; | 869 return result; |
| 865 } | 870 } |
| 866 case WM_CHAR: | 871 case WM_CHAR: { |
| 872 #if defined(USE_AURA) | |
| 873 ui::Accelerator accelerator(ui::KeyboardCodeFromNative(msg), | |
| 874 ui::EventFlagsFromNative(msg) & kModifierMask); | |
| 875 if (aura::client::GetAcceleratorClient() && | |
| 876 aura::client::GetAcceleratorClient()->Process(accelerator)) | |
| 877 return false; | |
| 878 #endif | |
| 867 return !SelectByChar(static_cast<char16>(msg.wParam)); | 879 return !SelectByChar(static_cast<char16>(msg.wParam)); |
| 880 } | |
| 868 | 881 |
| 869 case WM_KEYUP: | 882 case WM_KEYUP: |
| 870 return true; | 883 return true; |
| 871 | 884 |
| 872 case WM_SYSKEYUP: | 885 case WM_SYSKEYUP: |
| 873 // We may have been shown on a system key, as such don't do anything | 886 // We may have been shown on a system key, as such don't do anything |
| 874 // here. If another system key is pushed we'll get a WM_SYSKEYDOWN and | 887 // here. If another system key is pushed we'll get a WM_SYSKEYDOWN and |
| 875 // close the menu. | 888 // close the menu. |
| 876 return true; | 889 return true; |
| 877 | 890 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 896 base::MessagePumpDispatcher::EVENT_PROCESSED; | 909 base::MessagePumpDispatcher::EVENT_PROCESSED; |
| 897 } | 910 } |
| 898 | 911 |
| 899 #elif defined(USE_AURA) | 912 #elif defined(USE_AURA) |
| 900 base::MessagePumpDispatcher::DispatchStatus | 913 base::MessagePumpDispatcher::DispatchStatus |
| 901 MenuController::Dispatch(XEvent* xev) { | 914 MenuController::Dispatch(XEvent* xev) { |
| 902 if (exit_type_ == EXIT_ALL || exit_type_ == EXIT_DESTROYED) { | 915 if (exit_type_ == EXIT_ALL || exit_type_ == EXIT_DESTROYED) { |
| 903 aura::RootWindow::GetInstance()->GetDispatcher()->Dispatch(xev); | 916 aura::RootWindow::GetInstance()->GetDispatcher()->Dispatch(xev); |
| 904 return base::MessagePumpDispatcher::EVENT_QUIT; | 917 return base::MessagePumpDispatcher::EVENT_QUIT; |
| 905 } | 918 } |
| 919 | |
| 920 ui::KeyboardCode keycode = ui::KeyboardCodeFromNative(xev); | |
| 906 switch (ui::EventTypeFromNative(xev)) { | 921 switch (ui::EventTypeFromNative(xev)) { |
| 907 case ui::ET_KEY_PRESSED: | 922 case ui::ET_KEY_PRESSED: { |
| 908 if (!OnKeyDown(ui::KeyboardCodeFromNative(xev))) | 923 if (!OnKeyDown(keycode)) |
| 909 return base::MessagePumpDispatcher::EVENT_QUIT; | 924 return base::MessagePumpDispatcher::EVENT_QUIT; |
| 910 | |
| 911 // OnKeyDown may have set exit_type_. | 925 // OnKeyDown may have set exit_type_. |
| 912 // TODO(sky): This shouldn't be necessary if OnKeyDown returns correct | 926 // TODO(sky): This shouldn't be necessary if OnKeyDown returns correct |
| 913 // value for space key on edit menu. Fix OnKeyDown and remove this. | 927 // value for space key on edit menu. Fix OnKeyDown and remove this. |
| 914 // See crbug.com/107919. | 928 // See crbug.com/107919. |
| 915 if (exit_type_ != EXIT_NONE) | 929 if (exit_type_ != EXIT_NONE) |
| 916 return base::MessagePumpDispatcher::EVENT_QUIT; | 930 return base::MessagePumpDispatcher::EVENT_QUIT; |
| 917 | 931 |
| 918 return SelectByChar(ui::KeyboardCodeFromNative(xev)) ? | 932 ui::Accelerator accelerator(keycode, |
| 919 base::MessagePumpDispatcher::EVENT_QUIT : | 933 ui::EventFlagsFromNative(xev) & kModifierMask); |
| 920 base::MessagePumpDispatcher::EVENT_PROCESSED; | 934 if (aura::client::GetAcceleratorClient() && |
| 935 aura::client::GetAcceleratorClient()->Process(accelerator)) | |
| 936 return base::MessagePumpDispatcher::EVENT_QUIT; | |
| 937 | |
| 938 if (SelectByChar(keycode)) | |
| 939 return base::MessagePumpDispatcher::EVENT_QUIT; | |
| 940 | |
| 941 return base::MessagePumpDispatcher::EVENT_PROCESSED; | |
|
oshima
2012/01/27 21:41:34
I think WM accelerator should be handled before ch
| |
| 942 } | |
| 921 case ui::ET_KEY_RELEASED: | 943 case ui::ET_KEY_RELEASED: |
| 922 return base::MessagePumpDispatcher::EVENT_PROCESSED; | 944 return base::MessagePumpDispatcher::EVENT_PROCESSED; |
| 923 default: | 945 default: |
| 924 break; | 946 break; |
| 925 } | 947 } |
| 926 | 948 |
| 927 // TODO(oshima): Update Windows' Dispatcher to return DispatchStatus | 949 // TODO(oshima): Update Windows' Dispatcher to return DispatchStatus |
| 928 // instead of bool. | 950 // instead of bool. |
| 929 if (aura::RootWindow::GetInstance()->GetDispatcher()->Dispatch(xev) == | 951 if (aura::RootWindow::GetInstance()->GetDispatcher()->Dispatch(xev) == |
| 930 base::MessagePumpDispatcher::EVENT_IGNORED) | 952 base::MessagePumpDispatcher::EVENT_IGNORED) |
| (...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2020 (!pending_state_.item->HasSubmenu() || | 2042 (!pending_state_.item->HasSubmenu() || |
| 2021 !pending_state_.item->GetSubmenu()->IsShowing())) { | 2043 !pending_state_.item->GetSubmenu()->IsShowing())) { |
| 2022 // On exit if the user hasn't selected an item with a submenu, move the | 2044 // On exit if the user hasn't selected an item with a submenu, move the |
| 2023 // selection back to the parent menu item. | 2045 // selection back to the parent menu item. |
| 2024 SetSelection(pending_state_.item->GetParentMenuItem(), | 2046 SetSelection(pending_state_.item->GetParentMenuItem(), |
| 2025 SELECTION_OPEN_SUBMENU); | 2047 SELECTION_OPEN_SUBMENU); |
| 2026 } | 2048 } |
| 2027 } | 2049 } |
| 2028 | 2050 |
| 2029 } // namespace views | 2051 } // namespace views |
| OLD | NEW |