Skip to content

Commit 8db0d2b

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 1652ebb commit 8db0d2b

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
@@ -336,6 +336,222 @@ pub enum InputStatus {
336336
use activity_impl::AndroidAppInner;
337337
pub use activity_impl::AndroidAppWaker;
338338

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

931+
/// Set IME editor flags
932+
pub fn set_ime_editor_info(&self, input_type: InputType, options: ImeOptions) {
933+
self.inner
934+
.read()
935+
.unwrap()
936+
.set_ime_editor_info(input_type, options);
937+
}
938+
715939
/// Get an exclusive, lending iterator over buffered input events
716940
///
717941
/// 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)