Home | History | Annotate | Download | only in views
      1 // Copyright (c) 2011 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 "chrome/browser/ui/views/unhandled_keyboard_event_handler.h"
      6 
      7 #include "base/logging.h"
      8 #include "views/focus/focus_manager.h"
      9 
     10 UnhandledKeyboardEventHandler::UnhandledKeyboardEventHandler() {
     11   ignore_next_char_event_ = false;
     12 }
     13 
     14 UnhandledKeyboardEventHandler::~UnhandledKeyboardEventHandler() {
     15 }
     16 
     17 void UnhandledKeyboardEventHandler::HandleKeyboardEvent(
     18     const NativeWebKeyboardEvent& event,
     19     views::FocusManager* focus_manager) {
     20   if (!focus_manager) {
     21     NOTREACHED();
     22     return;
     23   }
     24   // Previous calls to TranslateMessage can generate Char events as well as
     25   // RawKeyDown events, even if the latter triggered an accelerator.  In these
     26   // cases, we discard the Char events.
     27   if (event.type == WebKit::WebInputEvent::Char && ignore_next_char_event_) {
     28     ignore_next_char_event_ = false;
     29     return;
     30   }
     31   // It's necessary to reset this flag, because a RawKeyDown event may not
     32   // always generate a Char event.
     33   ignore_next_char_event_ = false;
     34 
     35   if (event.type == WebKit::WebInputEvent::RawKeyDown) {
     36     views::Accelerator accelerator(
     37         static_cast<ui::KeyboardCode>(event.windowsKeyCode),
     38         (event.modifiers & NativeWebKeyboardEvent::ShiftKey) ==
     39             NativeWebKeyboardEvent::ShiftKey,
     40         (event.modifiers & NativeWebKeyboardEvent::ControlKey) ==
     41             NativeWebKeyboardEvent::ControlKey,
     42         (event.modifiers & NativeWebKeyboardEvent::AltKey) ==
     43             NativeWebKeyboardEvent::AltKey);
     44 
     45     // This is tricky: we want to set ignore_next_char_event_ if
     46     // ProcessAccelerator returns true. But ProcessAccelerator might delete
     47     // |this| if the accelerator is a "close tab" one. So we speculatively
     48     // set the flag and fix it if no event was handled.
     49     ignore_next_char_event_ = true;
     50 
     51     if (focus_manager->ProcessAccelerator(accelerator)) {
     52       return;
     53     }
     54 
     55     // ProcessAccelerator didn't handle the accelerator, so we know both
     56     // that |this| is still valid, and that we didn't want to set the flag.
     57     ignore_next_char_event_ = false;
     58   }
     59 
     60 #if defined(OS_WIN)
     61   // Any unhandled keyboard/character messages should be defproced.
     62   // This allows stuff like F10, etc to work correctly.
     63   DefWindowProc(event.os_event.hwnd, event.os_event.message,
     64                 event.os_event.wParam, event.os_event.lParam);
     65 #endif
     66 }
     67 
     68