summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2025-02-19 20:40:12 +0800
committerPo Lu <luangruo@yahoo.com>2025-02-19 20:40:12 +0800
commitded77feffface0c167edacf0d807273f3d4878db (patch)
tree7849fa1827ed2ad92420d5e43589a8a43d0eaca9 /java
parente97be722d392056b6ef9e47664273ee2ca7df374 (diff)
Fix remaining Android bugs reported over the past months
* 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.
Diffstat (limited to 'java')
-rw-r--r--java/org/gnu/emacs/EmacsActivity.java11
-rw-r--r--java/org/gnu/emacs/EmacsService.java15
-rw-r--r--java/org/gnu/emacs/EmacsView.java9
-rw-r--r--java/org/gnu/emacs/EmacsWindow.java56
4 files changed, 69 insertions, 22 deletions
diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java
index 8a5ccb4625b..9f36561cc02 100644
--- a/java/org/gnu/emacs/EmacsActivity.java
+++ b/java/org/gnu/emacs/EmacsActivity.java
@@ -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. */
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java
index 04563590dc4..8cdf5011b70 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -937,11 +937,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;
@@ -963,9 +963,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);
+ }
+ });
}
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java
index 8af76c73937..5abea711506 100644
--- a/java/org/gnu/emacs/EmacsView.java
+++ b/java/org/gnu/emacs/EmacsView.java
@@ -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 ());
}
}
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java
index 2f4e378fb78..861bcace2ad 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -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;
}