druid_shell/screen.rs
1// Copyright 2020 The Druid Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Module to get information about monitors
16
17use crate::backend;
18use crate::kurbo::Rect;
19use std::fmt;
20use std::fmt::Display;
21
22/// Monitor struct containing data about a monitor on the system
23///
24/// Use [`Screen::get_monitors`] to return a `Vec<Monitor>` of all the monitors on the system
25///
26/// [`Screen::get_monitors`]: Screen::get_monitors
27#[derive(Clone, Debug, PartialEq)]
28pub struct Monitor {
29 primary: bool,
30 rect: Rect,
31 // TODO: Work area, cross_platform
32 // https://developer.apple.com/documentation/appkit/nsscreen/1388369-visibleframe
33 // https://developer.gnome.org/gdk3/stable/GdkMonitor.html#gdk-monitor-get-workarea
34 // https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-monitorinfo
35 // Unsure about x11
36 work_rect: Rect,
37}
38
39impl Monitor {
40 #[allow(dead_code)]
41 pub(crate) fn new(primary: bool, rect: Rect, work_rect: Rect) -> Self {
42 Monitor {
43 primary,
44 rect,
45 work_rect,
46 }
47 }
48 /// Returns true if the monitor is the primary monitor.
49 /// The primary monitor has its origin at (0, 0) in virtual screen coordinates.
50 pub fn is_primary(&self) -> bool {
51 self.primary
52 }
53 /// Returns the monitor rectangle in virtual screen coordinates.
54 pub fn virtual_rect(&self) -> Rect {
55 self.rect
56 }
57
58 /// Returns the monitor working rectangle in virtual screen coordinates.
59 /// The working rectangle excludes certain things like the dock and menubar on mac,
60 /// and the taskbar on windows.
61 pub fn virtual_work_rect(&self) -> Rect {
62 self.work_rect
63 }
64}
65
66impl Display for Monitor {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 if self.primary {
69 write!(f, "Primary ")?;
70 } else {
71 write!(f, "Secondary ")?;
72 }
73 write!(
74 f,
75 "({}, {})({}, {})",
76 self.rect.x0, self.rect.x1, self.rect.y0, self.rect.y1
77 )?;
78 Ok(())
79 }
80}
81
82/// Information about the screen and monitors
83pub struct Screen {}
84
85impl Screen {
86 /// Returns a vector of all the [`monitors`] on the system.
87 ///
88 /// [`monitors`]: Monitor
89 pub fn get_monitors() -> Vec<Monitor> {
90 backend::screen::get_monitors()
91 }
92
93 /// Returns the bounding rectangle of the total virtual screen space in pixels.
94 pub fn get_display_rect() -> Rect {
95 Self::get_monitors()
96 .iter()
97 .map(|x| x.virtual_rect())
98 .fold(Rect::ZERO, |a, b| a.union(b))
99 }
100}