From d5e994d8d3d936589dc9c9c39298b32ee12471fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 1 Jan 2026 12:09:20 +0000 Subject: [PATCH 1/8] Initial plan From 84bea44f2c0603d7afafeac9a7737b9e08149e59 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 1 Jan 2026 12:13:37 +0000 Subject: [PATCH 2/8] Fix: Remove software layer from RecyclerView to prevent memory overflow on foldables Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com> --- .../java/org/thoughtcrime/securesms/ConversationFragment.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java index ecd0b8d34..30a032143 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java @@ -150,10 +150,6 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, this::handleReplyMessage ).attachToRecyclerView(list); - // setLayerType() is needed to allow larger items (long texts in our case) - // with hardware layers, drawing may result in errors as "OpenGLRenderer: Path too large to be rendered into a texture" - list.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - return view; } From 9c678db7cbdbd39e55110ba907e841c1650787f5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 16:03:44 +0000 Subject: [PATCH 3/8] Add conditional software layer based on screen size with proper documentation Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com> --- .../securesms/ConversationFragment.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java index 30a032143..a98b71a45 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java @@ -150,6 +150,25 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, this::handleReplyMessage ).attachToRecyclerView(list); + // Conditionally apply software layer only on smaller screens to avoid memory overflow on foldables. + // Background: Setting LAYER_TYPE_SOFTWARE was added to fix "OpenGL: Path too large to be rendered + // into a texture" errors when rendering long text messages with hardware acceleration. + // However, software layers have fixed memory limits (~11MB) that are exceeded on devices with + // large screens (foldables need ~18MB+), causing RecyclerView not to display. + // + // Solution: Only apply software layer on screens smaller than 1200dp width (typical foldable threshold). + // On foldables and tablets, use default rendering (LAYER_TYPE_NONE) which leverages RecyclerView's + // efficient view recycling to avoid memory issues. + // + // References: + // - RecyclerView design: https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView + // - Layer types: https://developer.android.com/reference/android/view/View#setLayerType(int,%20android.graphics.Paint) + // - Foldable best practices: https://developer.android.com/guide/topics/large-screens/learn-about-foldables + int screenWidthDp = getResources().getConfiguration().screenWidthDp; + if (screenWidthDp < 1200) { + list.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + } + return view; } From 6d4f5bc2ca7e0849eb9b3d0bd3ce92891cf21983 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 16:05:08 +0000 Subject: [PATCH 4/8] Extract magic number to named constant for better code quality Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com> --- .../org/thoughtcrime/securesms/ConversationFragment.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java index a98b71a45..e079caf23 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java @@ -82,6 +82,10 @@ public class ConversationFragment extends MessageSelectorFragment private static final int SCROLL_ANIMATION_THRESHOLD = 50; private static final int CODE_ADD_EDIT_CONTACT = 77; + + // Screen width threshold (in dp) for applying software layer. + // Foldable devices typically have inner screens >= 1200dp width. + private static final int FOLDABLE_SCREEN_WIDTH_THRESHOLD_DP = 1200; private final ActionModeCallback actionModeCallback = new ActionModeCallback(); private final ItemClickListener selectionClickListener = new ConversationFragmentItemClickListener(); @@ -165,7 +169,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, // - Layer types: https://developer.android.com/reference/android/view/View#setLayerType(int,%20android.graphics.Paint) // - Foldable best practices: https://developer.android.com/guide/topics/large-screens/learn-about-foldables int screenWidthDp = getResources().getConfiguration().screenWidthDp; - if (screenWidthDp < 1200) { + if (screenWidthDp < FOLDABLE_SCREEN_WIDTH_THRESHOLD_DP) { list.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } From 6b42987c9a9b51e4ff8a9cd360006cfb29742962 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 16:36:45 +0000 Subject: [PATCH 5/8] Limit message bubble width on large screens to prevent software layer overflow Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com> --- .../securesms/ConversationFragment.java | 25 +++---------------- .../res/layout/conversation_item_received.xml | 1 + .../res/layout/conversation_item_sent.xml | 1 + src/main/res/values-sw600dp/dimens.xml | 5 ++++ src/main/res/values/dimens.xml | 1 + 5 files changed, 11 insertions(+), 22 deletions(-) create mode 100644 src/main/res/values-sw600dp/dimens.xml diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java index e079caf23..ecd0b8d34 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java @@ -82,10 +82,6 @@ public class ConversationFragment extends MessageSelectorFragment private static final int SCROLL_ANIMATION_THRESHOLD = 50; private static final int CODE_ADD_EDIT_CONTACT = 77; - - // Screen width threshold (in dp) for applying software layer. - // Foldable devices typically have inner screens >= 1200dp width. - private static final int FOLDABLE_SCREEN_WIDTH_THRESHOLD_DP = 1200; private final ActionModeCallback actionModeCallback = new ActionModeCallback(); private final ItemClickListener selectionClickListener = new ConversationFragmentItemClickListener(); @@ -154,24 +150,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, this::handleReplyMessage ).attachToRecyclerView(list); - // Conditionally apply software layer only on smaller screens to avoid memory overflow on foldables. - // Background: Setting LAYER_TYPE_SOFTWARE was added to fix "OpenGL: Path too large to be rendered - // into a texture" errors when rendering long text messages with hardware acceleration. - // However, software layers have fixed memory limits (~11MB) that are exceeded on devices with - // large screens (foldables need ~18MB+), causing RecyclerView not to display. - // - // Solution: Only apply software layer on screens smaller than 1200dp width (typical foldable threshold). - // On foldables and tablets, use default rendering (LAYER_TYPE_NONE) which leverages RecyclerView's - // efficient view recycling to avoid memory issues. - // - // References: - // - RecyclerView design: https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView - // - Layer types: https://developer.android.com/reference/android/view/View#setLayerType(int,%20android.graphics.Paint) - // - Foldable best practices: https://developer.android.com/guide/topics/large-screens/learn-about-foldables - int screenWidthDp = getResources().getConfiguration().screenWidthDp; - if (screenWidthDp < FOLDABLE_SCREEN_WIDTH_THRESHOLD_DP) { - list.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - } + // setLayerType() is needed to allow larger items (long texts in our case) + // with hardware layers, drawing may result in errors as "OpenGLRenderer: Path too large to be rendered into a texture" + list.setLayerType(View.LAYER_TYPE_SOFTWARE, null); return view; } diff --git a/src/main/res/layout/conversation_item_received.xml b/src/main/res/layout/conversation_item_received.xml index 2e3e5d2a9..bab5fe073 100644 --- a/src/main/res/layout/conversation_item_received.xml +++ b/src/main/res/layout/conversation_item_received.xml @@ -69,6 +69,7 @@ android:id="@+id/body_bubble" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:maxWidth="@dimen/message_bubble_max_width" android:layout_marginRight="@dimen/message_bubble_edge_margin" android:layout_marginEnd="@dimen/message_bubble_edge_margin" android:layout_marginLeft="6dp" diff --git a/src/main/res/layout/conversation_item_sent.xml b/src/main/res/layout/conversation_item_sent.xml index 5b165fbd2..9865b9b9a 100644 --- a/src/main/res/layout/conversation_item_sent.xml +++ b/src/main/res/layout/conversation_item_sent.xml @@ -52,6 +52,7 @@ android:id="@+id/body_bubble" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:maxWidth="@dimen/message_bubble_max_width" android:orientation="vertical" android:layout_toLeftOf="@+id/indicators_parent" android:layout_toStartOf="@+id/indicators_parent" diff --git a/src/main/res/values-sw600dp/dimens.xml b/src/main/res/values-sw600dp/dimens.xml new file mode 100644 index 000000000..5d8fe85c2 --- /dev/null +++ b/src/main/res/values-sw600dp/dimens.xml @@ -0,0 +1,5 @@ + + + + 600dp + diff --git a/src/main/res/values/dimens.xml b/src/main/res/values/dimens.xml index 1d16f6c72..9da808ea8 100644 --- a/src/main/res/values/dimens.xml +++ b/src/main/res/values/dimens.xml @@ -23,6 +23,7 @@ 32dp 6dp 8dp + 512dp 2dp 24dp 24dp From 9bcc241445a2af0c49181f70012ca57190e3cb8d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 16:38:46 +0000 Subject: [PATCH 6/8] Update comments to explain software layer and bubble width constraint relationship Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com> --- .../java/org/thoughtcrime/securesms/ConversationFragment.java | 2 ++ src/main/res/values-sw600dp/dimens.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java index ecd0b8d34..55430c4fe 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationFragment.java @@ -152,6 +152,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, // setLayerType() is needed to allow larger items (long texts in our case) // with hardware layers, drawing may result in errors as "OpenGLRenderer: Path too large to be rendered into a texture" + // On foldable devices with large screens, software layer can exceed memory limits (~11MB). + // To prevent this, message bubble width is constrained via maxWidth in layout files. list.setLayerType(View.LAYER_TYPE_SOFTWARE, null); return view; diff --git a/src/main/res/values-sw600dp/dimens.xml b/src/main/res/values-sw600dp/dimens.xml index 5d8fe85c2..adc1dd339 100644 --- a/src/main/res/values-sw600dp/dimens.xml +++ b/src/main/res/values-sw600dp/dimens.xml @@ -1,5 +1,5 @@ - + 600dp From 07d6d8e81d65ba60664c6008eb7a6bf62b73cb4d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 17:46:03 +0000 Subject: [PATCH 7/8] Wrap body_bubble in FrameLayout to make maxWidth work with RelativeLayout constraints Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com> --- .../res/layout/conversation_item_received.xml | 29 ++++++++++++------- .../res/layout/conversation_item_sent.xml | 29 ++++++++++++------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/main/res/layout/conversation_item_received.xml b/src/main/res/layout/conversation_item_received.xml index bab5fe073..55946f519 100644 --- a/src/main/res/layout/conversation_item_received.xml +++ b/src/main/res/layout/conversation_item_received.xml @@ -38,13 +38,13 @@ android:id="@+id/reply_icon" android:layout_width="20dp" android:layout_height="20dp" - android:layout_alignStart="@id/body_bubble" - android:layout_alignTop="@id/body_bubble" - android:layout_alignBottom="@id/body_bubble" + android:layout_alignStart="@id/body_bubble_wrapper" + android:layout_alignTop="@id/body_bubble_wrapper" + android:layout_alignBottom="@id/body_bubble_wrapper" android:alpha="0" app:srcCompat="?menu_reply_icon" android:tint="?icon_tint" - android:layout_alignLeft="@id/body_bubble" /> + android:layout_alignLeft="@id/body_bubble_wrapper" /> + android:layout_alignBottom="@id/body_bubble_wrapper"> - + + + + diff --git a/src/main/res/layout/conversation_item_sent.xml b/src/main/res/layout/conversation_item_sent.xml index 9865b9b9a..65a7c5629 100644 --- a/src/main/res/layout/conversation_item_sent.xml +++ b/src/main/res/layout/conversation_item_sent.xml @@ -40,25 +40,30 @@ android:id="@+id/reply_icon" android:layout_width="20dp" android:layout_height="20dp" - android:layout_alignStart="@id/body_bubble" - android:layout_alignTop="@id/body_bubble" - android:layout_alignBottom="@id/body_bubble" + android:layout_alignStart="@id/body_bubble_wrapper" + android:layout_alignTop="@id/body_bubble_wrapper" + android:layout_alignBottom="@id/body_bubble_wrapper" android:alpha="0" app:srcCompat="?menu_reply_icon" android:tint="?icon_tint" - android:layout_alignLeft="@id/body_bubble" /> + android:layout_alignLeft="@id/body_bubble_wrapper" /> - + + + + From c60c8a7937f74d8cff8e73c896988c746dc1e748 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 18:03:47 +0000 Subject: [PATCH 8/8] Apply maxWidth to content views instead of container to properly limit bubble width Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com> --- src/main/res/layout/conversation_item_received.xml | 3 ++- src/main/res/layout/conversation_item_sent.xml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/res/layout/conversation_item_received.xml b/src/main/res/layout/conversation_item_received.xml index 55946f519..0046b44dc 100644 --- a/src/main/res/layout/conversation_item_received.xml +++ b/src/main/res/layout/conversation_item_received.xml @@ -80,7 +80,6 @@ android:id="@+id/body_bubble" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:maxWidth="@dimen/message_bubble_max_width" android:orientation="vertical" android:clipToPadding="false" android:clipChildren="false" @@ -118,6 +117,7 @@ android:id="@+id/quote_view" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:maxWidth="@dimen/message_bubble_max_width" android:layout_marginTop="@dimen/message_bubble_top_padding" android:layout_marginStart="6dp" android:layout_marginEnd="6dp" @@ -192,6 +192,7 @@ android:id="@+id/conversation_item_body" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:maxWidth="@dimen/message_bubble_max_width" android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding" android:layout_marginLeft="@dimen/message_bubble_horizontal_padding" android:layout_marginRight="@dimen/message_bubble_horizontal_padding" diff --git a/src/main/res/layout/conversation_item_sent.xml b/src/main/res/layout/conversation_item_sent.xml index 65a7c5629..38044fd7d 100644 --- a/src/main/res/layout/conversation_item_sent.xml +++ b/src/main/res/layout/conversation_item_sent.xml @@ -62,7 +62,6 @@ android:id="@+id/body_bubble" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:maxWidth="@dimen/message_bubble_max_width" android:orientation="vertical" android:clipToPadding="false" android:clipChildren="false" @@ -100,6 +99,7 @@ android:id="@+id/quote_view" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:maxWidth="@dimen/message_bubble_max_width" android:layout_marginTop="@dimen/message_bubble_top_padding" android:layout_marginStart="6dp" android:layout_marginEnd="6dp" @@ -174,6 +174,7 @@ android:id="@+id/conversation_item_body" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:maxWidth="@dimen/message_bubble_max_width" android:layout_marginLeft="@dimen/message_bubble_horizontal_padding" android:layout_marginRight="@dimen/message_bubble_horizontal_padding" android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"