diff --git a/lawnchair/res/layout/search_container_hotseat_google_search.xml b/lawnchair/res/layout/search_container_hotseat_google_search.xml
new file mode 100644
index 0000000000..bd0ed39960
--- /dev/null
+++ b/lawnchair/res/layout/search_container_hotseat_google_search.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/lawnchair/res/values/config.xml b/lawnchair/res/values/config.xml
index d767bbcc51..d7be9695aa 100644
--- a/lawnchair/res/values/config.xml
+++ b/lawnchair/res/values/config.xml
@@ -81,9 +81,11 @@
system
+
+ lawnchair
+
true
false
- true
false
true
false
diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml
index dbef74ec86..8f3e13cc7c 100644
--- a/lawnchair/res/values/strings.xml
+++ b/lawnchair/res/values/strings.xml
@@ -280,8 +280,11 @@
- Search Bar
- Show Search Bar
+ Search Bar Widget
+ Disabled
+ Lawnchair
+ Google Search Bar
+ Search Bar
Corner Radius
Apply Accent Color
Search Provider
diff --git a/lawnchair/src/app/lawnchair/hotseat/HotseatMode.kt b/lawnchair/src/app/lawnchair/hotseat/HotseatMode.kt
new file mode 100644
index 0000000000..6a050cfed4
--- /dev/null
+++ b/lawnchair/src/app/lawnchair/hotseat/HotseatMode.kt
@@ -0,0 +1,60 @@
+package app.lawnchair.hotseat
+
+import android.content.Context
+import androidx.annotation.LayoutRes
+import androidx.annotation.StringRes
+import app.lawnchair.util.isPackageInstalledAndEnabled
+import com.android.launcher3.R
+
+
+sealed class HotseatMode(
+ @StringRes val nameResourceId: Int,
+ @LayoutRes val layoutResourceId: Int,
+) {
+ companion object {
+ fun fromString(value: String): HotseatMode = when (value) {
+ "disabled" -> DisabledHotseat
+ "google_search" -> GoogleSearchHotseat
+ else -> LawnchairHotseat
+ }
+
+ /**
+ * @return The list of all hot seat modes.
+ */
+ fun values() = listOf(
+ DisabledHotseat,
+ LawnchairHotseat,
+ GoogleSearchHotseat,
+ )
+ }
+
+ abstract fun isAvailable(context: Context): Boolean
+}
+
+
+object LawnchairHotseat : HotseatMode(
+ nameResourceId = R.string.hotseat_mode_lawnchair,
+ layoutResourceId = R.layout.search_container_hotseat,
+) {
+ override fun toString() = "lawnchair"
+ override fun isAvailable(context: Context): Boolean = true
+}
+
+object GoogleSearchHotseat : HotseatMode(
+ nameResourceId = R.string.hotseat_mode_google_search,
+ layoutResourceId = R.layout.search_container_hotseat_google_search,
+) {
+ override fun toString(): String = "google_search"
+
+ override fun isAvailable(context: Context): Boolean =
+ context.packageManager.isPackageInstalledAndEnabled("com.google.android.googlequicksearchbox")
+}
+
+object DisabledHotseat : HotseatMode(
+ nameResourceId = R.string.hotseat_mode_disabled,
+ layoutResourceId = R.layout.empty_view,
+) {
+ override fun toString(): String = "disabled"
+
+ override fun isAvailable(context: Context): Boolean = true
+}
diff --git a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt
index 0759bcd1a9..a1e8a162a4 100644
--- a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt
+++ b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt
@@ -24,6 +24,7 @@ import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import app.lawnchair.font.FontCache
import app.lawnchair.gestures.config.GestureHandlerConfig
+import app.lawnchair.hotseat.HotseatMode
import app.lawnchair.icons.CustomAdaptiveIconDrawable
import app.lawnchair.icons.shape.IconShape
import app.lawnchair.icons.shape.IconShapeManager
@@ -76,9 +77,11 @@ class PreferenceManager2(private val context: Context) : PreferenceManager {
defaultValue = context.resources.getBoolean(R.bool.config_default_dark_status_bar),
)
- val hotseatQsb = preference(
- key = booleanPreferencesKey(name = "dock_search_bar"),
- defaultValue = context.resources.getBoolean(R.bool.config_default_dock_search_bar),
+ val hotseatMode = preference(
+ key = stringPreferencesKey("hotseat_mode"),
+ defaultValue = HotseatMode.fromString(context.getString(R.string.config_default_hotseat_mode)),
+ parse = { HotseatMode.fromString(it) },
+ save = { it.toString() },
onSet = { reloadHelper.restart() },
)
diff --git a/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt
index 5ad27f69f8..2c194fb5d0 100644
--- a/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt
+++ b/lawnchair/src/app/lawnchair/ui/preferences/DockPreferences.kt
@@ -17,14 +17,21 @@
package app.lawnchair.ui.preferences
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavGraphBuilder
+import app.lawnchair.hotseat.HotseatMode
+import app.lawnchair.hotseat.LawnchairHotseat
+import app.lawnchair.preferences.PreferenceAdapter
import app.lawnchair.preferences.getAdapter
import app.lawnchair.preferences.preferenceManager
import app.lawnchair.preferences2.preferenceManager2
import app.lawnchair.qsb.providers.QsbSearchProvider
import app.lawnchair.ui.preferences.components.DividerColumn
import app.lawnchair.ui.preferences.components.ExpandAndShrink
+import app.lawnchair.ui.preferences.components.ListPreference
+import app.lawnchair.ui.preferences.components.ListPreferenceEntry
import app.lawnchair.ui.preferences.components.NavigationActionPreference
import app.lawnchair.ui.preferences.components.PreferenceGroup
import app.lawnchair.ui.preferences.components.PreferenceLayout
@@ -48,34 +55,35 @@ fun DockPreferences() {
val prefs2 = preferenceManager2()
PreferenceLayout(label = stringResource(id = R.string.dock_label)) {
PreferenceGroup(heading = stringResource(id = R.string.search_bar_label)) {
- val hotseatQsbAdapter = prefs2.hotseatQsb.getAdapter()
- SwitchPreference(
- adapter = hotseatQsbAdapter,
- label = stringResource(id = R.string.hotseat_qsb_label),
- )
- ExpandAndShrink(visible = hotseatQsbAdapter.state.value) {
- DividerColumn {
- SwitchPreference(
- adapter = prefs2.themedHotseatQsb.getAdapter(),
- label = stringResource(id = R.string.apply_accent_color_label),
- )
- SliderPreference(
- label = stringResource(id = R.string.corner_radius_label),
- adapter = prefs.hotseatQsbCornerRadius.getAdapter(),
- step = 0.05F,
- valueRange = 0F..1F,
- showAsPercentage = true,
- )
- val hotseatQsbProviderAdapter by preferenceManager2().hotseatQsbProvider.getAdapter()
- NavigationActionPreference(
- label = stringResource(R.string.search_provider),
- destination = subRoute(DockRoutes.SEARCH_PROVIDER),
- subtitle = stringResource(
- id = QsbSearchProvider.values()
- .first { it == hotseatQsbProviderAdapter }
- .name,
- ),
- )
+ DividerColumn {
+ val hotseatModeAdapter = prefs2.hotseatMode.getAdapter()
+ HotseatModePreference(
+ adapter = hotseatModeAdapter,
+ )
+ ExpandAndShrink(visible = hotseatModeAdapter.state.value == LawnchairHotseat) {
+ DividerColumn {
+ SwitchPreference(
+ adapter = prefs2.themedHotseatQsb.getAdapter(),
+ label = stringResource(id = R.string.apply_accent_color_label),
+ )
+ SliderPreference(
+ label = stringResource(id = R.string.corner_radius_label),
+ adapter = prefs.hotseatQsbCornerRadius.getAdapter(),
+ step = 0.05F,
+ valueRange = 0F..1F,
+ showAsPercentage = true,
+ )
+ val hotseatQsbProviderAdapter by preferenceManager2().hotseatQsbProvider.getAdapter()
+ NavigationActionPreference(
+ label = stringResource(R.string.search_provider),
+ destination = subRoute(DockRoutes.SEARCH_PROVIDER),
+ subtitle = stringResource(
+ id = QsbSearchProvider.values()
+ .first { it == hotseatQsbProviderAdapter }
+ .name,
+ ),
+ )
+ }
}
}
}
@@ -89,3 +97,27 @@ fun DockPreferences() {
}
}
}
+
+@Composable
+private fun HotseatModePreference(
+ adapter: PreferenceAdapter,
+) {
+
+ val context = LocalContext.current
+
+ val entries = remember {
+ HotseatMode.values().map { mode ->
+ ListPreferenceEntry(
+ value = mode,
+ label = { stringResource(id = mode.nameResourceId) },
+ enabled = mode.isAvailable(context = context),
+ )
+ }
+ }
+
+ ListPreference(
+ adapter = adapter,
+ entries = entries,
+ label = stringResource(id = R.string.hotseat_mode_label),
+ )
+}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 45f93dda5e..5b44eaef8f 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -51,6 +51,7 @@ import com.patrykmichalik.opto.core.PreferenceExtensionsKt;
import java.io.PrintWriter;
import app.lawnchair.DeviceProfileOverrides;
+import app.lawnchair.hotseat.DisabledHotseat;
import app.lawnchair.preferences2.PreferenceManager2;
import app.lawnchair.theme.color.ColorOption;
@@ -351,7 +352,7 @@ public class DeviceProfile {
int hotseatBottomPaddingRes;
int hotseatBottomNonTallPaddingRes;
int hotseatExtraVerticalSizeRes;
- boolean hotseatQsb = PreferenceExtensionsKt.firstBlocking(preferenceManager2.getHotseatQsb());
+ boolean hotseatQsb = PreferenceExtensionsKt.firstBlocking(preferenceManager2.getHotseatMode()) != DisabledHotseat.INSTANCE;
if (hotseatQsb) {
hotseatTopPaddingRes = R.dimen.dynamic_grid_hotseat_top_padding;
hotseatBottomPaddingRes = R.dimen.dynamic_grid_hotseat_bottom_padding;
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 9ca306daa6..d99d7618c1 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -35,7 +35,10 @@ import com.patrykmichalik.opto.core.PreferenceExtensionsKt;
import java.util.function.Consumer;
+import app.lawnchair.hotseat.HotseatMode;
+import app.lawnchair.hotseat.LawnchairHotseat;
import app.lawnchair.preferences2.PreferenceManager2;
+import app.lawnchair.smartspace.model.LawnchairSmartspace;
/**
* View class that represents the bottom row of the home screen.
@@ -67,8 +70,15 @@ public class Hotseat extends CellLayout implements Insettable {
super(context, attrs, defStyle);
PreferenceManager2 preferenceManager2 = PreferenceManager2.getInstance(context);
- boolean hotseatQsb = PreferenceExtensionsKt.firstBlocking(preferenceManager2.getHotseatQsb());
- int layoutId = hotseatQsb ? R.layout.search_container_hotseat : R.layout.empty_view;
+ HotseatMode hotseatMode = PreferenceExtensionsKt.firstBlocking(preferenceManager2.getHotseatMode());
+ if (!hotseatMode.isAvailable(context)) {
+ // The current hotseat mode is not available,
+ // setting the hotseat mode to one that is always available
+ hotseatMode = LawnchairHotseat.INSTANCE;
+ PreferenceExtensionsKt.setBlocking(mPreferenceManager2.getHotseatMode(), hotseatMode);
+ }
+ int layoutId = hotseatMode.getLayoutResourceId();
+
mQsb = LayoutInflater.from(context).inflate(layoutId, this, false);
mQsbHeight = mQsb.getLayoutParams().height;
addView(mQsb);