mirror of https://github.com/ospab/ostp.git
fix(gui): honest TUN error on Linux, and a window that can be resized
Reported from the Linux GUI: it asked for "helper.exe" on Linux, and the
window was tiny.
The helper name had ".exe" hardcoded in every lookup path, so on Linux the
search could only ever fail. Fixing the name alone would have been misleading
though, because TUN mode does not work on Linux for a deeper reason:
launch_as_admin is `bail!("Windows only.")` outside Windows, and the release
workflow only builds ostp-tun-helper in the Windows GUI job. So the feature is
Windows-only, and the message now says exactly that and points at proxy mode,
instead of surfacing as a missing file named after a Windows executable —
which reads like a packaging mistake rather than an unimplemented feature. The
name is still resolved per-platform for when Linux elevation does land.
The window was 360x680 and `resizable: false`. Windows scales that by DPI, but
WebKitGTK on a HiDPI Linux display renders it close to raw pixels, giving a
postage-stamp window the user then could not resize. It is now resizable with
a sensible minimum, and .app-root caps and centres the column so a wider
window keeps the intended narrow layout instead of stretching the controls.
This commit is contained in:
parent
e483af541f
commit
8a1426ecf5
|
|
@ -625,13 +625,30 @@ async fn start_tun_via_helper(
|
||||||
raw: &ClientConfigRaw,
|
raw: &ClientConfigRaw,
|
||||||
app: tauri::AppHandle,
|
app: tauri::AppHandle,
|
||||||
) -> Result<bool, String> {
|
) -> Result<bool, String> {
|
||||||
|
// TUN mode goes through a privileged helper, and the only elevation path
|
||||||
|
// implemented is the Windows UAC one (see launch_as_admin). The helper is
|
||||||
|
// also not built for other platforms by the release workflow. Say that
|
||||||
|
// plainly and up front: previously this fell through to the helper lookup
|
||||||
|
// and surfaced as a missing-file error naming a Windows executable, which
|
||||||
|
// on Linux reads as a packaging mistake rather than an unimplemented
|
||||||
|
// feature.
|
||||||
|
if !cfg!(windows) {
|
||||||
|
return Err(
|
||||||
|
"TUN mode is currently Windows-only: it needs a privileged helper, and elevation \
|
||||||
|
for it is only implemented on Windows. Use proxy mode (SOCKS5/HTTP) on this \
|
||||||
|
platform."
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let port = {
|
let port = {
|
||||||
let listener = std::net::TcpListener::bind("127.0.0.1:0").map_err(|e| format!("Bind error: {}", e))?;
|
let listener = std::net::TcpListener::bind("127.0.0.1:0").map_err(|e| format!("Bind error: {}", e))?;
|
||||||
listener.local_addr().unwrap().port()
|
listener.local_addr().unwrap().port()
|
||||||
};
|
};
|
||||||
|
|
||||||
let auth_token = rand::random::<u64>().to_string();
|
let auth_token = rand::random::<u64>().to_string();
|
||||||
let helper_exe = find_helper_exe().ok_or_else(|| "ostp-tun-helper.exe not found.".to_string())?;
|
let helper_exe = find_helper_exe()
|
||||||
|
.ok_or_else(|| format!("{HELPER_EXE_NAME} not found next to the app or in target/."))?;
|
||||||
launch_as_admin(&helper_exe, &auth_token, port).map_err(|e| format!("Failed to launch helper: {}", e))?;
|
launch_as_admin(&helper_exe, &auth_token, port).map_err(|e| format!("Failed to launch helper: {}", e))?;
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(1500)).await;
|
tokio::time::sleep(std::time::Duration::from_millis(1500)).await;
|
||||||
|
|
||||||
|
|
@ -705,21 +722,32 @@ struct HelperPipeState {
|
||||||
error_msg: Option<String>,
|
error_msg: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Executable name of the TUN helper for the current platform.
|
||||||
|
///
|
||||||
|
/// The ".exe" suffix was hardcoded, so on Linux every lookup below searched for
|
||||||
|
/// a file that cannot exist and the GUI reported the helper as missing on a
|
||||||
|
/// platform where it ships without an extension.
|
||||||
|
const HELPER_EXE_NAME: &str = if cfg!(windows) {
|
||||||
|
"ostp-tun-helper.exe"
|
||||||
|
} else {
|
||||||
|
"ostp-tun-helper"
|
||||||
|
};
|
||||||
|
|
||||||
fn find_helper_exe() -> Option<PathBuf> {
|
fn find_helper_exe() -> Option<PathBuf> {
|
||||||
if let Ok(exe) = std::env::current_exe() {
|
if let Ok(exe) = std::env::current_exe() {
|
||||||
if let Some(dir) = exe.parent() {
|
if let Some(dir) = exe.parent() {
|
||||||
// 1. Release/Production adjacent
|
// 1. Release/Production adjacent
|
||||||
let candidate = dir.join("ostp-tun-helper.exe");
|
let candidate = dir.join(HELPER_EXE_NAME);
|
||||||
if candidate.exists() { return Some(candidate); }
|
if candidate.exists() { return Some(candidate); }
|
||||||
|
|
||||||
// 2. Tauri target directory fallback
|
// 2. Tauri target directory fallback
|
||||||
// e.g. from ostp-gui/src-tauri/target/debug/deps/
|
// e.g. from ostp-gui/src-tauri/target/debug/deps/
|
||||||
let mut parent = dir;
|
let mut parent = dir;
|
||||||
while let Some(p) = parent.parent() {
|
while let Some(p) = parent.parent() {
|
||||||
if p.file_name().map(|n| n == "target").unwrap_or(false) {
|
if p.file_name().map(|n| n == "target").unwrap_or(false) {
|
||||||
let deb = p.join("debug").join("ostp-tun-helper.exe");
|
let deb = p.join("debug").join(HELPER_EXE_NAME);
|
||||||
if deb.exists() { return Some(deb); }
|
if deb.exists() { return Some(deb); }
|
||||||
let rel = p.join("release").join("ostp-tun-helper.exe");
|
let rel = p.join("release").join(HELPER_EXE_NAME);
|
||||||
if rel.exists() { return Some(rel); }
|
if rel.exists() { return Some(rel); }
|
||||||
}
|
}
|
||||||
parent = p;
|
parent = p;
|
||||||
|
|
@ -729,13 +757,13 @@ fn find_helper_exe() -> Option<PathBuf> {
|
||||||
// 3. Current working directory target fallback
|
// 3. Current working directory target fallback
|
||||||
let cwd = std::env::current_dir().unwrap_or_default();
|
let cwd = std::env::current_dir().unwrap_or_default();
|
||||||
let candidates = [
|
let candidates = [
|
||||||
cwd.join("ostp-tun-helper.exe"),
|
cwd.join(HELPER_EXE_NAME),
|
||||||
cwd.join("target").join("debug").join("ostp-tun-helper.exe"),
|
cwd.join("target").join("debug").join(HELPER_EXE_NAME),
|
||||||
cwd.join("target").join("release").join("ostp-tun-helper.exe"),
|
cwd.join("target").join("release").join(HELPER_EXE_NAME),
|
||||||
cwd.join("..").join("target").join("debug").join("ostp-tun-helper.exe"),
|
cwd.join("..").join("target").join("debug").join(HELPER_EXE_NAME),
|
||||||
cwd.join("..").join("target").join("release").join("ostp-tun-helper.exe"),
|
cwd.join("..").join("target").join("release").join(HELPER_EXE_NAME),
|
||||||
cwd.join("..").join("..").join("target").join("debug").join("ostp-tun-helper.exe"),
|
cwd.join("..").join("..").join("target").join("debug").join(HELPER_EXE_NAME),
|
||||||
cwd.join("..").join("..").join("target").join("release").join("ostp-tun-helper.exe"),
|
cwd.join("..").join("..").join("target").join("release").join(HELPER_EXE_NAME),
|
||||||
];
|
];
|
||||||
for path in &candidates {
|
for path in &candidates {
|
||||||
if path.exists() { return Some(path.clone()); }
|
if path.exists() { return Some(path.clone()); }
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,11 @@
|
||||||
"windows": [
|
"windows": [
|
||||||
{
|
{
|
||||||
"title": "OSTP",
|
"title": "OSTP",
|
||||||
"width": 360,
|
"width": 400,
|
||||||
"height": 680,
|
"height": 720,
|
||||||
"resizable": false
|
"minWidth": 360,
|
||||||
|
"minHeight": 560,
|
||||||
|
"resizable": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,13 @@ a { text-decoration: none; }
|
||||||
.app-root {
|
.app-root {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
/* The window is resizable so users on desktops where the toolkit does not
|
||||||
|
apply our DPI scaling (WebKitGTK on HiDPI Linux renders the configured
|
||||||
|
size as raw pixels, giving a postage-stamp window) can size it themselves.
|
||||||
|
Capping and centring the column keeps the intended narrow layout instead of
|
||||||
|
stretching controls across a wide window. */
|
||||||
|
max-width: 460px;
|
||||||
|
margin: 0 auto;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue