🔨 修改终端配置.

This commit is contained in:
lijiahangmax
2025-06-29 00:48:18 +08:00
parent fa389f611e
commit b55efe035d
30 changed files with 542 additions and 487 deletions

View File

@@ -51,9 +51,9 @@ public class TerminalPreferenceModel implements GenericsDataModel {
private String newConnectionType; private String newConnectionType;
/** /**
* 终端主题 * ssh 主题
*/ */
private JSONObject theme; private JSONObject sshTheme;
/** /**
* ssh 显示设置 * ssh 显示设置
@@ -61,40 +61,40 @@ public class TerminalPreferenceModel implements GenericsDataModel {
private JSONObject sshDisplaySetting; private JSONObject sshDisplaySetting;
/** /**
* rdp 图形化设置 * ssh 右键菜单设置
*/ */
private JSONObject rdpGraphSetting; private List<String> sshRightMenuSetting;
/** /**
* ssh 操作栏设置 * ssh 操作栏设置
*/ */
private JSONObject sshActionBarSetting; private JSONObject sshActionBarSetting;
/**
* ssh 交互设置
*/
private JSONObject sshInteractSetting;
/**
* ssh 插件设置
*/
private JSONObject sshPluginsSetting;
/**
* rdp 会话设置
*/
private JSONObject rdpSessionSetting;
/**
* rdp 图形化设置
*/
private JSONObject rdpGraphSetting;
/** /**
* rdp 操作栏设置 * rdp 操作栏设置
*/ */
private JSONObject rdpActionBarSetting; private JSONObject rdpActionBarSetting;
/**
* 右键菜单设置
*/
private List<String> rightMenuSetting;
/**
* 交互设置
*/
private JSONObject interactSetting;
/**
* 插件设置
*/
private JSONObject pluginsSetting;
/**
* 会话设置
*/
private JSONObject sessionSetting;
/** /**
* 快捷键设置 * 快捷键设置
*/ */
@@ -148,94 +148,6 @@ public class TerminalPreferenceModel implements GenericsDataModel {
} }
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class RdpGraphSettingModel implements IJsonObject {
/**
* 显示大小
*/
private String displaySize;
/**
* 显示宽度
*/
private Integer displayWidth;
/**
* 显示高度
*/
private Integer displayHeight;
/**
* 启用音频输入
*/
private Boolean enableAudioInput;
/**
* 启用音频输出
*/
private Boolean enableAudioOutput;
/**
* 颜色深度
*/
private Integer colorDepth;
/**
* 无损压缩
*/
private Boolean forceLossless;
/**
* 启用壁纸
*/
private Boolean enableWallpaper;
/**
* 启用主题
*/
private Boolean enableTheming;
/**
* 启动平滑字体
*/
private Boolean enableFontSmoothing;
/**
* 启用窗口拖动
*/
private Boolean enableFullWindowDrag;
/**
* 启用桌面合成
*/
private Boolean enableDesktopComposition;
/**
* 启用菜单动画
*/
private Boolean enableMenuAnimations;
/**
* 禁用位图缓存
*/
private Boolean disableBitmapCaching;
/**
* 禁用离屏缓存
*/
private Boolean disableOffscreenCaching;
/**
* 禁用字形缓存
*/
private Boolean disableGlyphCaching;
}
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@@ -323,55 +235,7 @@ public class TerminalPreferenceModel implements GenericsDataModel {
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class RdpActionBarSettingModel implements IJsonObject { public static class SshInteractSettingModel implements IJsonObject {
/**
* 位置
*/
private String position;
/**
* 显示设置
*/
private Boolean display;
/**
* 组合键
*/
private Boolean combinationKey;
/**
* 剪切板
*/
private Boolean clipboard;
/**
* 上传
*/
private Boolean upload;
/**
* 保存为 rdp 文件
*/
private Boolean saveRdp;
/**
* 断开连接
*/
private Boolean disconnect;
/**
* 关闭
*/
private Boolean close;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class InteractSettingModel implements IJsonObject {
/** /**
* 快速滚动 * 快速滚动
@@ -423,13 +287,23 @@ public class TerminalPreferenceModel implements GenericsDataModel {
*/ */
private String wordSeparator; private String wordSeparator;
/**
* 伪终端类型
*/
private String terminalEmulationType;
/**
* 保存在缓冲区的行数
*/
private Integer scrollBackLine;
} }
@Data @Data
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class PluginsSettingModel implements IJsonObject { public static class SshPluginsSettingModel implements IJsonObject {
/** /**
* 超链接插件 * 超链接插件
@@ -457,17 +331,153 @@ public class TerminalPreferenceModel implements GenericsDataModel {
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class SessionSettingModel implements IJsonObject { public static class RdpGraphSettingModel implements IJsonObject {
/** /**
* 伪终端类型 * 显示大小
*/ */
private String terminalEmulationType; private String displaySize;
/** /**
* 保存在缓冲区的行数 * 显示宽度
*/ */
private Integer scrollBackLine; private Integer displayWidth;
/**
* 显示高度
*/
private Integer displayHeight;
/**
* 颜色深度
*/
private Integer colorDepth;
/**
* 无损压缩
*/
private Boolean forceLossless;
/**
* 启用壁纸
*/
private Boolean enableWallpaper;
/**
* 启用主题
*/
private Boolean enableTheming;
/**
* 启动平滑字体
*/
private Boolean enableFontSmoothing;
/**
* 启用窗口拖动
*/
private Boolean enableFullWindowDrag;
/**
* 启用桌面合成
*/
private Boolean enableDesktopComposition;
/**
* 启用菜单动画
*/
private Boolean enableMenuAnimations;
/**
* 禁用位图缓存
*/
private Boolean disableBitmapCaching;
/**
* 禁用离屏缓存
*/
private Boolean disableOffscreenCaching;
/**
* 禁用字形缓存
*/
private Boolean disableGlyphCaching;
/**
* 禁用图形加速
*/
private Boolean disableGfx;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class RdpActionBarSettingModel implements IJsonObject {
/**
* 位置
*/
private String position;
/**
* 显示设置
*/
private Boolean display;
/**
* 组合键
*/
private Boolean combinationKey;
/**
* 剪切板
*/
private Boolean clipboard;
/**
* 上传
*/
private Boolean upload;
/**
* 保存为 rdp 文件
*/
private Boolean saveRdp;
/**
* 断开连接
*/
private Boolean disconnect;
/**
* 关闭
*/
private Boolean close;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class RdpSessionSettingModel implements IJsonObject {
/**
* 启用音频输入
*/
private Boolean enableAudioInput;
/**
* 启用音频输出
*/
private Boolean enableAudioOutput;
/**
* 驱动挂载模式
*/
private String driveMountMode;
} }

View File

@@ -51,23 +51,23 @@ public class TerminalPreferenceStrategy extends AbstractGenericsDataStrategy<Ter
// 连接类型 // 连接类型
.newConnectionType("group") .newConnectionType("group")
// ssh 主题 // ssh 主题
.theme(new JSONObject()) .sshTheme(new JSONObject())
// ssh 显示设置 // ssh 显示设置
.sshDisplaySetting(JSONObject.parseObject(this.getDefaultSshDisplaySetting())) .sshDisplaySetting(JSONObject.parseObject(this.getDefaultSshDisplaySetting()))
// rdp 图形化设置
.rdpGraphSetting(JSONObject.parseObject(this.getDefaultRdpGraphSetting()))
// ssh 操作栏设置 // ssh 操作栏设置
.sshActionBarSetting(JSONObject.parseObject(this.getDefaultSshActionBarSetting())) .sshActionBarSetting(JSONObject.parseObject(this.getDefaultSshActionBarSetting()))
// ssh 右键菜单设置
.sshRightMenuSetting(this.getDefaultSshRightMenuSetting())
// ssh 交互设置
.sshInteractSetting(JSONObject.parseObject(this.getDefaultSshInteractSetting()))
// ssh 插件设置
.sshPluginsSetting(JSONObject.parseObject(this.getDefaultSshPluginsSetting()))
// rdp 图形化设置
.rdpGraphSetting(JSONObject.parseObject(this.getDefaultRdpGraphSetting()))
// rdp 操作栏设置 // rdp 操作栏设置
.rdpActionBarSetting(JSONObject.parseObject(this.getDefaultRdpActionBarSetting())) .rdpActionBarSetting(JSONObject.parseObject(this.getDefaultRdpActionBarSetting()))
// ssh 右键菜单设置 // rdp 会话设置
.rightMenuSetting(this.getDefaultRightMenuSetting()) .rdpSessionSetting(JSONObject.parseObject(this.getDefaultRdpSessionSetting()))
// 交互设置
.interactSetting(JSONObject.parseObject(this.getDefaultInteractSetting()))
// 插件设置
.pluginsSetting(JSONObject.parseObject(this.getDefaultPluginsSetting()))
// 会话设置
.sessionSetting(JSONObject.parseObject(this.getDefaultSessionSetting()))
// 快捷键设置 // 快捷键设置
.shortcutSetting(JSONObject.parseObject(this.getDefaultShortcutSetting())) .shortcutSetting(JSONObject.parseObject(this.getDefaultShortcutSetting()))
.build(); .build();
@@ -94,30 +94,12 @@ public class TerminalPreferenceStrategy extends AbstractGenericsDataStrategy<Ter
} }
/** /**
* 获取 rdp 图形化默认设置 * 获取 ssh 右键菜单默认设置
* *
* @return setting * @return setting
*/ */
private String getDefaultRdpGraphSetting() { private List<String> getDefaultSshRightMenuSetting() {
return TerminalPreferenceModel.RdpGraphSettingModel.builder() return Lists.of("selectAll", "copy", "paste", "search", "clear");
.displaySize("fit")
.displayWidth(0)
.displayHeight(0)
.colorDepth(24)
.enableAudioInput(false)
.enableAudioOutput(true)
.forceLossless(true)
.enableWallpaper(true)
.enableTheming(true)
.enableFontSmoothing(true)
.enableFullWindowDrag(true)
.enableDesktopComposition(true)
.enableMenuAnimations(false)
.disableBitmapCaching(false)
.disableOffscreenCaching(false)
.disableGlyphCaching(false)
.build()
.toJsonString();
} }
/** /**
@@ -147,6 +129,70 @@ public class TerminalPreferenceStrategy extends AbstractGenericsDataStrategy<Ter
.toJsonString(); .toJsonString();
} }
/**
* 获取 ssh 默认交互设置
*
* @return setting
*/
private String getDefaultSshInteractSetting() {
return TerminalPreferenceModel.SshInteractSettingModel.builder()
.fastScrollModifier(true)
.altClickMovesCursor(true)
.rightClickSelectsWord(false)
.selectionChangeCopy(false)
.copyAutoTrim(false)
.pasteAutoTrim(false)
.rightClickPaste(false)
.enableRightClickMenu(true)
.enableBell(false)
.wordSeparator("/\\()\"'` -.,:;<>~!@#$%^&*|+=[]{}~?│")
.terminalEmulationType(TerminalType.XTERM.getType())
.scrollBackLine(1000)
.build()
.toJsonString();
}
/**
* 获取默认插件设置
*
* @return setting
*/
private String getDefaultSshPluginsSetting() {
return TerminalPreferenceModel.SshPluginsSettingModel.builder()
.enableWeblinkPlugin(true)
.enableWebglPlugin(true)
.enableUnicodePlugin(true)
.enableImagePlugin(false)
.build()
.toJsonString();
}
/**
* 获取 rdp 图形化默认设置
*
* @return setting
*/
private String getDefaultRdpGraphSetting() {
return TerminalPreferenceModel.RdpGraphSettingModel.builder()
.displaySize("fit")
.displayWidth(0)
.displayHeight(0)
.colorDepth(24)
.forceLossless(true)
.enableWallpaper(true)
.enableTheming(true)
.enableFontSmoothing(true)
.enableFullWindowDrag(true)
.enableDesktopComposition(true)
.enableMenuAnimations(false)
.disableBitmapCaching(false)
.disableOffscreenCaching(false)
.disableGlyphCaching(false)
.disableGfx(false)
.build()
.toJsonString();
}
/** /**
* 获取 rdp 操作栏默认设置 * 获取 rdp 操作栏默认设置
* *
@@ -167,59 +213,15 @@ public class TerminalPreferenceStrategy extends AbstractGenericsDataStrategy<Ter
} }
/** /**
* 获取 ssh 右键菜单默认设置 * 获取 rdp 默认会话设置
* *
* @return setting * @return setting
*/ */
private List<String> getDefaultRightMenuSetting() { private String getDefaultRdpSessionSetting() {
return Lists.of("selectAll", "copy", "paste", "search", "clear"); return TerminalPreferenceModel.RdpSessionSettingModel.builder()
} .enableAudioInput(false)
.enableAudioOutput(true)
/** .driveMountMode("ASSET")
* 获取默认交互设置
*
* @return setting
*/
private String getDefaultInteractSetting() {
return TerminalPreferenceModel.InteractSettingModel.builder()
.fastScrollModifier(true)
.altClickMovesCursor(true)
.rightClickSelectsWord(false)
.selectionChangeCopy(false)
.copyAutoTrim(false)
.pasteAutoTrim(false)
.rightClickPaste(false)
.enableRightClickMenu(true)
.enableBell(false)
.wordSeparator("/\\()\"'` -.,:;<>~!@#$%^&*|+=[]{}~?│")
.build()
.toJsonString();
}
/**
* 获取默认插件设置
*
* @return setting
*/
private String getDefaultPluginsSetting() {
return TerminalPreferenceModel.PluginsSettingModel.builder()
.enableWeblinkPlugin(true)
.enableWebglPlugin(true)
.enableUnicodePlugin(true)
.enableImagePlugin(false)
.build()
.toJsonString();
}
/**
* 获取默认会话设置
*
* @return setting
*/
private String getDefaultSessionSetting() {
return TerminalPreferenceModel.SessionSettingModel.builder()
.terminalEmulationType(TerminalType.XTERM.getType())
.scrollBackLine(1000)
.build() .build()
.toJsonString(); .toJsonString();
} }

View File

@@ -306,10 +306,15 @@ public interface GuacdConst {
String DISABLE_OFFSCREEN_CACHING = "disable-offscreen-caching"; String DISABLE_OFFSCREEN_CACHING = "disable-offscreen-caching";
/** /**
* 禁用字形缓存 boolean 默认禁用 * 禁用字形缓存 boolean
*/ */
String DISABLE_GLYPH_CACHING = "disable-glyph-caching"; String DISABLE_GLYPH_CACHING = "disable-glyph-caching";
/**
* 禁用图形加速 boolean
*/
String DISABLE_GFX = "disable-gfx";
/** /**
* 远程应用名称 * 远程应用名称
*/ */

View File

@@ -126,6 +126,16 @@ public class TerminalChannelExtra {
*/ */
private Boolean disableGlyphCaching; private Boolean disableGlyphCaching;
/**
* 禁用图形加速
*/
private Boolean disableGfx;
/**
* 驱动挂载模式
*/
private String driveMountMode;
// -------------------- vnc -------------------- // -------------------- vnc --------------------
} }

View File

@@ -101,9 +101,10 @@ public class RdpSession extends AbstractGuacdSession<TerminalSessionRdpConfig> i
tunnel.setParameter(GuacdConst.ENABLE_FULL_WINDOW_DRAG, extra.getEnableFullWindowDrag()); tunnel.setParameter(GuacdConst.ENABLE_FULL_WINDOW_DRAG, extra.getEnableFullWindowDrag());
tunnel.setParameter(GuacdConst.ENABLE_DESKTOP_COMPOSITION, extra.getEnableDesktopComposition()); tunnel.setParameter(GuacdConst.ENABLE_DESKTOP_COMPOSITION, extra.getEnableDesktopComposition());
tunnel.setParameter(GuacdConst.ENABLE_MENU_ANIMATIONS, extra.getEnableMenuAnimations()); tunnel.setParameter(GuacdConst.ENABLE_MENU_ANIMATIONS, extra.getEnableMenuAnimations());
tunnel.setParameter(GuacdConst.DISABLE_BITMAP_CACHING, extra.getDisableBitmapCaching());
tunnel.setParameter(GuacdConst.DISABLE_OFFSCREEN_CACHING, extra.getDisableOffscreenCaching()); tunnel.setParameter(GuacdConst.DISABLE_OFFSCREEN_CACHING, extra.getDisableOffscreenCaching());
tunnel.setParameter(GuacdConst.DISABLE_GLYPH_CACHING, extra.getDisableGlyphCaching()); tunnel.setParameter(GuacdConst.DISABLE_GLYPH_CACHING, extra.getDisableGlyphCaching());
tunnel.setParameter(GuacdConst.DISABLE_BITMAP_CACHING, extra.getDisableBitmapCaching()); tunnel.setParameter(GuacdConst.DISABLE_GFX, extra.getDisableGfx());
// 音频 // 音频
tunnel.setAudioMimeTypes(GuacdConst.AUDIO_MIMETYPES); tunnel.setAudioMimeTypes(GuacdConst.AUDIO_MIMETYPES);
tunnel.setParameter(GuacdConst.ENABLE_AUDIO_INPUT, extra.getEnableAudioInput()); tunnel.setParameter(GuacdConst.ENABLE_AUDIO_INPUT, extra.getEnableAudioInput());
@@ -153,8 +154,9 @@ public class RdpSession extends AbstractGuacdSession<TerminalSessionRdpConfig> i
extra.setEnableDesktopComposition(false); extra.setEnableDesktopComposition(false);
extra.setEnableMenuAnimations(false); extra.setEnableMenuAnimations(false);
extra.setDisableBitmapCaching(false); extra.setDisableBitmapCaching(false);
extra.setDisableOffscreenCaching(false);
extra.setDisableGlyphCaching(false); extra.setDisableGlyphCaching(false);
extra.setDisableBitmapCaching(false); extra.setDisableGfx(false);
extra.setEnableAudioInput(false); extra.setEnableAudioInput(false);
extra.setEnableAudioOutput(false); extra.setEnableAudioOutput(false);
} }

View File

@@ -1,13 +1,13 @@
import type { import type {
TerminalInteractSetting,
TerminalPluginsSetting,
TerminalPreference, TerminalPreference,
TerminalRdpActionBarSetting, TerminalRdpActionBarSetting,
TerminalRdpGraphSetting, TerminalRdpGraphSetting,
TerminalSessionSetting, TerminalRdpSessionSetting,
TerminalShortcutSetting, TerminalShortcutSetting,
TerminalSshActionBarSetting, TerminalSshActionBarSetting,
TerminalSshDisplaySetting, TerminalSshDisplaySetting,
TerminalSshInteractSetting,
TerminalSshPluginsSetting,
TerminalState TerminalState
} from './types'; } from './types';
import type { import type {
@@ -40,24 +40,24 @@ import TerminalTransferManager from '@/views/terminal/service/transfer/terminal-
export const TerminalPreferenceItem = { export const TerminalPreferenceItem = {
// 新建连接类型 // 新建连接类型
NEW_CONNECTION_TYPE: 'newConnectionType', NEW_CONNECTION_TYPE: 'newConnectionType',
// 终端主题 // ssh 主题
THEME: 'theme', SSH_THEME: 'sshTheme',
// ssh 显示设置 // ssh 显示设置
SSH_DISPLAY_SETTING: 'sshDisplaySetting', SSH_DISPLAY_SETTING: 'sshDisplaySetting',
// rdp 图形化设置
RDP_GRAPH_SETTING: 'rdpGraphSetting',
// ssh 操作栏设置 // ssh 操作栏设置
SSH_ACTION_BAR_SETTING: 'sshActionBarSetting', SSH_ACTION_BAR_SETTING: 'sshActionBarSetting',
// ssh 右键菜单设置
SSH_RIGHT_MENU_SETTING: 'sshRightMenuSetting',
// ssh 交互设置
SSH_INTERACT_SETTING: 'sshInteractSetting',
// ssh 插件设置
SSH_PLUGINS_SETTING: 'sshPluginsSetting',
// rdp 图形化设置
RDP_GRAPH_SETTING: 'rdpGraphSetting',
// rdp 操作栏设置 // rdp 操作栏设置
RDP_ACTION_BAR_SETTING: 'rdpActionBarSetting', RDP_ACTION_BAR_SETTING: 'rdpActionBarSetting',
// 右键菜单设置
RIGHT_MENU_SETTING: 'rightMenuSetting',
// 交互设置
INTERACT_SETTING: 'interactSetting',
// 插件设置
PLUGINS_SETTING: 'pluginsSetting',
// 会话设置 // 会话设置
SESSION_SETTING: 'sessionSetting', RDP_SESSION_SETTING: 'rdpSessionSetting',
// 快捷键设置 // 快捷键设置
SHORTCUT_SETTING: 'shortcutSetting', SHORTCUT_SETTING: 'shortcutSetting',
}; };
@@ -66,17 +66,17 @@ export default defineStore('terminal', {
state: (): TerminalState => ({ state: (): TerminalState => ({
preference: { preference: {
newConnectionType: 'group', newConnectionType: 'group',
theme: { sshTheme: {
schema: {} as TerminalThemeSchema schema: {} as TerminalThemeSchema
} as TerminalTheme, } as TerminalTheme,
sshDisplaySetting: {} as TerminalSshDisplaySetting, sshDisplaySetting: {} as TerminalSshDisplaySetting,
rdpGraphSetting: {} as TerminalRdpGraphSetting,
sshActionBarSetting: {} as TerminalSshActionBarSetting, sshActionBarSetting: {} as TerminalSshActionBarSetting,
sshRightMenuSetting: [],
sshInteractSetting: {} as TerminalSshInteractSetting,
sshPluginsSetting: {} as TerminalSshPluginsSetting,
rdpGraphSetting: {} as TerminalRdpGraphSetting,
rdpSessionSetting: {} as TerminalRdpSessionSetting,
rdpActionBarSetting: {} as TerminalRdpActionBarSetting, rdpActionBarSetting: {} as TerminalRdpActionBarSetting,
rightMenuSetting: [],
interactSetting: {} as TerminalInteractSetting,
pluginsSetting: {} as TerminalPluginsSetting,
sessionSetting: {} as TerminalSessionSetting,
shortcutSetting: { shortcutSetting: {
enabled: false, enabled: false,
keys: [] keys: []
@@ -100,11 +100,11 @@ export default defineStore('terminal', {
// 加载偏好 // 加载偏好
const { data } = await getPreference<TerminalPreference>('TERMINAL'); const { data } = await getPreference<TerminalPreference>('TERMINAL');
// theme 不存在则默认加载第一个 // theme 不存在则默认加载第一个
if (!data.theme?.name) { if (!data.sshTheme?.name) {
const { data: themes } = await getTerminalThemes(); const { data: themes } = await getTerminalThemes();
data.theme = themes[0]; data.sshTheme = themes[0];
// 更新默认主题偏好 // 更新默认主题偏好
await this.updateTerminalPreference(TerminalPreferenceItem.THEME, data.theme); await this.updateTerminalPreference(TerminalPreferenceItem.SSH_THEME, data.sshTheme);
} }
// 移除禁用的快捷键 // 移除禁用的快捷键
if (data.shortcutSetting?.enabled) { if (data.shortcutSetting?.enabled) {

View File

@@ -14,15 +14,15 @@ export interface TerminalState {
// 终端配置 // 终端配置
export interface TerminalPreference { export interface TerminalPreference {
newConnectionType: string; newConnectionType: string;
theme: TerminalTheme; sshTheme: TerminalTheme;
sshDisplaySetting: TerminalSshDisplaySetting; sshDisplaySetting: TerminalSshDisplaySetting;
rdpGraphSetting: TerminalRdpGraphSetting;
sshActionBarSetting: TerminalSshActionBarSetting; sshActionBarSetting: TerminalSshActionBarSetting;
sshRightMenuSetting: Array<string>,
sshInteractSetting: TerminalSshInteractSetting;
sshPluginsSetting: TerminalSshPluginsSetting;
rdpGraphSetting: TerminalRdpGraphSetting;
rdpActionBarSetting: TerminalRdpActionBarSetting; rdpActionBarSetting: TerminalRdpActionBarSetting;
rightMenuSetting: Array<string>, rdpSessionSetting: TerminalRdpSessionSetting;
interactSetting: TerminalInteractSetting;
pluginsSetting: TerminalPluginsSetting;
sessionSetting: TerminalSessionSetting;
shortcutSetting: TerminalShortcutSetting; shortcutSetting: TerminalShortcutSetting;
} }
@@ -38,13 +38,44 @@ export interface TerminalSshDisplaySetting {
cursorBlink?: boolean; cursorBlink?: boolean;
} }
// SSH 操作栏设置
export interface TerminalSshActionBarSetting {
connectStatus?: boolean;
share?: boolean;
[key: string]: unknown;
}
// SSH 插件设置
export interface TerminalSshPluginsSetting {
enableWeblinkPlugin: boolean;
enableWebglPlugin: boolean;
enableUnicodePlugin: boolean;
enableImagePlugin: boolean;
}
// SSH 交互设置
export interface TerminalSshInteractSetting {
fastScrollModifier: boolean;
altClickMovesCursor: boolean;
rightClickSelectsWord: boolean;
selectionChangeCopy: boolean;
copyAutoTrim: boolean;
pasteAutoTrim: boolean;
rightClickPaste: boolean;
enableRightClickMenu: boolean;
enableBell: boolean;
wordSeparator: string;
terminalEmulationType: string;
scrollBackLine: number;
}
// RDP 图形化设置 // RDP 图形化设置
export interface TerminalRdpGraphSetting { export interface TerminalRdpGraphSetting {
displaySize?: string; displaySize?: string;
displayWidth?: number; displayWidth?: number;
displayHeight?: number; displayHeight?: number;
enableAudioInput?: boolean;
enableAudioOutput?: boolean;
colorDepth?: number; colorDepth?: number;
forceLossless?: boolean; forceLossless?: boolean;
enableWallpaper?: boolean; enableWallpaper?: boolean;
@@ -56,13 +87,7 @@ export interface TerminalRdpGraphSetting {
disableBitmapCaching?: boolean; disableBitmapCaching?: boolean;
disableOffscreenCaching?: boolean; disableOffscreenCaching?: boolean;
disableGlyphCaching?: boolean; disableGlyphCaching?: boolean;
} disableGfx?: boolean;
// SSH 操作栏设置
export interface TerminalSshActionBarSetting {
connectStatus?: boolean;
[key: string]: unknown;
} }
// RDP 操作栏设置 // RDP 操作栏设置
@@ -79,32 +104,11 @@ export interface TerminalRdpActionBarSetting {
[key: string]: unknown; [key: string]: unknown;
} }
// 交互设置 // RDP 会话设置
export interface TerminalInteractSetting { export interface TerminalRdpSessionSetting {
fastScrollModifier: boolean; enableAudioInput?: boolean;
altClickMovesCursor: boolean; enableAudioOutput?: boolean;
rightClickSelectsWord: boolean; driveMountMode?: string;
selectionChangeCopy: boolean;
copyAutoTrim: boolean;
pasteAutoTrim: boolean;
rightClickPaste: boolean;
enableRightClickMenu: boolean;
enableBell: boolean;
wordSeparator: string;
}
// 插件设置
export interface TerminalPluginsSetting {
enableWeblinkPlugin: boolean;
enableWebglPlugin: boolean;
enableUnicodePlugin: boolean;
enableImagePlugin: boolean;
}
// 会话设置
export interface TerminalSessionSetting {
terminalEmulationType: string;
scrollBackLine: number;
} }
// 终端快捷键设置 // 终端快捷键设置

View File

@@ -13,12 +13,12 @@
</div> </div>
<!-- 描述 --> <!-- 描述 -->
<div class="block-form-item-desc"> <div class="block-form-item-desc">
<template v-if="desc"> <template v-if="$slots.desc">
{{ desc }}
</template>
<template v-else>
<slot name="desc" /> <slot name="desc" />
</template> </template>
<template v-else-if="desc">
{{ desc }}
</template>
</div> </div>
</div> </div>
</a-col> </a-col>

View File

@@ -9,8 +9,8 @@
<terminal-ssh-action-bar-block /> <terminal-ssh-action-bar-block />
<!-- RDP 工具栏 --> <!-- RDP 工具栏 -->
<terminal-rdp-action-bar-block /> <terminal-rdp-action-bar-block />
<!-- 右键菜单 --> <!-- SSH 右键菜单 -->
<terminal-right-menu-block /> <terminal-ssh-right-menu-block />
</div> </div>
</div> </div>
</template> </template>
@@ -24,8 +24,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import TerminalSshDisplayBlock from './terminal-ssh-display-block.vue'; import TerminalSshDisplayBlock from './terminal-ssh-display-block.vue';
import TerminalSshActionBarBlock from './terminal-ssh-action-bar-block.vue'; import TerminalSshActionBarBlock from './terminal-ssh-action-bar-block.vue';
import TerminalSshRightMenuBlock from './terminal-ssh-right-menu-block.vue';
import TerminalRdpActionBarBlock from './terminal-rdp-action-bar-block.vue'; import TerminalRdpActionBarBlock from './terminal-rdp-action-bar-block.vue';
import TerminalRightMenuBlock from './terminal-right-menu-block.vue';
</script> </script>

View File

@@ -3,7 +3,7 @@
<!-- 顶部 --> <!-- 顶部 -->
<div class="terminal-setting-subtitle-wrapper"> <div class="terminal-setting-subtitle-wrapper">
<h3 class="terminal-setting-subtitle"> <h3 class="terminal-setting-subtitle">
显示偏好 SSH 显示偏好
</h3> </h3>
</div> </div>
<!-- 内容区域 --> <!-- 内容区域 -->
@@ -99,7 +99,7 @@
<span class="vertical-form-label">预览效果</span> <span class="vertical-form-label">预览效果</span>
<div class="terminal-example-wrapper" <div class="terminal-example-wrapper"
:style="{ background: background }"> :style="{ background: background }">
<terminal-example :schema="preference.theme.schema" <terminal-example :schema="preference.sshTheme.schema"
ref="previewTerminal" /> ref="previewTerminal" />
</div> </div>
</div> </div>
@@ -127,7 +127,7 @@
const { toOptions, toRadioOptions } = useDictStore(); const { toOptions, toRadioOptions } = useDictStore();
const { preference, updateTerminalPreference, sessionManager } = useTerminalStore(); const { preference, updateTerminalPreference, sessionManager } = useTerminalStore();
const background = preference.theme.schema.background; const background = preference.sshTheme.schema.background;
const previewTerminal = ref(); const previewTerminal = ref();
const formModel = ref<TerminalSshDisplaySetting>({}); const formModel = ref<TerminalSshDisplaySetting>({});

View File

@@ -3,7 +3,7 @@
<!-- 顶部 --> <!-- 顶部 -->
<div class="terminal-setting-subtitle-wrapper"> <div class="terminal-setting-subtitle-wrapper">
<h3 class="terminal-setting-subtitle"> <h3 class="terminal-setting-subtitle">
右键菜单设置 SSH 右键菜单设置
</h3> </h3>
</div> </div>
<!-- 提示 --> <!-- 提示 -->
@@ -80,7 +80,7 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'terminalRightMenuBlock' name: 'terminalSshRightMenuBlock'
}; };
</script> </script>
@@ -95,12 +95,12 @@
const { preference, updateTerminalPreference } = useTerminalStore(); const { preference, updateTerminalPreference } = useTerminalStore();
const popupContainer = ref(); const popupContainer = ref();
const rightActionItems = ref<Array<string>>([...preference.rightMenuSetting]); const rightActionItems = ref<Array<string>>([...preference.sshRightMenuSetting]);
// // // //
watch(rightActionItems, (v) => { watch(rightActionItems, (v) => {
// //
updateTerminalPreference(TerminalPreferenceItem.RIGHT_MENU_SETTING, JSON.stringify(v), true); updateTerminalPreference(TerminalPreferenceItem.SSH_RIGHT_MENU_SETTING, JSON.stringify(v), true);
}, { deep: true }); }, { deep: true });
// //

View File

@@ -3,14 +3,14 @@
<div class="terminal-setting-wrapper"> <div class="terminal-setting-wrapper">
<!-- 主标题 --> <!-- 主标题 -->
<h2 class="terminal-setting-title">终端设置</h2> <h2 class="terminal-setting-title">终端设置</h2>
<!-- 交互设置 --> <!-- SSH 交互设置 -->
<terminal-interact-block /> <terminal-ssh-interact-block />
<!-- 插件设置 --> <!-- SSH 插件设置 -->
<terminal-plugins-block /> <terminal-ssh-plugins-block />
<!-- 会话设置 -->
<terminal-session-block />
<!-- RDP 图形化设置 --> <!-- RDP 图形化设置 -->
<terminal-rdp-graph-block /> <terminal-rdp-graph-block />
<!-- RDP 会话设置 -->
<terminal-rdp-session-block />
</div> </div>
</div> </div>
</template> </template>
@@ -22,10 +22,10 @@
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import TerminalInteractBlock from './terminal-interact-block.vue'; import TerminalSshInteractBlock from './terminal-ssh-interact-block.vue';
import TerminalPluginsBlock from './terminal-plugins-block.vue'; import TerminalSshPluginsBlock from './terminal-ssh-plugins-block.vue';
import TerminalSessionBlock from './terminal-session-block.vue';
import TerminalRdpGraphBlock from './terminal-rdp-graph-block.vue'; import TerminalRdpGraphBlock from './terminal-rdp-graph-block.vue';
import TerminalRdpSessionBlock from './terminal-rdp-session-block.vue';
</script> </script>

View File

@@ -3,7 +3,7 @@
<!-- 顶部 --> <!-- 顶部 -->
<div class="terminal-setting-subtitle-wrapper"> <div class="terminal-setting-subtitle-wrapper">
<h3 class="terminal-setting-subtitle"> <h3 class="terminal-setting-subtitle">
RDP 设置 RDP 图形化设置
</h3> </h3>
</div> </div>
<!-- 提示 --> <!-- 提示 -->
@@ -28,61 +28,61 @@
</block-setting-item> </block-setting-item>
</a-row> </a-row>
<a-row class="mb16" align="stretch" :gutter="16"> <a-row class="mb16" align="stretch" :gutter="16">
<!-- 启用音频输出 -->
<block-setting-item label="启用音频输出" desc="启用后会将音频输出到浏览器播放">
<a-switch v-model="formModel.enableAudioOutput" type="round" />
</block-setting-item>
<!-- 无损压缩 --> <!-- 无损压缩 -->
<block-setting-item label="无损压缩" desc="是否启用对图形更新的无损压缩"> <block-setting-item label="无损压缩" desc="是否启用对图形更新的无损压缩">
<a-switch v-model="formModel.forceLossless" type="round" /> <a-switch v-model="formModel.forceLossless" type="round" />
</block-setting-item> </block-setting-item>
</a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 启用壁纸 --> <!-- 启用壁纸 -->
<block-setting-item label="启用壁纸" desc="是否启用桌面壁纸的渲染"> <block-setting-item label="启用壁纸" desc="是否启用桌面壁纸的渲染">
<a-switch v-model="formModel.enableWallpaper" type="round" /> <a-switch v-model="formModel.enableWallpaper" type="round" />
</block-setting-item> </block-setting-item>
</a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 启用主题 --> <!-- 启用主题 -->
<block-setting-item label="启用主题" desc="允许使用窗口和控件的主题"> <block-setting-item label="启用主题" desc="允许使用窗口和控件的主题">
<a-switch v-model="formModel.enableTheming" type="round" /> <a-switch v-model="formModel.enableTheming" type="round" />
</block-setting-item> </block-setting-item>
</a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 启动平滑字体 --> <!-- 启动平滑字体 -->
<block-setting-item label="启动平滑字体" desc="允许文本将以平滑的边缘呈现"> <block-setting-item label="启动平滑字体" desc="允许文本将以平滑的边缘呈现">
<a-switch v-model="formModel.enableFontSmoothing" type="round" /> <a-switch v-model="formModel.enableFontSmoothing" type="round" />
</block-setting-item> </block-setting-item>
</a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 启用窗口拖动 --> <!-- 启用窗口拖动 -->
<block-setting-item label="启用窗口拖动" desc="开启后当移动窗口时将显示窗口内容"> <block-setting-item label="启用窗口拖动" desc="开启后当移动窗口时将显示窗口内容">
<a-switch v-model="formModel.enableFullWindowDrag" type="round" /> <a-switch v-model="formModel.enableFullWindowDrag" type="round" />
</block-setting-item> </block-setting-item>
</a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 启用桌面合成 --> <!-- 启用桌面合成 -->
<block-setting-item label="启用桌面合成" desc="开启后将显示高级图形效果 (如透明窗口、阴影等)"> <block-setting-item label="启用桌面合成" desc="开启后将显示高级图形效果 (如透明窗口、阴影等)">
<a-switch v-model="formModel.enableDesktopComposition" type="round" /> <a-switch v-model="formModel.enableDesktopComposition" type="round" />
</block-setting-item> </block-setting-item>
</a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 启用菜单动画 --> <!-- 启用菜单动画 -->
<block-setting-item label="启用菜单动画" desc="开启后将显示菜单打开和关闭的过渡动画"> <block-setting-item label="启用菜单动画" desc="开启后将显示菜单打开和关闭的过渡动画">
<a-switch v-model="formModel.enableMenuAnimations" type="round" /> <a-switch v-model="formModel.enableMenuAnimations" type="round" />
</block-setting-item> </block-setting-item>
</a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 禁用位图缓存 --> <!-- 禁用位图缓存 -->
<block-setting-item label="禁用位图缓存" desc="在某些实现存在兼容性问题时, 禁用后可绕过位图缓存"> <block-setting-item label="禁用位图缓存" desc="在某些实现存在兼容性问题时, 禁用后可绕过位图缓存">
<a-switch v-model="formModel.disableBitmapCaching" type="round" /> <a-switch v-model="formModel.disableBitmapCaching" type="round" />
</block-setting-item> </block-setting-item>
</a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 禁用离屏缓存 --> <!-- 禁用离屏缓存 -->
<block-setting-item label="禁用离屏缓存" desc="在某些实现存在兼容性问题时, 禁用后将不再缓存屏幕外区域"> <block-setting-item label="禁用离屏缓存" desc="在某些实现存在兼容性问题时, 禁用后将不再缓存屏幕外区域">
<a-switch v-model="formModel.disableOffscreenCaching" type="round" /> <a-switch v-model="formModel.disableOffscreenCaching" type="round" />
</block-setting-item> </block-setting-item>
</a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 禁用字形缓存 --> <!-- 禁用字形缓存 -->
<block-setting-item label="禁用字形缓存" desc="在某些实现存在兼容性问题时, 禁用后将不再缓存常用字体和符号"> <block-setting-item label="禁用字形缓存" desc="在某些实现存在兼容性问题时, 禁用后将不再缓存常用字体和符号">
<a-switch v-model="formModel.disableGlyphCaching" type="round" /> <a-switch v-model="formModel.disableGlyphCaching" type="round" />
</block-setting-item> </block-setting-item>
</a-row> </a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 禁用图形加速 -->
<block-setting-item label="禁用图形加速" desc="禁用后将不再使用 GFX 进行数据编码">
<a-switch v-model="formModel.disableGfx" type="round" />
</block-setting-item>
</a-row>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -0,0 +1,66 @@
<template>
<div class="terminal-setting-block">
<!-- 顶部 -->
<div class="terminal-setting-subtitle-wrapper">
<h3 class="terminal-setting-subtitle">
RDP 会话设置
</h3>
</div>
<!-- 内容区域 -->
<div class="terminal-setting-body setting-body">
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 启用音频输出 -->
<block-setting-item label="启用音频输出" desc="启用后会将音频输出到浏览器播放">
<a-switch v-model="formModel.enableAudioOutput" type="round" />
</block-setting-item>
<!-- 驱动挂载模式 -->
<block-setting-item label="驱动挂载模式">
<a-select v-model="formModel.driveMountMode"
style="width: 198px;"
size="small"
:options="toOptions(driveMountModeKey)" />
<template #desc>
{{ getDictValue(driveMountModeKey, formModel.driveMountMode, 'help', '设置驱动路径的挂载模式') }}
</template>
</block-setting-item>
</a-row>
</div>
</div>
</template>
<script lang="ts">
export default {
name: 'terminalRdpSessionBlock'
};
</script>
<script lang="ts" setup>
import type { TerminalRdpSessionSetting } from '@/store/modules/terminal/types';
import { ref, watch } from 'vue';
import { useDictStore, useTerminalStore } from '@/store';
import { TerminalPreferenceItem } from '@/store/modules/terminal';
import { driveMountModeKey } from '@/views/terminal/types/const';
import BlockSettingItem from '../block-setting-item.vue';
const { toOptions, getDictValue } = useDictStore();
const { preference, updateTerminalPreference } = useTerminalStore();
const formModel = ref<TerminalRdpSessionSetting>({ ...preference.rdpSessionSetting });
// 监听内容变化
watch(formModel, (v) => {
if (!v) {
return;
}
// 同步
updateTerminalPreference(TerminalPreferenceItem.RDP_SESSION_SETTING, formModel.value);
}, { deep: true });
</script>
<style lang="less" scoped>
.setting-body {
flex-direction: column;
}
</style>

View File

@@ -1,70 +0,0 @@
<template>
<div class="terminal-setting-block">
<!-- 顶部 -->
<div class="terminal-setting-subtitle-wrapper">
<h3 class="terminal-setting-subtitle">
会话设置
</h3>
</div>
<!-- 内容区域 -->
<div class="terminal-setting-body setting-body">
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 终端类型 -->
<block-setting-item label="终端类型" desc="若显示异常请尝试切换此选项 兼容性 vt100 > xterm > 16color > 256color">
<a-select v-model="formModel.terminalEmulationType"
style="width: 198px;"
size="small"
:options="toOptions(emulationTypeKey)" />
</block-setting-item>
<!-- 缓冲区行数 -->
<block-setting-item label="缓冲区行数" desc="保存在缓冲区的行数, 多出的行数会被忽略, 此值越大占用内存的内存会更多">
<a-input-number v-model="formModel.scrollBackLine"
style="width: 198px"
size="small"
:min="1"
:max="100000"
placeholder="缓冲区行数 默认 1000 行"
allow-clear
hide-button />
</block-setting-item>
</a-row>
</div>
</div>
</template>
<script lang="ts">
export default {
name: 'terminalSessionBlock'
};
</script>
<script lang="ts" setup>
import type { TerminalSessionSetting } from '@/store/modules/terminal/types';
import { ref, watch } from 'vue';
import { useDictStore, useTerminalStore } from '@/store';
import { TerminalPreferenceItem } from '@/store/modules/terminal';
import { emulationTypeKey } from '@/views/terminal/types/const';
import BlockSettingItem from '../block-setting-item.vue';
const { toOptions } = useDictStore();
const { preference, updateTerminalPreference } = useTerminalStore();
const formModel = ref<TerminalSessionSetting>({ ...preference.sessionSetting });
// 监听内容变化
watch(formModel, (v) => {
if (!v) {
return;
}
// 同步
updateTerminalPreference(TerminalPreferenceItem.SESSION_SETTING, formModel.value);
}, { deep: true });
</script>
<style lang="less" scoped>
.setting-body {
flex-direction: column;
}
</style>

View File

@@ -3,7 +3,7 @@
<!-- 顶部 --> <!-- 顶部 -->
<div class="terminal-setting-subtitle-wrapper"> <div class="terminal-setting-subtitle-wrapper">
<h3 class="terminal-setting-subtitle"> <h3 class="terminal-setting-subtitle">
交互设置 SSH 交互设置
</h3> </h3>
</div> </div>
<!-- 提示 --> <!-- 提示 -->
@@ -56,9 +56,6 @@
<block-setting-item label="粘贴去除空格" <block-setting-item label="粘贴去除空格"
desc="粘贴文本前自动删除尾部空格 如: 命令输入框, 命令编辑器, 右键粘贴, 粘贴按钮, 右键菜单粘贴, 自定义粘贴快捷键. 默认粘贴快捷键无法去除空格"> desc="粘贴文本前自动删除尾部空格 如: 命令输入框, 命令编辑器, 右键粘贴, 粘贴按钮, 右键菜单粘贴, 自定义粘贴快捷键. 默认粘贴快捷键无法去除空格">
<a-switch v-model="formModel.pasteAutoTrim" type="round" /> <a-switch v-model="formModel.pasteAutoTrim" type="round" />
<template #desc>
</template>
</block-setting-item> </block-setting-item>
</a-row> </a-row>
<a-row class="mb16" align="stretch" :gutter="16"> <a-row class="mb16" align="stretch" :gutter="16">
@@ -75,27 +72,49 @@
allow-clear /> allow-clear />
</block-setting-item> </block-setting-item>
</a-row> </a-row>
<a-row class="mb16" align="stretch" :gutter="16">
<!-- 终端类型 -->
<block-setting-item label="终端类型" desc="若显示异常请尝试切换此选项 兼容性 vt100 > xterm > 16color > 256color">
<a-select v-model="formModel.terminalEmulationType"
style="width: 198px;"
size="small"
:options="toOptions(emulationTypeKey)" />
</block-setting-item>
<!-- 缓冲区行数 -->
<block-setting-item label="缓冲区行数" desc="保存在缓冲区的行数, 多出的行数会被忽略, 此值越大占用内存的内存会更多">
<a-input-number v-model="formModel.scrollBackLine"
style="width: 198px"
size="small"
:min="1"
:max="100000"
placeholder="缓冲区行数 默认 1000 行"
allow-clear
hide-button />
</block-setting-item>
</a-row>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'terminalInteractBlock' name: 'terminalSshInteractBlock'
}; };
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import type { TerminalInteractSetting } from '@/store/modules/terminal/types'; import type { TerminalSshInteractSetting } from '@/store/modules/terminal/types';
import { ref, watch } from 'vue'; import { ref, watch } from 'vue';
import { useTerminalStore } from '@/store'; import { useTerminalStore, useDictStore } from '@/store';
import { TerminalPreferenceItem } from '@/store/modules/terminal'; import { TerminalPreferenceItem } from '@/store/modules/terminal';
import { emulationTypeKey } from '@/views/terminal/types/const';
import { isSecureEnvironment } from '@/utils/env'; import { isSecureEnvironment } from '@/utils/env';
import BlockSettingItem from '../block-setting-item.vue'; import BlockSettingItem from '../block-setting-item.vue';
const { toOptions } = useDictStore();
const { preference, updateTerminalPreference } = useTerminalStore(); const { preference, updateTerminalPreference } = useTerminalStore();
const formModel = ref<TerminalInteractSetting>({ ...preference.interactSetting }); const formModel = ref<TerminalSshInteractSetting>({ ...preference.sshInteractSetting });
// //
watch(formModel, (v) => { watch(formModel, (v) => {
@@ -103,7 +122,7 @@
return; return;
} }
// //
updateTerminalPreference(TerminalPreferenceItem.INTERACT_SETTING, formModel.value); updateTerminalPreference(TerminalPreferenceItem.SSH_INTERACT_SETTING, formModel.value);
}, { deep: true }); }, { deep: true });
</script> </script>

View File

@@ -3,7 +3,7 @@
<!-- 顶部 --> <!-- 顶部 -->
<div class="terminal-setting-subtitle-wrapper"> <div class="terminal-setting-subtitle-wrapper">
<h3 class="terminal-setting-subtitle"> <h3 class="terminal-setting-subtitle">
插件设置 SSH 插件设置
</h3> </h3>
</div> </div>
<!-- 内容区域 --> <!-- 内容区域 -->
@@ -34,12 +34,12 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'terminalPluginsBlock' name: 'terminalSshPluginsBlock'
}; };
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import type { TerminalPluginsSetting } from '@/store/modules/terminal/types'; import type { TerminalSshPluginsSetting } from '@/store/modules/terminal/types';
import { ref, watch } from 'vue'; import { ref, watch } from 'vue';
import { useTerminalStore } from '@/store'; import { useTerminalStore } from '@/store';
import { TerminalPreferenceItem } from '@/store/modules/terminal'; import { TerminalPreferenceItem } from '@/store/modules/terminal';
@@ -47,7 +47,7 @@
const { preference, updateTerminalPreference } = useTerminalStore(); const { preference, updateTerminalPreference } = useTerminalStore();
const formModel = ref<TerminalPluginsSetting>({ ...preference.pluginsSetting }); const formModel = ref<TerminalSshPluginsSetting>({ ...preference.sshPluginsSetting });
// //
watch(formModel, (v) => { watch(formModel, (v) => {
@@ -55,7 +55,7 @@
return; return;
} }
// //
updateTerminalPreference(TerminalPreferenceItem.PLUGINS_SETTING, formModel.value); updateTerminalPreference(TerminalPreferenceItem.SSH_PLUGINS_SETTING, formModel.value);
}, { deep: true }); }, { deep: true });
</script> </script>

View File

@@ -3,7 +3,7 @@
<!-- 顶部 --> <!-- 顶部 -->
<div class="terminal-setting-subtitle-wrapper"> <div class="terminal-setting-subtitle-wrapper">
<h3 class="terminal-setting-subtitle"> <h3 class="terminal-setting-subtitle">
主题设置 SSH 主题设置
</h3> </h3>
</div> </div>
<!-- 加载中 --> <!-- 加载中 -->
@@ -49,7 +49,7 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'terminalThemeBlock' name: 'terminalSshThemeBlock'
}; };
</script> </script>
@@ -86,14 +86,14 @@
}); });
// //
currentThemeName.value = theme.name; currentThemeName.value = theme.name;
await updateTerminalPreference(TerminalPreferenceItem.THEME, theme, true); await updateTerminalPreference(TerminalPreferenceItem.SSH_THEME, theme, true);
}; };
// //
onMounted(async () => { onMounted(async () => {
try { try {
const { data } = await getPreference<Record<string, any>>('TERMINAL', [TerminalPreferenceItem.THEME]); const { data } = await getPreference<Record<string, any>>('TERMINAL', [TerminalPreferenceItem.SSH_THEME]);
currentThemeName.value = data[TerminalPreferenceItem.THEME]?.name; currentThemeName.value = data[TerminalPreferenceItem.SSH_THEME]?.name;
} catch (e) { } catch (e) {
} }
}); });

View File

@@ -3,8 +3,8 @@
<div class="terminal-setting-wrapper"> <div class="terminal-setting-wrapper">
<!-- 主标题 --> <!-- 主标题 -->
<h2 class="terminal-setting-title">主题设置</h2> <h2 class="terminal-setting-title">主题设置</h2>
<!-- 主题设置 --> <!-- SSH 主题设置 -->
<terminal-theme-block /> <terminal-ssh-theme-block />
</div> </div>
</div> </div>
</template> </template>
@@ -16,7 +16,7 @@
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import TerminalThemeBlock from './terminal-theme-block.vue'; import TerminalSshThemeBlock from './terminal-ssh-theme-block.vue';
</script> </script>

View File

@@ -2,7 +2,7 @@
<editor ref="editorRef" <editor ref="editorRef"
language="txt" language="txt"
:auto-focus="true" :auto-focus="true"
:theme="preference.theme.dark ? 'vs-dark' : 'vs'" /> :theme="preference.sshTheme.dark ? 'vs-dark' : 'vs'" />
</template> </template>
<script lang="ts"> <script lang="ts">

View File

@@ -8,7 +8,7 @@
<!-- 终端插槽 --> <!-- 终端插槽 -->
<slot /> <slot />
<!-- 右键菜单 --> <!-- 右键菜单 -->
<template v-if="session && preference.interactSetting.enableRightClickMenu" #content> <template v-if="session && preference.sshInteractSetting.enableRightClickMenu" #content>
<a-doption v-for="(action, index) in actions" <a-doption v-for="(action, index) in actions"
:key="index" :key="index"
:disabled="!session || !session.handler.enabledStatus(action.item)" :disabled="!session || !session.handler.enabledStatus(action.item)"
@@ -44,9 +44,9 @@
const { preference } = useTerminalStore(); const { preference } = useTerminalStore();
const actions: Array<ContextMenuItem> = !preference.interactSetting.enableRightClickMenu const actions: Array<ContextMenuItem> = !preference.sshInteractSetting.enableRightClickMenu
? [] ? []
: preference.rightMenuSetting : preference.sshRightMenuSetting
.map(s => SshActionBarItems.find(i => i.item === s) as ContextMenuItem) .map(s => SshActionBarItems.find(i => i.item === s) as ContextMenuItem)
.filter(Boolean); .filter(Boolean);

View File

@@ -6,7 +6,7 @@
<ssh-context-menu :session="session" @handle="doTerminalHandle"> <ssh-context-menu :session="session" @handle="doTerminalHandle">
<!-- 终端容器 --> <!-- 终端容器 -->
<div class="ssh-wrapper" <div class="ssh-wrapper"
:style="{ background: preference.theme.schema.background }"> :style="{ background: preference.sshTheme.schema.background }">
<!-- 终端实例 --> <!-- 终端实例 -->
<div class="ssh-viewport" ref="viewport" /> <div class="ssh-viewport" ref="viewport" />
<!-- 搜索模态框 --> <!-- 搜索模态框 -->

View File

@@ -154,7 +154,7 @@
// 加载偏好 // 加载偏好
fetchPreference().then(() => { fetchPreference().then(() => {
// 设置系统主题配色 // 设置系统主题配色
const dark = preference.theme.dark; const dark = preference.sshTheme.dark;
document.body.setAttribute('terminal-theme', dark ? 'dark' : 'light'); document.body.setAttribute('terminal-theme', dark ? 'dark' : 'light');
render.value = true; render.value = true;
}); });

View File

@@ -10,24 +10,28 @@ export default class RdpChannel extends BaseGuacdChannel<IRdpSession> {
// 打开 channel // 打开 channel
protected async openChannel(): Promise<void> { protected async openChannel(): Promise<void> {
const setting = useTerminalStore().preference.rdpGraphSetting; const preference = useTerminalStore().preference;
const graphSetting = preference.rdpGraphSetting;
const sessionSetting = preference.rdpSessionSetting;
const { data } = await getTerminalAccessToken({ const { data } = await getTerminalAccessToken({
hostId: this.session.info.hostId, hostId: this.session.info.hostId,
connectType: TerminalSessionTypes.RDP.type, connectType: TerminalSessionTypes.RDP.type,
extra: { extra: {
enableAudioInput: setting.enableAudioInput, enableAudioInput: sessionSetting.enableAudioInput,
enableAudioOutput: setting.enableAudioOutput, enableAudioOutput: sessionSetting.enableAudioOutput,
colorDepth: setting.colorDepth || 16, driveMountMode: sessionSetting.driveMountMode,
forceLossless: setting.forceLossless, colorDepth: graphSetting.colorDepth || 16,
enableWallpaper: setting.enableWallpaper, forceLossless: graphSetting.forceLossless,
enableTheming: setting.enableTheming, enableWallpaper: graphSetting.enableWallpaper,
enableFontSmoothing: setting.enableFontSmoothing, enableTheming: graphSetting.enableTheming,
enableFullWindowDrag: setting.enableFullWindowDrag, enableFontSmoothing: graphSetting.enableFontSmoothing,
enableDesktopComposition: setting.enableDesktopComposition, enableFullWindowDrag: graphSetting.enableFullWindowDrag,
enableMenuAnimations: setting.enableMenuAnimations, enableDesktopComposition: graphSetting.enableDesktopComposition,
disableBitmapCaching: setting.disableBitmapCaching, enableMenuAnimations: graphSetting.enableMenuAnimations,
disableOffscreenCaching: setting.disableOffscreenCaching, disableBitmapCaching: graphSetting.disableBitmapCaching,
disableGlyphCaching: setting.disableGlyphCaching, disableOffscreenCaching: graphSetting.disableOffscreenCaching,
disableGlyphCaching: graphSetting.disableGlyphCaching,
disableGfx: graphSetting.disableGfx,
} }
}); });
// 打开 channel // 打开 channel

View File

@@ -16,7 +16,7 @@ export default class SshChannel extends BaseTerminalChannel<ISshSession> impleme
hostId: this.session.info.hostId, hostId: this.session.info.hostId,
connectType: TerminalSessionTypes.SSH.type, connectType: TerminalSessionTypes.SSH.type,
extra: { extra: {
terminalType: preference.sessionSetting.terminalEmulationType ?? 'xterm', terminalType: preference.sshInteractSetting.terminalEmulationType ?? 'xterm',
} }
}); });
// 打开 channel // 打开 channel

View File

@@ -1,4 +1,4 @@
import type { ShortcutKey, TerminalInteractSetting, TerminalShortcutKey } from '@/store/modules/terminal/types'; import type { ShortcutKey, TerminalShortcutKey, TerminalSshInteractSetting } from '@/store/modules/terminal/types';
import type { ISshSession, ISshSessionHandler } from '@/views/terminal/interfaces'; import type { ISshSession, ISshSessionHandler } from '@/views/terminal/interfaces';
import type { Terminal } from '@xterm/xterm'; import type { Terminal } from '@xterm/xterm';
import useCopy from '@/hooks/copy'; import useCopy from '@/hooks/copy';
@@ -39,7 +39,7 @@ export default class SshSessionHandler implements ISshSessionHandler {
private readonly session: ISshSession; private readonly session: ISshSession;
private readonly interactSetting: TerminalInteractSetting; private readonly interactSetting: TerminalSshInteractSetting;
private readonly shortcutKeys: Array<TerminalShortcutKey>; private readonly shortcutKeys: Array<TerminalShortcutKey>;
@@ -47,7 +47,7 @@ export default class SshSessionHandler implements ISshSessionHandler {
this.session = session; this.session = session;
this.inst = session.inst; this.inst = session.inst;
const { preference } = useTerminalStore(); const { preference } = useTerminalStore();
this.interactSetting = preference.interactSetting; this.interactSetting = preference.sshInteractSetting;
this.shortcutKeys = preference.shortcutSetting.keys; this.shortcutKeys = preference.shortcutSetting.keys;
} }

View File

@@ -139,7 +139,7 @@ export default class RdpSession extends BaseSession<GuacdReactiveSessionStatus,
// 手动触发管道已连接 // 手动触发管道已连接
this.channel.processConnected({} as unknown as OutputPayload); this.channel.processConnected({} as unknown as OutputPayload);
// 监听音频输入 // 监听音频输入
if (useTerminalStore().preference.rdpGraphSetting?.enableAudioInput) { if (useTerminalStore().preference.rdpSessionSetting?.enableAudioInput) {
const requestAudioStream = (client: Guacamole.Client) => { const requestAudioStream = (client: Guacamole.Client) => {
const stream = client.createAudioStream(AUDIO_INPUT_MIMETYPE); const stream = client.createAudioStream(AUDIO_INPUT_MIMETYPE);
let recorder; let recorder;

View File

@@ -50,13 +50,13 @@ export default class SshSession extends BaseSession<ReactiveSessionState, ISshCh
// 初始化实例 // 初始化实例
this.inst.options = { this.inst.options = {
...(preference.sshDisplaySetting as any), ...(preference.sshDisplaySetting as any),
theme: preference.theme.schema, theme: preference.sshTheme.schema,
fastScrollModifier: !!preference.interactSetting.fastScrollModifier ? 'alt' : 'none', fastScrollModifier: !!preference.sshInteractSetting.fastScrollModifier ? 'alt' : 'none',
altClickMovesCursor: !!preference.interactSetting.altClickMovesCursor, altClickMovesCursor: !!preference.sshInteractSetting.altClickMovesCursor,
rightClickSelectsWord: !!preference.interactSetting.rightClickSelectsWord, rightClickSelectsWord: !!preference.sshInteractSetting.rightClickSelectsWord,
wordSeparator: preference.interactSetting.wordSeparator, wordSeparator: preference.sshInteractSetting.wordSeparator,
scrollback: preference.sshInteractSetting.scrollBackLine,
fontFamily: fontFamily === '_' ? defaultFontFamily : `${fontFamily}, ${defaultFontFamily}`, fontFamily: fontFamily === '_' ? defaultFontFamily : `${fontFamily}, ${defaultFontFamily}`,
scrollback: preference.sessionSetting.scrollBackLine,
allowProposedApi: true, allowProposedApi: true,
}; };
// 初始化 channel // 初始化 channel
@@ -138,14 +138,14 @@ export default class SshSession extends BaseSession<ReactiveSessionState, ISshCh
}); });
}); });
// 启用响铃 // 启用响铃
if (preference.interactSetting.enableBell) { if (preference.sshInteractSetting.enableBell) {
this.inst.onBell(() => { this.inst.onBell(() => {
// 播放响铃 // 播放响铃
playBell(); playBell();
}); });
} }
// 选中复制 // 选中复制
if (preference.interactSetting.selectionChangeCopy) { if (preference.sshInteractSetting.selectionChangeCopy) {
this.inst.onSelectionChange(() => { this.inst.onSelectionChange(() => {
// 复制选中内容 // 复制选中内容
this.handler.copy(); this.handler.copy();
@@ -164,12 +164,12 @@ export default class SshSession extends BaseSession<ReactiveSessionState, ISshCh
// 设置右键选项 // 设置右键选项
addEventListen(dom, 'contextmenu', async () => { addEventListen(dom, 'contextmenu', async () => {
// 右键粘贴逻辑 // 右键粘贴逻辑
if (preference.interactSetting.rightClickPaste) { if (preference.sshInteractSetting.rightClickPaste) {
if (!this.state.canWrite || !this.state.connected) { if (!this.state.canWrite || !this.state.connected) {
return; return;
} }
// 未开启右键选中 || 开启并无选中的内容则粘贴 // 未开启右键选中 || 开启并无选中的内容则粘贴
if (!preference.interactSetting.rightClickSelectsWord || !this.inst.hasSelection()) { if (!preference.sshInteractSetting.rightClickSelectsWord || !this.inst.hasSelection()) {
this.handler.paste(); this.handler.paste();
} }
} }
@@ -181,10 +181,10 @@ export default class SshSession extends BaseSession<ReactiveSessionState, ISshCh
this.addons.fit = new FitAddon(); this.addons.fit = new FitAddon();
this.addons.search = new SearchAddon(); this.addons.search = new SearchAddon();
// 超链接插件 // 超链接插件
if (preference.pluginsSetting.enableWeblinkPlugin) { if (preference.sshPluginsSetting.enableWeblinkPlugin) {
this.addons.weblink = new WebLinksAddon(); this.addons.weblink = new WebLinksAddon();
} }
if (preference.pluginsSetting.enableWebglPlugin && this.config.webglAvailable) { if (preference.sshPluginsSetting.enableWebglPlugin && this.config.webglAvailable) {
// WebGL 渲染插件 // WebGL 渲染插件
this.addons.webgl = new WebglAddon(true); this.addons.webgl = new WebglAddon(true);
} else { } else {
@@ -192,11 +192,11 @@ export default class SshSession extends BaseSession<ReactiveSessionState, ISshCh
this.addons.canvas = new CanvasAddon(); this.addons.canvas = new CanvasAddon();
} }
// 图片渲染插件 // 图片渲染插件
if (preference.pluginsSetting.enableImagePlugin) { if (preference.sshPluginsSetting.enableImagePlugin) {
this.addons.image = new ImageAddon(); this.addons.image = new ImageAddon();
} }
// unicode11 插件 // unicode11 插件
if (preference.pluginsSetting.enableUnicodePlugin) { if (preference.sshPluginsSetting.enableUnicodePlugin) {
this.addons.unicode = new Unicode11Addon(); this.addons.unicode = new Unicode11Addon();
} }
// 加载插件 // 加载插件

View File

@@ -530,6 +530,9 @@ export const screenResolutionKey = 'screenResolution';
// 图形化色彩深度 // 图形化色彩深度
export const graphColorDepthKey = 'graphColorDepth'; export const graphColorDepthKey = 'graphColorDepth';
// 驱动挂载模式
export const driveMountModeKey = 'driveMountMode';
// vnc光标 // vnc光标
export const vcnCursorKey = 'vcnCursor'; export const vcnCursorKey = 'vcnCursor';
@@ -557,7 +560,7 @@ export const pathBookmarkTypeKey = 'pathBookmarkType';
// 加载的字典值 // 加载的字典值
export const dictKeys = [ export const dictKeys = [
fontFamilyKey, fontSizeKey, fontWeightKey, cursorStyleKey, emulationTypeKey, fontFamilyKey, fontSizeKey, fontWeightKey, cursorStyleKey, emulationTypeKey,
graphActionBarPositionKey, graphColorDepthKey, screenResolutionKey, vcnCursorKey, graphActionBarPositionKey, graphColorDepthKey, screenResolutionKey, driveMountModeKey, vcnCursorKey,
newConnectionTypeKey, connectStatusKey, tabColorKey, newConnectionTypeKey, connectStatusKey, tabColorKey,
extraSshAuthTypeKey, extraPasswordAuthTypeKey, extraSshAuthTypeKey, extraPasswordAuthTypeKey,
transferStatusKey, transferStatusKey,

View File

@@ -34,7 +34,7 @@ export const screenshot = async (el: HTMLElement) => {
const w = Number.parseInt(wPx.substring(0, wPx.length - 2)); const w = Number.parseInt(wPx.substring(0, wPx.length - 2));
const h = Number.parseInt(hPx.substring(0, hPx.length - 2)); const h = Number.parseInt(hPx.substring(0, hPx.length - 2));
const fontSize = 14; const fontSize = 14;
ctx.fillStyle = useTerminalStore().preference.theme.dark ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'; ctx.fillStyle = useTerminalStore().preference.sshTheme.dark ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)';
ctx.font = `${fontSize}px Arial`; ctx.font = `${fontSize}px Arial`;
ctx.rotate(-24 * Math.PI / 180); ctx.rotate(-24 * Math.PI / 180);
// 水印内容 // 水印内容