aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorPo Lu2023-01-15 11:57:10 +0800
committerPo Lu2023-01-15 11:57:10 +0800
commit6e2bc91d924fbeb0ad5728e0424eabc905c0d366 (patch)
treef2835948a308d9d0898b9ef868893560048f6812 /java
parentc02a7b2ff48746fab891db16f58ccdc11d161745 (diff)
downloademacs-6e2bc91d924fbeb0ad5728e0424eabc905c0d366.tar.gz
emacs-6e2bc91d924fbeb0ad5728e0424eabc905c0d366.zip
Implement toolkit menus on Android
* java/org/gnu/emacs/EmacsActivity.java (onContextMenuClosed): New function. * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu): New field `itemAlreadySelected'. (onMenuItemClick): New function. (inflateMenuItems): Attach onClickListener as appropriate. (display1): Clear itemAlreadySelected. (display): Fix runnable synchronization. * java/org/gnu/emacs/EmacsNative.java (sendContextMenu): New function. * java/org/gnu/emacs/EmacsView.java (popupMenu): (cancelPopupMenu): Set popupactive correctly. * src/android.c (android_run_select_thread): Fix android_select again. (android_wait_event): New function. * src/android.h: Update prototypes. * src/androidgui.h (enum android_event_type): New `ANDROID_CONTEXT_MENU' event. (struct android_menu_event, union android_event): Add new event. * src/androidmenu.c (struct android_emacs_context_menu): New structure. (android_init_emacs_context_menu): Add `dismiss' method. (struct android_dismiss_menu_data): New structure. (android_dismiss_menu, android_process_events_for_menu): New functions. (android_menu_show): Set an actual item ID. (popup_activated): Define when stubify as well. (Fmenu_or_popup_active_p): New function. (syms_of_androidmenu): New function. * src/androidterm.c (handle_one_android_event): Handle context menu events. * src/androidterm.h (struct android_display_info): New field for menu item ID. * src/emacs.c (android_emacs_init): Call syms_of_androidmenu. * src/xdisp.c (note_mouse_highlight): Return if popup_activated on Android as well.
Diffstat (limited to 'java')
-rw-r--r--java/org/gnu/emacs/EmacsActivity.java15
-rw-r--r--java/org/gnu/emacs/EmacsContextMenu.java64
-rw-r--r--java/org/gnu/emacs/EmacsNative.java3
-rw-r--r--java/org/gnu/emacs/EmacsView.java2
4 files changed, 77 insertions, 7 deletions
diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java
index 4cd286d1e89..4b96a376987 100644
--- a/java/org/gnu/emacs/EmacsActivity.java
+++ b/java/org/gnu/emacs/EmacsActivity.java
@@ -30,6 +30,7 @@ import android.os.Bundle;
30import android.util.Log; 30import android.util.Log;
31import android.widget.FrameLayout; 31import android.widget.FrameLayout;
32import android.widget.FrameLayout.LayoutParams; 32import android.widget.FrameLayout.LayoutParams;
33import android.view.Menu;
33 34
34public class EmacsActivity extends Activity 35public class EmacsActivity extends Activity
35 implements EmacsWindowAttachmentManager.WindowConsumer 36 implements EmacsWindowAttachmentManager.WindowConsumer
@@ -227,4 +228,18 @@ public class EmacsActivity extends Activity
227 EmacsWindowAttachmentManager.MANAGER.noticeDeiconified (this); 228 EmacsWindowAttachmentManager.MANAGER.noticeDeiconified (this);
228 super.onResume (); 229 super.onResume ();
229 } 230 }
231
232 @Override
233 public void
234 onContextMenuClosed (Menu menu)
235 {
236 Log.d (TAG, "onContextMenuClosed: " + menu);
237
238 /* Send a context menu event given that no menu item has already
239 been selected. */
240 if (!EmacsContextMenu.itemAlreadySelected)
241 EmacsNative.sendContextMenu ((short) 0, 0);
242
243 super.onContextMenuClosed (menu);
244 }
230}; 245};
diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java
index 8d7ae08b257..02dd1c7efa9 100644
--- a/java/org/gnu/emacs/EmacsContextMenu.java
+++ b/java/org/gnu/emacs/EmacsContextMenu.java
@@ -31,6 +31,8 @@ import android.view.Menu;
31import android.view.MenuItem; 31import android.view.MenuItem;
32import android.view.View; 32import android.view.View;
33 33
34import android.util.Log;
35
34import android.widget.PopupMenu; 36import android.widget.PopupMenu;
35 37
36/* Context menu implementation. This object is built from JNI and 38/* Context menu implementation. This object is built from JNI and
@@ -40,12 +42,31 @@ import android.widget.PopupMenu;
40 42
41public class EmacsContextMenu 43public class EmacsContextMenu
42{ 44{
43 private class Item 45 private static final String TAG = "EmacsContextMenu";
46
47 /* Whether or not an item was selected. */
48 public static boolean itemAlreadySelected;
49
50 private class Item implements MenuItem.OnMenuItemClickListener
44 { 51 {
45 public int itemID; 52 public int itemID;
46 public String itemName; 53 public String itemName;
47 public EmacsContextMenu subMenu; 54 public EmacsContextMenu subMenu;
48 public boolean isEnabled; 55 public boolean isEnabled;
56
57 @Override
58 public boolean
59 onMenuItemClick (MenuItem item)
60 {
61 Log.d (TAG, "onMenuItemClick: " + itemName + " (" + itemID + ")");
62
63 /* Send a context menu event. */
64 EmacsNative.sendContextMenu ((short) 0, itemID);
65
66 /* Say that an item has already been selected. */
67 itemAlreadySelected = true;
68 return true;
69 }
49 }; 70 };
50 71
51 public List<Item> menuItems; 72 public List<Item> menuItems;
@@ -137,6 +158,7 @@ public class EmacsContextMenu
137 else 158 else
138 { 159 {
139 menuItem = menu.add (item.itemName); 160 menuItem = menu.add (item.itemName);
161 menuItem.setOnMenuItemClickListener (item);
140 162
141 /* If the item ID is zero, then disable the item. */ 163 /* If the item ID is zero, then disable the item. */
142 if (item.itemID == 0 || !item.isEnabled) 164 if (item.itemID == 0 || !item.isEnabled)
@@ -171,6 +193,10 @@ public class EmacsContextMenu
171 private boolean 193 private boolean
172 display1 (EmacsWindow window, int xPosition, int yPosition) 194 display1 (EmacsWindow window, int xPosition, int yPosition)
173 { 195 {
196 /* Set this flag to false. It is used to decide whether or not to
197 send 0 in response to the context menu being closed. */
198 itemAlreadySelected = false;
199
174 return window.view.popupMenu (this, xPosition, yPosition); 200 return window.view.popupMenu (this, xPosition, yPosition);
175 } 201 }
176 202
@@ -199,15 +225,39 @@ public class EmacsContextMenu
199 } 225 }
200 }; 226 };
201 227
202 try 228 synchronized (runnable)
203 { 229 {
204 runnable.wait (); 230 EmacsService.SERVICE.runOnUiThread (runnable);
205 } 231
206 catch (InterruptedException e) 232 try
207 { 233 {
208 EmacsNative.emacsAbort (); 234 runnable.wait ();
235 }
236 catch (InterruptedException e)
237 {
238 EmacsNative.emacsAbort ();
239 }
209 } 240 }
210 241
211 return rc.thing; 242 return rc.thing;
212 } 243 }
244
245 /* Dismiss this context menu. WINDOW is the window where the
246 context menu is being displayed. */
247
248 public void
249 dismiss (final EmacsWindow window)
250 {
251 Runnable runnable;
252
253 EmacsService.SERVICE.runOnUiThread (new Runnable () {
254 @Override
255 public void
256 run ()
257 {
258 window.view.cancelPopupMenu ();
259 itemAlreadySelected = false;
260 }
261 });
262 }
213}; 263};
diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java
index a11e509cd7f..4a80f88edcf 100644
--- a/java/org/gnu/emacs/EmacsNative.java
+++ b/java/org/gnu/emacs/EmacsNative.java
@@ -124,6 +124,9 @@ public class EmacsNative
124 /* Send an ANDROID_DEICONIFIED event. */ 124 /* Send an ANDROID_DEICONIFIED event. */
125 public static native void sendDeiconified (short window); 125 public static native void sendDeiconified (short window);
126 126
127 /* Send an ANDROID_CONTEXT_MENU event. */
128 public static native void sendContextMenu (short window, int menuEventID);
129
127 static 130 static
128 { 131 {
129 System.loadLibrary ("emacs"); 132 System.loadLibrary ("emacs");
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java
index 1391f630be0..445d8ffa023 100644
--- a/java/org/gnu/emacs/EmacsView.java
+++ b/java/org/gnu/emacs/EmacsView.java
@@ -453,6 +453,7 @@ public class EmacsView extends ViewGroup
453 return false; 453 return false;
454 454
455 contextMenu = menu; 455 contextMenu = menu;
456 popupActive = true;
456 457
457 /* On API 21 or later, use showContextMenu (float, float). */ 458 /* On API 21 or later, use showContextMenu (float, float). */
458 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) 459 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
@@ -469,5 +470,6 @@ public class EmacsView extends ViewGroup
469 + " popupActive set"); 470 + " popupActive set");
470 471
471 contextMenu = null; 472 contextMenu = null;
473 popupActive = false;
472 } 474 }
473}; 475};