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 ba47942..e0d1d00 100644 --- a/app/src/main/java/de/jrpie/android/launcher/Application.kt +++ b/app/src/main/java/de/jrpie/android/launcher/Application.kt @@ -28,7 +28,7 @@ import kotlinx.coroutines.launch import kotlin.system.exitProcess -const val APP_WIDGET_HOST_ID = 42 +const val APP_WIDGET_HOST_ID = 42; class Application : android.app.Application() { diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/TorchManager.kt b/app/src/main/java/de/jrpie/android/launcher/actions/TorchManager.kt index a2ea801..6768116 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/TorchManager.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/TorchManager.kt @@ -1,6 +1,7 @@ package de.jrpie.android.launcher.actions import android.content.Context +import android.hardware.camera2.CameraAccessException import android.hardware.camera2.CameraCharacteristics import android.hardware.camera2.CameraManager import android.os.Build diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/WidgetPanelAction.kt b/app/src/main/java/de/jrpie/android/launcher/actions/WidgetPanelAction.kt index 84c4179..d7829a6 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/WidgetPanelAction.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/WidgetPanelAction.kt @@ -1,6 +1,5 @@ package de.jrpie.android.launcher.actions -import android.app.Activity import android.content.Context import android.content.Intent import android.graphics.Rect @@ -26,18 +25,11 @@ class WidgetPanelAction(val widgetPanelId: Int) : Action { override fun invoke(context: Context, rect: Rect?): Boolean { - if (context is WidgetPanelActivity) { - if (context.widgetPanelId == widgetPanelId) { - context.finish() - return true - } - } - - if (WidgetPanel.byId(this.widgetPanelId) == null) { + if (WidgetPanel.byId(widgetPanelId) == null) { Toast.makeText(context, R.string.alert_widget_panel_not_found, Toast.LENGTH_LONG).show() } else { context.startActivity(Intent(context, WidgetPanelActivity::class.java).also { - it.putExtra(EXTRA_PANEL_ID, this.widgetPanelId) + it.putExtra(EXTRA_PANEL_ID, widgetPanelId) }) } return true diff --git a/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt b/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt index 541510a..93b4cbf 100644 --- a/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt +++ b/app/src/main/java/de/jrpie/android/launcher/actions/lock/LockMethod.kt @@ -6,6 +6,7 @@ import android.widget.Button import androidx.appcompat.app.AlertDialog import de.jrpie.android.launcher.BuildConfig import de.jrpie.android.launcher.R +import de.jrpie.android.launcher.actions.lock.LauncherAccessibilityService import de.jrpie.android.launcher.preferences.LauncherPreferences diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt index a4b1f43..e5877f5 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/Preferences.kt @@ -2,6 +2,7 @@ package de.jrpie.android.launcher.preferences import android.content.Context import android.util.Log +import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.BuildConfig import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.apps.AbstractAppInfo @@ -20,8 +21,8 @@ import de.jrpie.android.launcher.widgets.ClockWidget import de.jrpie.android.launcher.widgets.DebugInfoWidget import de.jrpie.android.launcher.widgets.WidgetPanel import de.jrpie.android.launcher.widgets.WidgetPosition +import de.jrpie.android.launcher.widgets.deleteAllWidgets import de.jrpie.android.launcher.widgets.generateInternalId -import de.jrpie.android.launcher.widgets.getAppWidgetHost /* Current version of the structure of preferences. * Increase when breaking changes are introduced and write an appropriate case in @@ -91,7 +92,7 @@ fun resetPreferences(context: Context) { Log.i(TAG, "Resetting preferences") LauncherPreferences.clear() LauncherPreferences.internal().versionCode(PREFERENCE_VERSION) - context.getAppWidgetHost().deleteHost() + deleteAllWidgets(context) LauncherPreferences.widgets().widgets( setOf( diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version4.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version4.kt index fb353d5..b13978b 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version4.kt +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/legacy/Version4.kt @@ -1,7 +1,9 @@ package de.jrpie.android.launcher.preferences.legacy import android.content.Context +import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.preferences.LauncherPreferences +import de.jrpie.android.launcher.preferences.PREFERENCE_VERSION import de.jrpie.android.launcher.widgets.ClockWidget import de.jrpie.android.launcher.widgets.WidgetPanel import de.jrpie.android.launcher.widgets.WidgetPosition diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt index 76bf443..f3cde9a 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt @@ -1,9 +1,16 @@ package de.jrpie.android.launcher.ui +import android.annotation.SuppressLint +import android.app.Activity import android.content.SharedPreferences +import android.content.res.Configuration import android.content.res.Resources +import android.os.Build import android.os.Bundle +import android.view.KeyEvent +import android.view.MotionEvent import android.view.View +import android.window.OnBackInvokedDispatcher import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.actions.Action import de.jrpie.android.launcher.actions.Gesture @@ -12,7 +19,6 @@ import de.jrpie.android.launcher.databinding.ActivityHomeBinding import de.jrpie.android.launcher.openTutorial import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.ui.tutorial.TutorialActivity -import de.jrpie.android.launcher.ui.util.LauncherGestureActivity /** * [HomeActivity] is the actual application Launcher, @@ -26,9 +32,10 @@ import de.jrpie.android.launcher.ui.util.LauncherGestureActivity * - Setting global variables (preferences etc.) * - Opening the [TutorialActivity] on new installations */ -class HomeActivity : UIObject, LauncherGestureActivity() { +class HomeActivity : UIObject, Activity() { private lateinit var binding: ActivityHomeBinding + private var touchGestureDetector: TouchGestureDetector? = null private var sharedPreferencesListener = SharedPreferences.OnSharedPreferenceChangeListener { _, prefKey -> @@ -47,21 +54,35 @@ class HomeActivity : UIObject, LauncherGestureActivity() { } override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) + super.onCreate(savedInstanceState) super.onCreate() + // Initialise layout binding = ActivityHomeBinding.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( + OnBackInvokedDispatcher.PRIORITY_OVERLAY + ) { + handleBack() + } + } binding.buttonFallbackSettings.setOnClickListener { LauncherAction.SETTINGS.invoke(this) } } + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + touchGestureDetector?.updateScreenSize(windowManager) + } + override fun onStart() { - super.onStart() + super.onStart() super.onStart() // If the tutorial was not finished, start it @@ -112,28 +133,80 @@ class HomeActivity : UIObject, LauncherGestureActivity() { override fun onResume() { super.onResume() + + /* This should be initialized in onCreate() + However on some devices there seems to be a bug where the touchGestureDetector + is not working properly after resuming the app. + Reinitializing the touchGestureDetector every time the app is resumed might help to fix that. + (see issue #138) + */ + touchGestureDetector = TouchGestureDetector( + this, 0, 0, + LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f + ).also { + it.updateScreenSize(windowManager) + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + binding.root.setOnApplyWindowInsetsListener { _, windowInsets -> + @Suppress("deprecation") // required to support API 29 + val insets = windowInsets.systemGestureInsets + touchGestureDetector?.setSystemGestureInsets(insets) + + windowInsets + } + } updateSettingsFallbackButtonVisibility() binding.homeWidgetContainer.updateWidgets(this@HomeActivity, LauncherPreferences.widgets().widgets() ) + (application as Application).appWidgetHost.startListening() } - override fun onDestroy() { LauncherPreferences.getSharedPreferences() .unregisterOnSharedPreferenceChangeListener(sharedPreferencesListener) super.onDestroy() } - override fun handleBack() { - Gesture.BACK(this) + @SuppressLint("GestureBackNavigation") + override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { + when (keyCode) { + KeyEvent.KEYCODE_BACK -> { + // Only used pre Android 13, cf. onBackInvokedDispatcher + handleBack() + } + + KeyEvent.KEYCODE_VOLUME_UP -> { + if (Action.forGesture(Gesture.VOLUME_UP) == LauncherAction.VOLUME_UP) { + // Let the OS handle the key event. This works better with some custom ROMs + // and apps like Samsung Sound Assistant. + return false + } + Gesture.VOLUME_UP(this) + } + + KeyEvent.KEYCODE_VOLUME_DOWN -> { + if (Action.forGesture(Gesture.VOLUME_DOWN) == LauncherAction.VOLUME_DOWN) { + // see above + return false + } + Gesture.VOLUME_DOWN(this) + } + } + return true } - override fun getRootView(): View { - return binding.root + override fun onTouchEvent(event: MotionEvent): Boolean { + touchGestureDetector?.onTouchEvent(event) + return true + } + + private fun handleBack() { + Gesture.BACK(this) } override fun isHomeScreen(): Boolean { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt index 70f737f..3dbdda8 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/PinShortcutActivity.kt @@ -1,6 +1,7 @@ package de.jrpie.android.launcher.ui import android.app.AlertDialog +import android.app.Service import android.content.Context import android.content.pm.LauncherApps import android.content.pm.LauncherApps.PinItemRequest @@ -44,7 +45,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { binding = ActivityPinShortcutBinding.inflate(layoutInflater) setContentView(binding.root) - val launcherApps = getSystemService(LAUNCHER_APPS_SERVICE) as LauncherApps + val launcherApps = getSystemService(Service.LAUNCHER_APPS_SERVICE) as LauncherApps val request = launcherApps.getPinItemRequest(intent) this.request = request @@ -55,7 +56,7 @@ class PinShortcutActivity : AppCompatActivity(), UIObject { if (request.requestType == PinItemRequest.REQUEST_TYPE_APPWIDGET) { - // TODO handle app widgets + // TODO request.getAppWidgetProviderInfo(this) // startActivity() finish() diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt index 8264752..8e8ed4e 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/TouchGestureDetector.kt @@ -17,7 +17,6 @@ import kotlin.math.max import kotlin.math.min import kotlin.math.tan -@Suppress("PrivatePropertyName") class TouchGestureDetector( private val context: Context, var width: Int, @@ -35,13 +34,13 @@ class TouchGestureDetector( private val MIN_TRIANGLE_HEIGHT = 250 + private val longPressHandler = Handler(Looper.getMainLooper()) + private var systemGestureInsetTop = 100 private var systemGestureInsetBottom = 0 private var systemGestureInsetLeft = 0 private var systemGestureInsetRight = 0 - private val longPressHandler = Handler(Looper.getMainLooper()) - data class Vector(val x: Float, val y: Float) { fun absSquared(): Float { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt index 784d6fa..65278ce 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/AppsRecyclerAdapter.kt @@ -237,4 +237,9 @@ class AppsRecyclerAdapter( appFilter.favoritesVisibility = v updateAppsList() } + + fun setHiddenAppsVisibility(v: AppFilter.Companion.AppSetVisibility) { + appFilter.hiddenVisibility = v + updateAppsList() + } } diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt index ed26729..a8e59ba 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/list/apps/ListFragmentApps.kt @@ -96,6 +96,7 @@ class ListFragmentApps : Fragment(), UIObject { if (LauncherPreferences.functionality().searchAutoCloseKeyboard()) { addOnScrollListener(object : RecyclerView.OnScrollListener() { var totalDy: Int = 0 + var threshold = (resources.displayMetrics.density * 100).toInt() override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { totalDy += dy diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt b/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt index 1a0e802..759d8cd 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/settings/meta/SettingsFragmentMeta.kt @@ -79,9 +79,6 @@ class SettingsFragmentMeta : Fragment(), UIObject { // view code bindURL(binding.settingsMetaButtonViewCode, R.string.settings_meta_link_github) - // view documentation - bindURL(binding.settingsMetaButtonViewDocs, R.string.settings_meta_link_docs) - // report a bug binding.settingsMetaButtonReportBug.setOnClickListener { val deviceInfo = getDeviceInfo() diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment5Finish.kt b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment5Finish.kt index 548c30b..e15cef1 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment5Finish.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/tutorial/tabs/TutorialFragment5Finish.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import de.jrpie.android.launcher.BuildConfig.VERSION_CODE import de.jrpie.android.launcher.databinding.Tutorial5FinishBinding import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.requestNotificationPermission diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/util/LauncherGestureActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/util/LauncherGestureActivity.kt deleted file mode 100644 index 0be09f9..0000000 --- a/app/src/main/java/de/jrpie/android/launcher/ui/util/LauncherGestureActivity.kt +++ /dev/null @@ -1,104 +0,0 @@ -package de.jrpie.android.launcher.ui.util - -import android.annotation.SuppressLint -import android.app.Activity -import android.content.res.Configuration -import android.os.Build -import android.os.Bundle -import android.view.KeyEvent -import android.view.MotionEvent -import android.view.View -import android.window.OnBackInvokedDispatcher -import de.jrpie.android.launcher.actions.Action -import de.jrpie.android.launcher.actions.Gesture -import de.jrpie.android.launcher.actions.LauncherAction -import de.jrpie.android.launcher.preferences.LauncherPreferences -import de.jrpie.android.launcher.ui.TouchGestureDetector - -/** - * An activity with a [TouchGestureDetector] as well as handling of volume and back keys set up. - */ -abstract class LauncherGestureActivity: Activity() { - protected var touchGestureDetector: TouchGestureDetector? = null - - override fun onTouchEvent(event: MotionEvent): Boolean { - touchGestureDetector?.onTouchEvent(event) - return true - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - // Handle back key / gesture on Android 13+, cf. onKeyDown() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - onBackInvokedDispatcher.registerOnBackInvokedCallback( - OnBackInvokedDispatcher.PRIORITY_OVERLAY - ) { - handleBack() - } - } - } - - override fun onResume() { - super.onResume() - - /* This should be initialized in onCreate() - However on some devices there seems to be a bug where the touchGestureDetector - is not working properly after resuming the app. - Reinitializing the touchGestureDetector every time the app is resumed might help to fix that. - (see issue #138) - */ - touchGestureDetector = TouchGestureDetector( - this, 0, 0, - LauncherPreferences.enabled_gestures().edgeSwipeEdgeWidth() / 100f - ).also { - it.updateScreenSize(windowManager) - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - getRootView()?.setOnApplyWindowInsetsListener { _, windowInsets -> - @Suppress("deprecation") // required to support API 29 - val insets = windowInsets.systemGestureInsets - touchGestureDetector?.setSystemGestureInsets(insets) - - windowInsets - } - } - } - - @SuppressLint("GestureBackNavigation") - override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { - when (keyCode) { - KeyEvent.KEYCODE_BACK -> { - // Only used pre Android 13, cf. onBackInvokedDispatcher - handleBack() - } - - KeyEvent.KEYCODE_VOLUME_UP -> { - if (Action.forGesture(Gesture.VOLUME_UP) == LauncherAction.VOLUME_UP) { - // Let the OS handle the key event. This works better with some custom ROMs - // and apps like Samsung Sound Assistant. - return false - } - Gesture.VOLUME_UP(this) - } - - KeyEvent.KEYCODE_VOLUME_DOWN -> { - if (Action.forGesture(Gesture.VOLUME_DOWN) == LauncherAction.VOLUME_DOWN) { - // see above - return false - } - Gesture.VOLUME_DOWN(this) - } - } - return true - } - - override fun onConfigurationChanged(newConfig: Configuration) { - super.onConfigurationChanged(newConfig) - touchGestureDetector?.updateScreenSize(windowManager) - } - - protected abstract fun getRootView(): View? - protected abstract fun handleBack() -} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/ClockView.kt b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/ClockView.kt index cbe5395..54d3869 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/ClockView.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/ClockView.kt @@ -8,11 +8,9 @@ import androidx.core.view.isVisible import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.databinding.WidgetClockBinding import de.jrpie.android.launcher.preferences.LauncherPreferences -import de.jrpie.android.launcher.widgets.WidgetPanel import java.util.Locale -class ClockView(context: Context, attrs: AttributeSet? = null, val appWidgetId: Int, val panelId: Int): ConstraintLayout(context, attrs) { - constructor(context: Context, attrs: AttributeSet?): this(context, attrs, WidgetPanel.HOME.id, -1) +class ClockView(context: Context, attrs: AttributeSet? = null, val appWidgetId: Int): ConstraintLayout(context, attrs) { val binding: WidgetClockBinding = WidgetClockBinding.inflate(LayoutInflater.from(context), this, true) init { @@ -59,7 +57,7 @@ class ClockView(context: Context, attrs: AttributeSet? = null, val appWidgetId: binding.clockUpperView.format12Hour = upperFormat } - private fun setOnClicks() { + fun setOnClicks() { binding.clockUpperView.setOnClickListener { if (LauncherPreferences.clock().flipDateTime()) { Gesture.TIME(context) @@ -76,4 +74,7 @@ class ClockView(context: Context, attrs: AttributeSet? = null, val appWidgetId: } } } + + + } \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/WidgetContainerView.kt b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/WidgetContainerView.kt index 5eab32f..5f8adf1 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/WidgetContainerView.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/WidgetContainerView.kt @@ -61,7 +61,7 @@ open class WidgetContainerView( it.value.y + it.value.height ).contains(position) == true }.any { - Widget.byId(it.key)?.allowInteraction == false + Widget.byId(context, it.key)?.allowInteraction == false } } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/WidgetPanelActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/WidgetPanelActivity.kt index 7d51b08..3c884db 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/WidgetPanelActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/WidgetPanelActivity.kt @@ -1,31 +1,27 @@ package de.jrpie.android.launcher.ui.widgets +import android.app.Activity import android.content.res.Resources import android.os.Bundle -import android.view.View import androidx.core.view.ViewCompat import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R import de.jrpie.android.launcher.databinding.ActivityWidgetPanelBinding import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.ui.UIObject -import de.jrpie.android.launcher.ui.util.LauncherGestureActivity import de.jrpie.android.launcher.ui.widgets.manage.EXTRA_PANEL_ID import de.jrpie.android.launcher.widgets.WidgetPanel -class WidgetPanelActivity : LauncherGestureActivity(), UIObject { - var binding: ActivityWidgetPanelBinding? = null - - var widgetPanelId: Int = WidgetPanel.HOME.id - +class WidgetPanelActivity : Activity(), UIObject { + lateinit var binding: ActivityWidgetPanelBinding + private var widgetPanelId: Int = WidgetPanel.HOME.id override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) + super.onCreate(savedInstanceState) super.onCreate() + widgetPanelId = intent.getIntExtra(EXTRA_PANEL_ID, WidgetPanel.HOME.id) val binding = ActivityWidgetPanelBinding.inflate(layoutInflater) setContentView(binding.root) - widgetPanelId = intent.getIntExtra(EXTRA_PANEL_ID, WidgetPanel.HOME.id) - // The widget container should extend below the status and navigation bars, // so let's set an empty WindowInsetsListener to prevent it from being moved. ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, windowInsets -> @@ -60,8 +56,9 @@ class WidgetPanelActivity : LauncherGestureActivity(), UIObject { } override fun onStart() { - super.onStart() + super.onStart() super.onStart() + } override fun onPause() { @@ -79,14 +76,6 @@ class WidgetPanelActivity : LauncherGestureActivity(), UIObject { (application as Application).appWidgetHost.startListening() } - override fun getRootView(): View? { - return binding?.root - } - - override fun handleBack() { - finish() - } - override fun isHomeScreen(): Boolean { return true } 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 163777f..89e1057 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 @@ -9,6 +9,7 @@ import android.widget.EditText import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager +import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.R import de.jrpie.android.launcher.databinding.ActivityManageWidgetPanelsBinding import de.jrpie.android.launcher.preferences.LauncherPreferences 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 531cdc1..953fc28 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 @@ -5,6 +5,7 @@ import android.appwidget.AppWidgetManager import android.content.Intent import android.content.SharedPreferences import android.content.res.Resources +import android.graphics.Rect import android.os.Bundle import android.util.Log import android.view.ViewGroup @@ -20,6 +21,7 @@ import de.jrpie.android.launcher.widgets.GRID_SIZE import de.jrpie.android.launcher.widgets.WidgetPanel import de.jrpie.android.launcher.widgets.WidgetPosition import kotlin.math.max +import kotlin.math.min import kotlin.math.roundToInt @@ -130,6 +132,7 @@ class ManageWidgetsActivity : UIObject, Activity() { private fun selectWidget() { + val appWidgetHost = (application as Application).appWidgetHost startActivityForResult( Intent(this, SelectWidgetActivity::class.java).also { it.putExtra( @@ -144,17 +147,13 @@ class ManageWidgetsActivity : UIObject, Activity() { private fun createWidget(data: Intent) { Log.i("Launcher", "creating widget") val appWidgetManager = (application as Application).appWidgetManager - val appWidgetHost = (application as Application).appWidgetHost val appWidgetId = data.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: return + val provider = appWidgetManager.getAppWidgetInfo(appWidgetId) + val display = windowManager.defaultDisplay val widgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId) - if (widgetInfo == null) { - Log.w("Launcher", "can't access widget") - appWidgetHost.deleteAppWidgetId(appWidgetId) - return - } val position = WidgetPosition.findFreeSpace( WidgetPanel.byId(panelId), @@ -162,7 +161,7 @@ class ManageWidgetsActivity : UIObject, Activity() { max(3, (GRID_SIZE * (widgetInfo.minHeight) / display.height.toFloat()).roundToInt()) ) - val widget = AppWidget(appWidgetId, position, panelId, widgetInfo) + val widget = AppWidget(appWidgetId, position, panelId, provider) LauncherPreferences.widgets().widgets( (LauncherPreferences.widgets().widgets() ?: HashSet()).also { it.add(widget) 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 f49f7da..d1c84d0 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 @@ -31,19 +31,19 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe WidgetContainerView(widgetPanelId, context, attrs) { constructor(context: Context, attrs: AttributeSet?) : this(WidgetPanel.HOME.id, context, attrs) - val touchSlop: Int - val touchSlopSquare: Int - val longPressTimeout: Long + val TOUCH_SLOP: Int + val TOUCH_SLOP_SQUARE: Int + val LONG_PRESS_TIMEOUT: Long private var overlayViewById = HashMap() init { val configuration = ViewConfiguration.get(context) - touchSlop = configuration.scaledTouchSlop - touchSlopSquare = touchSlop * touchSlop + TOUCH_SLOP = configuration.scaledTouchSlop + TOUCH_SLOP_SQUARE = TOUCH_SLOP * TOUCH_SLOP - longPressTimeout = ViewConfiguration.getLongPressTimeout().toLong() + LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout().toLong() } @@ -127,14 +127,14 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) endInteraction() } - }, longPressTimeout) + }, LONG_PRESS_TIMEOUT) } if (event.actionMasked == MotionEvent.ACTION_MOVE || event.actionMasked == MotionEvent.ACTION_UP ) { val distanceX = event.x - (currentGestureStart?.x ?: return true) val distanceY = event.y - (currentGestureStart?.y ?: return true) - if (distanceX * distanceX + distanceY * distanceY > touchSlopSquare) { + if (distanceX * distanceX + distanceY * distanceY > TOUCH_SLOP_SQUARE) { longPressHandler.removeCallbacksAndMessages(null) } val view = selectedWidgetOverlayView ?: return true @@ -160,8 +160,9 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe } if (event.actionMasked == MotionEvent.ACTION_UP) { + longPressHandler.removeCallbacksAndMessages(null) val id = selectedWidgetOverlayView?.widgetId ?: return true - val widget = Widget.byId(id) ?: return true + val widget = Widget.byId(context, id) ?: return true widget.position = newPosition endInteraction() updateWidget(widget) @@ -175,16 +176,8 @@ class WidgetManagerView(widgetPanelId: Int, context: Context, attrs: AttributeSe } private fun endInteraction() { - synchronized(this) { - longPressHandler.removeCallbacksAndMessages(null) - startWidgetPosition = null - selectedWidgetOverlayView?.mode = null - } - } - - override fun onDetachedFromWindow() { - endInteraction() - super.onDetachedFromWindow() + startWidgetPosition = null + selectedWidgetOverlayView?.mode = null } override fun updateWidgets(activity: Activity, widgets: Collection?) { diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/WidgetOverlayView.kt b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/WidgetOverlayView.kt index 0363069..61006b8 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/WidgetOverlayView.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/widgets/manage/WidgetOverlayView.kt @@ -54,18 +54,26 @@ class WidgetOverlayView : ViewGroup { var widgetId: Int = -1 set(newId) { field = newId - preview = Widget.byId(widgetId)?.getPreview(context) + preview = Widget.byId(context, widgetId)?.getPreview(context) } - constructor(context: Context) : super(context) + constructor(context: Context) : super(context) { + init(null, 0) + } - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { + init(attrs, 0) + } constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super( context, attrs, defStyle - ) + ) { + init(attrs, defStyle) + } + + private fun init(attrs: AttributeSet?, defStyle: Int) { } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) @@ -93,13 +101,13 @@ class WidgetOverlayView : ViewGroup { } fun showPopupMenu() { - val widget = Widget.byId(widgetId)?: return + val widget = Widget.byId(context, widgetId)?: return val menu = PopupMenu(context, popupAnchor) menu.menu.let { it.add( context.getString(R.string.widget_menu_remove) ).setOnMenuItemClickListener { _ -> - Widget.byId(widgetId)?.delete(context) + Widget.byId(context, widgetId)?.delete(context) return@setOnMenuItemClickListener true } it.add( @@ -118,7 +126,7 @@ class WidgetOverlayView : ViewGroup { } fun getHandles(): List { - return listOf( + return listOf( Handle(WidgetManagerView.EditMode.TOP, Rect(HANDLE_EDGE_SIZE, 0, width - HANDLE_EDGE_SIZE, HANDLE_SIZE)), Handle(WidgetManagerView.EditMode.BOTTOM, diff --git a/app/src/main/java/de/jrpie/android/launcher/widgets/ClockWidget.kt b/app/src/main/java/de/jrpie/android/launcher/widgets/ClockWidget.kt index 29d9308..f864ee8 100644 --- a/app/src/main/java/de/jrpie/android/launcher/widgets/ClockWidget.kt +++ b/app/src/main/java/de/jrpie/android/launcher/widgets/ClockWidget.kt @@ -18,8 +18,8 @@ class ClockWidget( override var allowInteraction: Boolean = true ) : Widget() { - override fun createView(activity: Activity): View { - return ClockView(activity, null, id, panelId) + override fun createView(activity: Activity): View? { + return ClockView(activity, null, id) } override fun findView(views: Sequence): ClockView? { 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 73f5d81..fd96f14 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 @@ -38,6 +38,10 @@ sealed class Widget { ) } + fun getPanel(): WidgetPanel? { + return WidgetPanel.byId(panelId) + } + override fun hashCode(): Int { return id } @@ -53,9 +57,9 @@ sealed class Widget { fun deserialize(serialized: String): Widget { return Json.decodeFromString(serialized) } - fun byId(id: Int): Widget? { + fun byId(context: Context, id: Int): Widget? { // TODO: do some caching - return LauncherPreferences.widgets().widgets().firstOrNull { + return LauncherPreferences.widgets().widgets().firstOrNull() { it.id == id } } diff --git a/app/src/main/java/de/jrpie/android/launcher/widgets/Widgets.kt b/app/src/main/java/de/jrpie/android/launcher/widgets/Widgets.kt index 864e5d3..593f3b3 100644 --- a/app/src/main/java/de/jrpie/android/launcher/widgets/Widgets.kt +++ b/app/src/main/java/de/jrpie/android/launcher/widgets/Widgets.kt @@ -15,6 +15,11 @@ import de.jrpie.android.launcher.Application import de.jrpie.android.launcher.preferences.LauncherPreferences import kotlin.math.min +fun deleteAllWidgets(context: Context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.getAppWidgetHost().appWidgetIds.forEach { AppWidget(it).delete(context) } + } +} /** * Tries to bind [providerInfo] to the id [id]. @@ -55,8 +60,8 @@ fun getAppWidgetProviders( context: Context ): List { (context.getSystemService(Service.USER_SERVICE) as UserManager).userProfiles } list.addAll( - profiles.map { profile -> - appWidgetManager.getInstalledProvidersForProfile(profile) + profiles.map { + appWidgetManager.getInstalledProvidersForProfile(it) .map { LauncherAppWidgetProvider(it) } }.flatten() ) diff --git a/app/src/main/res/layout/activity_manage_widget_panels.xml b/app/src/main/res/layout/activity_manage_widget_panels.xml index f84f42f..60413a3 100644 --- a/app/src/main/res/layout/activity_manage_widget_panels.xml +++ b/app/src/main/res/layout/activity_manage_widget_panels.xml @@ -40,7 +40,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="8dp" - android:contentDescription="@string/content_description_close" android:gravity="center" android:includeFontPadding="true" android:paddingLeft="16sp" @@ -65,7 +64,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" - android:contentDescription="@string/content_description_add_widget_panel" android:src="@drawable/baseline_add_24" app:layout_anchor="@+id/manage_widget_panels_recycler" app:layout_anchorGravity="end|bottom" diff --git a/app/src/main/res/layout/activity_manage_widgets.xml b/app/src/main/res/layout/activity_manage_widgets.xml index 4e63ec9..66404ee 100644 --- a/app/src/main/res/layout/activity_manage_widgets.xml +++ b/app/src/main/res/layout/activity_manage_widgets.xml @@ -20,7 +20,6 @@ android:layout_height="wrap_content" android:layout_margin="16dp" android:clickable="true" - android:contentDescription="@string/content_description_add_widget" android:focusable="true" android:src="@drawable/baseline_add_24" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/activity_pin_shortcut.xml b/app/src/main/res/layout/activity_pin_shortcut.xml index da724e7..2519374 100644 --- a/app/src/main/res/layout/activity_pin_shortcut.xml +++ b/app/src/main/res/layout/activity_pin_shortcut.xml @@ -44,7 +44,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="8dp" - android:contentDescription="@string/content_description_close" android:gravity="center" android:includeFontPadding="true" android:paddingLeft="16sp" diff --git a/app/src/main/res/layout/activity_select_widget.xml b/app/src/main/res/layout/activity_select_widget.xml index 14296bd..82db94d 100644 --- a/app/src/main/res/layout/activity_select_widget.xml +++ b/app/src/main/res/layout/activity_select_widget.xml @@ -45,7 +45,6 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" - android:contentDescription="@string/content_description_close" android:gravity="center" android:includeFontPadding="true" android:paddingLeft="16sp" diff --git a/app/src/main/res/layout/list.xml b/app/src/main/res/layout/list.xml index 958638a..8a3b5d9 100644 --- a/app/src/main/res/layout/list.xml +++ b/app/src/main/res/layout/list.xml @@ -62,7 +62,6 @@ android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" - android:contentDescription="@string/content_description_close" android:gravity="center" android:includeFontPadding="true" android:paddingLeft="16sp" @@ -73,7 +72,6 @@ app:layout_constraintTop_toTopOf="parent" /> + custom:tabTextColor="?attr/android:textColor" /> @@ -113,7 +110,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/list_appbar" app:layout_constraintVertical_bias="0.0" - custom:layout_behavior="@string/appbar_scrolling_view_behavior" - tools:ignore="SpeakableTextPresentCheck" /> + custom:layout_behavior="@string/appbar_scrolling_view_behavior" /> \ No newline at end of file diff --git a/app/src/main/res/layout/list_other_row.xml b/app/src/main/res/layout/list_other_row.xml index 78d92ae..530cc9e 100644 --- a/app/src/main/res/layout/list_other_row.xml +++ b/app/src/main/res/layout/list_other_row.xml @@ -11,7 +11,6 @@ android:id="@+id/list_other_row_icon" android:layout_width="35sp" android:layout_height="35sp" - android:contentDescription="@null" android:gravity="center" android:textSize="30sp" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/list_widgets_row.xml b/app/src/main/res/layout/list_widgets_row.xml index b828169..878aaad 100644 --- a/app/src/main/res/layout/list_widgets_row.xml +++ b/app/src/main/res/layout/list_widgets_row.xml @@ -6,96 +6,55 @@ android:id="@+id/list_apps_row_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginHorizontal="30sp"> + android:layout_margin="15sp"> - + tools:src="@mipmap/ic_launcher_round" + tools:ignore="ContentDescription" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings.xml b/app/src/main/res/layout/settings.xml index 8ce96c4..987e293 100644 --- a/app/src/main/res/layout/settings.xml +++ b/app/src/main/res/layout/settings.xml @@ -20,22 +20,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - + + + app:tabTextColor="?attr/android:textColor" /> diff --git a/app/src/main/res/layout/settings_actions_row.xml b/app/src/main/res/layout/settings_actions_row.xml index eb3339c..a60a5a4 100644 --- a/app/src/main/res/layout/settings_actions_row.xml +++ b/app/src/main/res/layout/settings_actions_row.xml @@ -68,7 +68,6 @@ android:id="@+id/settings_actions_row_remove" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:contentDescription="@string/content_description_settings_actions_row_button_remove" android:padding="8sp" android:src="@drawable/baseline_close_24" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/layout/settings_meta.xml b/app/src/main/res/layout/settings_meta.xml index 1adee37..6f21baa 100644 --- a/app/src/main/res/layout/settings_meta.xml +++ b/app/src/main/res/layout/settings_meta.xml @@ -41,13 +41,6 @@ android:text="@string/settings_meta_view_code" android:textAllCaps="false" /> -