0001-ozone-wayland-implement-text_input_manager_v3.patch 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. From dba362808a97ced4f43635cbd73de6b06d156527 Mon Sep 17 00:00:00 2001
  2. From: Moon Sungjoon <sumoon@seoulsaram.org>
  3. Date: Wed, 26 Apr 2023 03:25:44 +0900
  4. Subject: [PATCH] ui/ozone/platform/wayland: Implement text_input_manager_v3
  5. Based on the original work of Lukas Lihotzki <lukas@lihotzki.de> in https://crrev.com/c/3015331
  6. Bug: 1227719
  7. Change-Id: Ib883c9087377c9f1a0dfacc45a27e3e67ccf042e
  8. ---
  9. diff --git a/AUTHORS b/AUTHORS
  10. index f275151..a43a528 100644
  11. --- a/AUTHORS
  12. +++ b/AUTHORS
  13. @@ -942,6 +942,7 @@ Mohit Bhalla <bhallam@amazon.com>
  14. Moiseanu Rares-Marian <moiseanurares@gmail.com>
  15. Momoka Yamamoto <momoka.my6@gmail.com>
  16. Momoko Hattori <momohatt10@gmail.com>
  17. +Moon Sungjoon <sumoon@seoulsaram.org>
  18. Mostafa Sedaghat joo <mostafa.sedaghat@gmail.com>
  19. Mrunal Kapade <mrunal.kapade@intel.com>
  20. Munira Tursunova <moonira@google.com>
  21. diff --git a/third_party/wayland-protocols/BUILD.gn b/third_party/wayland-protocols/BUILD.gn
  22. index c84ec11..dffa0aa 100644
  23. --- a/third_party/wayland-protocols/BUILD.gn
  24. +++ b/third_party/wayland-protocols/BUILD.gn
  25. @@ -141,7 +141,10 @@ wayland_protocol("text_input_extension_protocol") {
  26. }
  27. wayland_protocol("text_input_protocol") {
  28. - sources = [ "src/unstable/text-input/text-input-unstable-v1.xml" ]
  29. + sources = [
  30. + "src/unstable/text-input/text-input-unstable-v1.xml",
  31. + "src/unstable/text-input/text-input-unstable-v3.xml",
  32. + ]
  33. }
  34. wayland_protocol("touchpad_haptics_protocol") {
  35. diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
  36. index 31314f3..c22888c 100644
  37. --- a/ui/ozone/platform/wayland/BUILD.gn
  38. +++ b/ui/ozone/platform/wayland/BUILD.gn
  39. @@ -221,6 +221,8 @@ source_set("wayland") {
  40. "host/zwp_text_input_wrapper.h",
  41. "host/zwp_text_input_wrapper_v1.cc",
  42. "host/zwp_text_input_wrapper_v1.h",
  43. + "host/zwp_text_input_wrapper_v3.cc",
  44. + "host/zwp_text_input_wrapper_v3.h",
  45. "ozone_platform_wayland.cc",
  46. "ozone_platform_wayland.h",
  47. "wayland_utils.cc",
  48. diff --git a/ui/ozone/platform/wayland/common/wayland_object.cc b/ui/ozone/platform/wayland/common/wayland_object.cc
  49. index bcc48aa..009667b 100644
  50. --- a/ui/ozone/platform/wayland/common/wayland_object.cc
  51. +++ b/ui/ozone/platform/wayland/common/wayland_object.cc
  52. @@ -30,6 +30,7 @@
  53. #include <surface-augmenter-client-protocol.h>
  54. #include <text-input-extension-unstable-v1-client-protocol.h>
  55. #include <text-input-unstable-v1-client-protocol.h>
  56. +#include <text-input-unstable-v3-client-protocol.h>
  57. #include <touchpad-haptics-unstable-v1-client-protocol.h>
  58. #include <viewporter-client-protocol.h>
  59. #include <wayland-client-core.h>
  60. @@ -287,6 +288,8 @@ IMPLEMENT_WAYLAND_OBJECT_TRAITS(zwp_relative_pointer_manager_v1)
  61. IMPLEMENT_WAYLAND_OBJECT_TRAITS(zwp_relative_pointer_v1)
  62. IMPLEMENT_WAYLAND_OBJECT_TRAITS(zwp_text_input_manager_v1)
  63. IMPLEMENT_WAYLAND_OBJECT_TRAITS(zwp_text_input_v1)
  64. +IMPLEMENT_WAYLAND_OBJECT_TRAITS(zwp_text_input_manager_v3)
  65. +IMPLEMENT_WAYLAND_OBJECT_TRAITS(zwp_text_input_v3)
  66. IMPLEMENT_WAYLAND_OBJECT_TRAITS(zxdg_decoration_manager_v1)
  67. IMPLEMENT_WAYLAND_OBJECT_TRAITS(zxdg_exporter_v1)
  68. IMPLEMENT_WAYLAND_OBJECT_TRAITS(zxdg_exported_v1)
  69. diff --git a/ui/ozone/platform/wayland/common/wayland_object.h b/ui/ozone/platform/wayland/common/wayland_object.h
  70. index c84c084..0817e78 100644
  71. --- a/ui/ozone/platform/wayland/common/wayland_object.h
  72. +++ b/ui/ozone/platform/wayland/common/wayland_object.h
  73. @@ -202,6 +202,8 @@ DECLARE_WAYLAND_OBJECT_TRAITS(zwp_relative_pointer_manager_v1)
  74. DECLARE_WAYLAND_OBJECT_TRAITS(zwp_relative_pointer_v1)
  75. DECLARE_WAYLAND_OBJECT_TRAITS(zwp_text_input_manager_v1)
  76. DECLARE_WAYLAND_OBJECT_TRAITS(zwp_text_input_v1)
  77. +DECLARE_WAYLAND_OBJECT_TRAITS(zwp_text_input_manager_v3)
  78. +DECLARE_WAYLAND_OBJECT_TRAITS(zwp_text_input_v3)
  79. DECLARE_WAYLAND_OBJECT_TRAITS(zxdg_decoration_manager_v1)
  80. DECLARE_WAYLAND_OBJECT_TRAITS(zxdg_exporter_v1)
  81. DECLARE_WAYLAND_OBJECT_TRAITS(zxdg_exported_v1)
  82. diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
  83. index ad3bbd6..995b1e2 100644
  84. --- a/ui/ozone/platform/wayland/host/wayland_connection.cc
  85. +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
  86. @@ -647,6 +647,14 @@ void WaylandConnection::HandleGlobal(wl_registry* registry,
  87. strcmp(interface, "zcr_text_input_extension_v1") == 0) {
  88. text_input_extension_v1_ = wl::Bind<zcr_text_input_extension_v1>(
  89. registry, name, std::min(version, kMaxTextInputExtensionVersion));
  90. + } else if (!text_input_manager_v3_ &&
  91. + strcmp(interface, "zwp_text_input_manager_v3") == 0) {
  92. + text_input_manager_v3_ = wl::Bind<zwp_text_input_manager_v3>(
  93. + registry, name, std::min(version, kMaxTextInputManagerVersion));
  94. + if (!text_input_manager_v3_) {
  95. + LOG(ERROR) << "Failed to bind to zwp_text_input_manager_v3 global";
  96. + return;
  97. + }
  98. } else if (!xdg_decoration_manager_ &&
  99. strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
  100. xdg_decoration_manager_ = wl::Bind<zxdg_decoration_manager_v1>(
  101. diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h
  102. index 6659bc5..f9739ea 100644
  103. --- a/ui/ozone/platform/wayland/host/wayland_connection.h
  104. +++ b/ui/ozone/platform/wayland/host/wayland_connection.h
  105. @@ -149,6 +149,9 @@ class WaylandConnection {
  106. zcr_text_input_extension_v1* text_input_extension_v1() const {
  107. return text_input_extension_v1_.get();
  108. }
  109. + zwp_text_input_manager_v3* text_input_manager_v3() const {
  110. + return text_input_manager_v3_.get();
  111. + }
  112. zwp_linux_explicit_synchronization_v1* linux_explicit_synchronization_v1()
  113. const {
  114. return linux_explicit_synchronization_.get();
  115. @@ -447,6 +450,7 @@ class WaylandConnection {
  116. wl::Object<zcr_stylus_v2> zcr_stylus_v2_;
  117. wl::Object<zwp_text_input_manager_v1> text_input_manager_v1_;
  118. wl::Object<zcr_text_input_extension_v1> text_input_extension_v1_;
  119. + wl::Object<zwp_text_input_manager_v3> text_input_manager_v3_;
  120. wl::Object<zwp_linux_explicit_synchronization_v1>
  121. linux_explicit_synchronization_;
  122. wl::Object<zxdg_decoration_manager_v1> xdg_decoration_manager_;
  123. diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
  124. index caa5074..c2e1798 100644
  125. --- a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
  126. +++ b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
  127. @@ -35,6 +35,7 @@
  128. #include "ui/ozone/platform/wayland/host/wayland_seat.h"
  129. #include "ui/ozone/platform/wayland/host/wayland_window.h"
  130. #include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.h"
  131. +#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.h"
  132. #include "ui/ozone/public/ozone_switches.h"
  133. #if BUILDFLAG(USE_XKBCOMMON)
  134. @@ -285,11 +286,18 @@ void WaylandInputMethodContext::Init(bool initialize_for_testing) {
  135. // If text input instance is not created then all ime context operations
  136. // are noop. This option is because in some environments someone might not
  137. // want to enable ime/virtual keyboard even if it's available.
  138. - if (use_ozone_wayland_vkb && !text_input_ &&
  139. - connection_->text_input_manager_v1()) {
  140. + if (!use_ozone_wayland_vkb || text_input_)
  141. + return;
  142. +
  143. + // Prefer text_input_manager_v1 because it is more powerful.
  144. + // It supports preedit styling for example.
  145. + if (connection_->text_input_manager_v1()) {
  146. text_input_ = std::make_unique<ZWPTextInputWrapperV1>(
  147. connection_, this, connection_->text_input_manager_v1(),
  148. connection_->text_input_extension_v1());
  149. + } else if (connection_->text_input_manager_v3()) {
  150. + text_input_ = std::make_unique<ZWPTextInputWrapperV3>(
  151. + connection_, this, connection_->text_input_manager_v3());
  152. }
  153. }
  154. @@ -657,6 +665,11 @@ void WaylandInputMethodContext::OnCursorPosition(int32_t index,
  155. void WaylandInputMethodContext::OnDeleteSurroundingText(int32_t index,
  156. uint32_t length) {
  157. + // Never fail if length is 0.
  158. + if (length == 0) {
  159. + return;
  160. + }
  161. +
  162. const auto& [surrounding_text, utf16_offset, selection, unsused_composition] =
  163. surrounding_text_tracker_.predicted_state();
  164. DCHECK(selection.IsValid());
  165. diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.cc b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.cc
  166. new file mode 100644
  167. index 0000000..a3ce6e4
  168. --- /dev/null
  169. +++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.cc
  170. @@ -0,0 +1,239 @@
  171. +// Copyright 2023 The Chromium Authors
  172. +// Use of this source code is governed by a BSD-style license that can be
  173. +// found in the LICENSE file.
  174. +
  175. +#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.h"
  176. +
  177. +#include <string>
  178. +#include <utility>
  179. +
  180. +#include "base/logging.h"
  181. +#include "base/memory/ptr_util.h"
  182. +#include "ui/base/wayland/wayland_client_input_types.h"
  183. +#include "ui/gfx/range/range.h"
  184. +#include "ui/ozone/platform/wayland/host/wayland_connection.h"
  185. +#include "ui/ozone/platform/wayland/host/wayland_seat.h"
  186. +#include "ui/ozone/platform/wayland/host/wayland_window.h"
  187. +
  188. +namespace ui {
  189. +
  190. +// Converts Chrome's TextInputType into wayland's content_purpose.
  191. +// Some of TextInputType values do not have clearly corresponding wayland value,
  192. +// and they fallback to closer type.
  193. +uint32_t InputTypeToContentPurpose(TextInputType input_type) {
  194. + switch (input_type) {
  195. + case TEXT_INPUT_TYPE_NONE:
  196. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL;
  197. + case TEXT_INPUT_TYPE_TEXT:
  198. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL;
  199. + case TEXT_INPUT_TYPE_PASSWORD:
  200. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PASSWORD;
  201. + case TEXT_INPUT_TYPE_SEARCH:
  202. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL;
  203. + case TEXT_INPUT_TYPE_EMAIL:
  204. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_EMAIL;
  205. + case TEXT_INPUT_TYPE_NUMBER:
  206. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER;
  207. + case TEXT_INPUT_TYPE_TELEPHONE:
  208. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE;
  209. + case TEXT_INPUT_TYPE_URL:
  210. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL;
  211. + case TEXT_INPUT_TYPE_DATE:
  212. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATE;
  213. + case TEXT_INPUT_TYPE_DATE_TIME:
  214. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATETIME;
  215. + case TEXT_INPUT_TYPE_DATE_TIME_LOCAL:
  216. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATETIME;
  217. + case TEXT_INPUT_TYPE_MONTH:
  218. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATE;
  219. + case TEXT_INPUT_TYPE_TIME:
  220. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TIME;
  221. + case TEXT_INPUT_TYPE_WEEK:
  222. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATE;
  223. + case TEXT_INPUT_TYPE_TEXT_AREA:
  224. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL;
  225. + case TEXT_INPUT_TYPE_CONTENT_EDITABLE:
  226. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL;
  227. + case TEXT_INPUT_TYPE_DATE_TIME_FIELD:
  228. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATETIME;
  229. + case TEXT_INPUT_TYPE_NULL:
  230. + return ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL;
  231. + }
  232. +}
  233. +
  234. +// Converts Chrome's TextInputType into wayland's content_hint.
  235. +uint32_t InputFlagsToContentHint(int input_flags) {
  236. + uint32_t hint = 0;
  237. + if (input_flags & TEXT_INPUT_FLAG_AUTOCOMPLETE_ON)
  238. + hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_COMPLETION;
  239. + if (input_flags & TEXT_INPUT_FLAG_SPELLCHECK_ON)
  240. + hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_SPELLCHECK;
  241. + // No good match. Fallback to AUTO_CORRECTION.
  242. + if (input_flags & TEXT_INPUT_FLAG_AUTOCORRECT_ON)
  243. + hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_SPELLCHECK;
  244. + if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_CHARACTERS)
  245. + hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_AUTO_CAPITALIZATION;
  246. + if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_WORDS)
  247. + hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_AUTO_CAPITALIZATION;
  248. + if (input_flags & TEXT_INPUT_FLAG_AUTOCAPITALIZE_SENTENCES)
  249. + hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_AUTO_CAPITALIZATION;
  250. + if (input_flags & TEXT_INPUT_FLAG_HAS_BEEN_PASSWORD)
  251. + hint |= ZWP_TEXT_INPUT_V3_CONTENT_HINT_SENSITIVE_DATA;
  252. + return hint;
  253. +}
  254. +
  255. +ZWPTextInputWrapperV3::ZWPTextInputWrapperV3(
  256. + WaylandConnection* connection,
  257. + ZWPTextInputWrapperClient* client,
  258. + zwp_text_input_manager_v3* text_input_manager)
  259. + : connection_(connection), client_(client) {
  260. + static const zwp_text_input_v3_listener text_input_listener = {
  261. + &OnEnter, // text_input_enter,
  262. + &OnLeave, // text_input_leave,
  263. + &OnPreeditString, // text_input_preedit_string,
  264. + &OnCommitString, // text_input_commit_string,
  265. + &OnDeleteSurroundingText, // text_input_delete_surrounding_text,
  266. + &OnDone, // text_input_done,
  267. + };
  268. +
  269. + DCHECK(text_input_manager);
  270. + auto* text_input = zwp_text_input_manager_v3_get_text_input(
  271. + text_input_manager, connection_->seat()->wl_object());
  272. + obj_ = wl::Object<zwp_text_input_v3>(text_input);
  273. +
  274. + zwp_text_input_v3_add_listener(text_input, &text_input_listener, this);
  275. +}
  276. +
  277. +ZWPTextInputWrapperV3::~ZWPTextInputWrapperV3() = default;
  278. +
  279. +void ZWPTextInputWrapperV3::Reset() {
  280. + NOTIMPLEMENTED_LOG_ONCE();
  281. +}
  282. +
  283. +void ZWPTextInputWrapperV3::Activate(WaylandWindow* window,
  284. + TextInputClient::FocusReason reason) {
  285. + zwp_text_input_v3_enable(obj_.get());
  286. + zwp_text_input_v3_commit(obj_.get());
  287. +}
  288. +
  289. +void ZWPTextInputWrapperV3::Deactivate() {
  290. + zwp_text_input_v3_disable(obj_.get());
  291. + zwp_text_input_v3_commit(obj_.get());
  292. +}
  293. +
  294. +void ZWPTextInputWrapperV3::ShowInputPanel() {
  295. + // Not directly supported in zwp_text_input_v3
  296. + // Enable again to show the screen keyboard in GNOME:
  297. + // https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1543#note_1051704
  298. + zwp_text_input_v3_enable(obj_.get());
  299. + zwp_text_input_v3_commit(obj_.get());
  300. +}
  301. +
  302. +void ZWPTextInputWrapperV3::HideInputPanel() {
  303. + // unsupported in zwp_text_input_v3
  304. +}
  305. +
  306. +void ZWPTextInputWrapperV3::SetCursorRect(const gfx::Rect& rect) {
  307. + zwp_text_input_v3_set_cursor_rectangle(obj_.get(), rect.x(), rect.y(),
  308. + rect.width(), rect.height());
  309. + zwp_text_input_v3_commit(obj_.get());
  310. +}
  311. +
  312. +void ZWPTextInputWrapperV3::SetSurroundingText(
  313. + const std::string& text,
  314. + const gfx::Range& selection_range) {
  315. + zwp_text_input_v3_set_surrounding_text(
  316. + obj_.get(), text.c_str(), selection_range.start(), selection_range.end());
  317. + zwp_text_input_v3_commit(obj_.get());
  318. +}
  319. +
  320. +void ZWPTextInputWrapperV3::ResetPendingState() {
  321. + commit_string_.clear();
  322. + delete_surrounding_text_before_length_ = 0;
  323. + delete_surrounding_text_after_length_ = 0;
  324. + preedit_string_.clear();
  325. + preedit_string_cursor_begin_ = 0;
  326. + preedit_string_cursor_end_ = 0;
  327. +}
  328. +
  329. +void ZWPTextInputWrapperV3::SetContentType(ui::TextInputType type,
  330. + ui::TextInputMode mode,
  331. + uint32_t flags,
  332. + bool should_do_learning,
  333. + bool can_compose_inline) {
  334. + // V3 doesn't have extension
  335. + uint32_t content_purpose = InputTypeToContentPurpose(type);
  336. + uint32_t content_hint = InputFlagsToContentHint(flags);
  337. + static_cast<void>(flags);
  338. + static_cast<void>(should_do_learning);
  339. + zwp_text_input_v3_set_content_type(obj_.get(), content_hint, content_purpose);
  340. +}
  341. +
  342. +void ZWPTextInputWrapperV3::OnEnter(void* data,
  343. + struct zwp_text_input_v3* text_input,
  344. + struct wl_surface* surface) {
  345. + NOTIMPLEMENTED_LOG_ONCE();
  346. +}
  347. +
  348. +void ZWPTextInputWrapperV3::OnLeave(void* data,
  349. + struct zwp_text_input_v3* text_input,
  350. + struct wl_surface* surface) {
  351. + NOTIMPLEMENTED_LOG_ONCE();
  352. +}
  353. +
  354. +void ZWPTextInputWrapperV3::OnPreeditString(
  355. + void* data,
  356. + struct zwp_text_input_v3* text_input,
  357. + const char* text,
  358. + int32_t cursor_begin,
  359. + int32_t cursor_end) {
  360. + auto* wti = static_cast<ZWPTextInputWrapperV3*>(data);
  361. + wti->preedit_string_ = text ? text : "";
  362. + wti->preedit_string_cursor_begin_ = cursor_begin;
  363. + wti->preedit_string_cursor_end_ = cursor_end;
  364. +}
  365. +
  366. +void ZWPTextInputWrapperV3::OnCommitString(void* data,
  367. + struct zwp_text_input_v3* text_input,
  368. + const char* text) {
  369. + auto* wti = static_cast<ZWPTextInputWrapperV3*>(data);
  370. + wti->commit_string_ = text ? text : "";
  371. +}
  372. +
  373. +void ZWPTextInputWrapperV3::OnDeleteSurroundingText(
  374. + void* data,
  375. + struct zwp_text_input_v3* text_input,
  376. + uint32_t before_length,
  377. + uint32_t after_length) {
  378. + auto* wti = static_cast<ZWPTextInputWrapperV3*>(data);
  379. + wti->delete_surrounding_text_before_length_ = before_length;
  380. + wti->delete_surrounding_text_after_length_ = after_length;
  381. +}
  382. +
  383. +void ZWPTextInputWrapperV3::OnDone(void* data,
  384. + struct zwp_text_input_v3* text_input,
  385. + uint32_t serial) {
  386. + auto* wti = static_cast<ZWPTextInputWrapperV3*>(data);
  387. + wti->client_->OnPreeditString("", {}, 0);
  388. + wti->client_->OnDeleteSurroundingText(
  389. + -int32_t(wti->delete_surrounding_text_before_length_),
  390. + int32_t(wti->delete_surrounding_text_before_length_) +
  391. + int32_t(wti->delete_surrounding_text_after_length_));
  392. + wti->client_->OnCommitString(wti->commit_string_.c_str());
  393. + wti->client_->OnPreeditString(wti->preedit_string_.c_str(), {},
  394. + wti->preedit_string_cursor_begin_);
  395. + wti->ResetPendingState();
  396. +}
  397. +
  398. +void ZWPTextInputWrapperV3::SetGrammarFragmentAtCursor(
  399. + const ui::GrammarFragment& fragment) {
  400. + NOTIMPLEMENTED_LOG_ONCE();
  401. +}
  402. +
  403. +void ZWPTextInputWrapperV3::SetAutocorrectInfo(
  404. + const gfx::Range& autocorrect_range,
  405. + const gfx::Rect& autocorrect_bounds) {
  406. + NOTIMPLEMENTED_LOG_ONCE();
  407. +}
  408. +
  409. +} // namespace ui
  410. diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.h b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.h
  411. new file mode 100644
  412. index 0000000..204d7e3
  413. --- /dev/null
  414. +++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v3.h
  415. @@ -0,0 +1,98 @@
  416. +// Copyright 2023 The Chromium Authors
  417. +// Use of this source code is governed by a BSD-style license that can be
  418. +// found in the LICENSE file.
  419. +
  420. +#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_V3_H_
  421. +#define UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_V3_H_
  422. +
  423. +#include <cstdint>
  424. +#include <string>
  425. +
  426. +#include <text-input-unstable-v3-client-protocol.h>
  427. +
  428. +#include "base/memory/raw_ptr.h"
  429. +#include "ui/ozone/platform/wayland/common/wayland_object.h"
  430. +#include "ui/ozone/platform/wayland/host/zwp_text_input_wrapper.h"
  431. +
  432. +namespace gfx {
  433. +class Rect;
  434. +}
  435. +
  436. +namespace ui {
  437. +
  438. +class WaylandConnection;
  439. +class WaylandWindow;
  440. +
  441. +// Text input wrapper for text-input-unstable-v3
  442. +class ZWPTextInputWrapperV3 : public ZWPTextInputWrapper {
  443. + public:
  444. + ZWPTextInputWrapperV3(WaylandConnection* connection,
  445. + ZWPTextInputWrapperClient* client,
  446. + zwp_text_input_manager_v3* text_input_manager);
  447. + ZWPTextInputWrapperV3(const ZWPTextInputWrapperV3&) = delete;
  448. + ZWPTextInputWrapperV3& operator=(const ZWPTextInputWrapperV3&) = delete;
  449. + ~ZWPTextInputWrapperV3() override;
  450. +
  451. + void Reset() override;
  452. +
  453. + void Activate(WaylandWindow* window,
  454. + ui::TextInputClient::FocusReason reason) override;
  455. + void Deactivate() override;
  456. +
  457. + void ShowInputPanel() override;
  458. + void HideInputPanel() override;
  459. +
  460. + void SetCursorRect(const gfx::Rect& rect) override;
  461. + void SetSurroundingText(const std::string& text,
  462. + const gfx::Range& selection_range) override;
  463. + void SetContentType(TextInputType type,
  464. + TextInputMode mode,
  465. + uint32_t flags,
  466. + bool should_do_learning,
  467. + bool can_compose_inline) override;
  468. + void SetGrammarFragmentAtCursor(const ui::GrammarFragment& fragment) override;
  469. + void SetAutocorrectInfo(const gfx::Range& autocorrect_range,
  470. + const gfx::Rect& autocorrect_bounds) override;
  471. +
  472. + private:
  473. + void ResetPendingState();
  474. +
  475. + // zwp_text_input_v3_listener
  476. + static void OnEnter(void* data,
  477. + struct zwp_text_input_v3* text_input,
  478. + struct wl_surface* surface);
  479. + static void OnLeave(void* data,
  480. + struct zwp_text_input_v3* text_input,
  481. + struct wl_surface* surface);
  482. + static void OnPreeditString(void* data,
  483. + struct zwp_text_input_v3* text_input,
  484. + const char* text,
  485. + int32_t cursor_begin,
  486. + int32_t cursor_end);
  487. + static void OnCommitString(void* data,
  488. + struct zwp_text_input_v3* text_input,
  489. + const char* text);
  490. + static void OnDeleteSurroundingText(void* data,
  491. + struct zwp_text_input_v3* text_input,
  492. + uint32_t before_length,
  493. + uint32_t after_length);
  494. + static void OnDone(void* data,
  495. + struct zwp_text_input_v3* text_input,
  496. + uint32_t serial);
  497. +
  498. + const raw_ptr<WaylandConnection> connection_;
  499. + wl::Object<zwp_text_input_v3> obj_;
  500. + const raw_ptr<ZWPTextInputWrapperClient> client_;
  501. +
  502. + // pending state until OnDone
  503. + std::string commit_string_;
  504. + uint32_t delete_surrounding_text_before_length_ = 0;
  505. + uint32_t delete_surrounding_text_after_length_ = 0;
  506. + std::string preedit_string_; // preedit string of pending state
  507. + int32_t preedit_string_cursor_begin_ = 0;
  508. + int32_t preedit_string_cursor_end_ = 0;
  509. +};
  510. +
  511. +} // namespace ui
  512. +
  513. +#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_TEXT_INPUT_WRAPPER_V3_H_