From f218f703eefc65f366c7efc6c057f92c7c0c06e0 Mon Sep 17 00:00:00 2001 From: Luke Wass Date: Thu, 2 Apr 2026 15:42:53 -0500 Subject: [PATCH 1/2] fix: skip non-user-facing alarm sources in AlarmWidget getNextAlarmClock() returns the next AlarmClockInfo alarm from any app, not just the Clock app. Background system processes can set alarm clock alarms that fire before the user's actual Clock alarm. Check the alarm's showIntent.creatorPackage against PackageManager to verify it belongs to a user-facing app (has a launcher icon); if not, display "No alarm". --- .../widgets/widget/AlarmWidgetReceiver.kt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/wassupluke/widgets/widget/AlarmWidgetReceiver.kt b/app/src/main/java/com/wassupluke/widgets/widget/AlarmWidgetReceiver.kt index ed7f302..9ca7767 100644 --- a/app/src/main/java/com/wassupluke/widgets/widget/AlarmWidgetReceiver.kt +++ b/app/src/main/java/com/wassupluke/widgets/widget/AlarmWidgetReceiver.kt @@ -4,6 +4,7 @@ import android.app.AlarmManager import android.appwidget.AppWidgetManager import android.content.Context import android.content.Intent +import android.content.pm.PackageManager import androidx.datastore.preferences.core.edit import androidx.glance.appwidget.GlanceAppWidget import androidx.glance.appwidget.GlanceAppWidgetReceiver @@ -42,7 +43,13 @@ class AlarmWidgetReceiver : GlanceAppWidgetReceiver() { val alarmText = if (nextAlarm == null) { context.getString(R.string.widget_alarm_none) } else { - DateFormat.getTimeInstance(DateFormat.SHORT).format(Date(nextAlarm.triggerTime)) + val creator = nextAlarm.showIntent?.creatorPackage + val fromClockApp = creator != null && isUserFacingApp(context, creator) + if (fromClockApp) { + DateFormat.getTimeInstance(DateFormat.SHORT).format(Date(nextAlarm.triggerTime)) + } else { + context.getString(R.string.widget_alarm_none) + } } context.dataStore.edit { it[WeatherDataStore.ALARM_TEXT] = alarmText } AlarmWidget().updateAll(context) @@ -51,4 +58,12 @@ class AlarmWidgetReceiver : GlanceAppWidgetReceiver() { } } } + + private fun isUserFacingApp(context: Context, packageName: String): Boolean { + val intent = Intent(Intent.ACTION_MAIN).apply { + addCategory(Intent.CATEGORY_LAUNCHER) + setPackage(packageName) + } + return context.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).isNotEmpty() + } } From 7d460b1ea468dd777e4961a6235719b344afcb55 Mon Sep 17 00:00:00 2001 From: Luke Wass Date: Thu, 2 Apr 2026 16:34:15 -0500 Subject: [PATCH 2/2] fix: move clickable to content element to fix Glance layout ID collision Both widgets sharing a Box > Box(clickable) > Content structure caused Glance to assign the same layout resource ID to both widgets, making one display the other's content. Move .clickable() directly onto the content element (Text for WeatherWidget, Row for AlarmWidget) so their composable trees are structurally distinct. Also narrows the tap target to the content only. --- .../wassupluke/widgets/widget/AlarmWidget.kt | 35 ++++++++++--------- .../widgets/widget/WeatherWidget.kt | 17 +++++---- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/wassupluke/widgets/widget/AlarmWidget.kt b/app/src/main/java/com/wassupluke/widgets/widget/AlarmWidget.kt index e47f508..960eef0 100644 --- a/app/src/main/java/com/wassupluke/widgets/widget/AlarmWidget.kt +++ b/app/src/main/java/com/wassupluke/widgets/widget/AlarmWidget.kt @@ -83,24 +83,25 @@ private fun AlarmWidgetContent( modifier = GlanceModifier.fillMaxSize(), contentAlignment = Alignment.Center ) { - Box(modifier = GlanceModifier.clickable(tapAction)) { - Row(verticalAlignment = Alignment.CenterVertically) { - Image( - provider = ImageProvider(R.drawable.ic_alarm), - contentDescription = null, - modifier = GlanceModifier.size(fontSize.dp), - colorFilter = ColorFilter.tint(textColorProvider) + Row( + modifier = GlanceModifier.clickable(tapAction), + verticalAlignment = Alignment.CenterVertically + ) { + Image( + provider = ImageProvider(R.drawable.ic_alarm), + contentDescription = null, + modifier = GlanceModifier.size(fontSize.dp), + colorFilter = ColorFilter.tint(textColorProvider) + ) + Spacer(GlanceModifier.width(4.dp)) + Text( + text = alarmText, + style = TextStyle( + fontSize = fontSize.sp, + fontWeight = FontWeight.Normal, + color = textColorProvider ) - Spacer(GlanceModifier.width(4.dp)) - Text( - text = alarmText, - style = TextStyle( - fontSize = fontSize.sp, - fontWeight = FontWeight.Normal, - color = textColorProvider - ) - ) - } + ) } } } diff --git a/app/src/main/java/com/wassupluke/widgets/widget/WeatherWidget.kt b/app/src/main/java/com/wassupluke/widgets/widget/WeatherWidget.kt index 19f4f01..9e38435 100644 --- a/app/src/main/java/com/wassupluke/widgets/widget/WeatherWidget.kt +++ b/app/src/main/java/com/wassupluke/widgets/widget/WeatherWidget.kt @@ -90,15 +90,14 @@ private fun WeatherWidgetContent( modifier = GlanceModifier.fillMaxSize(), contentAlignment = Alignment.Center ) { - Box(modifier = GlanceModifier.clickable(tapAction)) { - Text( - text = displayTemp, - style = TextStyle( - fontSize = fontSize.sp, - fontWeight = FontWeight.Normal, - color = textColorProvider - ) + Text( + text = displayTemp, + modifier = GlanceModifier.clickable(tapAction), + style = TextStyle( + fontSize = fontSize.sp, + fontWeight = FontWeight.Normal, + color = textColorProvider ) - } + ) } }