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 }
66}
67
68fn main() {
69 Application::new().run(|cx: &mut App| {
70 // Create several new windows, positioned in the top right corner of each screen
71 let size = Size {
72 width: px(350.),
73 height: px(75.),
74 };
75 let margin_offset = px(150.);
76
77 for screen in cx.displays() {
78 let bounds = Bounds {
79 origin: point(margin_offset, margin_offset),
80 size,
81 };
82
83 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
84 cx.new(|_| WindowContent {
85 text: format!("Top Left {:?}", screen.id()).into(),
86 bg: gpui::red(),
87 bounds,
88 })
89 })
90 .unwrap();
91
92 let bounds = Bounds {
93 origin: screen.bounds().top_right()
94 - point(size.width + margin_offset, -margin_offset),
95 size,
96 };
97
98 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
99 cx.new(|_| WindowContent {
100 text: format!("Top Right {:?}", screen.id()).into(),
101 bg: gpui::red(),
102 bounds,
103 })
104 })
105 .unwrap();
106
107 let bounds = Bounds {
108 origin: screen.bounds().bottom_left()
109 - point(-margin_offset, size.height + margin_offset),
110 size,
111 };
112
113 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
114 cx.new(|_| WindowContent {
115 text: format!("Bottom Left {:?}", screen.id()).into(),
116 bg: gpui::blue(),
117 bounds,
118 })
119 })
120 .unwrap();
121
122 let bounds = Bounds {
123 origin: screen.bounds().bottom_right()
124 - point(size.width + margin_offset, size.height + margin_offset),
125 size,
126 };
127
128 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
129 cx.new(|_| WindowContent {
130 text: format!("Bottom Right {:?}", screen.id()).into(),
131 bg: gpui::blue(),
132 bounds,
133 })
134 })
135 .unwrap();
136
137 let bounds = Bounds {
138 origin: point(screen.bounds().center().x - size.center().x, margin_offset),
139 size,
140 };
141
142 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
143 cx.new(|_| WindowContent {
144 text: format!("Top Center {:?}", screen.id()).into(),
145 bg: gpui::black(),
146 bounds,
147 })
148 })
149 .unwrap();
150
151 let bounds = Bounds {
152 origin: point(margin_offset, screen.bounds().center().y - size.center().y),
153 size,
154 };
155
156 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
157 cx.new(|_| WindowContent {
158 text: format!("Left Center {:?}", screen.id()).into(),
159 bg: gpui::black(),
160 bounds,
161 })
162 })
163 .unwrap();
164
165 let bounds = Bounds {
166 origin: point(
167 screen.bounds().center().x - size.center().x,
168 screen.bounds().center().y - size.center().y,
169 ),
170 size,
171 };
172
173 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
174 cx.new(|_| WindowContent {
175 text: format!("Center {:?}", screen.id()).into(),
176 bg: gpui::black(),
177 bounds,
178 })
179 })
180 .unwrap();
181
182 let bounds = Bounds {
183 origin: point(
184 screen.bounds().size.width - size.width - margin_offset,
185 screen.bounds().center().y - size.center().y,
186 ),
187 size,
188 };
189
190 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
191 cx.new(|_| WindowContent {
192 text: format!("Right Center {:?}", screen.id()).into(),
193 bg: gpui::black(),
194 bounds,
195 })
196 })
197 .unwrap();
198
199 let bounds = Bounds {
200 origin: point(
201 screen.bounds().center().x - size.center().x,
202 screen.bounds().size.height - size.height - margin_offset,
203 ),
204 size,
205 };
206
207 cx.open_window(build_window_options(screen.id(), bounds), |_, cx| {
208 cx.new(|_| WindowContent {
209 text: format!("Bottom Center {:?}", screen.id()).into(),
210 bg: gpui::black(),
211 bounds,
212 })
213 })
214 .unwrap();
215 }
216 });
217}