* Add multi-step IME support to TextInputModel
This updates the platform-independent TextInputModel to add support for
input method (abbreviated IM or IME) composing regions.
In contrast to languages such as English, where keyboard input is
managed keystroke-by-keystroke, languages such as Japanese require a
multi-step input process wherein the user begins a composing sequence,
during which point their keystrokes are captured by a system input
method and converted into a text sequence. During composing, the user is
able to edit the composing range and manage the conversion from keyboard
input to text before eventually committing the text to the underlying
text input field.
To illustrate this, in Japanese, this sequence might look something like
the following:
1. User types 'k'. The character 'k' is added to the composing region.
Typically, the text 'k' will be inserted inline into the underlying
text field but the composing range will be highlighted in some manner,
frequently with a highlight or underline.
2. User types 'a'. The composing range is replaced with the phonetic
kana character 'か' (ka). The composing range continues to be
highlighted.
3. User types 'k'. The character 'k' is appended to the composing
range such that the highlighted text is now 'かk'
4. User types 'u'. The trailing 'k' is replaced with the phonetic kana
character 'く' (ku) such that the composing range now reads 'かく'
The composing range continues to be highlighted.
5. The user presses the space bar to convert the kana characters to
kanji. The composing range is replaced with '書く' (kaku: to write).
6. The user presses the space bar again to show other conversions. The
user's configured input method (for example, ibus) pops up a
completions menu populated with alternatives such as 各 (kaku:
every), 描く (kaku: to draw), 核 (kaku: pit of a fruit, nucleus), 角
(kaku: angle), etc.
7. The user uses the arrow keys to navigate the completions menu and
select the alternative to input. As they do, the inline composing
region in the text field is updated. It continues to be highlighted
or underlined.
8. The user hits enter to commit the composing region. The text is
committed to the underlying text field and the visual highlighting is
removed.
9. If the user presses another key, a new composing sequence begins.
If a selection is present when composing begins, it is preserved until
the first keypress of input is received, at which point the selection is
deleted. If a composing sequence is aborted before the first keypress,
the selection is preserved. Creating a new selection (with the mouse,
for example) aborts composing and the composing region is automatically
committed. A composing range and selection, both with an extent, are
not permitted to co-exist.
During composing, keyboard navigation via the arrow keys, or home and
end (or equivalent shortcuts) is restricted to the composing range, as
are deletions via backspace and the delete key. This patch adds two new
private convenience methods, `editing_range` and `text_range`. The
former returns the range for which editing is currently active -- the
composing range, if composing, otherwise the full range of the text. The
latter, returns a range from position 0 (inclusive) to `text_.length()`
exclusive.
* Move SetComposingLength to TextRange::set_*
Adds set_base, set_extent, set_start, set_end methods to TextRange.
Adds tests for TextRange::Contains(const TextRange&) where the range
being tested spans the base/extent of the testing range.
This was originally intended to land in #21854, but it seems I didn't
push the additional tests before landing.
The C++ wrapper's plugin registrar can own plugins to provided lifetime
management. However, plugins expect the registrar to be valid for the
life of the object, including during destruction, so any owned plugins
must be explicitly cleared before any registrar-specific destruction
happens.
Replaces selection_base() and selection_extent() with selection() and
SetSelection(int, int) with SetSelection(range).
This also adds the following convenience methods to TextRange:
* reversed()
* Contains(size_t position)
* Contains(const TextRange& range)
as well as operator== for use in unit tests. When Flutter migrates to
C++20, we can replace that method with a default declaration.
Previously Skia did not require the clients to pass in the usage flags and Skia would just assumed they contained specific ones depending on how the client wrapped the VkImage. Now Skia allows the client to pass in the specific usage flags used so that Skia knows exactly what type of operations are legal without having to guess/assume what the client did.
Also update to set the sample count as well while I'm in here.
[fuchsia] add intercept_all_input flag support
This change also fixes an issue where FlutterRunnerProductConfiguration
crashes when a field is missing, when building with --unopt.
Test: Added unit tests
Bug: fxb/61466, fxb/61942
Adds a support for compiling flutter engine when
gdk does not have X11 backend. In such a configuration
the generated gdkconfig.h header file looks like the following:
/* gdkconfig.h
*
* This is a generated file. Please modify `configure.ac'
*/
#ifndef __GDKCONFIG_H__
#define __GDKCONFIG_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <glib.h>
G_BEGIN_DECLS
#define GDK_WINDOWING_WAYLAND
G_END_DECLS
#endif /* __GDKCONFIG_H__ */
Additionally headers like <gdk/gdkx.h> are not available at all.
Above configuration can be found on the most of the embedded systems.
This patch enables compilation of X11 specific code only when gdk
defines GDK_WINDOWING_X11.
Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
* Revert "Fix documentation build for window changes. (#21780)"
This reverts commit a539d91840d2fbbb4aa07eeed6a92d654db167ab.
* Revert "Migration to PlatformDispatcher and multi-window (#20496)"
This reverts commit a58fec63f196175eedfc5fbaedce9336dab5c508.
Extracts a TextRange class with a base and extent, and start(), end(),
collapsed(), and length() getters.
The possibility of reversed base and extent in selections and composing
ranges makes reasoning about them complex and increases the chances of
errors in the code. This change migrates most uses of base and extent in
the text model to start()/end() or position(). The position() method is
intended purely as an aid to readability to indicate that a collapsed
selection is expected at the call site; it also enforces a debug-time
assertion that this is the case.
This reverts commit 19ebd61442fd3bf6a69af2156c8b118fc8578ec2.
Additionally, the following _flutter.runInView deadlock is fixed.
Previously, a deadlock would occur when service protocol
_flutter.runInView is used to restart the engine wihtout tearing down
the shell: the shared mutex of the service protocol will be locked
during the restart as it's in the middle of handling a service protocol
message; if ServiceProtocol::AddHandler is also called during the
restart, the deadlock happens as AddHandler also requires such lock.
test/integration.shard/background_isolate_test.dart would fail
without this fix.
This is a PR for converting the dart:ui code in the engine to use a multi-window API. The goal here is to convert from the window singleton to an API that has the concept of multiple windows. Also, I'm matching up the new PlatformDispatcher class to talk directly to the PlatformConfiguration class in the engine. I'm not attempting to actually enable creating multiple windows here, just migrate to an API that has a concept of multiple windows. The multi-window API in this PR currently only ever creates one window.
The design doc for this change is here.
The major changes in this PR:
Move the platfom-specific attributes out of Window, and into the new PlatformDispatcher class that holds all of the platform state, so that the platform code need only update the configuration on this class.
Create FlutterView, FlutterWindow, and SingletonFlutterWindow classes to separate out the concepts of a view (of which there may be multiple in a window), a window (of which there may be multiple on a screen, and they host views), and a window where there is only ever expected to be one (this hosts the entire API of the former Window class, and will eventually be the type of the window singleton).
Next step after this PR lands:
Remove the Window class entirely (it is replaced by SingletonFlutterWindow). Some minor changes in the Framework are needed to switch to using SingletonFlutterWindow directly first.
The Window class still exists in this PR, but will be removed as soon as the framework is converted to point to the SingletonFlutterWindow class instead. They share the same API, just have different names (Window is currently a subclass of SingletonFlutterWindow). The intention is that the Window name will be freed up to use as a widget class name in the framework for managing windows. The singleton called window will remain, and keep the same API it has now.
Follow up from #21436 . That PR works for all embeddings except for Android, which creates a special JNI AssetResolver. Since the shell cannot recreate this resolver, update the logic to preserve existing resolvers instead.
Previously, the selection base and extent were stored internally as
iterators over text_. Since iterators must be treated as invalidated
whenever the underlying container changes, this requires that
selection_base_ and selection_extent_ be re-assigned after every change
to text_.
This is not currently particularly problematic, but once we add fields
to track the base and extent of the composing region for multi-step
input method support, as well as support for the sub-range within the
composing region to which edits/completions apply, we end up having to
regenerate a lot of iterators with each change, many of which are
logically unchanged in position.
A side benefit is that this simplifies inspection of these fields when
debugging.