[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 9443f8145e1: Communicate frame titles to the window manager on An
From: |
Po Lu |
Subject: |
master 9443f8145e1: Communicate frame titles to the window manager on Android |
Date: |
Mon, 13 May 2024 02:42:54 -0400 (EDT) |
branch: master
commit 9443f8145e1db86664a4af318b3bd1448094040e
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Communicate frame titles to the window manager on Android
* java/org/gnu/emacs/EmacsActivity.java (detachWindow)
(attachWindow): Call updateWmName.
(updateWmName): New function; transfer wm name from the window
attached to the task's description.
* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow)
<wmName>: New field.
(setWmName): New function.
* src/android.c (android_init_emacs_window): Link to new
function.
(android_set_wm_name): New function.
* src/android.h (struct android_emacs_service): Delete unused
entries.
* src/androidfns.c (android_set_name_internal, android_set_name)
(android_implicitly_set_name, android_explicitly_set_name)
(android_set_title): Port from X.
* src/androidterm.c (android_term_init): Compute default frame
title.
* src/androidterm.h (struct android_display_info) <x_id_name>:
New field.
---
java/org/gnu/emacs/EmacsActivity.java | 33 +++++++++++++++
java/org/gnu/emacs/EmacsWindow.java | 37 ++++++++++++++++-
src/android.c | 23 +++++++++++
src/android.h | 3 +-
src/androidfns.c | 78 ++++++++++++++++++++++++++++++++++-
src/androidterm.c | 20 +++++++++
src/androidterm.h | 3 ++
7 files changed, 192 insertions(+), 5 deletions(-)
diff --git a/java/org/gnu/emacs/EmacsActivity.java
b/java/org/gnu/emacs/EmacsActivity.java
index 118c3375ad5..7d02e4f4834 100644
--- a/java/org/gnu/emacs/EmacsActivity.java
+++ b/java/org/gnu/emacs/EmacsActivity.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
+import android.app.ActivityManager.TaskDescription;
import android.content.ContentResolver;
import android.content.Context;
@@ -166,6 +167,10 @@ public class EmacsActivity extends Activity
layout.removeView (window.view);
window = null;
+ /* Reset the WM name. */
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+ updateWmName ();
+
invalidateFocus (0);
}
}
@@ -205,6 +210,11 @@ public class EmacsActivity extends Activity
invalidateFocus (1);
}
});
+
+ /* Synchronize the window's window manager name with this activity's
+ task in the recents list. */
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+ updateWmName ();
}
@Override
@@ -522,6 +532,29 @@ public class EmacsActivity extends Activity
}
}
+ /* Update the name of this activity's task description from the
+ current window, or reset the same if no window is attached. */
+
+ @SuppressWarnings ("deprecation")
+ public final void
+ updateWmName ()
+ {
+ String wmName;
+ TaskDescription description;
+
+ if (window == null || window.wmName == null)
+ wmName = "Emacs";
+ else
+ wmName = window.wmName;
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
+ description = new TaskDescription (wmName);
+ else
+ description = (new TaskDescription.Builder ()
+ .setLabel (wmName).build ());
+ setTaskDescription (description);
+ }
+
@Override
public final void
onAttachedToWindow ()
diff --git a/java/org/gnu/emacs/EmacsWindow.java
b/java/org/gnu/emacs/EmacsWindow.java
index f8dd8518af0..483ba0dbced 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -169,6 +169,11 @@ public final class EmacsWindow extends EmacsHandleObject
and whether this window has previously been attached to a task. */
public boolean preserve, previouslyAttached;
+ /* The window manager name of this window, which supplies the name of
+ activities in which it is displayed as a toplevel window, or
+ NULL. */
+ public String wmName;
+
public
EmacsWindow (final EmacsWindow parent, int x, int y,
int width, int height, boolean overrideRedirect)
@@ -1562,6 +1567,36 @@ public final class EmacsWindow extends EmacsHandleObject
return dontFocusOnMap;
}
+ public void
+ setWmName (final String wmName)
+ {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
+ return;
+
+ EmacsService.SERVICE.runOnUiThread (new Runnable () {
+ @Override
+ public void
+ run ()
+ {
+ EmacsActivity activity;
+ Object tem;
+
+ EmacsWindow.this.wmName = wmName;
+
+ /* If an activity is already attached, replace its task
+ description. */
+
+ tem = getAttachedConsumer ();
+
+ if (tem != null && tem instanceof EmacsActivity)
+ {
+ activity = (EmacsActivity) tem;
+ activity.updateWmName ();
+ }
+ }
+ });
+ }
+
public int[]
translateCoordinates (int x, int y)
{
@@ -1631,7 +1666,7 @@ public final class EmacsWindow extends EmacsHandleObject
fullscreen = isFullscreen;
tem = getAttachedConsumer ();
- if (tem != null)
+ if (tem != null && tem instanceof EmacsActivity)
{
activity = (EmacsActivity) tem;
activity.syncFullscreenWith (EmacsWindow.this);
diff --git a/src/android.c b/src/android.c
index 72ef9e689ef..17b5d6d4115 100644
--- a/src/android.c
+++ b/src/android.c
@@ -115,6 +115,7 @@ struct android_emacs_window
jmethodID recreate_activity;
jmethodID clear_window;
jmethodID clear_area;
+ jmethodID set_wm_name;
};
struct android_emacs_cursor
@@ -1842,6 +1843,7 @@ android_init_emacs_window (void)
FIND_METHOD (recreate_activity, "recreateActivity", "()V");
FIND_METHOD (clear_window, "clearWindow", "()V");
FIND_METHOD (clear_area, "clearArea", "(IIII)V");
+ FIND_METHOD (set_wm_name, "setWmName", "(Ljava/lang/String;)V");
#undef FIND_METHOD
}
@@ -5603,6 +5605,27 @@ android_set_dont_accept_focus (android_window handle,
android_exception_check ();
}
+/* Set the WM name of HANDLE to STRING, a Java string. This name
+ provides the task description of activities that receive HANDLE. */
+
+void
+android_set_wm_name (android_window handle, jstring name)
+{
+ jmethodID method;
+ jobject window;
+
+ window = android_resolve_handle (handle);
+ method = window_class.set_wm_name;
+
+ if (android_get_current_api_level () < 21)
+ return;
+
+ (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, window,
+ window_class.class, method,
+ name);
+ android_exception_check ();
+}
+
void
android_get_keysym_name (int keysym, char *name_return, size_t size)
{
diff --git a/src/android.h b/src/android.h
index a582a9b7dff..78482d64de4 100644
--- a/src/android.h
+++ b/src/android.h
@@ -118,6 +118,7 @@ extern bool android_detect_keyboard (void);
extern void android_set_dont_focus_on_map (android_window, bool);
extern void android_set_dont_accept_focus (android_window, bool);
+extern void android_set_wm_name (android_window, jstring);
extern int android_verify_jni_string (const char *);
extern jstring android_build_string (Lisp_Object, ...);
@@ -275,8 +276,6 @@ struct android_emacs_service
jmethodID draw_rectangle;
jmethodID draw_line;
jmethodID draw_point;
- jmethodID clear_window;
- jmethodID clear_area;
jmethodID ring_bell;
jmethodID query_tree;
jmethodID get_screen_width;
diff --git a/src/androidfns.c b/src/androidfns.c
index df425e5779e..1c2690394a6 100644
--- a/src/androidfns.c
+++ b/src/androidfns.c
@@ -211,18 +211,90 @@ android_set_parent_frame (struct frame *f, Lisp_Object
new_value,
FRAME_TERMINAL (f)->fullscreen_hook (f);
}
+/* Set the WM name to NAME for frame F. Also set the icon name.
+ If the frame already has an icon name, use that, otherwise set the
+ icon name to NAME. */
+
+static void
+android_set_name_internal (struct frame *f, Lisp_Object name)
+{
+ jstring java_name;
+
+ if (FRAME_ANDROID_WINDOW (f))
+ {
+ java_name = android_build_string (name, NULL);
+ android_set_wm_name (FRAME_ANDROID_WINDOW (f), java_name);
+ ANDROID_DELETE_LOCAL_REF (java_name);
+ }
+}
+
+/* Change the name of frame F to NAME. If NAME is nil, set F's name to
+ x_id_name.
+
+ If EXPLICIT is true, that indicates that lisp code is setting the
+ name; if NAME is a string, set F's name to NAME and set
+ F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
+
+ If EXPLICIT is false, that indicates that Emacs redisplay code is
+ suggesting a new name, which lisp code should override; if
+ F->explicit_name is set, ignore the new name; otherwise, set it. */
+
+static void
+android_set_name (struct frame *f, Lisp_Object name, bool explicit)
+{
+ /* Make sure that requests from lisp code override requests from
+ Emacs redisplay code. */
+ if (explicit)
+ {
+ /* If we're switching from explicit to implicit, we had better
+ update the mode lines and thereby update the title. */
+ if (f->explicit_name && NILP (name))
+ update_mode_lines = 37;
+
+ f->explicit_name = ! NILP (name);
+ }
+ else if (f->explicit_name)
+ return;
+
+ /* If NAME is nil, set the name to the x_id_name. */
+ if (NILP (name))
+ {
+ /* Check for no change needed in this very common case
+ before we do any consing. */
+ if (!strcmp (FRAME_DISPLAY_INFO (f)->x_id_name,
+ SSDATA (f->name)))
+ return;
+ name = build_string (FRAME_DISPLAY_INFO (f)->x_id_name);
+ }
+ else
+ CHECK_STRING (name);
+
+ /* Don't change the name if it's already NAME. */
+ if (! NILP (Fstring_equal (name, f->name)))
+ return;
+
+ fset_name (f, name);
+
+ /* For setting the frame title, the title parameter should override
+ the name parameter. */
+ if (! NILP (f->title))
+ name = f->title;
+
+ android_set_name_internal (f, name);
+}
+
void
android_implicitly_set_name (struct frame *f, Lisp_Object arg,
Lisp_Object oldval)
{
-
+ android_set_name (f, arg, false);
}
void
android_explicitly_set_name (struct frame *f, Lisp_Object arg,
Lisp_Object oldval)
{
-
+ android_set_name (f, arg, true);
}
/* Set the number of lines used for the tool bar of frame F to VALUE.
@@ -2988,6 +3060,8 @@ android_set_title (struct frame *f, Lisp_Object name,
name = f->name;
else
CHECK_STRING (name);
+
+ android_set_name_internal (f, name);
}
static void
diff --git a/src/androidterm.c b/src/androidterm.c
index 67c20ec5245..94a115a66a6 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -6649,6 +6649,26 @@ android_term_init (void)
terminal->name = xstrdup ("android");
+ {
+ Lisp_Object system_name = Fsystem_name ();
+ static char const title[] = "GNU Emacs";
+ if (STRINGP (system_name))
+ {
+ static char const at[] = " at ";
+ ptrdiff_t nbytes = sizeof (title) + sizeof (at);
+ if (ckd_add (&nbytes, nbytes, SBYTES (system_name)))
+ memory_full (SIZE_MAX);
+ dpyinfo->x_id_name = xmalloc (nbytes);
+ sprintf (dpyinfo->x_id_name, "%s%s%s", title, at,
+ SDATA (system_name));
+ }
+ else
+ {
+ dpyinfo->x_id_name = xmalloc (sizeof (title));
+ strcpy (dpyinfo->x_id_name, title);
+ }
+ }
+
/* The display "connection" is now set up, and it must never go
away. */
terminal->reference_count = 30000;
diff --git a/src/androidterm.h b/src/androidterm.h
index f4459c45dc9..c8f1ab655a9 100644
--- a/src/androidterm.h
+++ b/src/androidterm.h
@@ -90,6 +90,9 @@ struct android_display_info
/* Minimum font height over all fonts in font_table. */
int smallest_font_height;
+ /* Default name for all frames on this display. */
+ char *x_id_name;
+
/* The number of fonts opened for this display. */
int n_fonts;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 9443f8145e1: Communicate frame titles to the window manager on Android,
Po Lu <=