11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/native_web_keyboard_event.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/focus/focus_manager.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NativeWebKeyboardEvent;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace views {
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)UnhandledKeyboardEventHandler::UnhandledKeyboardEventHandler()
170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    : ignore_next_char_event_(false) {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UnhandledKeyboardEventHandler::HandleKeyboardEvent(
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NativeWebKeyboardEvent& event,
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FocusManager* focus_manager) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!focus_manager) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Previous calls to TranslateMessage can generate Char events as well as
290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // RawKeyDown events, even if the latter triggered an accelerator.  In these
300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // cases, we discard the Char events.
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (event.type == blink::WebInputEvent::Char && ignore_next_char_event_) {
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ignore_next_char_event_ = false;
330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return;
340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // It's necessary to reset this flag, because a RawKeyDown event may not
360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // always generate a Char event.
370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ignore_next_char_event_ = false;
380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (event.type == blink::WebInputEvent::RawKeyDown) {
400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ui::Accelerator accelerator(
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        static_cast<ui::KeyboardCode>(event.windowsKeyCode),
420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        content::GetModifiersFromNativeWebKeyboardEvent(event));
430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // This is tricky: we want to set ignore_next_char_event_ if
450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // ProcessAccelerator returns true. But ProcessAccelerator might delete
460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // |this| if the accelerator is a "close tab" one. So we speculatively
470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // set the flag and fix it if no event was handled.
480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ignore_next_char_event_ = true;
490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (focus_manager->ProcessAccelerator(accelerator)) {
510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      return;
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // ProcessAccelerator didn't handle the accelerator, so we know both
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // that |this| is still valid, and that we didn't want to set the flag.
560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ignore_next_char_event_ = false;
570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event.os_event && !event.skip_in_browser)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    focus_manager->OnKeyEvent(*static_cast<ui::KeyEvent*>(event.os_event));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace views
64