]> git.eshelyaron.com Git - emacs.git/commitdiff
Correctly display popup dialogs from Emacsclient
authorPo Lu <luangruo@yahoo.com>
Thu, 8 Jun 2023 12:50:02 +0000 (20:50 +0800)
committerPo Lu <luangruo@yahoo.com>
Thu, 8 Jun 2023 12:50:02 +0000 (20:50 +0800)
* java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu):
Make subclasses final.
* java/org/gnu/emacs/EmacsDialog.java (display1): Check if an
instance of EmacsOpenActivity is open; if it is, try using it to
display the pop up dialog.
* java/org/gnu/emacs/EmacsDialogButtonLayout.java
(EmacsDialogButtonLayout): Make final.
* java/org/gnu/emacs/EmacsHolder.java (EmacsHolder<T>):
Likewise.
* java/org/gnu/emacs/EmacsOpenActivity.java (EmacsOpenActivity):
New field `currentActivity'.
(onCreate, onDestroy, onWindowFocusChanged, onPause): Set that
field as appropriate.

java/org/gnu/emacs/EmacsContextMenu.java
java/org/gnu/emacs/EmacsDialog.java
java/org/gnu/emacs/EmacsDialogButtonLayout.java
java/org/gnu/emacs/EmacsHolder.java
java/org/gnu/emacs/EmacsOpenActivity.java

index 60f2db67fb018607817c4d826128d5b2dae8c6ca..d69d0263b93eacec4886ff37651e7f4e60d2b029 100644 (file)
@@ -58,7 +58,7 @@ public final class EmacsContextMenu
   /* The last group ID used for a menu item.  */
   public int lastGroupId;
 
-  private static class Item implements MenuItem.OnMenuItemClickListener
+  private static final class Item implements MenuItem.OnMenuItemClickListener
   {
     public int itemID;
     public String itemName, tooltip;
index afdce3c50ecd2e6362933d6f8cec0c69ac5d1b81..3f8fe0109c088d4c54a8b7515aa112d379fc9a37 100644 (file)
@@ -68,8 +68,8 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
   /* The menu serial associated with this dialog box.  */
   private int menuEventSerial;
 
-  private class EmacsButton implements View.OnClickListener,
-                           DialogInterface.OnClickListener
+  private final class EmacsButton implements View.OnClickListener,
+                                 DialogInterface.OnClickListener
   {
     /* Name of this button.  */
     public String name;
@@ -244,13 +244,22 @@ public final class EmacsDialog implements DialogInterface.OnDismissListener
     if (EmacsActivity.focusedActivities.isEmpty ())
       {
        /* If focusedActivities is empty then this dialog may have
-          been displayed immediately after a popup dialog is
+          been displayed immediately after another popup dialog was
           dismissed.  Or Emacs might legitimately be in the
-          background.  Try the service context first if possible.  */
+          background, possibly displaying this popup in response to
+          an Emacsclient request.  Try the service context if it will
+          work, then any focused EmacsOpenActivity, and finally the
+          last EmacsActivity to be focused.  */
+
+       Log.d (TAG, "display1: no focused activities...");
+       Log.d (TAG, ("display1: EmacsOpenActivity.currentActivity: "
+                    + EmacsOpenActivity.currentActivity));
 
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
            || Settings.canDrawOverlays (EmacsService.SERVICE))
          context = EmacsService.SERVICE;
+       else if (EmacsOpenActivity.currentActivity != null)
+         context = EmacsOpenActivity.currentActivity;
        else
          context = EmacsActivity.lastFocusedActivity;
 
index 5d97eea32aa3a144fb7c99dec0681d7086d1162a..fd8d63d81d3c546216821d90fb84c564b7c467cf 100644 (file)
@@ -37,7 +37,7 @@ import android.view.ViewGroup;
 
 \f
 
-public class EmacsDialogButtonLayout extends ViewGroup
+public final class EmacsDialogButtonLayout extends ViewGroup
 {
   public
   EmacsDialogButtonLayout (Context context)
index 3ca803d16409086ff217c0c8f70f579d23b1e765..6cd48ba57ce90bbdd7b4211539d568e4730d8f4a 100644 (file)
@@ -24,7 +24,7 @@ package org.gnu.emacs;
 /* This class serves as a simple reference to an object of type T.
    Nothing could be found inside the standard library.  */
 
-public class EmacsHolder<T>
+public final class EmacsHolder<T>
 {
   T thing;
 };
index f402e25c7fb3a4f58ef63de203eceb85528f1936..6af2b2d2e949efa42a79761b4b9b5963df545ef1 100644 (file)
@@ -72,8 +72,17 @@ public final class EmacsOpenActivity extends Activity
   DialogInterface.OnCancelListener
 {
   private static final String TAG = "EmacsOpenActivity";
+
+  /* The name of any file that should be opened as EmacsThread starts
+     Emacs.  This is never cleared, even if EmacsOpenActivity is
+     started a second time, as EmacsThread only starts once.  */
   public static String fileToOpen;
 
+  /* Any currently focused EmacsOpenActivity.  Used to show pop ups
+     while the activity is active and Emacs doesn't have permission to
+     display over other programs.  */
+  public static EmacsOpenActivity currentActivity;
+
   private class EmacsClientThread extends Thread
   {
     private ProcessBuilder builder;
@@ -362,6 +371,15 @@ public final class EmacsOpenActivity extends Activity
     thread.start ();
   }
 
+  /* Run emacsclient to open the file specified in the Intent that
+     caused this activity to start.
+
+     Determine the name of the file corresponding to the URI specified
+     in that intent; then, run emacsclient and wait for it to finish.
+
+     Finally, display any error message, transfer the focus to an
+     Emacs frame, and finish the activity.  */
+
   @Override
   public void
   onCreate (Bundle savedInstanceState)
@@ -463,10 +481,60 @@ public final class EmacsOpenActivity extends Activity
              }
          }
 
-       /* And start emacsclient.  */
+       /* And start emacsclient.  Set `currentActivity' to this now.
+          Presumably, it will shortly become capable of displaying
+          dialogs.  */
+       currentActivity = this;
        startEmacsClient (fileName);
       }
     else
       finish ();
   }
+
+\f
+
+  @Override
+  public void
+  onDestroy ()
+  {
+    Log.d (TAG, "onDestroy: " + this);
+
+    /* Clear `currentActivity' if it refers to the activity being
+       destroyed.  */
+
+    if (currentActivity == this)
+      this.currentActivity = null;
+
+    super.onDestroy ();
+  }
+
+  @Override
+  public void
+  onWindowFocusChanged (boolean isFocused)
+  {
+    Log.d (TAG, "onWindowFocusChanged: " + this + ", is now focused: "
+          + isFocused);
+
+    if (isFocused)
+      currentActivity = this;
+    else if (currentActivity == this)
+      currentActivity = null;
+
+    super.onWindowFocusChanged (isFocused);
+  }
+
+  @Override
+  public void
+  onPause ()
+  {
+    Log.d (TAG, "onPause: " + this);
+
+    /* XXX: clear currentActivity here as well; I don't know whether
+       or not onWindowFocusChanged is always called prior to this.  */
+
+    if (currentActivity == this)
+      currentActivity = null;
+
+    super.onPause ();
+  }
 }