mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-06 21:34:00 -05:00
app: improve android editor perf and eliminate a deadlock in android text input
This commit is contained in:
@@ -182,21 +182,19 @@ impl GameTextInput {
|
||||
w!("push_update() - no input_connection set");
|
||||
return
|
||||
};
|
||||
if let Some(input_connection) = *self.input_connection.read() {
|
||||
unsafe {
|
||||
let env = android::attach_jni_env();
|
||||
let jstate = self.state_to_java(state);
|
||||
call_void_method!(
|
||||
env,
|
||||
input_connection,
|
||||
"setState",
|
||||
"(Ltextinput/State;)V",
|
||||
jstate
|
||||
);
|
||||
unsafe {
|
||||
let env = android::attach_jni_env();
|
||||
let jstate = self.state_to_java(state);
|
||||
call_void_method!(
|
||||
env,
|
||||
input_connection,
|
||||
"setState",
|
||||
"(Ltextinput/State;)V",
|
||||
jstate
|
||||
);
|
||||
|
||||
let delete_local_ref = (**env).DeleteLocalRef.unwrap();
|
||||
delete_local_ref(env, jstate);
|
||||
}
|
||||
let delete_local_ref = (**env).DeleteLocalRef.unwrap();
|
||||
delete_local_ref(env, jstate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,9 +78,11 @@ impl AndroidTextInput {
|
||||
// Always update our own state.
|
||||
let mut ours = self.state.lock();
|
||||
ours.state = state.clone();
|
||||
let is_active = ours.is_active;
|
||||
drop(ours);
|
||||
|
||||
// Only update java state when this input is active
|
||||
if ours.is_active {
|
||||
if is_active {
|
||||
let gti = GAME_TEXT_INPUT.get().unwrap();
|
||||
gti.push_update(&state);
|
||||
}
|
||||
|
||||
@@ -81,9 +81,14 @@ impl Editor {
|
||||
self.refresh().await;
|
||||
}
|
||||
pub async fn on_buffer_changed(&mut self, atom: &mut PropertyAtomicGuard) {
|
||||
// Refresh the layout using the Android buffer
|
||||
self.refresh().await;
|
||||
// Only refresh layout if text content actually changed
|
||||
// Avoid triggering expensive recomputes of layout and property tree.
|
||||
let old_text = self.text.get();
|
||||
if old_text == self.state.text {
|
||||
return
|
||||
}
|
||||
|
||||
self.refresh().await;
|
||||
// Update the text attribute
|
||||
self.text.set(atom, &self.state.text);
|
||||
}
|
||||
@@ -126,7 +131,7 @@ impl Editor {
|
||||
let cursor = parley::Cursor::from_point(&self.layout, pos.x, pos.y);
|
||||
let cursor_idx = cursor.index();
|
||||
t!(" move_to_pos: {cursor_idx}");
|
||||
self.state.text = self.text.get();
|
||||
assert!(cursor_idx <= self.state.text.len());
|
||||
self.state.select = (cursor_idx, cursor_idx);
|
||||
self.state.compose = None;
|
||||
self.input.set_state(self.state.clone());
|
||||
|
||||
@@ -1304,14 +1304,11 @@ impl BaseEdit {
|
||||
t!("handle_android_event({state:?})");
|
||||
let atom = &mut self.render_api.make_guard(gfxtag!("BaseEdit::handle_android_event"));
|
||||
|
||||
// Text changed - finish any active selection
|
||||
if state.text != self.text.get() || state.select.0 == state.select.1 {
|
||||
// Safe to call before we update the editor.
|
||||
// I just wanna avoid cloning state since we move it into editor.
|
||||
self.finish_select(atom);
|
||||
}
|
||||
|
||||
let mut editor = self.lock_editor().await;
|
||||
// Diff old and new state so we know what changed
|
||||
let is_text_changed = editor.state.text != state.text;
|
||||
let is_select_changed = editor.state.select != state.select;
|
||||
let is_compose_changed = editor.state.compose != state.compose;
|
||||
editor.state = state;
|
||||
editor.on_buffer_changed(atom).await;
|
||||
drop(editor);
|
||||
@@ -1319,10 +1316,21 @@ impl BaseEdit {
|
||||
self.eval_rect().await;
|
||||
self.behave.apply_cursor_scroll().await;
|
||||
|
||||
// Only redraw once we have the parent_rect
|
||||
// Can happen when we receive an Android event before the canvas is ready
|
||||
if self.parent_rect.lock().is_some() {
|
||||
self.redraw(atom).await;
|
||||
// Text changed - finish any active selection
|
||||
if is_text_changed || is_compose_changed {
|
||||
self.pause_blinking();
|
||||
//assert!(state.text != self.text.get());
|
||||
self.finish_select(atom);
|
||||
|
||||
// Only redraw once we have the parent_rect
|
||||
// Can happen when we receive an Android event before the canvas is ready
|
||||
if self.parent_rect.lock().is_some() {
|
||||
self.redraw(atom).await;
|
||||
}
|
||||
} else if is_select_changed {
|
||||
// Redrawing the entire text just for select changes is expensive
|
||||
self.redraw_cursor(atom.batch_id).await;
|
||||
self.redraw_select(atom.batch_id).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user