Skip to main content

gpui_macos/
window.rs

1//! Window presentation shared by the native and advanced component layers.
2use crate::ActiveTheme;
3use gpui_kit::base::{Root, RootPlugin};
4use gpui_kit::{
5    App, Context, Hsla, IntoElement, Refineable, Render, Stateful, Styled, Window, div, px,
6};
7
8pub(crate) struct WindowStyle {
9    scale: f32,
10}
11impl RootPlugin for WindowStyle {
12    fn prepare(&mut self, window: &mut Window, _: &mut Context<Self>) {
13        // The Kit plugin also supplies a rem size. Our per-window scale takes
14        // precedence so it survives redraws, overlays, and appearance changes.
15        window.set_rem_size(px(16. * self.scale));
16    }
17    fn style(&self, surface: &mut Stateful<gpui_kit::Div>, _: &mut Window, cx: &mut App) {
18        surface
19            .style()
20            .refine(
21                &gpui_kit::StyleRefinement::default().bg(if cx.macos().reduce_transparency {
22                    cx.macos().background
23                } else {
24                    Hsla::transparent_black()
25                }),
26            );
27    }
28}
29impl Render for WindowStyle {
30    fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
31        div()
32    }
33}
34pub(crate) fn init(cx: &mut App) {
35    Root::register_plugin(cx, |window, _| WindowStyle {
36        scale: window.rem_size().as_f32() / 16.,
37    });
38}
39/// Set this window's interface zoom from 50% to 200%, preserving it on redraw.
40/// Ordinary native window bounds and physical hairline borders remain in pixels.
41pub fn set_zoom(percent: u16, window: &mut Window, cx: &mut App) {
42    let scale = percent.clamp(50, 200) as f32 / 100.;
43    if let Some(style) = window
44        .root::<Root>()
45        .flatten()
46        .and_then(|root| root.read(cx).plugin::<WindowStyle>())
47    {
48        style.update(cx, |style, cx| {
49            style.scale = scale;
50            cx.notify();
51        });
52    }
53    window.set_rem_size(px(16. * scale));
54    window.refresh();
55}
56/// Current interface zoom as a percentage of the 16px rem baseline.
57pub fn zoom_percent(window: &Window) -> u16 {
58    (window.rem_size().as_f32() / 16. * 100.).round() as u16
59}