blob: 4f88691f371b2f8eefe33ed5acc5f2fbc061379e [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/events/ozone/keyboard/event_auto_repeat_handler.h"
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "ui/events/base_event_utils.h"
namespace ui {
namespace {
constexpr int kRepeatDelayMs = 500;
constexpr int kRepeatIntervalMs = 50;
} // namespace
EventAutoRepeatHandler::EventAutoRepeatHandler(Delegate* delegate)
: repeat_delay_(base::TimeDelta::FromMilliseconds(kRepeatDelayMs)),
repeat_interval_(base::TimeDelta::FromMilliseconds(kRepeatIntervalMs)),
delegate_(delegate) {
DCHECK(delegate_);
}
EventAutoRepeatHandler::~EventAutoRepeatHandler() {}
bool EventAutoRepeatHandler::IsAutoRepeatEnabled() {
return auto_repeat_enabled_;
}
void EventAutoRepeatHandler::SetAutoRepeatEnabled(bool enabled) {
auto_repeat_enabled_ = enabled;
}
void EventAutoRepeatHandler::SetAutoRepeatRate(
const base::TimeDelta& delay,
const base::TimeDelta& interval) {
repeat_delay_ = delay;
repeat_interval_ = interval;
}
void EventAutoRepeatHandler::GetAutoRepeatRate(base::TimeDelta* delay,
base::TimeDelta* interval) {
*delay = repeat_delay_;
*interval = repeat_interval_;
}
void EventAutoRepeatHandler::UpdateKeyRepeat(unsigned int key,
bool down,
bool suppress_auto_repeat,
int device_id) {
if (!auto_repeat_enabled_ || suppress_auto_repeat)
StopKeyRepeat();
else if (key != repeat_key_ && down)
StartKeyRepeat(key, device_id);
else if (key == repeat_key_ && !down)
StopKeyRepeat();
}
void EventAutoRepeatHandler::StartKeyRepeat(unsigned int key, int device_id) {
repeat_key_ = key;
repeat_device_id_ = device_id;
repeat_sequence_++;
ScheduleKeyRepeat(repeat_delay_);
}
void EventAutoRepeatHandler::StopKeyRepeat() {
repeat_key_ = kInvalidKey;
repeat_sequence_++;
}
void EventAutoRepeatHandler::ScheduleKeyRepeat(const base::TimeDelta& delay) {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&EventAutoRepeatHandler::OnRepeatTimeout,
weak_ptr_factory_.GetWeakPtr(), repeat_sequence_),
delay);
}
void EventAutoRepeatHandler::OnRepeatTimeout(unsigned int sequence) {
if (repeat_sequence_ != sequence)
return;
base::OnceClosure commit =
base::BindOnce(&EventAutoRepeatHandler::OnRepeatCommit,
weak_ptr_factory_.GetWeakPtr(), repeat_sequence_);
delegate_->FlushInput(std::move(commit));
}
void EventAutoRepeatHandler::OnRepeatCommit(unsigned int sequence) {
if (repeat_sequence_ != sequence)
return;
delegate_->DispatchKey(repeat_key_, true /* down */, true /* repeat */,
EventTimeForNow(), repeat_device_id_);
ScheduleKeyRepeat(repeat_interval_);
}
} // namespace ui