diff --git a/.scripts/release.sh b/.scripts/release.sh index f207c87..dc6959d 100755 --- a/.scripts/release.sh +++ b/.scripts/release.sh @@ -1,9 +1,25 @@ #!/bin/bash + +# This script builds all variants of µLauncher to create a release, namely: +# - app-release.apk (GitHub release; used by F-Droid for reproducible builds) +# - launcher-accrescent.apks (Accrescent) +# - app-release.aab (Play Store) + +# This is only intended to work on my (@jrpie) computer. +# To use this script for building a fork you need to: +# - install bundletool.jar and +# - create a keystore and modify the variables below accordingly + export JAVA_HOME="/usr/lib/jvm/java-21-openjdk/" OUTPUT_DIR="$HOME/launcher-release" BUILD_TOOLS_DIR="$HOME/Android/Sdk/build-tools/35.0.0" + +# keystore for the default release KEYSTORE="$HOME/data/keys/launcher_jrpie.jks" +# keystore for the default accrescent release KEYSTORE_ACCRESCENT="$HOME/data/keys/launcher_jrpie_accrescent.jks" + +# keepassxc-password is a custom script to fetch passwords from my password manager KEYSTORE_PASS=$(keepassxc-password "android_keys/launcher") KEYSTORE_ACCRESCENT_PASS=$(keepassxc-password "android_keys/launcher-accrescent") @@ -11,12 +27,11 @@ if [[ $(git status --porcelain) ]]; then echo "There are uncommitted changes." read -p "Continue anyway? (y/n) " -n 1 -r - echo # (optional) move to a new line + echo if ! [[ $REPLY =~ ^[Yy]$ ]] then exit 1 fi - fi rm -rf "$OUTPUT_DIR" diff --git a/app/src/main/java/de/jrpie/android/launcher/Application.kt b/app/src/main/java/de/jrpie/android/launcher/Application.kt index 775621c..3c2e3bc 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Application.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Application.kt @@ -22,8 +22,6 @@ 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 de.jrpie.android.launcher.widgets.LauncherWidgetProvider -import de.jrpie.android.launcher.widgets.Widget import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -34,7 +32,6 @@ const val APP_WIDGET_HOST_ID = 42; class Application : android.app.Application() { val apps = MutableLiveData>() - val widgets = MutableLiveData>() val privateSpaceLocked = MutableLiveData() lateinit var appWidgetHost: AppWidgetHost lateinit var appWidgetManager: AppWidgetManager @@ -101,8 +98,6 @@ class Application : android.app.Application() { customAppNames = LauncherPreferences.apps().customNames() } else if (pref == LauncherPreferences.apps().keys().pinnedShortcuts()) { loadApps() - } else if (pref == LauncherPreferences.widgets().keys().widgets()) { - widgets.postValue(LauncherPreferences.widgets().widgets() ?: setOf()) } } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetPanelsActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetPanelsActivity.kt index b18852f..cb57fda 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetPanelsActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetPanelsActivity.kt @@ -49,7 +49,6 @@ class ManageWidgetPanelsActivity : AppCompatActivity(), UIObject { }) } binding.manageWidgetPanelsRecycler.apply { - // improve performance (since content changes don't change the layout size) setHasFixedSize(true) layoutManager = viewManager adapter = viewAdapter diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetsActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetsActivity.kt index d191b70..665a851 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetsActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/ManageWidgetsActivity.kt @@ -34,10 +34,11 @@ class ManageWidgetsActivity : Activity(), UIObject { var panelId: Int = WidgetPanel.HOME.id + + // We can't observe the livedata because this is not an AppCompatActivity private var sharedPreferencesListener = SharedPreferences.OnSharedPreferenceChangeListener { _, prefKey -> if (prefKey == LauncherPreferences.widgets().keys().widgets()) { - // We can't observe the livedata because this is not an AppCompatActivity findViewById(R.id.manage_widgets_container).updateWidgets(this, LauncherPreferences.widgets().widgets() ) @@ -63,7 +64,7 @@ class ManageWidgetsActivity : Activity(), UIObject { findViewById(R.id.manage_widgets_container).let { it.widgetPanelId = panelId - it.updateWidgets(this, (application as Application).widgets.value) + it.updateWidgets(this, LauncherPreferences.widgets().widgets()) } } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/WidgetManagerView.kt b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/WidgetManagerView.kt index 7a355f7..f6c6c0d 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/WidgetManagerView.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/WidgetManagerView.kt @@ -19,6 +19,7 @@ import androidx.core.graphics.minus import androidx.core.graphics.toRect import androidx.core.view.children import de.jrpie.android.launcher.ui.widgets.WidgetContainerView +import de.jrpie.android.launcher.widgets.GRID_SIZE import de.jrpie.android.launcher.widgets.Widget import de.jrpie.android.launcher.widgets.WidgetPanel import de.jrpie.android.launcher.widgets.WidgetPosition @@ -47,21 +48,27 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe - enum class EditMode(val resize: (dx: Int, dy: Int, rect: Rect) -> Rect) { - MOVE({ dx, dy, rect -> - Rect(rect.left + dx, rect.top + dy, rect.right + dx, rect.bottom + dy) + enum class EditMode(val resize: (dx: Int, dy: Int, screenWidth: Int, screenHeight: Int, rect: Rect) -> Rect) { + MOVE({ dx, dy, sw, sh, rect -> + val cdx = dx.coerceIn(-rect.left, sw - rect.right) + val cdy = dy.coerceIn(-rect.top, sh - rect.bottom) + Rect(rect.left + cdx, rect.top + cdy, rect.right + cdx, rect.bottom + cdy) }), - TOP({ dx, dy, rect -> - Rect(rect.left, min(rect.top + dy, rect.bottom - 200), rect.right, rect.bottom) + TOP({ dx, dy, sw, sh, rect -> + val cdy = dy.coerceIn(-rect.top, rect.bottom - rect.top - (2 * sh / GRID_SIZE) + 5) + Rect(rect.left, rect.top + cdy, rect.right, rect.bottom) }), - BOTTOM({ dx, dy, rect -> - Rect(rect.left, rect.top, rect.right, max(rect.top + 200, rect.bottom + dy)) + BOTTOM({ dx, dy, sw, sh, rect -> + val cdy = dy.coerceIn((2 * sh / GRID_SIZE) + 5 + rect.top - rect.bottom, sh - rect.bottom) + Rect(rect.left, rect.top, rect.right, rect.bottom + cdy) }), - LEFT({ dx, dy, rect -> - Rect(min(rect.left + dx, rect.right - 200), rect.top, rect.right, rect.bottom) + LEFT({ dx, dy, sw, sh, rect -> + val cdx = dx.coerceIn(-rect.left, rect.right - rect.left - (2 * sw / GRID_SIZE) + 5) + Rect(rect.left + cdx, rect.top, rect.right, rect.bottom) }), - RIGHT({ dx, dy, rect -> - Rect(rect.left, rect.top, max(rect.left + 200, rect.right + dx), rect.bottom) + RIGHT({ dx, dy, sw, sh, rect -> + val cdx = dx.coerceIn((2 * sw / GRID_SIZE) + 5 + rect.left - rect.right, sw - rect.right) + Rect(rect.left, rect.top, rect.right + cdx, rect.bottom) }), } @@ -120,6 +127,7 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe val absoluteNewPosition = view.mode?.resize( distanceX.toInt(), distanceY.toInt(), + width, height, start ) ?: return true val newPosition = WidgetPosition.fromAbsoluteRect( @@ -162,7 +170,7 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe if (widgets == null) { return } - children.mapNotNull { it as? WidgetOverlayView }.forEach { removeView(it) } + children.filter { it is WidgetOverlayView }.forEach { removeView(it) } widgets.filter { it.panelId == widgetPanelId }.forEach { widget -> WidgetOverlayView(activity).let { diff --git a/app/src/main/java/de/jrpie/android/launcher/widgets/Widget.kt b/app/src/main/java/de/jrpie/android/launcher/widgets/Widget.kt index dbe667b..e31250b 100644 --- a/app/src/main/java/de/jrpie/android/launcher/widgets/Widget.kt +++ b/app/src/main/java/de/jrpie/android/launcher/widgets/Widget.kt @@ -57,7 +57,8 @@ sealed class Widget { return Json.decodeFromString(serialized) } fun byId(context: Context, id: Int): Widget? { - return (context.applicationContext as Application).widgets.value?.firstOrNull { + // TODO: do some caching + return LauncherPreferences.widgets().widgets().firstOrNull() { it.id == id } } diff --git a/app/src/main/res/layout/dialog_choose_color.xml b/app/src/main/res/layout/dialog_choose_color.xml index 90d13c3..dc7ddca 100644 --- a/app/src/main/res/layout/dialog_choose_color.xml +++ b/app/src/main/res/layout/dialog_choose_color.xml @@ -24,6 +24,21 @@ android:layout_width="match_parent" android:layout_height="10dp" /> + + + + + + - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7d29128..46fce3d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -159,9 +159,9 @@ Functionality - Double swipe actions + Double swipe gestures Swipe with two fingers - Edge swipe actions + Edge swipe gestures Swipe at the edge of the screen Edge width Launch search results diff --git a/docs/actions-and-gestures.md b/docs/actions-and-gestures.md new file mode 100644 index 0000000..f5d831f --- /dev/null +++ b/docs/actions-and-gestures.md @@ -0,0 +1,71 @@ +# Gestures and Actions + +µLauncher's central mechanism for accessing important functionality quickly +is to bind actions (e.g. launching an app) to gestures (e.g. swiping up). +These bindings can be configured in µLauncher Settings > ACTIONS. + + +## Available Gestures + +### Swipes + +- Basic swipes: Swipe up, down, left, or right +- Double swipes: Swipe up, down, left, or right with two fingers +- Edge swipes: + - Swipe up or down on the left or right edge + - Swipe left or right on the top or bottom edge + + The size of the edges is configurable in settings. + For a swipe to be detected as an edge swipe, the finger must not leave the respective edge region while swiping. + +### Taps + +- Tap on date or time +- Double tap +- Long click + +### Tap-then-Swipes + +- Tap then swipe up, down, left, or right + + To execute these gesture consistently, it is helpful to think of them as double taps, + where the finger stays on the screen after the second tap and then does a swipe. + The swipe must start very shortly after the tap ended. + +### Complex Gestures + +- Draw <, >, V, or Λ +- Draw <, >, V, or Λ in reverse direction + +### Hardware Buttons as Gestures + +- Back button (or back gesture if gesture navigation is enabled) +- Volume buttons + +*** + +## Available Actions + +To any of the available gestures, one of the following actions can be bound: + +- Launch an app (or a pinned shortcut) +- Open a widget panel. + Widget panels can hold widgets that are not needed on the home screen itself. + They can be created and managed in µLauncher Settings > Manage Widget Panels +- Open a list of all, favorite, or private apps (hidden apps are excluded). + Actions related to private space are only shown if private space is set up on the device. + µLauncher's settings can be accessed from those lists. + If private space is set up, an icon to (un)lock it is shown on the top right. +- Open µLauncher's settings +- Toggle private space lock +- Lock the screen: This allows to lock the screen. + There are two mechanisms by which the screen can be locked, accessibility service and device admin. +- Toggle the flashlight +- Raise, lower or adjust volume +- Play or pause media playback +- Skip to previous or next audio track +- Open notifications panel: Might be useful if the top of your screen is broken. +- Open quick settings panel: Why swipe down twice? +- Open [recent apps](https://developer.android.com/guide/components/activities/recents): Requires accessibility service. Can be used as a workaround for a Android bug. +- Launch another home screen: Allows using another installed home screen temporarily. +- Do nothing: Just prevents showing the message saying that no action is bound to this gesture. diff --git a/docs/build.md b/docs/build.md index 75921f9..1ffc338 100644 --- a/docs/build.md +++ b/docs/build.md @@ -1,11 +1,11 @@ -# Building µLauncher +# Building from Source ## Using the command line -Install JDK 17 and the Android Sdk. +Install JDK 17 and the Android SDK. Make sure that `JAVA_HOME` and `ANDROID_HOME` are set correctly. -``` +```bash git clone https://github.com/jrpie/Launcher cd Launcher @@ -15,7 +15,8 @@ cd Launcher This will create an apk file at `app/build/outputs/apk/default/release/app-default-release-unsigned.apk`. Note that you need to sign it: -``` + +```bash apksigner sign --ks "$YOUR_KEYSTORE" \ --ks-key-alias "$YOUR_ALIAS" \ --ks-pass="pass:$YOUR_PASSWORD" \ @@ -28,13 +29,17 @@ apksigner sign --ks "$YOUR_KEYSTORE" \ app-default-release-unsigned.apk ``` - See [this guide](https://developer.android.com/build/building-cmdline) for further instructions. - ## Using Android Studio + Install [Android Studio](https://developer.android.com/studio), import this project and build it. See [this guide](https://developer.android.com/studio/run) -for further instructions. +for further instructions. How to + +## CI Pipeline + +The [CI pipeline](https://github.com/jrpie/Launcher/actions) automatically creates debug builds. +> Note: These builds are *not* signed. They are in built in debug mode and only suitable for testing. diff --git a/docs/launcher.md b/docs/changes-fork.md similarity index 70% rename from docs/launcher.md rename to docs/changes-fork.md index cb290a0..8efc965 100644 --- a/docs/launcher.md +++ b/docs/changes-fork.md @@ -1,40 +1,45 @@ -# Notable changes compared to [Finn's Launcher][original-repo]: +# Notable changes compared to Finn's Launcher -µLauncher is a fork of [finnmglas's app Launcher][original-repo]. +µLauncher is a fork of [finnmglas's app Launcher](https://github.com/finnmglas/Launcher). Here is an incomplete list of changes: - - Additional gestures: - - Back - - V,Λ,<,> - - Edge gestures: There is a setting to allow distinguishing swiping at the edges of the screen from swiping in the center. + - Back + - V,Λ,<,> + - Edge gestures: There is a setting to allow distinguishing swiping at the edges of the screen from swiping in the center. + - Compatible with [work profile](https://www.android.com/enterprise/work-profile/), so apps like [Shelter](https://gitea.angry.im/PeterCxy/Shelter) can be used. - Compatible with [private space](https://source.android.com/docs/security/features/private-space) +- Support for [app widgets](https://developer.android.com/develop/ui/views/appwidgets/overview) +- Support for [pinned shortcuts](https://developer.android.com/develop/ui/views/launch/shortcuts/creating-shortcuts) - Option to rename apps - Option to hide apps - Favorite apps - New actions: - Toggle Torch - Lock screen + - Open a widget panel - The home button now works as expected. - Improved gesture detection. -### Visual +## Visual + - This app uses the system wallpaper instead of a custom solution. - The font has been changed to [Hack][hack-font], other fonts can be selected. - Font Awesome Icons were replaced by Material icons. - The gear button on the home screen was removed. A smaller button is show at the top right when necessary. +## Search -### Search - The search algorithm was modified to prefer matches at the beginning of the app name, i.e. when searching for `"te"`, `"termux"` is sorted before `"notes"`. - The search bar was moved to the bottom of the screen. -### Technical +## Technical + - Improved gesture detection. - Different apps set as default. - Package name was changed to `de.jrpie.android.launcher` to avoid clashing with the original app. @@ -42,9 +47,10 @@ The decision to create a hard fork was made two years later.--> - Fixed some bugs - Some refactoring - The complete list of changes can be viewed [here](https://github.com/jrpie/launcher/compare/340ee731...master). --- - [original-repo]: https://github.com/finnmglas/Launcher - [hack-font]: https://sourcefoundry.org/hack/ + +\[original-repo\]: [https://github.com/finnmglas/Launcher](https://github.com/finnmglas/Launcher) + +\[hack-font\]: [https://sourcefoundry.org/hack/](https://sourcefoundry.org/hack/) diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..8e9de53 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,24 @@ +# Contributing + +There are several ways to contribute to this app: +* You can add or improve [translations][toolate]. +
translation status +* If you found a bug or have an idea for a new feature you can [join the chat][chat] or open an [issue][issues]. + + > Please note that I work on this project in my free time. Thus I might not respond immediately and not all ideas will be implemented. + +* You can implement a new feature yourself: + - Create a [fork][fork] of this repository. + - Create a new branch named `feature/` or `fix/` and commit your changes. + - Open a new pull request. + + +See [build.md](build.md) for instructions how to build this project. +The [CI pipeline](https://github.com/jrpie/Launcher/actions) automatically creates debug builds. + + +--- + [fork]: https://github.com/jrpie/Launcher/fork/ + [issues]: https://github.com/jrpie/Launcher/issues/ + [chat]: https://s.jrpie.de/launcher-chat + [toolate]: https://toolate.othing.xyz/projects/jrpie-launcher/ diff --git a/docs/home.md b/docs/home.md new file mode 100644 index 0000000..9812e93 --- /dev/null +++ b/docs/home.md @@ -0,0 +1,43 @@ +# Welcome to the μLauncher Documentation + +## What is μLauncher? + +µLauncher is an *minimal* and *distraction-free* Android home screen that lets you launch apps using [swipe gestures and button presses](/actions-and-gestured.md). + +This project is a fork of [finnmglas's app Launcher](https://github.com/finnmglas/Launcher). An incomplete list of changes can be found [here](https://github.com/wassupluke/Launcher/blob/master/docs/launcher.md). + +## Where can I get μLauncher? + +[![Get it on F-Droid](https://fdroid.gitlab.io/artwork/badge/get-it-on.png)](https://f-droid.org/packages/de.jrpie.android.launcher/) + +[![Get it on Accrescent](https://accrescent.app/badges/get-it-on.png)](https://accrescent.app/app/de.jrpie.android.launcher.accrescent) + +[![Get it on Obtainium](https://raw.githubusercontent.com/ImranR98/Obtainium/b1c8ac6f2ab08497189721a788a5763e28ff64cd/assets/graphics/badge_obtainium.png)](https://apps.obtainium.imranr.dev/redirect?r=obtainium://app/{%22id%22:%22de.jrpie.android.launcher%22,%22url%22:%22https://github.com/jrpie/Launcher%22,%22author%22:%22jrpie%22,%22name%22:%22%c2%b5Launcher%22,%22additionalSettings%22:%22{\%22apkFilterRegEx\%22:\%22release\%22,\%22invertAPKFilter\%22:false,\%22about\%22:\%22%c2%b5Launcher%20is%20a%20minimal%20home%20screen.\%22}%22}) + +[![Get it on GitHub](https://raw.githubusercontent.com/NeoApplications/Neo-Backup/034b226cea5c1b30eb4f6a6f313e4dadcbb0ece4/badge_github.png)](https://github.com/jrpie/launcher/releases/latest) + +> You can also [get it on Google Play](https://play.google.com/store/apps/details?id=de.jrpie.android.launcher), but this is not recommend. + + +## How can I contribute? + +See [docs/contribute](/contribute.md) + +## Screenshots + +![μLauncher Home Screen screenshot](https://github.com/jrpie/launcher/blob/master/fastlane/metadata/android/en-US/images/phoneScreenshots/1.jpg) + +![μLauncher Settings screenshot](https://github.com/jrpie/launcher/blob/master/fastlane/metadata/android/en-US/images/phoneScreenshots/2.jpg) + +![μLauncher All Apps list view with icons screenshot](https://github.com/jrpie/launcher/blob/master/fastlane/metadata/android/en-US/images/phoneScreenshots/3.jpg) + +![μLauncher Favorite Apps list view with icons screenshot](https://github.com/jrpie/launcher/blob/master/fastlane/metadata/android/en-US/images/phoneScreenshots/4.jpg) + +![μLauncher Choose App to bind to gesture screenshot](https://github.com/jrpie/launcher/blob/master/fastlane/metadata/android/en-US/images/phoneScreenshots/5.jpg) + +![μLauncher App options card from list view with icons screenshot](https://github.com/jrpie/launcher/blob/master/fastlane/metadata/android/en-US/images/phoneScreenshots/7.jpg +) + +![μLauncher All Apps list view without icons screenshot](https://github.com/jrpie/launcher/blob/master/fastlane/metadata/android/en-US/images/phoneScreenshots/8.jpg) + + diff --git a/docs/profiles.md b/docs/profiles.md new file mode 100644 index 0000000..d9eaf52 --- /dev/null +++ b/docs/profiles.md @@ -0,0 +1,21 @@ +# Work Profile + +µLauncher is compatible with [work profile](https://www.android.com/enterprise/work-profile/), so apps like [Shelter](https://gitea.angry.im/PeterCxy/Shelter) can be used. +Apps from the work profile are shown in the usual app list. + + +# Private Space + +µLauncher is compatible with [private space](https://source.android.com/docs/security/features/private-space). + + +The private space can be (un)locked by a dedicated action. + +It is configurable whether apps from private space are + +1. shown in the usual app list + (in this case, (un)locking is accessible through a lock icon on the top right of the app drawer) + or +2. only shown in a separate list. + + diff --git a/docs/settings.md b/docs/settings.md new file mode 100644 index 0000000..f033f62 --- /dev/null +++ b/docs/settings.md @@ -0,0 +1,235 @@ +# Launcher Settings + +Tweaks and customizations can be made from within the Launcher Settings page. + +These settings let you change wallpapers, change colors and fonts, enable monochrome app icons, change the app drawer layout, and much more. + +In the following documentation, 'app drawer' will be used to refer to the 'All Apps', 'Favorite Apps' and 'Private Space' views. + +## Appearance + +> ### Choose a wallpaper + +This triggers Android's mechanism to change the wallpaper using a photos app, file explorer, or native wallpaper setting app. +µLauncher uses the system-wide wallpaper, i.e. this change also affects other launchers. + +> ### Font (in-app font) + +Set the font used within the app settings. This setting does not affect the date/time home screen font. + +**type:** `dropdown` + +**options:** `Hack`,`System default`,`Sans serif`,`Serif`,`Monospace`,`Serif monospace` + +> ### Text Shadow + +**type:** `toggle` + +> ### Background (app list and setting) + +**type:** `dropdown` + +**type:** `Transparent`,`Dim`,`Blur`,`Solid` + +> ### Monochrome app icons + +Remove coloring from all app icons. Can help decrease visual stimulus when enabled. + +**type:** `toggle` + +## Date & Time + +> ### Font (home screen) + +Set the home screen font for date and time. This setting does not affect the in-app font. + +**type:** `dropdown` + +**options:** `Hack`,`System default`,`Sans serif`,`Serif`,`Monospace`,`Serif monospace` + +> ### Color [`[bug]`](https://github.com/jrpie/launcher/issues/151) + +Set the color for the home screen date and time. + +Accepts a HEX color code (consisting of a '#' followed by three sets of two alphanumeric (letters and numbers) characters. A fourth set of two alphanumeric characters may be added to set the transparency of the color. + +[Color wheel picker](https://rgbacolorpicker.com/color-wheel-picker) + +**type:** `HEX`,`RGBA` + +> ### Use localized date format + +Adapt the display of dates and times to the specific conventions of a particular locale or region. Different locales use different date orders (e.g., MM/DD/YYYY in the US, DD/MM/YYYY in Europe). + +**type:** `toggle` + +> ### Show time + +Show the current time on the home screen. + +**type:** `toggle` + +> ### Show seconds + +Show the current time down to the second on the home screen. + +**type:** `toggle` + +> ### Show date + +Show the current date on the home screen. + +**type:** `toggle` + +> ### Flip date and time + +Place the current time above the current date on the home screen. + +**type:** `toggle` + +## Functionality + +> ### Launch search results + +Launches any app that matches user keyboard input when no other apps match. + +As you type inside the app drawer, the app narrows down the list of apps shown based on the app title matching your text input. +With the 'launch search results' setting, once only one matching app remains, it is launched immediately. +Usually it suffices to type two or three characters the single out the desired app. + +This feature becomes more powerful when combined with [renaming](#additional-settings) apps, effectively letting you define custom app names that could be considered 'aliases' or shortcuts. +For instance, if you want the keyboard input `gh` to open your `GitHub` app, you could rename `GitHub` to `GitHub gh`, `gh GitHub`, or simply `gh`. +Assuming no other installed apps have the `gh` combination of letters in them, opening the app drawer and typing `gh` would immediately launch your `GitHub` app. + +Press space to temporarily disable this feature and allow text entry without prematurely launching an app. Useful when combined with the [Search the web](#search-the-web) feature. + +**type:** `toggle` + +> ### Search the web + +Press return/enter while searching the app list to launch a web search. + +**type:** `toggle` + +> ### Start keyboard for search + +Automatically open the keyboard when the app drawer is opened. + +**type:** `toggle` + +> ### Double swipe gestures + +Enable double swipe (two finger) gestures in launcher settings. Does not erase gesture bindings if accidentally turned off. + +**type:** `toggle` + +> ### Edge swipe gestures + +Enable edge swipe (near edges of screen) gestures in launcher settings. Does not erase gesture bindings if accidentally turned off. + +**type:** `toggle` + +> ### Edge width + +Change how large a margin is used for detecting edge gestures. Shows the edge margin preview when using the slider. + +**type:** `slider` + +> ### Choose method for locking the screen + +There are two methods to lock the screen and unfortunately both have downsides. + +1. **`Device Admin`** + + - Doesn't work with unlocking by fingerprint or face recognition. + +2. **`Accessibility Service`** + + - Requires excessive privileges. + - μLauncher will use those privileges *only* for locking the screen. + - As a rule of thumb, it is [not recommended](https://android.stackexchange.com/questions/248171/is-it-safe-to-give-accessibility-permission-to-an-app) to grant access to accessibility services on a random app. Always review the [source code](https://github.com/jrpie/Launcher) before granting accessibility permissions so you familiarize yourself with what the code might do. + - On some devices, the start-up PIN will no longer be used for encrypting data after activating an accessibility service. + - This can be [reactivated](https://issuetracker.google.com/issues/37010136#comment36) afterwards. + + **type:** `text buttons` + + **options:** `USE DEVICE ADMIN`,`USE ACCESSIBILITY SERVICE` + +## Apps + +> ### Hidden apps + +Open an app drawer containing only hidden apps. + +> ### Don't show apps that are bound to a gesture in the app list + +Remove certain apps from the app drawer if they are already accessible via a gesture. + +Reduces redundancy and tidies up app drawer. + +**type:** `toggle` + +> ### Hide paused apps + +Remove paused apps from the app drawer. +For example an app belonging to the work profile is paused when the work profile is inactive. + +**type:** `toggle` + +> ### Hide private space from app list + +Remove private space from app drawer. + +**type:** `toggle` + +> ### Layout of app list + +Changes how the apps are displayed when accessing the app drawer. + +- `Default`: All apps in the drawer will show in a vertically-scrolled list with their app icon and title. +- `Text`: Removes the app icons, shows only app titles in the drawer as a vertically-scrolled list. + Work profile and private space apps are distinguished by a different label instead of a badge. +- `Grid`: Shows apps with their app icon and title in a grid layout. + +**type:** `dropdown` + +**options:** `Default`,`Text`,`Grid` + +> ### Reverse the app list + +Enable reverse alphabetical sorting of apps in the app drawer. +Useful for keeping apps within easier reach from the keyboard. + +**type:** `toggle` + +## Display + +> ### Rotate screen + +**type:** `toggle` + +> ### Keep screen on + +**type:** `toggle` + +> ### Hide status bar + +Remove the top status bar from the home screen. + +**type:** `toggle` + +> ### Hide navigation bar + +Remove the navigation bar from the home screen. Enabling this setting may make it difficult to use the device if gestures are not setup properly. + +**type:** `toggle` + +## Additional Settings + +> ### App Drawer Long Press on App + +Access additional per-app details and settings. To use, open the app drawer and long press on any app. + +**type:** `dropdown` + +**options:** `App Info`,`Add to favorites`,`Hide`,`Rename`,`Uninstall`