Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,9 @@ class SettingsRepository(
const val KEY_PIXEL_SEARCH_RESULT_FILES = "pixel_search_result_files"
const val KEY_PIXEL_SEARCH_BUBBLES_WEB = "pixel_search_bubbles_web"
const val KEY_PIXEL_SEARCH_ENGINE = "pixel_search_engine"
const val KEY_PIXEL_SEARCH_BLUR = "pixel_search_blur_enabled"
const val KEY_PIXEL_SEARCH_WALLPAPER_BG = "pixel_search_wallpaper_bg"
const val KEY_PIXEL_SEARCH_BLUR_RADIUS = "pixel_search_blur_radius"
const val KEY_AUTO_ACCESSIBILITY_ENABLED = "auto_accessibility_enabled"
const val KEY_USE_BLUR = "use_blur"
const val KEY_USE_RIPPLE = "use_ripple"
Expand Down Expand Up @@ -3702,6 +3705,15 @@ class SettingsRepository(
fun getPixelSearchEngine(): String = getString(KEY_PIXEL_SEARCH_ENGINE, "Google") ?: "Google"
fun setPixelSearchEngine(engine: String) = putString(KEY_PIXEL_SEARCH_ENGINE, engine)

fun isPixelSearchBlurEnabled(): Boolean = getBoolean(KEY_PIXEL_SEARCH_BLUR, true)
fun setPixelSearchBlurEnabled(enabled: Boolean) = putBoolean(KEY_PIXEL_SEARCH_BLUR, enabled)

fun isPixelSearchWallpaperBackgroundEnabled(): Boolean = getBoolean(KEY_PIXEL_SEARCH_WALLPAPER_BG, true)
fun setPixelSearchWallpaperBackgroundEnabled(enabled: Boolean) = putBoolean(KEY_PIXEL_SEARCH_WALLPAPER_BG, enabled)

fun getPixelSearchBlurRadius(): Float = getFloat(KEY_PIXEL_SEARCH_BLUR_RADIUS, 60f)
fun setPixelSearchBlurRadius(radius: Float) = putFloat(KEY_PIXEL_SEARCH_BLUR_RADIUS, radius)

fun isBubbleWebFullscreen(): Boolean = getBoolean(KEY_BUBBLE_WEB_FULLSCREEN, false)
fun setBubbleWebFullscreen(fullscreen: Boolean) = putBoolean(KEY_BUBBLE_WEB_FULLSCREEN, fullscreen)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.graphics.PixelFormat
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Bundle
import android.provider.ContactsContract
Expand Down Expand Up @@ -155,6 +157,8 @@ class PixelSearchResultsActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
window.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
window.setFormat(PixelFormat.TRANSLUCENT)
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.auto(
android.graphics.Color.TRANSPARENT,
Expand All @@ -170,18 +174,7 @@ class PixelSearchResultsActivity : ComponentActivity() {
window.isNavigationBarContrastEnforced = false
}

val isSystemDark = (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_NIGHT_MASK) == android.content.res.Configuration.UI_MODE_NIGHT_YES
val dimAmount = if (isSystemDark) 0.2f else 0.08f

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
window.addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND)
window.attributes.blurBehindRadius = 60
window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
window.setDimAmount(dimAmount)
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
window.setDimAmount(if (isSystemDark) 0.35f else 0.15f)
}
applyBlur()

val initialQuery = intent.getStringExtra(SearchManager.QUERY)
?: intent.getStringExtra("query")
Expand All @@ -200,9 +193,48 @@ class PixelSearchResultsActivity : ComponentActivity() {
}
}

override fun onResume() {
super.onResume()
applyBlur()
}

override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
applyBlur()
}

private fun applyBlur() {
val isSystemDark = (resources.configuration.uiMode and android.content.res.Configuration.UI_MODE_NIGHT_MASK) == android.content.res.Configuration.UI_MODE_NIGHT_YES
val dimAmount = if (isSystemDark) 0.2f else 0.08f

val repository = SettingsRepository(this)
val isBlurEnabled = repository.isPixelSearchBlurEnabled()
val isWallpaperBg = repository.isPixelSearchWallpaperBackgroundEnabled()
val blurRadius = repository.getPixelSearchBlurRadius().toInt().coerceIn(1, 300)

if (isWallpaperBg) {
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER)
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER)
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val params = window.attributes
if (isBlurEnabled) {
window.addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND)
params.blurBehindRadius = blurRadius
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND)
params.blurBehindRadius = 0
}
window.attributes = params
window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
window.setDimAmount(dimAmount)
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
window.setDimAmount(if (isSystemDark) 0.35f else 0.15f)
}
}
}

Expand Down Expand Up @@ -637,7 +669,21 @@ fun PixelSearchResultsScreen(
}
}

val scrimColor = MaterialTheme.colorScheme.surfaceContainer.copy(alpha = 0.55f)
val isWallpaperBg = remember { repository.isPixelSearchWallpaperBackgroundEnabled() }
val isBlurEffective = remember(context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val windowManager = context.getSystemService(WindowManager::class.java)
repository.isPixelSearchBlurEnabled() && (windowManager?.isCrossWindowBlurEnabled == true)
} else {
false
}
}
val scrimAlpha = when {
!isBlurEffective -> 0.85f
!isWallpaperBg -> 0.45f
else -> 0.55f
}
val scrimColor = MaterialTheme.colorScheme.surfaceContainer.copy(alpha = scrimAlpha)

Box(
modifier = Modifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import com.sameerasw.essentials.ui.core.containers.RoundedCardContainer
import com.sameerasw.essentials.ui.core.pickers.SegmentedPicker
import com.sameerasw.essentials.ui.core.sheets.FeatureHelpBottomSheet
import com.sameerasw.essentials.ui.core.sheets.PermissionsBottomSheet
import com.sameerasw.essentials.ui.core.sheets.PixelSearchBlurOptionsBottomSheet
import com.sameerasw.essentials.ui.modifiers.BlurDirection
import com.sameerasw.essentials.ui.modifiers.progressiveBlur
import com.sameerasw.essentials.ui.modifiers.scrollMotionBlur
Expand Down Expand Up @@ -324,6 +325,7 @@ fun PixelSearchbarSettingsUI(
var pendingWidgetId by remember { mutableStateOf(AppWidgetManager.INVALID_APPWIDGET_ID) }
var showWidgetPicker by remember { mutableStateOf(false) }
var isWidgetUnsupported by remember { mutableStateOf(false) }
var showBlurOptionsSheet by remember { mutableStateOf(false) }

LaunchedEffect(currentType) {
while (currentType == "widget") {
Expand Down Expand Up @@ -988,11 +990,33 @@ fun PixelSearchbarSettingsUI(
}
}
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val blurEnabled = viewModel.pixelSearchBlur.value
IconToggleItem(
iconRes = R.drawable.rounded_blur_on_24,
title = stringResource(R.string.pref_pixel_search_blur_title),
description = stringResource(R.string.pref_pixel_search_blur_desc),
isChecked = blurEnabled,
onCheckedChange = { checked ->
HapticUtil.performVirtualKeyHaptic(view)
viewModel.setPixelSearchBlurEnabled(checked)
},
onSettingsClick = { showBlurOptionsSheet = true },
)
}
}
}
}
}

if (showBlurOptionsSheet) {
PixelSearchBlurOptionsBottomSheet(
viewModel = viewModel,
onDismissRequest = { showBlurOptionsSheet = false },
)
}

if (showPermissionSheet) {
val permissionItem =
remember(context, viewModel) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2026 sameerasw.com
* License: MIT License
*
* Feature Module: UI Core Sheets
* File: PixelSearchBlurOptionsBottomSheet.kt
* Description: Bottom sheet for configuring Pixel Search blur and wallpaper background options.
*/

package com.sameerasw.essentials.ui.core.sheets

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.sameerasw.essentials.R
import com.sameerasw.essentials.ui.components.sliders.ConfigSliderItem
import com.sameerasw.essentials.ui.core.cards.IconToggleItem
import com.sameerasw.essentials.ui.core.containers.RoundedCardContainer
import com.sameerasw.essentials.utils.HapticUtil
import com.sameerasw.essentials.viewmodels.MainViewModel

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PixelSearchBlurOptionsBottomSheet(
viewModel: MainViewModel,
onDismissRequest: () -> Unit,
) {
val view = LocalView.current

EssentialsBottomSheet(onDismissRequest = onDismissRequest) {
Column(
modifier =
Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.padding(bottom = 24.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Text(
text = stringResource(R.string.pixel_search_blur_options_title),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.padding(start = 8.dp, bottom = 4.dp),
)

RoundedCardContainer(spacing = 2.dp, cornerRadius = 24.dp) {
IconToggleItem(
iconRes = R.drawable.rounded_wallpaper_24,
title = stringResource(R.string.pref_pixel_search_wallpaper_bg_title),
isChecked = viewModel.pixelSearchWallpaperBackground.value,
onCheckedChange = { checked ->
HapticUtil.performVirtualKeyHaptic(view)
viewModel.setPixelSearchWallpaperBackgroundEnabled(checked)
},
)

ConfigSliderItem(
title = stringResource(R.string.pref_pixel_search_blur_intensity_title),
value = viewModel.pixelSearchBlurRadius.floatValue,
onValueChange = {
HapticUtil.performUIHaptic(view)
viewModel.setPixelSearchBlurRadius(it)
},
valueRange = 10f..150f,
increment = 5f,
iconRes = R.drawable.rounded_blur_on_24,
valueFormatter = { "${it.toInt()} dp" },
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ fun UnsupportedFeaturesConfirmationSheet(
)

RoundedCardContainer(
modifier = Modifier.fillMaxWidth(),
modifier =
Modifier
.fillMaxWidth()
.weight(1f, fill = false),
) {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2890,6 +2890,9 @@ class MainViewModel : ViewModel() {
pixelSearchResultShortcuts.value = settingsRepository.isPixelSearchResultShortcutsEnabled()
pixelSearchResultWeb.value = settingsRepository.isPixelSearchResultWebEnabled()
pixelSearchBubblesWeb.value = settingsRepository.isPixelSearchBubblesWebEnabled()
pixelSearchBlur.value = settingsRepository.isPixelSearchBlurEnabled()
pixelSearchWallpaperBackground.value = settingsRepository.isPixelSearchWallpaperBackgroundEnabled()
pixelSearchBlurRadius.floatValue = settingsRepository.getPixelSearchBlurRadius()
pixelSearchEngine.value = settingsRepository.getPixelSearchEngine()
isPocketModeEnabled.value =
settingsRepository.getBoolean(SettingsRepository.KEY_POCKET_MODE_ENABLED)
Expand Down Expand Up @@ -4682,6 +4685,9 @@ class MainViewModel : ViewModel() {
val pixelSearchResultShortcuts = mutableStateOf(true)
val pixelSearchResultWeb = mutableStateOf(true)
val pixelSearchBubblesWeb = mutableStateOf(false)
val pixelSearchBlur = mutableStateOf(true)
val pixelSearchWallpaperBackground = mutableStateOf(true)
val pixelSearchBlurRadius = mutableFloatStateOf(60f)
val pixelSearchEngine = mutableStateOf("Google")

fun setPixelSearchResultAppsEnabled(enabled: Boolean) {
Expand Down Expand Up @@ -4724,6 +4730,21 @@ class MainViewModel : ViewModel() {
settingsRepository.setPixelSearchBubblesWebEnabled(enabled)
}

fun setPixelSearchBlurEnabled(enabled: Boolean) {
pixelSearchBlur.value = enabled
settingsRepository.setPixelSearchBlurEnabled(enabled)
}

fun setPixelSearchWallpaperBackgroundEnabled(enabled: Boolean) {
pixelSearchWallpaperBackground.value = enabled
settingsRepository.setPixelSearchWallpaperBackgroundEnabled(enabled)
}

fun setPixelSearchBlurRadius(radius: Float) {
pixelSearchBlurRadius.floatValue = radius
settingsRepository.setPixelSearchBlurRadius(radius)
}

fun setPixelSearchEngine(engine: String) {
pixelSearchEngine.value = engine
settingsRepository.setPixelSearchEngine(engine)
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2666,6 +2666,11 @@
<string name="pixel_searchbar_tap_action_enabled">Custom tap action</string>
<string name="pixel_searchbar_tap_action_enabled_desc">Use DIY tap action instead of widget\'s own</string>
<string name="pixel_searchbar_style_music">Music</string>
<string name="pref_pixel_search_blur_title">Blur</string>
<string name="pref_pixel_search_blur_desc">Blur the background of search results</string>
<string name="pixel_search_blur_options_title">Blur options</string>
<string name="pref_pixel_search_wallpaper_bg_title">Show wallpaper in background</string>
<string name="pref_pixel_search_blur_intensity_title">Blur intensity</string>
<string name="action_restart_shizuku">Restart Shizuku</string>
<string name="toast_enter_shizuku_token">Please enter Shizuku auth token in settings first</string>

Expand Down
1 change: 0 additions & 1 deletion app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowShowWallpaper">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
Expand Down
Loading