fix: unable to exit input when an external keyboard is connected & cannot input continuously
This commit is contained in:
parent
ea39dcb123
commit
16967ab508
|
@ -96,12 +96,20 @@ public class FCLInput implements View.OnCapturedPointerListener, View.OnGenericM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private View focusableView;
|
||||||
|
|
||||||
|
public View getFocusableView() {
|
||||||
|
return focusableView;
|
||||||
|
}
|
||||||
|
|
||||||
public void initExternalController(View view) {
|
public void initExternalController(View view) {
|
||||||
view.setFocusable(true);
|
view.setFocusable(true);
|
||||||
view.setOnCapturedPointerListener(this);
|
view.setOnCapturedPointerListener(this);
|
||||||
view.setOnGenericMotionListener(this);
|
view.setOnGenericMotionListener(this);
|
||||||
view.requestFocus();
|
view.requestFocus();
|
||||||
view.requestPointerCapture();
|
view.requestPointerCapture();
|
||||||
|
|
||||||
|
this.focusableView = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleExternalMouseEvent(MotionEvent event) {
|
private boolean handleExternalMouseEvent(MotionEvent event) {
|
||||||
|
@ -153,13 +161,14 @@ public class FCLInput implements View.OnCapturedPointerListener, View.OnGenericM
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onGenericMotion(View v, MotionEvent event) {
|
public boolean onGenericMotion(View v, MotionEvent event) {
|
||||||
if (menu instanceof GameMenu && !((GameMenu) menu).getTouchCharInput().isEnabled()) {
|
if (!((GameMenu) menu).getTouchCharInput().isEnabled()) {
|
||||||
((GameMenu) menu).getBaseLayout().requestFocus();
|
focusableView.requestFocus();
|
||||||
((GameMenu) menu).getBaseLayout().requestPointerCapture();
|
focusableView.requestPointerCapture();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean handleKeyEvent(KeyEvent event) {
|
public boolean handleKeyEvent(KeyEvent event) {
|
||||||
int fclKeycode = AndroidKeycodeMap.convertKeycode(event.getKeyCode());
|
int fclKeycode = AndroidKeycodeMap.convertKeycode(event.getKeyCode());
|
||||||
if (event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN)
|
if (event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN)
|
||||||
|
@ -168,28 +177,30 @@ public class FCLInput implements View.OnCapturedPointerListener, View.OnGenericM
|
||||||
return false;
|
return false;
|
||||||
if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP)
|
if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP)
|
||||||
return false;
|
return false;
|
||||||
if (event.getRepeatCount() != 0)
|
|
||||||
return true;
|
|
||||||
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
|
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
|
||||||
return true;
|
return true;
|
||||||
|
if (event.getAction() == KeyEvent.ACTION_UP && (event.getFlags() & KeyEvent.FLAG_CANCELED) != 0)
|
||||||
|
return true;
|
||||||
if (event.getDevice() != null && ((event.getSource() & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE || (event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE)) {
|
if (event.getDevice() != null && ((event.getSource() & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE || (event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE)) {
|
||||||
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
|
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
|
||||||
sendKeyEvent(MOUSE_RIGHT, event.getAction() == KeyEvent.ACTION_DOWN);
|
sendKeyEvent(MOUSE_RIGHT, event.getAction() == KeyEvent.ACTION_DOWN);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event.getKeyCode() == KeyEvent.KEYCODE_ALT_RIGHT && menu.getCursorMode() == FCLBridge.CursorEnabled) {
|
|
||||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
|
||||||
((GameMenu) menu).getTouchCharInput().switchKeyboardState();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ((event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) == KeyEvent.FLAG_SOFT_KEYBOARD) {
|
if ((event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) == KeyEvent.FLAG_SOFT_KEYBOARD) {
|
||||||
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
|
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
|
||||||
return true;
|
return true;
|
||||||
((GameMenu) menu).getTouchCharInput().dispatchKeyEvent(event);
|
((GameMenu) menu).getTouchCharInput().dispatchKeyEvent(event);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
|
||||||
|
if (!((GameMenu) menu).getTouchCharInput().isLock() && event.getAction() == KeyEvent.ACTION_UP && !((GameMenu) menu).getTouchCharInput().isEnabled()) {
|
||||||
|
((GameMenu) menu).getTouchCharInput().switchKeyboardState();
|
||||||
|
} else if (((GameMenu) menu).getTouchCharInput().isLock()) {
|
||||||
|
((GameMenu) menu).getTouchCharInput().setLock(false);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (fclKeycode == FCLKeycodes.KEY_UNKNOWN)
|
if (fclKeycode == FCLKeycodes.KEY_UNKNOWN)
|
||||||
return (event.getFlags() & KeyEvent.FLAG_FALLBACK) == KeyEvent.FLAG_FALLBACK;
|
return (event.getFlags() & KeyEvent.FLAG_FALLBACK) == KeyEvent.FLAG_FALLBACK;
|
||||||
sendKeyEvent(fclKeycode, event.getAction() == KeyEvent.ACTION_DOWN);
|
sendKeyEvent(fclKeycode, event.getAction() == KeyEvent.ACTION_DOWN);
|
||||||
|
|
|
@ -448,7 +448,7 @@ public class GameMenu implements MenuCallback, View.OnClickListener {
|
||||||
touchPad.post(() -> gameItemBar.setup(this));
|
touchPad.post(() -> gameItemBar.setup(this));
|
||||||
}
|
}
|
||||||
touchPad.init(this);
|
touchPad.init(this);
|
||||||
touchCharInput.setCharacterSender(new LwjglCharSender(this));
|
touchCharInput.setCharacterSender(this, new LwjglCharSender(this));
|
||||||
ViewGroup.LayoutParams layoutParams = cursorView.getLayoutParams();
|
ViewGroup.LayoutParams layoutParams = cursorView.getLayoutParams();
|
||||||
layoutParams.width = ConvertUtils.dip2px(activity, menuSetting.mouseSizeProperty().get());
|
layoutParams.width = ConvertUtils.dip2px(activity, menuSetting.mouseSizeProperty().get());
|
||||||
layoutParams.height = ConvertUtils.dip2px(activity, menuSetting.mouseSizeProperty().get());
|
layoutParams.height = ConvertUtils.dip2px(activity, menuSetting.mouseSizeProperty().get());
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class JarExecutorMenu implements MenuCallback, View.OnClickListener, View
|
||||||
touchCharInput = findViewById(R.id.input_scanner);
|
touchCharInput = findViewById(R.id.input_scanner);
|
||||||
touchPad.setOnTouchListener(this);
|
touchPad.setOnTouchListener(this);
|
||||||
logWindow.setVisibilityValue(true);
|
logWindow.setVisibilityValue(true);
|
||||||
touchCharInput.setCharacterSender(new AwtCharSender(awtInput));
|
touchCharInput.setCharacterSender(null, new AwtCharSender(awtInput));
|
||||||
|
|
||||||
forceExit = findViewById(R.id.force_exit);
|
forceExit = findViewById(R.id.force_exit);
|
||||||
showLog = findViewById(R.id.show_log);
|
showLog = findViewById(R.id.show_log);
|
||||||
|
|
|
@ -4,16 +4,14 @@ import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.Objects;
|
import com.tungsten.fcl.control.GameMenu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From PojavLauncher
|
* From PojavLauncher
|
||||||
|
@ -21,6 +19,8 @@ import java.util.Objects;
|
||||||
*/
|
*/
|
||||||
public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText {
|
public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText {
|
||||||
|
|
||||||
|
public static final String TEXT_FILLER = " ";
|
||||||
|
|
||||||
public TouchCharInput(@NonNull Context context) {
|
public TouchCharInput(@NonNull Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,19 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GameMenu menu;
|
||||||
|
private boolean lock = false;
|
||||||
private boolean isDoingInternalChanges = false;
|
private boolean isDoingInternalChanges = false;
|
||||||
private CharacterSenderStrategy characterSender;
|
private CharacterSenderStrategy characterSender;
|
||||||
|
|
||||||
|
public void setLock(boolean lock) {
|
||||||
|
this.lock = lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLock() {
|
||||||
|
return lock;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We take the new chars, and send them to the game.
|
* We take the new chars, and send them to the game.
|
||||||
* If less chars are present, remove some.
|
* If less chars are present, remove some.
|
||||||
|
@ -58,8 +68,8 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reset the keyboard state
|
// Reset the keyboard state
|
||||||
if(text.length() < 1)
|
if (text.length() < 1)
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,26 +97,28 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle on and off the soft keyboard, depending of the state
|
* Toggle on and off the soft keyboard, depending of the state
|
||||||
*
|
|
||||||
* @return if the keyboard is set to be shown.
|
|
||||||
*/
|
*/
|
||||||
public boolean switchKeyboardState() {
|
public void switchKeyboardState() {
|
||||||
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(INPUT_METHOD_SERVICE);
|
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(INPUT_METHOD_SERVICE);
|
||||||
// If an hard keyboard is present, never trigger the soft one
|
if (hasFocus()) {
|
||||||
if (hasFocus()
|
|
||||||
|| (getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY
|
|
||||||
&& getResources().getConfiguration().hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES)) {
|
|
||||||
inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
|
inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
|
||||||
clear();
|
clear();
|
||||||
disable();
|
disable();
|
||||||
return false;
|
if (menu != null && menu.getInput().getFocusableView() != null) {
|
||||||
} else {
|
menu.getInput().getFocusableView().requestFocus();
|
||||||
|
menu.getInput().getFocusableView().requestPointerCapture();
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
if (menu != null && menu.getInput().getFocusableView() != null) {
|
||||||
|
menu.getInput().getFocusableView().releasePointerCapture();
|
||||||
|
menu.getInput().getFocusableView().clearFocus();
|
||||||
|
}
|
||||||
enable();
|
enable();
|
||||||
inputMethodManager.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT);
|
inputMethodManager.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the EditText from any leftover inputs
|
* Clear the EditText from any leftover inputs
|
||||||
* It does not affect the in-game input
|
* It does not affect the in-game input
|
||||||
|
@ -114,10 +126,8 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
public void clear() {
|
public void clear() {
|
||||||
isDoingInternalChanges = true;
|
isDoingInternalChanges = true;
|
||||||
//Braille space, doesn't trigger keyboard auto-complete
|
setText(TEXT_FILLER);
|
||||||
//replacing directly the text without though setText avoids notifying changes
|
setSelection(TEXT_FILLER.length());
|
||||||
setText(" ");
|
|
||||||
setSelection(Objects.requireNonNull(getText()).length());
|
|
||||||
isDoingInternalChanges = false;
|
isDoingInternalChanges = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,8 +145,6 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
|
||||||
setVisibility(GONE);
|
setVisibility(GONE);
|
||||||
clearFocus();
|
clearFocus();
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(INPUT_METHOD_SERVICE);
|
|
||||||
inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send the enter key. */
|
/** Send the enter key. */
|
||||||
|
@ -146,16 +154,24 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Just sets the char sender that should be used. */
|
/** Just sets the char sender that should be used. */
|
||||||
public void setCharacterSender(CharacterSenderStrategy characterSender) {
|
public void setCharacterSender(GameMenu gameMenu, CharacterSenderStrategy characterSender) {
|
||||||
|
this.menu = gameMenu;
|
||||||
this.characterSender = characterSender;
|
this.characterSender = characterSender;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This function deals with anything that has to be executed when the constructor is called */
|
/** This function deals with anything that has to be executed when the constructor is called */
|
||||||
private void setup() {
|
private void setup() {
|
||||||
setOnEditorActionListener((textView, i, keyEvent) -> {
|
setOnEditorActionListener((textView, i, keyEvent) -> {
|
||||||
|
setLock(true);
|
||||||
|
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(getWindowToken(), 0);
|
||||||
sendEnter();
|
sendEnter();
|
||||||
clear();
|
clear();
|
||||||
disable();
|
disable();
|
||||||
|
if (menu != null && menu.getInput().getFocusableView() != null) {
|
||||||
|
menu.getInput().getFocusableView().requestFocus();
|
||||||
|
menu.getInput().getFocusableView().requestPointerCapture();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
clear();
|
clear();
|
||||||
|
|
Loading…
Reference in New Issue