From f0d42c5e47eaba2c8ccee0a804965a2b71923d41 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 28 Oct 2023 10:02:58 +0800 Subject: [PATCH] Minor adjustments to Android drag and drop and content URIs * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow) : New fields initialized to -1. (onDragEvent): Remember the position of the previous event to avoid sending duplicates. * src/androidvfs.c (EMACS_PATH_MAX): New define. (android_saf_tree_rename, android_saf_tree_opendir) (android_name_file, android_fstatat, android_faccessat) (android_fchmodat, android_readlinkat): Use EMACS_PATH_MAX where SAF file names might be encountered. --- java/org/gnu/emacs/EmacsWindow.java | 33 ++++++++++++++++++++-- src/androidvfs.c | 44 ++++++++++++++++++----------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 7662186a0eb..d7a37a8d57f 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java @@ -152,6 +152,10 @@ public final class EmacsWindow extends EmacsHandleObject /* The position of this window relative to the root window. */ public int xPosition, yPosition; + /* The position of the last drag and drop event received; both + values are -1 if no drag and drop operation is under way. */ + private int dndXPosition, dndYPosition; + public EmacsWindow (short handle, final EmacsWindow parent, int x, int y, int width, int height, boolean overrideRedirect) @@ -202,6 +206,9 @@ public final class EmacsWindow extends EmacsHandleObject return size () > 10; } }; + + dndXPosition = -1; + dndYPosition = -1; } public void @@ -1617,11 +1624,26 @@ public final class EmacsWindow extends EmacsHandleObject return true; case DragEvent.ACTION_DRAG_LOCATION: - /* Send this drag motion event to Emacs. */ - EmacsNative.sendDndDrag (handle, x, y); + /* Send this drag motion event to Emacs. Skip this when the + integer position hasn't changed, for Android sends events + even if the movement from the previous position of the drag + is less than 1 pixel on either axis. */ + + if (x != dndXPosition || y != dndYPosition) + { + EmacsNative.sendDndDrag (handle, x, y); + dndXPosition = x; + dndYPosition = y; + } + return true; case DragEvent.ACTION_DROP: + /* Reset this view's record of the previous drag and drop + event's position. */ + dndXPosition = -1; + dndYPosition = -1; + /* Judge whether this is plain text, or if it's a file URI for which permissions must be requested. */ @@ -1706,8 +1728,13 @@ public final class EmacsWindow extends EmacsHandleObject if (builder.length () > 0) EmacsNative.sendDndUri (handle, x, y, builder.toString ()); - return true; + + default: + /* Reset this view's record of the previous drag and drop + event's position. */ + dndXPosition = -1; + dndYPosition = -1; } return true; diff --git a/src/androidvfs.c b/src/androidvfs.c index b3d644e21a2..51558d2a375 100644 --- a/src/androidvfs.c +++ b/src/androidvfs.c @@ -403,6 +403,16 @@ android_init_fd_class (JNIEnv *env) +/* Account for SAF file names two times as large as PATH_MAX; larger + values are prohibitively slow, but smaller values can't face up to + some long file names within several nested layers of directories. + + Buffers holding components or other similar file name constitutents + which don't represent SAF files must continue to use PATH_MAX, for + that is the restriction imposed by the Unix file system. */ + +#define EMACS_PATH_MAX (PATH_MAX * 2) + /* Delete redundant instances of `.' and `..' from NAME in-place. NAME must be *LENGTH long, excluding a mandatory trailing NULL byte. @@ -4990,7 +5000,7 @@ android_saf_tree_rename (struct android_vnode *src, { char *last, *dst_last; struct android_saf_tree_vnode *vp, *vdst; - char path[PATH_MAX], path1[PATH_MAX]; + char path[EMACS_PATH_MAX], path1[EMACS_PATH_MAX]; char *fill, *dst_id; int rc; @@ -5076,8 +5086,8 @@ android_saf_tree_rename (struct android_vnode *src, /* The names of the source and destination directories will have to be copied to path. */ - if (last - vp->name >= PATH_MAX - || dst_last - vdst->name >= PATH_MAX) + if (last - vp->name >= EMACS_PATH_MAX + || dst_last - vdst->name >= EMACS_PATH_MAX) { errno = ENAMETOOLONG; return -1; @@ -5191,7 +5201,7 @@ android_saf_tree_rename (struct android_vnode *src, directory is required, as it provides the directory whose entries will be modified. */ - if (last - vp->name >= PATH_MAX) + if (last - vp->name >= EMACS_PATH_MAX) { errno = ENAMETOOLONG; return -1; @@ -5480,7 +5490,7 @@ android_saf_tree_opendir (struct android_vnode *vnode) struct android_saf_tree_vdir *dir; char *fill, *end; jobject cursor; - char component[PATH_MAX]; + char component[EMACS_PATH_MAX]; vp = (struct android_saf_tree_vnode *) vnode; @@ -5510,7 +5520,7 @@ android_saf_tree_opendir (struct android_vnode *vnode) if (!end) emacs_abort (); - if (end - fill >= PATH_MAX) + if (end - fill >= EMACS_PATH_MAX) { errno = ENAMETOOLONG; xfree (dir); @@ -6455,7 +6465,7 @@ android_root_name (struct android_vnode *vnode, char *name, least N bytes. NAME may be either an absolute file name or a name relative to the - current working directory. It must not be longer than PATH_MAX + current working directory. It must not be longer than EMACS_PATH_MAX bytes. Value is NULL upon failure with errno set accordingly, or the @@ -6464,14 +6474,14 @@ android_root_name (struct android_vnode *vnode, char *name, static struct android_vnode * android_name_file (const char *name) { - char buffer[PATH_MAX + 1], *head; + char buffer[EMACS_PATH_MAX + 1], *head; const char *end; size_t len; int nslash, c; struct android_vnode *vp; len = strlen (name); - if (len > PATH_MAX) + if (len > EMACS_PATH_MAX) { errno = ENAMETOOLONG; return NULL; @@ -7009,7 +7019,7 @@ int android_fstatat (int dirfd, const char *restrict pathname, struct stat *restrict statbuf, int flags) { - char buffer[PATH_MAX + 1]; + char buffer[EMACS_PATH_MAX + 1]; struct android_vnode *vp; int rc; @@ -7023,7 +7033,7 @@ android_fstatat (int dirfd, const char *restrict pathname, /* Now establish whether DIRFD is a file descriptor corresponding to an open VFS directory stream. */ - if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1)) + if (!android_fstatat_1 (dirfd, pathname, buffer, EMACS_PATH_MAX + 1)) { pathname = buffer; goto vfs; @@ -7049,7 +7059,7 @@ int android_faccessat (int dirfd, const char *restrict pathname, int mode, int flags) { - char buffer[PATH_MAX + 1]; + char buffer[EMACS_PATH_MAX + 1]; struct android_vnode *vp; int rc; @@ -7063,7 +7073,7 @@ android_faccessat (int dirfd, const char *restrict pathname, /* Now establish whether DIRFD is a file descriptor corresponding to an open VFS directory stream. */ - if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1)) + if (!android_fstatat_1 (dirfd, pathname, buffer, EMACS_PATH_MAX + 1)) { pathname = buffer; goto vfs; @@ -7089,7 +7099,7 @@ int android_fchmodat (int dirfd, const char *pathname, mode_t mode, int flags) { - char buffer[PATH_MAX + 1]; + char buffer[EMACS_PATH_MAX + 1]; struct android_vnode *vp; int rc; @@ -7099,7 +7109,7 @@ android_fchmodat (int dirfd, const char *pathname, mode_t mode, /* Now establish whether DIRFD is a file descriptor corresponding to an open VFS directory stream. */ - if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1)) + if (!android_fstatat_1 (dirfd, pathname, buffer, EMACS_PATH_MAX + 1)) { pathname = buffer; goto vfs; @@ -7125,7 +7135,7 @@ ssize_t android_readlinkat (int dirfd, const char *restrict pathname, char *restrict buf, size_t bufsiz) { - char buffer[PATH_MAX + 1]; + char buffer[EMACS_PATH_MAX + 1]; struct android_vnode *vp; ssize_t rc; @@ -7135,7 +7145,7 @@ android_readlinkat (int dirfd, const char *restrict pathname, /* Now establish whether DIRFD is a file descriptor corresponding to an open VFS directory stream. */ - if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1)) + if (!android_fstatat_1 (dirfd, pathname, buffer, EMACS_PATH_MAX + 1)) { pathname = buffer; goto vfs; -- 2.39.2