aboutsummaryrefslogtreecommitdiffstats
path: root/java/org
diff options
context:
space:
mode:
authorPo Lu2023-01-15 15:45:29 +0800
committerPo Lu2023-01-15 15:45:29 +0800
commitda9ae10636b84b88e9eb9c827b03cdaabd1611d1 (patch)
treeca5b14036c7771accabfd87dd72e1fc147bf9914 /java/org
parenta336fd98a1ed1f97d69652cade46f99868f7c7fb (diff)
downloademacs-da9ae10636b84b88e9eb9c827b03cdaabd1611d1.tar.gz
emacs-da9ae10636b84b88e9eb9c827b03cdaabd1611d1.zip
Implement submenus on Android
* java/org/gnu/emacs/EmacsActivity.java (onCreate): Set the default theme to Theme.DeviceDefault.NoActionBar if possible. (onContextMenuClosed): Add hack for Android bug. * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu) (onMenuItemClick): Set flag upon submenu selection. (inflateMenuItems): Set onClickListener for submenus as well. (display1): Clear new flag. * java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Fix rectangle bounds. * java/org/gnu/emacs/EmacsNative.java (EmacsNative): * java/org/gnu/emacs/EmacsService.java (onCreate): Pass cache directory. (sync): New function. * src/android.c (struct android_emacs_service): New method `sync'. (setEmacsParams, initEmacs): Handle cache directory. (android_init_emacs_service): Initialize new method `sync'. (android_sync): New function. * src/androidfns.c (Fx_show_tip): Call both functions. * src/androidgui.h: Update prototypes. * src/androidmenu.c (struct android_menu_subprefix) (android_free_subprefixes, android_menu_show): Handle submenu prefixes correctly. * src/androidterm.c (handle_one_android_event): Clear help echo on MotionNotify like on X. * src/menu.c (single_menu_item): Enable submenus on Android.
Diffstat (limited to 'java/org')
-rw-r--r--java/org/gnu/emacs/EmacsActivity.java12
-rw-r--r--java/org/gnu/emacs/EmacsContextMenu.java31
-rw-r--r--java/org/gnu/emacs/EmacsDrawRectangle.java2
-rw-r--r--java/org/gnu/emacs/EmacsNative.java4
-rw-r--r--java/org/gnu/emacs/EmacsService.java36
5 files changed, 78 insertions, 7 deletions
diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java
index 4b96a376987..79c0991a5d3 100644
--- a/java/org/gnu/emacs/EmacsActivity.java
+++ b/java/org/gnu/emacs/EmacsActivity.java
@@ -27,6 +27,7 @@ import android.app.Activity;
27import android.content.Context; 27import android.content.Context;
28import android.content.Intent; 28import android.content.Intent;
29import android.os.Bundle; 29import android.os.Bundle;
30import android.os.Build;
30import android.util.Log; 31import android.util.Log;
31import android.widget.FrameLayout; 32import android.widget.FrameLayout;
32import android.widget.FrameLayout.LayoutParams; 33import android.widget.FrameLayout.LayoutParams;
@@ -162,7 +163,11 @@ public class EmacsActivity extends Activity
162 FrameLayout.LayoutParams params; 163 FrameLayout.LayoutParams params;
163 164
164 /* Set the theme to one without a title bar. */ 165 /* Set the theme to one without a title bar. */
165 setTheme (android.R.style.Theme_NoTitleBar); 166
167 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
168 setTheme (android.R.style.Theme_DeviceDefault_NoActionBar);
169 else
170 setTheme (android.R.style.Theme_NoTitleBar);
166 171
167 params = new FrameLayout.LayoutParams (LayoutParams.MATCH_PARENT, 172 params = new FrameLayout.LayoutParams (LayoutParams.MATCH_PARENT,
168 LayoutParams.MATCH_PARENT); 173 LayoutParams.MATCH_PARENT);
@@ -235,6 +240,11 @@ public class EmacsActivity extends Activity
235 { 240 {
236 Log.d (TAG, "onContextMenuClosed: " + menu); 241 Log.d (TAG, "onContextMenuClosed: " + menu);
237 242
243 /* See the comment inside onMenuItemClick. */
244 if (EmacsContextMenu.wasSubmenuSelected
245 && menu.toString ().contains ("ContextMenuBuilder"))
246 return;
247
238 /* Send a context menu event given that no menu item has already 248 /* Send a context menu event given that no menu item has already
239 been selected. */ 249 been selected. */
240 if (!EmacsContextMenu.itemAlreadySelected) 250 if (!EmacsContextMenu.itemAlreadySelected)
diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java
index 02dd1c7efa9..00e204c9949 100644
--- a/java/org/gnu/emacs/EmacsContextMenu.java
+++ b/java/org/gnu/emacs/EmacsContextMenu.java
@@ -30,6 +30,7 @@ import android.os.Bundle;
30import android.view.Menu; 30import android.view.Menu;
31import android.view.MenuItem; 31import android.view.MenuItem;
32import android.view.View; 32import android.view.View;
33import android.view.SubMenu;
33 34
34import android.util.Log; 35import android.util.Log;
35 36
@@ -47,6 +48,9 @@ public class EmacsContextMenu
47 /* Whether or not an item was selected. */ 48 /* Whether or not an item was selected. */
48 public static boolean itemAlreadySelected; 49 public static boolean itemAlreadySelected;
49 50
51 /* Whether or not a submenu was selected. */
52 public static boolean wasSubmenuSelected;
53
50 private class Item implements MenuItem.OnMenuItemClickListener 54 private class Item implements MenuItem.OnMenuItemClickListener
51 { 55 {
52 public int itemID; 56 public int itemID;
@@ -60,6 +64,20 @@ public class EmacsContextMenu
60 { 64 {
61 Log.d (TAG, "onMenuItemClick: " + itemName + " (" + itemID + ")"); 65 Log.d (TAG, "onMenuItemClick: " + itemName + " (" + itemID + ")");
62 66
67 if (subMenu != null)
68 {
69 /* After opening a submenu within a submenu, Android will
70 send onContextMenuClosed for a ContextMenuBuilder. This
71 will normally confuse Emacs into thinking that the
72 context menu has been dismissed. Wrong!
73
74 Setting this flag makes EmacsActivity to only handle
75 SubMenuBuilder being closed, which always means the menu
76 has actually been dismissed. */
77 wasSubmenuSelected = true;
78 return false;
79 }
80
63 /* Send a context menu event. */ 81 /* Send a context menu event. */
64 EmacsNative.sendContextMenu ((short) 0, itemID); 82 EmacsNative.sendContextMenu ((short) 0, itemID);
65 83
@@ -144,7 +162,7 @@ public class EmacsContextMenu
144 { 162 {
145 Intent intent; 163 Intent intent;
146 MenuItem menuItem; 164 MenuItem menuItem;
147 Menu submenu; 165 SubMenu submenu;
148 166
149 for (Item item : menuItems) 167 for (Item item : menuItems)
150 { 168 {
@@ -153,7 +171,11 @@ public class EmacsContextMenu
153 /* This is a submenu. Create the submenu and add the 171 /* This is a submenu. Create the submenu and add the
154 contents of the menu to it. */ 172 contents of the menu to it. */
155 submenu = menu.addSubMenu (item.itemName); 173 submenu = menu.addSubMenu (item.itemName);
156 inflateMenuItems (submenu); 174 item.subMenu.inflateMenuItems (submenu);
175
176 /* This is still needed to set wasSubmenuSelected. */
177 menuItem = submenu.getItem ();
178 menuItem.setOnMenuItemClickListener (item);
157 } 179 }
158 else 180 else
159 { 181 {
@@ -184,7 +206,7 @@ public class EmacsContextMenu
184 public EmacsContextMenu 206 public EmacsContextMenu
185 parent () 207 parent ()
186 { 208 {
187 return parent; 209 return this.parent;
188 } 210 }
189 211
190 /* Like display, but does the actual work and runs in the main 212 /* Like display, but does the actual work and runs in the main
@@ -197,6 +219,9 @@ public class EmacsContextMenu
197 send 0 in response to the context menu being closed. */ 219 send 0 in response to the context menu being closed. */
198 itemAlreadySelected = false; 220 itemAlreadySelected = false;
199 221
222 /* No submenu has been selected yet. */
223 wasSubmenuSelected = false;
224
200 return window.view.popupMenu (this, xPosition, yPosition); 225 return window.view.popupMenu (this, xPosition, yPosition);
201 } 226 }
202 227
diff --git a/java/org/gnu/emacs/EmacsDrawRectangle.java b/java/org/gnu/emacs/EmacsDrawRectangle.java
index 84ff498847b..b42e9556e8c 100644
--- a/java/org/gnu/emacs/EmacsDrawRectangle.java
+++ b/java/org/gnu/emacs/EmacsDrawRectangle.java
@@ -59,7 +59,7 @@ public class EmacsDrawRectangle
59 } 59 }
60 60
61 paint = gc.gcPaint; 61 paint = gc.gcPaint;
62 rect = new Rect (x + 1, y + 1, x + width, y + height); 62 rect = new Rect (x, y, x + width, y + height);
63 63
64 paint.setStyle (Paint.Style.STROKE); 64 paint.setStyle (Paint.Style.STROKE);
65 65
diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java
index 4a80f88edcf..2f3a732ea7c 100644
--- a/java/org/gnu/emacs/EmacsNative.java
+++ b/java/org/gnu/emacs/EmacsNative.java
@@ -38,6 +38,9 @@ public class EmacsNative
38 libDir must be the package's data storage location for native 38 libDir must be the package's data storage location for native
39 libraries. It is used as PATH. 39 libraries. It is used as PATH.
40 40
41 cacheDir must be the package's cache directory. It is used as
42 the `temporary-file-directory'.
43
41 pixelDensityX and pixelDensityY are the DPI values that will be 44 pixelDensityX and pixelDensityY are the DPI values that will be
42 used by Emacs. 45 used by Emacs.
43 46
@@ -45,6 +48,7 @@ public class EmacsNative
45 public static native void setEmacsParams (AssetManager assetManager, 48 public static native void setEmacsParams (AssetManager assetManager,
46 String filesDir, 49 String filesDir,
47 String libDir, 50 String libDir,
51 String cacheDir,
48 float pixelDensityX, 52 float pixelDensityX,
49 float pixelDensityY, 53 float pixelDensityY,
50 EmacsService emacsService); 54 EmacsService emacsService);
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java
index f935b63fa0d..ca38f93dc98 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -108,7 +108,7 @@ public class EmacsService extends Service
108 { 108 {
109 AssetManager manager; 109 AssetManager manager;
110 Context app_context; 110 Context app_context;
111 String filesDir, libDir; 111 String filesDir, libDir, cacheDir;
112 double pixelDensityX; 112 double pixelDensityX;
113 double pixelDensityY; 113 double pixelDensityY;
114 114
@@ -126,12 +126,13 @@ public class EmacsService extends Service
126 parameters. */ 126 parameters. */
127 filesDir = app_context.getFilesDir ().getCanonicalPath (); 127 filesDir = app_context.getFilesDir ().getCanonicalPath ();
128 libDir = getLibraryDirectory (); 128 libDir = getLibraryDirectory ();
129 cacheDir = app_context.getCacheDir ().getCanonicalPath ();
129 130
130 Log.d (TAG, "Initializing Emacs, where filesDir = " + filesDir 131 Log.d (TAG, "Initializing Emacs, where filesDir = " + filesDir
131 + " and libDir = " + libDir); 132 + " and libDir = " + libDir);
132 133
133 EmacsNative.setEmacsParams (manager, filesDir, libDir, 134 EmacsNative.setEmacsParams (manager, filesDir, libDir,
134 (float) pixelDensityX, 135 cacheDir, (float) pixelDensityX,
135 (float) pixelDensityY, 136 (float) pixelDensityY,
136 this); 137 this);
137 138
@@ -407,4 +408,35 @@ public class EmacsService extends Service
407 { 408 {
408 return KeyEvent.keyCodeToString (keysym); 409 return KeyEvent.keyCodeToString (keysym);
409 } 410 }
411
412 public void
413 sync ()
414 {
415 Runnable runnable;
416
417 runnable = new Runnable () {
418 public void
419 run ()
420 {
421 synchronized (this)
422 {
423 notify ();
424 }
425 }
426 };
427
428 synchronized (runnable)
429 {
430 runOnUiThread (runnable);
431
432 try
433 {
434 runnable.wait ();
435 }
436 catch (InterruptedException e)
437 {
438 EmacsNative.emacsAbort ();
439 }
440 }
441 }
410}; 442};