Skip to content

Commit 6338298

Browse files
committed
input: add set_ime_editor_info
This corresponds to the GameActivity_setImeEditorInfo function on GameActivity. This is not supported on NativeActivity. Signed-off-by: William Casarin <[email protected]>
1 parent 69f3642 commit 6338298

File tree

3 files changed

+253
-2
lines changed

3 files changed

+253
-2
lines changed

android-activity/src/game_activity/mod.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ use crate::input::{Axis, KeyCharacterMap, KeyCharacterMapBinding};
2727
use crate::jni_utils::{self, CloneJavaVM};
2828
use crate::util::{abort_on_panic, forward_stdio_to_logcat, log_panic, try_get_path_from_ptr};
2929
use crate::{
30-
AndroidApp, ConfigurationRef, InputStatus, MainEvent, PollEvent, Rect, WindowManagerFlags,
30+
AndroidApp, ConfigurationRef, ImeOptions, InputStatus, InputType, MainEvent, PollEvent, Rect,
31+
WindowManagerFlags,
3132
};
3233

3334
mod ffi;
@@ -206,6 +207,22 @@ impl NativeAppGlue {
206207
}
207208
}
208209

210+
pub fn set_ime_editor_info(&self, input_type: InputType, options: ImeOptions) {
211+
unsafe {
212+
let activity = (*self.as_ptr()).activity;
213+
let action_id = 0; // IME_ACTION_UNSPECIFIED
214+
// (https://developer.android.com/reference/android/view/inputmethod/EditorInfo#IME_ACTION_DONE)
215+
// TODO: expose this later?
216+
217+
ffi::GameActivity_setImeEditorInfo(
218+
activity,
219+
input_type.bits(),
220+
action_id,
221+
options.bits(),
222+
);
223+
}
224+
}
225+
209226
// TODO: move into a trait
210227
pub fn set_text_input_state(&self, state: TextInputState) {
211228
unsafe {
@@ -521,6 +538,10 @@ impl AndroidAppInner {
521538
self.native_app.set_text_input_state(state);
522539
}
523540

541+
pub fn set_ime_editor_info(&self, input_type: InputType, options: ImeOptions) {
542+
self.native_app.set_ime_editor_info(input_type, options);
543+
}
544+
524545
pub(crate) fn device_key_character_map(
525546
&self,
526547
device_id: i32,

android-activity/src/lib.rs

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,222 @@ pub enum InputStatus {
335335
use activity_impl::AndroidAppInner;
336336
pub use activity_impl::AndroidAppWaker;
337337

338+
bitflags! {
339+
/// Flags for [`AndroidApp::set_ime_editor_info`]
340+
/// as per the [android.view.inputmethod.EditorInfo Java API](https://developer.android.com/reference/android/view/inputmethod/EditorInfo)
341+
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
342+
pub struct ImeOptions: u32 {
343+
/// If this flag is not set, IMEs will normally replace the "enter" key with the action
344+
/// supplied. This flag indicates that the action should not be available in-line as a
345+
/// replacement for the "enter" key. Typically this is because the action has such a
346+
/// significant impact or is not recoverable enough that accidentally hitting it should be
347+
/// avoided, such as sending a message.
348+
const IME_FLAG_NO_ENTER_ACTION = 1073741824;
349+
350+
/// Generic unspecified type for ImeOptions
351+
const IME_NULL = 0;
352+
353+
// TODO: remaining ime flags
354+
}
355+
}
356+
357+
bitflags! {
358+
/// Flags for [`AndroidApp::set_ime_editor_info`]
359+
/// as per the [android.view.inputmethod.EditorInfo Java API](https://developer.android.com/reference/android/view/inputmethod/EditorInfo)
360+
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
361+
pub struct InputType: u32 {
362+
/// Mask of bits that determine the overall class of text being given. Currently
363+
/// supported classes are: TYPE_CLASS_TEXT, TYPE_CLASS_NUMBER, TYPE_CLASS_PHONE,
364+
/// TYPE_CLASS_DATETIME. IME authors: If the class is not one you understand, assume
365+
/// TYPE_CLASS_TEXT with NO variation or flags.
366+
const TYPE_MASK_CLASS = 15;
367+
368+
/// Mask of bits that determine the variation of the base content class.
369+
const TYPE_MASK_VARIATION = 4080;
370+
371+
/// Mask of bits that provide addition bit flags of options.
372+
const TYPE_MASK_FLAGS = 16773120;
373+
374+
/// Special content type for when no explicit type has been specified. This should be
375+
/// interpreted to mean that the target input connection is not rich, it can not process
376+
/// and show things like candidate text nor retrieve the current text, so the input
377+
/// method will need to run in a limited "generate key events" mode, if it supports
378+
/// it. Note that some input methods may not support it, for example a voice-based
379+
/// input method will likely not be able to generate key events even if this flag is
380+
/// set.
381+
const TYPE_NULL = 0;
382+
383+
/// Class for normal text. This class supports the following flags (only one of which
384+
/// should be set): TYPE_TEXT_FLAG_CAP_CHARACTERS, TYPE_TEXT_FLAG_CAP_WORDS, and.
385+
/// TYPE_TEXT_FLAG_CAP_SENTENCES. It also supports the following variations:
386+
/// TYPE_TEXT_VARIATION_NORMAL, and TYPE_TEXT_VARIATION_URI. If you do not recognize the
387+
/// variation, normal should be assumed.
388+
const TYPE_CLASS_TEXT = 1;
389+
390+
/// Flag for TYPE_CLASS_TEXT: capitalize all characters. Overrides
391+
/// #TYPE_TEXT_FLAG_CAP_WORDS} and #TYPE_TEXT_FLAG_CAP_SENTENCES}. This value is
392+
/// explicitly defined to be the same as TextUtils#CAP_MODE_CHARACTERS}. Of
393+
/// course, this only affects languages where there are upper-case and lower-case
394+
/// letters.
395+
const TYPE_TEXT_FLAG_CAP_CHARACTERS = 4096;
396+
397+
/// Flag for TYPE_CLASS_TEXT: capitalize the first character of every word.
398+
/// Overrides TYPE_TEXT_FLAG_CAP_SENTENCES. This value is explicitly defined
399+
/// to be the same as TextUtils#CAP_MODE_WORDS. Of course, this only affects
400+
/// languages where there are upper-case and lower-case letters.
401+
const TYPE_TEXT_FLAG_CAP_WORDS = 8192;
402+
403+
/// Flag for TYPE_CLASS_TEXT: capitalize the first character of each sentence. This value
404+
/// is explicitly defined to be the same as TextUtils#CAP_MODE_SENTENCES. For example in
405+
/// English it means to capitalize after a period and a space (note that other languages
406+
/// may have different characters for period, or not use spaces, or use different
407+
/// grammatical rules). Of course, this only affects languages where there are upper-case
408+
/// and lower-case letters.
409+
const TYPE_TEXT_FLAG_CAP_SENTENCES = 16384;
410+
411+
/// Flag for TYPE_CLASS_TEXT: the user is entering free-form text that should have
412+
/// auto-correction applied to it. Without this flag, the IME will not try to correct
413+
/// typos. You should always set this flag unless you really expect users to type
414+
/// non-words in this field, for example to choose a name for a character in a game.
415+
/// Contrast this with TYPE_TEXT_FLAG_AUTO_COMPLETE and TYPE_TEXT_FLAG_NO_SUGGESTIONS:
416+
/// TYPE_TEXT_FLAG_AUTO_CORRECT means that the IME will try to auto-correct typos as the
417+
/// user is typing, but does not define whether the IME offers an interface to show
418+
/// suggestions.
419+
const TYPE_TEXT_FLAG_AUTO_CORRECT = 32768;
420+
421+
/// Flag for TYPE_CLASS_TEXT: the text editor (which means the application) is performing
422+
/// auto-completion of the text being entered based on its own semantics, which it will
423+
/// present to the user as they type. This generally means that the input method should
424+
/// not be showing candidates itself, but can expect the editor to supply its own
425+
/// completions/candidates from
426+
/// android.view.inputmethod.InputMethodSession#displayCompletions
427+
/// InputMethodSession.displayCompletions()} as a result of the editor calling
428+
/// android.view.inputmethod.InputMethodManager#displayCompletions
429+
/// InputMethodManager.displayCompletions()}. Note the contrast with
430+
/// TYPE_TEXT_FLAG_AUTO_CORRECT and TYPE_TEXT_FLAG_NO_SUGGESTIONS:
431+
/// TYPE_TEXT_FLAG_AUTO_COMPLETE means the editor should show an interface for displaying
432+
/// suggestions, but instead of supplying its own it will rely on the Editor to pass
433+
/// completions/corrections.
434+
const TYPE_TEXT_FLAG_AUTO_COMPLETE = 65536;
435+
436+
/// Flag for TYPE_CLASS_TEXT: multiple lines of text can be entered into the
437+
/// field. If this flag is not set, the text field will be constrained to a single
438+
/// line. The IME may also choose not to display an enter key when this flag is not set,
439+
/// as there should be no need to create new lines.
440+
const TYPE_TEXT_FLAG_MULTI_LINE = 131072;
441+
442+
/// Flag for TYPE_CLASS_TEXT: the regular text view associated with this should
443+
/// not be multi-line, but when a fullscreen input method is providing text it should
444+
/// use multiple lines if it can.
445+
const TYPE_TEXT_FLAG_IME_MULTI_LINE = 262144;
446+
447+
/// Flag for TYPE_CLASS_TEXT: the input method does not need to display any
448+
/// dictionary-based candidates. This is useful for text views that do not contain words
449+
/// from the language and do not benefit from any dictionary-based completions or
450+
/// corrections. It overrides the TYPE_TEXT_FLAG_AUTO_CORRECT value when set. Please
451+
/// avoid using this unless you are certain this is what you want. Many input methods need
452+
/// suggestions to work well, for example the ones based on gesture typing. Consider
453+
/// clearing TYPE_TEXT_FLAG_AUTO_CORRECT instead if you just do not want the IME to
454+
/// correct typos. Note the contrast with TYPE_TEXT_FLAG_AUTO_CORRECT and
455+
/// TYPE_TEXT_FLAG_AUTO_COMPLETE: TYPE_TEXT_FLAG_NO_SUGGESTIONS means the IME does not
456+
/// need to show an interface to display suggestions. Most IMEs will also take this to
457+
/// mean they do not need to try to auto-correct what the user is typing.
458+
const TYPE_TEXT_FLAG_NO_SUGGESTIONS = 524288;
459+
460+
/// Flag for TYPE_CLASS_TEXT: Let the IME know the text conversion suggestions are
461+
/// required by the application. Text conversion suggestion is for the transliteration
462+
/// languages which has pronunciation characters and target characters. When the user is
463+
/// typing the pronunciation charactes, the IME could provide the possible target
464+
/// characters to the user. When this flag is set, the IME should insert the text
465+
/// conversion suggestions through Builder#setTextConversionSuggestions(List)} and the
466+
/// TextAttribute} with initialized with the text conversion suggestions is provided by
467+
/// the IME to the application. To receive the additional information, the application
468+
/// needs to implement InputConnection#setComposingText(CharSequence, int,
469+
/// TextAttribute)}, InputConnection#setComposingRegion(int, int, TextAttribute)}, and
470+
/// InputConnection#commitText(CharSequence, int, TextAttribute)}.
471+
const TYPE_TEXT_FLAG_ENABLE_TEXT_CONVERSION_SUGGESTIONS = 1048576;
472+
/// Default variation of TYPE_CLASS_TEXT: plain old normal text.
473+
const TYPE_TEXT_VARIATION_NORMAL = 0;
474+
/// Variation of TYPE_CLASS_TEXT: entering a URI.
475+
const TYPE_TEXT_VARIATION_URI = 16;
476+
/// Variation of TYPE_CLASS_TEXT: entering an e-mail address.
477+
const TYPE_TEXT_VARIATION_EMAIL_ADDRESS = 32;
478+
/// Variation of TYPE_CLASS_TEXT: entering the subject line of an e-mail.
479+
const TYPE_TEXT_VARIATION_EMAIL_SUBJECT = 48;
480+
/// Variation of TYPE_CLASS_TEXT: entering a short, possibly informal message such as an instant message or a text message.
481+
const TYPE_TEXT_VARIATION_SHORT_MESSAGE = 64;
482+
/// Variation of TYPE_CLASS_TEXT: entering the content of a long, possibly formal message such as the body of an e-mail.
483+
const TYPE_TEXT_VARIATION_LONG_MESSAGE = 80;
484+
/// Variation of TYPE_CLASS_TEXT: entering the name of a person.
485+
const TYPE_TEXT_VARIATION_PERSON_NAME = 96;
486+
/// Variation of TYPE_CLASS_TEXT: entering a postal mailing address.
487+
const TYPE_TEXT_VARIATION_POSTAL_ADDRESS = 112;
488+
/// Variation of TYPE_CLASS_TEXT: entering a password.
489+
const TYPE_TEXT_VARIATION_PASSWORD = 128;
490+
/// Variation of TYPE_CLASS_TEXT: entering a password, which should be visible to the user.
491+
const TYPE_TEXT_VARIATION_VISIBLE_PASSWORD = 144;
492+
/// Variation of TYPE_CLASS_TEXT: entering text inside of a web form.
493+
const TYPE_TEXT_VARIATION_WEB_EDIT_TEXT = 160;
494+
/// Variation of TYPE_CLASS_TEXT: entering text to filter contents of a list etc.
495+
const TYPE_TEXT_VARIATION_FILTER = 176;
496+
/// Variation of TYPE_CLASS_TEXT: entering text for phonetic pronunciation, such as a
497+
/// phonetic name field in contacts. This is mostly useful for languages where one
498+
/// spelling may have several phonetic readings, like Japanese.
499+
const TYPE_TEXT_VARIATION_PHONETIC = 192;
500+
/// Variation of TYPE_CLASS_TEXT: entering e-mail address inside of a web form. This
501+
/// was added in android.os.Build.VERSION_CODES#HONEYCOMB}. An IME must target this API
502+
/// version or later to see this input type; if it doesn't, a request for this type will
503+
/// be seen as #TYPE_TEXT_VARIATION_EMAIL_ADDRESS} when passed through
504+
/// android.view.inputmethod.EditorInfo#makeCompatible(int)
505+
/// EditorInfo.makeCompatible(int)}.
506+
const TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS = 208;
507+
/// Variation of TYPE_CLASS_TEXT: entering password inside of a web form. This was
508+
/// added in android.os.Build.VERSION_CODES#HONEYCOMB}. An IME must target this API
509+
/// version or later to see this input type; if it doesn't, a request for this type will
510+
/// be seen as #TYPE_TEXT_VARIATION_PASSWORD} when passed through
511+
/// android.view.inputmethod.EditorInfo#makeCompatible(int)
512+
/// EditorInfo.makeCompatible(int)}.
513+
const TYPE_TEXT_VARIATION_WEB_PASSWORD = 224;
514+
/// Class for numeric text. This class supports the following flags:
515+
/// #TYPE_NUMBER_FLAG_SIGNED} and #TYPE_NUMBER_FLAG_DECIMAL}. It also supports the
516+
/// following variations: #TYPE_NUMBER_VARIATION_NORMAL} and
517+
/// #TYPE_NUMBER_VARIATION_PASSWORD}. <p>IME authors: If you do not recognize the
518+
/// variation, normal should be assumed.</p>
519+
const TYPE_CLASS_NUMBER = 2;
520+
/// Flag of TYPE_CLASS_NUMBER: the number is signed, allowing a positive or negative
521+
/// sign at the start.
522+
const TYPE_NUMBER_FLAG_SIGNED = 4096;
523+
/// Flag of TYPE_CLASS_NUMBER: the number is decimal, allowing a decimal point to
524+
/// provide fractional values.
525+
const TYPE_NUMBER_FLAG_DECIMAL = 8192;
526+
/// Default variation of TYPE_CLASS_NUMBER: plain normal numeric text. This was added
527+
/// in android.os.Build.VERSION_CODES#HONEYCOMB}. An IME must target this API version or
528+
/// later to see this input type; if it doesn't, a request for this type will be dropped
529+
/// when passed through android.view.inputmethod.EditorInfo#makeCompatible(int)
530+
/// EditorInfo.makeCompatible(int)}.
531+
const TYPE_NUMBER_VARIATION_NORMAL = 0;
532+
/// Variation of TYPE_CLASS_NUMBER: entering a numeric password. This was added in
533+
/// android.os.Build.VERSION_CODES#HONEYCOMB}. An IME must target this API version or
534+
/// later to see this input type; if it doesn't, a request for this type will be dropped
535+
/// when passed through android.view.inputmethod.EditorInfo#makeCompatible(int)
536+
/// EditorInfo.makeCompatible(int)}.
537+
const TYPE_NUMBER_VARIATION_PASSWORD = 16;
538+
/// Class for a phone number. This class currently supports no variations or flags.
539+
const TYPE_CLASS_PHONE = 3;
540+
/// Class for dates and times. It supports the following variations:
541+
/// #TYPE_DATETIME_VARIATION_NORMAL} #TYPE_DATETIME_VARIATION_DATE}, and
542+
/// #TYPE_DATETIME_VARIATION_TIME}.
543+
const TYPE_CLASS_DATETIME = 4;
544+
/// Default variation of #TYPE_CLASS_DATETIME}: allows entering both a date and time.
545+
const TYPE_DATETIME_VARIATION_NORMAL = 0;
546+
/// Default variation of #TYPE_CLASS_DATETIME}: allows entering only a date.
547+
const TYPE_DATETIME_VARIATION_DATE = 16;
548+
/// Default variation of #TYPE_CLASS_DATETIME}: allows entering only a time.
549+
const TYPE_DATETIME_VARIATION_TIME = 32;
550+
551+
}
552+
}
553+
338554
bitflags! {
339555
/// Flags for [`AndroidApp::set_window_flags`]
340556
/// as per the [android.view.WindowManager.LayoutParams Java API](https://developer.android.com/reference/android/view/WindowManager.LayoutParams)
@@ -711,6 +927,14 @@ impl AndroidApp {
711927
self.inner.read().unwrap().set_text_input_state(state);
712928
}
713929

930+
/// Set IME editor flags
931+
pub fn set_ime_editor_info(&self, input_type: InputType, options: ImeOptions) {
932+
self.inner
933+
.read()
934+
.unwrap()
935+
.set_ime_editor_info(input_type, options);
936+
}
937+
714938
/// Get an exclusive, lending iterator over buffered input events
715939
///
716940
/// Applications are expected to call this in-sync with their rendering or

android-activity/src/native_activity/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use crate::input::{Axis, KeyCharacterMap, KeyCharacterMapBinding};
1818
use crate::input::{TextInputState, TextSpan};
1919
use crate::jni_utils::{self, CloneJavaVM};
2020
use crate::{
21-
util, AndroidApp, ConfigurationRef, InputStatus, MainEvent, PollEvent, Rect, WindowManagerFlags,
21+
util, AndroidApp, ConfigurationRef, ImeOptions, InputStatus, InputType, MainEvent, PollEvent,
22+
Rect, WindowManagerFlags,
2223
};
2324

2425
pub mod input;
@@ -391,6 +392,11 @@ impl AndroidAppInner {
391392
// NOP: Unsupported
392393
}
393394

395+
// TODO: move into a trait
396+
pub fn set_ime_editor_info(&self, _input_type: InputType, _options: ImeOptions) {
397+
// NOP: Unsupported
398+
}
399+
394400
pub fn device_key_character_map(&self, device_id: i32) -> InternalResult<KeyCharacterMap> {
395401
let mut guard = self.key_maps.lock().unwrap();
396402

0 commit comments

Comments
 (0)