rust_macios/appkit/
ns_screen.rs

1use objc::{msg_send, sel, sel_impl};
2
3use crate::{
4    core_graphics::CGFloat,
5    foundation::{
6        Int, NSAlignmentOptions, NSDictionary, NSEdgeInsets, NSNotificationName, NSRect, NSString,
7        NSTimeInterval,
8    },
9    object,
10    objective_c_runtime::{
11        id,
12        traits::{FromId, PNSObject},
13    },
14    utils::to_bool,
15};
16
17/// These constants are the keys for device description dictionaries.
18pub type NSDeviceDescriptionKey = NSString;
19
20use super::{interface_impl, NSColorSpace, NSWindowDepth};
21
22#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
23#[repr(u64)]
24pub enum NSDisplayGamut {
25    Srgb = 1,
26    P3,
27}
28
29extern "C" {
30    pub static NSScreenColorSpaceDidChangeNotification: NSNotificationName;
31}
32
33object! {
34    /// An object that describes the attributes of a computer’s monitor or screen.
35    unsafe pub struct NSScreen;
36}
37
38#[interface_impl(NSObject)]
39impl NSScreen {
40    /* Getting Screen Objects
41     */
42
43    /// Returns the screen object containing the window with the keyboard focus.
44    #[property]
45    pub fn main_screen() -> NSScreen {
46        unsafe { NSScreen::from_id(msg_send![Self::m_class(), mainScreen]) }
47    }
48
49    /// Returns a screen object representing the screen that can best represent color.
50    #[property]
51    pub fn deepest_screen() -> NSScreen {
52        unsafe { NSScreen::from_id(msg_send![Self::m_class(), deepestScreen]) }
53    }
54
55    /// Returns an array of screen objects representing all of the screens available on the system.
56    #[property]
57    pub fn screens() -> NSScreen {
58        unsafe { NSScreen::from_id(msg_send![Self::m_class(), screens]) }
59    }
60
61    /*  Getting Screen Information
62     */
63
64    /// The current bit depth and colorspace information of the screen.
65    #[property]
66    pub fn depth(&self) -> NSWindowDepth {
67        unsafe { msg_send![self.m_self(), depth] }
68    }
69
70    /// The dimensions and location of the screen.
71    #[property]
72    pub fn frame(&self) -> NSRect {
73        unsafe { msg_send![self.m_self(), frame] }
74    }
75
76    /// A zero-terminated array of the window depths supported by the screen.
77    #[property]
78    pub fn supported_window_depths(&self) -> *const NSWindowDepth {
79        unsafe { msg_send![self.m_self(), supportedWindowDepths] }
80    }
81
82    /// The device dictionary for the screen.
83    #[property]
84    pub fn device_description(&self) -> NSDictionary<NSDeviceDescriptionKey, id> {
85        unsafe { NSDictionary::from_id(msg_send![self.m_self(), deviceDescription]) }
86    }
87
88    /// Returns the scaling factor from user space to device space on the screen.
89    #[deprecated]
90    #[method]
91    pub fn user_space_scale_factor(&self) -> CGFloat {
92        unsafe { msg_send![self.m_self(), userSpaceScaleFactor] }
93    }
94
95    /// The color space of the screen.
96    #[property]
97    pub fn color_space(&self) -> NSColorSpace {
98        unsafe { NSColorSpace::from_id(msg_send![self.m_self(), colorSpace]) }
99    }
100
101    /// The localized name of the display.
102    #[property]
103    pub fn localized_name(&self) -> NSString {
104        unsafe { NSString::from_id(msg_send![self.m_self(), localizedName]) }
105    }
106
107    /// A Boolean value indicating whether the color space of the screen is capable of representing the specified display gamut.
108    #[method]
109    pub fn can_represent_display_gamut(&self, display_gamut: NSDisplayGamut) -> bool {
110        unsafe {
111            to_bool(msg_send![
112                self.m_self(),
113                canRepresentDisplayGamut: display_gamut
114            ])
115        }
116    }
117
118    /// Returns a Boolean value indicating whether each screen can have its own set of spaces.
119    #[property]
120    pub fn screens_have_separate_spaces() -> bool {
121        unsafe { to_bool(msg_send![Self::m_class(), screensHaveSeparateSpaces]) }
122    }
123
124    /* Converting Between Screen and Backing Coordinates
125     */
126
127    /// Converts a rectangle in global screen coordinates to a pixel aligned rectangle.
128    #[method]
129    pub fn backing_aligned_rect_options(
130        &self,
131        rect: NSRect,
132        options: NSAlignmentOptions,
133    ) -> NSRect {
134        unsafe { msg_send![self.m_self(), backingAlignedRect: rect options: options] }
135    }
136
137    /// The backing store pixel scale factor for the screen.
138    #[property]
139    pub fn backing_scale_factor(&self) -> CGFloat {
140        unsafe { msg_send![self.m_self(), backingScaleFactor] }
141    }
142
143    /// Converts the rectangle from the device pixel aligned coordinates system of a screen.
144    #[method]
145    pub fn convert_rect_from_backing(&self, rect: NSRect) -> NSRect {
146        unsafe { msg_send![self.m_self(), convertRectFromBacking: rect] }
147    }
148
149    /// Converts the rectangle to the device pixel aligned coordinates system of a screen.
150    #[method]
151    pub fn convert_rect_to_backing(&self, rect: NSRect) -> NSRect {
152        unsafe { msg_send![self.m_self(), convertRectToBacking: rect] }
153    }
154
155    /* Getting the Visible Portion of the Screen
156     */
157
158    /// The current location and dimensions of the visible screen.
159    #[property]
160    pub fn visible_frame(&self) -> NSRect {
161        unsafe { msg_send![self.m_self(), visibleFrame] }
162    }
163
164    /// The distances from the screen’s edges at which content isn’t obscured.
165    #[property]
166    pub fn safe_area_insets(&self) -> NSEdgeInsets {
167        unsafe { msg_send![self.m_self(), safeAreaInsets] }
168    }
169
170    /* Getting Extended Dynamic Range Details
171     */
172
173    /// The maximum possible color component value for the screen when it's in extended dynamic range (EDR) mode.
174    #[property]
175    pub fn maximum_potential_extended_dynamic_range_color_component_value(&self) -> CGFloat {
176        unsafe {
177            msg_send![
178                self.m_self(),
179                maximumPotentialExtendedDynamicRangeColorComponentValue
180            ]
181        }
182    }
183
184    /// The current maximum color component value for the screen.
185    #[property]
186    pub fn maximum_extended_dynamic_range_color_component_value(&self) -> CGFloat {
187        unsafe {
188            msg_send![
189                self.m_self(),
190                maximumExtendedDynamicRangeColorComponentValue
191            ]
192        }
193    }
194
195    /// The current maximum color component value for reference rendering to the screen.
196    #[property]
197    pub fn maximum_reference_extended_dynamic_range_color_component_value(&self) -> CGFloat {
198        unsafe {
199            msg_send![
200                self.m_self(),
201                maximumReferenceExtendedDynamicRangeColorComponentValue
202            ]
203        }
204    }
205
206    /* Getting Variable Refresh Rate Details
207     */
208
209    /// The maximum number of frames per second that the screen supports.
210    #[property]
211    pub fn maximum_frames_per_second(&self) -> Int {
212        unsafe { msg_send![self.m_self(), maximumFramesPerSecond] }
213    }
214
215    /// The shortest refresh interval that the screen supports.
216    #[property]
217    pub fn minimum_refresh_interval(&self) -> NSTimeInterval {
218        unsafe { msg_send![self.m_self(), minimumRefreshInterval] }
219    }
220
221    /// The largest refresh interval that the screen supports.
222    #[property]
223    pub fn maximum_refresh_interval(&self) -> NSTimeInterval {
224        unsafe { msg_send![self.m_self(), maximumRefreshInterval] }
225    }
226
227    /// The number of seconds between the screen’s supported update rates, for screens that support fixed update rates.
228    #[property]
229    pub fn display_update_granularity(&self) -> NSTimeInterval {
230        unsafe { msg_send![self.m_self(), displayUpdateGranularity] }
231    }
232
233    /// The time of the last framebuffer update, expressed as the number of seconds since system startup.
234    #[property]
235    pub fn last_display_update_timestamp(&self) -> NSTimeInterval {
236        unsafe { msg_send![self.m_self(), lastDisplayUpdateTimestamp] }
237    }
238
239    /* Instance Properties
240     */
241
242    #[property]
243    pub fn auxiliary_top_left_area(&self) -> NSRect {
244        unsafe { msg_send![self.m_self(), auxiliaryTopLeftArea] }
245    }
246
247    #[property]
248    pub fn auxiliary_top_right_area(&self) -> NSRect {
249        unsafe { msg_send![self.m_self(), auxiliaryTopRightArea] }
250    }
251}