Update Android port

* java/org/gnu/emacs/EmacsActivity.java (EmacsActivity)
(onCreate): Add view tree observer.
(onGlobalLayout): Sync fullscreen state.
(syncFullscreenWith): Improve visibility flag setting.

* src/textconv.c (select_window): New function.
(textconv_query):
(restore_selected_window):
(really_commit_text):
(really_set_composing_text):
(really_set_composing_region):
(really_delete_surrounding_text):
(really_set_point_and_mark):
(get_extracted_text): Call it instead of Fselect_window
to avoid selecting the mini window if it is no longer active.
This commit is contained in:
Po Lu 2023-03-03 15:23:21 +08:00
parent bf93380c1c
commit bc9239eb51
2 changed files with 61 additions and 20 deletions

View file

@ -31,6 +31,7 @@
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
@ -38,7 +39,8 @@
import android.widget.FrameLayout;
public class EmacsActivity extends Activity
implements EmacsWindowAttachmentManager.WindowConsumer
implements EmacsWindowAttachmentManager.WindowConsumer,
ViewTreeObserver.OnGlobalLayoutListener
{
public static final String TAG = "EmacsActivity";
@ -180,6 +182,8 @@ public class EmacsActivity extends Activity
{
FrameLayout.LayoutParams params;
Intent intent;
View decorView;
ViewTreeObserver observer;
/* See if Emacs should be started with -Q. */
intent = getIntent ();
@ -203,9 +207,29 @@ public class EmacsActivity extends Activity
/* Add this activity to the list of available activities. */
EmacsWindowAttachmentManager.MANAGER.registerWindowConsumer (this);
/* Start observing global layout changes between Jelly Bean and Q.
This is required to restore the fullscreen state whenever the
on screen keyboard is displayed, as there is otherwise no way
to determine when the on screen keyboard becomes visible. */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
{
decorView = getWindow ().getDecorView ();
observer = decorView.getViewTreeObserver ();
observer.addOnGlobalLayoutListener (this);
}
super.onCreate (savedInstanceState);
}
@Override
public final void
onGlobalLayout ()
{
syncFullscreenWith (window);
}
@Override
public final void
onDestroy ()
@ -348,22 +372,20 @@ public class EmacsActivity extends Activity
if (isFullscreen)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
/* This flag means that Emacs will be full screen, but
the system will cancel the full screen state upon
switching to another program. */
view.setSystemUiVisibility (View.SYSTEM_UI_FLAG_FULLSCREEN);
else
flags = 0;
flags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
/* These flags means that Emacs will be full screen as
long as the state flag is set. */
flags = 0;
flags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
flags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
flags |= View.SYSTEM_UI_FLAG_IMMERSIVE;
flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
view.setSystemUiVisibility (flags);
}
/* Apply the given flags. */
view.setSystemUiVisibility (flags);
}
else
view.setSystemUiVisibility (View.SYSTEM_UI_FLAG_VISIBLE);

View file

@ -115,6 +115,25 @@ get_mark (void)
return -1;
}
/* Like Fselect_window. However, if WINDOW is a mini buffer window
but not the active minibuffer window, select its frame's selected
window instead. */
static void
select_window (Lisp_Object window, Lisp_Object norecord)
{
struct window *w;
w = XWINDOW (window);
if (MINI_WINDOW_P (w)
&& WINDOW_LIVE_P (window)
&& !EQ (window, Factive_minibuffer_window ()))
window = WINDOW_XFRAME (w)->selected_window;
Fselect_window (window, norecord);
}
/* Perform the text conversion operation specified in QUERY and return
the results.
@ -153,9 +172,9 @@ textconv_query (struct frame *f, struct textconv_callback_struct *query,
/* Temporarily switch to F's selected window at the time of the last
redisplay. */
Fselect_window ((WINDOW_LIVE_P (f->old_selected_window)
? f->old_selected_window
: f->selected_window), Qt);
select_window ((WINDOW_LIVE_P (f->old_selected_window)
? f->old_selected_window
: f->selected_window), Qt);
/* Now find the appropriate text bounds for QUERY. First, move
point QUERY->position steps forward or backwards. */
@ -526,7 +545,7 @@ static void
restore_selected_window (Lisp_Object window)
{
/* FIXME: not sure what to do if WINDOW has been deleted. */
Fselect_window (window, Qt);
select_window (window, Qt);
}
/* Commit the given text in the composing region. If there is no
@ -552,7 +571,7 @@ really_commit_text (struct frame *f, EMACS_INT position,
/* Temporarily switch to F's selected window at the time of the last
redisplay. */
Fselect_window (f->old_selected_window, Qt);
select_window (f->old_selected_window, Qt);
/* Now detect whether or not there is a composing region.
If there is, then replace it with TEXT. Don't do that
@ -703,7 +722,7 @@ really_set_composing_text (struct frame *f, ptrdiff_t position,
/* Temporarily switch to F's selected window at the time of the last
redisplay. */
w = XWINDOW (f->old_selected_window);
Fselect_window (f->old_selected_window, Qt);
select_window (f->old_selected_window, Qt);
/* Now set up the composition region if necessary. */
@ -824,7 +843,7 @@ really_set_composing_region (struct frame *f, ptrdiff_t start,
/* Temporarily switch to F's selected window at the time of the last
redisplay. */
Fselect_window (f->old_selected_window, Qt);
select_window (f->old_selected_window, Qt);
/* Now set up the composition region if necessary. */
@ -873,7 +892,7 @@ really_delete_surrounding_text (struct frame *f, ptrdiff_t left,
/* Temporarily switch to F's selected window at the time of the last
redisplay. */
Fselect_window (f->old_selected_window, Qt);
select_window (f->old_selected_window, Qt);
/* Figure out where to start deleting from. */
@ -963,7 +982,7 @@ really_set_point_and_mark (struct frame *f, ptrdiff_t point,
/* Temporarily switch to F's selected window at the time of the last
redisplay. */
Fselect_window (f->old_selected_window, Qt);
select_window (f->old_selected_window, Qt);
if (point == PT)
{
@ -1475,7 +1494,7 @@ get_extracted_text (struct frame *f, ptrdiff_t n,
/* Temporarily switch to F's selected window at the time of the last
redisplay. */
Fselect_window (f->old_selected_window, Qt);
select_window (f->old_selected_window, Qt);
buffer = NULL;
/* Figure out the bounds of the text to return. */