1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file. 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/views/controls/menu/menu_event_dispatcher_linux.h" 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/window.h" 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/events/event_utils.h" 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/events/keycodes/keyboard_code_conversion.h" 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/events/keycodes/keyboard_codes.h" 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/views/controls/menu/menu_controller.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/widget/widget.h" 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace views { 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace internal { 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochMenuEventDispatcher::MenuEventDispatcher(MenuController* controller) 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : menu_controller_(controller) {} 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochMenuEventDispatcher::~MenuEventDispatcher() {} 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool MenuEventDispatcher::CanDispatchEvent(const ui::PlatformEvent& event) { 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return true; 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochuint32_t MenuEventDispatcher::DispatchEvent(const ui::PlatformEvent& event) { 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool should_quit = false; 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool should_perform_default = true; 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool should_process_event = true; 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Check if the event should be handled. 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<ui::Event> ui_event(ui::EventFromNative(event)); 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (ui_event && menu_controller_->owner()) { 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) aura::Window* menu_window = menu_controller_->owner()->GetNativeWindow(); 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) aura::Window* target_window = static_cast<aura::Window*>( 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static_cast<ui::EventTarget*>(menu_window->GetRootWindow())-> 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetEventTargeter()->FindTargetForEvent(menu_window, 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui_event.get())); 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(flackr): The event shouldn't be handled if target_window is not 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // menu_window, however the event targeter does not properly target the 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // open menu. For now, we allow targeters to prevent handling by the menu. 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!target_window) 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_process_event = false; 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (menu_controller_->exit_type() == MenuController::EXIT_ALL || 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) menu_controller_->exit_type() == MenuController::EXIT_DESTROYED) { 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_quit = true; 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (should_process_event) { 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (ui::EventTypeFromNative(event)) { 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ui::ET_KEY_PRESSED: { 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!menu_controller_->OnKeyDown(ui::KeyboardCodeFromNative(event))) { 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_quit = true; 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_perform_default = false; 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Do not check mnemonics if the Alt or Ctrl modifiers are pressed. 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int flags = ui::EventFlagsFromNative(event); 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if ((flags & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)) == 0) { 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) char c = ui::GetCharacterFromKeyCode( 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::KeyboardCodeFromNative(event), flags); 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (menu_controller_->SelectByChar(c)) { 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_quit = true; 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_perform_default = false; 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_quit = false; 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_perform_default = false; 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ui::ET_KEY_RELEASED: 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_quit = false; 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) should_perform_default = false; 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (should_quit || menu_controller_->exit_type() != MenuController::EXIT_NONE) 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) menu_controller_->TerminateNestedMessageLoop(); 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return should_perform_default ? ui::POST_DISPATCH_PERFORM_DEFAULT 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : ui::POST_DISPATCH_NONE; 88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace internal 91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace views 92