diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java index 84d22e16820..439a8defa32 100644 --- a/java/org/gnu/emacs/EmacsActivity.java +++ b/java/org/gnu/emacs/EmacsActivity.java @@ -179,6 +179,8 @@ children and RESETWHENCHILDLESS is set (implying it is a 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 @@ children and RESETWHENCHILDLESS is set (implying it is a /* 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 5225337a826..babf2626ba5 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -938,11 +938,11 @@ invocation of app_process (through android-emacs) can } 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 @@ invocation of app_process (through android-emacs) can 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 @@ else if (MeasureSpec.getMode (heightMeasureSpec) == MeasureSpec.AT_MOST && 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 @@ else if (child.getVisibility () != GONE) } } - /* This method is called from both the UI thread and the Emacs - thread. */ - public void swapBuffers () { @@ -620,8 +620,7 @@ else if (child.getVisibility () != GONE) 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.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 @@ private static class Coordinate { int rectWidth, rectHeight; - rect.left = left; - rect.top = top; - rect.right = right; - rect.bottom = bottom; + /* 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. */ + 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; 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, System.currentTimeMillis (), left, top, rectWidth, @@ -1363,6 +1380,11 @@ else if (keyCode >= KeyEvent.KEYCODE_NUMPAD_0 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 @@ else if (EmacsWindow.this.isMapped) 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; }