diff options
| author | Po Lu | 2023-01-20 19:06:32 +0800 |
|---|---|---|
| committer | Po Lu | 2023-01-20 19:06:32 +0800 |
| commit | d44b60c2f001d57b010f0e9b82f798fbad9a23d6 (patch) | |
| tree | 1ff208bfccd74a3b2ad4488cd66c89762d0acd7e /java | |
| parent | e07b58dc35a66b5e611f437ec007292d82dc8f13 (diff) | |
| download | emacs-d44b60c2f001d57b010f0e9b82f798fbad9a23d6.tar.gz emacs-d44b60c2f001d57b010f0e9b82f798fbad9a23d6.zip | |
Update Android port
* .gitignore: Don't ignore verbose.mk.android.
* doc/emacs/Makefile.in (EMACSSOURCES): Add android.texi and
input.texi.
* doc/emacs/android.texi (Android): Document support for the
on-screen keyboard.
(Android Startup): Document how to start Emacs with -Q on
Android.
(Android Environment): Document how Emacs works around the
system ``task killer''. Document changes to frame deletion
behavior.
* doc/emacs/emacs.texi (Top):
* doc/emacs/input.texi (Other Input Devices, On-Screen
Keyboards): Document how to use Emacs with virtual keyboards.
* doc/lispref/commands.texi (Touchscreen Events): Document
changes to `touch-screen-track-drag'.
* doc/lispref/frames.texi (Frames, On-Screen Keyboards): New
node.
* java/AndroidManifest.xml.in: Add settings activity and
appropriate OSK adjustment mode.
* java/org/gnu/emacs/EmacsActivity.java (onCreate): Allow
creating Emacs with -Q.
(onDestroy): Don't remove if killed by the system.
* java/org/gnu/emacs/EmacsContextMenu.java (inflateMenuItems):
Fix context menus again.
* java/org/gnu/emacs/EmacsNative.java (EmacsNative): Make all
event sending functions return long.
* java/org/gnu/emacs/EmacsPreferencesActivity.java
(EmacsPreferencesActivity): New class.
* java/org/gnu/emacs/EmacsService.java (EmacsService)
(onStartCommand, onCreate, startEmacsService): Start as a
foreground service if necessary to bypass system restrictions.
* java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView):
* java/org/gnu/emacs/EmacsThread.java (EmacsThread, run):
* java/org/gnu/emacs/EmacsView.java (EmacsView, onLayout)
(onDetachedFromWindow):
* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow, viewLayout):
Implement frame resize synchronization..
* java/org/gnu/emacs/EmacsWindowAttachmentManager.java
(EmacsWindowAttachmentManager, removeWindowConsumer): Adjust
accordingly for changes to frame deletion behavior.
* lisp/frame.el (android-toggle-on-screen-keyboard)
(frame-toggle-on-screen-keyboard): New function.
* lisp/minibuffer.el (minibuffer-setup-on-screen-keyboard)
(minibuffer-exit-on-screen-keyboard): New functions.
(minibuffer-setup-hook, minibuffer-exit-hook): Add new functions
to hooks.
* lisp/touch-screen.el (touch-screen-relative-xy): Accept new
value of window `frame'. Return frame coordinates in that case.
(touch-screen-set-point-commands): New variable.
(touch-screen-handle-point-up): Respect that variable.
(touch-screen-track-drag): Return `no-drag' where appropriate.
(touch-screen-drag-mode-line-1, touch-screen-drag-mode-line):
Refactor to use `no-drag'.
* src/android.c (struct android_emacs_window): New methods.
Make all event sending functions return the event serial.
(android_toggle_on_screen_keyboard, android_window_updated): New
functions.
* src/android.h: Update prototypes.
* src/androidfns.c (Fandroid_toggle_on_screen_keyboard)
(syms_of_androidfns): New function.
* src/androidgui.h (struct android_any_event)
(struct android_key_event, struct android_configure_event)
(struct android_focus_event, struct android_window_action_event)
(struct android_crossing_event, struct android_motion_event)
(struct android_button_event, struct android_touch_event)
(struct android_wheel_event, struct android_iconify_event)
(struct android_menu_event): Add `serial' fields.
* src/androidterm.c (handle_one_android_event)
(android_frame_up_to_date):
* src/androidterm.h (struct android_output): Implement frame
resize synchronization.
Diffstat (limited to 'java')
| -rw-r--r-- | java/AndroidManifest.xml.in | 12 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsActivity.java | 20 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsContextMenu.java | 1 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsNative.java | 39 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsPreferencesActivity.java | 98 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsService.java | 62 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsSurfaceView.java | 127 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsThread.java | 12 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsView.java | 55 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsWindow.java | 58 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsWindowAttachmentManager.java | 4 |
11 files changed, 412 insertions, 76 deletions
diff --git a/java/AndroidManifest.xml.in b/java/AndroidManifest.xml.in index b680137a9d0..74f69d2a8e5 100644 --- a/java/AndroidManifest.xml.in +++ b/java/AndroidManifest.xml.in | |||
| @@ -62,8 +62,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. --> | |||
| 62 | android:theme="@android:style/Theme" | 62 | android:theme="@android:style/Theme" |
| 63 | android:debuggable="true" | 63 | android:debuggable="true" |
| 64 | android:extractNativeLibs="true"> | 64 | android:extractNativeLibs="true"> |
| 65 | |||
| 65 | <activity android:name="org.gnu.emacs.EmacsActivity" | 66 | <activity android:name="org.gnu.emacs.EmacsActivity" |
| 66 | android:launchMode="singleTop" | 67 | android:launchMode="singleTop" |
| 68 | android:windowSoftInputMode="adjustResize" | ||
| 67 | android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"> | 69 | android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"> |
| 68 | <intent-filter> | 70 | <intent-filter> |
| 69 | <action android:name="android.intent.action.MAIN" /> | 71 | <action android:name="android.intent.action.MAIN" /> |
| @@ -73,8 +75,18 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. --> | |||
| 73 | </activity> | 75 | </activity> |
| 74 | 76 | ||
| 75 | <activity android:name="org.gnu.emacs.EmacsMultitaskActivity" | 77 | <activity android:name="org.gnu.emacs.EmacsMultitaskActivity" |
| 78 | android:windowSoftInputMode="adjustResize" | ||
| 76 | android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"/> | 79 | android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"/> |
| 77 | 80 | ||
| 81 | <activity android:autoRemoveFromRecents="true" | ||
| 82 | android:label="Emacs options" | ||
| 83 | android:name=".EmacsPreferencesActivity"> | ||
| 84 | <intent-filter> | ||
| 85 | <action android:name="android.intent.action.APPLICATION_PREFERENCES" /> | ||
| 86 | <category android:name="android.intent.category.DEFAULT" /> | ||
| 87 | </intent-filter> | ||
| 88 | </activity> | ||
| 89 | |||
| 78 | <service android:name="org.gnu.emacs.EmacsService" | 90 | <service android:name="org.gnu.emacs.EmacsService" |
| 79 | android:directBootAware="false" | 91 | android:directBootAware="false" |
| 80 | android:enabled="true" | 92 | android:enabled="true" |
diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java index 79c0991a5d3..d377cf982ef 100644 --- a/java/org/gnu/emacs/EmacsActivity.java +++ b/java/org/gnu/emacs/EmacsActivity.java | |||
| @@ -161,6 +161,13 @@ public class EmacsActivity extends Activity | |||
| 161 | onCreate (Bundle savedInstanceState) | 161 | onCreate (Bundle savedInstanceState) |
| 162 | { | 162 | { |
| 163 | FrameLayout.LayoutParams params; | 163 | FrameLayout.LayoutParams params; |
| 164 | Intent intent; | ||
| 165 | |||
| 166 | /* See if Emacs should be started with -Q. */ | ||
| 167 | intent = getIntent (); | ||
| 168 | EmacsService.needDashQ | ||
| 169 | = intent.getBooleanExtra ("org.gnu.emacs.START_DASH_Q", | ||
| 170 | false); | ||
| 164 | 171 | ||
| 165 | /* Set the theme to one without a title bar. */ | 172 | /* Set the theme to one without a title bar. */ |
| 166 | 173 | ||
| @@ -179,9 +186,8 @@ public class EmacsActivity extends Activity | |||
| 179 | /* Set it as the content view. */ | 186 | /* Set it as the content view. */ |
| 180 | setContentView (layout); | 187 | setContentView (layout); |
| 181 | 188 | ||
| 182 | if (EmacsService.SERVICE == null) | 189 | /* Maybe start the Emacs service if necessary. */ |
| 183 | /* Start the Emacs service now. */ | 190 | EmacsService.startEmacsService (this); |
| 184 | startService (new Intent (this, EmacsService.class)); | ||
| 185 | 191 | ||
| 186 | /* Add this activity to the list of available activities. */ | 192 | /* Add this activity to the list of available activities. */ |
| 187 | EmacsWindowAttachmentManager.MANAGER.registerWindowConsumer (this); | 193 | EmacsWindowAttachmentManager.MANAGER.registerWindowConsumer (this); |
| @@ -193,10 +199,16 @@ public class EmacsActivity extends Activity | |||
| 193 | public void | 199 | public void |
| 194 | onDestroy () | 200 | onDestroy () |
| 195 | { | 201 | { |
| 202 | EmacsWindowAttachmentManager manager; | ||
| 203 | boolean isMultitask; | ||
| 204 | |||
| 205 | manager = EmacsWindowAttachmentManager.MANAGER; | ||
| 206 | |||
| 196 | /* The activity will die shortly hereafter. If there is a window | 207 | /* The activity will die shortly hereafter. If there is a window |
| 197 | attached, close it now. */ | 208 | attached, close it now. */ |
| 198 | Log.d (TAG, "onDestroy " + this); | 209 | Log.d (TAG, "onDestroy " + this); |
| 199 | EmacsWindowAttachmentManager.MANAGER.removeWindowConsumer (this); | 210 | isMultitask = this instanceof EmacsMultitaskActivity; |
| 211 | manager.removeWindowConsumer (this, isMultitask || isFinishing ()); | ||
| 200 | focusedActivities.remove (this); | 212 | focusedActivities.remove (this); |
| 201 | invalidateFocus (); | 213 | invalidateFocus (); |
| 202 | super.onDestroy (); | 214 | super.onDestroy (); |
diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java index ac67ebe4aa0..056d8fb692c 100644 --- a/java/org/gnu/emacs/EmacsContextMenu.java +++ b/java/org/gnu/emacs/EmacsContextMenu.java | |||
| @@ -174,6 +174,7 @@ public class EmacsContextMenu | |||
| 174 | support doing so, create the submenu and add the | 174 | support doing so, create the submenu and add the |
| 175 | contents of the menu to it. */ | 175 | contents of the menu to it. */ |
| 176 | submenu = menu.addSubMenu (item.itemName); | 176 | submenu = menu.addSubMenu (item.itemName); |
| 177 | item.subMenu.inflateMenuItems (submenu); | ||
| 177 | } | 178 | } |
| 178 | catch (UnsupportedOperationException exception) | 179 | catch (UnsupportedOperationException exception) |
| 179 | { | 180 | { |
diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java index 2f3a732ea7c..3efdc0cff9a 100644 --- a/java/org/gnu/emacs/EmacsNative.java +++ b/java/org/gnu/emacs/EmacsNative.java | |||
| @@ -61,75 +61,76 @@ public class EmacsNative | |||
| 61 | /* Abort and generate a native core dump. */ | 61 | /* Abort and generate a native core dump. */ |
| 62 | public static native void emacsAbort (); | 62 | public static native void emacsAbort (); |
| 63 | 63 | ||
| 64 | /* Send an ANDROID_CONFIGURE_NOTIFY event. */ | 64 | /* Send an ANDROID_CONFIGURE_NOTIFY event. The values of all the |
| 65 | public static native void sendConfigureNotify (short window, long time, | 65 | functions below are the serials of the events sent. */ |
| 66 | public static native long sendConfigureNotify (short window, long time, | ||
| 66 | int x, int y, int width, | 67 | int x, int y, int width, |
| 67 | int height); | 68 | int height); |
| 68 | 69 | ||
| 69 | /* Send an ANDROID_KEY_PRESS event. */ | 70 | /* Send an ANDROID_KEY_PRESS event. */ |
| 70 | public static native void sendKeyPress (short window, long time, int state, | 71 | public static native long sendKeyPress (short window, long time, int state, |
| 71 | int keyCode, int unicodeChar); | 72 | int keyCode, int unicodeChar); |
| 72 | 73 | ||
| 73 | /* Send an ANDROID_KEY_RELEASE event. */ | 74 | /* Send an ANDROID_KEY_RELEASE event. */ |
| 74 | public static native void sendKeyRelease (short window, long time, int state, | 75 | public static native long sendKeyRelease (short window, long time, int state, |
| 75 | int keyCode, int unicodeChar); | 76 | int keyCode, int unicodeChar); |
| 76 | 77 | ||
| 77 | /* Send an ANDROID_FOCUS_IN event. */ | 78 | /* Send an ANDROID_FOCUS_IN event. */ |
| 78 | public static native void sendFocusIn (short window, long time); | 79 | public static native long sendFocusIn (short window, long time); |
| 79 | 80 | ||
| 80 | /* Send an ANDROID_FOCUS_OUT event. */ | 81 | /* Send an ANDROID_FOCUS_OUT event. */ |
| 81 | public static native void sendFocusOut (short window, long time); | 82 | public static native long sendFocusOut (short window, long time); |
| 82 | 83 | ||
| 83 | /* Send an ANDROID_WINDOW_ACTION event. */ | 84 | /* Send an ANDROID_WINDOW_ACTION event. */ |
| 84 | public static native void sendWindowAction (short window, int action); | 85 | public static native long sendWindowAction (short window, int action); |
| 85 | 86 | ||
| 86 | /* Send an ANDROID_ENTER_NOTIFY event. */ | 87 | /* Send an ANDROID_ENTER_NOTIFY event. */ |
| 87 | public static native void sendEnterNotify (short window, int x, int y, | 88 | public static native long sendEnterNotify (short window, int x, int y, |
| 88 | long time); | 89 | long time); |
| 89 | 90 | ||
| 90 | /* Send an ANDROID_LEAVE_NOTIFY event. */ | 91 | /* Send an ANDROID_LEAVE_NOTIFY event. */ |
| 91 | public static native void sendLeaveNotify (short window, int x, int y, | 92 | public static native long sendLeaveNotify (short window, int x, int y, |
| 92 | long time); | 93 | long time); |
| 93 | 94 | ||
| 94 | /* Send an ANDROID_MOTION_NOTIFY event. */ | 95 | /* Send an ANDROID_MOTION_NOTIFY event. */ |
| 95 | public static native void sendMotionNotify (short window, int x, int y, | 96 | public static native long sendMotionNotify (short window, int x, int y, |
| 96 | long time); | 97 | long time); |
| 97 | 98 | ||
| 98 | /* Send an ANDROID_BUTTON_PRESS event. */ | 99 | /* Send an ANDROID_BUTTON_PRESS event. */ |
| 99 | public static native void sendButtonPress (short window, int x, int y, | 100 | public static native long sendButtonPress (short window, int x, int y, |
| 100 | long time, int state, | 101 | long time, int state, |
| 101 | int button); | 102 | int button); |
| 102 | 103 | ||
| 103 | /* Send an ANDROID_BUTTON_RELEASE event. */ | 104 | /* Send an ANDROID_BUTTON_RELEASE event. */ |
| 104 | public static native void sendButtonRelease (short window, int x, int y, | 105 | public static native long sendButtonRelease (short window, int x, int y, |
| 105 | long time, int state, | 106 | long time, int state, |
| 106 | int button); | 107 | int button); |
| 107 | 108 | ||
| 108 | /* Send an ANDROID_TOUCH_DOWN event. */ | 109 | /* Send an ANDROID_TOUCH_DOWN event. */ |
| 109 | public static native void sendTouchDown (short window, int x, int y, | 110 | public static native long sendTouchDown (short window, int x, int y, |
| 110 | long time, int pointerID); | 111 | long time, int pointerID); |
| 111 | 112 | ||
| 112 | /* Send an ANDROID_TOUCH_UP event. */ | 113 | /* Send an ANDROID_TOUCH_UP event. */ |
| 113 | public static native void sendTouchUp (short window, int x, int y, | 114 | public static native long sendTouchUp (short window, int x, int y, |
| 114 | long time, int pointerID); | 115 | long time, int pointerID); |
| 115 | 116 | ||
| 116 | /* Send an ANDROID_TOUCH_MOVE event. */ | 117 | /* Send an ANDROID_TOUCH_MOVE event. */ |
| 117 | public static native void sendTouchMove (short window, int x, int y, | 118 | public static native long sendTouchMove (short window, int x, int y, |
| 118 | long time, int pointerID); | 119 | long time, int pointerID); |
| 119 | 120 | ||
| 120 | /* Send an ANDROID_WHEEL event. */ | 121 | /* Send an ANDROID_WHEEL event. */ |
| 121 | public static native void sendWheel (short window, int x, int y, | 122 | public static native long sendWheel (short window, int x, int y, |
| 122 | long time, int state, | 123 | long time, int state, |
| 123 | float xDelta, float yDelta); | 124 | float xDelta, float yDelta); |
| 124 | 125 | ||
| 125 | /* Send an ANDROID_ICONIFIED event. */ | 126 | /* Send an ANDROID_ICONIFIED event. */ |
| 126 | public static native void sendIconified (short window); | 127 | public static native long sendIconified (short window); |
| 127 | 128 | ||
| 128 | /* Send an ANDROID_DEICONIFIED event. */ | 129 | /* Send an ANDROID_DEICONIFIED event. */ |
| 129 | public static native void sendDeiconified (short window); | 130 | public static native long sendDeiconified (short window); |
| 130 | 131 | ||
| 131 | /* Send an ANDROID_CONTEXT_MENU event. */ | 132 | /* Send an ANDROID_CONTEXT_MENU event. */ |
| 132 | public static native void sendContextMenu (short window, int menuEventID); | 133 | public static native long sendContextMenu (short window, int menuEventID); |
| 133 | 134 | ||
| 134 | static | 135 | static |
| 135 | { | 136 | { |
diff --git a/java/org/gnu/emacs/EmacsPreferencesActivity.java b/java/org/gnu/emacs/EmacsPreferencesActivity.java new file mode 100644 index 00000000000..0db983984fd --- /dev/null +++ b/java/org/gnu/emacs/EmacsPreferencesActivity.java | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | /* Communication module for Android terminals. -*- c-file-style: "GNU" -*- | ||
| 2 | |||
| 3 | Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | package org.gnu.emacs; | ||
| 21 | |||
| 22 | import android.app.Activity; | ||
| 23 | import android.content.Intent; | ||
| 24 | import android.os.Bundle; | ||
| 25 | import android.os.Build; | ||
| 26 | import android.view.View; | ||
| 27 | import android.view.ViewGroup.LayoutParams; | ||
| 28 | import android.widget.LinearLayout; | ||
| 29 | import android.widget.TextView; | ||
| 30 | |||
| 31 | import android.R; | ||
| 32 | |||
| 33 | /* This module provides a ``preferences'' display for Emacs. It is | ||
| 34 | supposed to be launched from inside the Settings application to | ||
| 35 | perform various actions, such as starting Emacs with the ``-Q'' | ||
| 36 | option, which would not be possible otherwise, as there is no | ||
| 37 | command line on Android. */ | ||
| 38 | |||
| 39 | public class EmacsPreferencesActivity extends Activity | ||
| 40 | { | ||
| 41 | /* The linear layout associated with the activity. */ | ||
| 42 | private LinearLayout layout; | ||
| 43 | |||
| 44 | /* Restart Emacs with -Q. Call EmacsThread.exit to kill Emacs now, and | ||
| 45 | tell the system to EmacsActivity with some parameters later. */ | ||
| 46 | |||
| 47 | private void | ||
| 48 | startEmacsQ () | ||
| 49 | { | ||
| 50 | Intent intent; | ||
| 51 | |||
| 52 | intent = new Intent (this, EmacsActivity.class); | ||
| 53 | intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | ||
| 54 | | Intent.FLAG_ACTIVITY_CLEAR_TASK); | ||
| 55 | intent.putExtra ("org.gnu.emacs.START_DASH_Q", true); | ||
| 56 | startActivity (intent); | ||
| 57 | System.exit (0); | ||
| 58 | } | ||
| 59 | |||
| 60 | @Override | ||
| 61 | public void | ||
| 62 | onCreate (Bundle savedInstanceState) | ||
| 63 | { | ||
| 64 | LinearLayout layout; | ||
| 65 | TextView textView; | ||
| 66 | LinearLayout.LayoutParams params; | ||
| 67 | int resid; | ||
| 68 | |||
| 69 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) | ||
| 70 | setTheme (R.style.Theme_DeviceDefault_Settings); | ||
| 71 | else if (Build.VERSION.SDK_INT | ||
| 72 | >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) | ||
| 73 | setTheme (R.style.Theme_DeviceDefault); | ||
| 74 | |||
| 75 | layout = new LinearLayout (this); | ||
| 76 | layout.setOrientation (LinearLayout.VERTICAL); | ||
| 77 | setContentView (layout); | ||
| 78 | |||
| 79 | textView = new TextView (this); | ||
| 80 | textView.setPadding (8, 20, 20, 8); | ||
| 81 | |||
| 82 | params = new LinearLayout.LayoutParams (LayoutParams.MATCH_PARENT, | ||
| 83 | LayoutParams.WRAP_CONTENT); | ||
| 84 | textView.setLayoutParams (params); | ||
| 85 | textView.setText ("(Re)start Emacs with -Q"); | ||
| 86 | textView.setOnClickListener (new View.OnClickListener () { | ||
| 87 | @Override | ||
| 88 | public void | ||
| 89 | onClick (View view) | ||
| 90 | { | ||
| 91 | startEmacsQ (); | ||
| 92 | } | ||
| 93 | }); | ||
| 94 | layout.addView (textView); | ||
| 95 | |||
| 96 | super.onCreate (savedInstanceState); | ||
| 97 | } | ||
| 98 | }; | ||
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index bcf8d9ff6e8..95f21b211a3 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java | |||
| @@ -32,7 +32,13 @@ import android.view.InputDevice; | |||
| 32 | import android.view.KeyEvent; | 32 | import android.view.KeyEvent; |
| 33 | 33 | ||
| 34 | import android.annotation.TargetApi; | 34 | import android.annotation.TargetApi; |
| 35 | |||
| 36 | import android.app.Notification; | ||
| 37 | import android.app.NotificationManager; | ||
| 38 | import android.app.NotificationChannel; | ||
| 39 | import android.app.PendingIntent; | ||
| 35 | import android.app.Service; | 40 | import android.app.Service; |
| 41 | |||
| 36 | import android.content.Context; | 42 | import android.content.Context; |
| 37 | import android.content.Intent; | 43 | import android.content.Intent; |
| 38 | import android.content.res.AssetManager; | 44 | import android.content.res.AssetManager; |
| @@ -63,6 +69,7 @@ public class EmacsService extends Service | |||
| 63 | public static final String TAG = "EmacsService"; | 69 | public static final String TAG = "EmacsService"; |
| 64 | public static final int MAX_PENDING_REQUESTS = 256; | 70 | public static final int MAX_PENDING_REQUESTS = 256; |
| 65 | public static volatile EmacsService SERVICE; | 71 | public static volatile EmacsService SERVICE; |
| 72 | public static boolean needDashQ; | ||
| 66 | 73 | ||
| 67 | private EmacsThread thread; | 74 | private EmacsThread thread; |
| 68 | private Handler handler; | 75 | private Handler handler; |
| @@ -74,6 +81,31 @@ public class EmacsService extends Service | |||
| 74 | public int | 81 | public int |
| 75 | onStartCommand (Intent intent, int flags, int startId) | 82 | onStartCommand (Intent intent, int flags, int startId) |
| 76 | { | 83 | { |
| 84 | Notification notification; | ||
| 85 | NotificationManager manager; | ||
| 86 | NotificationChannel channel; | ||
| 87 | String infoBlurb; | ||
| 88 | Object tem; | ||
| 89 | |||
| 90 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) | ||
| 91 | { | ||
| 92 | tem = getSystemService (Context.NOTIFICATION_SERVICE); | ||
| 93 | manager = (NotificationManager) tem; | ||
| 94 | infoBlurb = ("See (emacs)Android Environment for more" | ||
| 95 | + " details about this notification."); | ||
| 96 | channel | ||
| 97 | = new NotificationChannel ("emacs", "Emacs persistent notification", | ||
| 98 | NotificationManager.IMPORTANCE_DEFAULT); | ||
| 99 | manager.createNotificationChannel (channel); | ||
| 100 | notification = (new Notification.Builder (this, "emacs") | ||
| 101 | .setContentTitle ("Emacs") | ||
| 102 | .setContentText (infoBlurb) | ||
| 103 | .setSmallIcon (android.R.drawable.sym_def_app_icon) | ||
| 104 | .build ()); | ||
| 105 | manager.notify (1, notification); | ||
| 106 | startForeground (1, notification); | ||
| 107 | } | ||
| 108 | |||
| 77 | return START_NOT_STICKY; | 109 | return START_NOT_STICKY; |
| 78 | } | 110 | } |
| 79 | 111 | ||
| @@ -137,7 +169,7 @@ public class EmacsService extends Service | |||
| 137 | this); | 169 | this); |
| 138 | 170 | ||
| 139 | /* Start the thread that runs Emacs. */ | 171 | /* Start the thread that runs Emacs. */ |
| 140 | thread = new EmacsThread (this); | 172 | thread = new EmacsThread (this, needDashQ); |
| 141 | thread.start (); | 173 | thread.start (); |
| 142 | } | 174 | } |
| 143 | catch (IOException exception) | 175 | catch (IOException exception) |
| @@ -444,4 +476,32 @@ public class EmacsService extends Service | |||
| 444 | } | 476 | } |
| 445 | } | 477 | } |
| 446 | } | 478 | } |
| 479 | |||
| 480 | |||
| 481 | |||
| 482 | /* Start the Emacs service if necessary. On Android 26 and up, | ||
| 483 | start Emacs as a foreground service with a notification, to avoid | ||
| 484 | it being killed by the system. | ||
| 485 | |||
| 486 | On older systems, simply start it as a normal background | ||
| 487 | service. */ | ||
| 488 | |||
| 489 | public static void | ||
| 490 | startEmacsService (Context context) | ||
| 491 | { | ||
| 492 | PendingIntent intent; | ||
| 493 | |||
| 494 | if (EmacsService.SERVICE == null) | ||
| 495 | { | ||
| 496 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) | ||
| 497 | /* Start the Emacs service now. */ | ||
| 498 | context.startService (new Intent (context, | ||
| 499 | EmacsService.class)); | ||
| 500 | else | ||
| 501 | /* Display the permanant notification and start Emacs as a | ||
| 502 | foreground service. */ | ||
| 503 | context.startForegroundService (new Intent (context, | ||
| 504 | EmacsService.class)); | ||
| 505 | } | ||
| 506 | } | ||
| 447 | }; | 507 | }; |
diff --git a/java/org/gnu/emacs/EmacsSurfaceView.java b/java/org/gnu/emacs/EmacsSurfaceView.java index f713818d4bc..2fe9e103b2b 100644 --- a/java/org/gnu/emacs/EmacsSurfaceView.java +++ b/java/org/gnu/emacs/EmacsSurfaceView.java | |||
| @@ -32,53 +32,106 @@ import android.util.Log; | |||
| 32 | public class EmacsSurfaceView extends SurfaceView | 32 | public class EmacsSurfaceView extends SurfaceView |
| 33 | { | 33 | { |
| 34 | private static final String TAG = "EmacsSurfaceView"; | 34 | private static final String TAG = "EmacsSurfaceView"; |
| 35 | |||
| 36 | public Object surfaceChangeLock; | 35 | public Object surfaceChangeLock; |
| 37 | private boolean created; | 36 | private boolean created; |
| 37 | private EmacsView view; | ||
| 38 | 38 | ||
| 39 | public | 39 | /* This is the callback used on Android 8 to 25. */ |
| 40 | EmacsSurfaceView (final EmacsView view) | ||
| 41 | { | ||
| 42 | super (view.getContext ()); | ||
| 43 | |||
| 44 | surfaceChangeLock = new Object (); | ||
| 45 | 40 | ||
| 46 | getHolder ().addCallback (new SurfaceHolder.Callback () { | 41 | private class Callback implements SurfaceHolder.Callback |
| 47 | @Override | 42 | { |
| 48 | public void | 43 | @Override |
| 49 | surfaceChanged (SurfaceHolder holder, int format, | 44 | public void |
| 50 | int width, int height) | 45 | surfaceChanged (SurfaceHolder holder, int format, |
| 46 | int width, int height) | ||
| 47 | { | ||
| 48 | Log.d (TAG, "surfaceChanged: " + view + ", " + view.pendingConfigure); | ||
| 49 | |||
| 50 | /* Make sure not to swap buffers if there is pending | ||
| 51 | configuration, because otherwise the redraw callback will not | ||
| 52 | run correctly. */ | ||
| 53 | |||
| 54 | if (view.pendingConfigure == 0) | ||
| 55 | view.swapBuffers (); | ||
| 56 | } | ||
| 57 | |||
| 58 | @Override | ||
| 59 | public void | ||
| 60 | surfaceCreated (SurfaceHolder holder) | ||
| 61 | { | ||
| 62 | synchronized (surfaceChangeLock) | ||
| 51 | { | 63 | { |
| 52 | Log.d (TAG, "surfaceChanged: " + view); | 64 | Log.d (TAG, "surfaceCreated: " + view); |
| 53 | view.swapBuffers (); | 65 | created = true; |
| 54 | } | 66 | } |
| 55 | 67 | ||
| 56 | @Override | 68 | /* Drop the lock when doing this, or a deadlock can |
| 57 | public void | 69 | result. */ |
| 58 | surfaceCreated (SurfaceHolder holder) | 70 | view.swapBuffers (); |
| 59 | { | 71 | } |
| 60 | synchronized (surfaceChangeLock) | ||
| 61 | { | ||
| 62 | Log.d (TAG, "surfaceCreated: " + view); | ||
| 63 | created = true; | ||
| 64 | } | ||
| 65 | |||
| 66 | /* Drop the lock when doing this, or a deadlock can | ||
| 67 | result. */ | ||
| 68 | view.swapBuffers (); | ||
| 69 | } | ||
| 70 | 72 | ||
| 71 | @Override | 73 | @Override |
| 72 | public void | 74 | public void |
| 73 | surfaceDestroyed (SurfaceHolder holder) | 75 | surfaceDestroyed (SurfaceHolder holder) |
| 76 | { | ||
| 77 | synchronized (surfaceChangeLock) | ||
| 74 | { | 78 | { |
| 75 | synchronized (surfaceChangeLock) | 79 | Log.d (TAG, "surfaceDestroyed: " + view); |
| 76 | { | 80 | created = false; |
| 77 | Log.d (TAG, "surfaceDestroyed: " + view); | ||
| 78 | created = false; | ||
| 79 | } | ||
| 80 | } | 81 | } |
| 81 | }); | 82 | } |
| 83 | } | ||
| 84 | |||
| 85 | /* And this is the callback used on Android 26 and later. It is | ||
| 86 | used because it can tell the system when drawing completes. */ | ||
| 87 | |||
| 88 | private class Callback2 extends Callback implements SurfaceHolder.Callback2 | ||
| 89 | { | ||
| 90 | @Override | ||
| 91 | public void | ||
| 92 | surfaceRedrawNeeded (SurfaceHolder holder) | ||
| 93 | { | ||
| 94 | /* This version is not supported. */ | ||
| 95 | return; | ||
| 96 | } | ||
| 97 | |||
| 98 | @Override | ||
| 99 | public void | ||
| 100 | surfaceRedrawNeededAsync (SurfaceHolder holder, | ||
| 101 | Runnable drawingFinished) | ||
| 102 | { | ||
| 103 | Runnable old; | ||
| 104 | |||
| 105 | Log.d (TAG, "surfaceRedrawNeededAsync: " + view.pendingConfigure); | ||
| 106 | |||
| 107 | /* The system calls this function when it wants to know whether | ||
| 108 | or not Emacs is still configuring itself in response to a | ||
| 109 | resize. | ||
| 110 | |||
| 111 | If the view did not send an outstanding ConfigureNotify | ||
| 112 | event, then call drawingFinish immediately. Else, give it to | ||
| 113 | the view to execute after drawing completes. */ | ||
| 114 | |||
| 115 | if (view.pendingConfigure == 0) | ||
| 116 | drawingFinished.run (); | ||
| 117 | else | ||
| 118 | /* And set this runnable to run once drawing completes. */ | ||
| 119 | view.drawingFinished = drawingFinished; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | public | ||
| 124 | EmacsSurfaceView (final EmacsView view) | ||
| 125 | { | ||
| 126 | super (view.getContext ()); | ||
| 127 | |||
| 128 | this.surfaceChangeLock = new Object (); | ||
| 129 | this.view = view; | ||
| 130 | |||
| 131 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) | ||
| 132 | getHolder ().addCallback (new Callback ()); | ||
| 133 | else | ||
| 134 | getHolder ().addCallback (new Callback2 ()); | ||
| 82 | } | 135 | } |
| 83 | 136 | ||
| 84 | public boolean | 137 | public boolean |
diff --git a/java/org/gnu/emacs/EmacsThread.java b/java/org/gnu/emacs/EmacsThread.java index 0882753747f..f9bc132f354 100644 --- a/java/org/gnu/emacs/EmacsThread.java +++ b/java/org/gnu/emacs/EmacsThread.java | |||
| @@ -23,12 +23,13 @@ import java.lang.Thread; | |||
| 23 | 23 | ||
| 24 | public class EmacsThread extends Thread | 24 | public class EmacsThread extends Thread |
| 25 | { | 25 | { |
| 26 | EmacsService context; | 26 | /* Whether or not Emacs should be started -Q. */ |
| 27 | private boolean startDashQ; | ||
| 27 | 28 | ||
| 28 | public | 29 | public |
| 29 | EmacsThread (EmacsService service) | 30 | EmacsThread (EmacsService service, boolean startDashQ) |
| 30 | { | 31 | { |
| 31 | context = service; | 32 | this.startDashQ = startDashQ; |
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | public void | 35 | public void |
| @@ -36,7 +37,10 @@ public class EmacsThread extends Thread | |||
| 36 | { | 37 | { |
| 37 | String args[]; | 38 | String args[]; |
| 38 | 39 | ||
| 39 | args = new String[] { "libandroid-emacs.so", }; | 40 | if (!startDashQ) |
| 41 | args = new String[] { "libandroid-emacs.so", }; | ||
| 42 | else | ||
| 43 | args = new String[] { "libandroid-emacs.so", "-Q", }; | ||
| 40 | 44 | ||
| 41 | /* Run the native code now. */ | 45 | /* Run the native code now. */ |
| 42 | EmacsNative.initEmacs (args); | 46 | EmacsNative.initEmacs (args); |
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index 82f44acaebe..74bbb7b3ecc 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java | |||
| @@ -19,6 +19,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 19 | 19 | ||
| 20 | package org.gnu.emacs; | 20 | package org.gnu.emacs; |
| 21 | 21 | ||
| 22 | import android.content.Context; | ||
| 22 | import android.content.res.ColorStateList; | 23 | import android.content.res.ColorStateList; |
| 23 | 24 | ||
| 24 | import android.view.ContextMenu; | 25 | import android.view.ContextMenu; |
| @@ -27,6 +28,8 @@ import android.view.KeyEvent; | |||
| 27 | import android.view.MotionEvent; | 28 | import android.view.MotionEvent; |
| 28 | import android.view.ViewGroup; | 29 | import android.view.ViewGroup; |
| 29 | 30 | ||
| 31 | import android.view.inputmethod.InputMethodManager; | ||
| 32 | |||
| 30 | import android.graphics.Bitmap; | 33 | import android.graphics.Bitmap; |
| 31 | import android.graphics.Canvas; | 34 | import android.graphics.Canvas; |
| 32 | import android.graphics.Rect; | 35 | import android.graphics.Rect; |
| @@ -86,11 +89,23 @@ public class EmacsView extends ViewGroup | |||
| 86 | /* The serial of the last clip rectangle change. */ | 89 | /* The serial of the last clip rectangle change. */ |
| 87 | private long lastClipSerial; | 90 | private long lastClipSerial; |
| 88 | 91 | ||
| 92 | /* The InputMethodManager for this view's context. */ | ||
| 93 | private InputMethodManager imManager; | ||
| 94 | |||
| 95 | /* Runnable that will run once drawing completes. */ | ||
| 96 | public Runnable drawingFinished; | ||
| 97 | |||
| 98 | /* Serial of the last ConfigureNotify event sent that Emacs has not | ||
| 99 | yet responded to. 0 if there is no such outstanding event. */ | ||
| 100 | public long pendingConfigure; | ||
| 101 | |||
| 89 | public | 102 | public |
| 90 | EmacsView (EmacsWindow window) | 103 | EmacsView (EmacsWindow window) |
| 91 | { | 104 | { |
| 92 | super (EmacsService.SERVICE); | 105 | super (EmacsService.SERVICE); |
| 93 | 106 | ||
| 107 | Object tem; | ||
| 108 | |||
| 94 | this.window = window; | 109 | this.window = window; |
| 95 | this.damageRegion = new Region (); | 110 | this.damageRegion = new Region (); |
| 96 | this.paint = new Paint (); | 111 | this.paint = new Paint (); |
| @@ -111,6 +126,10 @@ public class EmacsView extends ViewGroup | |||
| 111 | /* Get rid of the default focus highlight. */ | 126 | /* Get rid of the default focus highlight. */ |
| 112 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) | 127 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) |
| 113 | setDefaultFocusHighlightEnabled (false); | 128 | setDefaultFocusHighlightEnabled (false); |
| 129 | |||
| 130 | /* Obtain the input method manager. */ | ||
| 131 | tem = getContext ().getSystemService (Context.INPUT_METHOD_SERVICE); | ||
| 132 | imManager = (InputMethodManager) tem; | ||
| 114 | } | 133 | } |
| 115 | 134 | ||
| 116 | private void | 135 | private void |
| @@ -259,7 +278,8 @@ public class EmacsView extends ViewGroup | |||
| 259 | if (changed || mustReportLayout) | 278 | if (changed || mustReportLayout) |
| 260 | { | 279 | { |
| 261 | mustReportLayout = false; | 280 | mustReportLayout = false; |
| 262 | window.viewLayout (left, top, right, bottom); | 281 | pendingConfigure |
| 282 | = window.viewLayout (left, top, right, bottom); | ||
| 263 | } | 283 | } |
| 264 | 284 | ||
| 265 | measuredWidth = right - left; | 285 | measuredWidth = right - left; |
| @@ -538,4 +558,37 @@ public class EmacsView extends ViewGroup | |||
| 538 | Runtime.getRuntime ().gc (); | 558 | Runtime.getRuntime ().gc (); |
| 539 | } | 559 | } |
| 540 | } | 560 | } |
| 561 | |||
| 562 | public void | ||
| 563 | showOnScreenKeyboard () | ||
| 564 | { | ||
| 565 | /* Specifying no flags at all tells the system the user asked for | ||
| 566 | the input method to be displayed. */ | ||
| 567 | imManager.showSoftInput (this, 0); | ||
| 568 | } | ||
| 569 | |||
| 570 | public void | ||
| 571 | hideOnScreenKeyboard () | ||
| 572 | { | ||
| 573 | imManager.hideSoftInputFromWindow (this.getWindowToken (), | ||
| 574 | 0); | ||
| 575 | } | ||
| 576 | |||
| 577 | public void | ||
| 578 | windowUpdated (long serial) | ||
| 579 | { | ||
| 580 | Log.d (TAG, "windowUpdated: serial is " + serial); | ||
| 581 | |||
| 582 | if (pendingConfigure <= serial | ||
| 583 | /* Detect wraparound. */ | ||
| 584 | || pendingConfigure - serial >= 0x7fffffff) | ||
| 585 | { | ||
| 586 | pendingConfigure = 0; | ||
| 587 | |||
| 588 | if (drawingFinished != null) | ||
| 589 | drawingFinished.run (); | ||
| 590 | |||
| 591 | drawingFinished = null; | ||
| 592 | } | ||
| 593 | } | ||
| 541 | }; | 594 | }; |
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index c5b1522086c..8511af9193e 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java | |||
| @@ -233,7 +233,7 @@ public class EmacsWindow extends EmacsHandleObject | |||
| 233 | return attached; | 233 | return attached; |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | public void | 236 | public long |
| 237 | viewLayout (int left, int top, int right, int bottom) | 237 | viewLayout (int left, int top, int right, int bottom) |
| 238 | { | 238 | { |
| 239 | int rectWidth, rectHeight; | 239 | int rectWidth, rectHeight; |
| @@ -249,10 +249,10 @@ public class EmacsWindow extends EmacsHandleObject | |||
| 249 | rectWidth = right - left; | 249 | rectWidth = right - left; |
| 250 | rectHeight = bottom - top; | 250 | rectHeight = bottom - top; |
| 251 | 251 | ||
| 252 | EmacsNative.sendConfigureNotify (this.handle, | 252 | return EmacsNative.sendConfigureNotify (this.handle, |
| 253 | System.currentTimeMillis (), | 253 | System.currentTimeMillis (), |
| 254 | left, top, rectWidth, | 254 | left, top, rectWidth, |
| 255 | rectHeight); | 255 | rectHeight); |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | public void | 258 | public void |
| @@ -589,11 +589,20 @@ public class EmacsWindow extends EmacsHandleObject | |||
| 589 | EmacsActivity.invalidateFocus (); | 589 | EmacsActivity.invalidateFocus (); |
| 590 | } | 590 | } |
| 591 | 591 | ||
| 592 | /* Notice that the activity has been detached or destroyed. | ||
| 593 | |||
| 594 | ISFINISHING is set if the activity is not the main activity, or | ||
| 595 | if the activity was not destroyed in response to explicit user | ||
| 596 | action. */ | ||
| 597 | |||
| 592 | public void | 598 | public void |
| 593 | onActivityDetached () | 599 | onActivityDetached (boolean isFinishing) |
| 594 | { | 600 | { |
| 595 | /* Destroy the associated frame when the activity is detached. */ | 601 | /* Destroy the associated frame when the activity is detached in |
| 596 | EmacsNative.sendWindowAction (this.handle, 0); | 602 | response to explicit user action. */ |
| 603 | |||
| 604 | if (isFinishing) | ||
| 605 | EmacsNative.sendWindowAction (this.handle, 0); | ||
| 597 | } | 606 | } |
| 598 | 607 | ||
| 599 | /* Look through the button state to determine what button EVENT was | 608 | /* Look through the button state to determine what button EVENT was |
| @@ -1064,4 +1073,37 @@ public class EmacsWindow extends EmacsHandleObject | |||
| 1064 | /* Return the resulting coordinates. */ | 1073 | /* Return the resulting coordinates. */ |
| 1065 | return array; | 1074 | return array; |
| 1066 | } | 1075 | } |
| 1076 | |||
| 1077 | public void | ||
| 1078 | toggleOnScreenKeyboard (final boolean on) | ||
| 1079 | { | ||
| 1080 | EmacsService.SERVICE.runOnUiThread (new Runnable () { | ||
| 1081 | @Override | ||
| 1082 | public void | ||
| 1083 | run () | ||
| 1084 | { | ||
| 1085 | if (on) | ||
| 1086 | view.showOnScreenKeyboard (); | ||
| 1087 | else | ||
| 1088 | view.hideOnScreenKeyboard (); | ||
| 1089 | } | ||
| 1090 | }); | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | /* Notice that outstanding configure events have been processed. | ||
| 1094 | SERIAL is checked in the UI thread to verify that no new | ||
| 1095 | configure events have been generated in the mean time. */ | ||
| 1096 | |||
| 1097 | public void | ||
| 1098 | windowUpdated (final long serial) | ||
| 1099 | { | ||
| 1100 | EmacsService.SERVICE.runOnUiThread (new Runnable () { | ||
| 1101 | @Override | ||
| 1102 | public void | ||
| 1103 | run () | ||
| 1104 | { | ||
| 1105 | view.windowUpdated (serial); | ||
| 1106 | } | ||
| 1107 | }); | ||
| 1108 | } | ||
| 1067 | }; | 1109 | }; |
diff --git a/java/org/gnu/emacs/EmacsWindowAttachmentManager.java b/java/org/gnu/emacs/EmacsWindowAttachmentManager.java index 15eb3bb65c2..510300571b8 100644 --- a/java/org/gnu/emacs/EmacsWindowAttachmentManager.java +++ b/java/org/gnu/emacs/EmacsWindowAttachmentManager.java | |||
| @@ -134,7 +134,7 @@ public class EmacsWindowAttachmentManager | |||
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | public void | 136 | public void |
| 137 | removeWindowConsumer (WindowConsumer consumer) | 137 | removeWindowConsumer (WindowConsumer consumer, boolean isFinishing) |
| 138 | { | 138 | { |
| 139 | EmacsWindow window; | 139 | EmacsWindow window; |
| 140 | 140 | ||
| @@ -147,7 +147,7 @@ public class EmacsWindowAttachmentManager | |||
| 147 | Log.d (TAG, "removeWindowConsumer: detaching " + window); | 147 | Log.d (TAG, "removeWindowConsumer: detaching " + window); |
| 148 | 148 | ||
| 149 | consumer.detachWindow (); | 149 | consumer.detachWindow (); |
| 150 | window.onActivityDetached (); | 150 | window.onActivityDetached (isFinishing); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | Log.d (TAG, "removeWindowConsumer: removing " + consumer); | 153 | Log.d (TAG, "removeWindowConsumer: removing " + consumer); |