emacs-diffs
[Top][All Lists]
Advanced

[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;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]