Compare commits

...

15 commits

Author SHA1 Message Date
Too Late (bot)
8028df14bb
Merge c448c51164 into 7257d4ca35 2025-02-17 00:07:23 +00:00
Ahmet Çeliker
c448c51164 Translated using Weblate (Turkish)
Currently translated at 86.6% (13 of 15 strings)

Translation: jrpie-Launcher/metadata
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/metadata/tr/
2025-02-17 00:07:18 +00:00
Vossa Excelencia
68b79724e8 Translated using Weblate (Portuguese (Brazil))
Currently translated at 26.6% (4 of 15 strings)

Translation: jrpie-Launcher/metadata
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/metadata/pt_BR/
2025-02-17 00:07:18 +00:00
Vossa Excelencia
bef38c2657 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (225 of 225 strings)

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/pt_BR/
2025-02-17 00:07:18 +00:00
Vossa Excelencia
d0b0c27b2c Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (220 of 220 strings)

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/pt_BR/
2025-02-17 00:07:18 +00:00
Vossa Excelencia
4508e4ee5c Translated using Weblate (Portuguese (Brazil))
Currently translated at 20.0% (3 of 15 strings)

Translation: jrpie-Launcher/metadata
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/metadata/pt_BR/
2025-02-17 00:07:18 +00:00
Vossa Excelencia
e959e9d957 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (220 of 220 strings)

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/pt_BR/
2025-02-17 00:07:18 +00:00
Nicola Bortoletto
958d4879f5 Translated using Weblate (Italian)
Currently translated at 99.0% (216 of 218 strings)

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/it/
2025-02-17 00:07:18 +00:00
Vossa Excelencia
7841a99415 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (218 of 218 strings)

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/pt_BR/
2025-02-17 00:07:18 +00:00
Xanadul
18b4fca933 Translated using Weblate (German)
Currently translated at 13.3% (2 of 15 strings)

Translation: jrpie-Launcher/metadata
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/metadata/de/
2025-02-17 00:07:18 +00:00
Nicola Bortoletto
5792c7f38c Translated using Weblate (Italian)
Currently translated at 98.1% (214 of 218 strings)

Translation: jrpie-Launcher/Launcher
Translate-URL: https://toolate.othing.xyz/projects/jrpie-launcher/launcher/it/
2025-02-17 00:07:18 +00:00
7257d4ca35
fix bug in gesture detection logic
Some checks are pending
Android CI / build (push) Waiting to run
2025-02-16 23:58:42 +01:00
47ae0bf35f
update README.md
Some checks are pending
Android CI / build (push) Waiting to run
2025-02-16 16:51:18 +01:00
5669279c64
add <,>,V,Λ gestures 2025-02-16 15:50:13 +01:00
0c0d90a357
improve gesture detection 2025-02-15 03:08:18 +01:00
26 changed files with 592 additions and 188 deletions

View file

@ -14,12 +14,6 @@
µLauncher is an Android home screen that lets you launch apps using swipe gestures and button presses.
It is *minimal, efficient and free of distraction*.
Your home screen only displays the date, time and a wallpaper.
Pressing back or swiping up (this can be configured) opens a list
of all installed apps, which can be searched efficiently.
This is a fork of [finnmglas's app Launcher][original-repo].
<a href="https://f-droid.org/packages/de.jrpie.android.launcher/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="80"></a>
<a href="https://accrescent.app/app/de.jrpie.android.launcher.accrescent"><img alt="Get it on Accrescent" src="https://accrescent.app/badges/get-it-on.png" height="80"></a>
@ -51,6 +45,45 @@ You can also [get it on Google Play](https://play.google.com/store/apps/details?
height="400">
µLauncher is a fork of [finnmglas's app Launcher][original-repo].
An incomplete list of changes can be found [here](docs/launcher.md).
## Features
µLauncher only displays the date, time and a wallpaper.
Pressing back or swiping up (this can be configured) opens a list
of all installed apps, which can be searched efficiently.
The following gestures are available:
- volume up / down,
- swipe up / down / left / right,
- swipe with two fingers,
- swipe on the left / right resp. top / bottom edge,
- draw < / > / V / Λ
- click on date / time,
- double click,
- long click,
- back button.
To every gesture you can bind one of the following actions:
- launch an app,
- open a list of all / favorite / private apps,
- open µLauncher settings,
- toggle private space lock,
- lock the screen,
- toggle the torch,
- volume up / down,
- go to previous / next audio track.
µ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.
By default the font is set to [Hack][hack-font], but other fonts can be selected.
## Contributing
There are several ways to contribute to this app:
@ -63,34 +96,10 @@ There are several ways to contribute to this app:
- Open a new pull request.
See [BUILD.md](BUILD.md) for instructions how to build this project.
See [build.md](docs/build.md) for instructions how to build this project.
The [CI pipeline](https://github.com/jrpie/Launcher/actions) automatically creates debug builds.
Note that those are not signed.
## Notable changes compared to [Finn's Launcher][original-repo]:
* 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.
* The home button now works as expected.
### Visual
* This app uses the system wallpaper instead of a custom solution.
* The font has been changed to [Hack][hack-font].
* Font Awesome Icons were replaced by Material icons.
* The gear button on the home screen was removed. Instead pressing back opens the list of applications and the app settings are accessible from there.
### 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
* Small improvements to the gesture detection.
* Different apps set as default.
* Package name was changed to `de.jrpie.android.launcher` to avoid clashing with the original app.
* Dropped support for API < 21 (i.e. pre Lollypop)
* Some refactoring
---
---
[hack-font]: https://sourcefoundry.org/hack/
[original-repo]: https://github.com/finnmglas/Launcher

View file

@ -1,6 +1,7 @@
package de.jrpie.android.launcher.actions
import android.content.Context
import android.util.Log
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.preferences.LauncherPreferences
@ -169,6 +170,54 @@ enum class Gesture(
R.array.default_double_right,
R.anim.left_right
),
SWIPE_LARGER(
"action.larger",
R.string.settings_gesture_swipe_larger,
R.string.settings_gesture_description_swipe_larger,
R.array.no_default
),
SWIPE_LARGER_REVERSE(
"action.larger_reverse",
R.string.settings_gesture_swipe_larger_reverse,
R.string.settings_gesture_description_swipe_larger_reverse,
R.array.no_default
),
SWIPE_SMALLER(
"action.smaller",
R.string.settings_gesture_swipe_smaller,
R.string.settings_gesture_description_swipe_smaller,
R.array.no_default
),
SWIPE_SMALLER_REVERSE(
"action.smaller_reverse",
R.string.settings_gesture_swipe_smaller_reverse,
R.string.settings_gesture_description_swipe_smaller_reverse,
R.array.no_default
),
SWIPE_LAMBDA(
"action.lambda",
R.string.settings_gesture_swipe_lambda,
R.string.settings_gesture_description_swipe_lambda,
R.array.no_default
),
SWIPE_LAMBDA_REVERSE(
"action.lambda_reverse",
R.string.settings_gesture_swipe_lambda_reverse,
R.string.settings_gesture_description_swipe_lambda_reverse,
R.array.no_default
),
SWIPE_V(
"action.v",
R.string.settings_gesture_swipe_v,
R.string.settings_gesture_description_swipe_v,
R.array.no_default
),
SWIPE_V_REVERSE(
"action.v_reverse",
R.string.settings_gesture_swipe_v_reverse,
R.string.settings_gesture_description_swipe_v_reverse,
R.array.no_default
),
BACK(
"action.back",
R.string.settings_gesture_back,
@ -267,6 +316,7 @@ enum class Gesture(
}
operator fun invoke(context: Context) {
Log.i("Launcher", "Detected gesture: $this")
val action = Action.forGesture(this)
Action.launch(action, context, this.animationIn, this.animationOut)
}

View file

@ -6,14 +6,11 @@ import android.content.res.Resources
import android.os.Build
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.GestureDetector
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.window.OnBackInvokedDispatcher
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.isVisible
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.actions.Action
@ -23,13 +20,6 @@ import de.jrpie.android.launcher.databinding.HomeBinding
import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.ui.tutorial.TutorialActivity
import java.util.Locale
import java.util.Timer
import kotlin.concurrent.fixedRateTimer
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.tan
/**
* [HomeActivity] is the actual application Launcher,
@ -43,10 +33,10 @@ import kotlin.math.tan
* - Setting global variables (preferences etc.)
* - Opening the [TutorialActivity] on new installations
*/
class HomeActivity : UIObject, AppCompatActivity(),
GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
class HomeActivity : UIObject, AppCompatActivity() {
private lateinit var binding: HomeBinding
private lateinit var touchGestureDetector: TouchGestureDetector
private var sharedPreferencesListener =
SharedPreferences.OnSharedPreferenceChangeListener { _, prefKey ->
@ -61,22 +51,29 @@ class HomeActivity : UIObject, AppCompatActivity(),
}
}
private var edgeWidth = 0.15f
private var bufferedPointerCount = 1 // how many fingers on screen
private var pointerBufferTimer = Timer()
private lateinit var mDetector: GestureDetectorCompat
override fun onCreate(savedInstanceState: Bundle?) {
super<AppCompatActivity>.onCreate(savedInstanceState)
super<UIObject>.onCreate()
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
val width = displayMetrics.widthPixels
val height = displayMetrics.heightPixels
touchGestureDetector = TouchGestureDetector(
this,
width,
height,
LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f
)
// Initialise layout
binding = HomeBinding.inflate(layoutInflater)
setContentView(binding.root)
// Handle back key / gesture on Android 13+, cf. onKeyDown()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
onBackInvokedDispatcher.registerOnBackInvokedCallback(
@ -95,9 +92,6 @@ class HomeActivity : UIObject, AppCompatActivity(),
override fun onStart() {
super<AppCompatActivity>.onStart()
mDetector = GestureDetectorCompat(this, this)
mDetector.setOnDoubleTapListener(this)
super<UIObject>.onStart()
LauncherPreferences.getSharedPreferences()
@ -172,7 +166,8 @@ class HomeActivity : UIObject, AppCompatActivity(),
override fun onResume() {
super.onResume()
edgeWidth = LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f
touchGestureDetector.edgeWidth =
LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f
initClock()
updateSettingsFallbackButtonVisibility()
@ -211,95 +206,8 @@ class HomeActivity : UIObject, AppCompatActivity(),
return true
}
override fun onFling(e1: MotionEvent?, e2: MotionEvent, dX: Float, dY: Float): Boolean {
if (e1 == null) return false
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
val width = displayMetrics.widthPixels
val height = displayMetrics.heightPixels
val diffX = e1.x - e2.x
val diffY = e1.y - e2.y
val doubleActions = LauncherPreferences.enabled_gestures().doubleSwipe()
val edgeActions = LauncherPreferences.enabled_gestures().edgeSwipe()
val threshold = ViewConfiguration.get(this).scaledTouchSlop
val angularThreshold = tan(Math.PI / 6)
var gesture = if (angularThreshold * abs(diffX) > abs(diffY)) { // horizontal swipe
if (diffX > threshold)
Gesture.SWIPE_LEFT
else if (diffX < -threshold)
Gesture.SWIPE_RIGHT
else null
} else if (angularThreshold * abs(diffY) > abs(diffX)) { // vertical swipe
// Only open if the swipe was not from the phones top edge
// TODO: replace 100px by sensible dp value (e.g. twice the height of the status bar)
if (diffY < -threshold && e1.y > 100)
Gesture.SWIPE_DOWN
else if (diffY > threshold)
Gesture.SWIPE_UP
else null
} else null
if (doubleActions && bufferedPointerCount > 1) {
gesture = gesture?.let(Gesture::getDoubleVariant)
}
if (edgeActions) {
if (max(e1.x, e2.x) < edgeWidth * width) {
gesture = gesture?.getEdgeVariant(Gesture.Edge.LEFT)
} else if (min(e1.x, e2.x) > (1 - edgeWidth) * width) {
gesture = gesture?.getEdgeVariant(Gesture.Edge.RIGHT)
}
if (max(e1.y, e2.y) < edgeWidth * height) {
gesture = gesture?.getEdgeVariant(Gesture.Edge.TOP)
} else if (min(e1.y, e2.y) > (1 - edgeWidth) * height) {
gesture = gesture?.getEdgeVariant(Gesture.Edge.BOTTOM)
}
}
gesture?.invoke(this)
return true
}
override fun onLongPress(event: MotionEvent) {
Gesture.LONG_CLICK(this)
}
override fun onDoubleTap(event: MotionEvent): Boolean {
Gesture.DOUBLE_CLICK(this)
return false
}
// Tooltip
override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
return false
}
override fun onTouchEvent(event: MotionEvent): Boolean {
// Buffer / Debounce the pointer count
if (event.pointerCount > bufferedPointerCount) {
bufferedPointerCount = event.pointerCount
pointerBufferTimer = fixedRateTimer("pointerBufferTimer", true, 300, 1000) {
bufferedPointerCount = 1
this.cancel() // a non-recurring timer
}
}
return if (mDetector.onTouchEvent(event)) {
false
} else {
super.onTouchEvent(event)
}
return touchGestureDetector.onTouchEvent(event) || super.onTouchEvent(event)
}
override fun setOnClicks() {
@ -329,16 +237,4 @@ class HomeActivity : UIObject, AppCompatActivity(),
override fun isHomeScreen(): Boolean {
return true
}
/* TODO: Remove those. For now they are necessary
* because this inherits from GestureDetector.OnGestureListener */
override fun onDoubleTapEvent(event: MotionEvent): Boolean { return false }
override fun onDown(event: MotionEvent): Boolean { return false }
override fun onScroll(e1: MotionEvent?, e2: MotionEvent, dX: Float, dY: Float): Boolean { return false }
override fun onShowPress(event: MotionEvent) {}
override fun onSingleTapUp(event: MotionEvent): Boolean { return false }
}

View file

@ -0,0 +1,246 @@
package de.jrpie.android.launcher.ui
import android.content.Context
import android.view.MotionEvent
import android.view.ViewConfiguration
import de.jrpie.android.launcher.actions.Gesture
import de.jrpie.android.launcher.preferences.LauncherPreferences
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.tan
class TouchGestureDetector(
private val context: Context,
val width: Int,
val height: Int,
var edgeWidth: Float
) {
private val ANGULAR_THRESHOLD = tan(Math.PI / 6)
private val TOUCH_SLOP: Int
private val TOUCH_SLOP_SQUARE: Int
private val DOUBLE_TAP_SLOP: Int
private val DOUBLE_TAP_SLOP_SQUARE: Int
private val LONG_PRESS_TIMEOUT: Int
private val TAP_TIMEOUT: Int
private val DOUBLE_TAP_TIMEOUT: Int
private val MIN_TRIANGLE_HEIGHT = 250
data class Vector(val x: Float, val y: Float) {
fun absSquared(): Float {
return this.x * this.x + this.y * this.y
}
fun plus(vector: Vector): Vector {
return Vector(this.x + vector.x, this.y + vector.y)
}
fun max(other: Vector): Vector {
return Vector(max(this.x, other.x), max(this.y, other.y))
}
fun min(other: Vector): Vector {
return Vector(min(this.x, other.x), min(this.y, other.y))
}
operator fun minus(vector: Vector): Vector {
return Vector(this.x - vector.x, this.y - vector.y)
}
}
class PointerPath(
val number: Int,
val start: Vector,
var last: Vector = start
) {
var min = Vector(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY)
var max = Vector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY)
fun sizeSquared(): Float {
return (max - min).absSquared()
}
fun getDirection(): Vector {
return last - start
}
fun update(vector: Vector) {
min = min.min(vector)
max = max.max(vector)
last = vector
}
}
private fun PointerPath.isTap(): Boolean {
return sizeSquared() < TOUCH_SLOP_SQUARE
}
init {
val configuration = ViewConfiguration.get(context)
TOUCH_SLOP = configuration.scaledTouchSlop
TOUCH_SLOP_SQUARE = TOUCH_SLOP * TOUCH_SLOP
DOUBLE_TAP_SLOP = configuration.scaledDoubleTapSlop
DOUBLE_TAP_SLOP_SQUARE = DOUBLE_TAP_SLOP * DOUBLE_TAP_SLOP
LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout()
TAP_TIMEOUT = ViewConfiguration.getTapTimeout()
DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout()
}
private var paths = HashMap<Int, PointerPath>()
private var lastTappedTime = 0L
private var lastTappedLocation: Vector? = null
fun onTouchEvent(event: MotionEvent): Boolean {
val pointerIdToIndex =
(0..<event.pointerCount).associateBy { event.getPointerId(it) }
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
paths = HashMap()
}
// add new pointers
for(i in 0..<event.pointerCount){
if(paths.containsKey(event.getPointerId(i))) {
continue
}
val index = pointerIdToIndex[i] ?: continue
paths[i] = PointerPath(
paths.entries.size,
Vector(event.getX(index), event.getY(index))
)
}
for (i in 0..<event.pointerCount) {
val index = pointerIdToIndex[i] ?: continue
for (j in 0..<event.historySize) {
paths[i]?.update(
Vector(
event.getHistoricalX(index, j),
event.getHistoricalY(index, j)
)
)
}
paths[i]?.update(Vector(event.getX(index), event.getY(index)))
}
if (event.actionMasked == MotionEvent.ACTION_UP) {
classifyPaths(paths, event.downTime, event.eventTime)
}
return true
}
private fun getGestureForDirection(direction: Vector): Gesture? {
return if (ANGULAR_THRESHOLD * abs(direction.x) > abs(direction.y)) { // horizontal swipe
if (direction.x > TOUCH_SLOP)
Gesture.SWIPE_RIGHT
else if (direction.x < -TOUCH_SLOP)
Gesture.SWIPE_LEFT
else null
} else if (ANGULAR_THRESHOLD * abs(direction.y) > abs(direction.x)) { // vertical swipe
if (direction.y < -TOUCH_SLOP)
Gesture.SWIPE_UP
else if (direction.y > TOUCH_SLOP)
Gesture.SWIPE_DOWN
else null
} else null
}
private fun classifyPaths(paths: Map<Int, PointerPath>, timeStart: Long, timeEnd: Long) {
val duration = timeEnd - timeStart
val pointerCount = paths.entries.size
if (paths.entries.isEmpty()) {
return
}
val mainPointerPath = paths.entries.firstOrNull { it.value.number == 0 }?.value ?: return
// Ignore swipes at the very top, since this interferes with the status bar.
// TODO: replace 100px by sensible dp value (e.g. twice the height of the status bar)
if (paths.entries.any { it.value.start.y < 100 }) {
return
}
if (pointerCount == 1 && mainPointerPath.isTap()) {
// detect taps
if (duration in 0..TAP_TIMEOUT) {
if (timeStart - lastTappedTime < DOUBLE_TAP_TIMEOUT &&
lastTappedLocation?.let {
(mainPointerPath.last - it).absSquared() < DOUBLE_TAP_SLOP_SQUARE} == true
) {
Gesture.DOUBLE_CLICK.invoke(context)
} else {
lastTappedTime = timeEnd
lastTappedLocation = mainPointerPath.last
}
} else if (duration > LONG_PRESS_TIMEOUT) {
// TODO: Don't wait until the finger is lifted.
// Instead set a timer to start long click as soon as LONG_PRESS_TIMEOUT is reached
Gesture.LONG_CLICK.invoke(context)
}
} else {
// detect swipes
val doubleActions = LauncherPreferences.enabled_gestures().doubleSwipe()
val edgeActions = LauncherPreferences.enabled_gestures().edgeSwipe()
var gesture = getGestureForDirection(mainPointerPath.getDirection())
if (doubleActions && pointerCount > 1) {
if (paths.entries.any { getGestureForDirection(it.value.getDirection()) != gesture }) {
// the directions of the pointers don't match
return
}
gesture = gesture?.let(Gesture::getDoubleVariant)
}
// detect triangles
val startEndMin = mainPointerPath.start.min(mainPointerPath.last)
val startEndMax = mainPointerPath.start.max(mainPointerPath.last)
when (gesture) {
Gesture.SWIPE_DOWN -> {
if(startEndMax.x + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.x) {
gesture = Gesture.SWIPE_LARGER
} else if (startEndMin.x - MIN_TRIANGLE_HEIGHT > mainPointerPath.min.x) {
gesture = Gesture.SWIPE_SMALLER
}
}
Gesture.SWIPE_UP -> {
if(startEndMax.x + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.x) {
gesture = Gesture.SWIPE_LARGER_REVERSE
} else if (startEndMin.x - MIN_TRIANGLE_HEIGHT > mainPointerPath.min.x) {
gesture = Gesture.SWIPE_SMALLER_REVERSE
}
}
Gesture.SWIPE_RIGHT -> {
if(startEndMax.y + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.y) {
gesture = Gesture.SWIPE_V
} else if (startEndMin.y - MIN_TRIANGLE_HEIGHT > mainPointerPath.min.y) {
gesture = Gesture.SWIPE_LAMBDA
}
}
Gesture.SWIPE_LEFT -> {
if(startEndMax.y + MIN_TRIANGLE_HEIGHT < mainPointerPath.max.y) {
gesture = Gesture.SWIPE_V_REVERSE
} else if (startEndMin.y - MIN_TRIANGLE_HEIGHT > mainPointerPath.min.y) {
gesture = Gesture.SWIPE_LAMBDA_REVERSE
}
}
else -> { }
}
if (edgeActions) {
if (mainPointerPath.max.x < edgeWidth * width) {
gesture = gesture?.getEdgeVariant(Gesture.Edge.LEFT)
} else if (mainPointerPath.min.x > (1 - edgeWidth) * width) {
gesture = gesture?.getEdgeVariant(Gesture.Edge.RIGHT)
}
if (mainPointerPath.max.y < edgeWidth * height) {
gesture = gesture?.getEdgeVariant(Gesture.Edge.TOP)
} else if (mainPointerPath.min.y > (1 - edgeWidth) * height) {
gesture = gesture?.getEdgeVariant(Gesture.Edge.BOTTOM)
}
}
gesture?.invoke(context)
}
}
}

View file

@ -4,7 +4,7 @@
<string name="settings_launcher_section_appearance">Aspetto</string>
<string name="settings_apps_choose">Scegliere l\'applicazione</string>
<string name="settings_theme_color_theme">Tema</string>
<string name="tutorial_concept_text">Questo launcher è progettato per essere minimale, efficiente e privo di distrazioni.\n\nNon contiene pagamenti, pubblicità o servizi di tracciamento.</string>
<string name="tutorial_concept_text">Questo launcher è progettato per essere minimale, efficiente e privo di distrazioni. Non contiene pagamenti, pubblicità o servizi di tracciamento.</string>
<string name="settings_theme_color_theme_item_default">Predefinito</string>
<string name="settings_apps_hide_bound_apps">Non mostrare applicazioni collegate a gesti nella lista delle app</string>
<string name="settings_list_layout_item_text">Testo</string>
@ -45,11 +45,11 @@
<string name="settings_gesture_description_double_down">Scorri verso il basso con due dita</string>
<string name="settings_gesture_left">Sinistra</string>
<string name="settings_gesture_description_left">Scorrere verso sinistra</string>
<string name="settings_gesture_double_left">Doppio a sinistra</string>
<string name="settings_gesture_double_left">Due dita verso sinistra</string>
<string name="settings_gesture_description_double_left">Scorrere verso sinistra con due dita</string>
<string name="settings_gesture_right">Destra</string>
<string name="settings_gesture_description_right">Scorri verso destra</string>
<string name="settings_gesture_double_right">Doppio a destra</string>
<string name="settings_gesture_double_right">Due dita verso destra</string>
<string name="settings_gesture_description_double_right">Scorri a destra con due dita</string>
<string name="settings_gesture_right_top_edge">Destra (in alto)</string>
<string name="settings_gesture_description_right_top_edge">Scorri verso destra sul bordo superiore dello schermo</string>
@ -125,12 +125,12 @@
<string name="tutorial_setup_text">Abbiamo impostato alcune app predefinite per te. Puoi modificarle ora se lo desideri:</string>
<string name="tutorial_setup_text_2">Puoi anche cambiare la tua selezione in seguito.</string>
<string name="tutorial_finish_title">Iniziamo!</string>
<string name="tutorial_finish_text">Sei pronto per iniziare!\n\nSpero questa applicazione ti risulti preziosa!\n\n- Finn (che ha ideato il launcher)\n\t e Josia (che ha aggiunto qualche miglioramento e mantiene il fork μLauncher)</string>
<string name="tutorial_finish_text">Sei pronto per iniziare! Spero questa applicazione ti risulti preziosa! - Finn (che ha ideato il launcher)\n \te Josia (che ha aggiunto qualche miglioramento e mantiene il fork μLauncher)</string>
<string name="tutorial_finish_button">Inizia</string>
<string name="settings">Impostazioni</string>
<string name="ic_menu_alt">Altre opzioni</string>
<string name="tutorial_usage_text_2">Puoi aprire le tue app facendo scorrere il dito sullo schermo o premendo un pulsante. Configura i gesti nella prossima slide.</string>
<string name="alert_cant_expand_status_bar_panel">Errore: impossibile espandere la barra di stato.\nQuesta azione utilizza funzionalità non incluse nelle API Android pubbliche. Sfortunatamente, non sembra funzionare sul tuo dispositivo.</string>
<string name="alert_cant_expand_status_bar_panel">Errore: impossibile espandere la barra di stato. Questa azione utilizza funzionalità non incluse nelle API Android pubbliche. Sfortunatamente, non sembra funzionare sul tuo dispositivo.</string>
<string name="snackbar_app_hidden">Applicazione nascosta. Puoi renderla nuovamente visibile nelle impostazioni.</string>
<string name="toast_device_admin_not_enabled">µLauncher deve essere autorizzato come amministratore del dispositivo per bloccare lo schermo.</string>
<string name="device_admin_description">Abilita il blocco dello schermo</string>
@ -182,7 +182,7 @@
<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 tra le applicazioni</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>
<string name="list_other_nop">Non fare niente</string>
@ -191,11 +191,50 @@
<string name="tutorial_title">Tutorial</string>
<string name="tutorial_start_text">Prenditi qualche secondo per imparare ad usare questo launcher!</string>
<string name="tutorial_concept_title">Concetto</string>
<string name="tutorial_concept_text_2">L\'app è open source (sotto licenza MIT) e disponibile su GitHub!\n\nVisita il nostro archivio!</string>
<string name="tutorial_concept_text_2">L\'app è open source (sotto licenza MIT) e disponibile su GitHub! Visita il nostro archivio!</string>
<string name="tutorial_usage_title">Utilizzo</string>
<string name="tutorial_usage_text">La schermata principale contiene solo data e ora. Nessuna distrazione.</string>
<string name="alert_requires_android_m">Questa funzione richiede Android 6.0 o successivi.</string>
<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>
<string name="dialog_consent_accessibility_privileges">Sono consapevole che questo concederà privilegi estesi a µLauncher.</string>
<string name="dialog_consent_accessibility_consent">Accetto che µLauncher utilizzi il servizio di accessibilità per fornire funzionalità non correlate all\'accessibilità.</string>
<string name="dialog_consent_accessibility_data_collection">Accetto che µLauncher non raccolga alcun dato.</string>
<string name="settings_apps_hide_paused_apps">Nascondi le app in pausa</string>
<string name="list_other_toggle_private_space_lock">Attiva/Disattiva Blocco Spazio Privato</string>
<string name="alert_requires_android_v">Questa funzionalità richiede Android 15 o successivi.</string>
<string name="dialog_select_color_red">Rosso</string>
<string name="dialog_select_color_alpha">Trasparente</string>
<string name="dialog_select_color_blue">Blu</string>
<string name="dialog_select_color_green">Verde</string>
<string name="dialog_select_color_ok">Ok</string>
<string name="dialog_select_color_color_hex">Colore</string>
<string name="dialog_choose_color_title">Scegli colore</string>
<string name="dialog_consent_accessibility_ok">Attiva Servizi di Accessibilità</string>
<string name="dialog_consent_accessibility_other_options">Sono consapevole che esistono altre opzioni (utilizzando i privilegi di amministratore del dispositivo o il pulsante di accensione).</string>
<string name="dialog_consent_accessibility_title">Attivazione dei Servizi di Accessibilità</string>
<string name="settings_functionality_search_web">Cerca su internet</string>
<string name="settings_functionality_search_web_summary">Premi invio durante la ricerca nell\'elenco delle app per avviare una ricerca su internet.</string>
<string name="list_apps_search_hint_no_auto_launch">Cerca (senza avvio automatico)</string>
<string name="settings_meta_licenses">Licenze Open Source</string>
<string name="legal_info_title">Licenze Open Source</string>
<string name="dialog_report_bug_title">Segnala un bug</string>
<string name="dialog_report_bug_info">Grazie per aver contribuito a migliorare µLauncher!\nSi prega di aggiungere le seguenti informazioni alla segnalazione del bug:</string>
<string name="dialog_report_bug_button_clipboard">Copia negli appunti</string>
<string name="dialog_report_bug_security_info">Non segnalare pubblicamente le vulnerabilità di sicurezza su GitHub, ma utilizza invece:</string>
<string name="dialog_cancel">Annulla</string>
<string name="settings_functionality_auto_launch_summary">Premi spazio per disabilitare temporaneamente questa funzionalità.</string>
<string name="dialog_report_bug_button_security">Segnala una vulnerabilità di sicurezza</string>
<string name="dialog_report_bug_create_report">Crea una segnalazione</string>
<string name="toast_private_space_locked">Spazio privato bloccato</string>
<string name="toast_private_space_unlocked">Spazio privato sbloccato</string>
<string name="toast_private_space_not_available">Spazio privato non disponibile</string>
<string name="toast_private_space_default_home_screen">µLauncher deve essere la schermata iniziale predefinita per accedere allo spazio privato.</string>
<string name="toast_activity_not_found_browser">Impossibile aprire l\'URL: nessun browser trovato.</string>
<string name="toast_activity_not_found_search_web">Non è stata trovata un\'applicazione per gestire la ricerca.</string>
<string name="dialog_consent_accessibility_text"><![CDATA[Stai per arrivare il servizio di accessibilità. Questo garantirà <strong>privilegi più ampi</strong> a µLauncher.<br/>µLauncher utilizzerà questi privilegi <strong>solo per bloccare lo schermo</strong>. µLauncher <strong>non raccoglierà mai alcun dato</strong>. In particolare, µLauncher non usa il servizio di accessibilità per raccogliere nessun dato.]]></string>
</resources>

View file

@ -30,14 +30,14 @@
<string name="settings_gesture_double_left">2 dedos para esquerda</string>
<string name="settings_gesture_right">Para direita</string>
<string name="settings_gesture_double_right">2 dedos para direita</string>
<string name="settings_gesture_right_top_edge">Para direita (No topo)</string>
<string name="settings_gesture_right_top_edge">Para direita (no topo)</string>
<string name="settings_gesture_right_bottom_edge">Para direita (em baixo)</string>
<string name="settings_gesture_left_bottom_edge">Para esquerda (Em baixo)</string>
<string name="settings_gesture_left_top_edge">Para esquerda (No topo)</string>
<string name="settings_gesture_up_left_edge">Para cima (Borda esquerda)</string>
<string name="settings_gesture_up_right_edge">Para cima (Borda direita)</string>
<string name="settings_gesture_down_left_edge">Para baixo (Borda esquerda)</string>
<string name="settings_gesture_down_right_edge">Para baixo (Borda direita)</string>
<string name="settings_gesture_left_bottom_edge">Para esquerda (em baixo)</string>
<string name="settings_gesture_left_top_edge">Para esquerda (no topo)</string>
<string name="settings_gesture_up_left_edge">Para cima (borda esquerda)</string>
<string name="settings_gesture_up_right_edge">Para cima (borda direita)</string>
<string name="settings_gesture_down_left_edge">Para baixo (borda esquerda)</string>
<string name="settings_gesture_down_right_edge">Para baixo (borda direita)</string>
<string name="settings_gesture_vol_up">Aumento de volume</string>
<string name="settings_gesture_vol_down">Diminuição de volume</string>
<string name="settings_gesture_double_click">Toque duplo</string>
@ -62,7 +62,7 @@
<string name="settings_clock_date_visible">Mostrar Data</string>
<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 um papel de parede</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>
@ -121,11 +121,11 @@
<string name="tutorial_concept_text">O Launcher foi criado para ser minimalista, eficiente e livre de distrações. Ele é livre de pagamentos, anúncios e serviços de rastreamento.</string>
<string name="tutorial_concept_text_2">O app é de código aberto (licença MIT) e está disponível no GitHub! Não deixe de conferir o repositório!</string>
<string name="tutorial_usage_title">Uso</string>
<string name="tutorial_usage_text">Sua tela inicial contém a data e hora local. Sem distração.</string>
<string name="tutorial_usage_text_2">Você pode iniciar seus aplicativos com um toque único ou pressionando um botão. Escolha algumas ações no próximo slide.</string>
<string name="tutorial_usage_text">Sua tela inicial contém a data e hora local. Sem distrações.</string>
<string name="tutorial_usage_text_2">Você pode iniciar seus aplicativos com um gesto único ou apertando um botão. Escolha algumas ações no próximo slide.</string>
<string name="tutorial_setup_title">Configurar</string>
<string name="tutorial_setup_text">Selecionamos alguns aplicativos padrão para você. Se quiser, você pode alterá-los agora:</string>
<string name="tutorial_setup_text_2">Você também pode alterar suas escolhas mais tarde.</string>
<string name="tutorial_setup_text_2">Você pode alterar suas escolhas mais tarde.</string>
<string name="tutorial_finish_title">Vamos lá!</string>
<string name="tutorial_finish_text">Tá todo pronto para começar! Espero que isso seja de grande valor para você! - Finn (que criou o Launcher) \te Josia (que fez algumas melhorias e tb mantém o fork do μLauncher)</string>
<string name="tutorial_finish_button">Começar</string>
@ -162,9 +162,9 @@
<string name="screen_lock_method_use_accessibility">Usar o Serviço de acessibilidade</string>
<string name="screen_lock_method_use_device_admin">Usar o Administrador do dispositivo</string>
<string name="screen_lock_method_dialog_title">Escolha um método de bloqueio</string>
<string name="settings_actions_lock_method">Escolha um método de bloqueio da tela</string>
<string name="settings_actions_lock_method">Escolha método de bloqueio da tela</string>
<string name="list_other_expand_settings_panel">Configurações rápidas</string>
<string name="alert_requires_android_m">Essa funcionalidade requer o Android 6.0 ou mais recente.</string>
<string name="alert_requires_android_m">Essa funcionalidade requer o Android 6 ou mais recente.</string>
<string name="alert_no_torch_found">Nenhuma câmera com lanterna detectada.</string>
<string name="toast_lock_screen_not_supported">Erro: O bloqueio da tela via Serviço de acessibilidade não é compatível com este aparelho. Tente usar Administrador do dispositivo como método alternativo.</string>
<string name="accessibility_service_description">Definindo µLauncher como Serviço de acessibilidade permite a ele bloquear a tela. Considere que é necessário conceder as permissões elevadas. Você nunca deveria autorizar essas permissões a qualquer aplicativo sem avaliação. O µLauncher usará o Serviço de acessibilidade somente para bloquear a tela. Você pode verificar o código-fonte para ter certeza. O bloqueio da tela também pode ser realizado dando ao µLauncher permissões de Administrador do dispositivo. Apesar de que esse método não funciona com impressão digital e desbloqueio facial.</string>
@ -260,7 +260,7 @@
<string name="legal_info_title">Licenças de código aberto</string>
<string name="settings_apps_hide_paused_apps">Ocultar apps pausados</string>
<string name="list_other_toggle_private_space_lock">Ativar o Espaço privado</string>
<string name="alert_requires_android_v">Essa funcionalidade requer o Android 15.0 ou mais recente.</string>
<string name="alert_requires_android_v">Essa funcionalidade requer o Android 15 ou mais recente.</string>
<string name="toast_private_space_locked">Espaço privado trancado</string>
<string name="toast_private_space_unlocked">Espaço privado liberado</string>
<string name="toast_private_space_not_available">Espaço privado indisponível</string>
@ -271,4 +271,14 @@
<string name="dialog_report_bug_create_report">Criar relatório</string>
<string name="dialog_report_bug_title">Relatar um bug</string>
<string name="dialog_report_bug_info">Obrigado por ajudar a melhorar o µLauncher!\nConsidere adicionar as seguintes informações ao relatório de bug:</string>
<string name="settings_functionality_auto_launch_summary">Toque no espaço para temporariamente desativar esta funcionalidade.</string>
<string name="toast_activity_not_found_browser">Não foi possível abrir a URL: nenhum navegador encontrado.</string>
<string name="toast_activity_not_found_search_web">Nenhum app encontrado para efetuar a pesquisa.</string>
<string name="settings_gesture_back">Voltar</string>
<string name="settings_gesture_description_back">Botão Voltar / gesto de Voltar</string>
<string name="settings_apps_hide_private_space_apps">Ocultar espaço privado na lista de apps</string>
<string name="list_title_private_space">Espaço privado</string>
<string name="list_other_list_private_space">Espaço privado</string>
<string name="tooltip_lock_private_space">Trancar espaço privado</string>
<string name="tooltip_unlock_private_space">Liberar espaço privado</string>
</resources>

View file

@ -2,6 +2,8 @@
<resources>
<!-- Default Apps for different actions (button-press, swipes ...) -->
<string-array name="no_default">
</string-array>
<!-- Back - Apps list -->
<string-array name="default_back">

View file

@ -59,6 +59,24 @@
<string name="settings_gesture_description_down_left_edge">Swipe down at the left edge of the screen</string>
<string name="settings_gesture_down_right_edge">Down (Right Edge)</string>
<string name="settings_gesture_description_down_right_edge">Swipe down at the right edge of the screen</string>
<string name="settings_gesture_swipe_larger"><![CDATA[>]]></string>
<string name="settings_gesture_description_swipe_larger">Top left -> mid right -> bottom left</string>
<string name="settings_gesture_swipe_larger_reverse"><![CDATA[> (reverse)]]></string>
<string name="settings_gesture_description_swipe_larger_reverse">Bottom left -> mid right -> top left</string>
<string name="settings_gesture_swipe_smaller"><![CDATA[<]]></string>
<string name="settings_gesture_description_swipe_smaller">Top right -> mid left -> bottom right</string>
<string name="settings_gesture_swipe_smaller_reverse"><![CDATA[< (reverse)]]></string>
<string name="settings_gesture_description_swipe_smaller_reverse">Bottom right -> mid left -> top right</string>
<string name="settings_gesture_swipe_v">V</string>
<string name="settings_gesture_description_swipe_v">Top left -> bottom mid -> top right</string>
<string name="settings_gesture_swipe_v_reverse">V (reverse)</string>
<string name="settings_gesture_description_swipe_v_reverse">Top right -> bottom mid -> top left</string>
<string name="settings_gesture_swipe_lambda">Λ</string>
<string name="settings_gesture_description_swipe_lambda">Bottom left -> top mid -> bottom right</string>
<string name="settings_gesture_swipe_lambda_reverse">Λ (reverse)</string>
<string name="settings_gesture_description_swipe_lambda_reverse">Bottom right -> top mid -> bottom left</string>
<string name="settings_gesture_vol_up">Volume Up</string>
<string name="settings_gesture_description_vol_up">Press the volume up button</string>
<string name="settings_gesture_vol_down">Volume Down</string>

49
docs/launcher.md Normal file
View file

@ -0,0 +1,49 @@
# Notable changes compared to [Finn's Launcher][original-repo]:
µ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.
- 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)
- Option to rename apps
- Option to hide apps
- Favorite apps
- New actions:
- Toggle Torch
- Lock screen
- The home button now works as expected.
- Improved gesture detection.
### 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
- 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
- Improved gesture detection.
- Different apps set as default.
- Package name was changed to `de.jrpie.android.launcher` to avoid clashing with the original app.
- Dropped support for API < 21 (i.e. pre Lollypop)
- 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

View file

@ -0,0 +1 @@
µLauncher

View file

@ -1,23 +1,23 @@
O µLauncher é uma tela inicial que permite abrir aplicativos através gestos de deslize e botões físicos.
O µLauncher é uma tela inicial que permite abrir apps através de gestos e botões físicos.
O launcher é minimalista, eficiente e livre de distrações.
Sua tela inicial exibe apenas a data, hora e papel de parede.
A tela inicial mostra apenas a data, hora e papel de parede.
Ao usar Voltar ou deslize para cima (pode ser configurado depois) você abre a lista
com todos os aplicativos instalados, que podem ser encontrados rápido.
Ao usar botão Voltar ou gesto pra cima (pode ser redefinido depois)
você abre com facilidade e rapidez a lista com todos os apps instalados.
Esta é uma modificação do app <a href="https://f-droid.org/packages/com.finnmglas.launcher/">Launcher</a>
feita por Finn M Glas.
O app é uma modificação do <a href="https://f-droid.org/packages/com.finnmglas.launcher/">Launcher</a>
feito por Finn M Glas.
Funcionalidades:
* Você pode associar várias ações a 22 gestos diferentes.
* Também pode definir algumas das seguintes acções:
- Iniciar algum app
* Pode definir algumas das seguintes ações:
- Iniciar vários apps
- Listar todos aplicativos
- Listar apps favoritos
- Aumentar / diminuir o volume
- Música: faixa anterior / seguinte
- Música: passar pra faixa anterior / seguinte
- Bloquear a tela
- Ligar a lanterna
- Mostrar notificações / configurações rápidas
* Compatível com Perfil de trabalho, desta forma apps como Shelter podem ser usados.
* App é compatível com Perfil de trabalho e pode ser usado com apps tipo Shelter.

View file

@ -1 +1 @@
Uma tela inicial minimalista e sem distrações para Android.
Tela inicial minimalista e sem distrações para Android.

View file

@ -0,0 +1,15 @@
- Çince çeviri (teşekkürler, yzqzss!)
- Fransızca çeviri iyileştirildi (teşekkürler, toby-bro!)
- Almanca çeviri iyileştirildi
Tüm Uygulamalar:
- Uygulama listesindeki üç nokta kaldırıldı (bunun yerine uzun tıklama kullanın)
- Enter'a basıldığında sorguyla eşleşen ilk uygulama açılıyor
- Klavyeyi tam ekran modunda açarken oluşan hata için geçici çözüm düzeltildi
- Sistem uygulamaları için kaldırma seçeneği kaldırıldı
- Ana Sayfa Düğmesi artık düzgün çalışıyor
Ayarlar:
- Küçük ekranlar için ayarlar düzeltildi
- Hassasiyet ayarı kaldırıldı (herkes zaten maksimuma ayarlıyordu)
- Tarih ve saat ayarları yeniden düzenlendi

View file

@ -0,0 +1,8 @@
* Renk teması, yazı tipi, arka plan, monokrom simgeler için seçenekler eklendi
* Tarih ve saat için seçenekler eklendi
* Döndürmeye izin verme seçeneği eklendi
* İyileştirilmiş arama algoritması
* Brezilya Portekizcesine çeviri - teşekkürler, Jonatas de Almeida Barros!
* Ayarlardan seçilen uygulamaların kaybolmasına neden olan bir hata düzeltildi
* İyileştirilmiş kod kalitesi
* Güncellenmiş çeviriler

View file

@ -0,0 +1,4 @@
* Favori uygulamalar
* Uygulamaları gizleme seçeneği
* Birden fazla ana aktiviteye sahip uygulamalar için destek
* Küçük ekranlarda ayarların düzeni düzeltildi

View file

@ -0,0 +1 @@
hata düzeltme

View file

@ -0,0 +1,9 @@
* Matrix ve Discord'da sohbet
* Hareket algılama iyileştirildi
* Hareket açıklamaları iyileştirildi
* Yeni eylem: Ekranı kilitle - teşekkürler, yzqzss!
* Yeni eylem: Meşaleyi aç
* Yeni eylem: Hızlı ayarları
* Fransızca çevirisi iyileştirildi - teşekkürler, toby-bro!
* Portekizce çevirisi iyileştirildi - teşekkürler, "Vossa Excelencia"!
* Bazı hatalar düzeltildi

View file

@ -0,0 +1 @@
Ekranı kilitlemek için Cihaz Yöneticisi yerine Erişilebilirlik Hizmetini kullanma seçeneği eklendi.

View file

@ -0,0 +1,11 @@
* Uygulamaları yeniden adlandırma seçeneği
* Uygulama listesinden hareketlere bağlı uygulamaları otomatik olarak gizleme seçeneği
* Uygulama listesinden µLauncher'ı varsayılan olarak gizle
* Varsayılan uygulamaların seçimi iyileştirildi
* Açık tema (deneysel)
* Aramadaki hata düzeltildi
* Kilit ekranı iletişim kutusundaki hata düzeltildi (teşekkürler, yzqzss ve jeroen!)
* Portekizce çeviri güncellendi (teşekkürler, "Vossa Excelencia"!)
* Almanca çeviri güncellendi

View file

@ -0,0 +1,5 @@
* Uygulama listesi için alternatif düzenler (ızgara, metin)
* Hata düzeltildi: Uygulamaların yeniden adlandırılması artık düzgün çalışıyor
* Çince çeviri güncellendi (teşekkürler, yzqzss!)
* Portekizce çeviri güncellendi (teşekkürler, "Vossa Excelencia"!)

View file

@ -0,0 +1,9 @@
* Saat rengini seçme seçeneği
* Dinamik renk teması eklendi; açık tema kaldırıldı
* Erişilebilirlik hizmeti için onay iletişim kutusu eklendi
* Türkçe çeviri eklendi (teşekkürler, Ahmet Çeliker!)
* İtalyanca çeviri eklendi (teşekkürler, Samantha!)
* Portekizce çeviri iyileştirildi (teşekkürler, "Vossa Excelencia"!)
* Uygulama çekmecesinde hareketle gezinmeyle ilgili hata düzeltildi. Artık geri basıldığında çekmece hemen kapanıyor.

View file

@ -0,0 +1,6 @@
* Ayarlar için depolama biçimi yeniden düzenlendi. Eski biçim otomatik olarak dönüştürülecek.
* Uygulama listesinden web'de arama yapma seçeneği eklendi.
* Ekranı kilitlemek için tercih edilen yöntem olarak cihaz yöneticisini ayarlayın.
* Bir erişilebilirlik hizmetini etkinleştirmenin şifrelemeyle çakışabileceğine dair bir uyarı eklendi.
* Yeniden adlandırma iletişim kutusundaki bir hata düzeltildi.
* Kilit ekranı iletişim kutusu kaydırılabilir hale getirildi.

View file

@ -0,0 +1,6 @@
* yeni özellik: otomatik başlatmayı geçici olarak devre dışı bırakmak için boşluk içeren önek sorgusu
* iyileştirilmiş arama: sorguda görünmedikleri sürece diakritik işaretler artık yok sayılıyor. (Android 7+)
* açık kaynak lisanslarının listesi eklendi
* erişilebilirlik hizmeti uyarısı güncellendi
* iyileştirilmiş Fransızca çeviri (teşekkürler, Alexandre Ancel ve Nin Dan!)
* iyileştirilmiş Portekizce çeviri (teşekkürler, "Vossa Excelencia"!)

View file

@ -0,0 +1,8 @@
* private space için temel destek (Android 15)
* light tema yeniden tanıtıldı
* Portekizce çeviri iyileştirildi (teşekkürler, "Vossa Excelencia"!)
* Almanca çeviri iyileştirildi
* ayarlara sürüm adı eklendi
* hata raporları için iletişim kutusu
* saat performansı iyileştirildi
* bazı hatalar düzeltildi

View file

@ -0,0 +1 @@
µBaşlatıcı