Skip to content

Commit d3aff51

Browse files
committed
fix browser selection
1 parent 5fb8654 commit d3aff51

File tree

2 files changed

+89
-76
lines changed

2 files changed

+89
-76
lines changed

src-tauri/src/browser_manager.rs

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -144,87 +144,52 @@ pub async fn get_running_instance(target_browser_path: &str) -> Option<String> {
144144
** launch a fresh instance
145145
*/
146146
pub async fn launch_new_instance(target_browser_path: &str, port: u16) -> Result<String, String> {
147-
let allowed_origins = get_allowed_origins();
148147
let is_dev = cfg!(debug_assertions);
149148

150149
println!("launching browser: {target_browser_path} with --remote-debugging-port={port}");
151150
println!(
152151
"environment: {} mode",
153152
if is_dev { "development" } else { "production" }
154153
);
155-
println!("allowed origins: {allowed_origins}");
154+
println!("allowed origins: {}", get_allowed_origins());
156155

157156
let lower = target_browser_path.to_lowercase();
158157
let is_edge = lower.contains("edge") || lower.contains("msedge");
159158
let is_chrome = lower.contains("chrome");
160159
let is_arc = lower.contains("arc");
161160

162-
println!("is_arc: {is_arc} running on port {port}");
163-
164161
let mut command = Command::new(target_browser_path);
165162
command
166163
.arg(format!("--remote-debugging-port={port}"))
167164
.arg("--remote-debugging-address=127.0.0.1")
168-
.arg(format!("--remote-allow-origins={allowed_origins}"))
165+
.arg(format!("--remote-allow-origins={}", get_allowed_origins()))
169166
.arg("--no-first-run")
170167
.arg("--no-default-browser-check")
171168
.arg("--disable-background-timer-throttling")
172169
.arg("--disable-backgrounding-occluded-windows")
173170
.arg("--disable-renderer-backgrounding")
174-
.arg("--enable-automation"); // for chromium forks
171+
.arg("--enable-automation");
175172

176173
if is_chrome {
177-
command
178-
.arg("--disable-background-networking")
179-
.arg("--disable-default-apps")
180-
.arg("--disable-sync")
181-
.arg("--disable-translate")
182-
.arg("--disable-ipc-flooding-protection");
183-
#[cfg(target_os = "windows")]
184-
command.arg("--user-data-dir=C:\\temp\\chrome-debug-profile");
185174
#[cfg(any(target_os = "macos", target_os = "linux"))]
186175
command.arg("--user-data-dir=/tmp/chrome-debug-profile");
187176
} else if is_edge {
188-
command
189-
.arg("--disable-background-networking")
190-
.arg("--disable-default-apps");
191-
#[cfg(target_os = "windows")]
192-
command.arg("--user-data-dir=C:\\temp\\edge-debug-profile");
193177
#[cfg(any(target_os = "macos", target_os = "linux"))]
194178
command.arg("--user-data-dir=/tmp/edge-debug-profile");
195179
} else if is_arc {
196-
command
197-
.arg("--disable-background-networking")
198-
.arg("--disable-default-apps");
199-
#[cfg(target_os = "windows")]
200-
command.arg("--user-data-dir=C:\\temp\\arc-debug-profile");
201180
#[cfg(any(target_os = "macos", target_os = "linux"))]
202181
command.arg("--user-data-dir=/tmp/arc-debug-profile");
203-
204-
let program = command.get_program();
205-
let args: Vec<&std::ffi::OsStr> = command.get_args().collect();
206-
println!("🚀 Final Arc browser command:");
207-
println!(" Program: {:?}", program);
208-
println!(" Arguments: {:?}", args);
209-
}
210-
211-
if is_dev {
212-
command
213-
.arg("--disable-features=VizDisplayCompositor")
214-
.arg("--disable-background-networking")
215-
.arg("--disable-default-apps")
216-
.arg("--allow-running-insecure-content");
217182
}
218183

184+
/*
185+
** give the browser a moment to finish booting
186+
*/
219187
let mut child_process = command
220188
.stdout(Stdio::piped())
221189
.stderr(Stdio::piped())
222190
.spawn()
223191
.map_err(|e| format!("failed to launch browser: {e}"))?;
224192

225-
/*
226-
** give the browser a moment to finish booting
227-
*/
228193
tokio::time::sleep(Duration::from_secs(2)).await;
229194

230195
match child_process.try_wait() {

src-tauri/src/commands.rs

Lines changed: 83 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,38 @@
11
use crate::apps::call;
2-
use crate::browser_manager::{get_running_instance, launch_new_instance, sunset_browser_instance};
2+
use crate::browser_manager::{get_running_instance, launch_new_instance, sunset_browser_instance, MANAGED_BROWSER};
33
use crate::network::{
44
create_new_page, determine_browser_type, extract_port_from_ws_url, find_free_port,
5-
get_browser_info, scan_for_existing_browser_instances,
5+
get_browser_info, get_browser_websocket_url, scan_for_existing_browser_instances,
66
};
77
use crate::platform::detect_browsers;
8-
use crate::sketchs::BrowserConfig;
8+
use crate::sketchs::{BrowserConfig, ManageableBrowserInstance};
99
use crate::sketchs_browser::WebsiteSkills;
1010
use crate::skills::download_skill_json;
1111

12-
fn is_equivalent_selection(selected: &str, running: &str) -> bool {
13-
if selected == running {
14-
return true;
12+
const CHROME_PORT: u16 = 9522;
13+
const EDGE_PORT: u16 = 9523;
14+
const ARC_PORT: u16 = 9524;
15+
16+
fn browser_id_for_path(path: &str) -> &'static str {
17+
let lower = path.to_lowercase();
18+
if lower.contains("edge") || lower.contains("msedge") {
19+
"edge"
20+
} else if lower.contains("arc") {
21+
"arc"
22+
} else {
23+
"chrome"
1524
}
25+
}
26+
fn static_port_for(id: &str) -> u16 {
27+
match id {
28+
"edge" => EDGE_PORT,
29+
"arc" => ARC_PORT,
30+
_ => CHROME_PORT,
31+
}
32+
}
33+
34+
fn is_equivalent_selection(selected: &str, running: &str) -> bool {
35+
if selected == running { return true; }
1636
selected == "arc" && running == "chrome"
1737
}
1838

@@ -30,12 +50,8 @@ pub async fn fetch_available_browsers() -> Result<Vec<BrowserConfig>, String> {
3050
}
3151

3252
#[tauri::command]
33-
pub async fn validate_connection(
34-
ws_endpoint: String,
35-
selected_browser_path: String,
36-
) -> Result<String, String> {
53+
pub async fn validate_connection(ws_endpoint: String, selected_browser_path: String) -> Result<String, String> {
3754
let port = extract_port_from_ws_url(&ws_endpoint)?;
38-
3955
let (browser_string, user_agent) = get_browser_info(&port).await?;
4056
let running_browser_type = determine_browser_type(&browser_string, &user_agent);
4157

@@ -116,48 +132,80 @@ pub async fn launch_browser(browser_path: Option<String>) -> Result<String, Stri
116132
.ok_or_else(|| "No browser found".to_string())?
117133
};
118134

135+
let selected_id = browser_id_for_path(&target_browser_path);
136+
let port = static_port_for(selected_id);
137+
119138
/*
120-
** try to reuse an existing instance
139+
** close any managed instance to free the static port.
121140
*/
122-
if let Some(ws_url) = get_running_instance(&target_browser_path).await {
123-
if let Ok(port_str) = extract_port_from_ws_url(&ws_url) {
124-
if let Ok(port) = port_str.parse::<u16>() {
125-
let _ = create_new_page(port, Some("https://www.google.com")).await;
141+
{
142+
let mut guard = MANAGED_BROWSER.lock().await;
143+
if let Some(mut inst) = guard.take() {
144+
if inst.path != target_browser_path || inst.port != port {
145+
if let Some(mut child) = inst.child.take() {
146+
let _ = child.kill();
147+
let _ = child.wait();
148+
}
149+
} else {
150+
*guard = Some(inst);
126151
}
127152
}
128-
return Ok(ws_url);
129153
}
130154

131155
/*
132-
** Force Arc => 9222, others => first free from 9222 upward
156+
** probe the static port (is anything already listening?)
133157
*/
134-
let is_arc = target_browser_path.to_lowercase().contains("arc");
135-
let port = if is_arc {
136-
match get_browser_info("9222").await {
137-
Ok((browser_string, _ua)) => {
138-
if let Some(ws) = scan_for_existing_browser_instances("arc").await {
139-
return Ok(ws);
158+
match get_browser_info(&port.to_string()).await {
159+
Ok((browser_string, user_agent)) => {
160+
let running = determine_browser_type(&browser_string, &user_agent);
161+
if is_equivalent_selection(selected_id, &running) {
162+
/*
163+
** reuse existing instance on the static port
164+
*/
165+
let ws_url = get_browser_websocket_url(port, 20, 500)
166+
.await
167+
.map_err(|e| format!("Failed to obtain DevTools websocket: {e}"))?;
168+
169+
/*
170+
** remember (not launched by us)
171+
*/
172+
{
173+
let mut managed = MANAGED_BROWSER.lock().await;
174+
*managed = Some(ManageableBrowserInstance {
175+
path: target_browser_path.clone(),
176+
port,
177+
ws_url: ws_url.clone(),
178+
child: None,
179+
launched_by_app: false,
180+
});
140181
}
182+
let _ = create_new_page(port, Some("https://www.google.com")).await;
183+
184+
return Ok(ws_url);
185+
} else {
141186
return Err(format!(
142-
"Port 9222 already in use by: {browser_string}. Close it and retry Arc."
187+
"Static port {port} is already occupied by another browser ({running}). Close it and retry."
143188
));
144189
}
145-
Err(_) => 9222,
146190
}
147-
} else {
148-
find_free_port(9222).ok_or_else(|| "Failed to find a free port".to_string())?
149-
};
191+
Err(_) => {
192+
/*
193+
** nothing on that port — proceed to launch a fresh instance on it
194+
*/
195+
}
196+
}
150197

151198
/*
152-
** Launch
199+
** launch on the static port
153200
*/
154201
match launch_new_instance(&target_browser_path, port).await {
155202
Ok(ws_url) => {
156-
if !is_arc {
157-
if let Ok(pstr) = extract_port_from_ws_url(&ws_url) {
158-
if let Ok(p) = pstr.parse::<u16>() {
159-
let _ = create_new_page(p, Some("https://www.google.com")).await;
160-
}
203+
/*
204+
** starter tab (keeps process alive / makes pages() non-empty)
205+
*/
206+
if let Ok(pstr) = extract_port_from_ws_url(&ws_url) {
207+
if let Ok(p) = pstr.parse::<u16>() {
208+
let _ = create_new_page(p, Some("https://www.google.com")).await;
161209
}
162210
}
163211
Ok(ws_url)

0 commit comments

Comments
 (0)