pub struct ControlledApp { /* private fields */ }Expand description
A launched application with capture and input methods bound to its exact seat connection.
Implementations§
Source§impl ControlledApp
impl ControlledApp
Sourcepub fn pid(&self) -> u32
pub fn pid(&self) -> u32
Spawned application process identifier.
Examples found in repository?
examples/basic.rs (line 20)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut arguments = std::env::args_os().skip(1);
7 let program = arguments
8 .next()
9 .unwrap_or_else(|| "gnome-calculator".into());
10 let harness = ComputerUse::builder()
11 .native_timeout(Duration::from_secs(8))
12 .fallback_timeout(Duration::from_secs(30))
13 .bridge_geometry(1280, 800)
14 .build()?;
15 let mut app = harness.launch(LaunchConfig::new(program).args(arguments))?;
16
17 let frame = app.capture()?;
18 println!(
19 "controlled pid={} transport={:?} frame={}x{}",
20 app.pid(),
21 app.transport(),
22 frame.width,
23 frame.height
24 );
25 frame.image.save("agent-seat-frame.png")?;
26
27 // Harmlessly focus the center of the captured app to prove pointer input.
28 app.click(
29 f64::from(frame.width) / 2.0,
30 f64::from(frame.height) / 2.0,
31 PointerButton::Left,
32 1,
33 )?;
34
35 app.stop();
36 Ok(())
37}Sourcepub fn transport(&self) -> Transport
pub fn transport(&self) -> Transport
Transport selected after launch probing.
Examples found in repository?
examples/basic.rs (line 21)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut arguments = std::env::args_os().skip(1);
7 let program = arguments
8 .next()
9 .unwrap_or_else(|| "gnome-calculator".into());
10 let harness = ComputerUse::builder()
11 .native_timeout(Duration::from_secs(8))
12 .fallback_timeout(Duration::from_secs(30))
13 .bridge_geometry(1280, 800)
14 .build()?;
15 let mut app = harness.launch(LaunchConfig::new(program).args(arguments))?;
16
17 let frame = app.capture()?;
18 println!(
19 "controlled pid={} transport={:?} frame={}x{}",
20 app.pid(),
21 app.transport(),
22 frame.width,
23 frame.height
24 );
25 frame.image.save("agent-seat-frame.png")?;
26
27 // Harmlessly focus the center of the captured app to prove pointer input.
28 app.click(
29 f64::from(frame.width) / 2.0,
30 f64::from(frame.height) / 2.0,
31 PointerButton::Left,
32 1,
33 )?;
34
35 app.stop();
36 Ok(())
37}More examples
examples/agent_loop.rs (line 23)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 let mut args = env::args().skip(1);
12 let program = args
13 .next()
14 .unwrap_or_else(|| "gnome-calculator".to_string());
15
16 let mut config = LaunchConfig::new(&program);
17 for extra in args {
18 config = config.arg(extra);
19 }
20
21 let harness = ComputerUse::new()?;
22 let mut app = harness.launch(config)?;
23 println!("launched {program} via {:?}", app.transport());
24
25 // 1. Perceive: capture the initial frame.
26 let before = app.capture()?;
27 before.image.save("agent-loop-before.png")?;
28 println!(
29 "captured {}x{} -> agent-loop-before.png",
30 before.image.width(),
31 before.image.height()
32 );
33
34 // 2. Act: focus, select-all, and type, exercising keyboard + text paths.
35 app.click(
36 before.image.width() as f64 / 2.0,
37 before.image.height() as f64 / 2.0,
38 PointerButton::Left,
39 1,
40 )?;
41 app.press_key("ctrl+a")?;
42 app.type_text("agent-seat-linux")?;
43
44 // 3. Perceive again: capture the post-action frame.
45 let after = app.capture()?;
46 after.image.save("agent-loop-after.png")?;
47 println!(
48 "captured {}x{} -> agent-loop-after.png",
49 after.image.width(),
50 after.image.height()
51 );
52
53 // 4. Teardown: stop the app, then close the seat.
54 app.stop();
55 harness.close();
56 println!("done");
57 Ok(())
58}Sourcepub fn capture(&self) -> Result<CapturedFrame>
pub fn capture(&self) -> Result<CapturedFrame>
Capture the application’s current window-scoped frame.
Examples found in repository?
examples/basic.rs (line 17)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut arguments = std::env::args_os().skip(1);
7 let program = arguments
8 .next()
9 .unwrap_or_else(|| "gnome-calculator".into());
10 let harness = ComputerUse::builder()
11 .native_timeout(Duration::from_secs(8))
12 .fallback_timeout(Duration::from_secs(30))
13 .bridge_geometry(1280, 800)
14 .build()?;
15 let mut app = harness.launch(LaunchConfig::new(program).args(arguments))?;
16
17 let frame = app.capture()?;
18 println!(
19 "controlled pid={} transport={:?} frame={}x{}",
20 app.pid(),
21 app.transport(),
22 frame.width,
23 frame.height
24 );
25 frame.image.save("agent-seat-frame.png")?;
26
27 // Harmlessly focus the center of the captured app to prove pointer input.
28 app.click(
29 f64::from(frame.width) / 2.0,
30 f64::from(frame.height) / 2.0,
31 PointerButton::Left,
32 1,
33 )?;
34
35 app.stop();
36 Ok(())
37}More examples
examples/agent_loop.rs (line 26)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 let mut args = env::args().skip(1);
12 let program = args
13 .next()
14 .unwrap_or_else(|| "gnome-calculator".to_string());
15
16 let mut config = LaunchConfig::new(&program);
17 for extra in args {
18 config = config.arg(extra);
19 }
20
21 let harness = ComputerUse::new()?;
22 let mut app = harness.launch(config)?;
23 println!("launched {program} via {:?}", app.transport());
24
25 // 1. Perceive: capture the initial frame.
26 let before = app.capture()?;
27 before.image.save("agent-loop-before.png")?;
28 println!(
29 "captured {}x{} -> agent-loop-before.png",
30 before.image.width(),
31 before.image.height()
32 );
33
34 // 2. Act: focus, select-all, and type, exercising keyboard + text paths.
35 app.click(
36 before.image.width() as f64 / 2.0,
37 before.image.height() as f64 / 2.0,
38 PointerButton::Left,
39 1,
40 )?;
41 app.press_key("ctrl+a")?;
42 app.type_text("agent-seat-linux")?;
43
44 // 3. Perceive again: capture the post-action frame.
45 let after = app.capture()?;
46 after.image.save("agent-loop-after.png")?;
47 println!(
48 "captured {}x{} -> agent-loop-after.png",
49 after.image.width(),
50 after.image.height()
51 );
52
53 // 4. Teardown: stop the app, then close the seat.
54 app.stop();
55 harness.close();
56 println!("done");
57 Ok(())
58}Sourcepub fn click(
&self,
x: f64,
y: f64,
button: PointerButton,
count: u32,
) -> Result<()>
pub fn click( &self, x: f64, y: f64, button: PointerButton, count: u32, ) -> Result<()>
Click at frame-local coordinates.
Examples found in repository?
examples/basic.rs (lines 28-33)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut arguments = std::env::args_os().skip(1);
7 let program = arguments
8 .next()
9 .unwrap_or_else(|| "gnome-calculator".into());
10 let harness = ComputerUse::builder()
11 .native_timeout(Duration::from_secs(8))
12 .fallback_timeout(Duration::from_secs(30))
13 .bridge_geometry(1280, 800)
14 .build()?;
15 let mut app = harness.launch(LaunchConfig::new(program).args(arguments))?;
16
17 let frame = app.capture()?;
18 println!(
19 "controlled pid={} transport={:?} frame={}x{}",
20 app.pid(),
21 app.transport(),
22 frame.width,
23 frame.height
24 );
25 frame.image.save("agent-seat-frame.png")?;
26
27 // Harmlessly focus the center of the captured app to prove pointer input.
28 app.click(
29 f64::from(frame.width) / 2.0,
30 f64::from(frame.height) / 2.0,
31 PointerButton::Left,
32 1,
33 )?;
34
35 app.stop();
36 Ok(())
37}More examples
examples/agent_loop.rs (lines 35-40)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 let mut args = env::args().skip(1);
12 let program = args
13 .next()
14 .unwrap_or_else(|| "gnome-calculator".to_string());
15
16 let mut config = LaunchConfig::new(&program);
17 for extra in args {
18 config = config.arg(extra);
19 }
20
21 let harness = ComputerUse::new()?;
22 let mut app = harness.launch(config)?;
23 println!("launched {program} via {:?}", app.transport());
24
25 // 1. Perceive: capture the initial frame.
26 let before = app.capture()?;
27 before.image.save("agent-loop-before.png")?;
28 println!(
29 "captured {}x{} -> agent-loop-before.png",
30 before.image.width(),
31 before.image.height()
32 );
33
34 // 2. Act: focus, select-all, and type, exercising keyboard + text paths.
35 app.click(
36 before.image.width() as f64 / 2.0,
37 before.image.height() as f64 / 2.0,
38 PointerButton::Left,
39 1,
40 )?;
41 app.press_key("ctrl+a")?;
42 app.type_text("agent-seat-linux")?;
43
44 // 3. Perceive again: capture the post-action frame.
45 let after = app.capture()?;
46 after.image.save("agent-loop-after.png")?;
47 println!(
48 "captured {}x{} -> agent-loop-after.png",
49 after.image.width(),
50 after.image.height()
51 );
52
53 // 4. Teardown: stop the app, then close the seat.
54 app.stop();
55 harness.close();
56 println!("done");
57 Ok(())
58}Sourcepub fn click_with_modifiers(
&self,
x: f64,
y: f64,
button: PointerButton,
count: u32,
modifiers: &str,
) -> Result<()>
pub fn click_with_modifiers( &self, x: f64, y: f64, button: PointerButton, count: u32, modifiers: &str, ) -> Result<()>
Click while holding a +-separated modifier list such as ctrl+shift.
Sourcepub fn scroll(&self, x: f64, y: f64, dx: i32, dy: i32) -> Result<()>
pub fn scroll(&self, x: f64, y: f64, dx: i32, dy: i32) -> Result<()>
Inject a pixel scroll delta at frame-local coordinates.
Sourcepub fn press_key(&self, combination: &str) -> Result<()>
pub fn press_key(&self, combination: &str) -> Result<()>
Press a key combination such as ctrl+shift+a.
Examples found in repository?
examples/agent_loop.rs (line 41)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 let mut args = env::args().skip(1);
12 let program = args
13 .next()
14 .unwrap_or_else(|| "gnome-calculator".to_string());
15
16 let mut config = LaunchConfig::new(&program);
17 for extra in args {
18 config = config.arg(extra);
19 }
20
21 let harness = ComputerUse::new()?;
22 let mut app = harness.launch(config)?;
23 println!("launched {program} via {:?}", app.transport());
24
25 // 1. Perceive: capture the initial frame.
26 let before = app.capture()?;
27 before.image.save("agent-loop-before.png")?;
28 println!(
29 "captured {}x{} -> agent-loop-before.png",
30 before.image.width(),
31 before.image.height()
32 );
33
34 // 2. Act: focus, select-all, and type, exercising keyboard + text paths.
35 app.click(
36 before.image.width() as f64 / 2.0,
37 before.image.height() as f64 / 2.0,
38 PointerButton::Left,
39 1,
40 )?;
41 app.press_key("ctrl+a")?;
42 app.type_text("agent-seat-linux")?;
43
44 // 3. Perceive again: capture the post-action frame.
45 let after = app.capture()?;
46 after.image.save("agent-loop-after.png")?;
47 println!(
48 "captured {}x{} -> agent-loop-after.png",
49 after.image.width(),
50 after.image.height()
51 );
52
53 // 4. Teardown: stop the app, then close the seat.
54 app.stop();
55 harness.close();
56 println!("done");
57 Ok(())
58}Sourcepub fn type_text(&self, text: &str) -> Result<()>
pub fn type_text(&self, text: &str) -> Result<()>
Type Unicode text through the application’s private seat.
Examples found in repository?
examples/agent_loop.rs (line 42)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 let mut args = env::args().skip(1);
12 let program = args
13 .next()
14 .unwrap_or_else(|| "gnome-calculator".to_string());
15
16 let mut config = LaunchConfig::new(&program);
17 for extra in args {
18 config = config.arg(extra);
19 }
20
21 let harness = ComputerUse::new()?;
22 let mut app = harness.launch(config)?;
23 println!("launched {program} via {:?}", app.transport());
24
25 // 1. Perceive: capture the initial frame.
26 let before = app.capture()?;
27 before.image.save("agent-loop-before.png")?;
28 println!(
29 "captured {}x{} -> agent-loop-before.png",
30 before.image.width(),
31 before.image.height()
32 );
33
34 // 2. Act: focus, select-all, and type, exercising keyboard + text paths.
35 app.click(
36 before.image.width() as f64 / 2.0,
37 before.image.height() as f64 / 2.0,
38 PointerButton::Left,
39 1,
40 )?;
41 app.press_key("ctrl+a")?;
42 app.type_text("agent-seat-linux")?;
43
44 // 3. Perceive again: capture the post-action frame.
45 let after = app.capture()?;
46 after.image.save("agent-loop-after.png")?;
47 println!(
48 "captured {}x{} -> agent-loop-after.png",
49 after.image.width(),
50 after.image.height()
51 );
52
53 // 4. Teardown: stop the app, then close the seat.
54 app.stop();
55 harness.close();
56 println!("done");
57 Ok(())
58}Sourcepub fn drag(&self, from_x: f64, from_y: f64, to_x: f64, to_y: f64) -> Result<()>
pub fn drag(&self, from_x: f64, from_y: f64, to_x: f64, to_y: f64) -> Result<()>
Drag between two frame-local points.
Sourcepub fn stop(&mut self)
pub fn stop(&mut self)
Kill and reap the controlled process. Calling this twice is safe.
Examples found in repository?
examples/basic.rs (line 35)
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let mut arguments = std::env::args_os().skip(1);
7 let program = arguments
8 .next()
9 .unwrap_or_else(|| "gnome-calculator".into());
10 let harness = ComputerUse::builder()
11 .native_timeout(Duration::from_secs(8))
12 .fallback_timeout(Duration::from_secs(30))
13 .bridge_geometry(1280, 800)
14 .build()?;
15 let mut app = harness.launch(LaunchConfig::new(program).args(arguments))?;
16
17 let frame = app.capture()?;
18 println!(
19 "controlled pid={} transport={:?} frame={}x{}",
20 app.pid(),
21 app.transport(),
22 frame.width,
23 frame.height
24 );
25 frame.image.save("agent-seat-frame.png")?;
26
27 // Harmlessly focus the center of the captured app to prove pointer input.
28 app.click(
29 f64::from(frame.width) / 2.0,
30 f64::from(frame.height) / 2.0,
31 PointerButton::Left,
32 1,
33 )?;
34
35 app.stop();
36 Ok(())
37}More examples
examples/agent_loop.rs (line 54)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 let mut args = env::args().skip(1);
12 let program = args
13 .next()
14 .unwrap_or_else(|| "gnome-calculator".to_string());
15
16 let mut config = LaunchConfig::new(&program);
17 for extra in args {
18 config = config.arg(extra);
19 }
20
21 let harness = ComputerUse::new()?;
22 let mut app = harness.launch(config)?;
23 println!("launched {program} via {:?}", app.transport());
24
25 // 1. Perceive: capture the initial frame.
26 let before = app.capture()?;
27 before.image.save("agent-loop-before.png")?;
28 println!(
29 "captured {}x{} -> agent-loop-before.png",
30 before.image.width(),
31 before.image.height()
32 );
33
34 // 2. Act: focus, select-all, and type, exercising keyboard + text paths.
35 app.click(
36 before.image.width() as f64 / 2.0,
37 before.image.height() as f64 / 2.0,
38 PointerButton::Left,
39 1,
40 )?;
41 app.press_key("ctrl+a")?;
42 app.type_text("agent-seat-linux")?;
43
44 // 3. Perceive again: capture the post-action frame.
45 let after = app.capture()?;
46 after.image.save("agent-loop-after.png")?;
47 println!(
48 "captured {}x{} -> agent-loop-after.png",
49 after.image.width(),
50 after.image.height()
51 );
52
53 // 4. Teardown: stop the app, then close the seat.
54 app.stop();
55 harness.close();
56 println!("done");
57 Ok(())
58}Trait Implementations§
Source§impl Drop for ControlledApp
impl Drop for ControlledApp
Auto Trait Implementations§
impl Freeze for ControlledApp
impl RefUnwindSafe for ControlledApp
impl Send for ControlledApp
impl Sync for ControlledApp
impl Unpin for ControlledApp
impl UnsafeUnpin for ControlledApp
impl UnwindSafe for ControlledApp
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Convert
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Convert
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Convert
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
Convert
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.