Skip to content

Commit 49a56a6

Browse files
committed
perf: update windows
1 parent 7abc3e6 commit 49a56a6

8 files changed

Lines changed: 193 additions & 89 deletions

File tree

go-client/pkg/awaken/awaken_linux.go

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,38 @@ func splitArgsWithLiteral(template string, literals map[string]string) []string
7373
return args
7474
}
7575

76+
func buildArgsFromTemplate(template string, values map[string]string) []string {
77+
if strings.TrimSpace(template) == "" {
78+
return nil
79+
}
80+
81+
replaced := template
82+
tokenValues := map[string]string{}
83+
index := 0
84+
85+
for placeholder, value := range values {
86+
token := fmt.Sprintf("__JMS_LITERAL_%d__", index)
87+
replaced = strings.ReplaceAll(replaced, "{"+placeholder+"}", token)
88+
tokenValues[token] = value
89+
index++
90+
}
91+
92+
fields := strings.Fields(replaced)
93+
args := make([]string, 0, len(fields))
94+
for _, field := range fields {
95+
if value, ok := tokenValues[field]; ok {
96+
args = append(args, value)
97+
continue
98+
}
99+
for token, value := range tokenValues {
100+
field = strings.ReplaceAll(field, token, value)
101+
}
102+
args = append(args, field)
103+
}
104+
105+
return args
106+
}
107+
76108
func buildLinuxTerminalCommand(terminalPath, clientPath, commands string) *exec.Cmd {
77109
terminalName := strings.ToLower(filepath.Base(strings.TrimSpace(terminalPath)))
78110
if terminalName == "" {
@@ -116,9 +148,17 @@ func awakenRDPCommand(filePath string, cfg *config.AppConfig) *exec.Cmd {
116148
if appItem == nil {
117149
return nil
118150
}
119-
args := splitArgsWithLiteral(appItem.ArgFormat, map[string]string{
120-
"{file}": filePath,
121-
})
151+
connectMap := map[string]string{
152+
"name": r.getName(),
153+
"protocol": r.Protocol,
154+
"username": r.getUserName(),
155+
"value": r.Value,
156+
"host": r.Host,
157+
"port": strconv.Itoa(r.Port),
158+
"file": filePath,
159+
}
160+
161+
args := buildArgsFromTemplate(appItem.ArgFormat, connectMap)
122162
cmd := exec.Command(appItem.Name, args...)
123163
return cmd
124164
}

go-client/pkg/plugin/loader.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,12 @@ func sanitizeState(state *pluginState) bool {
176176
}
177177
}
178178

179-
if runtime.GOOS == "linux" && state.Selections["remotedesktop:rdp"] == "builtin.mstsc" {
180-
delete(state.Selections, "remotedesktop:rdp")
181-
changed = true
179+
if runtime.GOOS == "linux" {
180+
switch state.Selections["remotedesktop:rdp"] {
181+
case "builtin.mstsc", "builtin.remmina":
182+
state.Selections["remotedesktop:rdp"] = "builtin.xfreerdp"
183+
changed = true
184+
}
182185
}
183186

184187
if state.Selections["filetransfer:sftp"] != "builtin.iterm-sftp" {

src-tauri/src/service/plugin.rs

Lines changed: 98 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,51 @@ impl PluginService {
1919
}
2020
}
2121

22+
fn resolve_resource_dir(app: &AppHandle, candidates: &[&str], marker: &str) -> Option<PathBuf> {
23+
for candidate in candidates {
24+
let Ok(path) = app
25+
.path()
26+
.resolve(candidate, tauri::path::BaseDirectory::Resource)
27+
else {
28+
continue;
29+
};
30+
31+
if path.join(marker).is_file() {
32+
log::info!("Resolved resource dir '{}' to {:?}", candidate, path);
33+
return Some(path);
34+
}
35+
}
36+
37+
None
38+
}
39+
40+
fn resolve_resource_file(app: &AppHandle, candidates: &[&str]) -> Option<PathBuf> {
41+
for candidate in candidates {
42+
let Ok(path) = app
43+
.path()
44+
.resolve(candidate, tauri::path::BaseDirectory::Resource)
45+
else {
46+
continue;
47+
};
48+
49+
if path.is_file() {
50+
log::info!("Resolved resource file '{}' to {:?}", candidate, path);
51+
return Some(path);
52+
}
53+
}
54+
55+
None
56+
}
57+
2258
fn resolve_builtin_dir(app: &AppHandle) -> Option<PathBuf> {
23-
let resource = app
24-
.path()
25-
.resolve(
26-
"resources/plugins/builtin",
27-
tauri::path::BaseDirectory::Resource,
28-
)
29-
.ok()
30-
.filter(|p| p.join("index.json").is_file())
31-
.or_else(|| {
32-
app.path()
33-
.resolve("plugins/builtin", tauri::path::BaseDirectory::Resource)
34-
.ok()
35-
.filter(|p| p.join("index.json").is_file())
36-
});
37-
38-
if resource.is_some() {
39-
return resource;
59+
let resource = Self::resolve_resource_dir(
60+
app,
61+
&["resources/plugins/builtin", "plugins/builtin", "builtin"],
62+
"index.json",
63+
);
64+
65+
if let Some(path) = resource {
66+
return Some(path);
4067
}
4168

4269
let cwd = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
@@ -45,40 +72,43 @@ impl PluginService {
4572
cwd.join("../plugins/builtin"),
4673
cwd.join("../../plugins/builtin"),
4774
];
48-
candidates
75+
let resolved = candidates
4976
.into_iter()
50-
.find(|p| p.join("index.json").is_file())
77+
.find(|p| p.join("index.json").is_file());
78+
79+
if let Some(path) = resolved.as_ref() {
80+
log::info!("Resolved builtin plugins from cwd fallback: {:?}", path);
81+
}
82+
83+
resolved
5184
}
5285

5386
fn resolve_defaults_path(app: &AppHandle) -> Option<PathBuf> {
54-
let resource = app
55-
.path()
56-
.resolve(
87+
let resource = Self::resolve_resource_file(
88+
app,
89+
&[
5790
"resources/plugins/plugins-state.defaults.json",
58-
tauri::path::BaseDirectory::Resource,
59-
)
60-
.ok()
61-
.filter(|p| p.is_file())
62-
.or_else(|| {
63-
app.path()
64-
.resolve(
65-
"plugins/plugins-state.defaults.json",
66-
tauri::path::BaseDirectory::Resource,
67-
)
68-
.ok()
69-
.filter(|p| p.is_file())
70-
});
71-
72-
if resource.is_some() {
73-
return resource;
91+
"plugins/plugins-state.defaults.json",
92+
"plugins-state.defaults.json",
93+
],
94+
);
95+
96+
if let Some(path) = resource {
97+
return Some(path);
7498
}
7599

76100
let cwd = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
77101
let candidates = [
78102
cwd.join("plugins/plugins-state.defaults.json"),
79103
cwd.join("../plugins/plugins-state.defaults.json"),
80104
];
81-
candidates.into_iter().find(|p| p.is_file())
105+
let resolved = candidates.into_iter().find(|p| p.is_file());
106+
107+
if let Some(path) = resolved.as_ref() {
108+
log::info!("Resolved plugin defaults from cwd fallback: {:?}", path);
109+
}
110+
111+
resolved
82112
}
83113

84114
fn read_json(path: &Path) -> Result<Value, String> {
@@ -95,7 +125,10 @@ impl PluginService {
95125

96126
let mut changed = false;
97127
if Self::os_key() != "windows" {
98-
if let Some(selections) = state_obj.get_mut("selections").and_then(|v| v.as_object_mut()) {
128+
if let Some(selections) = state_obj
129+
.get_mut("selections")
130+
.and_then(|v| v.as_object_mut())
131+
{
99132
for key in ["terminal:ssh", "terminal:telnet"] {
100133
if selections.get(key).and_then(|v| v.as_str()) == Some("builtin.putty") {
101134
selections.remove(key);
@@ -105,6 +138,24 @@ impl PluginService {
105138
}
106139
}
107140

141+
if Self::os_key() == "linux" {
142+
if let Some(selections) = state_obj
143+
.get_mut("selections")
144+
.and_then(|v| v.as_object_mut())
145+
{
146+
match selections.get("remotedesktop:rdp").and_then(|v| v.as_str()) {
147+
Some("builtin.mstsc") | Some("builtin.remmina") => {
148+
selections.insert(
149+
"remotedesktop:rdp".to_string(),
150+
Value::String("builtin.xfreerdp".to_string()),
151+
);
152+
changed = true;
153+
}
154+
_ => {}
155+
}
156+
}
157+
}
158+
108159
let should_remove_sftp_iterm = state_obj
109160
.get("selections")
110161
.and_then(|v| v.get("filetransfer:sftp"))
@@ -120,7 +171,9 @@ impl PluginService {
120171
.and_then(|v| v.get("builtin.iterm-sftp"))
121172
.and_then(|v| v.as_object())
122173
.map(|obj| {
123-
obj.get("enabled").and_then(|v| v.as_bool()).unwrap_or(false)
174+
obj.get("enabled")
175+
.and_then(|v| v.as_bool())
176+
.unwrap_or(false)
124177
|| obj
125178
.get("path")
126179
.and_then(|v| v.as_str())
@@ -133,7 +186,10 @@ impl PluginService {
133186
return changed;
134187
}
135188

136-
if let Some(selections) = state_obj.get_mut("selections").and_then(|v| v.as_object_mut()) {
189+
if let Some(selections) = state_obj
190+
.get_mut("selections")
191+
.and_then(|v| v.as_object_mut())
192+
{
137193
if selections.remove("filetransfer:sftp").is_some() {
138194
changed = true;
139195
}

src-tauri/src/setup/tray.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,7 @@ where
129129
true,
130130
None::<&str>,
131131
)?;
132-
let quit_i = MenuItem::with_id(
133-
app,
134-
"quit",
135-
labels.quit_label.as_str(),
136-
true,
137-
None::<&str>,
138-
)?;
132+
let quit_i = MenuItem::with_id(app, "quit", labels.quit_label.as_str(), true, None::<&str>)?;
139133

140134
Menu::with_items(
141135
app,

src-tauri/src/transcode/transcode.rs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
use crate::transcode::encoder::{create_encoder, H264Encoder};
44
use crate::transcode::parser::Parser;
55
use crate::transcode::renderer::Renderer;
6-
use crate::transcode::{
7-
bitrate_for_resolution, compute_target_dimensions, OutputResolution,
8-
};
6+
use crate::transcode::{bitrate_for_resolution, compute_target_dimensions, OutputResolution};
97
use fast_image_resize::images::{Image, ImageRef};
108
use fast_image_resize::PixelType::U8x3;
119
use fast_image_resize::{FilterType, ResizeAlg, ResizeOptions, Resizer};
@@ -429,18 +427,12 @@ pub fn transcode_to_mp4(
429427
&& (enc_w_frame != rw as usize
430428
|| enc_h_frame != rh as usize)
431429
{
432-
let src_view = ImageRef::new(
433-
rw,
434-
rh,
435-
&frame_buf[..src_len],
436-
U8x3,
437-
)
438-
.map_err(|e| format!("create image view: {}", e))?;
430+
let src_view =
431+
ImageRef::new(rw, rh, &frame_buf[..src_len], U8x3)
432+
.map_err(|e| format!("create image view: {}", e))?;
439433

440-
rgba_buf.resize(
441-
(enc_w_frame * enc_h_frame * 3) as usize,
442-
0,
443-
);
434+
rgba_buf
435+
.resize((enc_w_frame * enc_h_frame * 3) as usize, 0);
444436
let mut dst_image = Image::from_slice_u8(
445437
enc_w_frame as u32,
446438
enc_h_frame as u32,
@@ -463,20 +455,17 @@ pub fn transcode_to_mp4(
463455
src_w = enc_w_frame;
464456
src_h = enc_h_frame;
465457
} else {
466-
let mut cropped = vec![
467-
255u8;
468-
(enc_w_frame * enc_h_frame * 3) as usize
469-
];
458+
let mut cropped =
459+
vec![255u8; (enc_w_frame * enc_h_frame * 3) as usize];
470460
let src_stride = rw as usize * 3;
471461
let dst_stride = enc_w_frame * 3;
472462
for y in 0..enc_h_frame.min(rh as usize) {
473463
let src_off = y * src_stride;
474464
let dst_off = y * dst_stride;
475465
let copy_len = dst_stride.min(src_stride);
476-
cropped[dst_off..dst_off + copy_len]
477-
.copy_from_slice(
478-
&frame_buf[src_off..src_off + copy_len],
479-
);
466+
cropped[dst_off..dst_off + copy_len].copy_from_slice(
467+
&frame_buf[src_off..src_off + copy_len],
468+
);
480469
}
481470
rgb_data = cropped.into();
482471
src_w = enc_w_frame;
@@ -580,7 +569,11 @@ fn parse_and_build_timeline(guac_data: &[u8]) -> Result<TimelineInfo, String> {
580569
instruction_offset = parser.current_offset();
581570
}
582571

583-
Ok(TimelineInfo { frames, max_width: max_w, max_height: max_h })
572+
Ok(TimelineInfo {
573+
frames,
574+
max_width: max_w,
575+
max_height: max_h,
576+
})
584577
}
585578

586579
fn encode_chunks(

ui/app.vue

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const LOCALE_PREFIX_RE = /^\/[a-z]{2}(?:-[A-Z]{2})?(?=\/|$)/;
1111
1212
const route = useRoute();
1313
14-
const { isMacOS } = usePlatform();
14+
const { isLinux, isMacOS, isWindows } = usePlatform();
1515
const { locale, setLocale } = useI18n();
1616
const { userTheme, applyThemePreference, applySystemThemePreference } = useThemeAdapter();
1717
@@ -27,18 +27,25 @@ const unlistenFont = ref<UnlistenFn | null>(null);
2727
const backgroundColor = computed(() => {
2828
const isDark = userTheme.value === "dark";
2929
30-
// 只在 macOS 下设置透明度
3130
if (isMacOS.value) {
3231
return isDark ? "rgba(30, 30, 30, 0.8)" : "rgba(240, 240, 240, 0.4)";
33-
} else {
34-
return isDark ? "rgba(30, 30, 30, 0.8)" : "rgba(240, 240, 240, 0.83)";
3532
}
33+
34+
if (isWindows.value) {
35+
return isDark ? "#1e1e1e" : "#f4f4f5";
36+
}
37+
38+
if (isLinux.value) {
39+
return isDark ? "#1e1e1e" : "#f0f0f0";
40+
}
41+
42+
return isDark ? "#1e1e1e" : "#f4f4f5";
3643
});
3744
3845
const pageKey = computed(() => route.path.replace(LOCALE_PREFIX_RE, ""));
3946
4047
const platformClass = computed(() => {
41-
const platformKey = isMacOS.value ? "darwin" : "windows";
48+
const platformKey = isMacOS.value ? "darwin" : isLinux.value ? "linux" : isWindows.value ? "windows" : "unknown";
4249
return `platform-${platformKey}`;
4350
});
4451

0 commit comments

Comments
 (0)