Skip to content

Commit b6097d3

Browse files
author
Karim Mreisi
committed
wip: add game back menu
Add back menu to send sepcial keys. E.g. close fullscreen while using yuzu.
1 parent b8904bb commit b6097d3

File tree

2 files changed

+116
-1
lines changed

2 files changed

+116
-1
lines changed

app/src/main/java/com/limelight/Game.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@
3939
import android.annotation.SuppressLint;
4040
import android.annotation.TargetApi;
4141
import android.app.Activity;
42+
import android.app.AlertDialog;
4243
import android.app.PictureInPictureParams;
4344
import android.app.Service;
4445
import android.content.ComponentName;
4546
import android.content.Context;
47+
import android.content.DialogInterface;
4648
import android.content.Intent;
4749
import android.content.ServiceConnection;
4850
import android.content.SharedPreferences;
@@ -63,7 +65,10 @@
6365
import android.view.Display;
6466
import android.view.InputDevice;
6567
import android.view.KeyEvent;
68+
import android.view.LayoutInflater;
69+
import android.view.Menu;
6670
import android.view.MotionEvent;
71+
import android.view.SubMenu;
6772
import android.view.Surface;
6873
import android.view.SurfaceHolder;
6974
import android.view.View;
@@ -72,12 +77,15 @@
7277
import android.view.View.OnTouchListener;
7378
import android.view.Window;
7479
import android.view.WindowManager;
80+
import android.widget.ArrayAdapter;
7581
import android.widget.FrameLayout;
7682
import android.view.inputmethod.InputMethodManager;
83+
import android.widget.PopupMenu;
7784
import android.widget.TextView;
7885
import android.widget.Toast;
7986

8087
import java.io.ByteArrayInputStream;
88+
import java.io.PipedOutputStream;
8189
import java.lang.reflect.InvocationTargetException;
8290
import java.lang.reflect.Method;
8391
import java.security.cert.CertificateException;
@@ -2264,7 +2272,16 @@ public void onUsbPermissionPromptCompleted() {
22642272
public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
22652273
switch (keyEvent.getAction()) {
22662274
case KeyEvent.ACTION_DOWN:
2267-
return handleKeyDown(keyEvent);
2275+
boolean handled = handleKeyDown(keyEvent);
2276+
if (handled)
2277+
return true;
2278+
2279+
// Intercept back key event before android handles it
2280+
// Always handle the request, the user has to select "Disconnect" within the back menu to actually disconnect
2281+
if (keyCode == keyEvent.KEYCODE_BACK) {
2282+
new GameBackMenu(this, conn);
2283+
return true;
2284+
}
22682285
case KeyEvent.ACTION_UP:
22692286
return handleKeyUp(keyEvent);
22702287
default:
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.limelight;
2+
3+
import android.app.AlertDialog;
4+
import android.widget.ArrayAdapter;
5+
6+
import com.limelight.nvstream.NvConnection;
7+
import com.limelight.nvstream.input.KeyboardPacket;
8+
9+
public class GameBackMenu {
10+
11+
private final Game game;
12+
private final NvConnection conn;
13+
14+
public GameBackMenu(Game game, NvConnection conn) {
15+
this.game = game;
16+
this.conn = conn;
17+
18+
showMenuDialog("Back Menu", new MenuDialogOption[]{
19+
new MenuDialogOption("Send special key(s)", () -> showSpecialKeysMenu()),
20+
new MenuDialogOption("Disconnect", () -> game.onBackPressed()),
21+
new MenuDialogOption("Cancel", null),
22+
});
23+
}
24+
25+
private void sendKeySequence(byte modifier, short[] keys) {
26+
27+
for (short key : keys)
28+
conn.sendKeyboardInput(key, KeyboardPacket.KEY_DOWN, (byte) (modifier | KeyboardPacket.KEY_DOWN));
29+
30+
for (int pos = keys.length - 1; pos >= 0; pos--)
31+
conn.sendKeyboardInput(keys[pos], KeyboardPacket.KEY_UP, (byte) (modifier | KeyboardPacket.KEY_UP));
32+
}
33+
34+
private void showMenuDialog(String title, MenuDialogOption[] options) {
35+
AlertDialog.Builder builder = new AlertDialog.Builder(game);
36+
builder.setTitle(title);
37+
38+
final ArrayAdapter<String> actions =
39+
new ArrayAdapter<String>(game, android.R.layout.simple_list_item_1);
40+
41+
for (MenuDialogOption option : options) {
42+
actions.add(option.label);
43+
}
44+
45+
builder.setAdapter(actions, (dialog, which) -> {
46+
String label = actions.getItem(which);
47+
for (MenuDialogOption option : options) {
48+
if (!label.equals(option.label)) {
49+
continue;
50+
}
51+
52+
if (option.runnable != null) {
53+
option.runnable.run();
54+
}
55+
break;
56+
}
57+
});
58+
59+
builder.show();
60+
}
61+
62+
private void showSpecialKeysMenu() {
63+
showMenuDialog(ACTIONS.SEND_SPECIAL_KEYS, new MenuDialogOption[]{
64+
new MenuDialogOption("Send ESC", () -> sendKeySequence(
65+
(byte) 0, new short[]{0x18})),
66+
new MenuDialogOption("Send F11", () -> sendKeySequence(
67+
(byte) 0, new short[]{0x7a})),
68+
new MenuDialogOption("Send WIN (Open Start Menu)", () -> sendKeySequence(
69+
(byte) 0, new short[]{0x5B})),
70+
new MenuDialogOption("Send WIN + D (Switch to Desktop)", () -> sendKeySequence(
71+
(byte) 0, new short[]{0x5B, 0x44})),
72+
new MenuDialogOption("Send WIN + G (Open Xbox Game Bar)", () -> sendKeySequence(
73+
(byte) 0, new short[]{0x5B, 0x47})),
74+
/*
75+
TODO: Currently not working
76+
new MenuDialogOption("Send SHIFT + TAB (Open Steam Overlay)", () -> sendKeySequence(
77+
(byte) 0, new short[]{0xA0, 0x09})),
78+
*/
79+
new MenuDialogOption("Cancel", null),
80+
});
81+
}
82+
83+
private interface ACTIONS {
84+
String CONTINUE = "Continue";
85+
String SEND_SPECIAL_KEYS = "Send special key(s)";
86+
String DISCONNECT = "Disconnect";
87+
}
88+
89+
private class MenuDialogOption {
90+
private final String label;
91+
private final Runnable runnable;
92+
93+
MenuDialogOption(String label, Runnable runnable) {
94+
this.label = label;
95+
this.runnable = runnable;
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)