merge #193 - codebase improvements

Co-authored-by: Luke Wass <wassupluke@gmail.com>

Squashed commit of the following:

commit 075b4a5353cedea531ec6ebefa60d92de82e8e21
Author: Josia Pietsch <git@jrpie.de>
Date:   Thu May 29 15:34:23 2025 +0200

    some changes

commit ced2e30531
Author: Luke Wass <wassupluke@gmail.com>
Date:   Thu May 29 00:18:21 2025 -0500

    remove unused imports/functions/variables, improve naming convention, remove unused widget context

commit 956ad9795c
Author: Luke Wass <wassupluke@gmail.com>
Date:   Wed May 28 22:40:05 2025 -0500

    add contentDescriptions, ignore unspeakable sections, minor code reorganization

commit cb793860c0
Author: Luke Wass <wassupluke@gmail.com>
Date:   Wed May 28 21:03:03 2025 -0500

    remove empty method

commit 893de14c79
Author: Luke Wass <wassupluke@gmail.com>
Date:   Tue May 27 22:56:03 2025 -0500

    Simplify constructors by removing unused init parameters; clean up handle list type declaration

commit 39164d2e54
Author: Luke Wass <wassupluke@gmail.com>
Date:   Tue May 27 22:54:16 2025 -0500

    Refactor getAppWidgetProviders to use explicit lambda parameter names for clarity

commit 8e53ef0ebe
Author: Luke Wass <wassupluke@gmail.com>
Date:   Tue May 27 22:52:21 2025 -0500

    improve naming convention

commit 8c2a266c22
Author: Luke Wass <wassupluke@gmail.com>
Date:   Tue May 27 22:50:55 2025 -0500

    remove unused resources

commit be03af8ac6
Author: Luke Wass <wassupluke@gmail.com>
Date:   Tue May 27 22:50:33 2025 -0500

    fix table format
This commit is contained in:
Josia Pietsch 2025-05-29 15:48:41 +02:00
parent 15d36eeff4
commit 04a2b4d248
Signed by: jrpie
GPG key ID: E70B571D66986A2D
29 changed files with 91 additions and 99 deletions

View file

@ -28,7 +28,7 @@ import kotlinx.coroutines.launch
import kotlin.system.exitProcess import kotlin.system.exitProcess
const val APP_WIDGET_HOST_ID = 42; const val APP_WIDGET_HOST_ID = 42
class Application : android.app.Application() { class Application : android.app.Application() {

View file

@ -1,7 +1,6 @@
package de.jrpie.android.launcher.actions package de.jrpie.android.launcher.actions
import android.content.Context import android.content.Context
import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraCharacteristics import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager import android.hardware.camera2.CameraManager
import android.os.Build import android.os.Build

View file

@ -6,7 +6,6 @@ import android.widget.Button
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import de.jrpie.android.launcher.BuildConfig import de.jrpie.android.launcher.BuildConfig
import de.jrpie.android.launcher.R import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.actions.lock.LauncherAccessibilityService
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences

View file

@ -1,9 +1,7 @@
package de.jrpie.android.launcher.preferences.legacy package de.jrpie.android.launcher.preferences.legacy
import android.content.Context import android.content.Context
import de.jrpie.android.launcher.Application
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION
import de.jrpie.android.launcher.widgets.ClockWidget import de.jrpie.android.launcher.widgets.ClockWidget
import de.jrpie.android.launcher.widgets.WidgetPanel import de.jrpie.android.launcher.widgets.WidgetPanel
import de.jrpie.android.launcher.widgets.WidgetPosition import de.jrpie.android.launcher.widgets.WidgetPosition

View file

@ -1,7 +1,6 @@
package de.jrpie.android.launcher.ui package de.jrpie.android.launcher.ui
import android.app.AlertDialog import android.app.AlertDialog
import android.app.Service
import android.content.Context import android.content.Context
import android.content.pm.LauncherApps import android.content.pm.LauncherApps
import android.content.pm.LauncherApps.PinItemRequest import android.content.pm.LauncherApps.PinItemRequest
@ -45,7 +44,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject {
binding = ActivityPinShortcutBinding.inflate(layoutInflater) binding = ActivityPinShortcutBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
val launcherApps = getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps val launcherApps = getSystemService(LAUNCHER_APPS_SERVICE) as LauncherApps
val request = launcherApps.getPinItemRequest(intent) val request = launcherApps.getPinItemRequest(intent)
this.request = request this.request = request
@ -56,7 +55,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject {
if (request.requestType == PinItemRequest.REQUEST_TYPE_APPWIDGET) { if (request.requestType == PinItemRequest.REQUEST_TYPE_APPWIDGET) {
// TODO // TODO handle app widgets
request.getAppWidgetProviderInfo(this) request.getAppWidgetProviderInfo(this)
// startActivity() // startActivity()
finish() finish()

View file

@ -17,6 +17,7 @@ import kotlin.math.max
import kotlin.math.min import kotlin.math.min
import kotlin.math.tan import kotlin.math.tan
@Suppress("PrivatePropertyName")
class TouchGestureDetector( class TouchGestureDetector(
private val context: Context, private val context: Context,
var width: Int, var width: Int,
@ -34,13 +35,13 @@ class TouchGestureDetector(
private val MIN_TRIANGLE_HEIGHT = 250 private val MIN_TRIANGLE_HEIGHT = 250
private val longPressHandler = Handler(Looper.getMainLooper())
private var systemGestureInsetTop = 100 private var systemGestureInsetTop = 100
private var systemGestureInsetBottom = 0 private var systemGestureInsetBottom = 0
private var systemGestureInsetLeft = 0 private var systemGestureInsetLeft = 0
private var systemGestureInsetRight = 0 private var systemGestureInsetRight = 0
private val longPressHandler = Handler(Looper.getMainLooper())
data class Vector(val x: Float, val y: Float) { data class Vector(val x: Float, val y: Float) {
fun absSquared(): Float { fun absSquared(): Float {

View file

@ -237,9 +237,4 @@ class AppsRecyclerAdapter(
appFilter.favoritesVisibility = v appFilter.favoritesVisibility = v
updateAppsList() updateAppsList()
} }
fun setHiddenAppsVisibility(v: AppFilter.Companion.AppSetVisibility) {
appFilter.hiddenVisibility = v
updateAppsList()
}
} }

View file

@ -96,7 +96,6 @@ class ListFragmentApps : Fragment(), UIObject {
if (LauncherPreferences.functionality().searchAutoCloseKeyboard()) { if (LauncherPreferences.functionality().searchAutoCloseKeyboard()) {
addOnScrollListener(object : RecyclerView.OnScrollListener() { addOnScrollListener(object : RecyclerView.OnScrollListener() {
var totalDy: Int = 0 var totalDy: Int = 0
var threshold = (resources.displayMetrics.density * 100).toInt()
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
totalDy += dy totalDy += dy

View file

@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import de.jrpie.android.launcher.BuildConfig.VERSION_CODE
import de.jrpie.android.launcher.databinding.Tutorial5FinishBinding import de.jrpie.android.launcher.databinding.Tutorial5FinishBinding
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.requestNotificationPermission import de.jrpie.android.launcher.requestNotificationPermission

View file

@ -61,7 +61,7 @@ open class WidgetContainerView(
it.value.y + it.value.height it.value.y + it.value.height
).contains(position) == true ).contains(position) == true
}.any { }.any {
Widget.byId(context, it.key)?.allowInteraction == false Widget.byId(it.key)?.allowInteraction == false
} }
} }
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

View file

@ -9,7 +9,6 @@ import android.widget.EditText
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import de.jrpie.android.launcher.Application
import de.jrpie.android.launcher.R import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.databinding.ActivityManageWidgetPanelsBinding import de.jrpie.android.launcher.databinding.ActivityManageWidgetPanelsBinding
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences

View file

@ -5,7 +5,6 @@ import android.appwidget.AppWidgetManager
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.ViewGroup import android.view.ViewGroup
@ -21,7 +20,6 @@ import de.jrpie.android.launcher.widgets.GRID_SIZE
import de.jrpie.android.launcher.widgets.WidgetPanel import de.jrpie.android.launcher.widgets.WidgetPanel
import de.jrpie.android.launcher.widgets.WidgetPosition import de.jrpie.android.launcher.widgets.WidgetPosition
import kotlin.math.max import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -132,7 +130,6 @@ class ManageWidgetsActivity : UIObject, Activity() {
private fun selectWidget() { private fun selectWidget() {
val appWidgetHost = (application as Application).appWidgetHost
startActivityForResult( startActivityForResult(
Intent(this, SelectWidgetActivity::class.java).also { Intent(this, SelectWidgetActivity::class.java).also {
it.putExtra( it.putExtra(

View file

@ -31,19 +31,19 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe
WidgetContainerView(widgetPanelId, context, attrs) { WidgetContainerView(widgetPanelId, context, attrs) {
constructor(context: Context, attrs: AttributeSet?) : this(WidgetPanel.HOME.id, context, attrs) constructor(context: Context, attrs: AttributeSet?) : this(WidgetPanel.HOME.id, context, attrs)
val TOUCH_SLOP: Int val touchSlop: Int
val TOUCH_SLOP_SQUARE: Int val touchSlopSquare: Int
val LONG_PRESS_TIMEOUT: Long val longPressTimeout: Long
private var overlayViewById = HashMap<Int, WidgetOverlayView>() private var overlayViewById = HashMap<Int, WidgetOverlayView>()
init { init {
val configuration = ViewConfiguration.get(context) val configuration = ViewConfiguration.get(context)
TOUCH_SLOP = configuration.scaledTouchSlop touchSlop = configuration.scaledTouchSlop
TOUCH_SLOP_SQUARE = TOUCH_SLOP * TOUCH_SLOP touchSlopSquare = touchSlop * touchSlop
LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout().toLong() longPressTimeout = ViewConfiguration.getLongPressTimeout().toLong()
} }
@ -127,14 +127,14 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
endInteraction() endInteraction()
} }
}, LONG_PRESS_TIMEOUT) }, longPressTimeout)
} }
if (event.actionMasked == MotionEvent.ACTION_MOVE || if (event.actionMasked == MotionEvent.ACTION_MOVE ||
event.actionMasked == MotionEvent.ACTION_UP event.actionMasked == MotionEvent.ACTION_UP
) { ) {
val distanceX = event.x - (currentGestureStart?.x ?: return true) val distanceX = event.x - (currentGestureStart?.x ?: return true)
val distanceY = event.y - (currentGestureStart?.y ?: return true) val distanceY = event.y - (currentGestureStart?.y ?: return true)
if (distanceX * distanceX + distanceY * distanceY > TOUCH_SLOP_SQUARE) { if (distanceX * distanceX + distanceY * distanceY > touchSlopSquare) {
longPressHandler.removeCallbacksAndMessages(null) longPressHandler.removeCallbacksAndMessages(null)
} }
val view = selectedWidgetOverlayView ?: return true val view = selectedWidgetOverlayView ?: return true
@ -162,7 +162,7 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe
if (event.actionMasked == MotionEvent.ACTION_UP) { if (event.actionMasked == MotionEvent.ACTION_UP) {
longPressHandler.removeCallbacksAndMessages(null) longPressHandler.removeCallbacksAndMessages(null)
val id = selectedWidgetOverlayView?.widgetId ?: return true val id = selectedWidgetOverlayView?.widgetId ?: return true
val widget = Widget.byId(context, id) ?: return true val widget = Widget.byId(id) ?: return true
widget.position = newPosition widget.position = newPosition
endInteraction() endInteraction()
updateWidget(widget) updateWidget(widget)

View file

@ -54,26 +54,18 @@ class WidgetOverlayView : ViewGroup {
var widgetId: Int = -1 var widgetId: Int = -1
set(newId) { set(newId) {
field = newId field = newId
preview = Widget.byId(context, widgetId)?.getPreview(context) preview = Widget.byId(widgetId)?.getPreview(context)
} }
constructor(context: Context) : super(context) { constructor(context: Context) : super(context)
init(null, 0)
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
init(attrs, 0)
}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super( constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(
context, context,
attrs, attrs,
defStyle defStyle
) { )
init(attrs, defStyle)
}
private fun init(attrs: AttributeSet?, defStyle: Int) { }
override fun onDraw(canvas: Canvas) { override fun onDraw(canvas: Canvas) {
super.onDraw(canvas) super.onDraw(canvas)
@ -101,13 +93,13 @@ class WidgetOverlayView : ViewGroup {
} }
fun showPopupMenu() { fun showPopupMenu() {
val widget = Widget.byId(context, widgetId)?: return val widget = Widget.byId(widgetId)?: return
val menu = PopupMenu(context, popupAnchor) val menu = PopupMenu(context, popupAnchor)
menu.menu.let { menu.menu.let {
it.add( it.add(
context.getString(R.string.widget_menu_remove) context.getString(R.string.widget_menu_remove)
).setOnMenuItemClickListener { _ -> ).setOnMenuItemClickListener { _ ->
Widget.byId(context, widgetId)?.delete(context) Widget.byId(widgetId)?.delete(context)
return@setOnMenuItemClickListener true return@setOnMenuItemClickListener true
} }
it.add( it.add(
@ -126,7 +118,7 @@ class WidgetOverlayView : ViewGroup {
} }
fun getHandles(): List<Handle> { fun getHandles(): List<Handle> {
return listOf<Handle>( return listOf(
Handle(WidgetManagerView.EditMode.TOP, Handle(WidgetManagerView.EditMode.TOP,
Rect(HANDLE_EDGE_SIZE, 0, width - HANDLE_EDGE_SIZE, HANDLE_SIZE)), Rect(HANDLE_EDGE_SIZE, 0, width - HANDLE_EDGE_SIZE, HANDLE_SIZE)),
Handle(WidgetManagerView.EditMode.BOTTOM, Handle(WidgetManagerView.EditMode.BOTTOM,

View file

@ -38,10 +38,6 @@ sealed class Widget {
) )
} }
fun getPanel(): WidgetPanel? {
return WidgetPanel.byId(panelId)
}
override fun hashCode(): Int { override fun hashCode(): Int {
return id return id
} }
@ -57,9 +53,9 @@ sealed class Widget {
fun deserialize(serialized: String): Widget { fun deserialize(serialized: String): Widget {
return Json.decodeFromString(serialized) return Json.decodeFromString(serialized)
} }
fun byId(context: Context, id: Int): Widget? { fun byId(id: Int): Widget? {
// TODO: do some caching // TODO: do some caching
return LauncherPreferences.widgets().widgets().firstOrNull() { return LauncherPreferences.widgets().widgets().firstOrNull {
it.id == id it.id == id
} }
} }

View file

@ -55,8 +55,8 @@ fun getAppWidgetProviders( context: Context ): List<LauncherWidgetProvider> {
(context.getSystemService(Service.USER_SERVICE) as UserManager).userProfiles (context.getSystemService(Service.USER_SERVICE) as UserManager).userProfiles
} }
list.addAll( list.addAll(
profiles.map { profiles.map { profile ->
appWidgetManager.getInstalledProvidersForProfile(it) appWidgetManager.getInstalledProvidersForProfile(profile)
.map { LauncherAppWidgetProvider(it) } .map { LauncherAppWidgetProvider(it) }
}.flatten() }.flatten()
) )

View file

@ -40,6 +40,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:contentDescription="@string/content_description_close"
android:gravity="center" android:gravity="center"
android:includeFontPadding="true" android:includeFontPadding="true"
android:paddingLeft="16sp" android:paddingLeft="16sp"
@ -64,6 +65,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
android:contentDescription="@string/content_description_add_widget_panel"
android:src="@drawable/baseline_add_24" android:src="@drawable/baseline_add_24"
app:layout_anchor="@+id/manage_widget_panels_recycler" app:layout_anchor="@+id/manage_widget_panels_recycler"
app:layout_anchorGravity="end|bottom" app:layout_anchorGravity="end|bottom"

View file

@ -20,6 +20,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
android:clickable="true" android:clickable="true"
android:contentDescription="@string/content_description_add_widget"
android:focusable="true" android:focusable="true"
android:src="@drawable/baseline_add_24" android:src="@drawable/baseline_add_24"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"

View file

@ -44,6 +44,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:contentDescription="@string/content_description_close"
android:gravity="center" android:gravity="center"
android:includeFontPadding="true" android:includeFontPadding="true"
android:paddingLeft="16sp" android:paddingLeft="16sp"

View file

@ -45,6 +45,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:contentDescription="@string/content_description_close"
android:gravity="center" android:gravity="center"
android:includeFontPadding="true" android:includeFontPadding="true"
android:paddingLeft="16sp" android:paddingLeft="16sp"

View file

@ -62,6 +62,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:contentDescription="@string/content_description_close"
android:gravity="center" android:gravity="center"
android:includeFontPadding="true" android:includeFontPadding="true"
android:paddingLeft="16sp" android:paddingLeft="16sp"
@ -72,6 +73,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<ImageView <ImageView
android:id="@+id/list_lock" android:id="@+id/list_lock"
android:contentDescription="@string/content_description_lock"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible" tools:visibility="visible"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -91,7 +93,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:tabIndicatorColor="?attr/colorAccent" app:tabIndicatorColor="?attr/colorAccent"
custom:tabTextColor="?attr/android:textColor" /> custom:tabTextColor="?attr/android:textColor"
tools:ignore="SpeakableTextPresentCheck" />
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
@ -110,6 +113,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/list_appbar" app:layout_constraintTop_toBottomOf="@id/list_appbar"
app:layout_constraintVertical_bias="0.0" app:layout_constraintVertical_bias="0.0"
custom:layout_behavior="@string/appbar_scrolling_view_behavior" /> custom:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:ignore="SpeakableTextPresentCheck" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -11,6 +11,7 @@
android:id="@+id/list_other_row_icon" android:id="@+id/list_other_row_icon"
android:layout_width="35sp" android:layout_width="35sp"
android:layout_height="35sp" android:layout_height="35sp"
android:contentDescription="@null"
android:gravity="center" android:gravity="center"
android:textSize="30sp" android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"

View file

@ -20,6 +20,22 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ImageView
android:id="@+id/settings_system"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:contentDescription="@string/settings"
android:gravity="center"
android:includeFontPadding="true"
android:paddingLeft="16sp"
android:paddingRight="16sp"
android:src="@drawable/baseline_settings_applications_24"
custom:layout_constraintBottom_toBottomOf="parent"
custom:layout_constraintStart_toStartOf="parent"
custom:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/settings_heading" android:id="@+id/settings_heading"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -40,6 +56,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:contentDescription="@string/content_description_close"
android:gravity="center" android:gravity="center"
android:includeFontPadding="true" android:includeFontPadding="true"
android:paddingLeft="16sp" android:paddingLeft="16sp"
@ -48,28 +65,14 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/settings_system"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:gravity="center"
android:includeFontPadding="true"
android:paddingLeft="16sp"
android:paddingRight="16sp"
android:src="@drawable/baseline_settings_applications_24"
custom:layout_constraintBottom_toBottomOf="parent"
custom:layout_constraintStart_toStartOf="parent"
custom:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/settings_tabs" android:id="@+id/settings_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:tabTextColor="?attr/android:textColor" /> app:tabTextColor="?attr/android:textColor"
tools:ignore="SpeakableTextPresentCheck" />
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View file

@ -68,6 +68,7 @@
android:id="@+id/settings_actions_row_remove" android:id="@+id/settings_actions_row_remove"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/content_description_settings_actions_row_button_remove"
android:padding="8sp" android:padding="8sp"
android:src="@drawable/baseline_close_24" android:src="@drawable/baseline_close_24"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"

View file

@ -26,6 +26,7 @@
android:id="@+id/tutorial_button_back" android:id="@+id/tutorial_button_back"
android:layout_width="50dp" android:layout_width="50dp"
android:layout_height="50dp" android:layout_height="50dp"
android:contentDescription="@string/content_description_navigate_back"
android:gravity="center" android:gravity="center"
android:alpha="0.5" android:alpha="0.5"
android:src="@drawable/baseline_navigate_before_24" android:src="@drawable/baseline_navigate_before_24"
@ -43,12 +44,14 @@
app:layout_constraintStart_toEndOf="@+id/tutorial_button_back" app:layout_constraintStart_toEndOf="@+id/tutorial_button_back"
app:tabBackground="@drawable/tutorial_tab_selector" app:tabBackground="@drawable/tutorial_tab_selector"
app:tabGravity="center" app:tabGravity="center"
app:tabIndicatorHeight="0dp" /> app:tabIndicatorHeight="0dp"
tools:ignore="SpeakableTextPresentCheck" />
<ImageView <ImageView
android:id="@+id/tutorial_button_next" android:id="@+id/tutorial_button_next"
android:layout_width="50dp" android:layout_width="50dp"
android:layout_height="50dp" android:layout_height="50dp"
android:contentDescription="@string/content_description_navigate_next"
android:gravity="center" android:gravity="center"
android:src="@drawable/baseline_navigate_next_24" android:src="@drawable/baseline_navigate_next_24"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"

View file

@ -11,9 +11,5 @@
<color name="lightTheme_background_color">#fff</color> <color name="lightTheme_background_color">#fff</color>
<color name="lightTheme_accent_color">#9999ff</color> <color name="lightTheme_accent_color">#9999ff</color>
<color name="lightTheme_text_color">#000</color> <color name="lightTheme_text_color">#000</color>
<color name="light_blue_400">#FF29B6F6</color>
<color name="light_blue_600">#FF039BE5</color>
<color name="gray_400">#FFBDBDBD</color>
<color name="gray_600">#FF757575</color>
</resources> </resources>

View file

@ -1,11 +1,5 @@
<resources> <resources>
<!-- Default screen margins, per the Android Design guidelines. --> <!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="appbar_padding">16dp</dimen> <dimen name="appbar_padding">16dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="appbar_padding_top">8dp</dimen>
<dimen name="app_icon_side">40dip</dimen> <dimen name="app_icon_side">40dip</dimen>
<dimen name="app_action_height">48dip</dimen>
</resources> </resources>

View file

@ -444,4 +444,16 @@
<string name="send_email">Send Email</string> <string name="send_email">Send Email</string>
<string name="notification_channel_crash">Crashes and Debug Information</string> <string name="notification_channel_crash">Crashes and Debug Information</string>
<string name="settings_meta_view_docs">Documentation</string> <string name="settings_meta_view_docs">Documentation</string>
<!--
-
- Content Descriptions
-
-->
<string name="content_description_add_widget">Add widget</string>
<string name="content_description_add_widget_panel">Add widget panel</string>
<string name="content_description_close">Close</string>
<string name="content_description_navigate_back">Navigate back</string>
<string name="content_description_navigate_next">Navigate next</string>
<string name="content_description_lock">Lock</string>
<string name="content_description_settings_actions_row_button_remove">Remove binding</string>
</resources> </resources>

View file

@ -409,22 +409,22 @@ Similar to OLauncher?
:x: = Unsupported :x: = Unsupported
:warning: = Buggy/Broken; check this launcher's notes above :warning: = Buggy/Broken; check this launcher's notes above
| Launcher | Search | Search history | Customizable gestures | Folders | Tags | Rename apps | Widgets | Private space | Work profile | Pinned shortcuts | Icon packs | Material You | | Launcher | Search | Search history | Customizable gestures | Folders | Tags | Rename apps | Widgets | Private space | Work profile | Pinned shortcuts | Icon packs | Material You |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | |------------------------------------------------------|--------------------|--------------------|-----------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|--------------------|
| [µLauncher](#µLauncher) | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | | [µLauncher](#µLauncher) | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: |
| [Fossify](#Fossify) | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :grey_question: | :x: | :white_check_mark: | :x: | :white_check_mark: | | [Fossify](#Fossify) | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :grey_question: | :x: | :white_check_mark: | :x: | :white_check_mark: |
| [Lawnchair](#Lawnchair) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :grey_question: | :grey_question: | :x: | :white_check_mark: | :white_check_mark: | | [Lawnchair](#Lawnchair) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :grey_question: | :grey_question: | :x: | :white_check_mark: | :white_check_mark: |
| [Rootless Pixel Launcher](#Rootless-Pixel-Launcher) | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :warning: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | | [Rootless Pixel Launcher](#Rootless-Pixel-Launcher) | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :warning: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| [KISS Launcher](#KISS-Launcher) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :grey_question: | | [KISS Launcher](#KISS-Launcher) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :grey_question: |
| [Lunar Launcher](#Lunar-Launcher) | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :grey_question: | :x: | :white_check_mark: | :x: | :x: | | [Lunar Launcher](#Lunar-Launcher) | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :grey_question: | :x: | :white_check_mark: | :x: | :x: |
| [OLauncher](#OLauncher) | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :grey_question: | :white_check_mark: | :grey_question: | :x: | :grey_question: | | [OLauncher](#OLauncher) | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :grey_question: | :white_check_mark: | :grey_question: | :x: | :grey_question: |
| [TinyBit Launcher](#TinyBit-Launcher) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | | [TinyBit Launcher](#TinyBit-Launcher) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| [YAM Launcher](#YAM-Launcher) | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | | [YAM Launcher](#YAM-Launcher) | :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: |
| [Ion Launcher](#Ion-Launcher) | :warning: | :white_check_mark: | :x: | :warning: | :x: | :white_check_mark: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | | [Ion Launcher](#Ion-Launcher) | :warning: | :white_check_mark: | :x: | :warning: | :x: | :white_check_mark: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| [Pie Launcher](#Pie-Launcher) | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :x: | :x: | | [Pie Launcher](#Pie-Launcher) | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :x: | :x: |
| [folder launcher](#folder-launcher) | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :grey_question: | :x: | :white_check_mark: | :x: | :x: | | [folder launcher](#folder-launcher) | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :grey_question: | :x: | :white_check_mark: | :x: | :x: |
| [Discreet Launcher](#Discreet-Launcher) | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | | [Discreet Launcher](#Discreet-Launcher) | :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| [Aster Launcher](#Aster-Launcher) | :warning: | :x: | :x: | :x: | :x: | :x: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :x: | :x: | | [Aster Launcher](#Aster-Launcher) | :warning: | :x: | :x: | :x: | :x: | :x: | :x: | :grey_question: | :white_check_mark: | :white_check_mark: | :x: | :x: |
<!-- Automating checkboxes for the table <!-- Automating checkboxes for the table