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.
This commit is contained in:
parent
e97be722d3
commit
ded77fefff
4 changed files with 71 additions and 24 deletions
|
@ -179,6 +179,8 @@ children and RESETWHENCHILDLESS is set (implying it is a
|
||||||
public final void
|
public final void
|
||||||
attachWindow (EmacsWindow child)
|
attachWindow (EmacsWindow child)
|
||||||
{
|
{
|
||||||
|
FrameLayout.LayoutParams defaultParams;
|
||||||
|
|
||||||
if (window != null)
|
if (window != null)
|
||||||
throw new IllegalStateException ("trying to attach window when one"
|
throw new IllegalStateException ("trying to attach window when one"
|
||||||
+ " already exists");
|
+ " already exists");
|
||||||
|
@ -187,8 +189,15 @@ children and RESETWHENCHILDLESS is set (implying it is a
|
||||||
|
|
||||||
/* Record and attach the view. */
|
/* 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;
|
window = child;
|
||||||
layout.addView (window.view);
|
layout.addView (window.view, defaultParams);
|
||||||
child.setConsumer (this);
|
child.setConsumer (this);
|
||||||
|
|
||||||
/* If the window isn't no-focus-on-map, focus its view. */
|
/* If the window isn't no-focus-on-map, focus its view. */
|
||||||
|
|
|
@ -937,11 +937,11 @@ invocation of app_process (through android-emacs) can
|
||||||
}
|
}
|
||||||
|
|
||||||
public void
|
public void
|
||||||
updateCursorAnchorInfo (EmacsWindow window, float x,
|
updateCursorAnchorInfo (final EmacsWindow window, float x,
|
||||||
float y, float yBaseline,
|
float y, float yBaseline,
|
||||||
float yBottom)
|
float yBottom)
|
||||||
{
|
{
|
||||||
CursorAnchorInfo info;
|
final CursorAnchorInfo info;
|
||||||
CursorAnchorInfo.Builder builder;
|
CursorAnchorInfo.Builder builder;
|
||||||
Matrix matrix;
|
Matrix matrix;
|
||||||
int[] offsets;
|
int[] offsets;
|
||||||
|
@ -963,9 +963,14 @@ invocation of app_process (through android-emacs) can
|
||||||
Log.d (TAG, ("updateCursorAnchorInfo: " + x + " " + y
|
Log.d (TAG, ("updateCursorAnchorInfo: " + x + " " + y
|
||||||
+ " " + yBaseline + "-" + yBottom));
|
+ " " + yBaseline + "-" + yBottom));
|
||||||
|
|
||||||
icBeginSynchronous ();
|
EmacsService.SERVICE.runOnUiThread (new Runnable () {
|
||||||
window.view.imManager.updateCursorAnchorInfo (window.view, info);
|
@Override
|
||||||
icEndSynchronous ();
|
public void
|
||||||
|
run ()
|
||||||
|
{
|
||||||
|
window.view.imManager.updateCursorAnchorInfo (window.view, info);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -296,6 +296,9 @@ else if (MeasureSpec.getMode (heightMeasureSpec) == MeasureSpec.AT_MOST
|
||||||
&& height > MeasureSpec.getSize (heightMeasureSpec))
|
&& height > MeasureSpec.getSize (heightMeasureSpec))
|
||||||
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);
|
super.setMeasuredDimension (width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,9 +470,6 @@ else if (child.getVisibility () != GONE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This method is called from both the UI thread and the Emacs
|
|
||||||
thread. */
|
|
||||||
|
|
||||||
public void
|
public void
|
||||||
swapBuffers ()
|
swapBuffers ()
|
||||||
{
|
{
|
||||||
|
@ -620,8 +620,7 @@ else if (child.getVisibility () != GONE)
|
||||||
detachViewFromParent (index);
|
detachViewFromParent (index);
|
||||||
|
|
||||||
/* The view at 0 is the surface view. */
|
/* The view at 0 is the surface view. */
|
||||||
attachViewToParent (child, 1,
|
attachViewToParent (child, 1, child.getLayoutParams ());
|
||||||
child.getLayoutParams ());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewManager;
|
import android.view.ViewManager;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
@ -331,23 +332,39 @@ private static class Coordinate
|
||||||
{
|
{
|
||||||
int rectWidth, rectHeight;
|
int rectWidth, rectHeight;
|
||||||
|
|
||||||
rect.left = left;
|
/* If this is an override-redirect window, don't ever modify
|
||||||
rect.top = top;
|
rect.left and rect.top, as its WM window will always have been
|
||||||
rect.right = right;
|
moved in unison with itself. */
|
||||||
rect.bottom = bottom;
|
|
||||||
|
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. */
|
||||||
|
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
|
||||||
|
{
|
||||||
|
rect.left = left;
|
||||||
|
rect.top = top;
|
||||||
|
rect.right = right;
|
||||||
|
rect.bottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
rectWidth = right - left;
|
rectWidth = right - left;
|
||||||
rectHeight = bottom - top;
|
rectHeight = bottom - top;
|
||||||
|
|
||||||
/* If parent is null, use xPosition and yPosition instead of the
|
|
||||||
geometry rectangle positions. */
|
|
||||||
|
|
||||||
if (parent == null)
|
|
||||||
{
|
|
||||||
left = xPosition;
|
|
||||||
top = yPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EmacsNative.sendConfigureNotify (this.handle,
|
return EmacsNative.sendConfigureNotify (this.handle,
|
||||||
System.currentTimeMillis (),
|
System.currentTimeMillis (),
|
||||||
left, top, rectWidth,
|
left, top, rectWidth,
|
||||||
|
@ -1363,6 +1380,11 @@ else if (keyCode >= KeyEvent.KEYCODE_NUMPAD_0
|
||||||
EmacsWindowManager manager;
|
EmacsWindowManager manager;
|
||||||
ViewManager parent;
|
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. */
|
/* First, detach this window if necessary. */
|
||||||
manager = EmacsWindowManager.MANAGER;
|
manager = EmacsWindowManager.MANAGER;
|
||||||
manager.detachWindow (EmacsWindow.this);
|
manager.detachWindow (EmacsWindow.this);
|
||||||
|
@ -1637,6 +1659,18 @@ else if (EmacsWindow.this.isMapped)
|
||||||
array[0] += x;
|
array[0] += x;
|
||||||
array[1] += y;
|
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 the resulting coordinates. */
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue