diff options
| author | Po Lu <luangruo@yahoo.com> | 2023-01-14 22:12:16 +0800 |
|---|---|---|
| committer | Po Lu <luangruo@yahoo.com> | 2023-01-14 22:12:16 +0800 |
| commit | 2b87ab7b27163fbd7b6b64c5a44e26b0e692c00a (patch) | |
| tree | 3ab31df90bd435009d2d42b636ce3baf33bd2b28 /java/org/gnu/emacs/EmacsContextMenu.java | |
| parent | 28a9baccd4c8e997895d3adb3cfce4a11fa29896 (diff) | |
Update Android port
* java/Makefile.in (clean): Fix distclean and bootstrap-clean rules.
* java/debug.sh (jdb_port):
(attach_existing):
(num_pids):
(line): Add new options to upload a gdbserver binary to the device.
* java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): Make
focusedActivities public.
* java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
New class.
* java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Fix
bounds computation.
* java/org/gnu/emacs/EmacsGC.java (markDirty): Set stroke width
explicitly.
* java/org/gnu/emacs/EmacsService.java (EmacsService)
(getLocationOnScreen, nameKeysym): New functions.
* java/org/gnu/emacs/EmacsView.java (EmacsView): Disable focus
highlight.
(onCreateContextMenu, popupMenu, cancelPopupMenu): New
functions.
* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): Implement a
kind of ``override redirect'' window for tooltips.
* src/android.c (struct android_emacs_service): New method
`name_keysym'.
(android_run_select_thread, android_init_events):
(android_select): Release select thread on semaphores instead of
signals to avoid one nasty race on SIGUSR2 delivery.
(android_init_emacs_service): Initialize new method.
(android_create_window): Handle CW_OVERRIDE_REDIRECT.
(android_move_resize_window, android_map_raised)
(android_translate_coordinates, android_get_keysym_name)
(android_build_string, android_exception_check): New functions.
* src/android.h: Update prototypes.
* src/androidfns.c (android_set_parent_frame, Fx_create_frame)
(unwind_create_tip_frame, android_create_tip_frame)
(android_hide_tip, compute_tip_xy, Fx_show_tip, Fx_hide_tip)
(syms_of_androidfns): Implement tooltips and iconification
reporting.
* src/androidgui.h (enum android_window_value_mask): Add
CWOverrideRedirect.
(struct android_set_window_attributes): Add `override_redirect'.
(ANDROID_IS_MODIFIER_KEY): Recognize Caps Lock.
* src/androidmenu.c (struct android_emacs_context_menu): New
struct.
(android_init_emacs_context_menu, android_unwind_local_frame)
(android_push_local_frame, android_menu_show, init_androidmenu):
New functions.
* src/androidterm.c (handle_one_android_event): Fix NULL pointer
dereference.
(android_fullscreen_hook): Handle fullscreen correctly.
(android_draw_box_rect): Fix top line.
(get_keysym_name): Implement function.
(android_create_terminal): Remove scroll bar stubs and add menu
hook.
* src/androidterm.h: Update prototypes.
* src/emacs.c (android_emacs_init): Initialize androidmenu.c.
* xcompile/Makefile.in: Fix clean rules.
Diffstat (limited to 'java/org/gnu/emacs/EmacsContextMenu.java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsContextMenu.java | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java new file mode 100644 index 00000000000..8d7ae08b257 --- /dev/null +++ b/java/org/gnu/emacs/EmacsContextMenu.java @@ -0,0 +1,213 @@ +/* Communication module for Android terminals. -*- c-file-style: "GNU" -*- + +Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ + +package org.gnu.emacs; + +import java.util.List; +import java.util.ArrayList; + +import android.content.Context; +import android.content.Intent; + +import android.os.Bundle; + +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; + +import android.widget.PopupMenu; + +/* Context menu implementation. This object is built from JNI and + describes a menu hiearchy. Then, `inflate' can turn it into an + Android menu, which can be turned into a popup (or other kind of) + menu. */ + +public class EmacsContextMenu +{ + private class Item + { + public int itemID; + public String itemName; + public EmacsContextMenu subMenu; + public boolean isEnabled; + }; + + public List<Item> menuItems; + public String title; + private EmacsContextMenu parent; + + /* Create a context menu with no items inside and the title TITLE, + which may be NULL. */ + + public static EmacsContextMenu + createContextMenu (String title) + { + EmacsContextMenu menu; + + menu = new EmacsContextMenu (); + menu.menuItems = new ArrayList<Item> (); + menu.title = title; + + return menu; + } + + /* Add a normal menu item to the context menu with the id ITEMID and + the name ITEMNAME. Enable it if ISENABLED, else keep it + disabled. */ + + public void + addItem (int itemID, String itemName, boolean isEnabled) + { + Item item; + + item = new Item (); + item.itemID = itemID; + item.itemName = itemName; + item.isEnabled = isEnabled; + + menuItems.add (item); + } + + /* Create a disabled menu item with the name ITEMNAME. */ + + public void + addPane (String itemName) + { + Item item; + + item = new Item (); + item.itemName = itemName; + + menuItems.add (item); + } + + /* Add a submenu to the context menu with the specified title and + item name. */ + + public EmacsContextMenu + addSubmenu (String itemName, String title) + { + EmacsContextMenu submenu; + Item item; + + item = new Item (); + item.itemID = 0; + item.itemName = itemName; + item.subMenu = createContextMenu (title); + item.subMenu.parent = this; + + menuItems.add (item); + return item.subMenu; + } + + /* Add the contents of this menu to MENU. */ + + private void + inflateMenuItems (Menu menu) + { + Intent intent; + MenuItem menuItem; + Menu submenu; + + for (Item item : menuItems) + { + if (item.subMenu != null) + { + /* This is a submenu. Create the submenu and add the + contents of the menu to it. */ + submenu = menu.addSubMenu (item.itemName); + inflateMenuItems (submenu); + } + else + { + menuItem = menu.add (item.itemName); + + /* If the item ID is zero, then disable the item. */ + if (item.itemID == 0 || !item.isEnabled) + menuItem.setEnabled (false); + } + } + } + + /* Enter the items in this context menu to MENU. Create each menu + item with an Intent containing a Bundle, where the key + "emacs:menu_item_hi" maps to the high 16 bits of the + corresponding item ID, and the key "emacs:menu_item_low" maps to + the low 16 bits of the item ID. */ + + public void + expandTo (Menu menu) + { + inflateMenuItems (menu); + } + + /* Return the parent or NULL. */ + + public EmacsContextMenu + parent () + { + return parent; + } + + /* Like display, but does the actual work and runs in the main + thread. */ + + private boolean + display1 (EmacsWindow window, int xPosition, int yPosition) + { + return window.view.popupMenu (this, xPosition, yPosition); + } + + /* Display this context menu on WINDOW, at xPosition and + yPosition. */ + + public boolean + display (final EmacsWindow window, final int xPosition, + final int yPosition) + { + Runnable runnable; + final Holder<Boolean> rc; + + rc = new Holder<Boolean> (); + + runnable = new Runnable () { + @Override + public void + run () + { + synchronized (this) + { + rc.thing = display1 (window, xPosition, yPosition); + notify (); + } + } + }; + + try + { + runnable.wait (); + } + catch (InterruptedException e) + { + EmacsNative.emacsAbort (); + } + + return rc.thing; + } +}; |
