Compare commits

...

2 commits

Author SHA1 Message Date
da115bb2d9
refactor: remove unused stuff, fix lint warnings
Some checks are pending
Android CI / build (push) Waiting to run
2025-03-16 16:37:39 +01:00
90434617e7
replace (ViewPager, FragmentPagerAdapter) by (ViewPager2, FragmentStateAdapter) 2025-03-16 04:12:34 +01:00
53 changed files with 454 additions and 645 deletions

View file

@ -95,7 +95,7 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.activity:activity:1.8.0'
implementation 'androidx.activity:activity-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.core:core-ktx:1.15.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'

View file

@ -7,11 +7,8 @@ import android.content.IntentFilter
import android.content.SharedPreferences
import android.content.pm.LauncherApps
import android.content.pm.ShortcutInfo
import android.os.AsyncTask
import android.os.Build
import android.os.Build.VERSION_CODES
import android.os.Handler
import android.os.Looper
import android.os.UserHandle
import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData
@ -23,6 +20,9 @@ import de.jrpie.android.launcher.apps.isPrivateSpaceLocked
import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.preferences.migratePreferencesToNewVersion
import de.jrpie.android.launcher.preferences.resetPreferences
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class Application : android.app.Application() {
val apps = MutableLiveData<List<AbstractDetailedAppInfo>>()
@ -153,6 +153,8 @@ class Application : android.app.Application() {
private fun loadApps() {
privateSpaceLocked.postValue(isPrivateSpaceLocked(this))
AsyncTask.execute { apps.postValue(getApps(packageManager, applicationContext)) }
CoroutineScope(Dispatchers.Default).launch {
apps.postValue(getApps(packageManager, applicationContext))
}
}
}

View file

@ -12,7 +12,6 @@ import android.content.pm.LauncherApps
import android.content.pm.LauncherApps.ShortcutQuery
import android.content.pm.PackageManager
import android.content.pm.ShortcutInfo
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.UserHandle
@ -34,15 +33,9 @@ import de.jrpie.android.launcher.apps.getPrivateSpaceUser
import de.jrpie.android.launcher.apps.isPrivateSpaceSupported
import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.ui.tutorial.TutorialActivity
import androidx.core.net.toUri
/* REQUEST CODES */
const val REQUEST_CHOOSE_APP = 1
const val REQUEST_UNINSTALL = 2
const val REQUEST_SET_DEFAULT_HOME = 42
const val LOG_TAG = "Launcher"
fun isDefaultHomeScreen(context: Context): Boolean {
@ -69,9 +62,8 @@ fun setDefaultHomeScreen(context: Context, checkDefault: Boolean = false) {
&& !isDefault // using role manager only works when µLauncher is not already the default.
) {
val roleManager = context.getSystemService(RoleManager::class.java)
context.startActivityForResult(
roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME),
REQUEST_SET_DEFAULT_HOME
context.startActivity(
roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME)
)
return
}
@ -125,7 +117,7 @@ fun removeUnusedShortcuts(context: Context) {
}
fun openInBrowser(url: String, context: Context) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
intent.putExtras(Bundle().apply { putBoolean("new_window", true) })
try {
context.startActivity(intent)
@ -212,14 +204,6 @@ fun getApps(
return loadList
}
// Used in Tutorial and Settings `ActivityOnResult`
fun saveListActivityChoice(data: Intent?) {
val forGesture = data?.getStringExtra("forGesture") ?: return
Gesture.byId(forGesture)?.let { Action.setActionForGesture(it, Action.fromIntent(data)) }
}
// used for the bug report button
fun getDeviceInfo(): String {
return """

View file

@ -2,7 +2,6 @@ package de.jrpie.android.launcher.actions
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences.Editor
import android.graphics.Rect
import android.graphics.drawable.Drawable
@ -12,6 +11,7 @@ import de.jrpie.android.launcher.preferences.LauncherPreferences
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import androidx.core.content.edit
@Serializable
@ -29,10 +29,6 @@ sealed interface Action {
prefEditor.putString(id, Json.encodeToString(this))
}
fun writeToIntent(intent: Intent) {
intent.putExtra("action", Json.encodeToString(this))
}
companion object {
fun forGesture(gesture: Gesture): Action? {
@ -44,23 +40,23 @@ sealed interface Action {
}
fun resetToDefaultActions(context: Context) {
val editor = LauncherPreferences.getSharedPreferences().edit()
val boundActions = HashSet<String>()
Gesture.entries.forEach { gesture ->
context.resources
.getStringArray(gesture.defaultsResource)
.filterNot { boundActions.contains(it) }
.map { Pair(it, Json.decodeFromString<Action>(it)) }
.firstOrNull { it.second.isAvailable(context) }
?.apply {
// allow to bind CHOOSE to multiple gestures
if (second != LauncherAction.CHOOSE) {
boundActions.add(first)
LauncherPreferences.getSharedPreferences().edit {
val boundActions = HashSet<String>()
Gesture.entries.forEach { gesture ->
context.resources
.getStringArray(gesture.defaultsResource)
.filterNot { boundActions.contains(it) }
.map { Pair(it, Json.decodeFromString<Action>(it)) }
.firstOrNull { it.second.isAvailable(context) }
?.apply {
// allow to bind CHOOSE to multiple gestures
if (second != LauncherAction.CHOOSE) {
boundActions.add(first)
}
second.bindToGesture(this@edit, gesture.id)
}
second.bindToGesture(editor, gesture.id)
}
}
}
editor.apply()
}
fun setActionForGesture(gesture: Gesture, action: Action?) {
@ -68,15 +64,15 @@ sealed interface Action {
clearActionForGesture(gesture)
return
}
val editor = LauncherPreferences.getSharedPreferences().edit()
action.bindToGesture(editor, gesture.id)
editor.apply()
LauncherPreferences.getSharedPreferences().edit {
action.bindToGesture(this, gesture.id)
}
}
fun clearActionForGesture(gesture: Gesture) {
LauncherPreferences.getSharedPreferences().edit()
.remove(gesture.id)
.apply()
LauncherPreferences.getSharedPreferences().edit {
remove(gesture.id)
}
}
fun launch(
@ -87,6 +83,9 @@ sealed interface Action {
) {
if (action != null && action.invoke(context)) {
if (context is Activity) {
// There does not seem to be a good alternative to overridePendingTransition.
// Note that we can't use overrideActivityTransition here.
@Suppress("deprecation")
context.overridePendingTransition(animationIn, animationOut)
}
} else {
@ -97,10 +96,5 @@ sealed interface Action {
).show()
}
}
fun fromIntent(data: Intent): Action? {
val json = data.getStringExtra("action") ?: return null
return Json.decodeFromString(json)
}
}
}

View file

@ -250,7 +250,7 @@ enum class Gesture(
"action.back",
R.string.settings_gesture_back,
R.string.settings_gesture_description_back,
R.array.default_up
R.array.default_back
);
enum class Edge {

View file

@ -9,7 +9,6 @@ import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.preferences.LauncherPreferences
@Suppress("unused")
enum class LockMethod(
private val lock: (Context) -> Unit,
private val isEnabled: (Context) -> Boolean,

View file

@ -15,19 +15,7 @@ import kotlinx.serialization.Serializable
*/
@Serializable
@SerialName("app")
class AppInfo(val packageName: String, val activityName: String?, val user: Int = INVALID_USER): AbstractAppInfo {
override fun equals(other: Any?): Boolean {
if(other is AppInfo) {
return other.user == user && other.packageName == packageName
&& other.activityName == activityName
}
return super.equals(other)
}
override fun hashCode(): Int {
return packageName.hashCode()
}
data class AppInfo(val packageName: String, val activityName: String?, val user: Int = INVALID_USER): AbstractAppInfo {
fun getLauncherActivityInfo(
context: Context
@ -38,10 +26,4 @@ class AppInfo(val packageName: String, val activityName: String?, val user: Int
return activityList.firstOrNull { app -> app.name == activityName }
?: activityList.firstOrNull()
}
override fun toString(): String {
return "AppInfo {package=$packageName, activity=$activityName, user=$user}"
}
}

View file

@ -16,7 +16,7 @@ import kotlinx.serialization.Serializable
@RequiresApi(Build.VERSION_CODES.N_MR1)
@Serializable
@SerialName("shortcut")
class PinnedShortcutInfo(
data class PinnedShortcutInfo(
val id: String,
val packageName: String,
val activityName: String,
@ -43,25 +43,4 @@ class PinnedShortcutInfo(
null
}
}
override fun equals(other: Any?): Boolean {
return (other as? PinnedShortcutInfo)?.let {
packageName == this.packageName &&
activityName == this.activityName &&
id == this.id &&
user == this.user
} ?: false
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + packageName.hashCode()
result = 31 * result + activityName.hashCode()
result = 31 * result + user
return result
}
override fun toString(): String {
return "PinnedShortcutInfo { package=$packageName, activity=$activityName, user=$user, id=$id}"
}
}

View file

@ -123,6 +123,7 @@ fun togglePrivateSpaceLock(context: Context) {
}
}
@Suppress("SameReturnValue")
fun hidePrivateSpaceWhenLocked(context: Context): Boolean {
// Trying to access the setting as a 3rd party launcher raises a security exception.
// This is an Android bug: https://issuetracker.google.com/issues/352276244#comment5

View file

@ -17,6 +17,7 @@ import androidx.core.graphics.green
import androidx.core.graphics.red
import androidx.preference.Preference
import de.jrpie.android.launcher.R
import androidx.core.graphics.toColorInt
class ColorPreference(context: Context, attrs: AttributeSet?) :
Preference(context, attrs) {
@ -52,7 +53,7 @@ class ColorPreference(context: Context, attrs: AttributeSet?) :
AlertDialog.Builder(context, R.style.AlertDialogCustom).apply {
setView(R.layout.dialog_choose_color)
setTitle(R.string.dialog_choose_color_title)
setPositiveButton(R.string.dialog_select_color_ok) { _, _ ->
setPositiveButton(android.R.string.ok) { _, _ ->
persistInt(currentColor)
summary = currentColor.getHex()
}
@ -83,10 +84,10 @@ class ColorPreference(context: Context, attrs: AttributeSet?) :
override fun onTextChanged(text: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun afterTextChanged(editable: Editable?) {
preview.hasFocus() || return
val newText = editable?.toString()
newText.isNullOrBlank() && return
val newText = editable?.toString() ?: return
newText.isBlank() && return
try {
val newColor = Color.parseColor(newText.toString())
val newColor = newText.toColorInt()
currentColor = newColor
updateColor(false)
} catch (_: IllegalArgumentException) {

View file

@ -1,6 +1,7 @@
package de.jrpie.android.launcher.preferences
import android.content.Context
import android.util.TypedValue
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -27,8 +28,10 @@ enum class ListLayout(
GRID(
{ c ->
val displayMetrics = c.resources.displayMetrics
val widthSp = displayMetrics.widthPixels / displayMetrics.scaledDensity
GridLayoutManager(c, (widthSp / 90).toInt())
val widthColumnPx =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 90f, displayMetrics)
val numColumns = (displayMetrics.widthPixels / widthColumnPx).toInt()
GridLayoutManager(c, numColumns)
},
R.layout.list_apps_row_variant_grid,
false

View file

@ -13,9 +13,11 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.json.JSONException
import org.json.JSONObject
import androidx.core.content.edit
@Serializable
@Suppress("unused")
private class LegacyMapEntry(val key: AppInfo, val value: String)
private fun serializeMapAppInfo(value: Map<AppInfo, String>?): Set<String>? {
@ -100,7 +102,7 @@ private fun migrateAppInfoStringMap(key: String) {
}
}?.toMap(HashMap())
)?.let {
preferences.edit().putStringSet(key, it).apply()
preferences.edit { putStringSet(key, it) }
}
}
@ -109,16 +111,16 @@ private fun migrateAppInfoSet(key: String) {
.map(AppInfo.Companion::legacyDeserialize)
.map(AppInfo::serialize)
.toSet()
.let { LauncherPreferences.getSharedPreferences().edit().putStringSet(key, it).apply() }
.let { LauncherPreferences.getSharedPreferences().edit { putStringSet(key, it) } }
}
private fun migrateAction(key: String) {
Action.legacyFromPreference(key)?.let { action ->
LauncherPreferences.getSharedPreferences().edit()
.putString(key, Json.encodeToString(action))
.remove("$key.app")
.remove("$key.user")
.apply()
LauncherPreferences.getSharedPreferences().edit {
putString(key, Json.encodeToString(action))
.remove("$key.app")
.remove("$key.user")
}
}
}

View file

@ -6,7 +6,7 @@ import android.util.Log
import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.preferences.theme.Background
import de.jrpie.android.launcher.preferences.theme.ColorTheme
import androidx.core.content.edit
private fun migrateStringPreference(
@ -64,318 +64,317 @@ fun migratePreferencesFromVersionUnknown(context: Context) {
return
}
val newPrefs = LauncherPreferences.getSharedPreferences().edit()
LauncherPreferences.getSharedPreferences().edit {
migrateBooleanPreference(
oldPrefs,
newPrefs,
"startedBefore",
"internal.started_before",
false
)
migrateBooleanPreference(
oldPrefs,
this,
"startedBefore",
"internal.started_before",
false
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_volumeUpApp",
"action.volume_up.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_volumeUpApp_user",
"action.volume_up.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_volumeDownApp",
"action.volume_down.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_volumeDownApp_user",
"action.volume_down.user",
-1
)
migrateStringPreference(oldPrefs, newPrefs, "action_timeApp", "action.time.app", "")
migrateIntPreference(oldPrefs, newPrefs, "action_timeApp_user", "action.time.user", -1)
migrateStringPreference(oldPrefs, newPrefs, "action_dateApp", "action.date.app", "")
migrateIntPreference(oldPrefs, newPrefs, "action_dateApp_user", "action.date.user", -1)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_longClickApp",
"action.long_click.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_longClickApp_user",
"action.long_click.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_doubleClickApp",
"action.double_click.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_doubleClickApp_user",
"action.double_click.user",
-1
)
migrateStringPreference(oldPrefs, newPrefs, "action_upApp", "action.up.app", "")
migrateIntPreference(oldPrefs, newPrefs, "action_upApp_user", "action.up.user", -1)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_up_leftApp",
"action.up_left.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_up_leftApp_user",
"action.up_left.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_up_rightApp",
"action.up_right.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_up_rightApp_user",
"action.up_right.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_doubleUpApp",
"action.double_up.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_doubleUpApp_user",
"action.double_up.user",
-1
)
migrateStringPreference(oldPrefs, newPrefs, "action_downApp", "action.down.app", "")
migrateIntPreference(oldPrefs, newPrefs, "action_downApp_user", "action.down.user", -1)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_down_leftApp",
"action.down_left.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_down_leftApp_user",
"action.down_left.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_down_rightApp",
"action.down_right.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_down_rightApp_user",
"action.down_right.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_doubleDownApp",
"action.double_down.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_doubleDownApp_user",
"action.double_down.user",
-1
)
migrateStringPreference(oldPrefs, newPrefs, "action_leftApp", "action.left.app", "")
migrateIntPreference(oldPrefs, newPrefs, "action_leftApp_user", "action.left.user", -1)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_left_topApp",
"action.left_top.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_left_topApp_user",
"action.left_top.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_left_bottomApp",
"action.left_bottom.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_left_bottomApp_user",
"action.left_bottom.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_doubleLeftApp",
"action.double_left.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_doubleLeftApp_user",
"action.double_left.user",
-1
)
migrateStringPreference(oldPrefs, newPrefs, "action_rightApp", "action.right.app", "")
migrateIntPreference(
oldPrefs,
newPrefs,
"action_rightApp_user",
"action.right.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_right_topApp",
"action.right_top.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_right_topApp_user",
"action.right_top.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_right_bottomApp",
"action.right_bottom.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_right_bottomApp_user",
"action.right_bottom.user",
-1
)
migrateStringPreference(
oldPrefs,
newPrefs,
"action_doubleRightApp",
"action.double_right.app",
""
)
migrateIntPreference(
oldPrefs,
newPrefs,
"action_doubleRightApp_user",
"action.double_right.user",
-1
)
migrateBooleanPreference(oldPrefs, newPrefs, "timeVisible", "clock.time_visible", true)
migrateBooleanPreference(oldPrefs, newPrefs, "dateVisible", "clock.date_visible", true)
migrateBooleanPreference(
oldPrefs,
newPrefs,
"dateLocalized",
"clock.date_localized",
false
)
migrateBooleanPreference(
oldPrefs,
newPrefs,
"dateTimeFlip",
"clock.date_time_flip",
false
)
migrateBooleanPreference(
oldPrefs,
newPrefs,
"disableTimeout",
"display.disable_timeout",
false
)
migrateBooleanPreference(
oldPrefs,
newPrefs,
"useFullScreen",
"display.use_full_screen",
true
)
migrateBooleanPreference(
oldPrefs,
newPrefs,
"enableDoubleActions",
"enabled_gestures.double_actions",
true
)
migrateBooleanPreference(
oldPrefs,
newPrefs,
"enableEdgeActions",
"enabled_gestures.edge_actions",
true
)
migrateBooleanPreference(
oldPrefs,
newPrefs,
"searchAutoLaunch",
"functionality.search_auto_launch",
true
)
migrateBooleanPreference(
oldPrefs,
newPrefs,
"searchAutoKeyboard",
"functionality.search_auto_keyboard",
true
)
newPrefs.apply()
migrateStringPreference(
oldPrefs,
this,
"action_volumeUpApp",
"action.volume_up.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_volumeUpApp_user",
"action.volume_up.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_volumeDownApp",
"action.volume_down.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_volumeDownApp_user",
"action.volume_down.user",
-1
)
migrateStringPreference(oldPrefs, this, "action_timeApp", "action.time.app", "")
migrateIntPreference(oldPrefs, this, "action_timeApp_user", "action.time.user", -1)
migrateStringPreference(oldPrefs, this, "action_dateApp", "action.date.app", "")
migrateIntPreference(oldPrefs, this, "action_dateApp_user", "action.date.user", -1)
migrateStringPreference(
oldPrefs,
this,
"action_longClickApp",
"action.long_click.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_longClickApp_user",
"action.long_click.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_doubleClickApp",
"action.double_click.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_doubleClickApp_user",
"action.double_click.user",
-1
)
migrateStringPreference(oldPrefs, this, "action_upApp", "action.up.app", "")
migrateIntPreference(oldPrefs, this, "action_upApp_user", "action.up.user", -1)
migrateStringPreference(
oldPrefs,
this,
"action_up_leftApp",
"action.up_left.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_up_leftApp_user",
"action.up_left.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_up_rightApp",
"action.up_right.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_up_rightApp_user",
"action.up_right.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_doubleUpApp",
"action.double_up.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_doubleUpApp_user",
"action.double_up.user",
-1
)
migrateStringPreference(oldPrefs, this, "action_downApp", "action.down.app", "")
migrateIntPreference(oldPrefs, this, "action_downApp_user", "action.down.user", -1)
migrateStringPreference(
oldPrefs,
this,
"action_down_leftApp",
"action.down_left.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_down_leftApp_user",
"action.down_left.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_down_rightApp",
"action.down_right.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_down_rightApp_user",
"action.down_right.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_doubleDownApp",
"action.double_down.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_doubleDownApp_user",
"action.double_down.user",
-1
)
migrateStringPreference(oldPrefs, this, "action_leftApp", "action.left.app", "")
migrateIntPreference(oldPrefs, this, "action_leftApp_user", "action.left.user", -1)
migrateStringPreference(
oldPrefs,
this,
"action_left_topApp",
"action.left_top.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_left_topApp_user",
"action.left_top.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_left_bottomApp",
"action.left_bottom.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_left_bottomApp_user",
"action.left_bottom.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_doubleLeftApp",
"action.double_left.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_doubleLeftApp_user",
"action.double_left.user",
-1
)
migrateStringPreference(oldPrefs, this, "action_rightApp", "action.right.app", "")
migrateIntPreference(
oldPrefs,
this,
"action_rightApp_user",
"action.right.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_right_topApp",
"action.right_top.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_right_topApp_user",
"action.right_top.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_right_bottomApp",
"action.right_bottom.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_right_bottomApp_user",
"action.right_bottom.user",
-1
)
migrateStringPreference(
oldPrefs,
this,
"action_doubleRightApp",
"action.double_right.app",
""
)
migrateIntPreference(
oldPrefs,
this,
"action_doubleRightApp_user",
"action.double_right.user",
-1
)
migrateBooleanPreference(oldPrefs, this, "timeVisible", "clock.time_visible", true)
migrateBooleanPreference(oldPrefs, this, "dateVisible", "clock.date_visible", true)
migrateBooleanPreference(
oldPrefs,
this,
"dateLocalized",
"clock.date_localized",
false
)
migrateBooleanPreference(
oldPrefs,
this,
"dateTimeFlip",
"clock.date_time_flip",
false
)
migrateBooleanPreference(
oldPrefs,
this,
"disableTimeout",
"display.disable_timeout",
false
)
migrateBooleanPreference(
oldPrefs,
this,
"useFullScreen",
"display.use_full_screen",
true
)
migrateBooleanPreference(
oldPrefs,
this,
"enableDoubleActions",
"enabled_gestures.double_actions",
true
)
migrateBooleanPreference(
oldPrefs,
this,
"enableEdgeActions",
"enabled_gestures.edge_actions",
true
)
migrateBooleanPreference(
oldPrefs,
this,
"searchAutoLaunch",
"functionality.search_auto_launch",
true
)
migrateBooleanPreference(
oldPrefs,
this,
"searchAutoKeyboard",
"functionality.search_auto_keyboard",
true
)
}
when (oldPrefs.getString("theme", "finn")) {
"finn" -> {

View file

@ -5,7 +5,6 @@ import android.content.res.Resources
import com.google.android.material.color.DynamicColors
import de.jrpie.android.launcher.R
@Suppress("unused")
enum class ColorTheme(
private val id: Int,
private val labelResource: Int,

View file

@ -57,6 +57,8 @@ class HomeActivity : UIObject, AppCompatActivity() {
super<UIObject>.onCreate()
val displayMetrics = DisplayMetrics()
@Suppress("deprecation") // required to support API < 30
windowManager.defaultDisplay.getMetrics(displayMetrics)
val width = displayMetrics.widthPixels
@ -78,6 +80,7 @@ class HomeActivity : UIObject, AppCompatActivity() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
binding.root.setOnApplyWindowInsetsListener { _, windowInsets ->
@Suppress("deprecation") // required to support API 29
val insets = windowInsets.systemGestureInsets
touchGestureDetector.setSystemGestureInsets(insets)

View file

@ -24,6 +24,7 @@ import de.jrpie.android.launcher.actions.ShortcutAction
import de.jrpie.android.launcher.apps.PinnedShortcutInfo
import de.jrpie.android.launcher.databinding.ActivityPinShortcutBinding
import de.jrpie.android.launcher.preferences.LauncherPreferences
import androidx.core.content.edit
class PinShortcutActivity : AppCompatActivity(), UIObject {
private lateinit var binding: ActivityPinShortcutBinding
@ -72,9 +73,12 @@ class PinShortcutActivity : AppCompatActivity(), UIObject {
isBound = true
request.accept()
}
val editor = LauncherPreferences.getSharedPreferences().edit()
ShortcutAction(PinnedShortcutInfo(request.shortcutInfo!!)).bindToGesture(editor, gesture.id)
editor.apply()
LauncherPreferences.getSharedPreferences().edit {
ShortcutAction(PinnedShortcutInfo(request.shortcutInfo!!)).bindToGesture(
this,
gesture.id
)
}
dialog.dismiss()
}
dialog.findViewById<RecyclerView>(R.id.dialog_select_gesture_recycler).apply {
@ -117,11 +121,11 @@ class PinShortcutActivity : AppCompatActivity(), UIObject {
}
inner class GestureRecyclerAdapter(val context: Context, val onClick: (Gesture) -> Unit): RecyclerView.Adapter<GestureRecyclerAdapter.ViewHolder>() {
val gestures = Gesture.entries.filter { it.isEnabled() }.toList()
private val gestures = Gesture.entries.filter { it.isEnabled() }.toList()
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val label = itemView.findViewById<TextView>(R.id.dialog_select_gesture_row_name)
val description = itemView.findViewById<TextView>(R.id.dialog_select_gesture_row_description)
val icon = itemView.findViewById<ImageView>(R.id.dialog_select_gesture_row_icon)
val label: TextView = itemView.findViewById(R.id.dialog_select_gesture_row_name)
val description: TextView = itemView.findViewById(R.id.dialog_select_gesture_row_description)
val icon: ImageView = itemView.findViewById(R.id.dialog_select_gesture_row_icon)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

View file

@ -15,8 +15,10 @@ import de.jrpie.android.launcher.preferences.LauncherPreferences
* An interface implemented by every [Activity], Fragment etc. in Launcher.
* It handles themes and window flags - a useful abstraction as it is the same everywhere.
*/
@Suppress("deprecation") // FLAG_FULLSCREEN is required to support API level < 30
fun setWindowFlags(window: Window, homeScreen: Boolean) {
window.setFlags(0, 0) // clear flags
// Display notification bar
if (LauncherPreferences.display().hideStatusBar())
window.setFlags(

View file

@ -1,24 +1,18 @@
package de.jrpie.android.launcher.ui.list
import android.app.Activity
import android.content.Intent
import android.content.res.Resources
import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.view.View
import android.widget.Toast
import android.window.OnBackInvokedDispatcher
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.content.res.AppCompatResources
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayoutMediator
import de.jrpie.android.launcher.Application
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.REQUEST_UNINSTALL
import de.jrpie.android.launcher.actions.LauncherAction
import de.jrpie.android.launcher.apps.AppFilter
import de.jrpie.android.launcher.apps.hidePrivateSpaceWhenLocked
@ -115,10 +109,13 @@ class ListActivity : AppCompatActivity(), UIObject {
?.let { ListActivityIntention.valueOf(it) }
?: ListActivityIntention.VIEW
@Suppress("deprecation") // required to support API level < 33
favoritesVisibility = bundle.getSerializable("favoritesVisibility")
as? AppFilter.Companion.AppSetVisibility ?: favoritesVisibility
@Suppress("deprecation") // required to support API level < 33
privateSpaceVisibility = bundle.getSerializable("privateSpaceVisibility")
as? AppFilter.Companion.AppSetVisibility ?: privateSpaceVisibility
@Suppress("deprecation") // required to support API level < 33
hiddenVisibility = bundle.getSerializable("hiddenVisibility")
as? AppFilter.Companion.AppSetVisibility ?: hiddenVisibility
@ -185,20 +182,6 @@ class ListActivity : AppCompatActivity(), UIObject {
finish()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_UNINSTALL) {
if (resultCode == Activity.RESULT_OK) {
Toast.makeText(this, getString(R.string.list_removed), Toast.LENGTH_LONG).show()
finish()
} else if (resultCode == Activity.RESULT_FIRST_USER) {
Toast.makeText(this, getString(R.string.list_not_removed), Toast.LENGTH_LONG).show()
finish()
}
}
}
fun updateTitle() {
var titleResource = intention.titleResource
if (intention == ListActivityIntention.VIEW) {
@ -241,11 +224,14 @@ class ListActivity : AppCompatActivity(), UIObject {
updateTitle()
val sectionsPagerAdapter = ListSectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = findViewById(R.id.list_viewpager)
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.list_tabs)
tabs.setupWithViewPager(viewPager)
val sectionsPagerAdapter = ListSectionsPagerAdapter(this)
binding.listViewpager.apply {
adapter = sectionsPagerAdapter
currentItem = 0
}
TabLayoutMediator(binding.listTabs, binding.listViewpager) { tab, position ->
tab.text = sectionsPagerAdapter.getPageTitle(position)
}.attach()
}
}
@ -258,10 +244,10 @@ private val TAB_TITLES = arrayOf(
* The [ListSectionsPagerAdapter] returns the fragment,
* which corresponds to the selected tab in [ListActivity].
*/
class ListSectionsPagerAdapter(private val activity: ListActivity, fm: FragmentManager) :
FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
class ListSectionsPagerAdapter(private val activity: ListActivity) :
FragmentStateAdapter(activity) {
override fun getItem(position: Int): Fragment {
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> ListFragmentApps()
1 -> ListFragmentOther()
@ -269,11 +255,11 @@ class ListSectionsPagerAdapter(private val activity: ListActivity, fm: FragmentM
}
}
override fun getPageTitle(position: Int): CharSequence {
fun getPageTitle(position: Int): CharSequence {
return activity.resources.getString(TAB_TITLES[position])
}
override fun getCount(): Int {
override fun getItemCount(): Int {
return when (activity.intention) {
ListActivity.ListActivityIntention.VIEW -> 1
else -> 2

View file

@ -2,7 +2,6 @@ package de.jrpie.android.launcher.ui.list.apps
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Rect
import android.view.LayoutInflater
import android.view.View
@ -15,7 +14,8 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import de.jrpie.android.launcher.Application
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
import de.jrpie.android.launcher.actions.Action
import de.jrpie.android.launcher.actions.Gesture
import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo
import de.jrpie.android.launcher.apps.AppFilter
import de.jrpie.android.launcher.apps.AppInfo
@ -195,11 +195,10 @@ class AppsRecyclerAdapter(
}
ListActivity.ListActivityIntention.PICK -> {
val returnIntent = Intent()
appInfo.getAction().writeToIntent(returnIntent)
returnIntent.putExtra("forGesture", forGesture)
activity.setResult(REQUEST_CHOOSE_APP, returnIntent)
activity.finish()
forGesture ?: return
val gesture = Gesture.byId(forGesture) ?: return
Action.setActionForGesture(gesture, appInfo.getAction())
}
}
}

View file

@ -6,7 +6,6 @@ import android.content.Context
import android.content.Intent
import android.content.pm.LauncherApps
import android.graphics.Rect
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.View
@ -14,11 +13,9 @@ import android.widget.EditText
import androidx.appcompat.app.AlertDialog
import com.google.android.material.snackbar.Snackbar
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.REQUEST_UNINSTALL
import de.jrpie.android.launcher.apps.AppInfo
import de.jrpie.android.launcher.apps.AbstractAppInfo
import de.jrpie.android.launcher.apps.AbstractDetailedAppInfo
import de.jrpie.android.launcher.apps.DetailedAppInfo
import de.jrpie.android.launcher.apps.PinnedShortcutInfo
import de.jrpie.android.launcher.getUserFromId
import de.jrpie.android.launcher.preferences.LauncherPreferences
@ -44,17 +41,13 @@ fun AbstractAppInfo.uninstall(activity: Activity) {
Log.i(LOG_TAG, "uninstalling $this")
val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE)
val intent = Intent(Intent.ACTION_DELETE)
intent.data = "package:$packageName".toUri()
getUserFromId(userId, activity).let { user ->
intent.putExtra(Intent.EXTRA_USER, user)
}
activity.startActivity(intent)
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
activity.startActivityForResult(
intent,
REQUEST_UNINSTALL
)
} else if(this is PinnedShortcutInfo) {
val pinned = LauncherPreferences.apps().pinnedShortcuts() ?: mutableSetOf()
pinned.remove(this)
@ -102,8 +95,8 @@ fun AbstractDetailedAppInfo.showRenameDialog(context: Context) {
AlertDialog.Builder(context, R.style.AlertDialogCustom).apply {
setTitle(context.getString(R.string.dialog_rename_title, getLabel()))
setView(R.layout.dialog_rename_app)
setNegativeButton(R.string.dialog_cancel) { d, _ -> d.cancel() }
setPositiveButton(R.string.dialog_rename_ok) { d, _ ->
setNegativeButton(android.R.string.cancel) { d, _ -> d.cancel() }
setPositiveButton(android.R.string.ok) { d, _ ->
setCustomLabel(
(d as? AlertDialog)
?.findViewById<EditText>(R.id.dialog_rename_app_edit_text)

View file

@ -1,7 +1,6 @@
package de.jrpie.android.launcher.ui.list.other
import android.app.Activity
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -9,7 +8,8 @@ import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
import de.jrpie.android.launcher.actions.Action
import de.jrpie.android.launcher.actions.Gesture
import de.jrpie.android.launcher.actions.LauncherAction
import de.jrpie.android.launcher.ui.list.ListActivity
@ -36,7 +36,10 @@ class OtherRecyclerAdapter(val activity: Activity) :
val pos = bindingAdapterPosition
val content = othersList[pos]
(activity as? ListActivity)?.forGesture?.let { returnChoiceIntent(it, content) }
activity.finish()
val gestureId = (activity as? ListActivity)?.forGesture ?: return
val gesture = Gesture.byId(gestureId) ?: return
Action.setActionForGesture(gesture, content)
}
init {
@ -61,12 +64,4 @@ class OtherRecyclerAdapter(val activity: Activity) :
val view: View = inflater.inflate(R.layout.list_other_row, parent, false)
return ViewHolder(view)
}
private fun returnChoiceIntent(forGesture: String, action: LauncherAction) {
val returnIntent = Intent()
returnIntent.putExtra("forGesture", forGesture)
action.writeToIntent(returnIntent)
activity.setResult(REQUEST_CHOOSE_APP, returnIntent)
activity.finish()
}
}

View file

@ -1,6 +1,5 @@
package de.jrpie.android.launcher.ui.settings
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.Resources
@ -8,17 +7,14 @@ import android.os.Bundle
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayoutMediator
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
import de.jrpie.android.launcher.databinding.SettingsBinding
import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.preferences.theme.Background
import de.jrpie.android.launcher.preferences.theme.ColorTheme
import de.jrpie.android.launcher.saveListActivityChoice
import de.jrpie.android.launcher.ui.UIObject
import de.jrpie.android.launcher.ui.settings.actions.SettingsFragmentActions
import de.jrpie.android.launcher.ui.settings.launcher.SettingsFragmentLauncher
@ -49,15 +45,15 @@ class SettingsActivity : AppCompatActivity(), UIObject {
// This ugly workaround causes a jump to the top of the list, but at least
// the text stays readable.
val i = Intent(this, SettingsActivity::class.java)
.also { it.putExtra("tab", 1) }
.also { it.putExtra(EXTRA_TAB, 1) }
finish()
startActivity(i)
} else
if (prefKey?.startsWith("theme.") == true ||
prefKey?.startsWith("display.") == true
) {
recreate()
}
if (prefKey?.startsWith("theme.") == true ||
prefKey?.startsWith("display.") == true
) {
recreate()
}
}
private lateinit var binding: SettingsBinding
@ -71,15 +67,14 @@ class SettingsActivity : AppCompatActivity(), UIObject {
setContentView(binding.root)
// set up tabs and swiping in settings
val sectionsPagerAdapter = SettingsSectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = findViewById(R.id.settings_viewpager)
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.settings_tabs)
tabs.setupWithViewPager(viewPager)
if (intent.hasExtra("tab")) {
tabs.getTabAt(intent.getIntExtra("tab", 0))?.select()
val sectionsPagerAdapter = SettingsSectionsPagerAdapter(this)
binding.settingsViewpager.apply {
adapter = sectionsPagerAdapter
setCurrentItem(intent.getIntExtra(EXTRA_TAB, 0), false)
}
TabLayoutMediator(binding.settingsTabs, binding.settingsViewpager) { tab, position ->
tab.text = sectionsPagerAdapter.getPageTitle(position)
}.attach()
}
override fun onStart() {
@ -108,11 +103,8 @@ class SettingsActivity : AppCompatActivity(), UIObject {
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_CHOOSE_APP -> saveListActivityChoice(data)
else -> super.onActivityResult(requestCode, resultCode, data)
}
companion object {
private const val EXTRA_TAB = "tab"
}
}
@ -122,10 +114,10 @@ private val TAB_TITLES = arrayOf(
R.string.settings_tab_meta
)
class SettingsSectionsPagerAdapter(private val context: Context, fm: FragmentManager) :
FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
class SettingsSectionsPagerAdapter(private val activity: FragmentActivity) :
FragmentStateAdapter(activity) {
override fun getItem(position: Int): Fragment {
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> SettingsFragmentActions()
1 -> SettingsFragmentLauncher()
@ -134,11 +126,11 @@ class SettingsSectionsPagerAdapter(private val context: Context, fm: FragmentMan
}
}
override fun getPageTitle(position: Int): CharSequence {
return context.resources.getString(TAB_TITLES[position])
fun getPageTitle(position: Int): CharSequence {
return activity.resources.getString(TAB_TITLES[position])
}
override fun getCount(): Int {
override fun getItemCount(): Int {
return 3
}
}

View file

@ -16,7 +16,6 @@ import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
import de.jrpie.android.launcher.actions.Action
import de.jrpie.android.launcher.actions.Gesture
import de.jrpie.android.launcher.apps.AppFilter
@ -179,9 +178,6 @@ class ActionsRecyclerAdapter(val activity: Activity) :
intent.putExtra("intention", ListActivity.ListActivityIntention.PICK.toString())
intent.putExtra("hiddenVisibility", AppFilter.Companion.AppSetVisibility.VISIBLE)
intent.putExtra("forGesture", gesture.id) // for which action we choose the app
activity.startActivityForResult(
intent,
REQUEST_CHOOSE_APP
)
activity.startActivity(intent)
}
}

View file

@ -2,7 +2,6 @@ package de.jrpie.android.launcher.ui.settings.meta
import android.app.AlertDialog
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -20,7 +19,6 @@ import de.jrpie.android.launcher.openTutorial
import de.jrpie.android.launcher.preferences.resetPreferences
import de.jrpie.android.launcher.ui.LegalInfoActivity
import de.jrpie.android.launcher.ui.UIObject
import de.jrpie.android.launcher.ui.tutorial.TutorialActivity
/**
* The [SettingsFragmentMeta] is a used as a tab in the SettingsActivity.

View file

@ -1,6 +1,5 @@
package de.jrpie.android.launcher.ui.tutorial
import android.content.Intent
import android.content.res.Resources
import android.os.Build
import android.os.Bundle
@ -12,10 +11,8 @@ import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayoutMediator
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
import de.jrpie.android.launcher.databinding.TutorialBinding
import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.saveListActivityChoice
import de.jrpie.android.launcher.ui.UIObject
import de.jrpie.android.launcher.ui.blink
import de.jrpie.android.launcher.ui.tutorial.tabs.TutorialFragment0Start
@ -36,6 +33,7 @@ class TutorialActivity : AppCompatActivity(), UIObject {
private lateinit var binding: TutorialBinding
override fun onCreate(savedInstanceState: Bundle?) {
super<AppCompatActivity>.onCreate(savedInstanceState)
super<UIObject>.onCreate()
@ -113,14 +111,9 @@ class TutorialActivity : AppCompatActivity(), UIObject {
super<UIObject>.onStart()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_CHOOSE_APP -> saveListActivityChoice(data)
else -> super.onActivityResult(requestCode, resultCode, data)
}
}
// prevent going back when the tutorial is shown for the first time
@Deprecated("Deprecated in Java", ReplaceWith("use anyway"))
@Suppress("deprecation") // support API level < 33
override fun onBackPressed() {
if (LauncherPreferences.internal().started())
super.onBackPressed()

View file

@ -12,6 +12,7 @@ class HtmlTextView(context: Context, attr: AttributeSet?, int: Int) :
constructor(context: Context) : this(context, null, 0)
init {
@Suppress("deprecation") // required to support API level < 24
text = Html.fromHtml(text.toString())
movementMethod = LinkMovementMethod.getInstance()
}

View file

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 124 KiB

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -1,11 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path
android:fillColor="?android:textColor"
android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
</vector>

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#252827"
android:pathData="M0,0h108v108h-108z" />
</vector>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://stackoverflow.com/a/30692466 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp" />
</shape>

View file

@ -116,7 +116,7 @@
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pin_shortcut_button_ok"
android:text="@android:string/ok"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -95,7 +95,7 @@
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/list_viewpager"
android:layout_width="0dp"
android:layout_height="0dp"

View file

@ -73,7 +73,7 @@
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/settings_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"

View file

@ -33,7 +33,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tutorial_setup_title" />
<fragment
<androidx.fragment.app.FragmentContainerView
android:id="@+id/tutorial_setup_actions_rview_fragment"
android:name="de.jrpie.android.launcher.ui.settings.actions.SettingsFragmentActionsRecycler"
android:layout_width="0dp"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

View file

@ -67,7 +67,6 @@
<string name="settings_gesture_time">Uhr</string>
<string name="settings_gesture_description_time">Auf die Uhrzeit klicken</string>
<string name="settings_apps_choose">App wählen</string>
<string name="settings_apps_view_all">Alle Anwendungen</string>
<string name="settings_apps_install">Apps installieren</string>
<string name="settings_apps_toast_store_not_found">Store nicht gefunden</string>
<!--
@ -94,10 +93,8 @@
<string name="settings_theme_color_theme_item_dark">Dunkel</string>
<string name="settings_theme_color_theme_item_light">Hell</string>
<string name="settings_theme_wallpaper">Hintergrund auswählen</string>
<string name="settings_launcher_change_wallpaper">Hintergrund ändern</string>
<string name="settings_launcher_section_display">Bildschirm</string>
<string name="settings_display_screen_timeout_disabled">Bildschirm nicht ausschalten</string>
<string name="settings_display_full_screen">Vollbild</string>
<string name="settings_display_rotate_screen">Bildschirm drehen</string>
<string name="settings_launcher_section_functionality">Funktionalität</string>
<string name="settings_enabled_gestures_double_swipe">Doppelte Wischaktionen</string>
@ -118,7 +115,6 @@
<string name="settings_list_layout_item_grid">Raster</string>
<string name="settings_general_choose_home_screen">Launcher wählen</string>
<string name="settings_meta_cant_select_launcher">App Info</string>
<string name="settings_meta_cant_select_launcher_msg">Das Gerät unterstützt diese Funktion nicht. Stattdessen die App Details bearbeiten?</string>
<string name="settings_meta_show_tutorial">Zum Tutorial</string>
<string name="settings_meta_reset">Einstellungen zurücksetzen</string>
<string name="settings_meta_reset_confirm">Alle Einstellungen gehen verloren. Weitermachen?</string>
@ -145,8 +141,6 @@
<string name="list_app_info">App Info</string>
<string name="list_app_hidden_remove">Sichtbar machen</string>
<string name="list_app_rename">Umbenennen</string>
<string name="list_removed">Die App wurde entfernt</string>
<string name="list_not_removed">Die App konnte nicht entfernt werden</string>
<string name="list_apps_search_hint">Anwendungen suchen</string>
<string name="list_apps_search_hint_no_auto_launch">Suchen (kein Schnellstart)</string>
<string name="list_other_settings">µLauncher Einstellungen</string>

View file

@ -46,7 +46,6 @@
<string name="settings_gesture_date">Toca la fecha</string>
<string name="settings_gesture_time">Toca el reloj</string>
<string name="settings_apps_choose">Elegir Aplicación</string>
<string name="settings_apps_view_all">Todas las aplicaciones</string>
<string name="settings_apps_install">Instalar aplicaciones</string>
<string name="settings_apps_toast_store_not_found">No se encontró la Store</string>
<!--
@ -60,10 +59,8 @@
<string name="settings_theme_color_theme_item_dark">Oscuro</string>
<string name="settings_theme_color_theme_item_light">Luminoso</string>
<string name="settings_theme_wallpaper">Seleccionar fondo de pantalla</string>
<string name="settings_launcher_change_wallpaper">Cambiar fondo de pantalla</string>
<string name="settings_launcher_section_display">Pantalla</string>
<string name="settings_display_screen_timeout_disabled">Mantener encendida</string>
<string name="settings_display_full_screen">Pantalla completa</string>
<string name="settings_launcher_section_functionality">Funciones</string>
<string name="settings_enabled_gestures_double_swipe">Deslizar con dos dedos</string>
<string name="settings_functionality_auto_launch">Auto-lanzar búsquedas</string>
@ -76,7 +73,6 @@
-->
<string name="settings_general_choose_home_screen">Seleccionar Launcher</string>
<string name="settings_meta_cant_select_launcher">Información de la aplicación</string>
<string name="settings_meta_cant_select_launcher_msg">Su dispositivo no posee esta caracrerística. Desea cambiar los detalles de la aplicación?</string>
<string name="settings_meta_show_tutorial">Ver tutorial de Launcher</string>
<string name="settings_meta_reset">Configuración por defecto</string>
<string name="settings_meta_reset_confirm">Todas sus preferencias se eliminarán. Desea continuar?</string>
@ -96,8 +92,6 @@
<string name="list_tab_other">Otros</string>
<string name="list_app_delete">Desinstalar</string>
<string name="list_app_info">Información</string>
<string name="list_removed">Se eliminó la aplicación</string>
<string name="list_not_removed">No se pudo eliminar la aplicación</string>
<string name="list_apps_search_hint">Buscar Aplicaciones</string>
<string name="list_other_settings">Configuración de Launcher</string>
<string name="list_other_list">Aplicaciones</string>

View file

@ -37,7 +37,6 @@
<string name="settings_gesture_date">Date</string>
<string name="settings_gesture_time">Horloge</string>
<string name="settings_apps_choose">Choisir une application</string>
<string name="settings_apps_view_all">Voir toutes les applications</string>
<string name="settings_apps_install">Installer des applications</string>
<string name="settings_apps_toast_store_not_found">Magasin d\'applications introuvable</string>
<!--
@ -52,10 +51,8 @@
<string name="settings_theme_color_theme_item_dark">Sombre</string>
<string name="settings_theme_color_theme_item_light">Clair</string>
<string name="settings_theme_wallpaper">Choisir un fond d\'écran</string>
<string name="settings_launcher_change_wallpaper">Changer le fond d\'écran</string>
<string name="settings_launcher_section_display">Écran</string>
<string name="settings_display_screen_timeout_disabled">Garder l\'écran allumé</string>
<string name="settings_display_full_screen">Utiliser le plein écran</string>
<string name="settings_launcher_section_functionality">Fonctions</string>
<string name="settings_enabled_gestures_double_swipe">Actions de double balayage</string>
<string name="settings_functionality_auto_launch">Lancer apps par recherche</string>
@ -68,7 +65,6 @@
-->
<string name="settings_general_choose_home_screen">Choisir μLauncher comme application d\'écran d\'accueil par défaut</string>
<string name="settings_meta_cant_select_launcher">Informations sur l\'application</string>
<string name="settings_meta_cant_select_launcher_msg">Votre appareil ne prend pas en charge cette fonctionnalité. Souhaitez-vous plutôt accéder aux détails de l\'application ?</string>
<string name="settings_meta_show_tutorial">Regarder le tutoriel</string>
<string name="settings_meta_reset">Réinitialiser</string>
<string name="settings_meta_reset_confirm">Vous allez réinitialiser tous vos paramètres. Souhaitez-vous poursuivre ?</string>
@ -88,8 +84,6 @@
<string name="list_tab_other">Autre</string>
<string name="list_app_delete">Désinstaller</string>
<string name="list_app_info">Informations</string>
<string name="list_removed">Application supprimée</string>
<string name="list_not_removed">Impossible de désinstaller l\'application</string>
<string name="list_apps_search_hint">Chercher des applications</string>
<string name="list_other_settings">Réglages d\'µLauncher</string>
<string name="list_other_list">Toutes les Applications</string>

View file

@ -34,7 +34,6 @@
<br/><br/><br/><br/>
Puoi cambiare le tue scelte in seguito nelle impostazioni.
]]></string>
<string name="settings_meta_cant_select_launcher_msg">Il tuo dispositivo non supporta questa funzione. Vuoi aprire la pagina di dettaglio dell\'applicazione?</string>
<string name="alert_cant_open_title">Impossibile aprire l\'applicazione</string>
<string name="alert_cant_open_message">Desideri modificare le impostazioni?</string>
<string name="toast_cant_open_message">Apri le impostazioni per abbinare un\'azione a questo gesto</string>
@ -83,7 +82,6 @@
<string name="settings_gesture_description_vol_up">Premi il pulsante di aumento del volume</string>
<string name="settings_gesture_vol_down">Riduci il volume</string>
<string name="settings_gesture_description_vol_down">Premi il pulsante per ridurre il volume</string>
<string name="settings_apps_view_all">Vedi tutte le applicazioni</string>
<string name="settings_apps_install">Installa le applicazioni</string>
<string name="settings_theme_monochrome_icons">Icone monocromatiche</string>
<string name="settings_clock_time_visible">Mostra l\'ora</string>
@ -112,10 +110,8 @@
<string name="settings_theme_font">Font</string>
<string name="settings_clock_flip_date_time">Inverti data e ora</string>
<string name="settings_theme_wallpaper">Scegli uno sfondo</string>
<string name="settings_launcher_change_wallpaper">Cambia immagine di sfondo</string>
<string name="settings_launcher_section_display">Schermo</string>
<string name="settings_display_screen_timeout_disabled">Mantieni lo schermo acceso</string>
<string name="settings_display_full_screen">Schermo intero</string>
<string name="settings_display_rotate_screen">Ruota lo schermo</string>
<string name="settings_launcher_section_functionality">Funzionalità</string>
<string name="settings_functionality_auto_keyboard">Apri automaticamente la tastiera per cercare</string>
@ -181,7 +177,6 @@
<string name="list_app_hidden_add">Nascondi</string>
<string name="list_app_hidden_remove">Mostra</string>
<string name="list_app_rename">Rinomina</string>
<string name="list_removed">Le applicazioni selezionate sono state rimosse</string>
<string name="list_apps_search_hint">Cerca</string>
<string name="list_other_settings">Impostazioni μLauncher</string>
<string name="list_other_expand_notifications_panel">Espandi il pannello notifiche</string>
@ -197,7 +192,6 @@
<string name="alert_requires_android_m">Questa funzione richiede Android 6 o successivi.</string>
<string name="dialog_rename_ok">Ok</string>
<string name="dialog_rename_title">Rinomina %1$s</string>
<string name="list_not_removed">Impossibile rimuovere l\'applicazione</string>
<string name="settings_theme_color_theme_item_dynamic">Dinamico</string>
<string name="settings_clock_color">Colore</string>
<string name="settings_gesture_double_up">Due dita verso l\'alto</string>

View file

@ -45,7 +45,6 @@
<string name="settings_gesture_date">Data</string>
<string name="settings_gesture_time">Hora</string>
<string name="settings_apps_choose">Selecione um app</string>
<string name="settings_apps_view_all">Ver todos os apps</string>
<string name="settings_apps_install">Instalar aplicativos</string>
<string name="settings_apps_toast_store_not_found">Loja não encontrada</string>
<!--
@ -63,10 +62,8 @@
<string name="settings_clock_localized">Use formato de data localizado</string>
<string name="settings_clock_flip_date_time">Inverter data e hora</string>
<string name="settings_theme_wallpaper">Escolha papel de parede</string>
<string name="settings_launcher_change_wallpaper">Alterar papel de parede</string>
<string name="settings_launcher_section_display">Exibição</string>
<string name="settings_display_screen_timeout_disabled">Manter a tela ligada</string>
<string name="settings_display_full_screen">Usar tela cheia</string>
<string name="settings_launcher_section_functionality">Funcionalidades</string>
<string name="settings_enabled_gestures_double_swipe">Gestos com 2 dedos</string>
<string name="settings_enabled_gestures_edge_swipe">Ações de deslize nas bordas</string>
@ -80,7 +77,6 @@
-->
<string name="settings_general_choose_home_screen">Definir o μLauncher como tela inicial</string>
<string name="settings_meta_cant_select_launcher">Informações do aplicativo</string>
<string name="settings_meta_cant_select_launcher_msg">Seu dispositivo não é compatível com esse recurso. Gerenciar detalhes do app em vez disso?</string>
<string name="settings_meta_show_tutorial">Ver tutorial do launcher</string>
<string name="settings_meta_reset">Redefinir configuraçãos</string>
<string name="settings_meta_reset_confirm">Você vai descartar todas as suas preferências. Continuar?</string>
@ -100,8 +96,6 @@
<string name="list_tab_other">Outros</string>
<string name="list_app_delete">Desinstalar</string>
<string name="list_app_info">Informações do aplicativo</string>
<string name="list_removed">O app selecionado foi removido</string>
<string name="list_not_removed">Não foi possível remover o app</string>
<string name="list_apps_search_hint">Busque</string>
<string name="list_other_settings">Configurações do µLauncher</string>
<string name="list_other_list">Todos os apps</string>

View file

@ -105,7 +105,6 @@
<string name="settings_gesture_time">Saat</string>
<string name="settings_gesture_description_time">Saate tıklayın</string>
<string name="settings_apps_choose">Uygulama Seçin</string>
<string name="settings_apps_view_all">Tüm uygulamaları göster</string>
<string name="settings_apps_install">Uygulamaları yükle</string>
<string name="settings_apps_toast_store_not_found">Mağaza bulunamadı</string>
<string name="settings_launcher_section_appearance">Görünüş</string>
@ -120,8 +119,6 @@
<string name="list_other_nop">Hiçbir şey yapma</string>
<string name="settings_meta_view_code">Kaynak kodunu göster</string>
<string name="settings_meta_report_bug">Hatayı bildirin</string>
<string name="list_removed">Seçilen uygulama kaldırıldı</string>
<string name="list_not_removed">Uygulama kaldırılamadı</string>
<string name="list_apps_search_hint">Uygulamaları Ara</string>
<string name="list_other_list">Tüm Uygulamalar</string>
<string name="list_other_list_favorites">Favori Uygulamalar</string>
@ -134,10 +131,8 @@
<string name="settings_clock_show_seconds">Saniyeleri gösteri</string>
<string name="settings_clock_flip_date_time">Tarih ile zamanı yer değiştir</string>
<string name="settings_theme_wallpaper">Duvar kağıdı seç</string>
<string name="settings_launcher_change_wallpaper">Duvar kağıdını değiştir</string>
<string name="settings_launcher_section_display">Ekran</string>
<string name="settings_display_screen_timeout_disabled">Ekranıık tut</string>
<string name="settings_display_full_screen">Tam ekran kullan</string>
<string name="settings_display_rotate_screen">Ekranı döndür</string>
<string name="settings_launcher_section_functionality">İşlevsellik</string>
<string name="settings_enabled_gestures_edge_swipe_summary">Ekranın köşesinden kaydırın</string>
@ -165,7 +160,6 @@
<string name="settings_list_layout_item_text">Metin</string>
<string name="settings_list_layout_item_grid">Izgara</string>
<string name="settings_meta_cant_select_launcher">Uygulama Detayı</string>
<string name="settings_meta_cant_select_launcher_msg">Sizin cihazınız bu özelliği desteklemiyor. Onun yerine uygulama detaylarını düzenleyin?</string>
<string name="settings_meta_reset">Ayarları Sıfırlayın</string>
<string name="settings_meta_reset_confirm">Tüm tercihlerinizi bir kenara bırakacaksınız. Devam mı?</string>
<string name="settings_theme_font_item_monospace">Tek uzay</string>

View file

@ -1,6 +0,0 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>

View file

@ -37,21 +37,17 @@
<string name="settings_gesture_date">日期</string>
<string name="settings_gesture_time">时间</string>
<string name="settings_apps_choose">选择应用</string>
<string name="settings_apps_view_all">浏览全部应用</string>
<string name="settings_apps_install">安装应用</string>
<string name="settings_apps_toast_store_not_found">没有找到应用市场</string>
<string name="settings_launcher_section_date_time"><![CDATA[日期和时间]]></string>
<string name="settings_theme_wallpaper">选择一个壁纸</string>
<string name="settings_launcher_change_wallpaper">换壁纸</string>
<string name="settings_display_screen_timeout_disabled">保持屏幕常亮</string>
<string name="settings_display_full_screen">使用全屏</string>
<string name="settings_launcher_section_functionality">功能</string>
<string name="settings_enabled_gestures_edge_swipe">边缘滑动动作</string>
<string name="settings_functionality_auto_launch">零点击启动唯一搜索结果</string>
<string name="settings_functionality_auto_keyboard">搜索时呼出键盘</string>
<string name="settings_launcher_sensitivity">灵敏度</string>
<string name="settings_meta_cant_select_launcher">应用信息</string>
<string name="settings_meta_cant_select_launcher_msg">您的设备不支持此功能。要不打开应用程序详细?</string>
<string name="settings_meta_show_tutorial">查看启动器教程</string>
<string name="settings_meta_reset">重置设置</string>
<string name="settings_meta_reset_confirm">你将放弃你所有的配置。继续吗?</string>
@ -74,8 +70,6 @@
<string name="list_tab_app">应用</string>
<string name="list_app_delete">卸载</string>
<string name="list_app_info">应用信息</string>
<string name="list_not_removed">无法移除应用</string>
<string name="list_removed">移除了选定的应用</string>
<string name="list_apps_search_hint">搜索</string>
<string name="list_other_settings">启动器设置</string>
<string name="list_other_list">全部应用</string>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#000000</color>
</resources>

View file

@ -101,8 +101,6 @@
<string name="settings_apps_choose">Choose App</string>
<string name="settings_apps_view_all">View all apps</string>
<string name="settings_apps_install">Install apps</string>
<string name="settings_apps_toast_store_not_found">Store not found</string>
@ -148,7 +146,6 @@
<string name="settings_clock_flip_date_time">Flip date and time</string>
<string name="settings_theme_wallpaper">Choose a wallpaper</string>
<string name="settings_launcher_change_wallpaper">Change wallpaper</string>
<string name="settings_launcher_section_display">Display</string>
@ -240,9 +237,6 @@
<string name="list_app_hidden_remove">Show</string>
<string name="list_app_rename">Rename</string>
<string name="list_removed">Removed the selected application</string>
<string name="list_not_removed">Unable to remove application</string>
<string name="list_apps_search_hint">Search</string>
<string name="list_apps_search_hint_no_auto_launch">Search (no auto launch)</string>
@ -265,7 +259,6 @@
<!-- Pin shortcuts -->
<string name="pin_shortcut_title">Add Shortcut</string>
<string name="pin_shortcut_button_bind">Bind to gesture</string>
<string name="pin_shortcut_button_ok">Ok</string>
<string name="pin_shortcut_switch_visible">Show in app list</string>
<!--
@ -361,13 +354,11 @@
<string name="screen_lock_method_use_accessibility">Use Accessibility Service</string>
<string name="screen_lock_method_use_device_admin">Use Device Admin</string>
<string name="settings_actions_lock_method">Choose method for locking the screen</string>
<string name="dialog_rename_ok">Ok</string>
<string name="dialog_rename_title">Rename %1$s</string>
<string name="dialog_select_color_red">Red</string>
<string name="dialog_select_color_alpha">Alpha</string>
<string name="dialog_select_color_blue">Blue</string>
<string name="dialog_select_color_green">Green</string>
<string name="dialog_select_color_ok">Ok</string>
<string name="dialog_select_color_color_hex">Color</string>
<string name="dialog_choose_color_title">Choose color</string>
<string name="dialog_consent_accessibility_privileges">I am aware that this will grant far-reaching privileges to μLauncher.</string>

View file

@ -105,17 +105,6 @@
<item name="android:fontFamily">serif</item>
</style>
<style name="textColorWhite">
<item name="android:textColor">@color/finnmglasTheme_text_color</item>
</style>
<style name="textColorWhiteAndShadow">
<item name="android:textColor">@color/finnmglasTheme_text_color</item>
</style>
<style name="textColorBlack">
<item name="android:textColor">#000</item>
</style>
<style name="PopupMenuCustom" parent="@android:style/Widget.PopupMenu" tools:keep="@style/PopupMenuCustom">
<item name="android:popupBackground">#252827</item>
</style>

View file

@ -47,3 +47,4 @@ The complete list of changes can be viewed [here](https://github.com/jrpie/launc
---
[original-repo]: https://github.com/finnmglas/Launcher
[hack-font]: https://sourcefoundry.org/hack/

View file

@ -19,6 +19,6 @@ android.useAndroidX=true
android.enableJetifier=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
android.nonTransitiveRClass=false
android.nonFinalResIds=false
android.nonTransitiveRClass=true
android.nonFinalResIds=true
org.gradle.configuration-cache=true