Update Android port
* java/org/gnu/emacs/EmacsActivity.java (attachWindow, onDestroy) (onWindowFocusChanged, onContextMenuClosed): * java/org/gnu/emacs/EmacsContextMenu.java (onMenuItemClick): * java/org/gnu/emacs/EmacsDialog.java (onClick, display1, onDismiss): * java/org/gnu/emacs/EmacsOpenActivity.java (checkReadableOrCopy) (onDestroy, onWindowFocusChanged, onPause): * java/org/gnu/emacs/EmacsWindowAttachmentManager.java (registerWindow, removeWindowConsumer, detachWindow) (noticeIconified, noticeDeiconified): Remove superfluous debugging code now that the Android port is stable. * java/org/gnu/emacs/EmacsView.java (onLayout): Detect if the IME is hidden while a toplevel window is focused, and clear isCurrentlyTextEditor in that case. (onApplyWindowInsets): New function. (raise, lower, popupMenu, onCreateInputConnection): Delete aforementioned debugging code.
This commit is contained in:
parent
967fa846fc
commit
2134fd9f27
6 changed files with 79 additions and 76 deletions
|
@ -149,8 +149,6 @@ public class EmacsActivity extends Activity
|
|||
public final void
|
||||
attachWindow (EmacsWindow child)
|
||||
{
|
||||
Log.d (TAG, "attachWindow: " + child);
|
||||
|
||||
if (window != null)
|
||||
throw new IllegalStateException ("trying to attach window when one"
|
||||
+ " already exists");
|
||||
|
@ -257,7 +255,6 @@ public class EmacsActivity extends Activity
|
|||
|
||||
/* The activity will die shortly hereafter. If there is a window
|
||||
attached, close it now. */
|
||||
Log.d (TAG, "onDestroy " + this);
|
||||
isMultitask = this instanceof EmacsMultitaskActivity;
|
||||
manager.removeWindowConsumer (this, isMultitask || isFinishing ());
|
||||
focusedActivities.remove (this);
|
||||
|
@ -274,9 +271,6 @@ public class EmacsActivity extends Activity
|
|||
public final void
|
||||
onWindowFocusChanged (boolean isFocused)
|
||||
{
|
||||
Log.d (TAG, ("onWindowFocusChanged: "
|
||||
+ (isFocused ? "YES" : "NO")));
|
||||
|
||||
if (isFocused && !focusedActivities.contains (this))
|
||||
{
|
||||
focusedActivities.add (this);
|
||||
|
@ -323,8 +317,6 @@ public class EmacsActivity extends Activity
|
|||
{
|
||||
int serial;
|
||||
|
||||
Log.d (TAG, "onContextMenuClosed: " + menu);
|
||||
|
||||
/* See the comment inside onMenuItemClick. */
|
||||
|
||||
if (((EmacsContextMenu.wasSubmenuSelected == -2)
|
||||
|
|
|
@ -72,8 +72,6 @@ private static final class Item implements MenuItem.OnMenuItemClickListener
|
|||
public boolean
|
||||
onMenuItemClick (MenuItem item)
|
||||
{
|
||||
Log.d (TAG, "onMenuItemClick: " + itemName + " (" + itemID + ")");
|
||||
|
||||
if (subMenu != null)
|
||||
{
|
||||
/* Android 6.0 and earlier don't support nested submenus
|
||||
|
@ -81,8 +79,6 @@ private static final class Item implements MenuItem.OnMenuItemClickListener
|
|||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
|
||||
{
|
||||
Log.d (TAG, "onMenuItemClick: displaying submenu " + subMenu);
|
||||
|
||||
/* Still set wasSubmenuSelected -- if not set, the
|
||||
dismissal of this context menu will result in a
|
||||
context menu event being sent. */
|
||||
|
|
|
@ -88,8 +88,6 @@ private final class EmacsButton implements View.OnClickListener,
|
|||
public void
|
||||
onClick (View view)
|
||||
{
|
||||
Log.d (TAG, "onClicked " + this);
|
||||
|
||||
wasButtonClicked = true;
|
||||
EmacsNative.sendContextMenu ((short) 0, id, menuEventSerial);
|
||||
dismissDialog.dismiss ();
|
||||
|
@ -99,8 +97,6 @@ private final class EmacsButton implements View.OnClickListener,
|
|||
public void
|
||||
onClick (DialogInterface dialog, int which)
|
||||
{
|
||||
Log.d (TAG, "onClicked " + this);
|
||||
|
||||
wasButtonClicked = true;
|
||||
EmacsNative.sendContextMenu ((short) 0, id, menuEventSerial);
|
||||
}
|
||||
|
@ -300,10 +296,6 @@ private final class EmacsButton implements View.OnClickListener,
|
|||
work, then any focused EmacsOpenActivity, and finally the
|
||||
last EmacsActivity to be focused. */
|
||||
|
||||
Log.d (TAG, "display1: no focused activities...");
|
||||
Log.d (TAG, ("display1: EmacsOpenActivity.currentActivity: "
|
||||
+ EmacsOpenActivity.currentActivity));
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||
|| Settings.canDrawOverlays (EmacsService.SERVICE))
|
||||
context = EmacsService.SERVICE;
|
||||
|
@ -321,8 +313,6 @@ else if (EmacsOpenActivity.currentActivity != null)
|
|||
consistently. */
|
||||
context = EmacsActivity.focusedActivities.get (0);
|
||||
|
||||
Log.d (TAG, "display1: using context " + context);
|
||||
|
||||
dialog = dismissDialog = toAlertDialog (context);
|
||||
|
||||
try
|
||||
|
@ -418,8 +408,6 @@ else if (EmacsOpenActivity.currentActivity != null)
|
|||
public void
|
||||
onDismiss (DialogInterface dialog)
|
||||
{
|
||||
Log.d (TAG, "onDismiss: " + this);
|
||||
|
||||
if (wasButtonClicked)
|
||||
return;
|
||||
|
||||
|
|
|
@ -232,19 +232,14 @@ private class EmacsClientThread extends Thread
|
|||
int read;
|
||||
String content;
|
||||
|
||||
Log.d (TAG, "checkReadableOrCopy: " + file);
|
||||
|
||||
inFile = new File (file);
|
||||
|
||||
if (inFile.canRead ())
|
||||
return file;
|
||||
|
||||
Log.d (TAG, "checkReadableOrCopy: NO");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
||||
{
|
||||
content = EmacsService.buildContentName (uri);
|
||||
Log.d (TAG, "checkReadableOrCopy: " + content);
|
||||
return content;
|
||||
}
|
||||
|
||||
|
@ -509,8 +504,6 @@ private class EmacsClientThread extends Thread
|
|||
public void
|
||||
onDestroy ()
|
||||
{
|
||||
Log.d (TAG, "onDestroy: " + this);
|
||||
|
||||
/* Clear `currentActivity' if it refers to the activity being
|
||||
destroyed. */
|
||||
|
||||
|
@ -524,9 +517,6 @@ private class EmacsClientThread extends Thread
|
|||
public void
|
||||
onWindowFocusChanged (boolean isFocused)
|
||||
{
|
||||
Log.d (TAG, "onWindowFocusChanged: " + this + ", is now focused: "
|
||||
+ isFocused);
|
||||
|
||||
if (isFocused)
|
||||
currentActivity = this;
|
||||
else if (currentActivity == this)
|
||||
|
@ -539,8 +529,6 @@ else if (currentActivity == this)
|
|||
public void
|
||||
onPause ()
|
||||
{
|
||||
Log.d (TAG, "onPause: " + this);
|
||||
|
||||
/* XXX: clear currentActivity here as well; I don't know whether
|
||||
or not onWindowFocusChanged is always called prior to this. */
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
import android.view.MotionEvent;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowInsets;
|
||||
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
|
@ -302,6 +303,26 @@ else if (MeasureSpec.getMode (heightMeasureSpec) == MeasureSpec.AT_MOST
|
|||
super.setMeasuredDimension (width, height);
|
||||
}
|
||||
|
||||
/* Return whether this view's window is focused. This is made
|
||||
necessary by Android 11's unreliable dispatch of
|
||||
onWindowFocusChanged prior to gesture navigation away from a
|
||||
frame. */
|
||||
|
||||
public boolean
|
||||
checkWindowFocus ()
|
||||
{
|
||||
EmacsActivity activity;
|
||||
Object consumer;
|
||||
|
||||
consumer = window.getAttachedConsumer ();
|
||||
|
||||
if (!(consumer instanceof EmacsActivity))
|
||||
return false;
|
||||
|
||||
activity = (EmacsActivity) consumer;
|
||||
return activity.hasWindowFocus ();
|
||||
}
|
||||
|
||||
/* Note that the monitor lock for the window must never be held from
|
||||
within the lock for the view, because the window also locks the
|
||||
other way around. */
|
||||
|
@ -315,6 +336,7 @@ else if (MeasureSpec.getMode (heightMeasureSpec) == MeasureSpec.AT_MOST
|
|||
View child;
|
||||
Rect windowRect;
|
||||
boolean needExpose;
|
||||
WindowInsets rootWindowInsets;
|
||||
|
||||
count = getChildCount ();
|
||||
needExpose = false;
|
||||
|
@ -349,14 +371,37 @@ else if (MeasureSpec.getMode (heightMeasureSpec) == MeasureSpec.AT_MOST
|
|||
if (right - left > oldMeasuredWidth
|
||||
|| bottom - top > oldMeasuredHeight)
|
||||
needExpose = true;
|
||||
|
||||
/* This might return NULL if this view is not attached. */
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
||||
{
|
||||
/* If a toplevel view is focused and isCurrentlyTextEditor
|
||||
is enabled when the IME is hidden, clear
|
||||
isCurrentlyTextEditor so it isn't shown again if the
|
||||
user dismisses Emacs before returning. */
|
||||
rootWindowInsets = getRootWindowInsets ();
|
||||
|
||||
if (isCurrentlyTextEditor
|
||||
&& rootWindowInsets != null
|
||||
&& isAttachedToWindow
|
||||
&& !rootWindowInsets.isVisible (WindowInsets.Type.ime ())
|
||||
/* N.B. that the keyboard is dismissed during gesture
|
||||
navigation under Android 30, but the system is
|
||||
quite tempermental regarding whether the window is
|
||||
focused at that point. Ideally
|
||||
isCurrentlyTextEditor shouldn't be reset in that
|
||||
case, but detecting that situation appears to be
|
||||
impossible. Sigh. */
|
||||
&& (window == EmacsActivity.focusedWindow
|
||||
&& hasWindowFocus ()))
|
||||
isCurrentlyTextEditor = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
child = getChildAt (i);
|
||||
|
||||
Log.d (TAG, "onLayout: " + child);
|
||||
|
||||
if (child == surfaceView)
|
||||
child.layout (0, 0, right - left, bottom - top);
|
||||
else if (child.getVisibility () != GONE)
|
||||
|
@ -491,6 +536,8 @@ else if (child.getVisibility () != GONE)
|
|||
return window.onTouchEvent (motion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void
|
||||
moveChildToBack (View child)
|
||||
{
|
||||
|
@ -518,8 +565,6 @@ else if (child.getVisibility () != GONE)
|
|||
|
||||
parent = (EmacsView) getParent ();
|
||||
|
||||
Log.d (TAG, "raise: parent " + parent);
|
||||
|
||||
if (parent.indexOfChild (this)
|
||||
== parent.getChildCount () - 1)
|
||||
return;
|
||||
|
@ -534,8 +579,6 @@ else if (child.getVisibility () != GONE)
|
|||
|
||||
parent = (EmacsView) getParent ();
|
||||
|
||||
Log.d (TAG, "lower: parent " + parent);
|
||||
|
||||
if (parent.indexOfChild (this) == 1)
|
||||
return;
|
||||
|
||||
|
@ -562,9 +605,6 @@ else if (child.getVisibility () != GONE)
|
|||
contextMenu = menu;
|
||||
popupActive = true;
|
||||
|
||||
Log.d (TAG, "popupMenu: " + menu + " @" + xPosition
|
||||
+ ", " + yPosition + " " + force);
|
||||
|
||||
/* Use showContextMenu (float, float) on N to get actual popup
|
||||
behavior. */
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
|
@ -700,14 +740,8 @@ else if (child.getVisibility () != GONE)
|
|||
|
||||
selection = EmacsService.viewGetSelection (window.handle);
|
||||
|
||||
if (selection != null)
|
||||
Log.d (TAG, "onCreateInputConnection: current selection is: "
|
||||
+ selection[0] + ", by " + selection[1]);
|
||||
else
|
||||
if (selection == null)
|
||||
{
|
||||
Log.d (TAG, "onCreateInputConnection: current selection could"
|
||||
+ " not be retrieved.");
|
||||
|
||||
/* If the selection could not be obtained, return 0 by 0.
|
||||
However, ask for the selection position to be updated as
|
||||
soon as possible. */
|
||||
|
@ -780,4 +814,33 @@ else if (child.getVisibility () != GONE)
|
|||
window.notifyContentRectPosition (locations[0],
|
||||
locations[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowInsets
|
||||
onApplyWindowInsets (WindowInsets insets)
|
||||
{
|
||||
WindowInsets rootWindowInsets;
|
||||
|
||||
/* This function is called when window insets change, which
|
||||
encompasses input method visibility changes under Android 30
|
||||
and later. If a toplevel view is focused and
|
||||
isCurrentlyTextEditor is enabled when the IME is hidden, clear
|
||||
isCurrentlyTextEditor so it isn't shown again if the user
|
||||
dismisses Emacs before returning. */
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
|
||||
return super.onApplyWindowInsets (insets);
|
||||
|
||||
/* This might return NULL if this view is not attached. */
|
||||
rootWindowInsets = getRootWindowInsets ();
|
||||
|
||||
if (isCurrentlyTextEditor
|
||||
&& rootWindowInsets != null
|
||||
&& isAttachedToWindow
|
||||
&& !rootWindowInsets.isVisible (WindowInsets.Type.ime ())
|
||||
&& window == EmacsActivity.focusedWindow)
|
||||
isCurrentlyTextEditor = false;
|
||||
|
||||
return super.onApplyWindowInsets (insets);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -87,21 +87,17 @@ public interface WindowConsumer
|
|||
public void
|
||||
registerWindowConsumer (WindowConsumer consumer)
|
||||
{
|
||||
Log.d (TAG, "registerWindowConsumer " + consumer);
|
||||
|
||||
consumers.add (consumer);
|
||||
|
||||
for (EmacsWindow window : windows)
|
||||
{
|
||||
if (window.getAttachedConsumer () == null)
|
||||
{
|
||||
Log.d (TAG, "registerWindowConsumer: attaching " + window);
|
||||
consumer.attachWindow (window);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Log.d (TAG, "registerWindowConsumer: sendWindowAction 0, 0");
|
||||
EmacsNative.sendWindowAction ((short) 0, 0);
|
||||
}
|
||||
|
||||
|
@ -111,21 +107,16 @@ public interface WindowConsumer
|
|||
Intent intent;
|
||||
ActivityOptions options;
|
||||
|
||||
Log.d (TAG, "registerWindow (maybe): " + window);
|
||||
|
||||
if (windows.contains (window))
|
||||
/* The window is already registered. */
|
||||
return;
|
||||
|
||||
Log.d (TAG, "registerWindow: " + window);
|
||||
|
||||
windows.add (window);
|
||||
|
||||
for (WindowConsumer consumer : consumers)
|
||||
{
|
||||
if (consumer.getAttachedWindow () == null)
|
||||
{
|
||||
Log.d (TAG, "registerWindow: attaching " + consumer);
|
||||
consumer.attachWindow (window);
|
||||
return;
|
||||
}
|
||||
|
@ -147,8 +138,6 @@ public interface WindowConsumer
|
|||
EmacsService.SERVICE.startActivity (intent,
|
||||
options.toBundle ());
|
||||
}
|
||||
|
||||
Log.d (TAG, "registerWindow: startActivity");
|
||||
}
|
||||
|
||||
public void
|
||||
|
@ -156,19 +145,14 @@ public interface WindowConsumer
|
|||
{
|
||||
EmacsWindow window;
|
||||
|
||||
Log.d (TAG, "removeWindowConsumer " + consumer);
|
||||
|
||||
window = consumer.getAttachedWindow ();
|
||||
|
||||
if (window != null)
|
||||
{
|
||||
Log.d (TAG, "removeWindowConsumer: detaching " + window);
|
||||
|
||||
consumer.detachWindow ();
|
||||
window.onActivityDetached (isFinishing);
|
||||
}
|
||||
|
||||
Log.d (TAG, "removeWindowConsumer: removing " + consumer);
|
||||
consumers.remove (consumer);
|
||||
}
|
||||
|
||||
|
@ -177,14 +161,10 @@ public interface WindowConsumer
|
|||
{
|
||||
WindowConsumer consumer;
|
||||
|
||||
Log.d (TAG, "detachWindow " + window);
|
||||
|
||||
if (window.getAttachedConsumer () != null)
|
||||
{
|
||||
consumer = window.getAttachedConsumer ();
|
||||
|
||||
Log.d (TAG, "detachWindow: removing" + consumer);
|
||||
|
||||
consumers.remove (consumer);
|
||||
consumer.destroy ();
|
||||
}
|
||||
|
@ -197,8 +177,6 @@ public interface WindowConsumer
|
|||
{
|
||||
EmacsWindow window;
|
||||
|
||||
Log.d (TAG, "noticeIconified " + consumer);
|
||||
|
||||
/* If a window is attached, send the appropriate iconification
|
||||
events. */
|
||||
window = consumer.getAttachedWindow ();
|
||||
|
@ -212,8 +190,6 @@ public interface WindowConsumer
|
|||
{
|
||||
EmacsWindow window;
|
||||
|
||||
Log.d (TAG, "noticeDeiconified " + consumer);
|
||||
|
||||
/* If a window is attached, send the appropriate iconification
|
||||
events. */
|
||||
window = consumer.getAttachedWindow ();
|
||||
|
|
Loading…
Add table
Reference in a new issue