Compare commits

...
11 Commits
9 changed files with 50 additions and 10 deletions

No files matched your search

+2 -1
View File
@@ -1,6 +1,7 @@
# Moonlight Android # Moonlight Android
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/232a8tadrrn8jv0k/branch/master?svg=true)](https://ci.appveyor.com/project/cgutman/moonlight-android/branch/master) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/232a8tadrrn8jv0k/branch/master?svg=true)](https://ci.appveyor.com/project/cgutman/moonlight-android/branch/master)
[![Translation Status](https://hosted.weblate.org/widgets/moonlight/-/moonlight-android/svg-badge.svg)](https://hosted.weblate.org/projects/moonlight/moonlight-android/)
[Moonlight for Android](https://moonlight-stream.org) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield. [Moonlight for Android](https://moonlight-stream.org) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield.
@@ -9,7 +10,7 @@ whether in your own home or over the internet.
Moonlight also has a [PC client](https://github.com/moonlight-stream/moonlight-qt) and [iOS/tvOS client](https://github.com/moonlight-stream/moonlight-ios). Moonlight also has a [PC client](https://github.com/moonlight-stream/moonlight-qt) and [iOS/tvOS client](https://github.com/moonlight-stream/moonlight-ios).
Check out [the Moonlight wiki](https://github.com/moonlight-stream/moonlight-docs/wiki) for more detailed project information, setup guide, or troubleshooting steps. You can follow development on our [Discord server](https://moonlight-stream.org/discord) and help translate Moonlight into your language on [Weblate](https://hosted.weblate.org/projects/moonlight/moonlight-android/).
## Downloads ## Downloads
* [Google Play Store](https://play.google.com/store/apps/details?id=com.limelight) * [Google Play Store](https://play.google.com/store/apps/details?id=com.limelight)
+4 -2
View File
@@ -1,14 +1,16 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
ndkVersion "22.0.7026061"
compileSdkVersion 30 compileSdkVersion 30
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 30 targetSdkVersion 30
versionName "9.8.3" versionName "9.8.4"
versionCode = 254 versionCode = 255
} }
flavorDimensions "root" flavorDimensions "root"
+22 -6
View File
@@ -1000,6 +1000,26 @@ public class Game extends Activity implements SurfaceHolder.Callback,
return false; return false;
} }
// We cannot simply use modifierFlags for all key event processing, because
// some IMEs will not generate real key events for pressing Shift. Instead
// they will simply send key events with isShiftPressed() returning true,
// and we will need to send the modifier flag ourselves.
private byte getModifierState(KeyEvent event) {
// Start with the global modifier state to ensure we cover the case
// detailed in https://github.com/moonlight-stream/moonlight-android/issues/840
byte modifier = getModifierState();
if (event.isShiftPressed()) {
modifier |= KeyboardPacket.MODIFIER_SHIFT;
}
if (event.isCtrlPressed()) {
modifier |= KeyboardPacket.MODIFIER_CTRL;
}
if (event.isAltPressed()) {
modifier |= KeyboardPacket.MODIFIER_ALT;
}
return modifier;
}
private byte getModifierState() { private byte getModifierState() {
return (byte) modifierFlags; return (byte) modifierFlags;
} }
@@ -1065,10 +1085,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
return false; return false;
} }
byte modifiers = getModifierState(); byte modifiers = getModifierState(event);
if (KeyboardTranslator.needsShift(event.getKeyCode())) { if (KeyboardTranslator.needsShift(event.getKeyCode())) {
modifiers |= KeyboardPacket.MODIFIER_SHIFT; modifiers |= KeyboardPacket.MODIFIER_SHIFT;
conn.sendKeyboardInput((short) 0x8010, KeyboardPacket.KEY_DOWN, modifiers);
} }
conn.sendKeyboardInput(translated, KeyboardPacket.KEY_DOWN, modifiers); conn.sendKeyboardInput(translated, KeyboardPacket.KEY_DOWN, modifiers);
} }
@@ -1129,14 +1148,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
return false; return false;
} }
byte modifiers = getModifierState(); byte modifiers = getModifierState(event);
if (KeyboardTranslator.needsShift(event.getKeyCode())) { if (KeyboardTranslator.needsShift(event.getKeyCode())) {
modifiers |= KeyboardPacket.MODIFIER_SHIFT; modifiers |= KeyboardPacket.MODIFIER_SHIFT;
} }
conn.sendKeyboardInput(translated, KeyboardPacket.KEY_UP, modifiers); conn.sendKeyboardInput(translated, KeyboardPacket.KEY_UP, modifiers);
if (KeyboardTranslator.needsShift(event.getKeyCode())) {
conn.sendKeyboardInput((short) 0x8010, KeyboardPacket.KEY_UP, getModifierState());
}
} }
return true; return true;
@@ -26,6 +26,7 @@ public class Xbox360Controller extends AbstractXboxController {
0x0f0d, // Hori 0x0f0d, // Hori
0x1038, // SteelSeries 0x1038, // SteelSeries
0x11c9, // Nacon 0x11c9, // Nacon
0x1209, // Ardwiino
0x12ab, // Unknown 0x12ab, // Unknown
0x1430, // RedOctane 0x1430, // RedOctane
0x146b, // BigBen 0x146b, // BigBen
@@ -34,7 +35,9 @@ public class Xbox360Controller extends AbstractXboxController {
0x162e, // Joytech 0x162e, // Joytech
0x1689, // Razer Onza 0x1689, // Razer Onza
0x1bad, // Harmonix 0x1bad, // Harmonix
0x20d6, // PowerA
0x24c6, // PowerA 0x24c6, // PowerA
0x2f24, // GameSir
}; };
public static boolean canClaimDevice(UsbDevice device) { public static boolean canClaimDevice(UsbDevice device) {
@@ -21,7 +21,9 @@ public class XboxOneController extends AbstractXboxController {
0x0e6f, // Unknown 0x0e6f, // Unknown
0x0f0d, // Hori 0x0f0d, // Hori
0x1532, // Razer Wildcat 0x1532, // Razer Wildcat
0x20d6, // PowerA
0x24c6, // PowerA 0x24c6, // PowerA
0x2e24, // Hyperkin
}; };
private static final byte[] FW2015_INIT = {0x05, 0x20, 0x00, 0x01, 0x00}; private static final byte[] FW2015_INIT = {0x05, 0x20, 0x00, 0x01, 0x00};
@@ -147,6 +147,9 @@ public class RelativeTouchContext implements TouchContext {
} }
private synchronized void startDragTimer() { private synchronized void startDragTimer() {
// Cancel any existing drag timers
cancelDragTimer();
dragTimer = new Timer(true); dragTimer = new Timer(true);
dragTimer.schedule(new TimerTask() { dragTimer.schedule(new TimerTask() {
@Override @Override
@@ -177,6 +177,15 @@ public class DigitalButton extends VirtualControllerElement {
listener.onClick(); listener.onClick();
} }
if (timerLongClick != null) {
timerLongClick.cancel();
timerLongClick = null;
}
if (longClickTimerTask != null) {
longClickTimerTask.cancel();
longClickTimerTask = null;
}
timerLongClick = new Timer(); timerLongClick = new Timer();
longClickTimerTask = new TimerLongClickTimerTask(); longClickTimerTask = new TimerLongClickTimerTask();
timerLongClick.schedule(longClickTimerTask, timerLongClickTimeout); timerLongClick.schedule(longClickTimerTask, timerLongClickTimeout);
@@ -200,9 +209,11 @@ public class DigitalButton extends VirtualControllerElement {
// We may be called for a release without a prior click // We may be called for a release without a prior click
if (timerLongClick != null) { if (timerLongClick != null) {
timerLongClick.cancel(); timerLongClick.cancel();
timerLongClick = null;
} }
if (longClickTimerTask != null) { if (longClickTimerTask != null) {
longClickTimerTask.cancel(); longClickTimerTask.cancel();
longClickTimerTask = null;
} }
} }
+1 -1
View File
@@ -5,7 +5,7 @@ buildscript {
google() google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.2' classpath 'com.android.tools.build:gradle:4.1.3'
} }
} }
@@ -0,0 +1,2 @@
- Fixed typing upper-case letters with the software keyboard
- Improved device compatibility with the built-in USB Xbox gamepad driver