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"