Compare commits

..

No commits in common. "24e90deb627f76c2d528fbc12510ea4825dc9a98" and "a4fcdf60c7d3be3d37be15fb3fc8c9b286a7f953" have entirely different histories.

15 changed files with 58 additions and 483 deletions

View file

@ -1,25 +1,9 @@
#!/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")
@ -27,11 +11,12 @@ if [[ $(git status --porcelain) ]]; then
echo "There are uncommitted changes."
read -p "Continue anyway? (y/n) " -n 1 -r
echo
echo # (optional) move to a new line
if ! [[ $REPLY =~ ^[Yy]$ ]]
then
exit 1
fi
fi
rm -rf "$OUTPUT_DIR"

View file

@ -22,6 +22,8 @@ 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
@ -32,6 +34,7 @@ const val APP_WIDGET_HOST_ID = 42;
class Application : android.app.Application() {
val apps = MutableLiveData<List<AbstractDetailedAppInfo>>()
val widgets = MutableLiveData<Set<Widget>>()
val privateSpaceLocked = MutableLiveData<Boolean>()
lateinit var appWidgetHost: AppWidgetHost
lateinit var appWidgetManager: AppWidgetManager
@ -98,6 +101,8 @@ 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())
}
}

View file

@ -49,6 +49,7 @@ class ManageWidgetPanelsActivity : AppCompatActivity(), UIObject {
})
}
binding.manageWidgetPanelsRecycler.apply {
// improve performance (since content changes don't change the layout size)
setHasFixedSize(true)
layoutManager = viewManager
adapter = viewAdapter

View file

@ -34,11 +34,10 @@ 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<WidgetContainerView>(R.id.manage_widgets_container).updateWidgets(this,
LauncherPreferences.widgets().widgets()
)
@ -64,7 +63,7 @@ class ManageWidgetsActivity : Activity(), UIObject {
findViewById<WidgetContainerView>(R.id.manage_widgets_container).let {
it.widgetPanelId = panelId
it.updateWidgets(this, LauncherPreferences.widgets().widgets())
it.updateWidgets(this, (application as Application).widgets.value)
}
}

View file

@ -19,7 +19,6 @@ 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
@ -48,27 +47,21 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe
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)
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)
}),
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)
TOP({ dx, dy, rect ->
Rect(rect.left, min(rect.top + dy, rect.bottom - 200), rect.right, rect.bottom)
}),
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)
BOTTOM({ dx, dy, rect ->
Rect(rect.left, rect.top, rect.right, max(rect.top + 200, rect.bottom + dy))
}),
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)
LEFT({ dx, dy, rect ->
Rect(min(rect.left + dx, rect.right - 200), rect.top, rect.right, 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)
RIGHT({ dx, dy, rect ->
Rect(rect.left, rect.top, max(rect.left + 200, rect.right + dx), rect.bottom)
}),
}
@ -127,7 +120,6 @@ 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(
@ -170,7 +162,7 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe
if (widgets == null) {
return
}
children.filter { it is WidgetOverlayView }.forEach { removeView(it) }
children.mapNotNull { it as? WidgetOverlayView }.forEach { removeView(it) }
widgets.filter { it.panelId == widgetPanelId }.forEach { widget ->
WidgetOverlayView(activity).let {

View file

@ -57,8 +57,7 @@ sealed class Widget {
return Json.decodeFromString(serialized)
}
fun byId(context: Context, id: Int): Widget? {
// TODO: do some caching
return LauncherPreferences.widgets().widgets().firstOrNull() {
return (context.applicationContext as Application).widgets.value?.firstOrNull {
it.id == id
}
}

View file

@ -24,21 +24,6 @@
android:layout_width="match_parent"
android:layout_height="10dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dialog_select_color_alpha" />
<SeekBar
android:id="@+id/dialog_select_color_seekbar_alpha"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255" />
<Space
android:layout_width="match_parent"
android:layout_height="10dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -80,4 +65,18 @@
android:layout_height="wrap_content"
android:max="255" />
<Space
android:layout_width="match_parent"
android:layout_height="10dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dialog_select_color_alpha" />
<SeekBar
android:id="@+id/dialog_select_color_seekbar_alpha"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255" />
</LinearLayout>

View file

@ -159,9 +159,9 @@
<string name="settings_launcher_section_functionality">Functionality</string>
<string name="settings_enabled_gestures_double_swipe">Double swipe gestures</string>
<string name="settings_enabled_gestures_double_swipe">Double swipe actions</string>
<string name="settings_enabled_gestures_double_swipe_summary">Swipe with two fingers</string>
<string name="settings_enabled_gestures_edge_swipe">Edge swipe gestures</string>
<string name="settings_enabled_gestures_edge_swipe">Edge swipe actions</string>
<string name="settings_enabled_gestures_edge_swipe_summary">Swipe at the edge of the screen</string>
<string name="settings_enabled_gestures_edge_swipe_edge_width">Edge width</string>
<string name="settings_functionality_auto_launch">Launch search results</string>

View file

@ -1,71 +0,0 @@
# 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.

View file

@ -1,11 +1,11 @@
# Building from Source
# Building µLauncher
## 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,8 +15,7 @@ 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" \
@ -29,17 +28,13 @@ 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
## 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. 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.
for further instructions.

View file

@ -1,24 +0,0 @@
# Contributing
There are several ways to contribute to this app:
* You can add or improve [translations][toolate].
<br><img src="https://toolate.othing.xyz/widget/jrpie-launcher/launcher/horizontal-auto.svg" alt="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/<your feature>` or `fix/<your 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/

View file

@ -1,43 +0,0 @@
# 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)
<!-- missing μLauncher grid view screenshot-->

View file

@ -1,45 +1,40 @@
# Notable changes compared to Finn's Launcher
# Notable changes compared to [Finn's Launcher][original-repo]:
µLauncher is a fork of [finnmglas's app Launcher](https://github.com/finnmglas/Launcher).
µLauncher is a fork of [finnmglas's app Launcher][original-repo].
Here is an incomplete list of changes:
<!--The last commit of the original project is [340ee731](https://github.com/jrpie/launcher/commit/340ee7315293b028c060638e058516435bca296a)
The first commit of µLauncher is [cc2e7710](https://github.com/jrpie/launcher/commit/cc2e7710c824549c367d97a81a1646d27c6c8993),
which at the time was still intended as a patch for launcher.
The decision to create a hard fork was made two years later.-->
- 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.
- 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.
- 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.
@ -47,10 +42,9 @@ 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](https://github.com/finnmglas/Launcher)
\[hack-font\]: [https://sourcefoundry.org/hack/](https://sourcefoundry.org/hack/)
[original-repo]: https://github.com/finnmglas/Launcher
[hack-font]: https://sourcefoundry.org/hack/

View file

@ -1,21 +0,0 @@
# 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.

View file

@ -1,235 +0,0 @@
# 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:**&nbsp;`dropdown`
**options:**&nbsp;`Hack`,`System default`,`Sans serif`,`Serif`,`Monospace`,`Serif monospace`
> ### Text Shadow
**type:**&nbsp;`toggle`
> ### Background (app list and setting)
**type:**&nbsp;`dropdown`
**type:**&nbsp;`Transparent`,`Dim`,`Blur`,`Solid`
> ### Monochrome app icons
Remove coloring from all app icons. Can help decrease visual stimulus when enabled.
**type:**&nbsp;`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:**&nbsp;`dropdown`
**options:**&nbsp;`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:**&nbsp;`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:**&nbsp;`toggle`
> ### Show time
Show the current time on the home screen.
**type:**&nbsp;`toggle`
> ### Show seconds
Show the current time down to the second on the home screen.
**type:**&nbsp;`toggle`
> ### Show date
Show the current date on the home screen.
**type:**&nbsp;`toggle`
> ### Flip date and time
Place the current time above the current date on the home screen.
**type:**&nbsp;`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:**&nbsp;`toggle`
> ### Search the web
Press return/enter while searching the app list to launch a web search.
**type:**&nbsp;`toggle`
> ### Start keyboard for search
Automatically open the keyboard when the app drawer is opened.
**type:**&nbsp;`toggle`
> ### Double swipe gestures
Enable double swipe (two finger) gestures in launcher settings. Does not erase gesture bindings if accidentally turned off.
**type:**&nbsp;`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:**&nbsp;`toggle`
> ### Edge width
Change how large a margin is used for detecting edge gestures. Shows the edge margin preview when using the slider.
**type:**&nbsp;`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:**&nbsp;`text buttons`
**options:**&nbsp;`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:**&nbsp;`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:**&nbsp;`toggle`
> ### Hide private space from app list
Remove private space from app drawer.
**type:**&nbsp;`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:**&nbsp;`dropdown`
**options:**&nbsp;`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:**&nbsp;`toggle`
## Display
> ### Rotate screen
**type:**&nbsp;`toggle`
> ### Keep screen on
**type:**&nbsp;`toggle`
> ### Hide status bar
Remove the top status bar from the home screen.
**type:**&nbsp;`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:**&nbsp;`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:**&nbsp;`dropdown`
**options:**&nbsp;`App Info`,`Add to favorites`,`Hide`,`Rename`,`Uninstall`