Clear popups on KEYCODE_ESCAPE as well as KEYCODE_BACK
On desktop devices, users expect that the Escape key will clear various popup windows in the same way as the Back button will on mobile devices. This adds support for Escape to places the Back button currently clears ListPopupWindow, AutoCompleteTextView, PopupWindow, and ScrollView. Bug: 174164194 Test: Open popups of each type on a device with a physical keyboard and press escape. Change-Id: I32e65ce4317db7de043c8a050d87126b0f38acce
This commit is contained in:
@@ -5938,36 +5938,37 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
boolean handled = false;
|
||||
boolean okToSend = true;
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
case KeyEvent.KEYCODE_ENTER:
|
||||
case KeyEvent.KEYCODE_NUMPAD_ENTER:
|
||||
okToSend = false;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
if (mFiltered && mPopup != null && mPopup.isShowing()) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN
|
||||
&& event.getRepeatCount() == 0) {
|
||||
KeyEvent.DispatcherState state = getKeyDispatcherState();
|
||||
if (state != null) {
|
||||
state.startTracking(event, this);
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
case KeyEvent.KEYCODE_ENTER:
|
||||
case KeyEvent.KEYCODE_NUMPAD_ENTER:
|
||||
okToSend = false;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
case KeyEvent.KEYCODE_ESCAPE:
|
||||
if (mFiltered && mPopup != null && mPopup.isShowing()) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN
|
||||
&& event.getRepeatCount() == 0) {
|
||||
KeyEvent.DispatcherState state = getKeyDispatcherState();
|
||||
if (state != null) {
|
||||
state.startTracking(event, this);
|
||||
}
|
||||
handled = true;
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP
|
||||
&& event.isTracking() && !event.isCanceled()) {
|
||||
handled = true;
|
||||
mTextFilter.setText("");
|
||||
}
|
||||
handled = true;
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP
|
||||
&& event.isTracking() && !event.isCanceled()) {
|
||||
handled = true;
|
||||
mTextFilter.setText("");
|
||||
}
|
||||
}
|
||||
okToSend = false;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_SPACE:
|
||||
// Only send spaces once we are filtered
|
||||
okToSend = mFiltered;
|
||||
break;
|
||||
okToSend = false;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_SPACE:
|
||||
// Only send spaces once we are filtered
|
||||
okToSend = mFiltered;
|
||||
break;
|
||||
}
|
||||
|
||||
if (okToSend) {
|
||||
|
||||
@@ -788,8 +788,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
|
||||
|
||||
@Override
|
||||
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && isPopupShowing()
|
||||
&& !mPopup.isDropDownAlwaysVisible()) {
|
||||
if ((keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE)
|
||||
&& isPopupShowing() && !mPopup.isDropDownAlwaysVisible()) {
|
||||
// special case for the back key, we do not even try to send it
|
||||
// to the drop down list but instead, consume it immediately
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
|
||||
|
||||
@@ -1071,7 +1071,8 @@ public class ListPopupWindow implements ShowableListMenu {
|
||||
* @see #setModal(boolean)
|
||||
*/
|
||||
public boolean onKeyPreIme(int keyCode, @NonNull KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && isShowing()) {
|
||||
if ((keyCode == KeyEvent.KEYCODE_BACK
|
||||
|| keyCode == KeyEvent.KEYCODE_ESCAPE) && isShowing()) {
|
||||
// special case for the back key, we do not even try to send it
|
||||
// to the drop down list but instead, consume it immediately
|
||||
final View anchorView = mDropDownAnchorView;
|
||||
|
||||
@@ -2521,7 +2521,8 @@ public class PopupWindow {
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
|
||||
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
|
||||
|| event.getKeyCode() == KeyEvent.KEYCODE_ESCAPE) {
|
||||
if (getKeyDispatcherState() == null) {
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
@@ -509,7 +509,8 @@ public class ScrollView extends FrameLayout {
|
||||
mTempRect.setEmpty();
|
||||
|
||||
if (!canScroll()) {
|
||||
if (isFocused() && event.getKeyCode() != KeyEvent.KEYCODE_BACK) {
|
||||
if (isFocused() && event.getKeyCode() != KeyEvent.KEYCODE_BACK
|
||||
&& event.getKeyCode() != KeyEvent.KEYCODE_ESCAPE) {
|
||||
View currentFocused = findFocus();
|
||||
if (currentFocused == this) currentFocused = null;
|
||||
View nextFocused = FocusFinder.getInstance().findNextFocus(this,
|
||||
|
||||
Reference in New Issue
Block a user