1use gpui::{
2 App, Application, Bounds, Context, DisplayId, Hsla, Pixels, SharedString, Size, Window,
3 WindowBackgroundAppearance, WindowBounds, WindowKind, WindowOptions, div, point, prelude::*,
4 px, rgb,
5};
6
7struct WindowContent {
8 text: SharedString,
9 bounds: Bounds<Pixels>,
10 bg: Hsla,
11}
12
13impl Render for WindowContent {
14 fn render(&mut self, window: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
15 let window_bounds = window.bounds();
16
17 div()
18 .flex()
19 .flex_col()
20 .bg(self.bg)
21 .size_full()
22 .items_center()
23 .text_color(rgb(0xffffff))
24 .child(self.text.clone())
25 .child(
26 div()
27 .flex()
28 .flex_col()
29 .text_sm()
30 .items_center()
31 .size_full()
32 .child(format!(
33 "origin: {}, {} size: {}, {}",
34 self.bounds.origin.x,
35 self.bounds.origin.y,
36 self.bounds.size.width,
37 self.bounds.size.height
38 ))
39 .child(format!(
40 "cx.bounds() origin: {}, {} size {}, {}",
41 window_bounds.origin.x,
42 window_bounds.origin.y,
43 window_bounds.size.width,
44 window_bounds.size.height
45 )),
46 )
47 }
48}
49
50fn build_window_options(display_id: DisplayId, bounds: Bounds<Pixels>) -> WindowOptions {
51 WindowOptions {
52 // Set the bounds of the window in screen coordinates
53 window_bounds: Some(WindowBounds::Windowed(bounds)),
54 // Specify the display_id to ensure the window is created on the correct screen
55 display_id: Some(display_id),
56 titlebar: None,
57 window_background: WindowBackgroundAppearance::Transparent,
58 focus: false,
59 show: true,
60 kind: WindowKind::PopUp,
61 is_movable: false,
62 app_id: None,
63 window_min_size: None,
64 window_decorations: None,
65 ..Default::default()
66 }
67}
68
69fn main() {
70 Application::new().run(|cx: &mut App| {
71 // Create several new windows, positioned in the top right corner of each screen
72 let size = Size {
73 width: px(350.),
74 height: px(75.),
75 };
76 let margin_offset = px(150.);
77
78 for screen in cx.displays() {
79 let bounds = Bounds {
80 origin: point(margin_offset, margin_offset),
81 size,
82 };
83
84 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
85 cx.new(|_| WindowContent {
86 text: format!("Top Left {:?}", screen.id()).into(),
87 bg: gpui::red(),
88 bounds,
89 })
90 })
91 .unwrap();
92
93 let bounds = Bounds {
94 origin: screen.bounds().top_right()
95 - point(size.width + margin_offset, -margin_offset),
96 size,
97 };
98
99 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
100 cx.new(|_| WindowContent {
101 text: format!("Top Right {:?}", screen.id()).into(),
102 bg: gpui::red(),
103 bounds,
104 })
105 })
106 .unwrap();
107
108 let bounds = Bounds {
109 origin: screen.bounds().bottom_left()
110 - point(-margin_offset, size.height + margin_offset),
111 size,
112 };
113
114 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
115 cx.new(|_| WindowContent {
116 text: format!("Bottom Left {:?}", screen.id()).into(),
117 bg: gpui::blue(),
118 bounds,
119 })
120 })
121 .unwrap();
122
123 let bounds = Bounds {
124 origin: screen.bounds().bottom_right()
125 - point(size.width + margin_offset, size.height + margin_offset),
126 size,
127 };
128
129 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
130 cx.new(|_| WindowContent {
131 text: format!("Bottom Right {:?}", screen.id()).into(),
132 bg: gpui::blue(),
133 bounds,
134 })
135 })
136 .unwrap();
137
138 let bounds = Bounds {
139 origin: point(screen.bounds().center().x - size.center().x, margin_offset),
140 size,
141 };
142
143 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
144 cx.new(|_| WindowContent {
145 text: format!("Top Center {:?}", screen.id()).into(),
146 bg: gpui::black(),
147 bounds,
148 })
149 })
150 .unwrap();
151
152 let bounds = Bounds {
153 origin: point(margin_offset, screen.bounds().center().y - size.center().y),
154 size,
155 };
156
157 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
158 cx.new(|_| WindowContent {
159 text: format!("Left Center {:?}", screen.id()).into(),
160 bg: gpui::black(),
161 bounds,
162 })
163 })
164 .unwrap();
165
166 let bounds = Bounds {
167 origin: point(
168 screen.bounds().center().x - size.center().x,
169 screen.bounds().center().y - size.center().y,
170 ),
171 size,
172 };
173
174 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
175 cx.new(|_| WindowContent {
176 text: format!("Center {:?}", screen.id()).into(),
177 bg: gpui::black(),
178 bounds,
179 })
180 })
181 .unwrap();
182
183 let bounds = Bounds {
184 origin: point(
185 screen.bounds().size.width - size.width - margin_offset,
186 screen.bounds().center().y - size.center().y,
187 ),
188 size,
189 };
190
191 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
192 cx.new(|_| WindowContent {
193 text: format!("Right Center {:?}", screen.id()).into(),
194 bg: gpui::black(),
195 bounds,
196 })
197 })
198 .unwrap();
199
200 let bounds = Bounds {
201 origin: point(
202 screen.bounds().center().x - size.center().x,
203 screen.bounds().size.height - size.height - margin_offset,
204 ),
205 size,
206 };
207
208 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
209 cx.new(|_| WindowContent {
210 text: format!("Bottom Center {:?}", screen.id()).into(),
211 bg: gpui::black(),
212 bounds,
213 })
214 })
215 .unwrap();
216 }
217 });
218}