[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/android 634e3fcc20e: Update Android port
From: |
Po Lu |
Subject: |
feature/android 634e3fcc20e: Update Android port |
Date: |
Fri, 17 Mar 2023 22:54:45 -0400 (EDT) |
branch: feature/android
commit 634e3fcc20ea9fa5b1af59286f4b846a351f52c8
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Update Android port
* java/org/gnu/emacs/EmacsView.java (EmacsView)
(prepareForLayout): New function. Call this prior to mapping
the view.
(onGlobalLayout): New function. Register as global layout
listener.
* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow)
(notifyContentRectPosition): New function. Use specified
xPosition and yPosition when reporting the offsets of children
of the root window.
* java/org/gnu/emacs/EmacsWindowAttachmentManager.java
(registerWindow): Specify activity launch bounds if necessary.
* src/androidterm.c (handle_one_android_event): Send
MOVE_FRAME_EVENT where necessary.
---
java/org/gnu/emacs/EmacsView.java | 30 ++++-
java/org/gnu/emacs/EmacsWindow.java | 145 ++++++++++++---------
.../gnu/emacs/EmacsWindowAttachmentManager.java | 16 ++-
src/androidterm.c | 32 +++++
4 files changed, 160 insertions(+), 63 deletions(-)
diff --git a/java/org/gnu/emacs/EmacsView.java
b/java/org/gnu/emacs/EmacsView.java
index 681da98fa16..88d17a255a2 100644
--- a/java/org/gnu/emacs/EmacsView.java
+++ b/java/org/gnu/emacs/EmacsView.java
@@ -28,6 +28,7 @@ import android.view.View;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
@@ -51,6 +52,7 @@ import android.util.Log;
It is also a ViewGroup, as it also lays out children. */
public final class EmacsView extends ViewGroup
+ implements ViewTreeObserver.OnGlobalLayoutListener
{
public static final String TAG = "EmacsView";
@@ -136,6 +138,9 @@ public final class EmacsView extends ViewGroup
context = getContext ();
tem = context.getSystemService (Context.INPUT_METHOD_SERVICE);
imManager = (InputMethodManager) tem;
+
+ /* Add this view as its own global layout listener. */
+ getViewTreeObserver ().addOnGlobalLayoutListener (this);
}
private void
@@ -238,6 +243,13 @@ public final class EmacsView extends ViewGroup
return canvas;
}
+ public void
+ prepareForLayout (int wantedWidth, int wantedHeight)
+ {
+ measuredWidth = wantedWidth;
+ measuredHeight = wantedWidth;
+ }
+
@Override
protected void
onMeasure (int widthMeasureSpec, int heightMeasureSpec)
@@ -562,8 +574,7 @@ public final class EmacsView extends ViewGroup
bitmapDirty = true;
/* Now expose the view contents again. */
- EmacsNative.sendExpose (this.window.handle, 0, 0,
- measuredWidth, measuredHeight);
+ EmacsNative.sendExpose (this.window.handle, 0, 0, 0, 0);
super.onAttachedToWindow ();
}
@@ -678,4 +689,19 @@ public final class EmacsView extends ViewGroup
{
return icMode;
}
+
+ @Override
+ public void
+ onGlobalLayout ()
+ {
+ int[] locations;
+
+ /* Get the absolute offset of this view and specify its left and
+ top position in subsequent ConfigureNotify events. */
+
+ locations = new int[2];
+ getLocationInWindow (locations);
+ window.notifyContentRectPosition (locations[0],
+ locations[1]);
+ }
};
diff --git a/java/org/gnu/emacs/EmacsWindow.java
b/java/org/gnu/emacs/EmacsWindow.java
index a8d1beedef7..c14bf16b96e 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -133,6 +133,9 @@ public final class EmacsWindow extends EmacsHandleObject
creating new bitmaps. */
public volatile int background;
+ /* The position of this window relative to the root window. */
+ public int xPosition, yPosition;
+
public
EmacsWindow (short handle, final EmacsWindow parent, int x, int y,
int width, int height, boolean overrideRedirect)
@@ -192,18 +195,14 @@ public final class EmacsWindow extends EmacsHandleObject
background = pixel;
}
- public Rect
+ public synchronized Rect
getGeometry ()
{
- synchronized (this)
- {
- /* Huh, this is it. */
- return rect;
- }
+ return new Rect (rect);
}
@Override
- public void
+ public synchronized void
destroyHandle () throws IllegalStateException
{
if (parent != null)
@@ -258,22 +257,28 @@ public final class EmacsWindow extends EmacsHandleObject
return attached;
}
- public long
+ public synchronized long
viewLayout (int left, int top, int right, int bottom)
{
int rectWidth, rectHeight;
- synchronized (this)
- {
- rect.left = left;
- rect.top = top;
- rect.right = right;
- rect.bottom = bottom;
- }
+ 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,
@@ -283,8 +288,6 @@ public final class EmacsWindow extends EmacsHandleObject
public void
requestViewLayout ()
{
- /* This is necessary because otherwise subsequent drawing on the
- Emacs thread may be lost. */
view.explicitlyDirtyBitmap ();
EmacsService.SERVICE.runOnUiThread (new Runnable () {
@@ -302,35 +305,29 @@ public final class EmacsWindow extends EmacsHandleObject
});
}
- public void
+ public synchronized void
resizeWindow (int width, int height)
{
- synchronized (this)
- {
- rect.right = rect.left + width;
- rect.bottom = rect.top + height;
+ rect.right = rect.left + width;
+ rect.bottom = rect.top + height;
- requestViewLayout ();
- }
+ requestViewLayout ();
}
- public void
+ public synchronized void
moveWindow (int x, int y)
{
int width, height;
- synchronized (this)
- {
- width = rect.width ();
- height = rect.height ();
+ width = rect.width ();
+ height = rect.height ();
- rect.left = x;
- rect.top = y;
- rect.right = x + width;
- rect.bottom = y + height;
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + width;
+ rect.bottom = y + height;
- requestViewLayout ();
- }
+ requestViewLayout ();
}
private WindowManager.LayoutParams
@@ -366,13 +363,17 @@ public final class EmacsWindow extends EmacsHandleObject
return EmacsService.SERVICE;
}
- public void
+ public synchronized void
mapWindow ()
{
+ final int width, height;
+
if (isMapped)
return;
isMapped = true;
+ width = rect.width ();
+ height = rect.height ();
if (parent == null)
{
@@ -424,6 +425,7 @@ public final class EmacsWindow extends EmacsHandleObject
/* Attach the view. */
try
{
+ view.prepareForLayout (width, height);
windowManager.addView (view, params);
/* Record the window manager being used in the
@@ -448,10 +450,14 @@ public final class EmacsWindow extends EmacsHandleObject
public void
run ()
{
+ /* Prior to mapping the view, set its measuredWidth and
+ measuredHeight to some reasonable value, in order to
+ avoid excessive bitmap dirtying. */
+
+ view.prepareForLayout (width, height);
view.setVisibility (View.VISIBLE);
if (!getDontFocusOnMap ())
- /* Eventually this should check no-focus-on-map. */
view.requestFocus ();
}
});
@@ -512,12 +518,9 @@ public final class EmacsWindow extends EmacsHandleObject
public void
clearWindow ()
{
- synchronized (this)
- {
- EmacsService.SERVICE.fillRectangle (this, scratchGC,
- 0, 0, rect.width (),
- rect.height ());
- }
+ EmacsService.SERVICE.fillRectangle (this, scratchGC,
+ 0, 0, rect.width (),
+ rect.height ());
}
public void
@@ -1001,7 +1004,7 @@ public final class EmacsWindow extends EmacsHandleObject
return false;
}
- public void
+ public synchronized void
reparentTo (final EmacsWindow otherWindow, int x, int y)
{
int width, height;
@@ -1017,15 +1020,12 @@ public final class EmacsWindow extends EmacsHandleObject
parent = otherWindow;
/* Move this window to the new location. */
- synchronized (this)
- {
- width = rect.width ();
- height = rect.height ();
- rect.left = x;
- rect.top = y;
- rect.right = x + width;
- rect.bottom = y + height;
- }
+ width = rect.width ();
+ height = rect.height ();
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + width;
+ rect.bottom = y + height;
/* Now do the work necessary on the UI thread to reparent the
window. */
@@ -1081,7 +1081,7 @@ public final class EmacsWindow extends EmacsHandleObject
});
}
- public void
+ public synchronized void
raise ()
{
/* This does nothing here. */
@@ -1103,7 +1103,7 @@ public final class EmacsWindow extends EmacsHandleObject
});
}
- public void
+ public synchronized void
lower ()
{
/* This does nothing here. */
@@ -1125,17 +1125,15 @@ public final class EmacsWindow extends EmacsHandleObject
});
}
- public int[]
+ public synchronized int[]
getWindowGeometry ()
{
int[] array;
- Rect rect;
array = new int[4];
- rect = getGeometry ();
- array[0] = rect.left;
- array[1] = rect.top;
+ array[0] = parent != null ? rect.left : xPosition;
+ array[1] = parent != null ? rect.top : yPosition;
array[2] = rect.width ();
array[3] = rect.height ();
@@ -1272,4 +1270,31 @@ public final class EmacsWindow extends EmacsHandleObject
}
});
}
+
+ public synchronized void
+ notifyContentRectPosition (int xPosition, int yPosition)
+ {
+ Rect geometry;
+
+ /* Ignore these notifications if not a child of the root
+ window. */
+ if (parent != null)
+ return;
+
+ /* xPosition and yPosition are the position of this window
+ relative to the screen. Set them and request a ConfigureNotify
+ event. */
+
+ if (this.xPosition != xPosition
+ || this.yPosition != yPosition)
+ {
+ this.xPosition = xPosition;
+ this.yPosition = yPosition;
+
+ EmacsNative.sendConfigureNotify (this.handle,
+ System.currentTimeMillis (),
+ xPosition, yPosition,
+ rect.width (), rect.height ());
+ }
+ }
};
diff --git a/java/org/gnu/emacs/EmacsWindowAttachmentManager.java
b/java/org/gnu/emacs/EmacsWindowAttachmentManager.java
index c0197ab802c..4fda48616f0 100644
--- a/java/org/gnu/emacs/EmacsWindowAttachmentManager.java
+++ b/java/org/gnu/emacs/EmacsWindowAttachmentManager.java
@@ -22,7 +22,9 @@ package org.gnu.emacs;
import java.util.ArrayList;
import java.util.List;
+import android.app.ActivityOptions;
import android.content.Intent;
+import android.os.Build;
import android.util.Log;
/* Code to paper over the differences in lifecycles between
@@ -102,6 +104,7 @@ public final class EmacsWindowAttachmentManager
registerWindow (EmacsWindow window)
{
Intent intent;
+ ActivityOptions options;
Log.d (TAG, "registerWindow (maybe): " + window);
@@ -128,7 +131,18 @@ public final class EmacsWindowAttachmentManager
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_DOCUMENT
| Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- EmacsService.SERVICE.startActivity (intent);
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
+ EmacsService.SERVICE.startActivity (intent);
+ else
+ {
+ /* Specify the desired window size. */
+ options = ActivityOptions.makeBasic ();
+ options.setLaunchBounds (window.getGeometry ());
+ EmacsService.SERVICE.startActivity (intent,
+ options.toBundle ());
+ }
+
Log.d (TAG, "registerWindow: startActivity");
}
diff --git a/src/androidterm.c b/src/androidterm.c
index 1cf9bc4afde..825d6da60fa 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -787,6 +787,33 @@ handle_one_android_event (struct android_display_info
*dpyinfo,
cancel_mouse_face (f);
}
+ /* Now change the left and top position of this window. */
+
+ {
+ int old_left = f->left_pos;
+ int old_top = f->top_pos;
+ Lisp_Object frame;
+
+ XSETFRAME (frame, f);
+
+ {
+ android_window root;
+ unsigned int dummy_uint;
+
+ android_get_geometry (FRAME_ANDROID_WINDOW (f),
+ &root, &f->left_pos, &f->top_pos,
+ &dummy_uint, &dummy_uint,
+ &dummy_uint);
+ }
+
+ if (!FRAME_TOOLTIP_P (f)
+ && (old_left != f->left_pos || old_top != f->top_pos))
+ {
+ inev.ie.kind = MOVE_FRAME_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
+ }
+
goto OTHER;
case ANDROID_KEY_PRESS:
@@ -1100,6 +1127,11 @@ handle_one_android_event (struct android_display_info
*dpyinfo,
if (!FRAME_GARBAGED_P (f))
{
+ __android_log_print (ANDROID_LOG_VERBOSE, __func__,
+ "expose: %d %d %d %d\n",
+ event->xexpose.x, event->xexpose.y,
+ event->xexpose.width,
+ event->xexpose.height);
expose_frame (f, event->xexpose.x, event->xexpose.y,
event->xexpose.width, event->xexpose.height);
show_back_buffer (f);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- feature/android 634e3fcc20e: Update Android port,
Po Lu <=