diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt index b6321d07a..e4dd7d34f 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt @@ -37,7 +37,7 @@ import org.oxycblt.auxio.settings.SettingsManager import org.oxycblt.auxio.util.isNight import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.replaceInsetsCompat -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat /** * The single [AppCompatActivity] for Auxio. @@ -113,18 +113,25 @@ class MainActivity : AppCompatActivity() { private fun applyEdgeToEdgeWindow(binding: ViewBinding) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - // Do modern edge to edge, which happens to be around twice the size of the - // old way of doing things. Thanks android, very cool! logD("Doing R+ edge-to-edge.") window?.setDecorFitsSystemWindows(false) + // "Should we automatically acquire the insets we need and return them + // whenever the user wants them?" + // "Nah, let's make the user define what insets they want instead through + // a barely-documented API that is not brought up in a single tutorial!" + // "Great idea!" binding.root.setOnApplyWindowInsetsListener { _, insets -> WindowInsets.Builder() .setInsets( WindowInsets.Type.systemBars(), insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) ) + .setInsets( + WindowInsets.Type.systemGestures(), + insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemGestures()) + ) .build() .applyLeftRightInsets(binding) } @@ -145,7 +152,7 @@ class MainActivity : AppCompatActivity() { } private fun WindowInsets.applyLeftRightInsets(binding: ViewBinding): WindowInsets { - val bars = systemBarsCompat + val bars = systemBarInsetsCompat binding.root.updatePadding( left = bars.left, diff --git a/app/src/main/java/org/oxycblt/auxio/home/FloatingActionButtonContainer.kt b/app/src/main/java/org/oxycblt/auxio/home/FloatingActionButtonContainer.kt index b73a2b371..863306dc9 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/FloatingActionButtonContainer.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/FloatingActionButtonContainer.kt @@ -23,7 +23,7 @@ import android.util.AttributeSet import android.view.WindowInsets import android.widget.FrameLayout import androidx.core.view.updatePadding -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat /** * A container for a FloatingActionButton that enables edge-to-edge support. @@ -43,7 +43,7 @@ class FloatingActionButtonContainer @JvmOverloads constructor( } override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets { - updatePadding(bottom = insets.systemBarsCompat.bottom) + updatePadding(bottom = insets.systemBarInsetsCompat.bottom) return insets } diff --git a/app/src/main/java/org/oxycblt/auxio/home/fastscroll/FastScrollRecyclerView.kt b/app/src/main/java/org/oxycblt/auxio/home/fastscroll/FastScrollRecyclerView.kt index 94696e469..74c9ed99d 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/fastscroll/FastScrollRecyclerView.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/fastscroll/FastScrollRecyclerView.kt @@ -44,7 +44,7 @@ import org.oxycblt.auxio.R import org.oxycblt.auxio.util.canScroll import org.oxycblt.auxio.util.resolveAttr import org.oxycblt.auxio.util.resolveDrawable -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat import kotlin.math.abs /** @@ -315,7 +315,7 @@ class FastScrollRecyclerView @JvmOverloads constructor( } override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets { - val bars = insets.systemBarsCompat + val bars = insets.systemBarInsetsCompat updatePadding( initialPadding.left, initialPadding.top, initialPadding.right, diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarView.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarView.kt index 350cb61ef..81599c23b 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarView.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBarView.kt @@ -19,6 +19,7 @@ package org.oxycblt.auxio.playback import android.content.Context +import android.os.Build import android.util.AttributeSet import android.view.WindowInsets import androidx.constraintlayout.widget.ConstraintLayout @@ -31,7 +32,7 @@ import org.oxycblt.auxio.detail.DetailViewModel import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.util.inflater import org.oxycblt.auxio.util.resolveAttr -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat /** * A view displaying the playback state in a compact manner. This is only meant to be used @@ -48,17 +49,39 @@ class PlaybackBarView @JvmOverloads constructor( id = R.id.playback_bar // Deliberately override the progress bar color [in a Lollipop-friendly way] so that - // we use colorSecondary instead of colorSurfaceVariant. This is for two reasons: - // 1. colorSurfaceVariant is used with the assumption that the view that is using it - // is not elevated and is therefore not colored. This view is elevated. - // 2. The way a solid color plays along with a ripple just doesnt look that good. + // we use colorSecondary instead of colorSurfaceVariant. This is because + // colorSurfaceVariant is used with the assumption that the view that is using it is + // not elevated and is therefore not colored. This view is elevated. binding.playbackProgressBar.trackColor = MaterialColors.compositeARGBWithAlpha( R.attr.colorSecondary.resolveAttr(context), (255 * 0.2).toInt() ) } override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets { - updatePadding(bottom = insets.systemBarsCompat.bottom) + // Since we swipe up this view, we need to make sure it does not collide with + // any gesture events. So, apply the system gesture insets if present and then + // only default to the system bar insets when there are no other options. + val gesturePadding = when { + Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> { + insets.getInsets(WindowInsets.Type.systemGestures()).bottom + } + + Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> { + @Suppress("DEPRECATION") + insets.systemGestureInsets.bottom + } + + else -> 0 + } + + updatePadding( + bottom = + if (gesturePadding != 0) + gesturePadding + else + insets.systemBarInsetsCompat.bottom + ) + return insets } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt index ca8d0f7b6..03b2b9663 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt @@ -34,7 +34,7 @@ import org.oxycblt.auxio.detail.DetailViewModel import org.oxycblt.auxio.playback.state.LoopMode import org.oxycblt.auxio.ui.memberBinding import org.oxycblt.auxio.util.logD -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat /** * A [Fragment] that displays more information about the song, along with more media controls. @@ -62,7 +62,7 @@ class PlaybackFragment : Fragment() { binding.detailModel = detailModel binding.root.setOnApplyWindowInsetsListener { _, insets -> - val bars = insets.systemBarsCompat + val bars = insets.systemBarInsetsCompat binding.root.updatePadding( top = bars.top, diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt index 0c5c668e9..afa67d5e9 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt @@ -3,10 +3,8 @@ package org.oxycblt.auxio.playback import android.content.Context import android.content.res.ColorStateList import android.graphics.Canvas -import android.graphics.Insets import android.graphics.Rect import android.graphics.drawable.LayerDrawable -import android.os.Build import android.os.Bundle import android.os.Parcelable import android.util.AttributeSet @@ -26,9 +24,10 @@ import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.R import org.oxycblt.auxio.detail.DetailViewModel import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.util.replaceInsetsCompat import org.oxycblt.auxio.util.resolveAttr import org.oxycblt.auxio.util.resolveDrawable -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat import kotlin.math.abs import kotlin.math.max import kotlin.math.min @@ -169,7 +168,7 @@ class PlaybackLayout @JvmOverloads constructor( } catch (e: Exception) { // Band-aid to stop the app crashing if we have to swap out the content view // without warning (which we have to do sometimes because android is the worst - // thing ever + // thing ever) } } } @@ -379,29 +378,11 @@ class PlaybackLayout @JvmOverloads constructor( // We kind to do a reverse-measure to figure out how we should inset this view. // Find how much space is lost by the panel and then combine that with the // bottom inset to find how much space we should apply. - val bars = insets.systemBarsCompat + val bars = insets.systemBarInsetsCompat val consumedByPanel = computePanelTopPosition(panelOffset) - measuredHeight val adjustedBottomInset = (consumedByPanel + bars.bottom).coerceAtLeast(0) - return when { - Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> { - WindowInsets.Builder(insets) - .setInsets( - WindowInsets.Type.systemBars(), - Insets.of(bars.left, bars.top, bars.right, adjustedBottomInset) - ) - .build() - } - - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1 -> { - @Suppress("DEPRECATION") - insets.replaceSystemWindowInsets( - bars.left, bars.top, bars.right, adjustedBottomInset - ) - } - - else -> insets - } + return insets.replaceInsetsCompat(bars.left, bars.top, bars.right, adjustedBottomInset) } override fun onSaveInstanceState(): Parcelable = Bundle().apply { @@ -536,8 +517,7 @@ class PlaybackLayout @JvmOverloads constructor( /** * Do the nice view animations that occur whenever we slide up the playback panel. * The way I transition is largely inspired by Android 12's notification panel, with the - * compact view fading out completely before the panel view fades in. We don't fade out the - * content though so we have cohesion between the other sliding transitions. + * compact view fading out completely before the panel view fades in. */ private fun updatePanelTransition() { val ratio = max(panelOffset, 0f) @@ -546,7 +526,6 @@ class PlaybackLayout @JvmOverloads constructor( val halfOutRatio = min(ratio / 0.5f, 1f) val halfInRatio = max(ratio - 0.5f, 0f) / 0.5f - // Optimize out drawing for this view completely contentView.apply { alpha = outRatio isInvisible = alpha == 0f @@ -569,7 +548,7 @@ class PlaybackLayout @JvmOverloads constructor( // [reminder that this view also applies the bottom window inset] and we can't // apply padding to the whole container layout since that would adjust the size // of the playback view. This seems to be the least obtrusive way to do this. - lastInsets?.systemBarsCompat?.let { bars -> + lastInsets?.systemBarInsetsCompat?.let { bars -> val params = layoutParams as FrameLayout.LayoutParams val oldTopMargin = params.topMargin diff --git a/app/src/main/java/org/oxycblt/auxio/settings/AboutFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/AboutFragment.kt index c0dab74a1..64cb1bf26 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/AboutFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/AboutFragment.kt @@ -38,7 +38,7 @@ import org.oxycblt.auxio.databinding.FragmentAboutBinding import org.oxycblt.auxio.home.HomeViewModel import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.showToast -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat /** * A [BottomSheetDialogFragment] that shows Auxio's about screen. @@ -55,7 +55,7 @@ class AboutFragment : Fragment() { val binding = FragmentAboutBinding.inflate(layoutInflater) binding.aboutContents.setOnApplyWindowInsetsListener { _, insets -> - binding.aboutContents.updatePadding(bottom = insets.systemBarsCompat.bottom) + binding.aboutContents.updatePadding(bottom = insets.systemBarInsetsCompat.bottom) insets } diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt index 1a95d5bf1..57eeae1b9 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt @@ -40,7 +40,7 @@ import org.oxycblt.auxio.settings.pref.IntListPreference import org.oxycblt.auxio.util.isNight import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.showToast -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat /** * The actual fragment containing the settings menu. Inherits [PreferenceFragmentCompat]. @@ -64,7 +64,7 @@ class SettingsListFragment : PreferenceFragmentCompat() { clipToPadding = false setOnApplyWindowInsetsListener { _, insets -> - updatePadding(bottom = insets.systemBarsCompat.bottom) + updatePadding(bottom = insets.systemBarInsetsCompat.bottom) insets } diff --git a/app/src/main/java/org/oxycblt/auxio/ui/EdgeAppBarLayout.kt b/app/src/main/java/org/oxycblt/auxio/ui/EdgeAppBarLayout.kt index 5dd3b8f8c..60f6ff74c 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/EdgeAppBarLayout.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/EdgeAppBarLayout.kt @@ -30,7 +30,7 @@ import androidx.core.content.res.ResourcesCompat import androidx.core.view.updatePadding import com.google.android.material.appbar.AppBarLayout import org.oxycblt.auxio.util.logE -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat /** * An [AppBarLayout] that fixes a bug with the default implementation where the lifted state @@ -67,7 +67,7 @@ open class EdgeAppBarLayout @JvmOverloads constructor( override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets { super.onApplyWindowInsets(insets) - updatePadding(top = insets.systemBarsCompat.top) + updatePadding(top = insets.systemBarInsetsCompat.top) return insets } diff --git a/app/src/main/java/org/oxycblt/auxio/ui/EdgeRecyclerView.kt b/app/src/main/java/org/oxycblt/auxio/ui/EdgeRecyclerView.kt index 93d2f9184..8f8fc4b1d 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/EdgeRecyclerView.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/EdgeRecyclerView.kt @@ -23,7 +23,7 @@ import android.util.AttributeSet import android.view.WindowInsets import androidx.core.view.updatePadding import androidx.recyclerview.widget.RecyclerView -import org.oxycblt.auxio.util.systemBarsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat /** * A [RecyclerView] that automatically applies insets to itself. @@ -34,7 +34,7 @@ class EdgeRecyclerView @JvmOverloads constructor( defStyleAttr: Int = -1 ) : RecyclerView(context, attrs, defStyleAttr) { override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets { - updatePadding(bottom = insets.systemBarsCompat.bottom) + updatePadding(bottom = insets.systemBarInsetsCompat.bottom) return insets } } diff --git a/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt index 967fcea9c..4641ee208 100644 --- a/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt @@ -122,7 +122,7 @@ fun @receiver:AttrRes Int.resolveAttr(context: Context): Int { * Resolve window insets in a version-aware manner. This can be used to apply padding to * a view that properly follows all the frustrating changes that were made between 8-11. */ -val WindowInsets.systemBarsCompat: Rect get() { +val WindowInsets.systemBarInsetsCompat: Rect get() { return when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> { getInsets(WindowInsets.Type.systemBars()).run {