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}