[ozone/wayland] Text input refactors part 2: Split interfaces
Split the legacy ZWPTextInputWrapper interface in two and add impls for each of them: - ZwpTextInputV1[Impl] - ZwpTextInputV3[Impl] In this change the text input v1 and v3 objects are still multi-instance, i.e. each WaylandInputMethodContext owns a separate instance of either ZwpTextInputV1 or ZwpTextInputV3. ZwpTextInputV* objects will be converted to singletons in a subsequent change. Bug: 414284073 Change-Id: I99751d0ec27f646dacd836808d25b5b9d96ff7b4 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6495371 Commit-Queue: Orko Garai <orko@igalia.com> Reviewed-by: Kramer Ge <fangzhoug@chromium.org> Cr-Commit-Position: refs/heads/main@{#1454042}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
ff527e1256
commit
dc46fa8321
ui/ozone/platform/wayland
BUILD.gn
host
span_style.hwayland_input_method_context.ccwayland_input_method_context.hwayland_input_method_context_unittest.cczwp_text_input_v1.cczwp_text_input_v1.hzwp_text_input_v1_unittest.cczwp_text_input_v3.cczwp_text_input_v3.hzwp_text_input_v3_unittest.cczwp_text_input_wrapper.hzwp_text_input_wrapper_v1.h
test
@ -68,6 +68,7 @@ source_set("wayland") {
|
||||
"host/overlay_prioritizer.h",
|
||||
"host/single_pixel_buffer.cc",
|
||||
"host/single_pixel_buffer.h",
|
||||
"host/span_style.h",
|
||||
"host/toplevel_icon_manager.cc",
|
||||
"host/toplevel_icon_manager.h",
|
||||
"host/wayland_async_cursor.cc",
|
||||
@ -209,11 +210,10 @@ source_set("wayland") {
|
||||
"host/zwp_primary_selection_device_manager.h",
|
||||
"host/zwp_primary_selection_offer.cc",
|
||||
"host/zwp_primary_selection_offer.h",
|
||||
"host/zwp_text_input_wrapper.h",
|
||||
"host/zwp_text_input_wrapper_v1.cc",
|
||||
"host/zwp_text_input_wrapper_v1.h",
|
||||
"host/zwp_text_input_wrapper_v3.cc",
|
||||
"host/zwp_text_input_wrapper_v3.h",
|
||||
"host/zwp_text_input_v1.cc",
|
||||
"host/zwp_text_input_v1.h",
|
||||
"host/zwp_text_input_v3.cc",
|
||||
"host/zwp_text_input_v3.h",
|
||||
"ozone_platform_wayland.cc",
|
||||
"ozone_platform_wayland.h",
|
||||
"wayland_utils.cc",
|
||||
@ -397,8 +397,10 @@ source_set("test_support") {
|
||||
"test/mock_zwp_linux_dmabuf.h",
|
||||
"test/mock_zwp_text_input.cc",
|
||||
"test/mock_zwp_text_input.h",
|
||||
"test/mock_zwp_text_input_wrapper_client.cc",
|
||||
"test/mock_zwp_text_input_wrapper_client.h",
|
||||
"test/mock_zwp_text_input_v1_client.cc",
|
||||
"test/mock_zwp_text_input_v1_client.h",
|
||||
"test/mock_zwp_text_input_v3_client.cc",
|
||||
"test/mock_zwp_text_input_v3_client.h",
|
||||
"test/scoped_wl_array.cc",
|
||||
"test/scoped_wl_array.h",
|
||||
"test/server_object.cc",
|
||||
@ -552,8 +554,8 @@ source_set("wayland_unittests") {
|
||||
"host/wayland_zwp_pointer_gestures_unittest.cc",
|
||||
"host/xdg_activation_unittest.cc",
|
||||
"host/xdg_toplevel_icon_unittest.cc",
|
||||
"host/zwp_text_input_wrapper_v1_unittest.cc",
|
||||
"host/zwp_text_input_wrapper_v3_unittest.cc",
|
||||
"host/zwp_text_input_v1_unittest.cc",
|
||||
"host/zwp_text_input_v3_unittest.cc",
|
||||
"mojom/wayland_overlay_config_mojom_traits_unittest.cc",
|
||||
"test/wayland_drag_drop_test.cc",
|
||||
"test/wayland_drag_drop_test.h",
|
||||
|
34
ui/ozone/platform/wayland/host/span_style.h
Normal file
34
ui/ozone/platform/wayland/host/span_style.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_SPAN_STYLE_H_
|
||||
#define UI_OZONE_PLATFORM_WAYLAND_HOST_SPAN_STYLE_H_
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "ui/base/ime/ime_text_span.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
struct SpanStyle {
|
||||
struct Style {
|
||||
bool operator==(const Style& other) const = default;
|
||||
|
||||
ImeTextSpan::Type type;
|
||||
ImeTextSpan::Thickness thickness;
|
||||
};
|
||||
|
||||
bool operator==(const SpanStyle& other) const = default;
|
||||
|
||||
// Byte offset.
|
||||
uint32_t index;
|
||||
// Length in bytes.
|
||||
uint32_t length;
|
||||
// One of preedit_style.
|
||||
std::optional<Style> style;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_SPAN_STYLE_H_
|
@ -36,11 +36,10 @@
|
||||
#include "ui/events/types/event_type.h"
|
||||
#include "ui/gfx/range/range.h"
|
||||
#include "ui/ozone/platform/wayland/common/wayland_util.h"
|
||||
#include "ui/ozone/platform/wayland/host/span_style.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_seat.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_window.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.h"
|
||||
#include "ui/ozone/public/ozone_switches.h"
|
||||
|
||||
#if BUILDFLAG(USE_XKBCOMMON)
|
||||
@ -177,6 +176,67 @@ std::optional<OffsetText> TrimSurroundingTextForStandard(
|
||||
truncated_range.start()};
|
||||
}
|
||||
|
||||
class WaylandInputMethodContextV1Client : public ZwpTextInputV1Client {
|
||||
public:
|
||||
explicit WaylandInputMethodContextV1Client(WaylandInputMethodContext* context)
|
||||
: context_(context) {}
|
||||
|
||||
void OnPreeditString(std::string_view text,
|
||||
const std::vector<SpanStyle>& spans,
|
||||
const gfx::Range& preedit_cursor) override {
|
||||
context_->OnPreeditString(text, spans, preedit_cursor);
|
||||
}
|
||||
|
||||
void OnCommitString(std::string_view text) override {
|
||||
context_->OnCommitString(text);
|
||||
}
|
||||
|
||||
void OnCursorPosition(int32_t index, int32_t anchor) override {
|
||||
context_->OnCursorPosition(index, anchor);
|
||||
}
|
||||
|
||||
void OnDeleteSurroundingText(int32_t index, uint32_t length) override {
|
||||
context_->OnDeleteSurroundingText(index, length);
|
||||
}
|
||||
|
||||
void OnKeysym(uint32_t key,
|
||||
uint32_t state,
|
||||
uint32_t modifiers,
|
||||
uint32_t time) override {
|
||||
context_->OnKeysym(key, state, modifiers, time);
|
||||
}
|
||||
|
||||
void OnInputPanelState(uint32_t state) override {
|
||||
context_->OnInputPanelState(state);
|
||||
}
|
||||
|
||||
void OnModifiersMap(std::vector<std::string> map) override {
|
||||
context_->OnModifiersMap(std::move(map));
|
||||
}
|
||||
|
||||
private:
|
||||
raw_ptr<WaylandInputMethodContext> context_;
|
||||
};
|
||||
|
||||
class WaylandInputmethodContextV3Client : public ZwpTextInputV3Client {
|
||||
public:
|
||||
explicit WaylandInputmethodContextV3Client(WaylandInputMethodContext* context)
|
||||
: context_(context) {}
|
||||
|
||||
void OnPreeditString(std::string_view text,
|
||||
const std::vector<SpanStyle>& spans,
|
||||
const gfx::Range& preedit_cursor) override {
|
||||
context_->OnPreeditString(text, spans, preedit_cursor);
|
||||
}
|
||||
|
||||
void OnCommitString(std::string_view text) override {
|
||||
context_->OnCommitString(text);
|
||||
}
|
||||
|
||||
private:
|
||||
raw_ptr<WaylandInputMethodContext> context_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
WaylandInputMethodContext::WaylandInputMethodContext(
|
||||
@ -186,21 +246,23 @@ WaylandInputMethodContext::WaylandInputMethodContext(
|
||||
: connection_(connection),
|
||||
key_delegate_(key_delegate),
|
||||
ime_delegate_(ime_delegate),
|
||||
text_input_(nullptr),
|
||||
text_input_v1_(nullptr),
|
||||
character_composer_(kPreeditStringMode) {
|
||||
connection_->window_manager()->AddObserver(this);
|
||||
Init();
|
||||
}
|
||||
|
||||
WaylandInputMethodContext::~WaylandInputMethodContext() {
|
||||
if (text_input_) {
|
||||
if (text_input_v3_) {
|
||||
text_input_v3_->OnClientDestroyed(text_input_v3_client_.get());
|
||||
} else if (text_input_v1_) {
|
||||
DismissVirtualKeyboard();
|
||||
text_input_->Deactivate();
|
||||
text_input_v1_->OnClientDestroyed(text_input_v1_client_.get());
|
||||
}
|
||||
connection_->window_manager()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::CreateTextInputWrapper() {
|
||||
void WaylandInputMethodContext::CreateTextInput() {
|
||||
// Can be specified as value for --wayland-ime-version to use text-input-v1 or
|
||||
// text-input-v3.
|
||||
constexpr char kWaylandTextInputVersion1[] = "1";
|
||||
@ -213,49 +275,70 @@ void WaylandInputMethodContext::CreateTextInputWrapper() {
|
||||
cmd_line->HasSwitch(switches::kEnableWaylandIme) &&
|
||||
!version_from_cmd_line.empty();
|
||||
|
||||
if (base::FeatureList::IsEnabled(features::kWaylandTextInputV3) ||
|
||||
(enable_using_cmd_line_version &&
|
||||
version_from_cmd_line == kWaylandTextInputVersion3)) {
|
||||
if (connection_->text_input_manager_v3()) {
|
||||
text_input_ = std::make_unique<ZWPTextInputWrapperV3>(
|
||||
connection_, this, connection_->text_input_manager_v3());
|
||||
} else {
|
||||
LOG(WARNING) << "text-input-v3 not available.";
|
||||
if (enable_using_cmd_line_version &&
|
||||
version_from_cmd_line == kWaylandTextInputVersion1) {
|
||||
if (!connection_->text_input_manager_v1()) {
|
||||
LOG(WARNING) << "text-input-v1 is not supported by the compositor.";
|
||||
return;
|
||||
}
|
||||
return;
|
||||
} else if (enable_using_cmd_line_version &&
|
||||
version_from_cmd_line != kWaylandTextInputVersion1) {
|
||||
LOG(WARNING) << "text input version should be either 1 or 3. Defaulting to "
|
||||
"text-input-v1.";
|
||||
}
|
||||
if (connection_->text_input_manager_v1()) {
|
||||
text_input_ = std::make_unique<ZWPTextInputWrapperV1>(
|
||||
connection_, this, connection_->text_input_manager_v1());
|
||||
} else {
|
||||
LOG(WARNING) << "text-input-v1 not available.";
|
||||
text_input_v1_ = std::make_unique<ZwpTextInputV1Impl>(
|
||||
connection_, connection_->text_input_manager_v1());
|
||||
text_input_v1_client_ =
|
||||
std::make_unique<WaylandInputMethodContextV1Client>(this);
|
||||
} else if (base::FeatureList::IsEnabled(features::kWaylandTextInputV3) ||
|
||||
enable_using_cmd_line_version) {
|
||||
if (!version_from_cmd_line.empty() &&
|
||||
version_from_cmd_line != kWaylandTextInputVersion3) {
|
||||
LOG(WARNING) << "--wayland-text-input-version should have a value of "
|
||||
"either 1 or 3 and "
|
||||
"--enable-wayland-ime should be present. Defaulting to "
|
||||
"text-input-v3.";
|
||||
}
|
||||
if (!connection_->text_input_manager_v3()) {
|
||||
LOG(WARNING) << "text-input-v3 is not supported by the compositor.";
|
||||
return;
|
||||
}
|
||||
text_input_v3_ = std::make_unique<ZwpTextInputV3Impl>(
|
||||
connection_, connection_->text_input_manager_v3());
|
||||
text_input_v3_client_ =
|
||||
std::make_unique<WaylandInputmethodContextV3Client>(this);
|
||||
}
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::Init(
|
||||
bool initialize_for_testing,
|
||||
std::unique_ptr<ZWPTextInputWrapper> wrapper_for_testing,
|
||||
std::optional<base::nix::DesktopEnvironment> desktop_for_testing) {
|
||||
desktop_environment_ = desktop_for_testing.value_or(
|
||||
base::nix::GetDesktopEnvironment(base::Environment::Create().get()));
|
||||
if (wrapper_for_testing) {
|
||||
text_input_ = std::move(wrapper_for_testing);
|
||||
return;
|
||||
}
|
||||
|
||||
bool use_ozone_wayland_vkb = initialize_for_testing || IsImeEnabled();
|
||||
void WaylandInputMethodContext::Init() {
|
||||
bool use_ozone_wayland_ime = IsImeEnabled();
|
||||
// If text input instance is not created then all ime context operations
|
||||
// are noop. This option is because in some environments someone might not
|
||||
// want to enable ime/virtual keyboard even if it's available.
|
||||
if (!use_ozone_wayland_vkb || text_input_) {
|
||||
if (!use_ozone_wayland_ime || text_input_v3_ || text_input_v1_) {
|
||||
return;
|
||||
}
|
||||
|
||||
CreateTextInputWrapper();
|
||||
CreateTextInput();
|
||||
CHECK(!(text_input_v3_ && text_input_v1_))
|
||||
<< "Both text-input-v1 and text-input-v3 used at the same time.";
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::SetTextInputV1ForTesting(
|
||||
std::unique_ptr<ZwpTextInputV1> text_input_v1) {
|
||||
text_input_v1_ = std::move(text_input_v1);
|
||||
if (!text_input_v1_client_) {
|
||||
text_input_v1_client_ =
|
||||
std::make_unique<WaylandInputMethodContextV1Client>(this);
|
||||
}
|
||||
text_input_v1_->SetClient(text_input_v1_client_.get());
|
||||
text_input_v3_ = nullptr;
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::SetTextInputV3ForTesting(
|
||||
std::unique_ptr<ZwpTextInputV3> text_input_v3) {
|
||||
text_input_v3_ = std::move(text_input_v3);
|
||||
if (!text_input_v3_client_) {
|
||||
text_input_v3_client_ =
|
||||
std::make_unique<WaylandInputmethodContextV3Client>(this);
|
||||
}
|
||||
text_input_v3_->SetClient(text_input_v3_client_.get());
|
||||
text_input_v1_ = nullptr;
|
||||
}
|
||||
|
||||
bool WaylandInputMethodContext::DispatchKeyEvent(const KeyEvent& key_event) {
|
||||
@ -308,8 +391,11 @@ void WaylandInputMethodContext::Reset() {
|
||||
// intentions. Introduce a dedicated extended Wayland API for resetting only
|
||||
// the composition.
|
||||
surrounding_text_tracker_.CancelComposition();
|
||||
if (text_input_)
|
||||
text_input_->Reset();
|
||||
if (text_input_v3_) {
|
||||
text_input_v3_->Reset();
|
||||
} else if (text_input_v1_) {
|
||||
text_input_v1_->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::WillUpdateFocus(TextInputClient* old_client,
|
||||
@ -334,23 +420,21 @@ void WaylandInputMethodContext::UpdateFocus(
|
||||
if (old_type != TEXT_INPUT_TYPE_NONE)
|
||||
Blur(skip_vk_update);
|
||||
if (new_type != TEXT_INPUT_TYPE_NONE)
|
||||
Focus(skip_vk_update, reason);
|
||||
Focus(skip_vk_update);
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::Focus(bool skip_virtual_keyboard_update,
|
||||
TextInputClient::FocusReason reason) {
|
||||
void WaylandInputMethodContext::Focus(bool skip_virtual_keyboard_update) {
|
||||
focused_ = true;
|
||||
MaybeUpdateActivated(skip_virtual_keyboard_update, reason);
|
||||
MaybeUpdateActivated(skip_virtual_keyboard_update);
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::Blur(bool skip_virtual_keyboard_update) {
|
||||
focused_ = false;
|
||||
MaybeUpdateActivated(skip_virtual_keyboard_update,
|
||||
TextInputClient::FOCUS_REASON_NONE);
|
||||
MaybeUpdateActivated(skip_virtual_keyboard_update);
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::SetCursorLocation(const gfx::Rect& rect) {
|
||||
if (!text_input_) {
|
||||
if (!text_input_v3_ && !text_input_v1_) {
|
||||
return;
|
||||
}
|
||||
WaylandWindow* focused_window =
|
||||
@ -358,8 +442,13 @@ void WaylandInputMethodContext::SetCursorLocation(const gfx::Rect& rect) {
|
||||
if (!focused_window) {
|
||||
return;
|
||||
}
|
||||
text_input_->SetCursorRect(
|
||||
rect - focused_window->GetBoundsInDIP().OffsetFromOrigin());
|
||||
if (text_input_v3_) {
|
||||
text_input_v3_->SetCursorRect(
|
||||
rect - focused_window->GetBoundsInDIP().OffsetFromOrigin());
|
||||
} else {
|
||||
text_input_v1_->SetCursorRect(
|
||||
rect - focused_window->GetBoundsInDIP().OffsetFromOrigin());
|
||||
}
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::SetSurroundingText(
|
||||
@ -387,8 +476,9 @@ void WaylandInputMethodContext::SetSurroundingText(
|
||||
size_t utf16_offset = text_range.GetMin();
|
||||
surrounding_text_tracker_.Update(text, utf16_offset, selection_range);
|
||||
|
||||
if (!text_input_)
|
||||
if (!text_input_v3_ && !text_input_v1_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert into UTF8 unit.
|
||||
std::vector<size_t> offsets_for_adjustment = {
|
||||
@ -451,30 +541,44 @@ void WaylandInputMethodContext::SetSurroundingText(
|
||||
gfx::Range relocated_selection_range(
|
||||
selection_range_utf8.start() - surrounding_text_offset_,
|
||||
selection_range_utf8.end() - surrounding_text_offset_);
|
||||
text_input_->SetSurroundingText(text_utf8, relocated_preedit_range,
|
||||
relocated_selection_range);
|
||||
if (text_input_v3_) {
|
||||
text_input_v3_->SetSurroundingText(text_utf8, relocated_preedit_range,
|
||||
relocated_selection_range);
|
||||
} else {
|
||||
text_input_v1_->SetSurroundingText(text_utf8, relocated_preedit_range,
|
||||
relocated_selection_range);
|
||||
}
|
||||
}
|
||||
|
||||
VirtualKeyboardController*
|
||||
WaylandInputMethodContext::GetVirtualKeyboardController() {
|
||||
if (!text_input_)
|
||||
if (!text_input_v3_ && !text_input_v1_) {
|
||||
return nullptr;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
bool WaylandInputMethodContext::DisplayVirtualKeyboard() {
|
||||
if (!text_input_)
|
||||
if (!text_input_v3_ && !text_input_v1_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
text_input_->ShowInputPanel();
|
||||
// Text-input-v3 does not support input panel show/hide yet.
|
||||
if (text_input_v1_) {
|
||||
text_input_v1_->ShowInputPanel();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::DismissVirtualKeyboard() {
|
||||
if (!text_input_)
|
||||
if (!text_input_v3_ && !text_input_v1_) {
|
||||
return;
|
||||
}
|
||||
|
||||
text_input_->HideInputPanel();
|
||||
// Text-input-v3 does not support input panel show/hide yet.
|
||||
if (text_input_v1_) {
|
||||
text_input_v1_->HideInputPanel();
|
||||
}
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::AddObserver(
|
||||
@ -715,39 +819,57 @@ void WaylandInputMethodContext::OnModifiersMap(
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::OnKeyboardFocusedWindowChanged() {
|
||||
MaybeUpdateActivated(false, TextInputClient::FOCUS_REASON_OTHER);
|
||||
if (text_input_v3_) {
|
||||
// For text-input-v3, zwp_text_input_l3::{enter,leave} is used instead.
|
||||
return;
|
||||
}
|
||||
MaybeUpdateActivated(false);
|
||||
}
|
||||
|
||||
void WaylandInputMethodContext::MaybeUpdateActivated(
|
||||
bool skip_virtual_keyboard_update,
|
||||
TextInputClient::FocusReason reason) {
|
||||
if (!text_input_)
|
||||
bool skip_virtual_keyboard_update) {
|
||||
if (!text_input_v3_ && !text_input_v1_) {
|
||||
return;
|
||||
}
|
||||
|
||||
WaylandWindow* window =
|
||||
WaylandWindow* focused_window =
|
||||
connection_->window_manager()->GetCurrentKeyboardFocusedWindow();
|
||||
if (!window && !connection_->seat()->keyboard())
|
||||
window = connection_->window_manager()->GetCurrentActiveWindow();
|
||||
// Activate Wayland IME only if 1) InputMethod in Chrome has some
|
||||
// TextInputClient connected, and 2) the actual keyboard focus of Wayland
|
||||
// is given to Chrome, which is notified via wl_keyboard::enter.
|
||||
// If no keyboard is connected, the current active window is used for 2)
|
||||
// instead (https://crbug.com/1168411).
|
||||
bool activated = focused_ && window;
|
||||
if (!focused_window && !connection_->seat()->keyboard()) {
|
||||
// If no keyboard is connected, the current active window is used.
|
||||
focused_window = connection_->window_manager()->GetCurrentActiveWindow();
|
||||
}
|
||||
// Activate Wayland IME only if the following conditions are met:
|
||||
// 1) InputMethod has some TextInputClient connected.
|
||||
// 2) There is a focused Chromium window.
|
||||
// 3) The focused window matches the window containing this
|
||||
// WaylandInputMethodContext.
|
||||
bool activated = focused_ && focused_window;
|
||||
if (activated_ == activated)
|
||||
return;
|
||||
|
||||
activated_ = activated;
|
||||
if (activated) {
|
||||
text_input_->Activate(window, reason);
|
||||
text_input_->SetContentType(attributes_.input_type, attributes_.flags,
|
||||
attributes_.should_do_learning);
|
||||
if (text_input_v3_) {
|
||||
text_input_v3_->SetClient(text_input_v3_client_.get());
|
||||
text_input_v3_->Enable();
|
||||
text_input_v3_->SetContentType(attributes_.input_type, attributes_.flags,
|
||||
attributes_.should_do_learning);
|
||||
} else {
|
||||
text_input_v1_->SetClient(text_input_v1_client_.get());
|
||||
text_input_v1_->Activate(focused_window);
|
||||
text_input_v1_->SetContentType(attributes_.input_type, attributes_.flags,
|
||||
attributes_.should_do_learning);
|
||||
}
|
||||
if (!skip_virtual_keyboard_update)
|
||||
DisplayVirtualKeyboard();
|
||||
} else {
|
||||
if (!skip_virtual_keyboard_update)
|
||||
DismissVirtualKeyboard();
|
||||
text_input_->Deactivate();
|
||||
if (text_input_v3_) {
|
||||
text_input_v3_->Disable();
|
||||
} else {
|
||||
text_input_v1_->Deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,8 @@
|
||||
#include "ui/gfx/range/range.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_keyboard.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_window_observer.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_v1.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_v3.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
@ -29,8 +30,7 @@ class WaylandConnection;
|
||||
|
||||
class WaylandInputMethodContext : public LinuxInputMethodContext,
|
||||
public VirtualKeyboardController,
|
||||
public WaylandWindowObserver,
|
||||
public ZWPTextInputWrapperClient {
|
||||
public WaylandWindowObserver {
|
||||
public:
|
||||
class Delegate;
|
||||
|
||||
@ -42,10 +42,7 @@ class WaylandInputMethodContext : public LinuxInputMethodContext,
|
||||
delete;
|
||||
~WaylandInputMethodContext() override;
|
||||
|
||||
void Init(bool initialize_for_testing = false,
|
||||
std::unique_ptr<ZWPTextInputWrapper> wrapper_for_testing = nullptr,
|
||||
std::optional<base::nix::DesktopEnvironment> desktop_for_testing =
|
||||
std::nullopt);
|
||||
void Init();
|
||||
|
||||
// LinuxInputMethodContext overrides:
|
||||
bool DispatchKeyEvent(const KeyEvent& key_event) override;
|
||||
@ -76,37 +73,44 @@ class WaylandInputMethodContext : public LinuxInputMethodContext,
|
||||
// WaylandWindowObserver overrides:
|
||||
void OnKeyboardFocusedWindowChanged() override;
|
||||
|
||||
// ZWPTextInputWrapperClient overrides:
|
||||
// Callbacks from the v1 and v3 clients.
|
||||
void OnPreeditString(std::string_view text,
|
||||
const std::vector<SpanStyle>& spans,
|
||||
const gfx::Range& preedit_cursor) override;
|
||||
void OnCommitString(std::string_view text) override;
|
||||
void OnCursorPosition(int32_t index, int32_t anchor) override;
|
||||
void OnDeleteSurroundingText(int32_t index, uint32_t length) override;
|
||||
const gfx::Range& preedit_cursor);
|
||||
void OnCommitString(std::string_view text);
|
||||
void OnCursorPosition(int32_t index, int32_t anchor);
|
||||
void OnDeleteSurroundingText(int32_t index, uint32_t length);
|
||||
void OnKeysym(uint32_t keysym,
|
||||
uint32_t state,
|
||||
uint32_t modifiers,
|
||||
uint32_t time) override;
|
||||
uint32_t time);
|
||||
|
||||
void OnInputPanelState(uint32_t state) override;
|
||||
void OnModifiersMap(std::vector<std::string> modifiers_map) override;
|
||||
void OnInputPanelState(uint32_t state);
|
||||
void OnModifiersMap(std::vector<std::string> modifiers_map);
|
||||
|
||||
const SurroundingTextTracker::State& predicted_state_for_testing() const {
|
||||
return surrounding_text_tracker_.predicted_state();
|
||||
}
|
||||
|
||||
void SetTextInputV1ForTesting(std::unique_ptr<ZwpTextInputV1> text_input_v1);
|
||||
|
||||
void SetTextInputV3ForTesting(std::unique_ptr<ZwpTextInputV3> text_input_v3);
|
||||
|
||||
void SetDesktopEnvironmentForTesting(
|
||||
base::nix::DesktopEnvironment desktop_environment) {
|
||||
desktop_environment_ = desktop_environment;
|
||||
}
|
||||
|
||||
private:
|
||||
void CreateTextInputWrapper();
|
||||
void Focus(bool skip_virtual_keyboard_update,
|
||||
TextInputClient::FocusReason reason);
|
||||
void CreateTextInput();
|
||||
void Focus(bool skip_virtual_keyboard_update);
|
||||
void Blur(bool skip_virtual_keyboard_update);
|
||||
void UpdatePreeditText(const std::u16string& preedit_text);
|
||||
// If |skip_virtual_keyboard_update| is true, no virtual keyboard show/hide
|
||||
// requests will be sent. This is used to prevent flickering the virtual
|
||||
// keyboard when it would be immediately reshown anyway, e.g. when changing
|
||||
// focus from one text input to another.
|
||||
void MaybeUpdateActivated(bool skip_virtual_keyboard_update,
|
||||
TextInputClient::FocusReason reason);
|
||||
void MaybeUpdateActivated(bool skip_virtual_keyboard_update);
|
||||
|
||||
const raw_ptr<WaylandConnection>
|
||||
connection_; // TODO(jani) Handle this better
|
||||
@ -117,7 +121,10 @@ class WaylandInputMethodContext : public LinuxInputMethodContext,
|
||||
// Delegate IME-specific events to be handled by //ui code.
|
||||
const raw_ptr<LinuxInputMethodContextDelegate> ime_delegate_;
|
||||
|
||||
std::unique_ptr<ZWPTextInputWrapper> text_input_;
|
||||
std::unique_ptr<ZwpTextInputV1Client> text_input_v1_client_;
|
||||
std::unique_ptr<ZwpTextInputV3Client> text_input_v3_client_;
|
||||
std::unique_ptr<ZwpTextInputV1> text_input_v1_;
|
||||
std::unique_ptr<ZwpTextInputV3> text_input_v3_;
|
||||
|
||||
// Tracks whether InputMethod in Chrome has some focus.
|
||||
bool focused_ = false;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "ui/ozone/platform/wayland/host/wayland_event_source.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_seat.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_window.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_v1.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_surface.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input.h"
|
||||
#include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h"
|
||||
@ -151,20 +152,20 @@ class MockTextInputClient : public TextInputClient {
|
||||
base::WeakPtrFactory<MockTextInputClient> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
class MockZWPTextInputWrapper : public ZWPTextInputWrapper {
|
||||
class MockZwpTextInputV3 : public ZwpTextInputV3 {
|
||||
public:
|
||||
~MockZWPTextInputWrapper() override = default;
|
||||
~MockZwpTextInputV3() override = default;
|
||||
|
||||
MOCK_METHOD(void, Reset, (), (override));
|
||||
MOCK_METHOD(void, SetClient, (ZwpTextInputV3Client * context), (override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
Activate,
|
||||
(WaylandWindow * window, ui::TextInputClient::FocusReason reason),
|
||||
OnClientDestroyed,
|
||||
(ZwpTextInputV3Client * context),
|
||||
(override));
|
||||
MOCK_METHOD(void, Deactivate, (), (override));
|
||||
|
||||
MOCK_METHOD(void, ShowInputPanel, (), (override));
|
||||
MOCK_METHOD(void, HideInputPanel, (), (override));
|
||||
MOCK_METHOD(void, Enable, (), (override));
|
||||
MOCK_METHOD(void, Disable, (), (override));
|
||||
MOCK_METHOD(void, Reset, (), (override));
|
||||
|
||||
MOCK_METHOD(void, SetCursorRect, (const gfx::Rect& rect), (override));
|
||||
MOCK_METHOD(void,
|
||||
@ -327,8 +328,11 @@ class WaylandInputMethodContextTest : public WaylandTest {
|
||||
input_method_context_ = std::make_unique<WaylandInputMethodContext>(
|
||||
connection_.get(), keyboard_delegate_.get(),
|
||||
input_method_context_delegate_.get());
|
||||
input_method_context_->Init(
|
||||
true, nullptr,
|
||||
auto text_input_v1 = std::make_unique<ZwpTextInputV1Impl>(
|
||||
connection_.get(), connection_->text_input_manager_v1());
|
||||
text_input_v1_ = text_input_v1.get();
|
||||
input_method_context_->SetTextInputV1ForTesting(std::move(text_input_v1));
|
||||
input_method_context_->SetDesktopEnvironmentForTesting(
|
||||
// Ensure by default it doesn't pick the current desktop from the system
|
||||
// the tests are running on.
|
||||
base::nix::DesktopEnvironment::DESKTOP_ENVIRONMENT_OTHER);
|
||||
@ -350,11 +354,12 @@ class WaylandInputMethodContextTest : public WaylandTest {
|
||||
input_method_context_delegate_;
|
||||
std::unique_ptr<TestKeyboardDelegate> keyboard_delegate_;
|
||||
std::unique_ptr<WaylandInputMethodContext> input_method_context_;
|
||||
raw_ptr<ZwpTextInputV1> text_input_v1_;
|
||||
|
||||
uint32_t surface_id_ = 0u;
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(TextInput,
|
||||
INSTANTIATE_TEST_SUITE_P(TextInputV1,
|
||||
WaylandInputMethodContextTest,
|
||||
::testing::Values(wl::ServerConfig{}));
|
||||
|
||||
@ -1167,7 +1172,7 @@ class WaylandInputMethodContextNoKeyboardTest
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(TextInput,
|
||||
INSTANTIATE_TEST_SUITE_P(TextInputV1,
|
||||
WaylandInputMethodContextNoKeyboardTest,
|
||||
::testing::Values(wl::ServerConfig{}));
|
||||
|
||||
@ -1254,9 +1259,9 @@ TEST_P(WaylandInputMethodContextNoKeyboardTest, UpdateFocusBetweenTextFields) {
|
||||
});
|
||||
}
|
||||
|
||||
// For use in tests that simply test the WaylandInputMethodContext in isolation
|
||||
// without using a real v1/v3 wrapper.
|
||||
class WaylandInputMethodContextWithMockWrapperTest : public WaylandTestSimple {
|
||||
// For use in tests that test the WaylandInputMethodContext in isolation with a
|
||||
// mock V3 client.
|
||||
class WaylandInputMethodContextWithMockV3Test : public WaylandTestSimple {
|
||||
public:
|
||||
void SetUp() override {
|
||||
WaylandTestSimple::SetUp();
|
||||
@ -1266,10 +1271,10 @@ class WaylandInputMethodContextWithMockWrapperTest : public WaylandTestSimple {
|
||||
input_method_context_ = std::make_unique<WaylandInputMethodContext>(
|
||||
connection_.get(), keyboard_delegate_.get(),
|
||||
input_method_context_delegate_.get());
|
||||
auto mock_wrapper = std::make_unique<MockZWPTextInputWrapper>();
|
||||
auto mock_wrapper = std::make_unique<MockZwpTextInputV3>();
|
||||
mock_wrapper_ = mock_wrapper.get();
|
||||
input_method_context_->Init(
|
||||
true, std::move(mock_wrapper),
|
||||
input_method_context_->SetTextInputV3ForTesting(std::move(mock_wrapper));
|
||||
input_method_context_->SetDesktopEnvironmentForTesting(
|
||||
// Ensure by default it doesn't pick the current desktop from the system
|
||||
// the tests are running on.
|
||||
base::nix::DesktopEnvironment::DESKTOP_ENVIRONMENT_OTHER);
|
||||
@ -1280,10 +1285,10 @@ class WaylandInputMethodContextWithMockWrapperTest : public WaylandTestSimple {
|
||||
input_method_context_delegate_;
|
||||
std::unique_ptr<TestKeyboardDelegate> keyboard_delegate_;
|
||||
std::unique_ptr<WaylandInputMethodContext> input_method_context_;
|
||||
raw_ptr<MockZWPTextInputWrapper> mock_wrapper_;
|
||||
raw_ptr<MockZwpTextInputV3> mock_wrapper_;
|
||||
};
|
||||
|
||||
TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
TEST_F(WaylandInputMethodContextWithMockV3Test,
|
||||
SetSurroundingShortTextWithCompositionRange) {
|
||||
const std::u16string text(50, u'あ');
|
||||
constexpr gfx::Range range(20, 30);
|
||||
@ -1304,7 +1309,7 @@ TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
connection_->Flush();
|
||||
}
|
||||
|
||||
TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
TEST_F(WaylandInputMethodContextWithMockV3Test,
|
||||
SetSurroundingLongTextWithCompositionRange) {
|
||||
const std::u16string text(5000, u'あ');
|
||||
constexpr gfx::Range kRange(2800, 3200);
|
||||
@ -1325,7 +1330,7 @@ TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
kRange);
|
||||
}
|
||||
|
||||
TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
TEST_F(WaylandInputMethodContextWithMockV3Test,
|
||||
SetSurroundingLongTextWithCompositionRangeOutsideSurroundingTextRange) {
|
||||
const std::u16string text(5000, u'あ');
|
||||
constexpr gfx::Range kSelectionRange(2800, 3200);
|
||||
@ -1362,7 +1367,7 @@ TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
kSelectionRange);
|
||||
}
|
||||
|
||||
TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
TEST_F(WaylandInputMethodContextWithMockV3Test,
|
||||
SetSurroundingWithCompositionRangeOutideText) {
|
||||
const std::u16string text(5000, u'あ');
|
||||
constexpr gfx::Range kSelectionRange(2800, 3200);
|
||||
@ -1377,7 +1382,7 @@ TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
kSelectionRange);
|
||||
}
|
||||
|
||||
TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
TEST_F(WaylandInputMethodContextWithMockV3Test,
|
||||
SetSurroundingWithCompositionRangeInvalid) {
|
||||
const std::u16string text(5000, u'あ');
|
||||
constexpr gfx::Range kSelectionRange(2800, 3200);
|
||||
@ -1399,7 +1404,7 @@ TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
kSelectionRange);
|
||||
}
|
||||
|
||||
TEST_F(WaylandInputMethodContextWithMockWrapperTest, OnPreeditChanged) {
|
||||
TEST_F(WaylandInputMethodContextWithMockV3Test, OnPreeditChanged) {
|
||||
const std::u16string text(50, u'あ');
|
||||
const std::string text_utf8 = base::UTF16ToUTF8(text);
|
||||
|
||||
@ -1419,7 +1424,7 @@ TEST_F(WaylandInputMethodContextWithMockWrapperTest, OnPreeditChanged) {
|
||||
gfx::Range(20, 10));
|
||||
}
|
||||
|
||||
TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
TEST_F(WaylandInputMethodContextWithMockV3Test,
|
||||
OnPreeditChangedInvalidCursorEnd) {
|
||||
const std::u16string text(50, u'あ');
|
||||
const std::string text_utf8 = base::UTF16ToUTF8(text);
|
||||
@ -1443,7 +1448,7 @@ TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
gfx::Range(0, 0));
|
||||
}
|
||||
|
||||
TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
TEST_F(WaylandInputMethodContextWithMockV3Test,
|
||||
OnPreeditChangedGnomeWorkaround) {
|
||||
const std::u16string text(50, u'あ');
|
||||
const std::string text_utf8 = base::UTF16ToUTF8(text);
|
||||
@ -1453,9 +1458,8 @@ TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
input_method_context = std::make_unique<WaylandInputMethodContext>(
|
||||
connection_.get(), keyboard_delegate_.get(),
|
||||
input_method_context_delegate_.get());
|
||||
auto mock_wrapper = std::make_unique<MockZWPTextInputWrapper>();
|
||||
input_method_context->Init(true, std::move(mock_wrapper),
|
||||
base::nix::DESKTOP_ENVIRONMENT_KDE3);
|
||||
input_method_context->SetDesktopEnvironmentForTesting(
|
||||
base::nix::DESKTOP_ENVIRONMENT_KDE3);
|
||||
|
||||
input_method_context->OnPreeditString(text_utf8, {}, {60, 30});
|
||||
EXPECT_EQ(
|
||||
@ -1468,9 +1472,8 @@ TEST_F(WaylandInputMethodContextWithMockWrapperTest,
|
||||
input_method_context = std::make_unique<WaylandInputMethodContext>(
|
||||
connection_.get(), keyboard_delegate_.get(),
|
||||
input_method_context_delegate_.get());
|
||||
mock_wrapper = std::make_unique<MockZWPTextInputWrapper>();
|
||||
input_method_context->Init(true, std::move(mock_wrapper),
|
||||
base::nix::DESKTOP_ENVIRONMENT_GNOME);
|
||||
input_method_context->SetDesktopEnvironmentForTesting(
|
||||
base::nix::DESKTOP_ENVIRONMENT_GNOME);
|
||||
input_method_context->OnPreeditString(text_utf8, {}, {60, 30});
|
||||
EXPECT_EQ(
|
||||
input_method_context->predicted_state_for_testing().surrounding_text,
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_v1.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
@ -74,21 +74,28 @@ uint32_t InputTypeToContentPurpose(TextInputType input_type) {
|
||||
// Converts Chrome's TextInputType into wayland's content_hint.
|
||||
uint32_t InputFlagsToContentHint(int input_flags) {
|
||||
uint32_t hint = 0;
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCOMPLETE_ON)
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCOMPLETE_ON) {
|
||||
hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_COMPLETION;
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCORRECT_ON)
|
||||
}
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCORRECT_ON) {
|
||||
hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CORRECTION;
|
||||
}
|
||||
// No good match. Fallback to AUTO_CORRECTION.
|
||||
if (input_flags & TEXT_INPUT_FLAG_SPELLCHECK_ON)
|
||||
if (input_flags & TEXT_INPUT_FLAG_SPELLCHECK_ON) {
|
||||
hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CORRECTION;
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_CHARACTERS)
|
||||
}
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_CHARACTERS) {
|
||||
hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_UPPERCASE;
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS)
|
||||
}
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS) {
|
||||
hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_TITLECASE;
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_SENTENCES)
|
||||
}
|
||||
if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_SENTENCES) {
|
||||
hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CAPITALIZATION;
|
||||
if (input_flags & TEXT_INPUT_FLAG_HAS_BEEN_PASSWORD)
|
||||
}
|
||||
if (input_flags & TEXT_INPUT_FLAG_HAS_BEEN_PASSWORD) {
|
||||
hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_PASSWORD;
|
||||
}
|
||||
return hint;
|
||||
}
|
||||
|
||||
@ -106,8 +113,7 @@ std::vector<std::string> ParseModifiersMap(wl_array* array) {
|
||||
|
||||
// Returns ImeTextSpan style to be assigned. Maybe nullopt if it is not
|
||||
// supported.
|
||||
std::optional<ZWPTextInputWrapperClient::SpanStyle::Style> ConvertStyle(
|
||||
uint32_t style) {
|
||||
std::optional<SpanStyle::Style> ConvertStyle(uint32_t style) {
|
||||
switch (style) {
|
||||
case ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_DEFAULT:
|
||||
return {{ImeTextSpan::Type::kComposition, ImeTextSpan::Thickness::kNone}};
|
||||
@ -132,11 +138,10 @@ std::optional<ZWPTextInputWrapperClient::SpanStyle::Style> ConvertStyle(
|
||||
|
||||
} // namespace
|
||||
|
||||
ZWPTextInputWrapperV1::ZWPTextInputWrapperV1(
|
||||
ZwpTextInputV1Impl::ZwpTextInputV1Impl(
|
||||
WaylandConnection* connection,
|
||||
ZWPTextInputWrapperClient* client,
|
||||
zwp_text_input_manager_v1* text_input_manager)
|
||||
: connection_(connection), client_(client) {
|
||||
: connection_(connection) {
|
||||
static constexpr zwp_text_input_v1_listener kTextInputListener = {
|
||||
.enter = &OnEnter,
|
||||
.leave = &OnLeave,
|
||||
@ -159,103 +164,108 @@ ZWPTextInputWrapperV1::ZWPTextInputWrapperV1(
|
||||
zwp_text_input_v1_add_listener(obj_.get(), &kTextInputListener, this);
|
||||
}
|
||||
|
||||
ZWPTextInputWrapperV1::~ZWPTextInputWrapperV1() = default;
|
||||
ZwpTextInputV1Impl::~ZwpTextInputV1Impl() = default;
|
||||
|
||||
void ZWPTextInputWrapperV1::Reset() {
|
||||
void ZwpTextInputV1Impl::Reset() {
|
||||
ResetInputEventState();
|
||||
zwp_text_input_v1_reset(obj_.get());
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV1::Activate(WaylandWindow* window,
|
||||
TextInputClient::FocusReason reason) {
|
||||
void ZwpTextInputV1Impl::Activate(WaylandWindow* window) {
|
||||
DCHECK(connection_->seat());
|
||||
zwp_text_input_v1_activate(obj_.get(), connection_->seat()->wl_object(),
|
||||
window->root_surface()->surface());
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV1::Deactivate() {
|
||||
void ZwpTextInputV1Impl::SetClient(ZwpTextInputV1Client* context) {
|
||||
client_ = context;
|
||||
}
|
||||
|
||||
void ZwpTextInputV1Impl::OnClientDestroyed(ZwpTextInputV1Client* context) {
|
||||
if (client_ == context) {
|
||||
client_ = nullptr;
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void ZwpTextInputV1Impl::Deactivate() {
|
||||
DCHECK(connection_->seat());
|
||||
|
||||
zwp_text_input_v1_deactivate(obj_.get(), connection_->seat()->wl_object());
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV1::ShowInputPanel() {
|
||||
void ZwpTextInputV1Impl::ShowInputPanel() {
|
||||
zwp_text_input_v1_show_input_panel(obj_.get());
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV1::HideInputPanel() {
|
||||
void ZwpTextInputV1Impl::HideInputPanel() {
|
||||
zwp_text_input_v1_hide_input_panel(obj_.get());
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV1::SetCursorRect(const gfx::Rect& rect) {
|
||||
void ZwpTextInputV1Impl::SetCursorRect(const gfx::Rect& rect) {
|
||||
zwp_text_input_v1_set_cursor_rectangle(obj_.get(), rect.x(), rect.y(),
|
||||
rect.width(), rect.height());
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV1::SetSurroundingText(
|
||||
const std::string& text,
|
||||
const gfx::Range& preedit_range,
|
||||
const gfx::Range& selection_range) {
|
||||
void ZwpTextInputV1Impl::SetSurroundingText(const std::string& text,
|
||||
const gfx::Range& preedit_range,
|
||||
const gfx::Range& selection_range) {
|
||||
zwp_text_input_v1_set_surrounding_text(
|
||||
obj_.get(), text.c_str(), selection_range.start(), selection_range.end());
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV1::SetContentType(ui::TextInputType type,
|
||||
uint32_t flags,
|
||||
bool should_do_learning) {
|
||||
// If wayland compositor supports the extended version of set input type,
|
||||
// use it to avoid losing the info.
|
||||
// Otherwise, fallback to the standard set_content_type.
|
||||
void ZwpTextInputV1Impl::SetContentType(ui::TextInputType type,
|
||||
uint32_t flags,
|
||||
bool should_do_learning) {
|
||||
uint32_t content_purpose = InputTypeToContentPurpose(type);
|
||||
uint32_t content_hint = InputFlagsToContentHint(flags);
|
||||
if (!should_do_learning)
|
||||
if (!should_do_learning) {
|
||||
content_hint |= ZWP_TEXT_INPUT_V1_CONTENT_HINT_SENSITIVE_DATA;
|
||||
}
|
||||
zwp_text_input_v1_set_content_type(obj_.get(), content_hint, content_purpose);
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV1::ResetInputEventState() {
|
||||
void ZwpTextInputV1Impl::ResetInputEventState() {
|
||||
spans_.clear();
|
||||
preedit_cursor_ = -1;
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnEnter(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
struct wl_surface* surface) {
|
||||
void ZwpTextInputV1Impl::OnEnter(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
struct wl_surface* surface) {
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnLeave(void* data,
|
||||
struct zwp_text_input_v1* text_input) {
|
||||
void ZwpTextInputV1Impl::OnLeave(void* data,
|
||||
struct zwp_text_input_v1* text_input) {
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnModifiersMap(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
struct wl_array* map) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
|
||||
void ZwpTextInputV1Impl::OnModifiersMap(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
struct wl_array* map) {
|
||||
auto* self = static_cast<ZwpTextInputV1Impl*>(data);
|
||||
self->client_->OnModifiersMap(ParseModifiersMap(map));
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnInputPanelState(
|
||||
void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t state) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
|
||||
void ZwpTextInputV1Impl::OnInputPanelState(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t state) {
|
||||
auto* self = static_cast<ZwpTextInputV1Impl*>(data);
|
||||
self->client_->OnInputPanelState(state);
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnPreeditString(
|
||||
void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* text,
|
||||
const char* commit) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
|
||||
void ZwpTextInputV1Impl::OnPreeditString(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* text,
|
||||
const char* commit) {
|
||||
auto* self = static_cast<ZwpTextInputV1Impl*>(data);
|
||||
auto spans = std::move(self->spans_);
|
||||
int32_t preedit_cursor = self->preedit_cursor_;
|
||||
self->ResetInputEventState();
|
||||
@ -266,82 +276,77 @@ void ZWPTextInputWrapperV1::OnPreeditString(
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnPreeditStyling(
|
||||
void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t index,
|
||||
uint32_t length,
|
||||
uint32_t style) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
|
||||
self->spans_.push_back(
|
||||
ZWPTextInputWrapperClient::SpanStyle{index, length, ConvertStyle(style)});
|
||||
void ZwpTextInputV1Impl::OnPreeditStyling(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t index,
|
||||
uint32_t length,
|
||||
uint32_t style) {
|
||||
auto* self = static_cast<ZwpTextInputV1Impl*>(data);
|
||||
self->spans_.push_back(SpanStyle{index, length, ConvertStyle(style)});
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnPreeditCursor(
|
||||
void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
|
||||
void ZwpTextInputV1Impl::OnPreeditCursor(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index) {
|
||||
auto* self = static_cast<ZwpTextInputV1Impl*>(data);
|
||||
self->preedit_cursor_ = index;
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnCommitString(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* text) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
|
||||
void ZwpTextInputV1Impl::OnCommitString(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* text) {
|
||||
auto* self = static_cast<ZwpTextInputV1Impl*>(data);
|
||||
self->ResetInputEventState();
|
||||
self->client_->OnCommitString(text);
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnCursorPosition(
|
||||
void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index,
|
||||
int32_t anchor) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
|
||||
void ZwpTextInputV1Impl::OnCursorPosition(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index,
|
||||
int32_t anchor) {
|
||||
auto* self = static_cast<ZwpTextInputV1Impl*>(data);
|
||||
self->client_->OnCursorPosition(index, anchor);
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnDeleteSurroundingText(
|
||||
void ZwpTextInputV1Impl::OnDeleteSurroundingText(
|
||||
void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index,
|
||||
uint32_t length) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
|
||||
auto* self = static_cast<ZwpTextInputV1Impl*>(data);
|
||||
self->client_->OnDeleteSurroundingText(index, length);
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnKeysym(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state,
|
||||
uint32_t modifiers) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV1*>(data);
|
||||
void ZwpTextInputV1Impl::OnKeysym(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state,
|
||||
uint32_t modifiers) {
|
||||
auto* self = static_cast<ZwpTextInputV1Impl*>(data);
|
||||
self->client_->OnKeysym(key, state, modifiers, time);
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnLanguage(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* language) {
|
||||
void ZwpTextInputV1Impl::OnLanguage(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* language) {
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
||||
// static
|
||||
void ZWPTextInputWrapperV1::OnTextDirection(
|
||||
void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
uint32_t direction) {
|
||||
void ZwpTextInputV1Impl::OnTextDirection(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
uint32_t direction) {
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
200
ui/ozone/platform/wayland/host/zwp_text_input_v1.h
Normal file
200
ui/ozone/platform/wayland/host/zwp_text_input_v1.h
Normal file
@ -0,0 +1,200 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_V1_H_
|
||||
#define UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_V1_H_
|
||||
|
||||
#include <text-input-unstable-v1-client-protocol.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "ui/base/ime/text_input_client.h"
|
||||
#include "ui/ozone/platform/wayland/common/wayland_object.h"
|
||||
#include "ui/ozone/platform/wayland/host/span_style.h"
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
class Range;
|
||||
} // namespace gfx
|
||||
|
||||
namespace ui {
|
||||
|
||||
class WaylandConnection;
|
||||
class WaylandWindow;
|
||||
|
||||
// Client interface which handles wayland text input callbacks
|
||||
class ZwpTextInputV1Client {
|
||||
public:
|
||||
virtual ~ZwpTextInputV1Client() = default;
|
||||
|
||||
// Called when a new composing text (pre-edit) should be set around the
|
||||
// current cursor position. Any previously set composing text should
|
||||
// be removed.
|
||||
// Note that the preedit_cursor is byte-offset. It is the pre-edit cursor
|
||||
// position if the range is empty and selection otherwise.
|
||||
virtual void OnPreeditString(std::string_view text,
|
||||
const std::vector<SpanStyle>& spans,
|
||||
const gfx::Range& preedit_cursor) = 0;
|
||||
|
||||
// Called when a complete input sequence has been entered. The text to
|
||||
// commit could be either just a single character after a key press or the
|
||||
// result of some composing (pre-edit).
|
||||
virtual void OnCommitString(std::string_view text) = 0;
|
||||
|
||||
// Called when the cursor position or selection should be modified. The new
|
||||
// cursor position is applied on the next OnCommitString. |index| and |anchor|
|
||||
// are measured in UTF-8 bytes.
|
||||
virtual void OnCursorPosition(int32_t index, int32_t anchor) = 0;
|
||||
|
||||
// Called when client needs to delete all or part of the text surrounding
|
||||
// the cursor. |index| and |length| are expected to be a byte offset of |text|
|
||||
// passed via ZWPTextInputWrapper::SetSurroundingText.
|
||||
virtual void OnDeleteSurroundingText(int32_t index, uint32_t length) = 0;
|
||||
|
||||
// Notify when a key event was sent. Key events should not be used
|
||||
// for normal text input operations, which should be done with
|
||||
// commit_string, delete_surrounding_text, etc.
|
||||
virtual void OnKeysym(uint32_t key,
|
||||
uint32_t state,
|
||||
uint32_t modifiers,
|
||||
uint32_t time) = 0;
|
||||
|
||||
// Called when the visibility state of the input panel changed.
|
||||
// There's no detailed spec of |state|, and no actual implementor except
|
||||
// components/exo is found in the world at this moment.
|
||||
// Thus, in ozone/wayland use the lowest bit as boolean
|
||||
// (visible=1/invisible=0), and ignore other bits for future compatibility.
|
||||
virtual void OnInputPanelState(uint32_t state) = 0;
|
||||
|
||||
// Called when the modifiers map is updated.
|
||||
// Each element holds the XKB name represents a modifier, such as "Shift".
|
||||
// The position of the element represents the bit position of modifiers
|
||||
// on OnKeysym. E.g., if LSB of modifiers is set, modifiers_map[0] is
|
||||
// set, if (1 << 1) of modifiers is set, modifiers_map[1] is set, and so on.
|
||||
virtual void OnModifiersMap(std::vector<std::string> modifiers_map) = 0;
|
||||
};
|
||||
|
||||
// A wrapper around different versions of wayland text input protocols.
|
||||
// Wayland compositors support various different text input protocols which
|
||||
// all from Chromium point of view provide the functionality needed by Chromium
|
||||
// IME. This interface collects the functionality behind one wrapper API.
|
||||
class ZwpTextInputV1 {
|
||||
public:
|
||||
virtual ~ZwpTextInputV1() = default;
|
||||
|
||||
virtual void Reset() = 0;
|
||||
|
||||
virtual void SetClient(ZwpTextInputV1Client* context) = 0;
|
||||
virtual void OnClientDestroyed(ZwpTextInputV1Client* context) = 0;
|
||||
virtual void Activate(WaylandWindow* window) = 0;
|
||||
virtual void Deactivate() = 0;
|
||||
|
||||
virtual void ShowInputPanel() = 0;
|
||||
virtual void HideInputPanel() = 0;
|
||||
|
||||
virtual void SetCursorRect(const gfx::Rect& rect) = 0;
|
||||
virtual void SetSurroundingText(const std::string& text,
|
||||
const gfx::Range& preedit_range,
|
||||
const gfx::Range& selection_range) = 0;
|
||||
virtual void SetContentType(TextInputType type,
|
||||
uint32_t flags,
|
||||
bool should_do_learning) = 0;
|
||||
};
|
||||
|
||||
// Text input wrapper for text-input-unstable-v1
|
||||
class ZwpTextInputV1Impl : public ZwpTextInputV1 {
|
||||
public:
|
||||
ZwpTextInputV1Impl(WaylandConnection* connection,
|
||||
zwp_text_input_manager_v1* text_input_manager);
|
||||
ZwpTextInputV1Impl(const ZwpTextInputV1Impl&) = delete;
|
||||
ZwpTextInputV1Impl& operator=(const ZwpTextInputV1Impl&) = delete;
|
||||
~ZwpTextInputV1Impl() override;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
void SetClient(ZwpTextInputV1Client* context) override;
|
||||
void OnClientDestroyed(ZwpTextInputV1Client* context) override;
|
||||
void Activate(WaylandWindow* window) override;
|
||||
void Deactivate() override;
|
||||
|
||||
void ShowInputPanel() override;
|
||||
void HideInputPanel() override;
|
||||
|
||||
void SetCursorRect(const gfx::Rect& rect) override;
|
||||
void SetSurroundingText(const std::string& text,
|
||||
const gfx::Range& preedit_range,
|
||||
const gfx::Range& selection_range) override;
|
||||
void SetContentType(TextInputType type,
|
||||
uint32_t flags,
|
||||
bool should_do_learning) override;
|
||||
|
||||
private:
|
||||
void ResetInputEventState();
|
||||
|
||||
// zwp_text_input_v1_listener callbacks:
|
||||
static void OnEnter(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
struct wl_surface* surface);
|
||||
static void OnLeave(void* data, struct zwp_text_input_v1* text_input);
|
||||
static void OnModifiersMap(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
struct wl_array* map);
|
||||
static void OnInputPanelState(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t state);
|
||||
static void OnPreeditString(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* text,
|
||||
const char* commit);
|
||||
static void OnPreeditStyling(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t index,
|
||||
uint32_t length,
|
||||
uint32_t style);
|
||||
static void OnPreeditCursor(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index);
|
||||
static void OnCommitString(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* text);
|
||||
static void OnCursorPosition(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index,
|
||||
int32_t anchor);
|
||||
static void OnDeleteSurroundingText(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index,
|
||||
uint32_t length);
|
||||
static void OnKeysym(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state,
|
||||
uint32_t modifiers);
|
||||
static void OnLanguage(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* language);
|
||||
static void OnTextDirection(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
uint32_t direction);
|
||||
|
||||
const raw_ptr<WaylandConnection> connection_;
|
||||
wl::Object<zwp_text_input_v1> obj_;
|
||||
raw_ptr<ZwpTextInputV1Client> client_;
|
||||
|
||||
std::vector<SpanStyle> spans_;
|
||||
int32_t preedit_cursor_ = -1;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_V1_H_
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_v1.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
@ -12,9 +12,10 @@
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "text-input-unstable-v1-server-protocol.h"
|
||||
#include "ui/ozone/platform/wayland/host/span_style.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input_wrapper_client.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input_v1_client.h"
|
||||
#include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h"
|
||||
#include "ui/ozone/platform/wayland/test/wayland_test.h"
|
||||
|
||||
@ -24,26 +25,27 @@ using ::testing::Mock;
|
||||
|
||||
namespace ui {
|
||||
|
||||
class ZWPTextInputWrapperV1Test : public WaylandTestSimple {
|
||||
class ZwpTextInputV1Test : public WaylandTestSimple {
|
||||
public:
|
||||
void SetUp() override {
|
||||
WaylandTestSimple::SetUp();
|
||||
|
||||
wrapper_ = std::make_unique<ZWPTextInputWrapperV1>(
|
||||
connection_.get(), &test_client_, connection_->text_input_manager_v1());
|
||||
text_input_v1_ = std::make_unique<ZwpTextInputV1Impl>(
|
||||
connection_.get(), connection_->text_input_manager_v1());
|
||||
text_input_v1_->SetClient(&test_client_);
|
||||
}
|
||||
|
||||
protected:
|
||||
MockZWPTextInputWrapperClient test_client_;
|
||||
std::unique_ptr<ZWPTextInputWrapperV1> wrapper_;
|
||||
MockZwpTextInputV1Client test_client_;
|
||||
std::unique_ptr<ZwpTextInputV1> text_input_v1_;
|
||||
};
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV1Test, OnPreeditString) {
|
||||
TEST_F(ZwpTextInputV1Test, OnPreeditString) {
|
||||
constexpr std::string_view kPreeditString("PreeditString");
|
||||
constexpr int32_t kPreeditCursor = kPreeditString.size();
|
||||
EXPECT_CALL(test_client_,
|
||||
OnPreeditString(kPreeditString,
|
||||
std::vector<ZWPTextInputWrapperClient::SpanStyle>{
|
||||
std::vector<SpanStyle>{
|
||||
{0,
|
||||
static_cast<uint32_t>(kPreeditString.size()),
|
||||
{{ImeTextSpan::Type::kComposition,
|
||||
@ -62,7 +64,7 @@ TEST_F(ZWPTextInputWrapperV1Test, OnPreeditString) {
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV1Test, OnKeySym_TimestampPropagated) {
|
||||
TEST_F(ZwpTextInputV1Test, OnKeySym_TimestampPropagated) {
|
||||
uint32_t test_time = 666;
|
||||
|
||||
EXPECT_CALL(test_client_, OnKeysym(_, _, _, test_time));
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_v3.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@ -13,6 +13,7 @@
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "ui/base/wayland/wayland_client_input_types.h"
|
||||
#include "ui/gfx/range/range.h"
|
||||
#include "ui/ozone/platform/wayland/host/span_style.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_seat.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_window.h"
|
||||
@ -96,11 +97,10 @@ uint32_t InputFlagsToContentHint(int input_flags) {
|
||||
|
||||
} // namespace
|
||||
|
||||
ZWPTextInputWrapperV3::ZWPTextInputWrapperV3(
|
||||
ZwpTextInputV3Impl::ZwpTextInputV3Impl(
|
||||
WaylandConnection* connection,
|
||||
ZWPTextInputWrapperClient* client,
|
||||
zwp_text_input_manager_v3* text_input_manager)
|
||||
: connection_(connection), client_(client) {
|
||||
: connection_(connection) {
|
||||
static constexpr zwp_text_input_v3_listener kTextInputListener = {
|
||||
&OnEnter,
|
||||
&OnLeave,
|
||||
@ -118,9 +118,9 @@ ZWPTextInputWrapperV3::ZWPTextInputWrapperV3(
|
||||
zwp_text_input_v3_add_listener(text_input, &kTextInputListener, this);
|
||||
}
|
||||
|
||||
ZWPTextInputWrapperV3::~ZWPTextInputWrapperV3() = default;
|
||||
ZwpTextInputV3Impl::~ZwpTextInputV3Impl() = default;
|
||||
|
||||
void ZWPTextInputWrapperV3::Reset() {
|
||||
void ZwpTextInputV3Impl::Reset() {
|
||||
// Clear last sent values.
|
||||
ResetLastSentValues();
|
||||
// There is no explicit reset API in v3. See [1].
|
||||
@ -151,8 +151,18 @@ void ZWPTextInputWrapperV3::Reset() {
|
||||
Commit();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::Activate(WaylandWindow* window,
|
||||
TextInputClient::FocusReason reason) {
|
||||
void ZwpTextInputV3Impl::SetClient(ZwpTextInputV3Client* context) {
|
||||
client_ = context;
|
||||
}
|
||||
|
||||
void ZwpTextInputV3Impl::OnClientDestroyed(ZwpTextInputV3Client* context) {
|
||||
if (client_ == context) {
|
||||
client_ = nullptr;
|
||||
Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void ZwpTextInputV3Impl::Enable() {
|
||||
// Pending state is reset on enable.
|
||||
ResetPendingSetRequests();
|
||||
ResetPendingInputEvents();
|
||||
@ -160,7 +170,7 @@ void ZWPTextInputWrapperV3::Activate(WaylandWindow* window,
|
||||
Commit();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::Deactivate() {
|
||||
void ZwpTextInputV3Impl::Disable() {
|
||||
// Avoid sending pending requests if done is received after disabling.
|
||||
ResetPendingSetRequests();
|
||||
// Do not process pending input events after deactivating.
|
||||
@ -169,33 +179,7 @@ void ZWPTextInputWrapperV3::Deactivate() {
|
||||
Commit();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::ShowInputPanel() {
|
||||
VLOG(1) << __func__;
|
||||
// Unsupported in zwp_text_input_v3 yet. To be supported soon as per wayland
|
||||
// governance meeting on 2024-07-02:
|
||||
// https://gitlab.freedesktop.org/wayland/wayland-protocols/-/wikis/meetings
|
||||
//
|
||||
// Some earlier notes in
|
||||
// https://lists.freedesktop.org/archives/wayland-devel/2018-March/037341.html
|
||||
//
|
||||
// Calling enable here could be problematic, as enable clears state, so for
|
||||
// instance cursor position sent previously will be reset and the input method
|
||||
// popup will not appear next to the cursor after this.
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::HideInputPanel() {
|
||||
VLOG(1) << __func__;
|
||||
// Unsupported in zwp_text_input_v3 yet. To be supported soon as per wayland
|
||||
// governance meeting on 2024-07-02:
|
||||
// https://gitlab.freedesktop.org/wayland/wayland-protocols/-/wikis/meetings
|
||||
//
|
||||
// Some earlier notes in
|
||||
// https://lists.freedesktop.org/archives/wayland-devel/2018-March/037341.html
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::SetCursorRect(const gfx::Rect& rect) {
|
||||
void ZwpTextInputV3Impl::SetCursorRect(const gfx::Rect& rect) {
|
||||
if (last_sent_cursor_rect_ == rect) {
|
||||
// This is to avoid a loop in sending cursor rect and receiving pre-edit
|
||||
// string.
|
||||
@ -209,14 +193,14 @@ void ZWPTextInputWrapperV3::SetCursorRect(const gfx::Rect& rect) {
|
||||
Commit();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::SendCursorRect(const gfx::Rect& rect) {
|
||||
void ZwpTextInputV3Impl::SendCursorRect(const gfx::Rect& rect) {
|
||||
CHECK_EQ(commit_count_, last_done_serial_);
|
||||
zwp_text_input_v3_set_cursor_rectangle(obj_.get(), rect.x(), rect.y(),
|
||||
rect.width(), rect.height());
|
||||
last_sent_cursor_rect_ = rect;
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::SetSurroundingText(
|
||||
void ZwpTextInputV3Impl::SetSurroundingText(
|
||||
const std::string& text_with_preedit,
|
||||
const gfx::Range& preedit_range,
|
||||
const gfx::Range& selection_range) {
|
||||
@ -264,7 +248,7 @@ void ZWPTextInputWrapperV3::SetSurroundingText(
|
||||
Commit();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::SendSurroundingText(
|
||||
void ZwpTextInputV3Impl::SendSurroundingText(
|
||||
const SetSurroundingTextData& data) {
|
||||
CHECK_EQ(commit_count_, last_done_serial_);
|
||||
zwp_text_input_v3_set_surrounding_text(obj_.get(), data.text.c_str(),
|
||||
@ -272,14 +256,17 @@ void ZWPTextInputWrapperV3::SendSurroundingText(
|
||||
last_sent_surrounding_text_data_ = data;
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::SetContentType(ui::TextInputType type,
|
||||
uint32_t flags,
|
||||
bool should_do_learning) {
|
||||
void ZwpTextInputV3Impl::SetContentType(ui::TextInputType type,
|
||||
uint32_t flags,
|
||||
bool should_do_learning) {
|
||||
uint32_t content_hint = InputFlagsToContentHint(flags);
|
||||
if (!should_do_learning) {
|
||||
content_hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_SENSITIVE_DATA;
|
||||
}
|
||||
uint32_t content_purpose = InputTypeToContentPurpose(type);
|
||||
if (!should_do_learning) {
|
||||
content_hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_SENSITIVE_DATA;
|
||||
}
|
||||
ContentType content_type{content_hint, content_purpose};
|
||||
if (last_sent_content_type_ == content_type) {
|
||||
return;
|
||||
@ -292,14 +279,14 @@ void ZWPTextInputWrapperV3::SetContentType(ui::TextInputType type,
|
||||
Commit();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::SendContentType(const ContentType& content_type) {
|
||||
void ZwpTextInputV3Impl::SendContentType(const ContentType& content_type) {
|
||||
CHECK_EQ(commit_count_, last_done_serial_);
|
||||
zwp_text_input_v3_set_content_type(obj_.get(), content_type.content_hint,
|
||||
content_type.content_purpose);
|
||||
last_sent_content_type_ = content_type;
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::ApplyPendingSetRequests() {
|
||||
void ZwpTextInputV3Impl::ApplyPendingSetRequests() {
|
||||
bool commit = false;
|
||||
if (auto content_type = pending_set_content_type_) {
|
||||
SendContentType(*content_type);
|
||||
@ -319,67 +306,66 @@ void ZWPTextInputWrapperV3::ApplyPendingSetRequests() {
|
||||
}
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::ResetPendingSetRequests() {
|
||||
void ZwpTextInputV3Impl::ResetPendingSetRequests() {
|
||||
pending_set_cursor_rect_.reset();
|
||||
pending_set_content_type_.reset();
|
||||
pending_set_surrounding_text_.reset();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::ResetLastSentValues() {
|
||||
void ZwpTextInputV3Impl::ResetLastSentValues() {
|
||||
last_sent_cursor_rect_.reset();
|
||||
last_sent_content_type_.reset();
|
||||
last_sent_surrounding_text_data_.reset();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::ResetPendingInputEvents() {
|
||||
void ZwpTextInputV3Impl::ResetPendingInputEvents() {
|
||||
pending_preedit_.reset();
|
||||
pending_commit_.reset();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::Commit() {
|
||||
void ZwpTextInputV3Impl::Commit() {
|
||||
zwp_text_input_v3_commit(obj_.get());
|
||||
// It will wrap around to 0 once it reaches uint32_t max value. It is
|
||||
// expected that this will occur on the compositor side as well.
|
||||
++commit_count_;
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::OnEnter(void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
struct wl_surface* surface) {
|
||||
void ZwpTextInputV3Impl::OnEnter(void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
struct wl_surface* surface) {
|
||||
// Same as text-input-v1, we don't use this for text-input focus changes and
|
||||
// instead use wayland keyboard enter/leave events to activate or deactivate
|
||||
// text-input.
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::OnLeave(void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
struct wl_surface* surface) {
|
||||
void ZwpTextInputV3Impl::OnLeave(void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
struct wl_surface* surface) {
|
||||
// Same as text-input-v1, we don't use this for text-input focus changes and
|
||||
// instead use wayland keyboard enter/leave events to activate or deactivate
|
||||
// text-input.
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::OnPreeditString(
|
||||
void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
const char* text,
|
||||
int32_t cursor_begin,
|
||||
int32_t cursor_end) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV3*>(data);
|
||||
void ZwpTextInputV3Impl::OnPreeditString(void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
const char* text,
|
||||
int32_t cursor_begin,
|
||||
int32_t cursor_end) {
|
||||
auto* self = static_cast<ZwpTextInputV3Impl*>(data);
|
||||
self->pending_preedit_ = {text ? text : std::string(), cursor_begin,
|
||||
cursor_end};
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::OnCommitString(void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
const char* text) {
|
||||
auto* self = static_cast<ZWPTextInputWrapperV3*>(data);
|
||||
void ZwpTextInputV3Impl::OnCommitString(void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
const char* text) {
|
||||
auto* self = static_cast<ZwpTextInputV3Impl*>(data);
|
||||
self->pending_commit_ = text ? text : std::string();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::OnDeleteSurroundingText(
|
||||
void ZwpTextInputV3Impl::OnDeleteSurroundingText(
|
||||
void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
uint32_t before_length,
|
||||
@ -387,11 +373,16 @@ void ZWPTextInputWrapperV3::OnDeleteSurroundingText(
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
||||
void ZWPTextInputWrapperV3::OnDone(void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
uint32_t serial) {
|
||||
void ZwpTextInputV3Impl::OnDone(void* data,
|
||||
struct zwp_text_input_v3* text_input,
|
||||
uint32_t serial) {
|
||||
// TODO(crbug.com/40113488) apply delete surrounding
|
||||
auto* self = static_cast<ZWPTextInputWrapperV3*>(data);
|
||||
auto* self = static_cast<ZwpTextInputV3Impl*>(data);
|
||||
|
||||
if (!self->client_) {
|
||||
self->last_done_serial_ = serial;
|
||||
return;
|
||||
}
|
||||
|
||||
if (const auto& commit_string = self->pending_commit_) {
|
||||
// Replace the existing preedit with the commit string.
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_V3_H_
|
||||
#define UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_V3_H_
|
||||
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_V3_H_
|
||||
#define UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_V3_H_
|
||||
|
||||
#include <text-input-unstable-v3-client-protocol.h>
|
||||
|
||||
@ -11,34 +11,69 @@
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "ui/base/ime/text_input_mode.h"
|
||||
#include "ui/base/ime/text_input_type.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/range/range.h"
|
||||
#include "ui/ozone/platform/wayland/common/wayland_object.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
struct SpanStyle;
|
||||
class WaylandConnection;
|
||||
class WaylandWindow;
|
||||
|
||||
// Text input wrapper for text-input-unstable-v3
|
||||
class ZWPTextInputWrapperV3 : public ZWPTextInputWrapper {
|
||||
class ZwpTextInputV3Client {
|
||||
public:
|
||||
ZWPTextInputWrapperV3(WaylandConnection* connection,
|
||||
ZWPTextInputWrapperClient* client,
|
||||
zwp_text_input_manager_v3* text_input_manager);
|
||||
ZWPTextInputWrapperV3(const ZWPTextInputWrapperV3&) = delete;
|
||||
ZWPTextInputWrapperV3& operator=(const ZWPTextInputWrapperV3&) = delete;
|
||||
~ZWPTextInputWrapperV3() override;
|
||||
virtual ~ZwpTextInputV3Client() = default;
|
||||
|
||||
// Called when a new composing text (pre-edit) should be set around the
|
||||
// current cursor position. Any previously set composing text should
|
||||
// be removed.
|
||||
// Note that the preedit_cursor is byte-offset. It is the pre-edit cursor
|
||||
// position if the range is empty and selection otherwise.
|
||||
virtual void OnPreeditString(std::string_view text,
|
||||
const std::vector<SpanStyle>& spans,
|
||||
const gfx::Range& preedit_cursor) = 0;
|
||||
|
||||
// Called when a complete input sequence has been entered. The text to
|
||||
// commit could be either just a single character after a key press or the
|
||||
// result of some composing (pre-edit).
|
||||
virtual void OnCommitString(std::string_view text) = 0;
|
||||
};
|
||||
|
||||
class ZwpTextInputV3 {
|
||||
public:
|
||||
virtual ~ZwpTextInputV3() = default;
|
||||
|
||||
virtual void SetClient(ZwpTextInputV3Client* context) = 0;
|
||||
virtual void OnClientDestroyed(ZwpTextInputV3Client* context) = 0;
|
||||
virtual void Enable() = 0;
|
||||
virtual void Disable() = 0;
|
||||
virtual void Reset() = 0;
|
||||
virtual void SetCursorRect(const gfx::Rect& rect) = 0;
|
||||
virtual void SetSurroundingText(const std::string& text,
|
||||
const gfx::Range& preedit_range,
|
||||
const gfx::Range& selection_range) = 0;
|
||||
virtual void SetContentType(TextInputType type,
|
||||
uint32_t flags,
|
||||
bool should_do_learning) = 0;
|
||||
};
|
||||
|
||||
// Represents a zwp_text_input_v3 object.
|
||||
class ZwpTextInputV3Impl : public ZwpTextInputV3 {
|
||||
public:
|
||||
ZwpTextInputV3Impl(WaylandConnection* connection,
|
||||
zwp_text_input_manager_v3* text_input_manager);
|
||||
ZwpTextInputV3Impl(const ZwpTextInputV3Impl&) = delete;
|
||||
ZwpTextInputV3Impl& operator=(const ZwpTextInputV3Impl&) = delete;
|
||||
~ZwpTextInputV3Impl() override;
|
||||
|
||||
void SetClient(ZwpTextInputV3Client* context) override;
|
||||
void OnClientDestroyed(ZwpTextInputV3Client* context) override;
|
||||
void Enable() override;
|
||||
void Disable() override;
|
||||
void Reset() override;
|
||||
|
||||
void Activate(WaylandWindow* window,
|
||||
ui::TextInputClient::FocusReason reason) override;
|
||||
void Deactivate() override;
|
||||
|
||||
void ShowInputPanel() override;
|
||||
void HideInputPanel() override;
|
||||
|
||||
void SetCursorRect(const gfx::Rect& rect) override;
|
||||
void SetSurroundingText(const std::string& text,
|
||||
const gfx::Range& preedit_range,
|
||||
@ -114,7 +149,7 @@ class ZWPTextInputWrapperV3 : public ZWPTextInputWrapper {
|
||||
|
||||
const raw_ptr<WaylandConnection> connection_;
|
||||
wl::Object<zwp_text_input_v3> obj_;
|
||||
const raw_ptr<ZWPTextInputWrapperClient> client_;
|
||||
raw_ptr<ZwpTextInputV3Client> client_;
|
||||
uint32_t commit_count_ = 0;
|
||||
uint32_t last_done_serial_ = 0;
|
||||
|
||||
@ -135,4 +170,4 @@ class ZWPTextInputWrapperV3 : public ZWPTextInputWrapper {
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_V3_H_
|
||||
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_V3_H_
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_v3.h"
|
||||
|
||||
#include <text-input-unstable-v3-client-protocol.h>
|
||||
#include <text-input-unstable-v3-server-protocol.h>
|
||||
@ -14,9 +14,10 @@
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/base/ime/text_input_flags.h"
|
||||
#include "ui/gfx/range/range.h"
|
||||
#include "ui/ozone/platform/wayland/host/span_style.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input_wrapper_client.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input_v3_client.h"
|
||||
#include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h"
|
||||
#include "ui/ozone/platform/wayland/test/wayland_test.h"
|
||||
|
||||
@ -26,17 +27,17 @@ using ::testing::Mock;
|
||||
|
||||
namespace ui {
|
||||
|
||||
class ZWPTextInputWrapperV3Test : public WaylandTestSimple {
|
||||
class ZwpTextInputV3Test : public WaylandTestSimple {
|
||||
public:
|
||||
ZWPTextInputWrapperV3Test()
|
||||
: WaylandTestSimple(
|
||||
{.text_input_wrapper_type = wl::ZWPTextInputWrapperType::kV3}) {}
|
||||
ZwpTextInputV3Test()
|
||||
: WaylandTestSimple({.text_input_type = wl::ZwpTextInputType::kV3}) {}
|
||||
|
||||
void SetUp() override {
|
||||
WaylandTestSimple::SetUp();
|
||||
|
||||
wrapper_ = std::make_unique<ZWPTextInputWrapperV3>(
|
||||
connection_.get(), &test_client_, connection_->text_input_manager_v3());
|
||||
text_input_v3_ = std::make_unique<ZwpTextInputV3Impl>(
|
||||
connection_.get(), connection_->text_input_manager_v3());
|
||||
text_input_v3_->SetClient(&test_client_);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -44,11 +45,11 @@ class ZWPTextInputWrapperV3Test : public WaylandTestSimple {
|
||||
Mock::VerifyAndClearExpectations(&test_client_);
|
||||
}
|
||||
|
||||
MockZWPTextInputWrapperClient test_client_;
|
||||
std::unique_ptr<ZWPTextInputWrapperV3> wrapper_;
|
||||
MockZwpTextInputV3Client test_client_;
|
||||
std::unique_ptr<ZwpTextInputV3> text_input_v3_;
|
||||
};
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, Activate) {
|
||||
TEST_F(ZwpTextInputV3Test, Enable) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
InSequence s;
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Enable())
|
||||
@ -56,10 +57,10 @@ TEST_F(ZWPTextInputWrapperV3Test, Activate) {
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Commit())
|
||||
.Times(1);
|
||||
});
|
||||
wrapper_->Activate(window_.get(), ui::TextInputClient::FOCUS_REASON_NONE);
|
||||
text_input_v3_->Enable();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, Deactivate) {
|
||||
TEST_F(ZwpTextInputV3Test, Disable) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
InSequence s;
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Disable())
|
||||
@ -67,10 +68,10 @@ TEST_F(ZWPTextInputWrapperV3Test, Deactivate) {
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Commit())
|
||||
.Times(1);
|
||||
});
|
||||
wrapper_->Deactivate();
|
||||
text_input_v3_->Disable();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, Reset) {
|
||||
TEST_F(ZwpTextInputV3Test, Reset) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
InSequence s;
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Disable())
|
||||
@ -82,34 +83,10 @@ TEST_F(ZWPTextInputWrapperV3Test, Reset) {
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Commit())
|
||||
.Times(1);
|
||||
});
|
||||
wrapper_->Reset();
|
||||
text_input_v3_->Reset();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, ShowInputPanel) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Enable())
|
||||
.Times(0);
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Disable())
|
||||
.Times(0);
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Commit())
|
||||
.Times(0);
|
||||
});
|
||||
wrapper_->ShowInputPanel();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, HideInputPanel) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Enable())
|
||||
.Times(0);
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Disable())
|
||||
.Times(0);
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Commit())
|
||||
.Times(0);
|
||||
});
|
||||
wrapper_->HideInputPanel();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, SetContentType) {
|
||||
TEST_F(ZwpTextInputV3Test, SetContentType) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
InSequence s;
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
@ -121,8 +98,8 @@ TEST_F(ZWPTextInputWrapperV3Test, SetContentType) {
|
||||
.Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, false);
|
||||
text_input_v3_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, false);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Calling again with the same values should be a no-op.
|
||||
@ -133,8 +110,8 @@ TEST_F(ZWPTextInputWrapperV3Test, SetContentType) {
|
||||
// Commit has been called once. So send done serial matching commit.
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 1);
|
||||
});
|
||||
wrapper_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, false);
|
||||
text_input_v3_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, false);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Calling with different values should work.
|
||||
@ -148,11 +125,11 @@ TEST_F(ZWPTextInputWrapperV3Test, SetContentType) {
|
||||
.Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->SetContentType(TEXT_INPUT_TYPE_NUMBER,
|
||||
TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS, false);
|
||||
text_input_v3_->SetContentType(TEXT_INPUT_TYPE_NUMBER,
|
||||
TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS, false);
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, SetCursorRect) {
|
||||
TEST_F(ZwpTextInputV3Test, SetCursorRect) {
|
||||
constexpr gfx::Rect kRect(50, 20, 1, 1);
|
||||
PostToServerAndWait([kRect](wl::TestWaylandServerThread* server) {
|
||||
InSequence s;
|
||||
@ -161,7 +138,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetCursorRect) {
|
||||
kRect.width(), kRect.height()));
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->SetCursorRect(kRect);
|
||||
text_input_v3_->SetCursorRect(kRect);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Calling again with the same values should be a no-op.
|
||||
@ -172,7 +149,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetCursorRect) {
|
||||
// Commit has been called once. So send done serial matching commit.
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 1);
|
||||
});
|
||||
wrapper_->SetCursorRect(kRect);
|
||||
text_input_v3_->SetCursorRect(kRect);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Calling again with different values should work.
|
||||
@ -185,11 +162,11 @@ TEST_F(ZWPTextInputWrapperV3Test, SetCursorRect) {
|
||||
SetCursorRect(kRect2.x(), kRect2.y(), kRect2.width(), kRect2.height()));
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->SetCursorRect(kRect2);
|
||||
text_input_v3_->SetCursorRect(kRect2);
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
TEST_F(ZwpTextInputV3Test, SetSurroundingText) {
|
||||
const std::string text("surroundingすしはおいしいですtext");
|
||||
constexpr std::string kSurroundingText("surroundingtext");
|
||||
constexpr gfx::Range kPreeditRange(11, 38);
|
||||
@ -204,7 +181,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*server->text_input_manager_v3()->text_input(), Commit())
|
||||
.Times(1);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// values unchanged
|
||||
@ -218,7 +195,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
// Ensure done serial matches commit count.
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 1);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text2, preedit_range2, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text2, preedit_range2, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// selection before preedit
|
||||
@ -230,7 +207,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
.Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// selection bounded by preedit
|
||||
@ -243,7 +220,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 2);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// selection starts inside preedit and ends after preedit
|
||||
@ -256,7 +233,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 3);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// selection starts inside preedit and ends after preedit (inverted selection)
|
||||
@ -269,7 +246,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 4);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// selection starts before preedit and ends inside preedit
|
||||
@ -282,7 +259,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 5);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// selection starts before preedit and ends inside preedit (inverted
|
||||
@ -296,7 +273,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 6);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// selection starts before preedit and ends after preedit
|
||||
@ -309,7 +286,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 7);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// selection after preedit
|
||||
@ -322,7 +299,7 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 8);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// invalid preedit
|
||||
@ -335,8 +312,8 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 9);
|
||||
});
|
||||
wrapper_->SetSurroundingText(kSurroundingText, gfx::Range::InvalidRange(),
|
||||
selection_range);
|
||||
text_input_v3_->SetSurroundingText(
|
||||
kSurroundingText, gfx::Range::InvalidRange(), selection_range);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// invalid selection
|
||||
@ -348,7 +325,8 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 10);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, gfx::Range::InvalidRange());
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange,
|
||||
gfx::Range::InvalidRange());
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// invalid preedit and selection
|
||||
@ -359,12 +337,12 @@ TEST_F(ZWPTextInputWrapperV3Test, SetSurroundingText) {
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 11);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, gfx::Range::InvalidRange(),
|
||||
gfx::Range::InvalidRange());
|
||||
text_input_v3_->SetSurroundingText(text, gfx::Range::InvalidRange(),
|
||||
gfx::Range::InvalidRange());
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsSentOnDone) {
|
||||
TEST_F(ZwpTextInputV3Test, PendingRequestsSentOnDone) {
|
||||
constexpr gfx::Rect kRect(50, 20, 1, 1);
|
||||
const std::string text("surroundingすしはおいしいですtext");
|
||||
constexpr std::string kSurroundingText("surroundingtext");
|
||||
@ -375,18 +353,18 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsSentOnDone) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input, Enable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable());
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Activate(window_.get(), ui::TextInputClient::FOCUS_REASON_NONE);
|
||||
text_input_v3_->Enable();
|
||||
VerifyAndClearExpectations();
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input, Enable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable());
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Activate(window_.get(), ui::TextInputClient::FOCUS_REASON_NONE);
|
||||
text_input_v3_->Enable();
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Now if commit number doesn't match done serial it shouldn't send a request.
|
||||
@ -399,36 +377,36 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsSentOnDone) {
|
||||
// Commit has been called twice. So done serial 1 should not match.
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 1);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, kSelectionRange);
|
||||
wrapper_->SetCursorRect(kRect);
|
||||
wrapper_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, true);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, kSelectionRange);
|
||||
text_input_v3_->SetCursorRect(kRect);
|
||||
text_input_v3_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, true);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Multiple pending requests should be sent when commit number finally
|
||||
// matches.
|
||||
PostToServerAndWait([kRect,
|
||||
kSurroundingText](wl::TestWaylandServerThread* server) {
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input,
|
||||
SetContentType(ZWP_TEXT_INPUT_V3_CONTENT_HINT_SPELLCHECK,
|
||||
ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_EMAIL))
|
||||
.Times(1);
|
||||
EXPECT_CALL(
|
||||
*server->text_input_manager_v3()->text_input(),
|
||||
SetCursorRect(kRect.x(), kRect.y(), kRect.width(), kRect.height()));
|
||||
EXPECT_CALL(*zwp_text_input,
|
||||
SetSurroundingText(kSurroundingText, gfx::Range{11, 11}))
|
||||
.Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
// Commit has been called twice. So done serial 2 should match.
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 2);
|
||||
});
|
||||
PostToServerAndWait(
|
||||
[kRect, kSurroundingText](wl::TestWaylandServerThread* server) {
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input,
|
||||
SetContentType(ZWP_TEXT_INPUT_V3_CONTENT_HINT_SPELLCHECK,
|
||||
ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_EMAIL))
|
||||
.Times(1);
|
||||
EXPECT_CALL(
|
||||
*server->text_input_manager_v3()->text_input(),
|
||||
SetCursorRect(kRect.x(), kRect.y(), kRect.width(), kRect.height()));
|
||||
EXPECT_CALL(*zwp_text_input,
|
||||
SetSurroundingText(kSurroundingText, gfx::Range{11, 11}))
|
||||
.Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
// Commit has been called twice. So done serial 2 should match.
|
||||
zwp_text_input_v3_send_done(zwp_text_input->resource(), 2);
|
||||
});
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnEnable) {
|
||||
TEST_F(ZwpTextInputV3Test, PendingRequestsClearedOnEnable) {
|
||||
constexpr gfx::Rect kRect(50, 20, 1, 1);
|
||||
const std::string text("surroundingすしはおいしいですtext");
|
||||
constexpr gfx::Range kPreeditRange(11, 38);
|
||||
@ -438,10 +416,10 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnEnable) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input, Enable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable());
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Activate(window_.get(), ui::TextInputClient::FOCUS_REASON_NONE);
|
||||
text_input_v3_->Enable();
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Pending set requests should not be sent without matching done event.
|
||||
@ -452,20 +430,20 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnEnable) {
|
||||
EXPECT_CALL(*zwp_text_input, SetSurroundingText(_, _)).Times(0);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(0);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, kSelectionRange);
|
||||
wrapper_->SetCursorRect(kRect);
|
||||
wrapper_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, true);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, kSelectionRange);
|
||||
text_input_v3_->SetCursorRect(kRect);
|
||||
text_input_v3_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, true);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Enable should clear pending requests.
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input, Enable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable());
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Activate(window_.get(), ui::TextInputClient::FOCUS_REASON_NONE);
|
||||
text_input_v3_->Enable();
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Since there are no more pending requests nothing should be sent even if
|
||||
@ -482,7 +460,7 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnEnable) {
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnDisable) {
|
||||
TEST_F(ZwpTextInputV3Test, PendingRequestsClearedOnDisable) {
|
||||
constexpr gfx::Rect kRect(50, 20, 1, 1);
|
||||
const std::string text("surroundingすしはおいしいですtext");
|
||||
constexpr gfx::Range kPreeditRange(11, 38);
|
||||
@ -492,10 +470,10 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnDisable) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input, Enable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable());
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Activate(window_.get(), ui::TextInputClient::FOCUS_REASON_NONE);
|
||||
text_input_v3_->Enable();
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Pending set requests should not be sent without matching done event.
|
||||
@ -506,10 +484,10 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnDisable) {
|
||||
EXPECT_CALL(*zwp_text_input, SetSurroundingText(_, _)).Times(0);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(0);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, kSelectionRange);
|
||||
wrapper_->SetCursorRect(kRect);
|
||||
wrapper_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, true);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, kSelectionRange);
|
||||
text_input_v3_->SetCursorRect(kRect);
|
||||
text_input_v3_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, true);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Disable should clear pending requests.
|
||||
@ -519,7 +497,7 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnDisable) {
|
||||
EXPECT_CALL(*zwp_text_input, Disable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Deactivate();
|
||||
text_input_v3_->Disable();
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Since there are no more pending requests nothing should be sent even if
|
||||
@ -536,7 +514,7 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnDisable) {
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnReset) {
|
||||
TEST_F(ZwpTextInputV3Test, PendingRequestsClearedOnReset) {
|
||||
constexpr gfx::Rect kRect(50, 20, 1, 1);
|
||||
const std::string text("surroundingすしはおいしいですtext");
|
||||
constexpr gfx::Range kPreeditRange(11, 38);
|
||||
@ -546,10 +524,10 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnReset) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input, Enable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable());
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Activate(window_.get(), ui::TextInputClient::FOCUS_REASON_NONE);
|
||||
text_input_v3_->Enable();
|
||||
|
||||
// Pending set requests should not be sent without matching done event.
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
@ -559,10 +537,10 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnReset) {
|
||||
EXPECT_CALL(*zwp_text_input, SetSurroundingText(_, _)).Times(0);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(0);
|
||||
});
|
||||
wrapper_->SetSurroundingText(text, kPreeditRange, kSelectionRange);
|
||||
wrapper_->SetCursorRect(kRect);
|
||||
wrapper_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, true);
|
||||
text_input_v3_->SetSurroundingText(text, kPreeditRange, kSelectionRange);
|
||||
text_input_v3_->SetCursorRect(kRect);
|
||||
text_input_v3_->SetContentType(TEXT_INPUT_TYPE_EMAIL,
|
||||
TEXT_INPUT_FLAG_AUTOCORRECT_ON, true);
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Reset should clear pending requests.
|
||||
@ -571,10 +549,10 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnReset) {
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input, Disable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable());
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Reset();
|
||||
text_input_v3_->Reset();
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Since there are no more pending requests nothing should be sent even if
|
||||
@ -592,14 +570,12 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingRequestsClearedOnReset) {
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, OnPreeditString) {
|
||||
TEST_F(ZwpTextInputV3Test, OnPreeditString) {
|
||||
constexpr std::string_view kPreeditString("PreeditString");
|
||||
constexpr gfx::Range kPreeditCursor{0, 13};
|
||||
EXPECT_CALL(
|
||||
test_client_,
|
||||
OnPreeditString(kPreeditString,
|
||||
std::vector<ZWPTextInputWrapperClient::SpanStyle>{},
|
||||
kPreeditCursor));
|
||||
EXPECT_CALL(test_client_,
|
||||
OnPreeditString(kPreeditString, std::vector<SpanStyle>{},
|
||||
kPreeditCursor));
|
||||
PostToServerAndWait(
|
||||
[kPreeditString, kPreeditCursor](wl::TestWaylandServerThread* server) {
|
||||
auto* text_input = server->text_input_manager_v3()->text_input();
|
||||
@ -611,11 +587,9 @@ TEST_F(ZWPTextInputWrapperV3Test, OnPreeditString) {
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Invalid range if negative cursor begin
|
||||
EXPECT_CALL(
|
||||
test_client_,
|
||||
OnPreeditString(kPreeditString,
|
||||
std::vector<ZWPTextInputWrapperClient::SpanStyle>{},
|
||||
gfx::Range::InvalidRange()));
|
||||
EXPECT_CALL(test_client_,
|
||||
OnPreeditString(kPreeditString, std::vector<SpanStyle>{},
|
||||
gfx::Range::InvalidRange()));
|
||||
PostToServerAndWait(
|
||||
[kPreeditString, kPreeditCursor](wl::TestWaylandServerThread* server) {
|
||||
auto* text_input = server->text_input_manager_v3()->text_input();
|
||||
@ -627,11 +601,9 @@ TEST_F(ZWPTextInputWrapperV3Test, OnPreeditString) {
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Invalid range if negative cursor end
|
||||
EXPECT_CALL(
|
||||
test_client_,
|
||||
OnPreeditString(kPreeditString,
|
||||
std::vector<ZWPTextInputWrapperClient::SpanStyle>{},
|
||||
gfx::Range::InvalidRange()));
|
||||
EXPECT_CALL(test_client_,
|
||||
OnPreeditString(kPreeditString, std::vector<SpanStyle>{},
|
||||
gfx::Range::InvalidRange()));
|
||||
PostToServerAndWait(
|
||||
[kPreeditString, kPreeditCursor](wl::TestWaylandServerThread* server) {
|
||||
auto* text_input = server->text_input_manager_v3()->text_input();
|
||||
@ -643,7 +615,7 @@ TEST_F(ZWPTextInputWrapperV3Test, OnPreeditString) {
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, OnCommitString) {
|
||||
TEST_F(ZwpTextInputV3Test, OnCommitString) {
|
||||
constexpr std::string kCommitString("CommitString");
|
||||
EXPECT_CALL(test_client_, OnCommitString(kCommitString));
|
||||
PostToServerAndWait([kCommitString](wl::TestWaylandServerThread* server) {
|
||||
@ -655,17 +627,15 @@ TEST_F(ZWPTextInputWrapperV3Test, OnCommitString) {
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, OnDoneWithCommitAndPreedit) {
|
||||
TEST_F(ZwpTextInputV3Test, OnDoneWithCommitAndPreedit) {
|
||||
constexpr std::string kPreeditString("PreeditString");
|
||||
constexpr gfx::Range kPreeditCursor{0, 13};
|
||||
constexpr std::string kCommitString("CommitString");
|
||||
InSequence s;
|
||||
EXPECT_CALL(test_client_, OnCommitString(kCommitString));
|
||||
EXPECT_CALL(
|
||||
test_client_,
|
||||
OnPreeditString(kPreeditString,
|
||||
std::vector<ZWPTextInputWrapperClient::SpanStyle>{},
|
||||
kPreeditCursor));
|
||||
EXPECT_CALL(test_client_,
|
||||
OnPreeditString(kPreeditString, std::vector<SpanStyle>{},
|
||||
kPreeditCursor));
|
||||
PostToServerAndWait([kPreeditString, kPreeditCursor,
|
||||
kCommitString](wl::TestWaylandServerThread* server) {
|
||||
auto* text_input = server->text_input_manager_v3()->text_input();
|
||||
@ -679,7 +649,7 @@ TEST_F(ZWPTextInputWrapperV3Test, OnDoneWithCommitAndPreedit) {
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, PendingInputEventsClearedOnEnable) {
|
||||
TEST_F(ZwpTextInputV3Test, PendingInputEventsClearedOnEnable) {
|
||||
constexpr std::string kCommitString("CommitString");
|
||||
constexpr std::string_view kPreeditString("PreeditString");
|
||||
constexpr gfx::Range kPreeditCursor{0, 13};
|
||||
@ -697,10 +667,10 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingInputEventsClearedOnEnable) {
|
||||
PostToServerAndWait([](wl::TestWaylandServerThread* server) {
|
||||
auto* zwp_text_input = server->text_input_manager_v3()->text_input();
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input, Enable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable());
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Activate(window_.get(), ui::TextInputClient::FOCUS_REASON_NONE);
|
||||
text_input_v3_->Enable();
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Sending done should have no effect.
|
||||
@ -713,7 +683,7 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingInputEventsClearedOnEnable) {
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, PendingInputEventsClearedOnDisable) {
|
||||
TEST_F(ZwpTextInputV3Test, PendingInputEventsClearedOnDisable) {
|
||||
constexpr std::string_view kPreeditString("PreeditString");
|
||||
constexpr gfx::Range kPreeditCursor{0, 13};
|
||||
PostToServerAndWait(
|
||||
@ -731,7 +701,7 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingInputEventsClearedOnDisable) {
|
||||
EXPECT_CALL(*zwp_text_input, Disable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Deactivate();
|
||||
text_input_v3_->Disable();
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Sending done should have no effect.
|
||||
@ -743,7 +713,7 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingInputEventsClearedOnDisable) {
|
||||
VerifyAndClearExpectations();
|
||||
}
|
||||
|
||||
TEST_F(ZWPTextInputWrapperV3Test, PendingInputEventsClearedOnReset) {
|
||||
TEST_F(ZwpTextInputV3Test, PendingInputEventsClearedOnReset) {
|
||||
constexpr std::string kCommitString("CommitString");
|
||||
constexpr std::string_view kPreeditString("PreeditString");
|
||||
constexpr gfx::Range kPreeditCursor{0, 13};
|
||||
@ -763,10 +733,10 @@ TEST_F(ZWPTextInputWrapperV3Test, PendingInputEventsClearedOnReset) {
|
||||
InSequence s;
|
||||
EXPECT_CALL(*zwp_text_input, Disable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable()).Times(1);
|
||||
EXPECT_CALL(*zwp_text_input, Enable());
|
||||
EXPECT_CALL(*zwp_text_input, Commit()).Times(1);
|
||||
});
|
||||
wrapper_->Reset();
|
||||
text_input_v3_->Reset();
|
||||
VerifyAndClearExpectations();
|
||||
|
||||
// Sending done should have no effect.
|
@ -1,128 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_H_
|
||||
#define UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "ui/base/ime/grammar_fragment.h"
|
||||
#include "ui/base/ime/text_input_client.h"
|
||||
#include "ui/base/ime/text_input_mode.h"
|
||||
#include "ui/base/ime/text_input_type.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
class Range;
|
||||
} // namespace gfx
|
||||
|
||||
namespace ui {
|
||||
|
||||
class WaylandWindow;
|
||||
|
||||
// Client interface which handles wayland text input callbacks
|
||||
class ZWPTextInputWrapperClient {
|
||||
public:
|
||||
struct SpanStyle {
|
||||
struct Style {
|
||||
bool operator==(const Style& other) const = default;
|
||||
|
||||
ImeTextSpan::Type type;
|
||||
ImeTextSpan::Thickness thickness;
|
||||
};
|
||||
|
||||
bool operator==(const SpanStyle& other) const = default;
|
||||
|
||||
// Byte offset.
|
||||
uint32_t index;
|
||||
// Length in bytes.
|
||||
uint32_t length;
|
||||
// One of preedit_style.
|
||||
std::optional<Style> style;
|
||||
};
|
||||
|
||||
virtual ~ZWPTextInputWrapperClient() = default;
|
||||
|
||||
// Called when a new composing text (pre-edit) should be set around the
|
||||
// current cursor position. Any previously set composing text should
|
||||
// be removed.
|
||||
// Note that the preedit_cursor is byte-offset. It is the pre-edit cursor
|
||||
// position if the range is empty and selection otherwise.
|
||||
virtual void OnPreeditString(std::string_view text,
|
||||
const std::vector<SpanStyle>& spans,
|
||||
const gfx::Range& preedit_cursor) = 0;
|
||||
|
||||
// Called when a complete input sequence has been entered. The text to
|
||||
// commit could be either just a single character after a key press or the
|
||||
// result of some composing (pre-edit).
|
||||
virtual void OnCommitString(std::string_view text) = 0;
|
||||
|
||||
// Called when the cursor position or selection should be modified. The new
|
||||
// cursor position is applied on the next OnCommitString. |index| and |anchor|
|
||||
// are measured in UTF-8 bytes.
|
||||
virtual void OnCursorPosition(int32_t index, int32_t anchor) = 0;
|
||||
|
||||
// Called when client needs to delete all or part of the text surrounding
|
||||
// the cursor. |index| and |length| are expected to be a byte offset of |text|
|
||||
// passed via ZWPTextInputWrapper::SetSurroundingText.
|
||||
virtual void OnDeleteSurroundingText(int32_t index, uint32_t length) = 0;
|
||||
|
||||
// Notify when a key event was sent. Key events should not be used
|
||||
// for normal text input operations, which should be done with
|
||||
// commit_string, delete_surrounding_text, etc.
|
||||
virtual void OnKeysym(uint32_t key,
|
||||
uint32_t state,
|
||||
uint32_t modifiers,
|
||||
uint32_t time) = 0;
|
||||
|
||||
// Called when the visibility state of the input panel changed.
|
||||
// There's no detailed spec of |state|, and no actual implementor except
|
||||
// components/exo is found in the world at this moment.
|
||||
// Thus, in ozone/wayland use the lowest bit as boolean
|
||||
// (visible=1/invisible=0), and ignore other bits for future compatibility.
|
||||
// This behavior must be consistent with components/exo.
|
||||
virtual void OnInputPanelState(uint32_t state) = 0;
|
||||
|
||||
// Called when the modifiers map is updated.
|
||||
// Each element holds the XKB name represents a modifier, such as "Shift".
|
||||
// The position of the element represents the bit position of modifiers
|
||||
// on OnKeysym. E.g., if LSB of modifiers is set, modifiers_map[0] is
|
||||
// set, if (1 << 1) of modifiers is set, modifiers_map[1] is set, and so on.
|
||||
virtual void OnModifiersMap(std::vector<std::string> modifiers_map) = 0;
|
||||
};
|
||||
|
||||
// A wrapper around different versions of wayland text input protocols.
|
||||
// Wayland compositors support various different text input protocols which
|
||||
// all from Chromium point of view provide the functionality needed by Chromium
|
||||
// IME. This interface collects the functionality behind one wrapper API.
|
||||
class ZWPTextInputWrapper {
|
||||
public:
|
||||
virtual ~ZWPTextInputWrapper() = default;
|
||||
|
||||
virtual void Reset() = 0;
|
||||
|
||||
virtual void Activate(WaylandWindow* window,
|
||||
ui::TextInputClient::FocusReason reason) = 0;
|
||||
virtual void Deactivate() = 0;
|
||||
|
||||
virtual void ShowInputPanel() = 0;
|
||||
virtual void HideInputPanel() = 0;
|
||||
|
||||
virtual void SetCursorRect(const gfx::Rect& rect) = 0;
|
||||
virtual void SetSurroundingText(const std::string& text,
|
||||
const gfx::Range& preedit_range,
|
||||
const gfx::Range& selection_range) = 0;
|
||||
virtual void SetContentType(ui::TextInputType type,
|
||||
uint32_t flags,
|
||||
bool should_do_learning) = 0;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_H_
|
@ -1,120 +0,0 @@
|
||||
// Copyright 2018 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_V1_H_
|
||||
#define UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_V1_H_
|
||||
|
||||
#include <text-input-unstable-v1-client-protocol.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "ui/ozone/platform/wayland/common/wayland_object.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h"
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
|
||||
class WaylandConnection;
|
||||
class WaylandWindow;
|
||||
|
||||
// Text input wrapper for text-input-unstable-v1
|
||||
class ZWPTextInputWrapperV1 : public ZWPTextInputWrapper {
|
||||
public:
|
||||
ZWPTextInputWrapperV1(WaylandConnection* connection,
|
||||
ZWPTextInputWrapperClient* client,
|
||||
zwp_text_input_manager_v1* text_input_manager);
|
||||
ZWPTextInputWrapperV1(const ZWPTextInputWrapperV1&) = delete;
|
||||
ZWPTextInputWrapperV1& operator=(const ZWPTextInputWrapperV1&) = delete;
|
||||
~ZWPTextInputWrapperV1() override;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
void Activate(WaylandWindow* window,
|
||||
ui::TextInputClient::FocusReason reason) override;
|
||||
void Deactivate() override;
|
||||
|
||||
void ShowInputPanel() override;
|
||||
void HideInputPanel() override;
|
||||
|
||||
void SetCursorRect(const gfx::Rect& rect) override;
|
||||
void SetSurroundingText(const std::string& text,
|
||||
const gfx::Range& preedit_range,
|
||||
const gfx::Range& selection_range) override;
|
||||
void SetContentType(TextInputType type,
|
||||
uint32_t flags,
|
||||
bool should_do_learning) override;
|
||||
|
||||
private:
|
||||
void ResetInputEventState();
|
||||
|
||||
// zwp_text_input_v1_listener callbacks:
|
||||
static void OnEnter(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
struct wl_surface* surface);
|
||||
static void OnLeave(void* data, struct zwp_text_input_v1* text_input);
|
||||
static void OnModifiersMap(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
struct wl_array* map);
|
||||
static void OnInputPanelState(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t state);
|
||||
static void OnPreeditString(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* text,
|
||||
const char* commit);
|
||||
static void OnPreeditStyling(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t index,
|
||||
uint32_t length,
|
||||
uint32_t style);
|
||||
static void OnPreeditCursor(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index);
|
||||
static void OnCommitString(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* text);
|
||||
static void OnCursorPosition(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index,
|
||||
int32_t anchor);
|
||||
static void OnDeleteSurroundingText(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
int32_t index,
|
||||
uint32_t length);
|
||||
static void OnKeysym(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state,
|
||||
uint32_t modifiers);
|
||||
static void OnLanguage(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
const char* language);
|
||||
static void OnTextDirection(void* data,
|
||||
struct zwp_text_input_v1* text_input,
|
||||
uint32_t serial,
|
||||
uint32_t direction);
|
||||
|
||||
const raw_ptr<WaylandConnection> connection_;
|
||||
wl::Object<zwp_text_input_v1> obj_;
|
||||
const raw_ptr<ZWPTextInputWrapperClient> client_;
|
||||
|
||||
std::vector<ZWPTextInputWrapperClient::SpanStyle> spans_;
|
||||
int32_t preedit_cursor_ = -1;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_V1_H_
|
@ -0,0 +1,12 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input_v1_client.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
MockZwpTextInputV1Client::MockZwpTextInputV1Client() = default;
|
||||
MockZwpTextInputV1Client::~MockZwpTextInputV1Client() = default;
|
||||
|
||||
} // namespace ui
|
@ -1,22 +1,21 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_ZWP_TEXT_INPUT_WRAPPER_CLIENT_H_
|
||||
#define UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_ZWP_TEXT_INPUT_WRAPPER_CLIENT_H_
|
||||
#ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_ZWP_TEXT_INPUT_V1_CLIENT_H_
|
||||
#define UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_ZWP_TEXT_INPUT_V1_CLIENT_H_
|
||||
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_v1.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class MockZWPTextInputWrapperClient : public ZWPTextInputWrapperClient {
|
||||
class MockZwpTextInputV1Client : public ZwpTextInputV1Client {
|
||||
public:
|
||||
MockZWPTextInputWrapperClient();
|
||||
MockZWPTextInputWrapperClient(const MockZWPTextInputWrapperClient&) = delete;
|
||||
MockZWPTextInputWrapperClient& operator=(
|
||||
const MockZWPTextInputWrapperClient&) = delete;
|
||||
~MockZWPTextInputWrapperClient() override;
|
||||
MockZwpTextInputV1Client();
|
||||
MockZwpTextInputV1Client(const MockZwpTextInputV1Client&) = delete;
|
||||
MockZwpTextInputV1Client& operator=(const MockZwpTextInputV1Client&) = delete;
|
||||
~MockZwpTextInputV1Client() override;
|
||||
|
||||
MOCK_METHOD(void,
|
||||
OnPreeditString,
|
||||
@ -46,4 +45,4 @@ class MockZWPTextInputWrapperClient : public ZWPTextInputWrapperClient {
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_ZWP_TEXT_INPUT_WRAPPER_CLIENT_H_
|
||||
#endif // UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_ZWP_TEXT_INPUT_V1_CLIENT_H_
|
@ -0,0 +1,14 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input_v3_client.h"
|
||||
|
||||
#include "ui/ozone/platform/wayland/host/span_style.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
MockZwpTextInputV3Client::MockZwpTextInputV3Client() = default;
|
||||
MockZwpTextInputV3Client::~MockZwpTextInputV3Client() = default;
|
||||
|
||||
} // namespace ui
|
@ -0,0 +1,31 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_ZWP_TEXT_INPUT_V3_CLIENT_H_
|
||||
#define UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_ZWP_TEXT_INPUT_V3_CLIENT_H_
|
||||
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_v3.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class MockZwpTextInputV3Client : public ZwpTextInputV3Client {
|
||||
public:
|
||||
MockZwpTextInputV3Client();
|
||||
MockZwpTextInputV3Client(const MockZwpTextInputV3Client&) = delete;
|
||||
MockZwpTextInputV3Client& operator=(const MockZwpTextInputV3Client&) = delete;
|
||||
~MockZwpTextInputV3Client() override;
|
||||
|
||||
MOCK_METHOD(void,
|
||||
OnPreeditString,
|
||||
(std::string_view text,
|
||||
const std::vector<SpanStyle>& spans,
|
||||
const gfx::Range& preedit_cursor),
|
||||
(override));
|
||||
MOCK_METHOD(void, OnCommitString, (std::string_view text), (override));
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_ZWP_TEXT_INPUT_V3_CLIENT_H_
|
@ -1,12 +0,0 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/wayland/test/mock_zwp_text_input_wrapper_client.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
MockZWPTextInputWrapperClient::MockZWPTextInputWrapperClient() = default;
|
||||
MockZWPTextInputWrapperClient::~MockZWPTextInputWrapperClient() = default;
|
||||
|
||||
} // namespace ui
|
@ -131,7 +131,7 @@ bool TestWaylandServerThread::Start() {
|
||||
if (!xdg_shell_.Initialize(display_.get()))
|
||||
return false;
|
||||
|
||||
if (config_.text_input_wrapper_type == ZWPTextInputWrapperType::kV3) {
|
||||
if (config_.text_input_type == ZwpTextInputType::kV3) {
|
||||
if (!zwp_text_input_manager_v3_.Initialize(display_.get())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "base/threading/thread.h"
|
||||
#include "base/threading/thread_checker.h"
|
||||
#include "ui/display/types/display_constants.h"
|
||||
#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h"
|
||||
#include "ui/ozone/platform/wayland/test/global_object.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_wayland_zcr_color_manager.h"
|
||||
#include "ui/ozone/platform/wayland/test/mock_wp_presentation.h"
|
||||
@ -56,11 +55,10 @@ enum class PrimarySelectionProtocol { kNone, kGtk, kZwp };
|
||||
enum class ShouldUseExplicitSynchronizationProtocol { kNone, kUse };
|
||||
enum class ShouldUseLinuxDrmSyncobjProtocol { kNone, kUse };
|
||||
// Text input protocol type.
|
||||
enum class ZWPTextInputWrapperType { kV1, kV3 };
|
||||
enum class ZwpTextInputType { kV1, kV3 };
|
||||
|
||||
struct ServerConfig {
|
||||
ZWPTextInputWrapperType text_input_wrapper_type =
|
||||
ZWPTextInputWrapperType::kV1;
|
||||
ZwpTextInputType text_input_type = ZwpTextInputType::kV1;
|
||||
TestCompositor::Version compositor_version = TestCompositor::Version::kV4;
|
||||
PrimarySelectionProtocol primary_selection_protocol =
|
||||
PrimarySelectionProtocol::kNone;
|
||||
|
Reference in New Issue
Block a user