[fix] show shortcut controls only for Windows hosts

This commit is contained in:
dijunkun
2026-10-27 04:01:39 +08:00
parent a9e3178042
commit 1687816bde
9 changed files with 59 additions and 42 deletions
@@ -338,7 +338,7 @@ public final class MainActivity extends Activity implements NativeSession.Listen
public void mute(){muted=!muted;if(session!=null)session.control(2,muted?0:1);controls.setMuted(muted);}
public void mouse(){boolean relative=!preferences.getBoolean("relativeMouse",true);preferences.edit().putBoolean("relativeMouse",relative).apply();video.setRelative(relative);controls.setRelative(relative);}
public void videoSettings(int field,int value){RemoteVideoSettings.Values old=MainActivity.this.videoSettings.selection;updateVideoSettings(new RemoteVideoSettings.Values(field==0?value:old.quality,field==1?value:old.frameRate,field==2?value:old.preference));}
});controls.setRelative(preferences.getBoolean("relativeMouse",true));controls.setMuted(muted);controls.videoSettings(videoSettings);root.addView(controls,new LinearLayout.LayoutParams(-1,-1));getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
});controls.setHostPlatform(hostPlatform);controls.setRelative(preferences.getBoolean("relativeMouse",true));controls.setMuted(muted);controls.videoSettings(videoSettings);root.addView(controls,new LinearLayout.LayoutParams(-1,-1));getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
controls.attachMouseBar(canvas,new VirtualMouseBar(ui,video.mouseInput));
privacyChanged();
video.remoteFocusChanged=()->{if(controls!=null)controls.resetKeyboardContext();};
@@ -496,8 +496,8 @@ public final class MainActivity extends Activity implements NativeSession.Listen
if(!ready)return;int count=Math.min(displays.length(),8);if(count==0){toast("等待远端屏幕信息");return;}String[] labels=new String[count];for(int i=0;i<count;i++){JSONObject display=displays.optJSONObject(i);labels[i]=(i+1)+" · "+(display==null?"显示器":display.optString("name","显示器"));}new AlertDialog.Builder(this).setTitle("显示器").setItems(labels,(d,w)->{if(session!=null){if(w!=selectedDisplay&&video!=null)video.resetViewport();selectedDisplay=w;session.control(4,w);if(controls!=null)controls.resetVideoStatistics();}}).show();
}
private void secureAttention(){
if(!ready||session==null)return;
if(!remoteServiceAvailable){controlFeedback(hostPlatform.equals("windows")?"请在远端启用 CrossDesk 系统服务后重试":"Ctrl+Alt+Del 需要远端 Windows 系统服务支持");return;}
if(!ready||session==null||!hostPlatform.equals("windows"))return;
if(!remoteServiceAvailable){controlFeedback("请在远端启用 CrossDesk 系统服务后重试");return;}
session.secureAttention();
}
private void chooseFile(){
@@ -650,6 +650,7 @@ public final class MainActivity extends Activity implements NativeSession.Listen
JSONObject info=message.optJSONObject("host_info");
if(info!=null){
hostPlatform=info.optString("platform","");JSONArray list=info.optJSONArray("displays");if(list!=null)displays=list;history.metadata(serverKey(),connectedRemote,info.optString("host_name",connectedRemote),hostPlatform);
if(controls!=null)controls.setHostPlatform(hostPlatform);
boolean wasSupported=videoSettings.supported;videoSettings.setSupported(info.optBoolean("supports_video_settings",false));
if(!videoSettings.supported)cancelVideoSettingsTimeout();
if(controls!=null)controls.videoSettings(videoSettings);
@@ -739,7 +740,7 @@ public final class MainActivity extends Activity implements NativeSession.Listen
videoSettings=retained.videoSettings;ready=true;retained.attach(this);
if(rebuild)sessionScreen(retained.autoLandscape);
if(retained.width>0&&retained.height>0)videoSize(retained.width,retained.height);
if(controls!=null){controls.setMuted(muted);controls.videoSettings(videoSettings);controls.fileStatus(retained.fileStatus,receivedFile!=null);}
if(controls!=null){controls.setHostPlatform(hostPlatform);controls.setMuted(muted);controls.videoSettings(videoSettings);controls.fileStatus(retained.fileStatus,receivedFile!=null);}
retained.setBackground(false);signaling(signalState,localIdentity);
return true;
}
@@ -51,7 +51,7 @@ final class SessionControls extends FrameLayout {
private LinearLayout[] trafficRows;
private TextView[] networkDetails;
private View encryptionLock,encryptionOpen;
private boolean muted,relative=true,orbPositioned;
private boolean muted,relative=true,orbPositioned,secureAttentionVisible;
SessionControls(Context context,MobileUi ui,Actions actions){
super(context);this.ui=ui;this.actions=actions;
keyboard=new RemoteKeyboard(context,ui,actions,()->{requestLayout();positionMouse();});
@@ -66,6 +66,12 @@ final class SessionControls extends FrameLayout {
drag(orb,orb,()->{if(menu==null)openMenu("controls");else closeMenu();});
}
void setRelative(boolean value){relative=value;if(menu!=null&&menuPage.equals("controls"))openMenu("controls");}
void setHostPlatform(String platform){
boolean visible="windows".equals(platform);
if(secureAttentionVisible==visible)return;
secureAttentionVisible=visible;
if(menu!=null&&menuPage.equals("controls"))openMenu("controls");
}
void attachMouseBar(FrameLayout host, VirtualMouseBar bar) {
mouseHost=host;mouseBar=bar;
// A direct, tightly bounded sibling of the video is essential: otherwise
@@ -130,8 +136,13 @@ final class SessionControls extends FrameLayout {
String[] icons={"keyboard","mouse","mouse","display","sliders","audio","folder","chart","lock","clipboard","lock"};
Runnable[] clicks={()->{closeMenu();toggleKeyboard();},this::toggleMouse,actions::mouse,actions::display,()->openMenu("video"),actions::mute,actions::sendFile,()->openMenu("network"),actions::secureAttention,actions::clipboard,actions::togglePrivacy};
menuColumns=controlColumns();
int controlCount=privacy.desktopAvailable?labels.length:labels.length-1;
for(int row=0;row<(controlCount+menuColumns-1)/menuColumns;row++){LinearLayout line=ui.row();for(int col=0;col<menuColumns;col++){int index=row*menuColumns+col;if(index>=controlCount){View spacer=new View(getContext());LinearLayout.LayoutParams p=new LinearLayout.LayoutParams(0,ui.dp(52),1);if(col>0)p.leftMargin=ui.dp(7);line.addView(spacer,p);continue;}LinearLayout control=ui.column();control.setGravity(Gravity.CENTER);control.setBackground(ui.background(0xFFF0F0F2,10));control.addView(ui.icon(icons[index],INK),ui.size(19,19));ui.gap(control,4);TextView caption=ui.text(labels[index],10,false);caption.setSingleLine();caption.setGravity(Gravity.CENTER);control.addView(caption);control.setContentDescription(labels[index]);control.setClickable(true);control.setFocusable(true);control.setOnClickListener(v->clicks[index].run());
java.util.List<Integer> visibleControls=new java.util.ArrayList<>();
for(int index=0;index<labels.length;index++){
if(index==8&&!secureAttentionVisible||index==10&&!privacy.desktopAvailable)continue;
visibleControls.add(index);
}
int controlCount=visibleControls.size();
for(int row=0;row<(controlCount+menuColumns-1)/menuColumns;row++){LinearLayout line=ui.row();for(int col=0;col<menuColumns;col++){int position=row*menuColumns+col;if(position>=controlCount){View spacer=new View(getContext());LinearLayout.LayoutParams p=new LinearLayout.LayoutParams(0,ui.dp(52),1);if(col>0)p.leftMargin=ui.dp(7);line.addView(spacer,p);continue;}int index=visibleControls.get(position);LinearLayout control=ui.column();control.setGravity(Gravity.CENTER);control.setBackground(ui.background(0xFFF0F0F2,10));control.addView(ui.icon(icons[index],INK),ui.size(19,19));ui.gap(control,4);TextView caption=ui.text(labels[index],10,false);caption.setSingleLine();caption.setGravity(Gravity.CENTER);control.addView(caption);control.setContentDescription(labels[index]);control.setClickable(true);control.setFocusable(true);control.setOnClickListener(v->clicks[index].run());
if(index==10){privacyButton=control;privacyCaption=caption;}
LinearLayout.LayoutParams p=new LinearLayout.LayoutParams(0,ui.dp(52),1);if(col>0)p.leftMargin=ui.dp(7);line.addView(control,p);
}body.addView(line);if((row+1)*menuColumns<controlCount)ui.gap(body,7);}