blob: 20a0eb41d65f5d29939dc2eee45938913b48bce9 [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/input/key_repeat_filter.h"
#include "cobalt/base/token.h"
#include "cobalt/base/tokens.h"
namespace cobalt {
namespace input {
namespace {
const base::TimeDelta kRepeatInitialDelay =
base::TimeDelta::FromMilliseconds(500);
const float kRepeatRateInHertz = 20.0f;
const base::TimeDelta kRepeatRate = base::TimeDelta::FromMilliseconds(
base::Time::kMillisecondsPerSecond / kRepeatRateInHertz);
} // namespace
KeyRepeatFilter::KeyRepeatFilter(const KeyboardEventCallback& callback)
: KeyEventHandler(callback) {}
KeyRepeatFilter::KeyRepeatFilter(KeyEventHandler* filter)
: KeyEventHandler(filter) {}
void KeyRepeatFilter::HandleKeyboardEvent(
base::Token type, const dom::KeyboardEventInit& keyboard_event) {
if (type == base::Tokens::keydown()) {
HandleKeyDown(type, keyboard_event);
}
if (type == base::Tokens::keyup()) {
HandleKeyUp(type, keyboard_event);
}
}
void KeyRepeatFilter::HandleKeyDown(
base::Token type, const dom::KeyboardEventInit& keyboard_event) {
// Record the information of the KeyboardEvent for firing repeat events.
last_event_data_ = keyboard_event;
DispatchKeyboardEvent(type, keyboard_event);
// This key down event is triggered for the first time, so start the timer
// with |kRepeatInitialDelay|.
key_repeat_timer_.Start(FROM_HERE, kRepeatInitialDelay, this,
&KeyRepeatFilter::FireKeyRepeatEvent);
}
void KeyRepeatFilter::HandleKeyUp(
base::Token type, const dom::KeyboardEventInit& keyboard_event) {
DispatchKeyboardEvent(type, keyboard_event);
// If it is a key up event and it matches the previous one, stop the key
// repeat timer.
if (last_event_data_->key_code() == keyboard_event.key_code()) {
key_repeat_timer_.Stop();
}
}
void KeyRepeatFilter::FireKeyRepeatEvent() {
dom::KeyboardEventInit repeat_event(*last_event_data_);
repeat_event.set_repeat(true);
DispatchKeyboardEvent(base::Tokens::keydown(), repeat_event);
// If |FireKeyRepeatEvent| is triggered for the first time then reset the
// timer to the repeat rate instead of the initial delay.
if (key_repeat_timer_.GetCurrentDelay() == kRepeatInitialDelay) {
key_repeat_timer_.Stop();
key_repeat_timer_.Start(FROM_HERE, kRepeatRate, this,
&KeyRepeatFilter::FireKeyRepeatEvent);
}
}
} // namespace input
} // namespace cobalt