diff options
Diffstat (limited to 'java/org')
| -rw-r--r-- | java/org/gnu/emacs/EmacsActivity.java | 36 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsContextMenu.java | 17 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsService.java | 90 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsWindow.java | 101 |
4 files changed, 140 insertions, 104 deletions
diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java index 3237f650240..66a1e41d84c 100644 --- a/java/org/gnu/emacs/EmacsActivity.java +++ b/java/org/gnu/emacs/EmacsActivity.java | |||
| @@ -97,7 +97,7 @@ public class EmacsActivity extends Activity | |||
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | public static void | 99 | public static void |
| 100 | invalidateFocus () | 100 | invalidateFocus (int whence) |
| 101 | { | 101 | { |
| 102 | EmacsWindow oldFocus; | 102 | EmacsWindow oldFocus; |
| 103 | 103 | ||
| @@ -144,7 +144,7 @@ public class EmacsActivity extends Activity | |||
| 144 | layout.removeView (window.view); | 144 | layout.removeView (window.view); |
| 145 | window = null; | 145 | window = null; |
| 146 | 146 | ||
| 147 | invalidateFocus (); | 147 | invalidateFocus (0); |
| 148 | } | 148 | } |
| 149 | } | 149 | } |
| 150 | 150 | ||
| @@ -172,8 +172,17 @@ public class EmacsActivity extends Activity | |||
| 172 | if (isPaused) | 172 | if (isPaused) |
| 173 | window.noticeIconified (); | 173 | window.noticeIconified (); |
| 174 | 174 | ||
| 175 | /* Invalidate the focus. */ | 175 | /* Invalidate the focus. Since attachWindow may be called from |
| 176 | invalidateFocus (); | 176 | either the main or the UI thread, post this to the UI thread. */ |
| 177 | |||
| 178 | runOnUiThread (new Runnable () { | ||
| 179 | @Override | ||
| 180 | public void | ||
| 181 | run () | ||
| 182 | { | ||
| 183 | invalidateFocus (1); | ||
| 184 | } | ||
| 185 | }); | ||
| 177 | } | 186 | } |
| 178 | 187 | ||
| 179 | @Override | 188 | @Override |
| @@ -238,6 +247,10 @@ public class EmacsActivity extends Activity | |||
| 238 | } | 247 | } |
| 239 | 248 | ||
| 240 | super.onCreate (savedInstanceState); | 249 | super.onCreate (savedInstanceState); |
| 250 | |||
| 251 | /* Call `onWindowFocusChanged' to read the focus state, which fails | ||
| 252 | to be called after an activity is recreated. */ | ||
| 253 | onWindowFocusChanged (false); | ||
| 241 | } | 254 | } |
| 242 | 255 | ||
| 243 | @Override | 256 | @Override |
| @@ -261,7 +274,7 @@ public class EmacsActivity extends Activity | |||
| 261 | isMultitask = this instanceof EmacsMultitaskActivity; | 274 | isMultitask = this instanceof EmacsMultitaskActivity; |
| 262 | manager.removeWindowConsumer (this, isMultitask || isFinishing ()); | 275 | manager.removeWindowConsumer (this, isMultitask || isFinishing ()); |
| 263 | focusedActivities.remove (this); | 276 | focusedActivities.remove (this); |
| 264 | invalidateFocus (); | 277 | invalidateFocus (2); |
| 265 | 278 | ||
| 266 | /* Remove this activity from the static field, lest it leak. */ | 279 | /* Remove this activity from the static field, lest it leak. */ |
| 267 | if (lastFocusedActivity == this) | 280 | if (lastFocusedActivity == this) |
| @@ -274,9 +287,16 @@ public class EmacsActivity extends Activity | |||
| 274 | public final void | 287 | public final void |
| 275 | onWindowFocusChanged (boolean isFocused) | 288 | onWindowFocusChanged (boolean isFocused) |
| 276 | { | 289 | { |
| 277 | if (isFocused && !focusedActivities.contains (this)) | 290 | /* At times and on certain versions of Android ISFOCUSED does not |
| 291 | reflect whether the window actually holds focus, so replace it | ||
| 292 | with the value of `hasWindowFocus'. */ | ||
| 293 | isFocused = hasWindowFocus (); | ||
| 294 | |||
| 295 | if (isFocused) | ||
| 278 | { | 296 | { |
| 279 | focusedActivities.add (this); | 297 | if (!focusedActivities.contains (this)) |
| 298 | focusedActivities.add (this); | ||
| 299 | |||
| 280 | lastFocusedActivity = this; | 300 | lastFocusedActivity = this; |
| 281 | 301 | ||
| 282 | /* Update the window insets as the focus change may have | 302 | /* Update the window insets as the focus change may have |
| @@ -291,7 +311,7 @@ public class EmacsActivity extends Activity | |||
| 291 | else | 311 | else |
| 292 | focusedActivities.remove (this); | 312 | focusedActivities.remove (this); |
| 293 | 313 | ||
| 294 | invalidateFocus (); | 314 | invalidateFocus (3); |
| 295 | } | 315 | } |
| 296 | 316 | ||
| 297 | @Override | 317 | @Override |
diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java index 17e6033377d..2bbf2a313d6 100644 --- a/java/org/gnu/emacs/EmacsContextMenu.java +++ b/java/org/gnu/emacs/EmacsContextMenu.java | |||
| @@ -361,8 +361,23 @@ public final class EmacsContextMenu | |||
| 361 | public Boolean | 361 | public Boolean |
| 362 | call () | 362 | call () |
| 363 | { | 363 | { |
| 364 | boolean rc; | ||
| 365 | |||
| 364 | lastMenuEventSerial = serial; | 366 | lastMenuEventSerial = serial; |
| 365 | return display1 (window, xPosition, yPosition); | 367 | rc = display1 (window, xPosition, yPosition); |
| 368 | |||
| 369 | /* Android 3.0 to Android 7.0 perform duplicate calls to | ||
| 370 | onContextMenuClosed the second time a context menu is | ||
| 371 | dismissed. Since the second call after such a dismissal is | ||
| 372 | otherwise liable to prematurely cancel any context menu | ||
| 373 | displayed immediately afterwards, ignore calls received | ||
| 374 | within 150 milliseconds of this menu's being displayed. */ | ||
| 375 | |||
| 376 | if (rc && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB | ||
| 377 | && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) | ||
| 378 | wasSubmenuSelected = System.currentTimeMillis () - 150; | ||
| 379 | |||
| 380 | return rc; | ||
| 366 | } | 381 | } |
| 367 | }); | 382 | }); |
| 368 | 383 | ||
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index 5cb1ceca0aa..d17ba597d8e 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java | |||
| @@ -60,6 +60,7 @@ import android.content.UriPermission; | |||
| 60 | import android.content.pm.PackageManager; | 60 | import android.content.pm.PackageManager; |
| 61 | 61 | ||
| 62 | import android.content.res.AssetManager; | 62 | import android.content.res.AssetManager; |
| 63 | import android.content.res.Configuration; | ||
| 63 | 64 | ||
| 64 | import android.hardware.input.InputManager; | 65 | import android.hardware.input.InputManager; |
| 65 | 66 | ||
| @@ -135,6 +136,10 @@ public final class EmacsService extends Service | |||
| 135 | been created yet. */ | 136 | been created yet. */ |
| 136 | private EmacsSafThread storageThread; | 137 | private EmacsSafThread storageThread; |
| 137 | 138 | ||
| 139 | /* The Thread object representing the Android user interface | ||
| 140 | thread. */ | ||
| 141 | private Thread mainThread; | ||
| 142 | |||
| 138 | static | 143 | static |
| 139 | { | 144 | { |
| 140 | servicingQuery = new AtomicInteger (); | 145 | servicingQuery = new AtomicInteger (); |
| @@ -235,6 +240,7 @@ public final class EmacsService extends Service | |||
| 235 | / metrics.density) | 240 | / metrics.density) |
| 236 | * pixelDensityX); | 241 | * pixelDensityX); |
| 237 | resolver = getContentResolver (); | 242 | resolver = getContentResolver (); |
| 243 | mainThread = Thread.currentThread (); | ||
| 238 | 244 | ||
| 239 | /* If the density used to compute the text size is lesser than | 245 | /* If the density used to compute the text size is lesser than |
| 240 | 160, there's likely a bug with display density computation. | 246 | 160, there's likely a bug with display density computation. |
| @@ -383,7 +389,13 @@ public final class EmacsService extends Service | |||
| 383 | { | 389 | { |
| 384 | if (DEBUG_THREADS) | 390 | if (DEBUG_THREADS) |
| 385 | { | 391 | { |
| 386 | if (Thread.currentThread () instanceof EmacsThread) | 392 | /* When SERVICE is NULL, Emacs is being executed non-interactively. */ |
| 393 | if (SERVICE == null | ||
| 394 | /* It was previously assumed that only instances of | ||
| 395 | `EmacsThread' were valid for graphics calls, but this is | ||
| 396 | no longer true now that Lisp threads can be attached to | ||
| 397 | the JVM. */ | ||
| 398 | || (Thread.currentThread () != SERVICE.mainThread)) | ||
| 387 | return; | 399 | return; |
| 388 | 400 | ||
| 389 | throw new RuntimeException ("Emacs thread function" | 401 | throw new RuntimeException ("Emacs thread function" |
| @@ -437,21 +449,6 @@ public final class EmacsService extends Service | |||
| 437 | EmacsDrawPoint.perform (drawable, gc, x, y); | 449 | EmacsDrawPoint.perform (drawable, gc, x, y); |
| 438 | } | 450 | } |
| 439 | 451 | ||
| 440 | public void | ||
| 441 | clearWindow (EmacsWindow window) | ||
| 442 | { | ||
| 443 | checkEmacsThread (); | ||
| 444 | window.clearWindow (); | ||
| 445 | } | ||
| 446 | |||
| 447 | public void | ||
| 448 | clearArea (EmacsWindow window, int x, int y, int width, | ||
| 449 | int height) | ||
| 450 | { | ||
| 451 | checkEmacsThread (); | ||
| 452 | window.clearArea (x, y, width, height); | ||
| 453 | } | ||
| 454 | |||
| 455 | @SuppressWarnings ("deprecation") | 452 | @SuppressWarnings ("deprecation") |
| 456 | public void | 453 | public void |
| 457 | ringBell (int duration) | 454 | ringBell (int duration) |
| @@ -581,6 +578,15 @@ public final class EmacsService extends Service | |||
| 581 | return false; | 578 | return false; |
| 582 | } | 579 | } |
| 583 | 580 | ||
| 581 | public boolean | ||
| 582 | detectKeyboard () | ||
| 583 | { | ||
| 584 | Configuration configuration; | ||
| 585 | |||
| 586 | configuration = getResources ().getConfiguration (); | ||
| 587 | return configuration.keyboard != Configuration.KEYBOARD_NOKEYS; | ||
| 588 | } | ||
| 589 | |||
| 584 | public String | 590 | public String |
| 585 | nameKeysym (int keysym) | 591 | nameKeysym (int keysym) |
| 586 | { | 592 | { |
| @@ -905,48 +911,6 @@ public final class EmacsService extends Service | |||
| 905 | 911 | ||
| 906 | /* Content provider functions. */ | 912 | /* Content provider functions. */ |
| 907 | 913 | ||
| 908 | /* Return a ContentResolver capable of accessing as many files as | ||
| 909 | possible, namely the content resolver of the last selected | ||
| 910 | activity if available: only they posses the rights to access drag | ||
| 911 | and drop files. */ | ||
| 912 | |||
| 913 | public ContentResolver | ||
| 914 | getUsefulContentResolver () | ||
| 915 | { | ||
| 916 | EmacsActivity activity; | ||
| 917 | |||
| 918 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) | ||
| 919 | /* Since the system predates drag and drop, return this resolver | ||
| 920 | to avoid any unforeseen difficulties. */ | ||
| 921 | return resolver; | ||
| 922 | |||
| 923 | activity = EmacsActivity.lastFocusedActivity; | ||
| 924 | if (activity == null) | ||
| 925 | return resolver; | ||
| 926 | |||
| 927 | return activity.getContentResolver (); | ||
| 928 | } | ||
| 929 | |||
| 930 | /* Return a context whose ContentResolver is granted access to most | ||
| 931 | files, as in `getUsefulContentResolver'. */ | ||
| 932 | |||
| 933 | public Context | ||
| 934 | getContentResolverContext () | ||
| 935 | { | ||
| 936 | EmacsActivity activity; | ||
| 937 | |||
| 938 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) | ||
| 939 | /* Since the system predates drag and drop, return this resolver | ||
| 940 | to avoid any unforeseen difficulties. */ | ||
| 941 | return this; | ||
| 942 | |||
| 943 | activity = EmacsActivity.lastFocusedActivity; | ||
| 944 | if (activity == null) | ||
| 945 | return this; | ||
| 946 | |||
| 947 | return activity; | ||
| 948 | } | ||
| 949 | |||
| 950 | /* Open a content URI described by the bytes BYTES, a non-terminated | 914 | /* Open a content URI described by the bytes BYTES, a non-terminated |
| 951 | string; make it writable if WRITABLE, and readable if READABLE. | 915 | string; make it writable if WRITABLE, and readable if READABLE. |
| 952 | Truncate the file if TRUNCATE. | 916 | Truncate the file if TRUNCATE. |
| @@ -960,9 +924,6 @@ public final class EmacsService extends Service | |||
| 960 | String name, mode; | 924 | String name, mode; |
| 961 | ParcelFileDescriptor fd; | 925 | ParcelFileDescriptor fd; |
| 962 | int i; | 926 | int i; |
| 963 | ContentResolver resolver; | ||
| 964 | |||
| 965 | resolver = getUsefulContentResolver (); | ||
| 966 | 927 | ||
| 967 | /* Figure out the file access mode. */ | 928 | /* Figure out the file access mode. */ |
| 968 | 929 | ||
| @@ -1024,12 +985,8 @@ public final class EmacsService extends Service | |||
| 1024 | ParcelFileDescriptor fd; | 985 | ParcelFileDescriptor fd; |
| 1025 | Uri uri; | 986 | Uri uri; |
| 1026 | int rc, flags; | 987 | int rc, flags; |
| 1027 | Context context; | ||
| 1028 | ContentResolver resolver; | ||
| 1029 | ParcelFileDescriptor descriptor; | 988 | ParcelFileDescriptor descriptor; |
| 1030 | 989 | ||
| 1031 | context = getContentResolverContext (); | ||
| 1032 | |||
| 1033 | uri = Uri.parse (name); | 990 | uri = Uri.parse (name); |
| 1034 | flags = 0; | 991 | flags = 0; |
| 1035 | 992 | ||
| @@ -1039,7 +996,7 @@ public final class EmacsService extends Service | |||
| 1039 | if (writable) | 996 | if (writable) |
| 1040 | flags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION; | 997 | flags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION; |
| 1041 | 998 | ||
| 1042 | rc = context.checkCallingUriPermission (uri, flags); | 999 | rc = checkCallingUriPermission (uri, flags); |
| 1043 | 1000 | ||
| 1044 | if (rc == PackageManager.PERMISSION_GRANTED) | 1001 | if (rc == PackageManager.PERMISSION_GRANTED) |
| 1045 | return true; | 1002 | return true; |
| @@ -1053,7 +1010,6 @@ public final class EmacsService extends Service | |||
| 1053 | 1010 | ||
| 1054 | try | 1011 | try |
| 1055 | { | 1012 | { |
| 1056 | resolver = context.getContentResolver (); | ||
| 1057 | descriptor = resolver.openFileDescriptor (uri, "r"); | 1013 | descriptor = resolver.openFileDescriptor (uri, "r"); |
| 1058 | return true; | 1014 | return true; |
| 1059 | } | 1015 | } |
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 304304a328b..6e8bdaf7401 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java | |||
| @@ -27,6 +27,8 @@ import java.util.HashMap; | |||
| 27 | import java.util.LinkedHashMap; | 27 | import java.util.LinkedHashMap; |
| 28 | import java.util.Map; | 28 | import java.util.Map; |
| 29 | 29 | ||
| 30 | import android.app.Activity; | ||
| 31 | |||
| 30 | import android.content.ClipData; | 32 | import android.content.ClipData; |
| 31 | import android.content.ClipDescription; | 33 | import android.content.ClipDescription; |
| 32 | import android.content.Context; | 34 | import android.content.Context; |
| @@ -240,7 +242,7 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 240 | } | 242 | } |
| 241 | } | 243 | } |
| 242 | 244 | ||
| 243 | EmacsActivity.invalidateFocus (); | 245 | EmacsActivity.invalidateFocus (4); |
| 244 | 246 | ||
| 245 | if (!children.isEmpty ()) | 247 | if (!children.isEmpty ()) |
| 246 | throw new IllegalStateException ("Trying to destroy window with " | 248 | throw new IllegalStateException ("Trying to destroy window with " |
| @@ -362,6 +364,9 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 362 | requestViewLayout (); | 364 | requestViewLayout (); |
| 363 | } | 365 | } |
| 364 | 366 | ||
| 367 | /* Return WM layout parameters for an override redirect window with | ||
| 368 | the geometry provided here. */ | ||
| 369 | |||
| 365 | private WindowManager.LayoutParams | 370 | private WindowManager.LayoutParams |
| 366 | getWindowLayoutParams () | 371 | getWindowLayoutParams () |
| 367 | { | 372 | { |
| @@ -384,15 +389,15 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 384 | return params; | 389 | return params; |
| 385 | } | 390 | } |
| 386 | 391 | ||
| 387 | private Context | 392 | private Activity |
| 388 | findSuitableActivityContext () | 393 | findSuitableActivityContext () |
| 389 | { | 394 | { |
| 390 | /* Find a recently focused activity. */ | 395 | /* Find a recently focused activity. */ |
| 391 | if (!EmacsActivity.focusedActivities.isEmpty ()) | 396 | if (!EmacsActivity.focusedActivities.isEmpty ()) |
| 392 | return EmacsActivity.focusedActivities.get (0); | 397 | return EmacsActivity.focusedActivities.get (0); |
| 393 | 398 | ||
| 394 | /* Return the service context, which probably won't work. */ | 399 | /* Resort to the last activity to be focused. */ |
| 395 | return EmacsService.SERVICE; | 400 | return EmacsActivity.lastFocusedActivity; |
| 396 | } | 401 | } |
| 397 | 402 | ||
| 398 | public synchronized void | 403 | public synchronized void |
| @@ -416,7 +421,7 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 416 | { | 421 | { |
| 417 | EmacsWindowAttachmentManager manager; | 422 | EmacsWindowAttachmentManager manager; |
| 418 | WindowManager windowManager; | 423 | WindowManager windowManager; |
| 419 | Context ctx; | 424 | Activity ctx; |
| 420 | Object tem; | 425 | Object tem; |
| 421 | WindowManager.LayoutParams params; | 426 | WindowManager.LayoutParams params; |
| 422 | 427 | ||
| @@ -447,11 +452,23 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 447 | activity using the system window manager. */ | 452 | activity using the system window manager. */ |
| 448 | 453 | ||
| 449 | ctx = findSuitableActivityContext (); | 454 | ctx = findSuitableActivityContext (); |
| 455 | |||
| 456 | if (ctx == null) | ||
| 457 | { | ||
| 458 | Log.w (TAG, "failed to attach override-redirect window" | ||
| 459 | + " for want of activity"); | ||
| 460 | return; | ||
| 461 | } | ||
| 462 | |||
| 450 | tem = ctx.getSystemService (Context.WINDOW_SERVICE); | 463 | tem = ctx.getSystemService (Context.WINDOW_SERVICE); |
| 451 | windowManager = (WindowManager) tem; | 464 | windowManager = (WindowManager) tem; |
| 452 | 465 | ||
| 453 | /* Calculate layout parameters. */ | 466 | /* Calculate layout parameters and propagate the |
| 467 | activity's token into it. */ | ||
| 468 | |||
| 454 | params = getWindowLayoutParams (); | 469 | params = getWindowLayoutParams (); |
| 470 | params.token = (ctx.findViewById (android.R.id.content) | ||
| 471 | .getWindowToken ()); | ||
| 455 | view.setLayoutParams (params); | 472 | view.setLayoutParams (params); |
| 456 | 473 | ||
| 457 | /* Attach the view. */ | 474 | /* Attach the view. */ |
| @@ -644,7 +661,7 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 644 | public void | 661 | public void |
| 645 | onKeyDown (int keyCode, KeyEvent event) | 662 | onKeyDown (int keyCode, KeyEvent event) |
| 646 | { | 663 | { |
| 647 | int state, state_1, num_lock_flag; | 664 | int state, state_1, extra_ignored; |
| 648 | long serial; | 665 | long serial; |
| 649 | String characters; | 666 | String characters; |
| 650 | 667 | ||
| @@ -665,23 +682,37 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 665 | 682 | ||
| 666 | state = eventModifiers (event); | 683 | state = eventModifiers (event); |
| 667 | 684 | ||
| 668 | /* Num Lock and Scroll Lock aren't supported by systems older than | 685 | /* Num Lock, Scroll Lock and Meta aren't supported by systems older |
| 669 | Android 3.0. */ | 686 | than Android 3.0. */ |
| 670 | 687 | ||
| 671 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) | 688 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) |
| 672 | num_lock_flag = (KeyEvent.META_NUM_LOCK_ON | 689 | extra_ignored = (KeyEvent.META_NUM_LOCK_ON |
| 673 | | KeyEvent.META_SCROLL_LOCK_ON); | 690 | | KeyEvent.META_SCROLL_LOCK_ON |
| 691 | | KeyEvent.META_META_MASK); | ||
| 674 | else | 692 | else |
| 675 | num_lock_flag = 0; | 693 | extra_ignored = 0; |
| 676 | 694 | ||
| 677 | /* Ignore meta-state understood by Emacs for now, or key presses | 695 | /* Ignore meta-state understood by Emacs for now, or key presses |
| 678 | such as Ctrl+C and Meta+C will not be recognized as an ASCII | 696 | such as Ctrl+C and Meta+C will not be recognized as ASCII key |
| 679 | key press event. */ | 697 | press events. */ |
| 680 | 698 | ||
| 681 | state_1 | 699 | state_1 |
| 682 | = state & ~(KeyEvent.META_ALT_MASK | KeyEvent.META_CTRL_MASK | 700 | = state & ~(KeyEvent.META_ALT_MASK | KeyEvent.META_CTRL_MASK |
| 683 | | KeyEvent.META_SYM_ON | KeyEvent.META_META_MASK | 701 | | KeyEvent.META_SYM_ON | extra_ignored); |
| 684 | | num_lock_flag); | 702 | |
| 703 | /* There's no distinction between Right Alt and Alt Gr on Android, | ||
| 704 | so restore META_ALT_RIGHT_ON if set in state to enable composing | ||
| 705 | characters. (bug#69321) */ | ||
| 706 | |||
| 707 | if ((state & KeyEvent.META_ALT_RIGHT_ON) != 0) | ||
| 708 | { | ||
| 709 | state_1 |= KeyEvent.META_ALT_ON | KeyEvent.META_ALT_RIGHT_ON; | ||
| 710 | |||
| 711 | /* If Alt is also not depressed, remove its bit from the mask | ||
| 712 | reported to Emacs. */ | ||
| 713 | if ((state & KeyEvent.META_ALT_LEFT_ON) == 0) | ||
| 714 | state &= ~KeyEvent.META_ALT_MASK; | ||
| 715 | } | ||
| 685 | 716 | ||
| 686 | synchronized (eventStrings) | 717 | synchronized (eventStrings) |
| 687 | { | 718 | { |
| @@ -702,29 +733,43 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 702 | public void | 733 | public void |
| 703 | onKeyUp (int keyCode, KeyEvent event) | 734 | onKeyUp (int keyCode, KeyEvent event) |
| 704 | { | 735 | { |
| 705 | int state, state_1, unicode_char, num_lock_flag; | 736 | int state, state_1, unicode_char, extra_ignored; |
| 706 | long time; | 737 | long time; |
| 707 | 738 | ||
| 708 | /* Compute the event's modifier mask. */ | 739 | /* Compute the event's modifier mask. */ |
| 709 | state = eventModifiers (event); | 740 | state = eventModifiers (event); |
| 710 | 741 | ||
| 711 | /* Num Lock and Scroll Lock aren't supported by systems older than | 742 | /* Num Lock, Scroll Lock and Meta aren't supported by systems older |
| 712 | Android 3.0. */ | 743 | than Android 3.0. */ |
| 713 | 744 | ||
| 714 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) | 745 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) |
| 715 | num_lock_flag = (KeyEvent.META_NUM_LOCK_ON | 746 | extra_ignored = (KeyEvent.META_NUM_LOCK_ON |
| 716 | | KeyEvent.META_SCROLL_LOCK_ON); | 747 | | KeyEvent.META_SCROLL_LOCK_ON |
| 748 | | KeyEvent.META_META_MASK); | ||
| 717 | else | 749 | else |
| 718 | num_lock_flag = 0; | 750 | extra_ignored = 0; |
| 719 | 751 | ||
| 720 | /* Ignore meta-state understood by Emacs for now, or key presses | 752 | /* Ignore meta-state understood by Emacs for now, or key presses |
| 721 | such as Ctrl+C and Meta+C will not be recognized as an ASCII | 753 | such as Ctrl+C and Meta+C will not be recognized as ASCII key |
| 722 | key press event. */ | 754 | press events. */ |
| 723 | 755 | ||
| 724 | state_1 | 756 | state_1 |
| 725 | = state & ~(KeyEvent.META_ALT_MASK | KeyEvent.META_CTRL_MASK | 757 | = state & ~(KeyEvent.META_ALT_MASK | KeyEvent.META_CTRL_MASK |
| 726 | | KeyEvent.META_SYM_ON | KeyEvent.META_META_MASK | 758 | | KeyEvent.META_SYM_ON | extra_ignored); |
| 727 | | num_lock_flag); | 759 | |
| 760 | /* There's no distinction between Right Alt and Alt Gr on Android, | ||
| 761 | so restore META_ALT_RIGHT_ON if set in state to enable composing | ||
| 762 | characters. */ | ||
| 763 | |||
| 764 | if ((state & KeyEvent.META_ALT_RIGHT_ON) != 0) | ||
| 765 | { | ||
| 766 | state_1 |= KeyEvent.META_ALT_ON | KeyEvent.META_ALT_RIGHT_ON; | ||
| 767 | |||
| 768 | /* If Alt is also not depressed, remove its bit from the mask | ||
| 769 | reported to Emacs. */ | ||
| 770 | if ((state & KeyEvent.META_ALT_LEFT_ON) == 0) | ||
| 771 | state &= ~KeyEvent.META_ALT_MASK; | ||
| 772 | } | ||
| 728 | 773 | ||
| 729 | unicode_char = getEventUnicodeChar (event, state_1); | 774 | unicode_char = getEventUnicodeChar (event, state_1); |
| 730 | 775 | ||
| @@ -760,7 +805,7 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 760 | public void | 805 | public void |
| 761 | onFocusChanged (boolean gainFocus) | 806 | onFocusChanged (boolean gainFocus) |
| 762 | { | 807 | { |
| 763 | EmacsActivity.invalidateFocus (); | 808 | EmacsActivity.invalidateFocus (gainFocus ? 6 : 5); |
| 764 | } | 809 | } |
| 765 | 810 | ||
| 766 | /* Notice that the activity has been detached or destroyed. | 811 | /* Notice that the activity has been detached or destroyed. |
| @@ -1746,7 +1791,7 @@ public final class EmacsWindow extends EmacsHandleObject | |||
| 1746 | 1791 | ||
| 1747 | /* Attempt to acquire permissions for this URI; | 1792 | /* Attempt to acquire permissions for this URI; |
| 1748 | failing which, insert it as text instead. */ | 1793 | failing which, insert it as text instead. */ |
| 1749 | 1794 | ||
| 1750 | if (uri != null | 1795 | if (uri != null |
| 1751 | && uri.getScheme () != null | 1796 | && uri.getScheme () != null |
| 1752 | && uri.getScheme ().equals ("content") | 1797 | && uri.getScheme ().equals ("content") |