aboutsummaryrefslogtreecommitdiffstats
path: root/java/org
diff options
context:
space:
mode:
authorPo Lu2023-03-09 16:30:02 +0800
committerPo Lu2023-03-09 16:30:02 +0800
commite859a14bee7a84a3aaed45770c89ef60c68b3e08 (patch)
tree5f875640bc70b3726ad1a3d2f41732ecc54fbcdf /java/org
parent745890de5204850bb4173c19ceb79c698acb7a20 (diff)
downloademacs-e859a14bee7a84a3aaed45770c89ef60c68b3e08.tar.gz
emacs-e859a14bee7a84a3aaed45770c89ef60c68b3e08.zip
Fix menu and popup race conditions on Android
* java/org/gnu/emacs/EmacsActivity.java (onContextMenuClosed): * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu) (onMenuItemClick, run): * java/org/gnu/emacs/EmacsDialog.java (EmacsDialog, onClick) (createDialog, onDismiss): Take menu event serial, and pass it along in context menu events. * java/org/gnu/emacs/EmacsNative.java (sendContextMenu): New argument. * src/android.c (sendContextMenu): Pass serial number in event. * src/androidgui.h (struct android_menu_event): New field `menu_event_serial'. * src/androidmenu.c (FIND_METHOD_STATIC) (android_init_emacs_context_menu): Adjust method declarations. (android_menu_show, android_dialog_show): * src/androidterm.c (handle_one_android_event): Expect serial in context menu events. * src/androidterm.h: Update prototypes.
Diffstat (limited to 'java/org')
-rw-r--r--java/org/gnu/emacs/EmacsActivity.java8
-rw-r--r--java/org/gnu/emacs/EmacsContextMenu.java14
-rw-r--r--java/org/gnu/emacs/EmacsDialog.java15
-rw-r--r--java/org/gnu/emacs/EmacsNative.java3
4 files changed, 29 insertions, 11 deletions
diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java
index 692d8a14e22..735a464be8e 100644
--- a/java/org/gnu/emacs/EmacsActivity.java
+++ b/java/org/gnu/emacs/EmacsActivity.java
@@ -315,6 +315,8 @@ public class EmacsActivity extends Activity
315 public final void 315 public final void
316 onContextMenuClosed (Menu menu) 316 onContextMenuClosed (Menu menu)
317 { 317 {
318 int serial;
319
318 Log.d (TAG, "onContextMenuClosed: " + menu); 320 Log.d (TAG, "onContextMenuClosed: " + menu);
319 321
320 /* See the comment inside onMenuItemClick. */ 322 /* See the comment inside onMenuItemClick. */
@@ -335,7 +337,11 @@ public class EmacsActivity extends Activity
335 /* Send a context menu event given that no menu item has already 337 /* Send a context menu event given that no menu item has already
336 been selected. */ 338 been selected. */
337 if (!EmacsContextMenu.itemAlreadySelected) 339 if (!EmacsContextMenu.itemAlreadySelected)
338 EmacsNative.sendContextMenu ((short) 0, 0); 340 {
341 serial = EmacsContextMenu.lastMenuEventSerial;
342 EmacsNative.sendContextMenu ((short) 0, 0,
343 serial);
344 }
339 345
340 super.onContextMenuClosed (menu); 346 super.onContextMenuClosed (menu);
341 } 347 }
diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java
index 0553ff9d4a3..abc1869ac6a 100644
--- a/java/org/gnu/emacs/EmacsContextMenu.java
+++ b/java/org/gnu/emacs/EmacsContextMenu.java
@@ -49,6 +49,9 @@ public final class EmacsContextMenu
49 /* Whether or not a submenu was selected. */ 49 /* Whether or not a submenu was selected. */
50 public static boolean wasSubmenuSelected; 50 public static boolean wasSubmenuSelected;
51 51
52 /* The serial ID of the last context menu to be displayed. */
53 public static int lastMenuEventSerial;
54
52 private static class Item implements MenuItem.OnMenuItemClickListener 55 private static class Item implements MenuItem.OnMenuItemClickListener
53 { 56 {
54 public int itemID; 57 public int itemID;
@@ -106,7 +109,8 @@ public final class EmacsContextMenu
106 } 109 }
107 110
108 /* Send a context menu event. */ 111 /* Send a context menu event. */
109 EmacsNative.sendContextMenu ((short) 0, itemID); 112 EmacsNative.sendContextMenu ((short) 0, itemID,
113 lastMenuEventSerial);
110 114
111 /* Say that an item has already been selected. */ 115 /* Say that an item has already been selected. */
112 itemAlreadySelected = true; 116 itemAlreadySelected = true;
@@ -293,12 +297,13 @@ public final class EmacsContextMenu
293 false); 297 false);
294 } 298 }
295 299
296 /* Display this context menu on WINDOW, at xPosition and 300 /* Display this context menu on WINDOW, at xPosition and yPosition.
297 yPosition. */ 301 SERIAL is a number that will be returned in any menu event
302 generated to identify this context menu. */
298 303
299 public boolean 304 public boolean
300 display (final EmacsWindow window, final int xPosition, 305 display (final EmacsWindow window, final int xPosition,
301 final int yPosition) 306 final int yPosition, final int serial)
302 { 307 {
303 Runnable runnable; 308 Runnable runnable;
304 final Holder<Boolean> rc; 309 final Holder<Boolean> rc;
@@ -312,6 +317,7 @@ public final class EmacsContextMenu
312 { 317 {
313 synchronized (this) 318 synchronized (this)
314 { 319 {
320 lastMenuEventSerial = serial;
315 rc.thing = display1 (window, xPosition, yPosition); 321 rc.thing = display1 (window, xPosition, yPosition);
316 notify (); 322 notify ();
317 } 323 }
diff --git a/java/org/gnu/emacs/EmacsDialog.java b/java/org/gnu/emacs/EmacsDialog.java
index 80a5e5f7369..aed84de29e5 100644
--- a/java/org/gnu/emacs/EmacsDialog.java
+++ b/java/org/gnu/emacs/EmacsDialog.java
@@ -57,6 +57,9 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
57 /* Dialog to dismiss after click. */ 57 /* Dialog to dismiss after click. */
58 private AlertDialog dismissDialog; 58 private AlertDialog dismissDialog;
59 59
60 /* The menu serial associated with this dialog box. */
61 private int menuEventSerial;
62
60 private class EmacsButton implements View.OnClickListener, 63 private class EmacsButton implements View.OnClickListener,
61 DialogInterface.OnClickListener 64 DialogInterface.OnClickListener
62 { 65 {
@@ -76,7 +79,7 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
76 Log.d (TAG, "onClicked " + this); 79 Log.d (TAG, "onClicked " + this);
77 80
78 wasButtonClicked = true; 81 wasButtonClicked = true;
79 EmacsNative.sendContextMenu ((short) 0, id); 82 EmacsNative.sendContextMenu ((short) 0, id, menuEventSerial);
80 dismissDialog.dismiss (); 83 dismissDialog.dismiss ();
81 } 84 }
82 85
@@ -87,15 +90,16 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
87 Log.d (TAG, "onClicked " + this); 90 Log.d (TAG, "onClicked " + this);
88 91
89 wasButtonClicked = true; 92 wasButtonClicked = true;
90 EmacsNative.sendContextMenu ((short) 0, id); 93 EmacsNative.sendContextMenu ((short) 0, id, menuEventSerial);
91 } 94 }
92 }; 95 };
93 96
94 /* Create a popup dialog with the title TITLE and the text TEXT. 97 /* Create a popup dialog with the title TITLE and the text TEXT.
95 TITLE may be NULL. */ 98 TITLE may be NULL. MENUEVENTSERIAL is a number which will
99 identify this popup dialog inside events it sends. */
96 100
97 public static EmacsDialog 101 public static EmacsDialog
98 createDialog (String title, String text) 102 createDialog (String title, String text, int menuEventSerial)
99 { 103 {
100 EmacsDialog dialog; 104 EmacsDialog dialog;
101 105
@@ -103,6 +107,7 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
103 dialog.buttons = new ArrayList<EmacsButton> (); 107 dialog.buttons = new ArrayList<EmacsButton> ();
104 dialog.title = title; 108 dialog.title = title;
105 dialog.text = text; 109 dialog.text = text;
110 dialog.menuEventSerial = menuEventSerial;
106 111
107 return dialog; 112 return dialog;
108 } 113 }
@@ -330,6 +335,6 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
330 if (wasButtonClicked) 335 if (wasButtonClicked)
331 return; 336 return;
332 337
333 EmacsNative.sendContextMenu ((short) 0, 0); 338 EmacsNative.sendContextMenu ((short) 0, 0, menuEventSerial);
334 } 339 }
335}; 340};
diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java
index 8e626b9534b..11da5db8746 100644
--- a/java/org/gnu/emacs/EmacsNative.java
+++ b/java/org/gnu/emacs/EmacsNative.java
@@ -155,7 +155,8 @@ public final class EmacsNative
155 public static native long sendDeiconified (short window); 155 public static native long sendDeiconified (short window);
156 156
157 /* Send an ANDROID_CONTEXT_MENU event. */ 157 /* Send an ANDROID_CONTEXT_MENU event. */
158 public static native long sendContextMenu (short window, int menuEventID); 158 public static native long sendContextMenu (short window, int menuEventID,
159 int menuEventSerial);
159 160
160 /* Send an ANDROID_EXPOSE event. */ 161 /* Send an ANDROID_EXPOSE event. */
161 public static native long sendExpose (short window, int x, int y, 162 public static native long sendExpose (short window, int x, int y,