Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:38:38.873Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

move_entity_between_windows.rs

155 lines · 5.1 KB · rust
1//! An entity registers callbacks via the `_in` API family and then gets
2//! re-hosted in a new window via a click. The point of the example is to
3//! demonstrate that callbacks dispatched after the move correctly target the
4//! entity's *current* window rather than the window it was in at
5//! registration time.
6//!
7//! To run:  cargo run -p gpui --example move_entity_between_windows
8
9#![cfg_attr(target_family = "wasm", no_main)]
10
11use std::time::Duration;
12
13use gpui::{
14    App, AppContext as _, Bounds, Context, EventEmitter, MouseButton, Render, SharedString,
15    Subscription, Task, Window, WindowBounds, WindowOptions, div, prelude::*, px, rgb, size,
16};
17use gpui_platform::application;
18
19struct MoveToNewWindow;
20
21struct HelloWorld {
22    text: SharedString,
23    tick_count: u32,
24    move_count: u32,
25    _tasks: Vec<Task<()>>,
26    _subscriptions: Vec<Subscription>,
27}
28
29impl EventEmitter<MoveToNewWindow> for HelloWorld {}
30
31impl HelloWorld {
32    fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
33        let self_entity = cx.entity();
34
35        let task = cx.spawn_in(window, async move |this, cx| {
36            loop {
37                cx.background_executor().timer(Duration::from_secs(1)).await;
38                let result = this.update_in(cx, |this, window, _cx| {
39                    this.tick_count += 1;
40                    println!(
41                        "tick #{} fired in entity's current window {}",
42                        this.tick_count,
43                        window.window_handle().window_id().as_u64(),
44                    );
45                });
46                if let Err(err) = result {
47                    println!("tick task giving up: {err}");
48                    return;
49                }
50            }
51        });
52
53        let subscription = cx.subscribe_in::<_, MoveToNewWindow>(
54            &self_entity,
55            window,
56            move |this, _emitter, _event, window, cx| {
57                let entered_window_id = window.window_handle().window_id().as_u64();
58                println!(
59                    "MoveToNewWindow handler fired in entity's current window {entered_window_id}",
60                );
61
62                this.move_count += 1;
63                cx.notify();
64
65                let entity = cx.entity();
66                let old_window = window.window_handle();
67                cx.defer(move |cx| {
68                    let bounds = Bounds::centered(None, size(px(500.0), px(500.0)), cx);
69                    cx.open_window(
70                        WindowOptions {
71                            window_bounds: Some(WindowBounds::Windowed(bounds)),
72                            ..Default::default()
73                        },
74                        move |_, _| entity,
75                    )
76                    .expect("failed to open new window");
77                    old_window
78                        .update(cx, |_, window, _| window.remove_window())
79                        .ok();
80                });
81            },
82        );
83
84        Self {
85            text: "World".into(),
86            tick_count: 0,
87            move_count: 0,
88            _tasks: vec![task],
89            _subscriptions: vec![subscription],
90        }
91    }
92}
93
94impl Render for HelloWorld {
95    fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
96        let window_id = window.window_handle().window_id().as_u64();
97
98        div()
99            .flex()
100            .flex_col()
101            .gap_3()
102            .bg(rgb(0x505050))
103            .size(px(500.0))
104            .justify_center()
105            .items_center()
106            .text_xl()
107            .text_color(rgb(0xffffff))
108            .child(format!("Hello, {}!", &self.text))
109            .child(format!("Rendering in window: {window_id}"))
110            .child(format!("Ticks observed by entity: {}", self.tick_count))
111            .child(format!("Moves observed by entity: {}", self.move_count))
112            .child(
113                div()
114                    .px_4()
115                    .py_2()
116                    .bg(rgb(0x4040ff))
117                    .rounded_md()
118                    .child("Move me to a new window")
119                    .on_mouse_down(
120                        MouseButton::Left,
121                        cx.listener(|_this, _, _window, cx| {
122                            cx.emit(MoveToNewWindow);
123                        }),
124                    ),
125            )
126    }
127}
128
129fn run_example() {
130    application().run(|cx: &mut App| {
131        let bounds = Bounds::centered(None, size(px(500.0), px(500.0)), cx);
132        cx.open_window(
133            WindowOptions {
134                window_bounds: Some(WindowBounds::Windowed(bounds)),
135                ..Default::default()
136            },
137            |window, cx| cx.new(|cx| HelloWorld::new(window, cx)),
138        )
139        .unwrap();
140        cx.activate(true);
141    });
142}
143
144#[cfg(not(target_family = "wasm"))]
145fn main() {
146    run_example();
147}
148
149#[cfg(target_family = "wasm")]
150#[wasm_bindgen::prelude::wasm_bindgen(start)]
151pub fn start() {
152    gpui_platform::web_init();
153    run_example();
154}
155
Served at tenant.openagents/omega Member data and write actions are omitted.