diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt index 1c61cfe..0dadc51 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/activities/MainActivity.kt @@ -23,6 +23,7 @@ import android.os.Handler import android.provider.Telephony import android.telecom.TelecomManager import android.view.* +import android.view.accessibility.AccessibilityNodeInfo import android.view.animation.DecelerateInterpolator import android.widget.PopupMenu import androidx.core.graphics.drawable.toBitmap @@ -139,6 +140,14 @@ class MainActivity : SimpleActivity(), FlingListener { } } } + + home_screen_grid.itemClickListener = { + performItemClick(it) + } + + home_screen_grid.itemLongClickListener = { + performItemLongClick(home_screen_grid.getClickableRect(it).left.toFloat(), it) + } } private fun findFirstEmptyCell(): Rect? { @@ -241,6 +250,7 @@ class MainActivity : SimpleActivity(), FlingListener { refetchLaunchers() } } + REQUEST_ALLOW_BINDING_WIDGET -> mActionOnCanBindWidget?.invoke(resultCode == Activity.RESULT_OK) REQUEST_CONFIGURE_WIDGET -> mActionOnWidgetConfiguredWidget?.invoke(resultCode == Activity.RESULT_OK) REQUEST_CREATE_SHORTCUT -> { @@ -403,6 +413,7 @@ class MainActivity : SimpleActivity(), FlingListener { window.navigationBarColor = resources.getColor(R.color.semitransparent_navigation) home_screen_grid.fragmentExpanded() home_screen_grid.hideResizeLines() + fragment.performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null) } private fun hideFragment(fragment: View) { @@ -433,12 +444,7 @@ class MainActivity : SimpleActivity(), FlingListener { mIgnoreMoveEvents = true val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt()) if (clickedGridItem != null) { - if (clickedGridItem.type == ITEM_TYPE_ICON || clickedGridItem.type == ITEM_TYPE_SHORTCUT) { - main_holder.performHapticFeedback() - } - - val anchorY = home_screen_grid.sideMargins.top + (clickedGridItem.top * home_screen_grid.cellHeight.toFloat()) - showHomeIconMenu(x, anchorY, clickedGridItem, false) + performItemLongClick(x, clickedGridItem) return } @@ -450,24 +456,37 @@ class MainActivity : SimpleActivity(), FlingListener { home_screen_grid.hideResizeLines() val clickedGridItem = home_screen_grid.isClickingGridItem(x.toInt(), y.toInt()) if (clickedGridItem != null) { - if (clickedGridItem.type == ITEM_TYPE_ICON) { - launchApp(clickedGridItem.packageName, clickedGridItem.activityName) - } else if (clickedGridItem.type == ITEM_TYPE_SHORTCUT) { - if (clickedGridItem.intent.isNotEmpty()) { - launchShortcutIntent(clickedGridItem) - } else { - // launch pinned shortcuts - val id = clickedGridItem.shortcutId - val packageName = clickedGridItem.packageName - val userHandle = android.os.Process.myUserHandle() - val shortcutBounds = home_screen_grid.getClickableRect(clickedGridItem) - val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps - launcherApps.startShortcut(packageName, id, shortcutBounds, null, userHandle) - } + performItemClick(clickedGridItem) + } + } + + private fun performItemClick(clickedGridItem: HomeScreenGridItem) { + if (clickedGridItem.type == ITEM_TYPE_ICON) { + launchApp(clickedGridItem.packageName, clickedGridItem.activityName) + } else if (clickedGridItem.type == ITEM_TYPE_SHORTCUT) { + if (clickedGridItem.intent.isNotEmpty()) { + launchShortcutIntent(clickedGridItem) + } else { + // launch pinned shortcuts + val id = clickedGridItem.shortcutId + val packageName = clickedGridItem.packageName + val userHandle = android.os.Process.myUserHandle() + val shortcutBounds = home_screen_grid.getClickableRect(clickedGridItem) + val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps + launcherApps.startShortcut(packageName, id, shortcutBounds, null, userHandle) } } } + private fun performItemLongClick(x: Float, clickedGridItem: HomeScreenGridItem) { + if (clickedGridItem.type == ITEM_TYPE_ICON || clickedGridItem.type == ITEM_TYPE_SHORTCUT) { + main_holder.performHapticFeedback() + } + + val anchorY = home_screen_grid.sideMargins.top + (clickedGridItem.top * home_screen_grid.cellHeight.toFloat()) + showHomeIconMenu(x, anchorY, clickedGridItem, false) + } + fun showHomeIconMenu(x: Float, y: Float, gridItem: HomeScreenGridItem, isOnAllAppsFragment: Boolean) { home_screen_grid.hideResizeLines() mLongPressedIcon = gridItem diff --git a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt index b75324c..d87a4fd 100644 --- a/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt +++ b/app/src/main/kotlin/com/simplemobiletools/launcher/views/HomeScreenGrid.kt @@ -15,8 +15,12 @@ import android.text.TextUtils import android.util.AttributeSet import android.util.Size import android.util.SizeF +import android.view.View import android.widget.RelativeLayout import androidx.core.graphics.drawable.toDrawable +import androidx.core.view.ViewCompat +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat +import androidx.customview.widget.ExploreByTouchHelper import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.helpers.isSPlus @@ -58,7 +62,12 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel val appWidgetHost = MyAppWidgetHost(context, WIDGET_HOST_ID) private val appWidgetManager = AppWidgetManager.getInstance(context) + var itemClickListener: ((HomeScreenGridItem) -> Unit)? = null + var itemLongClickListener: ((HomeScreenGridItem) -> Unit)? = null + init { + ViewCompat.setAccessibilityDelegate(this, HomeScreenGridTouchHelper(this)) + textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG).apply { color = Color.WHITE textSize = context.resources.getDimension(R.dimen.smaller_text_size) @@ -706,4 +715,60 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel return null } + + private inner class HomeScreenGridTouchHelper(host: View) : ExploreByTouchHelper(host) { + override fun getVirtualViewAt(x: Float, y: Float): Int { + val item = isClickingGridItem(x.toInt(), y.toInt()) + + return if (item != null) { + item.id?.toInt() ?: INVALID_ID + } else { + INVALID_ID + } + } + + override fun getVisibleVirtualViews(virtualViewIds: MutableList?) { + val sorted = gridItems.sortedBy { it.top * 100 + it.left } + sorted.forEachIndexed { index, homeScreenGridItem -> + virtualViewIds?.add(index, homeScreenGridItem.id?.toInt() ?: index) + } + } + + override fun onPopulateNodeForVirtualView(virtualViewId: Int, node: AccessibilityNodeInfoCompat) { + val item = gridItems.firstOrNull { it.id?.toInt() == virtualViewId } ?: throw IllegalArgumentException("Unknown id") + + node.text = item.title + + val viewLocation = IntArray(2) + getLocationOnScreen(viewLocation) + + val viewBounds = getClickableRect(item) + val onScreenBounds = Rect(viewBounds) + onScreenBounds.offset(viewLocation[0], viewLocation[1]) + node.setBoundsInScreen(onScreenBounds) + node.setBoundsInParent(viewBounds) + + node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK) + node.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK) + node.setParent(this@HomeScreenGrid) + } + + override fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, arguments: Bundle?): Boolean { + val item = gridItems.firstOrNull { it.id?.toInt() == virtualViewId } ?: throw IllegalArgumentException("Unknown id") + when (action) { + AccessibilityNodeInfoCompat.ACTION_CLICK -> itemClickListener?.apply { + invoke(item) + return true + } + + AccessibilityNodeInfoCompat.ACTION_LONG_CLICK -> itemLongClickListener?.apply { + invoke(item) + return true + } + } + + return false + } + + } }