diff options
| author | Po Lu | 2023-02-19 13:17:43 +0800 |
|---|---|---|
| committer | Po Lu | 2023-02-19 13:17:43 +0800 |
| commit | c8f49c9276d34741bfbe7752dd38391c0b8d782b (patch) | |
| tree | 02f627d6bcbc83900ce459570c59ec77a63152da /java | |
| parent | c6809eb92780f8206423898151cc40c959921753 (diff) | |
| download | emacs-c8f49c9276d34741bfbe7752dd38391c0b8d782b.tar.gz emacs-c8f49c9276d34741bfbe7752dd38391c0b8d782b.zip | |
Implement `fullscreen' on Android 4.0 and later
* doc/emacs/android.texi (Android Windowing): Document what new
frame parameters are now supported.
* java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): New
field `isFullscreen'.
(detachWindow, attachWindow): Sync fullscreen state.
(onWindowFocusChanged): Add more logging.
(onResume): Restore previous fullscreen state.
(syncFullscreen): New function.
* java/org/gnu/emacs/EmacsWindow.java (EmacsWindow)
(setFullscreen): New function.
* src/android.c (struct android_emacs_window): Add new method.
(android_init_emacs_window): Look up new method.
(android_set_fullscreen): New function.
* src/androidgui.h:
* src/androidterm.c (android_fullscreen_hook): Implement
accordingly.
Diffstat (limited to 'java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsActivity.java | 107 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsWindow.java | 26 |
2 files changed, 130 insertions, 3 deletions
diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java index 3156a144a0f..7e09e608984 100644 --- a/java/org/gnu/emacs/EmacsActivity.java +++ b/java/org/gnu/emacs/EmacsActivity.java | |||
| @@ -26,12 +26,16 @@ import java.util.ArrayList; | |||
| 26 | import android.app.Activity; | 26 | import android.app.Activity; |
| 27 | import android.content.Context; | 27 | import android.content.Context; |
| 28 | import android.content.Intent; | 28 | import android.content.Intent; |
| 29 | import android.os.Bundle; | ||
| 30 | import android.os.Build; | 29 | import android.os.Build; |
| 30 | import android.os.Bundle; | ||
| 31 | import android.util.Log; | 31 | import android.util.Log; |
| 32 | import android.widget.FrameLayout; | ||
| 33 | import android.widget.FrameLayout.LayoutParams; | ||
| 34 | import android.view.Menu; | 32 | import android.view.Menu; |
| 33 | import android.view.View; | ||
| 34 | import android.view.Window; | ||
| 35 | import android.view.WindowInsets; | ||
| 36 | import android.view.WindowInsetsController; | ||
| 37 | import android.widget.FrameLayout.LayoutParams; | ||
| 38 | import android.widget.FrameLayout; | ||
| 35 | 39 | ||
| 36 | public class EmacsActivity extends Activity | 40 | public class EmacsActivity extends Activity |
| 37 | implements EmacsWindowAttachmentManager.WindowConsumer | 41 | implements EmacsWindowAttachmentManager.WindowConsumer |
| @@ -56,6 +60,9 @@ public class EmacsActivity extends Activity | |||
| 56 | /* Whether or not this activity is paused. */ | 60 | /* Whether or not this activity is paused. */ |
| 57 | private boolean isPaused; | 61 | private boolean isPaused; |
| 58 | 62 | ||
| 63 | /* Whether or not this activity is fullscreen. */ | ||
| 64 | private boolean isFullscreen; | ||
| 65 | |||
| 59 | static | 66 | static |
| 60 | { | 67 | { |
| 61 | focusedActivities = new ArrayList<EmacsActivity> (); | 68 | focusedActivities = new ArrayList<EmacsActivity> (); |
| @@ -104,6 +111,8 @@ public class EmacsActivity extends Activity | |||
| 104 | public void | 111 | public void |
| 105 | detachWindow () | 112 | detachWindow () |
| 106 | { | 113 | { |
| 114 | syncFullscreenWith (null); | ||
| 115 | |||
| 107 | if (window == null) | 116 | if (window == null) |
| 108 | Log.w (TAG, "detachWindow called, but there is no window"); | 117 | Log.w (TAG, "detachWindow called, but there is no window"); |
| 109 | else | 118 | else |
| @@ -131,6 +140,8 @@ public class EmacsActivity extends Activity | |||
| 131 | throw new IllegalStateException ("trying to attach window when one" | 140 | throw new IllegalStateException ("trying to attach window when one" |
| 132 | + " already exists"); | 141 | + " already exists"); |
| 133 | 142 | ||
| 143 | syncFullscreenWith (child); | ||
| 144 | |||
| 134 | /* Record and attach the view. */ | 145 | /* Record and attach the view. */ |
| 135 | 146 | ||
| 136 | window = child; | 147 | window = child; |
| @@ -230,6 +241,9 @@ public class EmacsActivity extends Activity | |||
| 230 | public void | 241 | public void |
| 231 | onWindowFocusChanged (boolean isFocused) | 242 | onWindowFocusChanged (boolean isFocused) |
| 232 | { | 243 | { |
| 244 | Log.d (TAG, ("onWindowFocusChanged: " | ||
| 245 | + (isFocused ? "YES" : "NO"))); | ||
| 246 | |||
| 233 | if (isFocused && !focusedActivities.contains (this)) | 247 | if (isFocused && !focusedActivities.contains (this)) |
| 234 | { | 248 | { |
| 235 | focusedActivities.add (this); | 249 | focusedActivities.add (this); |
| @@ -257,6 +271,9 @@ public class EmacsActivity extends Activity | |||
| 257 | { | 271 | { |
| 258 | isPaused = false; | 272 | isPaused = false; |
| 259 | 273 | ||
| 274 | /* Update the window insets. */ | ||
| 275 | syncFullscreenWith (window); | ||
| 276 | |||
| 260 | EmacsWindowAttachmentManager.MANAGER.noticeDeiconified (this); | 277 | EmacsWindowAttachmentManager.MANAGER.noticeDeiconified (this); |
| 261 | super.onResume (); | 278 | super.onResume (); |
| 262 | } | 279 | } |
| @@ -279,4 +296,88 @@ public class EmacsActivity extends Activity | |||
| 279 | 296 | ||
| 280 | super.onContextMenuClosed (menu); | 297 | super.onContextMenuClosed (menu); |
| 281 | } | 298 | } |
| 299 | |||
| 300 | @SuppressWarnings ("deprecation") | ||
| 301 | public void | ||
| 302 | syncFullscreenWith (EmacsWindow emacsWindow) | ||
| 303 | { | ||
| 304 | WindowInsetsController controller; | ||
| 305 | Window window; | ||
| 306 | int behavior, flags; | ||
| 307 | View view; | ||
| 308 | |||
| 309 | if (emacsWindow != null) | ||
| 310 | isFullscreen = emacsWindow.fullscreen; | ||
| 311 | else | ||
| 312 | isFullscreen = false; | ||
| 313 | |||
| 314 | /* On Android 11 or later, use the window insets controller to | ||
| 315 | control whether or not the view is fullscreen. */ | ||
| 316 | |||
| 317 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) | ||
| 318 | { | ||
| 319 | window = getWindow (); | ||
| 320 | |||
| 321 | /* If there is no attached window, return immediately. */ | ||
| 322 | if (window == null) | ||
| 323 | return; | ||
| 324 | |||
| 325 | behavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; | ||
| 326 | controller = window.getInsetsController (); | ||
| 327 | controller.setSystemBarsBehavior (behavior); | ||
| 328 | |||
| 329 | if (isFullscreen) | ||
| 330 | controller.hide (WindowInsets.Type.statusBars () | ||
| 331 | | WindowInsets.Type.navigationBars ()); | ||
| 332 | else | ||
| 333 | controller.show (WindowInsets.Type.statusBars () | ||
| 334 | | WindowInsets.Type.navigationBars ()); | ||
| 335 | |||
| 336 | return; | ||
| 337 | } | ||
| 338 | |||
| 339 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) | ||
| 340 | { | ||
| 341 | /* On Android 4.1 or later, use `setSystemUiVisibility'. */ | ||
| 342 | |||
| 343 | window = getWindow (); | ||
| 344 | |||
| 345 | if (window == null) | ||
| 346 | return; | ||
| 347 | |||
| 348 | view = window.getDecorView (); | ||
| 349 | |||
| 350 | if (isFullscreen) | ||
| 351 | { | ||
| 352 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) | ||
| 353 | /* This flag means that Emacs will be full screen, but | ||
| 354 | the system will cancel the full screen state upon | ||
| 355 | switching to another program. */ | ||
| 356 | view.setSystemUiVisibility (View.SYSTEM_UI_FLAG_FULLSCREEN); | ||
| 357 | else | ||
| 358 | { | ||
| 359 | /* These flags means that Emacs will be full screen as | ||
| 360 | long as the state flag is set. */ | ||
| 361 | flags = 0; | ||
| 362 | flags |= View.SYSTEM_UI_FLAG_FULLSCREEN; | ||
| 363 | flags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; | ||
| 364 | flags |= View.SYSTEM_UI_FLAG_IMMERSIVE; | ||
| 365 | flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; | ||
| 366 | view.setSystemUiVisibility (flags); | ||
| 367 | } | ||
| 368 | } | ||
| 369 | else | ||
| 370 | view.setSystemUiVisibility (View.SYSTEM_UI_FLAG_VISIBLE); | ||
| 371 | } | ||
| 372 | } | ||
| 373 | |||
| 374 | @Override | ||
| 375 | public void | ||
| 376 | onAttachedToWindow () | ||
| 377 | { | ||
| 378 | super.onAttachedToWindow (); | ||
| 379 | |||
| 380 | /* Update the window insets. */ | ||
| 381 | syncFullscreenWith (window); | ||
| 382 | } | ||
| 282 | }; | 383 | }; |
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 0eca35cec61..90fc4c44198 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java | |||
| @@ -128,6 +128,9 @@ public class EmacsWindow extends EmacsHandleObject | |||
| 128 | events. */ | 128 | events. */ |
| 129 | public LinkedHashMap<Integer, String> eventStrings; | 129 | public LinkedHashMap<Integer, String> eventStrings; |
| 130 | 130 | ||
| 131 | /* Whether or not this window is fullscreen. */ | ||
| 132 | public boolean fullscreen; | ||
| 133 | |||
| 131 | public | 134 | public |
| 132 | EmacsWindow (short handle, final EmacsWindow parent, int x, int y, | 135 | EmacsWindow (short handle, final EmacsWindow parent, int x, int y, |
| 133 | int width, int height, boolean overrideRedirect) | 136 | int width, int height, boolean overrideRedirect) |
| @@ -1179,4 +1182,27 @@ public class EmacsWindow extends EmacsHandleObject | |||
| 1179 | 1182 | ||
| 1180 | return any; | 1183 | return any; |
| 1181 | } | 1184 | } |
| 1185 | |||
| 1186 | public void | ||
| 1187 | setFullscreen (final boolean isFullscreen) | ||
| 1188 | { | ||
| 1189 | EmacsService.SERVICE.runOnUiThread (new Runnable () { | ||
| 1190 | @Override | ||
| 1191 | public void | ||
| 1192 | run () | ||
| 1193 | { | ||
| 1194 | EmacsActivity activity; | ||
| 1195 | Object tem; | ||
| 1196 | |||
| 1197 | fullscreen = isFullscreen; | ||
| 1198 | tem = getAttachedConsumer (); | ||
| 1199 | |||
| 1200 | if (tem != null) | ||
| 1201 | { | ||
| 1202 | activity = (EmacsActivity) getAttachedConsumer (); | ||
| 1203 | activity.syncFullscreenWith (EmacsWindow.this); | ||
| 1204 | } | ||
| 1205 | } | ||
| 1206 | }); | ||
| 1207 | } | ||
| 1182 | }; | 1208 | }; |