1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-30 00:51:50 -08:00

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.
This commit is contained in:
Po Lu 2023-01-15 11:57:10 +08:00
parent c02a7b2ff4
commit 6e2bc91d92
12 changed files with 258 additions and 16 deletions

View file

@ -31,6 +31,8 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.util.Log;
import android.widget.PopupMenu;
/* Context menu implementation. This object is built from JNI and
@ -40,12 +42,31 @@ import android.widget.PopupMenu;
public class EmacsContextMenu
{
private class Item
private static final String TAG = "EmacsContextMenu";
/* Whether or not an item was selected. */
public static boolean itemAlreadySelected;
private class Item implements MenuItem.OnMenuItemClickListener
{
public int itemID;
public String itemName;
public EmacsContextMenu subMenu;
public boolean isEnabled;
@Override
public boolean
onMenuItemClick (MenuItem item)
{
Log.d (TAG, "onMenuItemClick: " + itemName + " (" + itemID + ")");
/* Send a context menu event. */
EmacsNative.sendContextMenu ((short) 0, itemID);
/* Say that an item has already been selected. */
itemAlreadySelected = true;
return true;
}
};
public List<Item> menuItems;
@ -137,6 +158,7 @@ public class EmacsContextMenu
else
{
menuItem = menu.add (item.itemName);
menuItem.setOnMenuItemClickListener (item);
/* If the item ID is zero, then disable the item. */
if (item.itemID == 0 || !item.isEnabled)
@ -171,6 +193,10 @@ public class EmacsContextMenu
private boolean
display1 (EmacsWindow window, int xPosition, int yPosition)
{
/* Set this flag to false. It is used to decide whether or not to
send 0 in response to the context menu being closed. */
itemAlreadySelected = false;
return window.view.popupMenu (this, xPosition, yPosition);
}
@ -199,15 +225,39 @@ public class EmacsContextMenu
}
};
try
synchronized (runnable)
{
runnable.wait ();
}
catch (InterruptedException e)
{
EmacsNative.emacsAbort ();
EmacsService.SERVICE.runOnUiThread (runnable);
try
{
runnable.wait ();
}
catch (InterruptedException e)
{
EmacsNative.emacsAbort ();
}
}
return rc.thing;
}
/* Dismiss this context menu. WINDOW is the window where the
context menu is being displayed. */
public void
dismiss (final EmacsWindow window)
{
Runnable runnable;
EmacsService.SERVICE.runOnUiThread (new Runnable () {
@Override
public void
run ()
{
window.view.cancelPopupMenu ();
itemAlreadySelected = false;
}
});
}
};