]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix remaining Android bugs reported over the past months
authorPo Lu <luangruo@yahoo.com>
Wed, 19 Feb 2025 12:40:12 +0000 (20:40 +0800)
committerEshel Yaron <me@eshelyaron.com>
Thu, 20 Feb 2025 21:43:27 +0000 (22:43 +0100)
* java/org/gnu/emacs/EmacsActivity.java (attachWindow):
Guarantee that child windows promoted to toplevels receive
layout parameters that direct them to receive their parents'
dimensions.  Otherwise, the size of the window as a child is
retained on Huawei HarmonyOS 4.2 and possibly other Android
distributions.

* java/org/gnu/emacs/EmacsService.java (updateCursorAnchorInfo):
Run anchor updates on the UI thread, as
`InputMethodManager#updateCursorAnchorInfo' is liable to call
`View#requestLayout'.

* java/org/gnu/emacs/EmacsView.java (onMeasure): Always call
`measureChildren', or child frames' onLayout handlers might not
be invoked after they request a layout cycle and are duly
processed in `onLayout'.
(swapBuffers): Delete erroneous commentary.

* java/org/gnu/emacs/EmacsWindow.java (viewLayout): If
overrideRedirect, don't inadvertently clear rect.left and
rect.top by recording the window's WM window-relative position.
Fix typos.
(reparentTo): Invalidate focus after transferring frame.
(translateCoordinates): Account for override-redirect windows.
Mostly important for mouse-drag-and-drop-region.

(cherry picked from commit ded77feffface0c167edacf0d807273f3d4878db)

java/org/gnu/emacs/EmacsActivity.java
java/org/gnu/emacs/EmacsService.java
java/org/gnu/emacs/EmacsView.java
java/org/gnu/emacs/EmacsWindow.java

index 84d22e168208634129da8669ef061c84dfb94af8..439a8defa32431b638602c97ba04ada19acb162a 100644 (file)
@@ -179,6 +179,8 @@ public class EmacsActivity extends Activity
   public final void
   attachWindow (EmacsWindow child)
   {
+    FrameLayout.LayoutParams defaultParams;
+
     if (window != null)
       throw new IllegalStateException ("trying to attach window when one"
                                       + " already exists");
@@ -187,8 +189,15 @@ public class EmacsActivity extends Activity
 
     /* Record and attach the view.  */
 
+    /* Reset residual LayoutParams that might remain in effect on this
+       window, or some distributions of Android (e.g. Huawei HarmonyOS
+       4.2) will retain the size of this window as a child frame.  */
+    defaultParams
+      = new FrameLayout.LayoutParams (FrameLayout.LayoutParams.MATCH_PARENT,
+                                     FrameLayout.LayoutParams.MATCH_PARENT);
+    syncFullscreenWith (child);
     window = child;
-    layout.addView (window.view);
+    layout.addView (window.view, defaultParams);
     child.setConsumer (this);
 
     /* If the window isn't no-focus-on-map, focus its view.  */
index 5225337a8267053722106ad7e10589bef4160c82..babf2626ba50d49e3960a1bebc559cea10cafd14 100644 (file)
@@ -938,11 +938,11 @@ public final class EmacsService extends Service
   }
 
   public void
-  updateCursorAnchorInfo (EmacsWindow window, float x,
+  updateCursorAnchorInfo (final EmacsWindow window, float x,
                          float y, float yBaseline,
                          float yBottom)
   {
-    CursorAnchorInfo info;
+    final CursorAnchorInfo info;
     CursorAnchorInfo.Builder builder;
     Matrix matrix;
     int[] offsets;
@@ -964,9 +964,14 @@ public final class EmacsService extends Service
       Log.d (TAG, ("updateCursorAnchorInfo: " + x + " " + y
                   + " " + yBaseline + "-" + yBottom));
 
-    icBeginSynchronous ();
-    window.view.imManager.updateCursorAnchorInfo (window.view, info);
-    icEndSynchronous ();
+    EmacsService.SERVICE.runOnUiThread (new Runnable () {
+       @Override
+       public void
+       run ()
+       {
+         window.view.imManager.updateCursorAnchorInfo (window.view, info);
+       }
+    });
   }
 
 \f
index 8af76c73937f722f370d22d64446bd620723d352..5abea7115068e983d568619b7770955e999533d1 100644 (file)
@@ -296,6 +296,9 @@ public final class EmacsView extends ViewGroup
             && height > MeasureSpec.getSize (heightMeasureSpec))
       height = MeasureSpec.getSize (heightMeasureSpec);
 
+    /* This is strictly necessary to propagate layout requests to
+       children.  */
+    this.measureChildren (widthMeasureSpec, heightMeasureSpec);
     super.setMeasuredDimension (width, height);
   }
 
@@ -467,9 +470,6 @@ public final class EmacsView extends ViewGroup
       }
   }
 
-  /* This method is called from both the UI thread and the Emacs
-     thread.  */
-
   public void
   swapBuffers ()
   {
@@ -620,8 +620,7 @@ public final class EmacsView extends ViewGroup
        detachViewFromParent (index);
 
        /* The view at 0 is the surface view.  */
-       attachViewToParent (child, 1,
-                           child.getLayoutParams ());
+       attachViewToParent (child, 1, child.getLayoutParams ());
       }
   }
 
index 6a4d4cba9b97f98a5368f50c4940440a70e61081..801a5ebc96ba9423a62bc1b1b108be7d9db30e9a 100644 (file)
@@ -50,6 +50,7 @@ import android.view.InputDevice;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewManager;
 import android.view.WindowManager;
 
@@ -331,23 +332,39 @@ public final class EmacsWindow extends EmacsHandleObject
   {
     int rectWidth, rectHeight;
 
-    rect.left = left;
-    rect.top = top;
-    rect.right = right;
-    rect.bottom = bottom;
-
-    rectWidth = right - left;
-    rectHeight = bottom - top;
+    /* If this is an override-redirect window, don't ever modify
+       rect.left and rect.top, as its WM window will always have been
+       moved in unison with itself.  */
 
+    if (overrideRedirect)
+      {
+       rect.right = rect.left + (right - left);
+       rect.bottom = rect.top + (bottom - top);
+      }
     /* If parent is null, use xPosition and yPosition instead of the
        geometry rectangle positions.  */
-
-    if (parent == null)
+    else if (parent == null)
+      {
+       rect.left = xPosition;
+       rect.top = yPosition;
+       rect.right = rect.left + (right - left);
+       rect.bottom = rect.top + (bottom - top);
+      }
+    /* Otherwise accept the new position offered by the toolkit.  FIXME:
+       isn't there a potential race condition here if the toolkit lays
+       out EmacsView after a child frame's rect is set but before it
+       calls onLayout to read the modifies rect?  */
+    else
       {
-       left = xPosition;
-       top = yPosition;
+       rect.left = left;
+       rect.top = top;
+       rect.right = right;
+       rect.bottom = bottom;
       }
 
+    rectWidth = right - left;
+    rectHeight = bottom - top;
+
     return EmacsNative.sendConfigureNotify (this.handle,
                                            System.currentTimeMillis (),
                                            left, top, rectWidth,
@@ -1363,6 +1380,11 @@ public final class EmacsWindow extends EmacsHandleObject
          EmacsWindowManager manager;
          ViewManager parent;
 
+         /* Invalidate the focus; this should transfer the input focus
+            to the next eligible window as this window is no longer
+            present in parent.children.  */
+         EmacsActivity.invalidateFocus (7);
+
          /* First, detach this window if necessary.  */
          manager = EmacsWindowManager.MANAGER;
          manager.detachWindow (EmacsWindow.this);
@@ -1637,6 +1659,18 @@ public final class EmacsWindow extends EmacsHandleObject
     array[0] += x;
     array[1] += y;
 
+    /* In the case of an override redirect window, the WM window's
+       extents and position match the Emacs window exactly.  */
+
+    if (overrideRedirect)
+      {
+       synchronized (this)
+         {
+           array[0] += rect.left;
+           array[1] += rect.top;
+         }
+      }
+
     /* Return the resulting coordinates.  */
     return array;
   }