monitor_info/
monitor_info.rs1use bevy::{
4 camera::RenderTarget,
5 prelude::*,
6 window::{ExitCondition, Monitor, OnMonitor, WindowMode, WindowRef},
7};
8
9fn main() {
10 App::new()
11 .add_plugins(DefaultPlugins.set(WindowPlugin {
12 primary_window: None,
13 exit_condition: ExitCondition::DontExit,
14 ..default()
15 }))
16 .add_systems(Update, (update, close_on_esc))
17 .run();
18}
19
20fn update(
21 mut commands: Commands,
22 monitors_added: Query<(Entity, &Monitor), Added<Monitor>>,
23 mut monitors_removed: RemovedComponents<Monitor>,
24 windows: Query<(Entity, &OnMonitor)>,
25) {
26 for (entity, monitor) in monitors_added.iter() {
27 let name = monitor.name.clone().unwrap_or_else(|| "<no name>".into());
29 let size = format!("{}x{}px", monitor.physical_height, monitor.physical_width);
30 let hz = monitor
31 .refresh_rate_millihertz
32 .map(|x| format!("{}Hz", x as f32 / 1000.0))
33 .unwrap_or_else(|| "<unknown>".into());
34 let position = format!(
35 "x={} y={}",
36 monitor.physical_position.x, monitor.physical_position.y
37 );
38 let scale = format!("{:.2}", monitor.scale_factor);
39
40 let window = commands
41 .spawn((Window {
42 title: name.clone(),
43 mode: WindowMode::Fullscreen(
44 MonitorSelection::Entity(entity),
45 VideoModeSelection::Current,
46 ),
47 position: WindowPosition::Centered(MonitorSelection::Entity(entity)),
48 ..default()
49 },))
50 .id();
51
52 let camera = commands
53 .spawn((Camera2d, RenderTarget::Window(WindowRef::Entity(window))))
54 .id();
55
56 let info_text = format!(
57 "Monitor: {name}\nSize: {size}\nRefresh rate: {hz}\nPosition: {position}\nScale: {scale}\n\n",
58 );
59 commands.spawn((
60 Text(info_text),
61 Node {
62 position_type: PositionType::Relative,
63 height: percent(100),
64 width: percent(100),
65 ..default()
66 },
67 UiTargetCamera(camera),
68 ));
69 }
70
71 for monitor_entity in monitors_removed.read() {
73 for (window_entity, on_monitor) in windows.iter() {
74 if on_monitor.0 == monitor_entity {
75 commands.entity(window_entity).despawn();
76 }
77 }
78 }
79}
80
81fn close_on_esc(
82 mut commands: Commands,
83 focused_windows: Query<(Entity, &Window)>,
84 input: Res<ButtonInput<KeyCode>>,
85) {
86 for (window, focus) in focused_windows.iter() {
87 if !focus.focused {
88 continue;
89 }
90
91 if input.just_pressed(KeyCode::Escape) {
92 commands.entity(window).despawn();
93 }
94 }
95}