mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-01 08:17:38 +00:00
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.
This commit is contained in:
parent
a336fd98a1
commit
da9ae10636
@ -27,6 +27,7 @@
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.FrameLayout.LayoutParams;
|
||||
@ -162,7 +163,11 @@ public class EmacsActivity extends Activity
|
||||
FrameLayout.LayoutParams params;
|
||||
|
||||
/* Set the theme to one without a title bar. */
|
||||
setTheme (android.R.style.Theme_NoTitleBar);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||
setTheme (android.R.style.Theme_DeviceDefault_NoActionBar);
|
||||
else
|
||||
setTheme (android.R.style.Theme_NoTitleBar);
|
||||
|
||||
params = new FrameLayout.LayoutParams (LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.MATCH_PARENT);
|
||||
@ -235,6 +240,11 @@ public class EmacsActivity extends Activity
|
||||
{
|
||||
Log.d (TAG, "onContextMenuClosed: " + menu);
|
||||
|
||||
/* See the comment inside onMenuItemClick. */
|
||||
if (EmacsContextMenu.wasSubmenuSelected
|
||||
&& menu.toString ().contains ("ContextMenuBuilder"))
|
||||
return;
|
||||
|
||||
/* Send a context menu event given that no menu item has already
|
||||
been selected. */
|
||||
if (!EmacsContextMenu.itemAlreadySelected)
|
||||
|
@ -30,6 +30,7 @@
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.SubMenu;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
@ -47,6 +48,9 @@ public class EmacsContextMenu
|
||||
/* Whether or not an item was selected. */
|
||||
public static boolean itemAlreadySelected;
|
||||
|
||||
/* Whether or not a submenu was selected. */
|
||||
public static boolean wasSubmenuSelected;
|
||||
|
||||
private class Item implements MenuItem.OnMenuItemClickListener
|
||||
{
|
||||
public int itemID;
|
||||
@ -60,6 +64,20 @@ private class Item implements MenuItem.OnMenuItemClickListener
|
||||
{
|
||||
Log.d (TAG, "onMenuItemClick: " + itemName + " (" + itemID + ")");
|
||||
|
||||
if (subMenu != null)
|
||||
{
|
||||
/* After opening a submenu within a submenu, Android will
|
||||
send onContextMenuClosed for a ContextMenuBuilder. This
|
||||
will normally confuse Emacs into thinking that the
|
||||
context menu has been dismissed. Wrong!
|
||||
|
||||
Setting this flag makes EmacsActivity to only handle
|
||||
SubMenuBuilder being closed, which always means the menu
|
||||
has actually been dismissed. */
|
||||
wasSubmenuSelected = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Send a context menu event. */
|
||||
EmacsNative.sendContextMenu ((short) 0, itemID);
|
||||
|
||||
@ -144,7 +162,7 @@ private class Item implements MenuItem.OnMenuItemClickListener
|
||||
{
|
||||
Intent intent;
|
||||
MenuItem menuItem;
|
||||
Menu submenu;
|
||||
SubMenu submenu;
|
||||
|
||||
for (Item item : menuItems)
|
||||
{
|
||||
@ -153,7 +171,11 @@ private class Item implements MenuItem.OnMenuItemClickListener
|
||||
/* This is a submenu. Create the submenu and add the
|
||||
contents of the menu to it. */
|
||||
submenu = menu.addSubMenu (item.itemName);
|
||||
inflateMenuItems (submenu);
|
||||
item.subMenu.inflateMenuItems (submenu);
|
||||
|
||||
/* This is still needed to set wasSubmenuSelected. */
|
||||
menuItem = submenu.getItem ();
|
||||
menuItem.setOnMenuItemClickListener (item);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -184,7 +206,7 @@ private class Item implements MenuItem.OnMenuItemClickListener
|
||||
public EmacsContextMenu
|
||||
parent ()
|
||||
{
|
||||
return parent;
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
/* Like display, but does the actual work and runs in the main
|
||||
@ -197,6 +219,9 @@ private class Item implements MenuItem.OnMenuItemClickListener
|
||||
send 0 in response to the context menu being closed. */
|
||||
itemAlreadySelected = false;
|
||||
|
||||
/* No submenu has been selected yet. */
|
||||
wasSubmenuSelected = false;
|
||||
|
||||
return window.view.popupMenu (this, xPosition, yPosition);
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ public class EmacsDrawRectangle
|
||||
}
|
||||
|
||||
paint = gc.gcPaint;
|
||||
rect = new Rect (x + 1, y + 1, x + width, y + height);
|
||||
rect = new Rect (x, y, x + width, y + height);
|
||||
|
||||
paint.setStyle (Paint.Style.STROKE);
|
||||
|
||||
|
@ -38,6 +38,9 @@ public class EmacsNative
|
||||
libDir must be the package's data storage location for native
|
||||
libraries. It is used as PATH.
|
||||
|
||||
cacheDir must be the package's cache directory. It is used as
|
||||
the `temporary-file-directory'.
|
||||
|
||||
pixelDensityX and pixelDensityY are the DPI values that will be
|
||||
used by Emacs.
|
||||
|
||||
@ -45,6 +48,7 @@ public class EmacsNative
|
||||
public static native void setEmacsParams (AssetManager assetManager,
|
||||
String filesDir,
|
||||
String libDir,
|
||||
String cacheDir,
|
||||
float pixelDensityX,
|
||||
float pixelDensityY,
|
||||
EmacsService emacsService);
|
||||
|
@ -108,7 +108,7 @@ else if (apiLevel >= Build.VERSION_CODES.DONUT)
|
||||
{
|
||||
AssetManager manager;
|
||||
Context app_context;
|
||||
String filesDir, libDir;
|
||||
String filesDir, libDir, cacheDir;
|
||||
double pixelDensityX;
|
||||
double pixelDensityY;
|
||||
|
||||
@ -126,12 +126,13 @@ else if (apiLevel >= Build.VERSION_CODES.DONUT)
|
||||
parameters. */
|
||||
filesDir = app_context.getFilesDir ().getCanonicalPath ();
|
||||
libDir = getLibraryDirectory ();
|
||||
cacheDir = app_context.getCacheDir ().getCanonicalPath ();
|
||||
|
||||
Log.d (TAG, "Initializing Emacs, where filesDir = " + filesDir
|
||||
+ " and libDir = " + libDir);
|
||||
|
||||
EmacsNative.setEmacsParams (manager, filesDir, libDir,
|
||||
(float) pixelDensityX,
|
||||
cacheDir, (float) pixelDensityX,
|
||||
(float) pixelDensityY,
|
||||
this);
|
||||
|
||||
@ -407,4 +408,35 @@ else if (apiLevel >= Build.VERSION_CODES.DONUT)
|
||||
{
|
||||
return KeyEvent.keyCodeToString (keysym);
|
||||
}
|
||||
|
||||
public void
|
||||
sync ()
|
||||
{
|
||||
Runnable runnable;
|
||||
|
||||
runnable = new Runnable () {
|
||||
public void
|
||||
run ()
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
notify ();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
synchronized (runnable)
|
||||
{
|
||||
runOnUiThread (runnable);
|
||||
|
||||
try
|
||||
{
|
||||
runnable.wait ();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
EmacsNative.emacsAbort ();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -88,6 +88,7 @@ struct android_emacs_service
|
||||
jmethodID get_screen_height;
|
||||
jmethodID detect_mouse;
|
||||
jmethodID name_keysym;
|
||||
jmethodID sync;
|
||||
};
|
||||
|
||||
struct android_emacs_pixmap
|
||||
@ -116,15 +117,18 @@ static AAssetManager *asset_manager;
|
||||
/* Whether or not Emacs has been initialized. */
|
||||
static int emacs_initialized;
|
||||
|
||||
/* The path used to store site-lisp. */
|
||||
/* The directory used to store site-lisp. */
|
||||
char *android_site_load_path;
|
||||
|
||||
/* The path used to store native libraries. */
|
||||
/* The directory used to store native libraries. */
|
||||
char *android_lib_dir;
|
||||
|
||||
/* The path used to store game files. */
|
||||
/* The directory used to store game files. */
|
||||
char *android_game_path;
|
||||
|
||||
/* The directory used to store temporary files. */
|
||||
char *android_cache_dir;
|
||||
|
||||
/* The display's pixel densities. */
|
||||
double android_pixel_density_x, android_pixel_density_y;
|
||||
|
||||
@ -911,6 +915,7 @@ JNIEXPORT void JNICALL
|
||||
NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
|
||||
jobject local_asset_manager,
|
||||
jobject files_dir, jobject libs_dir,
|
||||
jobject cache_dir,
|
||||
jfloat pixel_density_x,
|
||||
jfloat pixel_density_y,
|
||||
jobject emacs_service_object)
|
||||
@ -986,6 +991,20 @@ NATIVE_NAME (setEmacsParams) (JNIEnv *env, jobject object,
|
||||
(*env)->ReleaseStringUTFChars (env, (jstring) libs_dir,
|
||||
java_string);
|
||||
|
||||
java_string = (*env)->GetStringUTFChars (env, (jstring) cache_dir,
|
||||
NULL);
|
||||
|
||||
if (!java_string)
|
||||
emacs_abort ();
|
||||
|
||||
android_cache_dir = strdup ((const char *) java_string);
|
||||
|
||||
if (!android_files_dir)
|
||||
emacs_abort ();
|
||||
|
||||
(*env)->ReleaseStringUTFChars (env, (jstring) cache_dir,
|
||||
java_string);
|
||||
|
||||
/* Calculate the site-lisp path. */
|
||||
|
||||
android_site_load_path = malloc (PATH_MAX + 1);
|
||||
@ -1083,6 +1102,7 @@ android_init_emacs_service (void)
|
||||
FIND_METHOD (get_screen_height, "getScreenHeight", "(Z)I");
|
||||
FIND_METHOD (detect_mouse, "detectMouse", "()Z");
|
||||
FIND_METHOD (name_keysym, "nameKeysym", "(I)Ljava/lang/String;");
|
||||
FIND_METHOD (sync, "sync", "()V");
|
||||
#undef FIND_METHOD
|
||||
}
|
||||
|
||||
@ -1216,6 +1236,9 @@ NATIVE_NAME (initEmacs) (JNIEnv *env, jobject object, jarray argv)
|
||||
/* Set HOME to the app data directory. */
|
||||
setenv ("HOME", android_files_dir, 1);
|
||||
|
||||
/* Set TMPDIR to the temporary files directory. */
|
||||
setenv ("TMPDIR", android_cache_dir, 1);
|
||||
|
||||
/* Set the cwd to that directory as well. */
|
||||
if (chdir (android_files_dir))
|
||||
__android_log_print (ANDROID_LOG_WARN, __func__,
|
||||
@ -3519,6 +3542,15 @@ android_get_keysym_name (int keysym, char *name_return, size_t size)
|
||||
ANDROID_DELETE_LOCAL_REF (string);
|
||||
}
|
||||
|
||||
void
|
||||
android_sync (void)
|
||||
{
|
||||
(*android_java_env)->CallVoidMethod (android_java_env,
|
||||
emacs_service,
|
||||
service_class.sync);
|
||||
android_exception_check ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#undef faccessat
|
||||
|
@ -26,6 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
#include "blockinput.h"
|
||||
#include "keyboard.h"
|
||||
#include "buffer.h"
|
||||
#include "androidgui.h"
|
||||
|
||||
#ifndef ANDROID_STUBIFY
|
||||
|
||||
@ -2282,6 +2283,13 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
|
||||
android_map_raised (FRAME_ANDROID_WINDOW (tip_f));
|
||||
unblock_input ();
|
||||
|
||||
/* Synchronize with the UI thread. This is required to prevent ugly
|
||||
black splotches. */
|
||||
android_sync ();
|
||||
|
||||
/* Garbage the tip frame too. */
|
||||
SET_FRAME_GARBAGED (tip_f);
|
||||
|
||||
w->must_be_updated_p = true;
|
||||
update_single_window (w);
|
||||
flush_frame (tip_f);
|
||||
|
@ -504,6 +504,7 @@ extern void android_move_resize_window (android_window, int, int,
|
||||
extern void android_map_raised (android_window);
|
||||
extern void android_translate_coordinates (android_window, int,
|
||||
int, int *, int *);
|
||||
extern void android_sync (void);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -28,6 +28,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef ANDROID_STUBIFY
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
/* Flag indicating whether or not a popup menu has been posted and not
|
||||
yet popped down. */
|
||||
|
||||
@ -188,6 +190,35 @@ android_process_events_for_menu (int *id)
|
||||
*id = x_display_list->menu_event_id;
|
||||
}
|
||||
|
||||
/* Structure describing a ``subprefix'' in the menu. */
|
||||
|
||||
struct android_menu_subprefix
|
||||
{
|
||||
/* The subprefix above. */
|
||||
struct android_menu_subprefix *last;
|
||||
|
||||
/* The subprefix itself. */
|
||||
Lisp_Object subprefix;
|
||||
};
|
||||
|
||||
/* Free the subprefixes starting from *DATA. */
|
||||
|
||||
static void
|
||||
android_free_subprefixes (void *data)
|
||||
{
|
||||
struct android_menu_subprefix **head, *subprefix;
|
||||
|
||||
head = data;
|
||||
|
||||
while (*head)
|
||||
{
|
||||
subprefix = *head;
|
||||
*head = subprefix->last;
|
||||
|
||||
xfree (subprefix);
|
||||
}
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
android_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||
Lisp_Object title, const char **error_name)
|
||||
@ -198,13 +229,15 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||
Lisp_Object pane_name, prefix;
|
||||
const char *pane_string;
|
||||
specpdl_ref count, count1;
|
||||
Lisp_Object item_name, enable, def, tem;
|
||||
Lisp_Object item_name, enable, def, tem, entry;
|
||||
jmethodID method;
|
||||
jobject store;
|
||||
bool rc;
|
||||
jobject window;
|
||||
int id, item_id;
|
||||
int id, item_id, submenu_depth;
|
||||
struct android_dismiss_menu_data data;
|
||||
struct android_menu_subprefix *subprefix, *temp_subprefix;
|
||||
struct android_menu_subprefix *subprefix_1;
|
||||
|
||||
count = SPECPDL_INDEX ();
|
||||
|
||||
@ -232,7 +265,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||
android_push_local_frame ();
|
||||
|
||||
/* Iterate over the menu. */
|
||||
i = 0;
|
||||
i = 0, submenu_depth = 0;
|
||||
|
||||
while (i < menu_items_used)
|
||||
{
|
||||
@ -241,6 +274,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||
/* This is the start of a new submenu. However, it can be
|
||||
ignored here. */
|
||||
i += 1;
|
||||
submenu_depth += 1;
|
||||
}
|
||||
else if (EQ (AREF (menu_items, i), Qlambda))
|
||||
{
|
||||
@ -256,9 +290,18 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||
if (store != context_menu)
|
||||
ANDROID_DELETE_LOCAL_REF (store);
|
||||
i += 1;
|
||||
submenu_depth -= 1;
|
||||
|
||||
eassert (current_context_menu);
|
||||
if (!current_context_menu || submenu_depth < 0)
|
||||
{
|
||||
__android_log_print (ANDROID_LOG_FATAL, __func__,
|
||||
"unbalanced submenu pop in menu_items");
|
||||
emacs_abort ();
|
||||
}
|
||||
}
|
||||
else if (EQ (AREF (menu_items, i), Qt)
|
||||
&& submenu_depth != 0)
|
||||
i += MENU_ITEMS_PANE_LENGTH;
|
||||
else if (EQ (AREF (menu_items, i), Qquote))
|
||||
i += 1;
|
||||
else if (EQ (AREF (menu_items, i), Qt))
|
||||
@ -300,8 +343,8 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||
/* This is an actual menu item (or submenu). Add it to the
|
||||
menu. */
|
||||
|
||||
if (i + MENU_ITEMS_ITEM_LENGTH < menu_items_used &&
|
||||
NILP (AREF (menu_items, i + MENU_ITEMS_ITEM_LENGTH)))
|
||||
if (i + MENU_ITEMS_ITEM_LENGTH < menu_items_used
|
||||
&& NILP (AREF (menu_items, i + MENU_ITEMS_ITEM_LENGTH)))
|
||||
{
|
||||
/* This is a submenu. Add it. */
|
||||
title_string = (!NILP (item_name)
|
||||
@ -312,7 +355,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||
= (*android_java_env)->CallObjectMethod (android_java_env,
|
||||
current_context_menu,
|
||||
menu_class.add_submenu,
|
||||
title_string);
|
||||
title_string, NULL);
|
||||
android_exception_check ();
|
||||
|
||||
if (store != context_menu)
|
||||
@ -385,13 +428,78 @@ android_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||
/* This means no menu item was selected. */
|
||||
goto finish;
|
||||
|
||||
/* id is an index into menu_items. Check that it remains
|
||||
valid. */
|
||||
/* This means the id is invalid. */
|
||||
if (id >= ASIZE (menu_items))
|
||||
goto finish;
|
||||
|
||||
/* Now return the menu item at that location. */
|
||||
tem = AREF (menu_items, id);
|
||||
tem = Qnil;
|
||||
subprefix = NULL;
|
||||
record_unwind_protect_ptr (android_free_subprefixes, &subprefix);
|
||||
|
||||
/* Find the selected item, and its pane, to return
|
||||
the proper value. */
|
||||
|
||||
prefix = entry = Qnil;
|
||||
i = 0;
|
||||
while (i < menu_items_used)
|
||||
{
|
||||
if (NILP (AREF (menu_items, i)))
|
||||
{
|
||||
temp_subprefix = xmalloc (sizeof *temp_subprefix);
|
||||
temp_subprefix->last = subprefix;
|
||||
subprefix = temp_subprefix;
|
||||
subprefix->subprefix = prefix;
|
||||
|
||||
prefix = entry;
|
||||
i++;
|
||||
}
|
||||
else if (EQ (AREF (menu_items, i), Qlambda))
|
||||
{
|
||||
prefix = subprefix->subprefix;
|
||||
temp_subprefix = subprefix->last;
|
||||
xfree (subprefix);
|
||||
subprefix = temp_subprefix;
|
||||
|
||||
i++;
|
||||
}
|
||||
else if (EQ (AREF (menu_items, i), Qt))
|
||||
{
|
||||
prefix
|
||||
= AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
|
||||
i += MENU_ITEMS_PANE_LENGTH;
|
||||
}
|
||||
/* Ignore a nil in the item list.
|
||||
It's meaningful only for dialog boxes. */
|
||||
else if (EQ (AREF (menu_items, i), Qquote))
|
||||
i += 1;
|
||||
else
|
||||
{
|
||||
entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
|
||||
|
||||
if (i + MENU_ITEMS_ITEM_VALUE == id)
|
||||
{
|
||||
if (menuflags & MENU_KEYMAPS)
|
||||
{
|
||||
entry = list1 (entry);
|
||||
|
||||
if (!NILP (prefix))
|
||||
entry = Fcons (prefix, entry);
|
||||
|
||||
for (subprefix_1 = subprefix; subprefix_1;
|
||||
subprefix_1 = subprefix_1->last)
|
||||
if (!NILP (subprefix_1->subprefix))
|
||||
entry = Fcons (subprefix_1->subprefix, entry);
|
||||
}
|
||||
|
||||
tem = entry;
|
||||
}
|
||||
i += MENU_ITEMS_ITEM_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
Fprint (tem, Qexternal_debugging_output);
|
||||
|
||||
unblock_input ();
|
||||
return unbind_to (count, tem);
|
||||
|
||||
|
@ -689,6 +689,16 @@ handle_one_android_event (struct android_display_info *dpyinfo,
|
||||
goto OTHER;
|
||||
|
||||
case ANDROID_MOTION_NOTIFY:
|
||||
|
||||
previous_help_echo_string = help_echo_string;
|
||||
help_echo_string = Qnil;
|
||||
|
||||
if (hlinfo->mouse_face_hidden)
|
||||
{
|
||||
hlinfo->mouse_face_hidden = false;
|
||||
clear_mouse_face (hlinfo);
|
||||
}
|
||||
|
||||
f = any;
|
||||
|
||||
if (f)
|
||||
|
@ -167,7 +167,7 @@ ensure_menu_items (int items)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_EXT_MENU_BAR
|
||||
#if defined HAVE_EXT_MENU_BAR || defined HAVE_ANDROID
|
||||
|
||||
/* Begin a submenu. */
|
||||
|
||||
@ -191,7 +191,7 @@ push_submenu_end (void)
|
||||
menu_items_submenu_depth--;
|
||||
}
|
||||
|
||||
#endif /* HAVE_EXT_MENU_BAR */
|
||||
#endif /* HAVE_EXT_MENU_BAR || HAVE_ANDROID */
|
||||
|
||||
/* Indicate boundary between left and right. */
|
||||
|
||||
@ -420,8 +420,9 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
|
||||
AREF (item_properties, ITEM_PROPERTY_SELECTED),
|
||||
AREF (item_properties, ITEM_PROPERTY_HELP));
|
||||
|
||||
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) \
|
||||
|| defined (HAVE_NTGUI) || defined (HAVE_HAIKU) || defined (HAVE_PGTK)
|
||||
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) \
|
||||
|| defined (HAVE_NTGUI) || defined (HAVE_HAIKU) || defined (HAVE_PGTK) \
|
||||
|| defined (HAVE_ANDROID)
|
||||
/* Display a submenu using the toolkit. */
|
||||
if (FRAME_WINDOW_P (XFRAME (Vmenu_updating_frame))
|
||||
&& ! (NILP (map) || NILP (enabled)))
|
||||
|
Loading…
Reference in New Issue
Block a user