From b03279a2e2bcd66c9d9318e4da1689e9e2816c09 Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Sat, 8 Mar 2025 09:08:09 +0100 Subject: [PATCH] fix window insets related bugs (#4978) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixes the background of the ComposeActivity in table mode which looked weird since https://github.com/tuskyapp/Tusky/pull/4897 - The ComposeActivity in tablet mode will now resize when the keyboard expands, the previously used fixed height would cause the bottom bar to hide entered text on some devices, closes https://github.com/tuskyapp/Tusky/issues/4973 - The bottom sheets in the compose view will now be in fully hidden state by default, as some weirdness on some devices caused them to peek over the bottom bar in half collapsed state. Please test @fin-w - The bottom sheet in the image viewer will now expand a bit more in edge-to-edge mode so it doesn't look it is deliberately obscured by the system bar. The image also moves up a bit so it won't be covered by the bottom sheet as much. - The "Performing lookup…" bottom sheet won't be covered by the nav bar anymore --- .../com/keylesspalace/tusky/BaseActivity.kt | 38 ++++++++++--------- .../tusky/BottomSheetActivity.kt | 12 ++++++ .../components/compose/ComposeActivity.kt | 28 +++++++++----- .../tusky/fragment/ViewImageFragment.kt | 17 ++++++--- .../drawable/background_dialog_activity.xml | 12 ++++-- app/src/main/res/layout/activity_compose.xml | 26 +++++++------ .../main/res/layout/fragment_view_image.xml | 5 ++- .../res/layout/item_status_bottom_sheet.xml | 6 ++- app/src/main/res/values-large-land/dimens.xml | 2 +- app/src/main/res/values-large/dimens.xml | 2 - app/src/main/res/values-large/styles.xml | 8 +--- app/src/main/res/values/dimens.xml | 9 ++++- 12 files changed, 103 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/BaseActivity.kt b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.kt index d8d02f457..e329f8da7 100644 --- a/app/src/main/java/com/keylesspalace/tusky/BaseActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/BaseActivity.kt @@ -132,26 +132,30 @@ abstract class BaseActivity : AppCompatActivity() { override fun onPostCreate(savedInstanceState: Bundle?) { super.onPostCreate(savedInstanceState) - window.decorView.setBackgroundColor(Color.BLACK) - val contentView: View = findViewById(android.R.id.content) - contentView.setBackgroundColor(MaterialColors.getColor(contentView, android.R.attr.colorBackground)) + // currently only ComposeActivity on tablets is floating + if (!window.isFloating) { + window.decorView.setBackgroundColor(Color.BLACK) - // handle left/right insets. This is relevant for edge-to-edge mode in landscape orientation - ViewCompat.setOnApplyWindowInsetsListener(contentView) { _, insets -> - val systemBarInsets = insets.getInsets(systemBars()) - val displayCutoutInsets = insets.getInsets(displayCutout()) - // use padding for system bar insets so they get our background color and margin for cutout insets to turn them black - contentView.updatePadding(left = systemBarInsets.left, right = systemBarInsets.right) - contentView.updateLayoutParams { - leftMargin = displayCutoutInsets.left - rightMargin = displayCutoutInsets.right + val contentView: View = findViewById(android.R.id.content) + contentView.setBackgroundColor(MaterialColors.getColor(contentView, android.R.attr.colorBackground)) + + // handle left/right insets. This is relevant for edge-to-edge mode in landscape orientation + ViewCompat.setOnApplyWindowInsetsListener(contentView) { _, insets -> + val systemBarInsets = insets.getInsets(systemBars()) + val displayCutoutInsets = insets.getInsets(displayCutout()) + // use padding for system bar insets so they get our background color and margin for cutout insets to turn them black + contentView.updatePadding(left = systemBarInsets.left, right = systemBarInsets.right) + contentView.updateLayoutParams { + leftMargin = displayCutoutInsets.left + rightMargin = displayCutoutInsets.right + } + + WindowInsetsCompat.Builder(insets) + .setInsets(systemBars(), Insets.of(0, systemBarInsets.top, 0, systemBarInsets.bottom)) + .setInsets(displayCutout(), Insets.of(0, displayCutoutInsets.top, 0, displayCutoutInsets.bottom)) + .build() } - - WindowInsetsCompat.Builder(insets) - .setInsets(systemBars(), Insets.of(0, systemBarInsets.top, 0, systemBarInsets.bottom)) - .setInsets(displayCutout(), Insets.of(0, displayCutoutInsets.top, 0, displayCutoutInsets.bottom)) - .build() } } diff --git a/app/src/main/java/com/keylesspalace/tusky/BottomSheetActivity.kt b/app/src/main/java/com/keylesspalace/tusky/BottomSheetActivity.kt index 73c87cf2e..82023881b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/BottomSheetActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/BottomSheetActivity.kt @@ -22,6 +22,10 @@ import android.view.View import android.widget.LinearLayout import android.widget.Toast import androidx.annotation.VisibleForTesting +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat.Type.ime +import androidx.core.view.WindowInsetsCompat.Type.systemBars +import androidx.core.view.updatePadding import androidx.lifecycle.lifecycleScope import at.connyduck.calladapter.networkresult.fold import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -62,6 +66,14 @@ abstract class BottomSheetActivity : BaseActivity() { override fun onSlide(bottomSheet: View, slideOffset: Float) {} }) + + ViewCompat.setOnApplyWindowInsetsListener(bottomSheetLayout) { _, insets -> + val systemBarsInsets = insets.getInsets(systemBars() or ime()) + val bottomInsets = systemBarsInsets.bottom + + bottomSheetLayout.updatePadding(bottom = bottomInsets) + insets + } } open fun viewUrl( diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt index 5a3baada5..a27cae7ad 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt @@ -54,6 +54,7 @@ import androidx.core.view.WindowInsetsCompat.Type.ime import androidx.core.view.WindowInsetsCompat.Type.systemBars import androidx.core.view.isGone import androidx.core.view.isVisible +import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding import androidx.core.widget.doAfterTextChanged import androidx.core.widget.doOnTextChanged @@ -265,12 +266,14 @@ class ComposeActivity : binding.composeBottomBar.setOnWindowInsetsChangeListener { windowInsets -> val insets = windowInsets.getInsets(systemBars() or ime()) - binding.composeBottomBar.updatePadding(bottom = insets.bottom + at.connyduck.sparkbutton.helpers.Utils.dpToPx(this@ComposeActivity, 4)) - binding.addMediaBottomSheet.updatePadding(bottom = insets.bottom + at.connyduck.sparkbutton.helpers.Utils.dpToPx(this@ComposeActivity, 50)) - binding.emojiView.updatePadding(bottom = insets.bottom + at.connyduck.sparkbutton.helpers.Utils.dpToPx(this@ComposeActivity, 50)) - binding.composeOptionsBottomSheet.updatePadding(bottom = insets.bottom + at.connyduck.sparkbutton.helpers.Utils.dpToPx(this@ComposeActivity, 50)) - binding.composeScheduleView.updatePadding(bottom = insets.bottom + at.connyduck.sparkbutton.helpers.Utils.dpToPx(this@ComposeActivity, 50)) - (binding.composeMainScrollView.layoutParams as ViewGroup.MarginLayoutParams).bottomMargin = insets.bottom + at.connyduck.sparkbutton.helpers.Utils.dpToPx(this@ComposeActivity, 58) + val bottomBarHeight = resources.getDimensionPixelSize(R.dimen.compose_bottom_bar_height) + val bottomBarPadding = resources.getDimensionPixelSize(R.dimen.compose_bottom_bar_padding_vertical) + binding.composeBottomBar.updatePadding(bottom = insets.bottom + bottomBarPadding) + binding.addMediaBottomSheet.updatePadding(bottom = insets.bottom + bottomBarHeight) + binding.emojiView.updatePadding(bottom = insets.bottom + bottomBarHeight) + binding.composeOptionsBottomSheet.updatePadding(bottom = insets.bottom + bottomBarHeight) + binding.composeScheduleView.updatePadding(bottom = insets.bottom + bottomBarHeight) + binding.composeMainScrollView.updateLayoutParams { bottomMargin = insets.bottom + bottomBarHeight } } setupActionBar() @@ -610,6 +613,11 @@ class ComposeActivity : scheduleBehavior = BottomSheetBehavior.from(binding.composeScheduleView) emojiBehavior = BottomSheetBehavior.from(binding.emojiView) + composeOptionsBehavior.state = BottomSheetBehavior.STATE_HIDDEN + addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN + scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN + emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN + val bottomSheetCallback = object : BottomSheetCallback() { override fun onStateChanged(bottomSheet: View, newState: Int) { updateOnBackPressedCallbackState() @@ -1005,11 +1013,11 @@ class ComposeActivity : override fun onSlide(bottomSheet: View, slideOffset: Float) {} } ) - addMediaBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN } private fun openPollDialog() = lifecycleScope.launch { - addMediaBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN val instanceParams = viewModel.instanceInfo.first() showAddPollDialog( context = this@ComposeActivity, @@ -1058,7 +1066,7 @@ class ComposeActivity : } override fun onVisibilityChanged(visibility: Status.Visibility) { - composeOptionsBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + composeOptionsBehavior.state = BottomSheetBehavior.STATE_HIDDEN viewModel.changeStatusVisibility(visibility) } @@ -1165,7 +1173,7 @@ class ComposeActivity : } private fun initiateCameraApp() { - addMediaBehavior.state = BottomSheetBehavior.STATE_COLLAPSED + addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN val photoFile: File = try { createNewImageFile(this) diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/ViewImageFragment.kt b/app/src/main/java/com/keylesspalace/tusky/fragment/ViewImageFragment.kt index 04c17f785..6faf739c2 100644 --- a/app/src/main/java/com/keylesspalace/tusky/fragment/ViewImageFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/fragment/ViewImageFragment.kt @@ -29,6 +29,7 @@ import android.view.ViewGroup import android.widget.ImageView import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat.Type.systemBars +import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding import androidx.lifecycle.lifecycleScope import com.bumptech.glide.Glide @@ -36,6 +37,7 @@ import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.target.Target +import com.google.android.material.bottomsheet.BottomSheetBehavior import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.FragmentViewImageBinding import com.keylesspalace.tusky.entity.Attachment @@ -110,12 +112,17 @@ class ViewImageFragment : ViewMediaFragment() { } } - ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets -> - val systemBarInsets = insets.getInsets(systemBars()) - val mediaDescriptionBottomPadding = requireContext().resources.getDimensionPixelSize(R.dimen.media_description_sheet_bottom_padding) - binding.mediaDescription.updatePadding(bottom = mediaDescriptionBottomPadding + systemBarInsets.bottom) + val descriptionBottomSheet = BottomSheetBehavior.from(binding.captionSheet) - insets.inset(0, 0, 0, systemBarInsets.bottom) + ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets -> + val bottomInsets = insets.getInsets(systemBars()).bottom + val mediaDescriptionBottomPadding = requireContext().resources.getDimensionPixelSize(R.dimen.media_description_sheet_bottom_padding) + val mediaDescriptionPeekHeight = requireContext().resources.getDimensionPixelSize(R.dimen.media_description_sheet_peek_height) + val imageViewBottomMargin = requireContext().resources.getDimensionPixelSize(R.dimen.media_image_view_bottom_margin) + binding.mediaDescription.updatePadding(bottom = mediaDescriptionBottomPadding + bottomInsets) + descriptionBottomSheet.setPeekHeight(mediaDescriptionPeekHeight + bottomInsets, false) + binding.photoView.updateLayoutParams { bottomMargin = imageViewBottomMargin + bottomInsets } + insets.inset(0, 0, 0, bottomInsets) } val singleTapDetector = GestureDetector( diff --git a/app/src/main/res/drawable/background_dialog_activity.xml b/app/src/main/res/drawable/background_dialog_activity.xml index 7af1b9869..732502d4e 100644 --- a/app/src/main/res/drawable/background_dialog_activity.xml +++ b/app/src/main/res/drawable/background_dialog_activity.xml @@ -1,5 +1,9 @@ - - - - + + + + + + diff --git a/app/src/main/res/layout/activity_compose.xml b/app/src/main/res/layout/activity_compose.xml index 77ec47fa4..c3cfc3e1f 100644 --- a/app/src/main/res/layout/activity_compose.xml +++ b/app/src/main/res/layout/activity_compose.xml @@ -82,10 +82,11 @@ @@ -242,6 +245,7 @@ android:padding="8dp" android:text="@string/action_add_poll" android:textSize="?attr/status_text_medium" /> + @@ -267,7 +271,7 @@ android:paddingStart="24dp" android:paddingTop="12dp" android:paddingEnd="24dp" - android:paddingBottom="60dp" + android:paddingBottom="@dimen/compose_bottom_bar_height" app:behavior_hideable="true" app:behavior_peekHeight="0dp" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" /> @@ -281,7 +285,7 @@ android:paddingStart="16dp" android:paddingTop="8dp" android:paddingEnd="16dp" - android:paddingBottom="52dp" + android:paddingBottom="@dimen/compose_bottom_bar_height" app:behavior_hideable="true" app:behavior_peekHeight="0dp" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" /> @@ -291,15 +295,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" - android:animateLayoutChanges="true" android:background="?attr/colorSurface" android:elevation="12dp" android:gravity="center_vertical" - android:paddingStart="8dp" - android:paddingTop="4dp" - android:paddingEnd="8dp" - android:paddingBottom="4dp" - app:layout_insetEdge="bottom"> + android:paddingStart="@dimen/compose_bottom_bar_padding_horizontal" + android:paddingTop="@dimen/compose_bottom_bar_padding_vertical" + android:paddingEnd="@dimen/compose_bottom_bar_padding_horizontal" + android:paddingBottom="@dimen/compose_bottom_bar_padding_vertical"> + android:layout_height="match_parent" + android:layout_marginBottom="@dimen/media_image_view_bottom_margin"/> - \ No newline at end of file + + diff --git a/app/src/main/res/values-large-land/dimens.xml b/app/src/main/res/values-large-land/dimens.xml index 8a9db25eb..217a26538 100644 --- a/app/src/main/res/values-large-land/dimens.xml +++ b/app/src/main/res/values-large-land/dimens.xml @@ -1,3 +1,3 @@ - 180dp + 16dp diff --git a/app/src/main/res/values-large/dimens.xml b/app/src/main/res/values-large/dimens.xml index 046974e0d..e9a8f4873 100644 --- a/app/src/main/res/values-large/dimens.xml +++ b/app/src/main/res/values-large/dimens.xml @@ -1,6 +1,4 @@ - 400dp - 160dp 180dp diff --git a/app/src/main/res/values-large/styles.xml b/app/src/main/res/values-large/styles.xml index 8d05f273d..e536b2a95 100644 --- a/app/src/main/res/values-large/styles.xml +++ b/app/src/main/res/values-large/styles.xml @@ -4,11 +4,9 @@ @drawable/background_dialog_activity true @null - stateUnspecified|adjustPan + stateAlwaysVisible|adjustResize false true - 80% - 80% diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index de283e30f..6be5fe36d 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -21,7 +21,6 @@ 200dp 100dp - -1px -1px -2 @@ -83,6 +82,8 @@ 24dp 8dp + 90dp + 24dp 64dp @@ -94,4 +95,10 @@ 6dp 38dp + 56dp + 4dp + 8dp + + 64dp +