Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions flutter/shell/platform/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ template("embedder") {
defines += [ "CLIPBOARD_SUPPORT" ]
}

if (api_version != "6.0" && api_version != "6.5" && api_version != "7.0") {
defines += [ "DIRECTIONAL_KEY_REPEAT_SUPPORT" ]
}

configs += [
":flutter_tizen_config",
"//flutter/shell/platform/common:desktop_library_implementation",
Expand Down
142 changes: 142 additions & 0 deletions flutter/shell/platform/tizen/tizen_window_ecore_wl2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#include "tizen_window_ecore_wl2.h"

#include <algorithm>
#include <cmath>

#ifdef TV_PROFILE
#include <app.h>
#include <app_preference.h>
Expand Down Expand Up @@ -325,6 +328,28 @@ void TizenWindowEcoreWl2::ShowUnsupportedToast() {
#endif

void TizenWindowEcoreWl2::RegisterEventHandlers() {
for (int event_type :
{ECORE_EVENT_DEVICE_DEL, ECORE_WL2_EVENT_SEAT_KEYMAP_CHANGED,
ECORE_WL2_EVENT_SEAT_KEYBOARD_REPEAT_CHANGED}) {
ecore_event_handlers_.push_back(ecore_event_handler_add(
event_type,
[](void* data, int type, void* event) -> Eina_Bool {
static_cast<TizenWindowEcoreWl2*>(data)->ResetKeyRepeat();
return ECORE_CALLBACK_PASS_ON;
},
this));
}
ecore_event_handlers_.push_back(ecore_event_handler_add(
ECORE_WL2_EVENT_FOCUS_OUT,
[](void* data, int type, void* event) -> Eina_Bool {
auto* self = static_cast<TizenWindowEcoreWl2*>(data);
auto* focus_event = static_cast<Ecore_Wl2_Event_Focus_Out*>(event);
if (focus_event->window == self->GetWindowId()) {
self->ResetKeyRepeat();
}
return ECORE_CALLBACK_PASS_ON;
},
this));
ecore_event_handlers_.push_back(ecore_event_handler_add(
ECORE_WL2_EVENT_WINDOW_ROTATE,
[](void* data, int type, void* event) -> Eina_Bool {
Expand Down Expand Up @@ -482,11 +507,15 @@ void TizenWindowEcoreWl2::RegisterEventHandlers() {
if (self->view_delegate_) {
auto* key_event = reinterpret_cast<Ecore_Event_Key*>(event);
if (key_event->window == self->GetWindowId()) {
const bool is_modifier = self->UpdateKeyModifiers(*key_event, true);
bool handled = false;
if (self->input_method_context_->ShouldFilterKey(key_event->key)) {
handled = self->input_method_context_->HandleEcoreEventKey(
key_event, true);
}
if (!is_modifier) {
self->StartKeyRepeat(*key_event, handled);
}
if (!handled) {
self->view_delegate_->OnKey(
key_event->key, key_event->string, key_event->compose,
Expand All @@ -507,6 +536,10 @@ void TizenWindowEcoreWl2::RegisterEventHandlers() {
if (self->view_delegate_) {
auto* key_event = reinterpret_cast<Ecore_Event_Key*>(event);
if (key_event->window == self->GetWindowId()) {
self->UpdateKeyModifiers(*key_event, false);
if (self->repeat_scan_code_ == key_event->keycode) {
self->StopKeyRepeat();
}
bool handled = false;
if (self->input_method_context_->ShouldFilterKey(key_event->key)) {
handled = self->input_method_context_->HandleEcoreEventKey(
Expand All @@ -526,12 +559,121 @@ void TizenWindowEcoreWl2::RegisterEventHandlers() {
}

void TizenWindowEcoreWl2::UnregisterEventHandlers() {
ResetKeyRepeat();
for (Ecore_Event_Handler* handler : ecore_event_handlers_) {
ecore_event_handler_del(handler);
}
ecore_event_handlers_.clear();
}

bool TizenWindowEcoreWl2::UpdateKeyModifiers(const Ecore_Event_Key& event,
bool is_down) {
key_modifiers_ = event.modifiers;
const auto modifier = event.key
? ecore_event_update_modifier(event.key, nullptr, 0)
: ECORE_NONE;
const uint32_t bit = ecore_event_modifier_mask(modifier);
constexpr uint32_t kHeldModifiers =
ECORE_EVENT_MODIFIER_SHIFT | ECORE_EVENT_MODIFIER_CTRL |
ECORE_EVENT_MODIFIER_ALT | ECORE_EVENT_MODIFIER_WIN |
ECORE_EVENT_MODIFIER_ALTGR;
if (bit & kHeldModifiers) {
if (is_down) {
pressed_modifiers_[event.keycode] = bit;
} else {
pressed_modifiers_.erase(event.keycode);
}
key_modifiers_ &= ~bit;
for (const auto& entry : pressed_modifiers_) {
key_modifiers_ |= entry.second;
}
}
return modifier != ECORE_NONE;
}

void TizenWindowEcoreWl2::StartKeyRepeat(const Ecore_Event_Key& event,
bool imf_handled) {
bool native_repeat =
repeat_scan_code_ != 0 && repeat_scan_code_ == event.keycode;
#ifdef DIRECTIONAL_KEY_REPEAT_SUPPORT
native_repeat |= (event.event_flags & ECORE_EVENT_FLAG_REPEAT) != 0;
#endif
StopKeyRepeat();
const std::string key = event.key ? event.key : "";
const bool is_arrow =
key == "Up" || key == "Down" || key == "Left" || key == "Right";
if (imf_handled || !is_arrow || !event.dev || event.keycode == 0 ||
ecore_device_class_get(event.dev) != ECORE_DEVICE_CLASS_KEYBOARD ||
ecore_device_subclass_get(event.dev) == ECORE_DEVICE_SUBCLASS_REMOCON) {
return;
}
repeat_scan_code_ = event.keycode;
if (native_repeat) {
return;
}
repeat_key_ = key;
const char* name = ecore_device_name_get(event.dev);
repeat_device_name_ = name ? name : "";
ScheduleKeyRepeat(true);
}

void TizenWindowEcoreWl2::StopKeyRepeat() {
if (key_repeat_timer_id_) {
g_source_remove(key_repeat_timer_id_);
key_repeat_timer_id_ = 0;
}
repeat_scan_code_ = 0;
}

void TizenWindowEcoreWl2::ResetKeyRepeat() {
StopKeyRepeat();
key_modifiers_ = 0;
pressed_modifiers_.clear();
}

void TizenWindowEcoreWl2::ScheduleKeyRepeat(bool initial) {
auto* input = ecore_wl2_window_input_get(ecore_wl2_window_);
if (!input) {
return;
}
double rate = 0;
double delay = 0;
bool have_repeat = false;
#ifdef DIRECTIONAL_KEY_REPEAT_SUPPORT
have_repeat = (repeat_key_ == "Left" || repeat_key_ == "Right")
? ecore_wl2_input_keyboard_horizontal_way_repeat_get(
input, &rate, &delay)
: ecore_wl2_input_keyboard_vertical_way_repeat_get(
input, &rate, &delay);
#endif
if (!have_repeat) {
have_repeat = ecore_wl2_input_keyboard_repeat_get(input, &rate, &delay);
}
const double interval_ms =
std::ceil(rate * 1000 + (initial ? delay * 1000 : 0));
if (!have_repeat || !std::isfinite(rate) || !std::isfinite(delay) ||
rate <= 0 || delay < 0 || !std::isfinite(interval_ms) ||
interval_ms > G_MAXUINT) {
return;
}
key_repeat_timer_id_ = g_timeout_add(
static_cast<guint>(std::max(interval_ms, 1.0)),
[](gpointer data) -> gboolean {
auto* self = static_cast<TizenWindowEcoreWl2*>(data);
self->key_repeat_timer_id_ = 0;
self->ScheduleKeyRepeat(false);
if (self->key_repeat_timer_id_ && self->view_delegate_) {
const auto key = self->repeat_key_;
const auto device_name = self->repeat_device_name_;
self->view_delegate_->OnKey(
key.c_str(), nullptr, nullptr, self->key_modifiers_,
self->repeat_scan_code_, device_name.c_str(), true);
}
return G_SOURCE_REMOVE;
},
this);
}

void TizenWindowEcoreWl2::DestroyWindow() {
if (ecore_wl2_egl_window_) {
ecore_wl2_egl_window_destroy(ecore_wl2_egl_window_);
Expand Down
18 changes: 18 additions & 0 deletions flutter/shell/platform/tizen/tizen_window_ecore_wl2.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

#define EFL_BETA_API_SUPPORT
#include <Ecore_Wl2.h>
#include <glib.h>
#include <tizen-extension-client-protocol.h>

#include <cstdint>
#include <map>
#include <string>
#include <vector>

Expand Down Expand Up @@ -89,6 +91,16 @@ class TizenWindowEcoreWl2 : public TizenWindow {

void PrepareInputMethod();

bool UpdateKeyModifiers(const Ecore_Event_Key& event, bool is_down);

void StartKeyRepeat(const Ecore_Event_Key& event, bool imf_handled);

void StopKeyRepeat();

void ResetKeyRepeat();

void ScheduleKeyRepeat(bool initial);

Ecore_Wl2_Display* ecore_wl2_display_ = nullptr;
Ecore_Wl2_Window* ecore_wl2_window_ = nullptr;
Ecore_Wl2_Egl_Window* ecore_wl2_egl_window_ = nullptr;
Expand All @@ -97,6 +109,12 @@ class TizenWindowEcoreWl2 : public TizenWindow {
std::vector<Ecore_Event_Handler*> ecore_event_handlers_;
tizen_policy* tizen_policy_ = nullptr;
uint32_t resource_id_ = 0;
guint key_repeat_timer_id_ = 0;
uint32_t repeat_scan_code_ = 0;
std::string repeat_key_;
std::string repeat_device_name_;
uint32_t key_modifiers_ = 0;
std::map<uint32_t, uint32_t> pressed_modifiers_;

#ifdef TV_PROFILE
bool pointing_device_support_ = true;
Expand Down
Loading
Loading