aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorPo Lu2023-10-10 13:11:14 +0800
committerPo Lu2023-10-10 13:11:14 +0800
commit336c3674119f61bd78a056476769ce83b97230bb (patch)
tree0af3b8f39dabdf71849c30fe0bf67952305b9319 /java
parent238292d6571402e93d4f7886baac9853011b36f6 (diff)
downloademacs-336c3674119f61bd78a056476769ce83b97230bb.tar.gz
emacs-336c3674119f61bd78a056476769ce83b97230bb.zip
Implement frame restacking under Android
* java/org/gnu/emacs/EmacsActivity.java (invalidateFocus1): Synchronize with window.children for iteration through it. * java/org/gnu/emacs/EmacsService.java (queryTree): Synchronize with windowList for iteration through it. * java/org/gnu/emacs/EmacsView.java (moveChildToBack): Correct formatting mistake. (moveAbove, moveBelow): New functions. * java/org/gnu/emacs/EmacsWindow.java (destroyHandle, reparentTo) (raise, lower): Remedy synchronization blunders. (reconfigure): New function. * src/android.c (android_init_emacs_window): Link with `reconfigure'. (android_reconfigure_wm_window): New wrapper function. * src/androidfns.c (android_frame_restack): New function. (Fandroid_frame_restack): Properly implement this function and expunge outdated comment. * src/androidgui.h (enum android_stack_mode) (enum android_window_changes): New enumerators.
Diffstat (limited to 'java')
-rw-r--r--java/org/gnu/emacs/EmacsActivity.java7
-rw-r--r--java/org/gnu/emacs/EmacsService.java17
-rw-r--r--java/org/gnu/emacs/EmacsView.java40
-rw-r--r--java/org/gnu/emacs/EmacsWindow.java130
4 files changed, 171 insertions, 23 deletions
diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java
index cecd9c21d99..f9aa261e355 100644
--- a/java/org/gnu/emacs/EmacsActivity.java
+++ b/java/org/gnu/emacs/EmacsActivity.java
@@ -89,8 +89,11 @@ public class EmacsActivity extends Activity
89 if (window.view.isFocused ()) 89 if (window.view.isFocused ())
90 focusedWindow = window; 90 focusedWindow = window;
91 91
92 for (EmacsWindow child : window.children) 92 synchronized (window.children)
93 invalidateFocus1 (child); 93 {
94 for (EmacsWindow child : window.children)
95 invalidateFocus1 (child);
96 }
94 } 97 }
95 98
96 public static void 99 public static void
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java
index 28b725d0cd0..6fa2ebb3fdb 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -505,15 +505,18 @@ public final class EmacsService extends Service
505 else 505 else
506 windowList = window.children; 506 windowList = window.children;
507 507
508 array = new short[windowList.size () + 1]; 508 synchronized (windowList)
509 i = 1; 509 {
510 array = new short[windowList.size () + 1];
511 i = 1;
510 512
511 array[0] = (window == null 513 array[0] = (window == null
512 ? 0 : (window.parent != null 514 ? 0 : (window.parent != null
513 ? window.parent.handle : 0)); 515 ? window.parent.handle : 0));
514 516
515 for (EmacsWindow treeWindow : windowList) 517 for (EmacsWindow treeWindow : windowList)
516 array[i++] = treeWindow.handle; 518 array[i++] = treeWindow.handle;
519 }
517 520
518 return array; 521 return array;
519 } 522 }
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java
index d09dcc7e50d..877b1ce2429 100644
--- a/java/org/gnu/emacs/EmacsView.java
+++ b/java/org/gnu/emacs/EmacsView.java
@@ -581,12 +581,12 @@ public final class EmacsView extends ViewGroup
581 581
582 /* The view at 0 is the surface view. */ 582 /* The view at 0 is the surface view. */
583 attachViewToParent (child, 1, 583 attachViewToParent (child, 1,
584 child.getLayoutParams()); 584 child.getLayoutParams ());
585 } 585 }
586 } 586 }
587 587
588 /* The following two functions must not be called if the view has no 588 /* The following four functions must not be called if the view has
589 parent, or is parented to an activity. */ 589 no parent, or is parented to an activity. */
590 590
591 public void 591 public void
592 raise () 592 raise ()
@@ -615,6 +615,40 @@ public final class EmacsView extends ViewGroup
615 parent.moveChildToBack (this); 615 parent.moveChildToBack (this);
616 } 616 }
617 617
618 public void
619 moveAbove (EmacsView view)
620 {
621 EmacsView parent;
622 int index;
623
624 parent = (EmacsView) getParent ();
625
626 if (parent != view.getParent ())
627 throw new IllegalStateException ("Moving view above non-sibling");
628
629 index = parent.indexOfChild (this);
630 parent.detachViewFromParent (index);
631 index = parent.indexOfChild (view);
632 parent.attachViewToParent (this, index + 1, getLayoutParams ());
633 }
634
635 public void
636 moveBelow (EmacsView view)
637 {
638 EmacsView parent;
639 int index;
640
641 parent = (EmacsView) getParent ();
642
643 if (parent != view.getParent ())
644 throw new IllegalStateException ("Moving view above non-sibling");
645
646 index = parent.indexOfChild (this);
647 parent.detachViewFromParent (index);
648 index = parent.indexOfChild (view);
649 parent.attachViewToParent (this, index, getLayoutParams ());
650 }
651
618 @Override 652 @Override
619 protected void 653 protected void
620 onCreateContextMenu (ContextMenu menu) 654 onCreateContextMenu (ContextMenu menu)
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java
index 1f28d5f4f53..8d444aa27f5 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -22,6 +22,7 @@ package org.gnu.emacs;
22import java.lang.IllegalStateException; 22import java.lang.IllegalStateException;
23import java.util.ArrayList; 23import java.util.ArrayList;
24import java.util.List; 24import java.util.List;
25import java.util.ListIterator;
25import java.util.HashMap; 26import java.util.HashMap;
26import java.util.LinkedHashMap; 27import java.util.LinkedHashMap;
27import java.util.Map; 28import java.util.Map;
@@ -93,7 +94,9 @@ public final class EmacsWindow extends EmacsHandleObject
93 public EmacsWindow parent; 94 public EmacsWindow parent;
94 95
95 /* List of all children in stacking order. This must be kept 96 /* List of all children in stacking order. This must be kept
96 consistent with their Z order! */ 97 consistent with their Z order!
98
99 Synchronize access to this list with itself. */
97 public ArrayList<EmacsWindow> children; 100 public ArrayList<EmacsWindow> children;
98 101
99 /* Map between pointer identifiers and last known position. Used to 102 /* Map between pointer identifiers and last known position. Used to
@@ -165,7 +168,11 @@ public final class EmacsWindow extends EmacsHandleObject
165 168
166 if (parent != null) 169 if (parent != null)
167 { 170 {
168 parent.children.add (this); 171 synchronized (parent.children)
172 {
173 parent.children.add (this);
174 }
175
169 EmacsService.SERVICE.runOnUiThread (new Runnable () { 176 EmacsService.SERVICE.runOnUiThread (new Runnable () {
170 @Override 177 @Override
171 public void 178 public void
@@ -214,7 +221,12 @@ public final class EmacsWindow extends EmacsHandleObject
214 destroyHandle () throws IllegalStateException 221 destroyHandle () throws IllegalStateException
215 { 222 {
216 if (parent != null) 223 if (parent != null)
217 parent.children.remove (this); 224 {
225 synchronized (parent.children)
226 {
227 parent.children.remove (this);
228 }
229 }
218 230
219 EmacsActivity.invalidateFocus (); 231 EmacsActivity.invalidateFocus ();
220 232
@@ -1163,10 +1175,20 @@ public final class EmacsWindow extends EmacsHandleObject
1163 /* Reparent this window to the other window. */ 1175 /* Reparent this window to the other window. */
1164 1176
1165 if (parent != null) 1177 if (parent != null)
1166 parent.children.remove (this); 1178 {
1179 synchronized (parent.children)
1180 {
1181 parent.children.remove (this);
1182 }
1183 }
1167 1184
1168 if (otherWindow != null) 1185 if (otherWindow != null)
1169 otherWindow.children.add (this); 1186 {
1187 synchronized (otherWindow.children)
1188 {
1189 otherWindow.children.add (this);
1190 }
1191 }
1170 1192
1171 parent = otherWindow; 1193 parent = otherWindow;
1172 1194
@@ -1239,9 +1261,12 @@ public final class EmacsWindow extends EmacsHandleObject
1239 if (parent == null) 1261 if (parent == null)
1240 return; 1262 return;
1241 1263
1242 /* Remove and add this view again. */ 1264 synchronized (parent.children)
1243 parent.children.remove (this); 1265 {
1244 parent.children.add (this); 1266 /* Remove and add this view again. */
1267 parent.children.remove (this);
1268 parent.children.add (this);
1269 }
1245 1270
1246 /* Request a relayout. */ 1271 /* Request a relayout. */
1247 EmacsService.SERVICE.runOnUiThread (new Runnable () { 1272 EmacsService.SERVICE.runOnUiThread (new Runnable () {
@@ -1261,9 +1286,12 @@ public final class EmacsWindow extends EmacsHandleObject
1261 if (parent == null) 1286 if (parent == null)
1262 return; 1287 return;
1263 1288
1264 /* Remove and add this view again. */ 1289 synchronized (parent.children)
1265 parent.children.remove (this); 1290 {
1266 parent.children.add (this); 1291 /* Remove and add this view again. */
1292 parent.children.remove (this);
1293 parent.children.add (this);
1294 }
1267 1295
1268 /* Request a relayout. */ 1296 /* Request a relayout. */
1269 EmacsService.SERVICE.runOnUiThread (new Runnable () { 1297 EmacsService.SERVICE.runOnUiThread (new Runnable () {
@@ -1276,6 +1304,86 @@ public final class EmacsWindow extends EmacsHandleObject
1276 }); 1304 });
1277 } 1305 }
1278 1306
1307 public synchronized void
1308 reconfigure (final EmacsWindow window, final int stackMode)
1309 {
1310 ListIterator<EmacsWindow> iterator;
1311 EmacsWindow object;
1312
1313 /* This does nothing here. */
1314 if (parent == null)
1315 return;
1316
1317 /* If window is NULL, call lower or upper subject to
1318 stackMode. */
1319
1320 if (window == null)
1321 {
1322 if (stackMode == 1) /* ANDROID_BELOW */
1323 lower ();
1324 else
1325 raise ();
1326
1327 return;
1328 }
1329
1330 /* Otherwise, if window.parent is distinct from this, return. */
1331 if (window.parent != this.parent)
1332 return;
1333
1334 /* Synchronize with the parent's child list. Iterate over each
1335 item until WINDOW is encountered, before moving this window to
1336 the location prescribed by STACKMODE. */
1337
1338 synchronized (parent.children)
1339 {
1340 /* Remove this window from parent.children, for it will be
1341 reinserted before or after WINDOW. */
1342 parent.children.remove (this);
1343
1344 /* Create an iterator. */
1345 iterator = parent.children.listIterator ();
1346
1347 while (iterator.hasNext ())
1348 {
1349 object = iterator.next ();
1350
1351 if (object == window)
1352 {
1353 /* Now place this before or after the cursor of the
1354 iterator. */
1355
1356 if (stackMode == 0) /* ANDROID_ABOVE */
1357 iterator.add (this);
1358 else
1359 {
1360 iterator.previous ();
1361 iterator.add (this);
1362 }
1363
1364 /* Effect the same adjustment upon the view
1365 hiearchy. */
1366
1367 EmacsService.SERVICE.runOnUiThread (new Runnable () {
1368 @Override
1369 public void
1370 run ()
1371 {
1372 if (stackMode == 0)
1373 view.moveAbove (window.view);
1374 else
1375 view.moveBelow (window.view);
1376 }
1377 });
1378 }
1379 }
1380
1381 /* parent.children does not list WINDOW, which should never
1382 transpire. */
1383 EmacsNative.emacsAbort ();
1384 }
1385 }
1386
1279 public synchronized int[] 1387 public synchronized int[]
1280 getWindowGeometry () 1388 getWindowGeometry ()
1281 { 1389 {