diff options
| author | Lena <lena@omega> | 2026-08-01 00:00:00 +0000 |
|---|---|---|
| committer | Lena <lena@omega> | 2026-08-01 00:00:00 +0000 |
| commit | 3037f9f8fdcc6cdadfe94ba248d10e647578cf53 (patch) | |
| tree | e07e981d8d6b05c1a3dc836434d88bff7d76c703 /app/src/main/java/invalid/lena/scrcpy/Mirror.java | |
| parent | 70290eb3d79a5347cdc114daf6ce0b1b2e86528a (diff) | |
| download | scrcpy-android-3037f9f8fdcc6cdadfe94ba248d10e647578cf53.tar.gz | |
app: refine physical-device interface
Use target-safe capture defaults and remove redundant navigation and
frame-rate controls.
Diffstat (limited to 'app/src/main/java/invalid/lena/scrcpy/Mirror.java')
| -rw-r--r-- | app/src/main/java/invalid/lena/scrcpy/Mirror.java | 61 |
1 files changed, 33 insertions, 28 deletions
diff --git a/app/src/main/java/invalid/lena/scrcpy/Mirror.java b/app/src/main/java/invalid/lena/scrcpy/Mirror.java index bc9db34..51e861a 100644 --- a/app/src/main/java/invalid/lena/scrcpy/Mirror.java +++ b/app/src/main/java/invalid/lena/scrcpy/Mirror.java @@ -11,13 +11,13 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; +import android.view.Gravity; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; -import android.view.ViewGroup; import android.view.WindowInsets; import android.view.WindowInsetsController; import android.view.WindowManager; @@ -65,6 +65,7 @@ public final class Mirror extends Activity { private State state = State.CONNECTING; private int connectedW, connectedH; private long connectedGeometryVersion; + private int gestureBottomInset; private SurfaceView surfaceView; @@ -114,26 +115,25 @@ public final class Mirror extends Activity { // video surface, so re-fit from here as well. root.addOnLayoutChangeListener( (view, l, t, r, b, ol, ot, or, ob) -> applyLetterbox()); + // Keep the target's bottom edge above the source's mandatory Home + // gesture area. A target gesture can then start on the mirrored + // handle instead of being claimed by the source system. + root.setOnApplyWindowInsetsListener((view, insets) -> { + int bottom = insets.getInsetsIgnoringVisibility( + WindowInsets.Type.mandatorySystemGestures()).bottom; + if (gestureBottomInset != bottom) { + gestureBottomInset = bottom; + applyLetterbox(); + } + return insets; + }); + root.requestApplyInsets(); statusBar = findViewById(R.id.status_bar); statusText = findViewById(R.id.status_text); reconnectBtn = findViewById(R.id.reconnect); insetStatusBar(); reconnectBtn.setOnClickListener(view -> reconnect()); - // Back, Home and Recents as explicit controls. On a - // gesture-navigation source the target's own navigation cannot be - // reached by forwarding touches: the source claims the bottom - // edge swipe for itself and, unlike the side edges, that region - // cannot be released with setSystemGestureExclusionRects. - findViewById(R.id.nav_back).setOnClickListener(view -> { - if (session != null) session.onBack(); - }); - findViewById(R.id.nav_home).setOnClickListener(view -> { - if (session != null) session.onHome(); - }); - findViewById(R.id.nav_recents).setOnClickListener(view -> { - if (session != null) session.onRecents(); - }); updateStatusBar(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { @@ -220,22 +220,29 @@ public final class Mirror extends Activity { View v = surfaceView; if (v == null || root == null || session == null) return; int cw = root.getWidth(), ch = root.getHeight(); + int availableH = ch - gestureBottomInset; int tw = connectedW, th = connectedH; - if (cw <= 0 || ch <= 0 || tw <= 0 || th <= 0) return; + if (cw <= 0 || availableH <= 0 || tw <= 0 || th <= 0) return; - float scale = Math.min(cw / (float) tw, ch / (float) th); + float scale = Math.min(cw / (float) tw, availableH / (float) th); int w = Math.min(cw, Math.max(1, Math.round(tw * scale))); - int h = Math.min(ch, Math.max(1, Math.round(th * scale))); + int h = Math.min(availableH, Math.max(1, Math.round(th * scale))); + int x = (cw - w) / 2; + int y = (availableH - h) / 2; - ViewGroup.LayoutParams lp = v.getLayoutParams(); - if (lp.width != w || lp.height != h) { + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams(); + if (lp.width != w || lp.height != h || lp.leftMargin != x + || lp.topMargin != y || lp.gravity != (Gravity.TOP | Gravity.START)) { lp.width = w; lp.height = h; + lp.leftMargin = x; + lp.topMargin = y; + lp.gravity = Gravity.TOP | Gravity.START; v.setLayoutParams(lp); // re-layout re-enters here, then converges - Log.i("mirror: letterbox %dx%d -> %dx%d in %dx%d", tw, th, w, h, cw, ch); + Log.i("mirror: letterbox %dx%d -> %dx%d in %dx%d gesture_bottom=%d", + tw, th, w, h, cw, ch, gestureBottomInset); } - session.setViewport(connectedGeometryVersion, - (cw - w) / 2, (ch - h) / 2, w, h); + session.setViewport(connectedGeometryVersion, x, y, w, h); } private void detachSurface() { @@ -377,12 +384,10 @@ public final class Mirror extends Activity { statusText.setText(s); reconnectBtn.setVisibility(state == State.DISCONNECTED ? View.VISIBLE : View.GONE); - // Hide the whole bar while actively mirroring if the user opted - // out; keep it up whenever not CONNECTED so the status and the - // Reconnect button stay reachable. + // Status is only needed during bring-up and after a terminal error. + // Target navigation remains inside the mirrored frame. if (statusBar != null) { - boolean show = Settings.showStatusBar(this) || state != State.CONNECTED; - statusBar.setVisibility(show ? View.VISIBLE : View.GONE); + statusBar.setVisibility(state == State.CONNECTED ? View.GONE : View.VISIBLE); } } |