diff --git a/crates/assistant/src/prompt_library.rs b/crates/assistant/src/prompt_library.rs index c85320d909..972a595e06 100644 --- a/crates/assistant/src/prompt_library.rs +++ b/crates/assistant/src/prompt_library.rs @@ -14,8 +14,8 @@ use futures::{ use fuzzy::StringMatchCandidate; use gpui::{ actions, percentage, point, size, Animation, AnimationExt, AppContext, BackgroundExecutor, - Bounds, DevicePixels, EventEmitter, Global, PromptLevel, ReadGlobal, Subscription, Task, - TitlebarOptions, Transformation, UpdateGlobal, View, WindowBounds, WindowHandle, WindowOptions, + Bounds, EventEmitter, Global, PromptLevel, ReadGlobal, Subscription, Task, TitlebarOptions, + Transformation, UpdateGlobal, View, WindowBounds, WindowHandle, WindowOptions, }; use heed::{types::SerdeBincode, Database, RoTxn}; use language::{language_settings::SoftWrap, Buffer, LanguageRegistry}; @@ -80,11 +80,7 @@ pub fn open_prompt_library( cx.spawn(|cx| async move { let store = store.await?; cx.update(|cx| { - let bounds = Bounds::centered( - None, - size(DevicePixels::from(1024), DevicePixels::from(768)), - cx, - ); + let bounds = Bounds::centered(None, size(px(1024.0), px(768.0)), cx); cx.open_window( WindowOptions { titlebar: Some(TitlebarOptions { diff --git a/crates/collab_ui/src/collab_ui.rs b/crates/collab_ui/src/collab_ui.rs index 94f7c7ba32..774bf139ef 100644 --- a/crates/collab_ui/src/collab_ui.rs +++ b/crates/collab_ui/src/collab_ui.rs @@ -13,8 +13,8 @@ use call::{report_call_event_for_room, ActiveCall}; pub use collab_panel::CollabPanel; pub use collab_titlebar_item::CollabTitlebarItem; use gpui::{ - actions, point, AppContext, DevicePixels, Pixels, PlatformDisplay, Size, Task, - WindowBackgroundAppearance, WindowBounds, WindowContext, WindowKind, WindowOptions, + actions, point, AppContext, Pixels, PlatformDisplay, Size, Task, WindowBackgroundAppearance, + WindowBounds, WindowContext, WindowKind, WindowOptions, }; use panel_settings::MessageEditorSettings; pub use panel_settings::{ @@ -22,6 +22,7 @@ pub use panel_settings::{ }; use release_channel::ReleaseChannel; use settings::Settings; +use ui::px; use workspace::{notifications::DetachAndPromptErr, AppState}; actions!( @@ -96,22 +97,19 @@ pub fn toggle_deafen(_: &ToggleDeafen, cx: &mut AppContext) { fn notification_window_options( screen: Rc, - window_size: Size, + size: Size, cx: &AppContext, ) -> WindowOptions { - let notification_margin_width = DevicePixels::from(16); - let notification_margin_height = DevicePixels::from(-0) - DevicePixels::from(48); + let notification_margin_width = px(16.); + let notification_margin_height = px(-48.); - let screen_bounds = screen.bounds(); - let size: Size = window_size.into(); - - let bounds = gpui::Bounds:: { - origin: screen_bounds.upper_right() + let bounds = gpui::Bounds:: { + origin: screen.bounds().upper_right() - point( size.width + notification_margin_width, notification_margin_height, ), - size: window_size.into(), + size, }; let app_id = ReleaseChannel::global(cx).app_id(); diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index bc232a0170..4771c8bc01 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -7659,8 +7659,8 @@ async fn test_following(cx: &mut gpui::TestAppContext) { cx.open_window( WindowOptions { window_bounds: Some(WindowBounds::Windowed(Bounds::from_corners( - gpui::Point::new(0.into(), 0.into()), - gpui::Point::new(10.into(), 80.into()), + gpui::Point::new(px(0.), px(0.)), + gpui::Point::new(px(10.), px(80.)), ))), ..Default::default() }, diff --git a/crates/gpui/examples/image/image.rs b/crates/gpui/examples/image/image.rs index b6da594c7a..9710125ae2 100644 --- a/crates/gpui/examples/image/image.rs +++ b/crates/gpui/examples/image/image.rs @@ -80,8 +80,8 @@ fn main() { }), window_bounds: Some(WindowBounds::Windowed(Bounds { - size: size(px(1100.), px(600.)).into(), - origin: Point::new(DevicePixels::from(200), DevicePixels::from(200)), + size: size(px(1100.), px(600.)), + origin: Point::new(px(200.), px(200.)), })), ..Default::default() diff --git a/crates/gpui/examples/window_positioning.rs b/crates/gpui/examples/window_positioning.rs index 7398b5aa9b..9632ccb467 100644 --- a/crates/gpui/examples/window_positioning.rs +++ b/crates/gpui/examples/window_positioning.rs @@ -24,21 +24,18 @@ fn main() { for screen in cx.displays() { let options = { - let popup_margin_width = DevicePixels::from(16); - let popup_margin_height = DevicePixels::from(-0) - DevicePixels::from(48); + let margin_right = px(16.); + let margin_height = px(-48.); - let window_size = Size { + let size = Size { width: px(400.), height: px(72.), }; - let screen_bounds = screen.bounds(); - let size: Size = window_size.into(); - - let bounds = gpui::Bounds:: { - origin: screen_bounds.upper_right() - - point(size.width + popup_margin_width, popup_margin_height), - size: window_size.into(), + let bounds = gpui::Bounds:: { + origin: screen.bounds().upper_right() + - point(size.width + margin_right, margin_height), + size, }; WindowOptions { diff --git a/crates/gpui/src/geometry.rs b/crates/gpui/src/geometry.rs index 95bb18b61d..1d3c32daa4 100644 --- a/crates/gpui/src/geometry.rs +++ b/crates/gpui/src/geometry.rs @@ -363,15 +363,6 @@ pub struct Size { pub height: T, } -impl From> for Size { - fn from(size: Size) -> Self { - Size { - width: Pixels(size.width.0 as f32), - height: Pixels(size.height.0 as f32), - } - } -} - /// Constructs a new `Size` with the provided width and height. /// /// # Arguments @@ -633,15 +624,6 @@ impl From> for Size { } } -impl From> for Size { - fn from(size: Size) -> Self { - Size { - width: DevicePixels(size.width.0 as i32), - height: DevicePixels(size.height.0 as i32), - } - } -} - impl From> for Size { fn from(size: Size) -> Self { Size { @@ -722,28 +704,27 @@ pub struct Bounds { pub size: Size, } -impl Bounds { +impl Bounds { /// Generate a centered bounds for the given display or primary display if none is provided pub fn centered( display_id: Option, - size: impl Into>, + size: Size, cx: &mut AppContext, ) -> Self { let display = display_id .and_then(|id| cx.find_display(id)) .or_else(|| cx.primary_display()); - let size = size.into(); display .map(|display| { let center = display.bounds().center(); Bounds { - origin: point(center.x - size.width / 2, center.y - size.height / 2), + origin: point(center.x - size.width / 2., center.y - size.height / 2.), size, } }) .unwrap_or_else(|| Bounds { - origin: point(DevicePixels(0), DevicePixels(0)), + origin: point(px(0.), px(0.)), size, }) } @@ -757,8 +738,8 @@ impl Bounds { display .map(|display| display.bounds()) .unwrap_or_else(|| Bounds { - origin: point(DevicePixels(0), DevicePixels(0)), - size: size(DevicePixels(1024), DevicePixels(768)), + origin: point(px(0.), px(0.)), + size: size(px(1024.), px(768.)), }) } } @@ -1309,6 +1290,26 @@ impl Bounds { } } +impl Size { + /// Converts the size from physical to logical pixels. + pub(crate) fn to_pixels(self, scale_factor: f32) -> Size { + size( + px(self.width.0 as f32 / scale_factor), + px(self.height.0 as f32 / scale_factor), + ) + } +} + +impl Size { + /// Converts the size from physical to logical pixels. + pub(crate) fn to_device_pixels(self, scale_factor: f32) -> Size { + size( + DevicePixels((self.width.0 * scale_factor) as i32), + DevicePixels((self.height.0 * scale_factor) as i32), + ) + } +} + impl Bounds { /// Scales the bounds by a given factor, typically used to adjust for display scaling. /// @@ -1346,6 +1347,30 @@ impl Bounds { size: self.size.scale(factor), } } + + /// Convert the bounds from logical pixels to physical pixels + pub fn to_device_pixels(&self, factor: f32) -> Bounds { + Bounds { + origin: point( + DevicePixels((self.origin.x.0 * factor) as i32), + DevicePixels((self.origin.y.0 * factor) as i32), + ), + size: self.size.to_device_pixels(factor), + } + } +} + +impl Bounds { + /// Convert the bounds from physical pixels to logical pixels + pub fn to_pixels(self, scale_factor: f32) -> Bounds { + Bounds { + origin: point( + px(self.origin.x.0 as f32 / scale_factor), + px(self.origin.y.0 as f32 / scale_factor), + ), + size: self.size.to_pixels(scale_factor), + } + } } impl Copy for Bounds {} diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 7df9547b44..def79f526d 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -187,12 +187,12 @@ pub trait PlatformDisplay: Send + Sync + Debug { fn uuid(&self) -> Result; /// Get the bounds for this display - fn bounds(&self) -> Bounds; + fn bounds(&self) -> Bounds; /// Get the default bounds for this display to place a window - fn default_bounds(&self) -> Bounds { + fn default_bounds(&self) -> Bounds { let center = self.bounds().center(); - let offset = DEFAULT_WINDOW_SIZE / 2; + let offset = DEFAULT_WINDOW_SIZE / 2.0; let origin = point(center.x - offset.width, center.y - offset.height); Bounds::new(origin, DEFAULT_WINDOW_SIZE) } @@ -211,7 +211,7 @@ impl Debug for DisplayId { unsafe impl Send for DisplayId {} pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle { - fn bounds(&self) -> Bounds; + fn bounds(&self) -> Bounds; fn is_maximized(&self) -> bool; fn window_bounds(&self) -> WindowBounds; fn content_size(&self) -> Size; @@ -569,7 +569,7 @@ pub struct WindowOptions { /// The variables that can be configured when creating a new window #[derive(Debug)] pub(crate) struct WindowParams { - pub bounds: Bounds, + pub bounds: Bounds, /// The titlebar configuration of the window pub titlebar: Option, @@ -597,13 +597,13 @@ pub(crate) struct WindowParams { #[derive(Debug, Copy, Clone, PartialEq)] pub enum WindowBounds { /// Indicates that the window should open in a windowed state with the given bounds. - Windowed(Bounds), + Windowed(Bounds), /// Indicates that the window should open in a maximized state. /// The bounds provided here represent the restore size of the window. - Maximized(Bounds), + Maximized(Bounds), /// Indicates that the window should open in fullscreen mode. /// The bounds provided here represent the restore size of the window. - Fullscreen(Bounds), + Fullscreen(Bounds), } impl Default for WindowBounds { @@ -614,7 +614,7 @@ impl Default for WindowBounds { impl WindowBounds { /// Retrieve the inner bounds - pub fn get_bounds(&self) -> Bounds { + pub fn get_bounds(&self) -> Bounds { match self { WindowBounds::Windowed(bounds) => *bounds, WindowBounds::Maximized(bounds) => *bounds, diff --git a/crates/gpui/src/platform/blade/blade_renderer.rs b/crates/gpui/src/platform/blade/blade_renderer.rs index 761466495e..1830d0cd0d 100644 --- a/crates/gpui/src/platform/blade/blade_renderer.rs +++ b/crates/gpui/src/platform/blade/blade_renderer.rs @@ -3,8 +3,8 @@ use super::{BladeAtlas, PATH_TEXTURE_FORMAT}; use crate::{ - AtlasTextureKind, AtlasTile, Bounds, ContentMask, Hsla, MonochromeSprite, Path, PathId, - PathVertex, PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow, Size, + AtlasTextureKind, AtlasTile, Bounds, ContentMask, DevicePixels, Hsla, MonochromeSprite, Path, + PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad, ScaledPixels, Scene, Shadow, Size, Underline, }; use bytemuck::{Pod, Zeroable}; @@ -417,10 +417,10 @@ impl BladeRenderer { } } - pub fn update_drawable_size(&mut self, size: Size) { + pub fn update_drawable_size(&mut self, size: Size) { let gpu_size = gpu::Extent { - width: size.width as u32, - height: size.height as u32, + width: size.width.0 as u32, + height: size.height.0 as u32, depth: 1, }; diff --git a/crates/gpui/src/platform/linux/wayland/client.rs b/crates/gpui/src/platform/linux/wayland/client.rs index a8b2871f40..e3a67ef302 100644 --- a/crates/gpui/src/platform/linux/wayland/client.rs +++ b/crates/gpui/src/platform/linux/wayland/client.rs @@ -557,7 +557,7 @@ impl LinuxClient for WaylandClient { Rc::new(WaylandDisplay { id: id.clone(), name: output.name.clone(), - bounds: output.bounds, + bounds: output.bounds.to_pixels(output.scale as f32), }) as Rc }) .collect() @@ -573,7 +573,7 @@ impl LinuxClient for WaylandClient { Rc::new(WaylandDisplay { id: object_id.clone(), name: output.name.clone(), - bounds: output.bounds, + bounds: output.bounds.to_pixels(output.scale as f32), }) as Rc }) }) diff --git a/crates/gpui/src/platform/linux/wayland/display.rs b/crates/gpui/src/platform/linux/wayland/display.rs index 34a54ad133..e6eed95ccd 100644 --- a/crates/gpui/src/platform/linux/wayland/display.rs +++ b/crates/gpui/src/platform/linux/wayland/display.rs @@ -6,14 +6,14 @@ use std::{ use uuid::Uuid; use wayland_backend::client::ObjectId; -use crate::{Bounds, DevicePixels, DisplayId, PlatformDisplay}; +use crate::{Bounds, DisplayId, Pixels, PlatformDisplay}; #[derive(Debug, Clone)] pub(crate) struct WaylandDisplay { /// The ID of the wl_output object pub id: ObjectId, pub name: Option, - pub bounds: Bounds, + pub bounds: Bounds, } impl Hash for WaylandDisplay { @@ -35,7 +35,7 @@ impl PlatformDisplay for WaylandDisplay { } } - fn bounds(&self) -> Bounds { + fn bounds(&self) -> Bounds { self.bounds } } diff --git a/crates/gpui/src/platform/linux/wayland/window.rs b/crates/gpui/src/platform/linux/wayland/window.rs index d24c1b5a5e..16e4afb67b 100644 --- a/crates/gpui/src/platform/linux/wayland/window.rs +++ b/crates/gpui/src/platform/linux/wayland/window.rs @@ -1,6 +1,5 @@ use std::cell::{Ref, RefCell, RefMut}; use std::ffi::c_void; -use std::num::NonZeroU32; use std::ptr::NonNull; use std::rc::Rc; use std::sync::Arc; @@ -26,9 +25,9 @@ use crate::platform::linux::wayland::serial::SerialKind; use crate::platform::{PlatformAtlas, PlatformInputHandler, PlatformWindow}; use crate::scene::Scene; use crate::{ - px, size, AnyWindowHandle, Bounds, DevicePixels, Globals, Modifiers, Output, Pixels, - PlatformDisplay, PlatformInput, Point, PromptLevel, Size, WaylandClientStatePtr, - WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowParams, + px, size, AnyWindowHandle, Bounds, Globals, Modifiers, Output, Pixels, PlatformDisplay, + PlatformInput, Point, PromptLevel, Size, WaylandClientStatePtr, WindowAppearance, + WindowBackgroundAppearance, WindowBounds, WindowParams, }; #[derive(Default)] @@ -76,13 +75,13 @@ pub struct WaylandWindowState { display: Option<(ObjectId, Output)>, globals: Globals, renderer: BladeRenderer, - bounds: Bounds, + bounds: Bounds, scale: f32, input_handler: Option, decoration_state: WaylandDecorationState, fullscreen: bool, maximized: bool, - windowed_bounds: Bounds, + windowed_bounds: Bounds, client: WaylandClientStatePtr, handle: AnyWindowHandle, active: bool, @@ -108,8 +107,6 @@ impl WaylandWindowState { globals: Globals, options: WindowParams, ) -> anyhow::Result { - let bounds = options.bounds.map(|p| p.0 as u32); - let raw = RawWindow { window: surface.id().as_ptr().cast::(), display: surface @@ -134,8 +131,8 @@ impl WaylandWindowState { ); let config = BladeSurfaceConfig { size: gpu::Extent { - width: bounds.size.width, - height: bounds.size.height, + width: options.bounds.size.width.0 as u32, + height: options.bounds.size.height.0 as u32, depth: 1, }, transparent: options.window_background != WindowBackgroundAppearance::Opaque, @@ -153,7 +150,7 @@ impl WaylandWindowState { outputs: HashMap::default(), display: None, renderer: BladeRenderer::new(gpu, config), - bounds, + bounds: options.bounds, scale: 1.0, input_handler: None, decoration_state: WaylandDecorationState::Client, @@ -349,10 +346,16 @@ impl WaylandWindowStatePtr { pub fn handle_toplevel_event(&self, event: xdg_toplevel::Event) -> bool { match event { xdg_toplevel::Event::Configure { - mut width, - mut height, + width, + height, states, } => { + let mut size = if width == 0 || height == 0 { + None + } else { + Some(size(px(width as f32), px(height as f32))) + }; + let fullscreen = states.contains(&(xdg_toplevel::State::Fullscreen as u8)); let maximized = states.contains(&(xdg_toplevel::State::Maximized as u8)); @@ -362,19 +365,20 @@ impl WaylandWindowStatePtr { state.maximized = maximized; if got_unmaximized { - width = state.windowed_bounds.size.width.0; - height = state.windowed_bounds.size.height.0; - } else if width != 0 && height != 0 && !fullscreen && !maximized { - state.windowed_bounds = Bounds { - origin: Point::default(), - size: size(width.into(), height.into()), - }; + size = Some(state.windowed_bounds.size); + } else if !fullscreen && !maximized { + if let Some(size) = size { + state.windowed_bounds = Bounds { + origin: Point::default(), + size, + }; + } } - let width = NonZeroU32::new(width as u32); - let height = NonZeroU32::new(height as u32); drop(state); - self.resize(width, height); + if let Some(size) = size { + self.resize(size); + } false } @@ -483,63 +487,43 @@ impl WaylandWindowStatePtr { bounds } - pub fn set_size_and_scale( - &self, - width: Option, - height: Option, - scale: Option, - ) { - let (width, height, scale) = { + pub fn set_size_and_scale(&self, size: Option>, scale: Option) { + let (size, scale) = { let mut state = self.state.borrow_mut(); - if width.map_or(true, |width| width.get() == state.bounds.size.width) - && height.map_or(true, |height| height.get() == state.bounds.size.height) + if size.map_or(true, |size| size == state.bounds.size) && scale.map_or(true, |scale| scale == state.scale) { return; } - if let Some(width) = width { - state.bounds.size.width = width.get(); - } - if let Some(height) = height { - state.bounds.size.height = height.get(); + if let Some(size) = size { + state.bounds.size = size; } if let Some(scale) = scale { state.scale = scale; } - let width = state.bounds.size.width; - let height = state.bounds.size.height; - let scale = state.scale; - state.renderer.update_drawable_size(size( - width as f64 * scale as f64, - height as f64 * scale as f64, - )); - (width, height, scale) + let device_bounds = state.bounds.to_device_pixels(state.scale); + state.renderer.update_drawable_size(device_bounds.size); + (state.bounds.size, state.scale) }; if let Some(ref mut fun) = self.callbacks.borrow_mut().resize { - fun( - Size { - width: px(width as f32), - height: px(height as f32), - }, - scale, - ); + fun(size, scale); } { let state = self.state.borrow(); if let Some(viewport) = &state.viewport { - viewport.set_destination(width as i32, height as i32); + viewport.set_destination(size.width.0 as i32, size.height.0 as i32); } } } - pub fn resize(&self, width: Option, height: Option) { - self.set_size_and_scale(width, height, None); + pub fn resize(&self, size: Size) { + self.set_size_and_scale(Some(size), None); } pub fn rescale(&self, scale: f32) { - self.set_size_and_scale(None, None, Some(scale)); + self.set_size_and_scale(None, Some(scale)); } /// Notifies the window of the state of the decorations. @@ -625,8 +609,8 @@ impl rwh::HasDisplayHandle for WaylandWindow { } impl PlatformWindow for WaylandWindow { - fn bounds(&self) -> Bounds { - self.borrow().bounds.map(|p| DevicePixels(p as i32)) + fn bounds(&self) -> Bounds { + self.borrow().bounds } fn is_maximized(&self) -> bool { @@ -640,16 +624,13 @@ impl PlatformWindow for WaylandWindow { } else if state.maximized { WindowBounds::Maximized(state.windowed_bounds) } else { - WindowBounds::Windowed(state.bounds.map(|p| DevicePixels(p as i32))) + drop(state); + WindowBounds::Windowed(self.bounds()) } } fn content_size(&self) -> Size { - let state = self.borrow(); - Size { - width: Pixels(state.bounds.size.width as f32), - height: Pixels(state.bounds.size.height as f32), - } + self.borrow().bounds.size } fn scale_factor(&self) -> f32 { @@ -661,11 +642,12 @@ impl PlatformWindow for WaylandWindow { } fn display(&self) -> Option> { - self.borrow().display.as_ref().map(|(id, display)| { + let state = self.borrow(); + state.display.as_ref().map(|(id, display)| { Rc::new(WaylandDisplay { id: id.clone(), name: display.name.clone(), - bounds: display.bounds, + bounds: display.bounds.to_pixels(state.scale), }) as Rc }) } diff --git a/crates/gpui/src/platform/linux/x11/client.rs b/crates/gpui/src/platform/linux/x11/client.rs index b3b149d3c5..2e9add68da 100644 --- a/crates/gpui/src/platform/linux/x11/client.rs +++ b/crates/gpui/src/platform/linux/x11/client.rs @@ -908,8 +908,11 @@ impl LinuxClient for X11Client { .iter() .enumerate() .filter_map(|(root_id, _)| { - Some(Rc::new(X11Display::new(&state.xcb_connection, root_id)?) - as Rc) + Some(Rc::new(X11Display::new( + &state.xcb_connection, + state.scale_factor, + root_id, + )?) as Rc) }) .collect() } @@ -918,8 +921,12 @@ impl LinuxClient for X11Client { let state = self.0.borrow(); Some(Rc::new( - X11Display::new(&state.xcb_connection, state.x_root_index) - .expect("There should always be a root index"), + X11Display::new( + &state.xcb_connection, + state.scale_factor, + state.x_root_index, + ) + .expect("There should always be a root index"), )) } @@ -928,6 +935,7 @@ impl LinuxClient for X11Client { Some(Rc::new(X11Display::new( &state.xcb_connection, + state.scale_factor, id.0 as usize, )?)) } diff --git a/crates/gpui/src/platform/linux/x11/display.rs b/crates/gpui/src/platform/linux/x11/display.rs index f68b2194c6..871d709fa9 100644 --- a/crates/gpui/src/platform/linux/x11/display.rs +++ b/crates/gpui/src/platform/linux/x11/display.rs @@ -2,25 +2,29 @@ use anyhow::Result; use uuid::Uuid; use x11rb::{connection::Connection as _, xcb_ffi::XCBConnection}; -use crate::{Bounds, DevicePixels, DisplayId, PlatformDisplay, Size}; +use crate::{px, Bounds, DisplayId, Pixels, PlatformDisplay, Size}; #[derive(Debug)] pub(crate) struct X11Display { x_screen_index: usize, - bounds: Bounds, + bounds: Bounds, uuid: Uuid, } impl X11Display { - pub(crate) fn new(xc: &XCBConnection, x_screen_index: usize) -> Option { + pub(crate) fn new( + xc: &XCBConnection, + scale_factor: f32, + x_screen_index: usize, + ) -> Option { let screen = xc.setup().roots.get(x_screen_index).unwrap(); Some(Self { - x_screen_index: x_screen_index, + x_screen_index, bounds: Bounds { origin: Default::default(), size: Size { - width: DevicePixels(screen.width_in_pixels as i32), - height: DevicePixels(screen.height_in_pixels as i32), + width: px(screen.width_in_pixels as f32 / scale_factor), + height: px(screen.height_in_pixels as f32 / scale_factor), }, }, uuid: Uuid::from_bytes([0; 16]), @@ -37,7 +41,7 @@ impl PlatformDisplay for X11Display { Ok(self.uuid) } - fn bounds(&self) -> Bounds { + fn bounds(&self) -> Bounds { self.bounds } } diff --git a/crates/gpui/src/platform/linux/x11/window.rs b/crates/gpui/src/platform/linux/x11/window.rs index e9831dacce..b36e3da52f 100644 --- a/crates/gpui/src/platform/linux/x11/window.rs +++ b/crates/gpui/src/platform/linux/x11/window.rs @@ -1,6 +1,6 @@ use crate::{ platform::blade::{BladeRenderer, BladeSurfaceConfig}, - size, AnyWindowHandle, Bounds, DevicePixels, ForegroundExecutor, Modifiers, Pixels, + px, size, AnyWindowHandle, Bounds, DevicePixels, ForegroundExecutor, Modifiers, Pixels, PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow, Point, PromptLevel, Scene, Size, WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowKind, WindowParams, X11ClientStatePtr, @@ -162,7 +162,7 @@ pub struct X11WindowState { atoms: XcbAtoms, x_root_window: xproto::Window, _raw: RawWindow, - bounds: Bounds, + bounds: Bounds, scale_factor: f32, renderer: BladeRenderer, display: Rc, @@ -273,10 +273,10 @@ impl X11WindowState { visual.depth, x_window, visual_set.root, - params.bounds.origin.x.0 as i16, - params.bounds.origin.y.0 as i16, - params.bounds.size.width.0 as u16, - params.bounds.size.height.0 as u16, + (params.bounds.origin.x.0 * scale_factor) as i16, + (params.bounds.origin.y.0 * scale_factor) as i16, + (params.bounds.size.width.0 * scale_factor) as u16, + (params.bounds.size.height.0 * scale_factor) as u16, 0, xproto::WindowClass::INPUT_OUTPUT, visual.id, @@ -370,10 +370,12 @@ impl X11WindowState { Ok(Self { client, executor, - display: Rc::new(X11Display::new(xcb_connection, x_screen_index).unwrap()), + display: Rc::new( + X11Display::new(xcb_connection, scale_factor, x_screen_index).unwrap(), + ), _raw: raw, x_root_window: visual_set.root, - bounds: params.bounds.map(|v| v.0), + bounds: params.bounds, scale_factor, renderer: BladeRenderer::new(gpu, config), atoms: *atoms, @@ -627,6 +629,7 @@ impl X11WindowStatePtr { let is_resize; { let mut state = self.state.borrow_mut(); + let bounds = bounds.map(|f| px(f as f32 / state.scale_factor)); is_resize = bounds.size.width != state.bounds.size.width || bounds.size.height != state.bounds.size.height; @@ -641,9 +644,10 @@ impl X11WindowStatePtr { let gpu_size = query_render_extent(&self.xcb_connection, self.x_window); if state.renderer.viewport_size() != gpu_size { - state - .renderer - .update_drawable_size(size(gpu_size.width as f64, gpu_size.height as f64)); + state.renderer.update_drawable_size(size( + DevicePixels(gpu_size.width as i32), + DevicePixels(gpu_size.height as i32), + )); resize_args = Some((state.content_size(), state.scale_factor)); } } @@ -678,8 +682,8 @@ impl X11WindowStatePtr { } impl PlatformWindow for X11Window { - fn bounds(&self) -> Bounds { - self.0.state.borrow().bounds.map(|v| v.into()) + fn bounds(&self) -> Bounds { + self.0.state.borrow().bounds } fn is_maximized(&self) -> bool { @@ -693,7 +697,11 @@ impl PlatformWindow for X11Window { fn window_bounds(&self) -> WindowBounds { let state = self.0.state.borrow(); - WindowBounds::Windowed(state.bounds.map(|p| DevicePixels(p))) + if self.is_maximized() { + WindowBounds::Maximized(state.bounds) + } else { + WindowBounds::Windowed(state.bounds) + } } fn content_size(&self) -> Size { diff --git a/crates/gpui/src/platform/mac/display.rs b/crates/gpui/src/platform/mac/display.rs index ce3e5ef85c..fc6d6376e0 100644 --- a/crates/gpui/src/platform/mac/display.rs +++ b/crates/gpui/src/platform/mac/display.rs @@ -1,4 +1,4 @@ -use crate::{point, size, Bounds, DevicePixels, DisplayId, PlatformDisplay}; +use crate::{px, size, Bounds, DisplayId, Pixels, PlatformDisplay}; use anyhow::Result; use cocoa::{ appkit::NSScreen, @@ -102,18 +102,15 @@ impl PlatformDisplay for MacDisplay { ])) } - fn bounds(&self) -> Bounds { + fn bounds(&self) -> Bounds { unsafe { // CGDisplayBounds is in "global display" coordinates, where 0 is // the top left of the primary display. let bounds = CGDisplayBounds(self.0); Bounds { - origin: point(DevicePixels(0), DevicePixels(0)), - size: size( - DevicePixels(bounds.size.width as i32), - DevicePixels(bounds.size.height as i32), - ), + origin: Default::default(), + size: size(px(bounds.size.width as f32), px(bounds.size.height as f32)), } } } diff --git a/crates/gpui/src/platform/mac/metal_renderer.rs b/crates/gpui/src/platform/mac/metal_renderer.rs index b6a69cc1b9..f6818fe3de 100644 --- a/crates/gpui/src/platform/mac/metal_renderer.rs +++ b/crates/gpui/src/platform/mac/metal_renderer.rs @@ -8,7 +8,7 @@ use anyhow::{anyhow, Result}; use block::ConcreteBlock; use cocoa::{ base::{NO, YES}, - foundation::NSUInteger, + foundation::{NSSize, NSUInteger}, quartzcore::AutoresizingMask, }; use collections::HashMap; @@ -268,7 +268,11 @@ impl MetalRenderer { .set_presents_with_transaction(presents_with_transaction); } - pub fn update_drawable_size(&mut self, size: Size) { + pub fn update_drawable_size(&mut self, size: Size) { + let size = NSSize { + width: size.width.0 as f64, + height: size.height.0 as f64, + }; unsafe { let _: () = msg_send![ self.layer(), diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 6f9330607f..04746f8823 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -1,11 +1,10 @@ use super::{ns_string, renderer, MacDisplay, NSRange, NSStringExt}; use crate::{ - platform::PlatformInputHandler, point, px, size, AnyWindowHandle, Bounds, DevicePixels, - DisplayLink, ExternalPaths, FileDropEvent, ForegroundExecutor, KeyDownEvent, Keystroke, - Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, - Pixels, PlatformAtlas, PlatformDisplay, PlatformInput, PlatformWindow, Point, PromptLevel, - Size, Timer, WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowKind, - WindowParams, + platform::PlatformInputHandler, point, px, size, AnyWindowHandle, Bounds, DisplayLink, + ExternalPaths, FileDropEvent, ForegroundExecutor, KeyDownEvent, Keystroke, Modifiers, + ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, + PlatformAtlas, PlatformDisplay, PlatformInput, PlatformWindow, Point, PromptLevel, Size, Timer, + WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowKind, WindowParams, }; use block::ConcreteBlock; use cocoa::{ @@ -345,7 +344,7 @@ struct MacWindowState { external_files_dragged: bool, // Whether the next left-mouse click is also the focusing click. first_mouse: bool, - fullscreen_restore_bounds: Bounds, + fullscreen_restore_bounds: Bounds, } impl MacWindowState { @@ -439,7 +438,7 @@ impl MacWindowState { } } - fn bounds(&self) -> Bounds { + fn bounds(&self) -> Bounds { let mut window_frame = unsafe { NSWindow::frame(self.native_window) }; let screen_frame = unsafe { let screen = NSWindow::screen(self.native_window); @@ -452,12 +451,12 @@ impl MacWindowState { let bounds = Bounds::new( point( - ((window_frame.origin.x - screen_frame.origin.x) as i32).into(), - ((window_frame.origin.y - screen_frame.origin.y) as i32).into(), + px((window_frame.origin.x - screen_frame.origin.x) as f32), + px((window_frame.origin.y - screen_frame.origin.y) as f32), ), size( - (window_frame.size.width as i32).into(), - (window_frame.size.height as i32).into(), + px(window_frame.size.width as f32), + px(window_frame.size.height as f32), ), ); bounds @@ -473,13 +472,6 @@ impl MacWindowState { get_scale_factor(self.native_window) } - fn update_drawable_size(&mut self, drawable_size: NSSize) { - self.renderer.update_drawable_size(Size { - width: drawable_size.width, - height: drawable_size.height, - }) - } - fn titlebar_height(&self) -> Pixels { unsafe { let frame = NSWindow::frame(self.native_window); @@ -599,14 +591,6 @@ impl MacWindow { let native_view = NSView::init(native_view); assert!(!native_view.is_null()); - let window_size = { - let scale = get_scale_factor(native_window); - size( - bounds.size.width.0 as f32 * scale, - bounds.size.height.0 as f32 * scale, - ) - }; - let mut window = Self(Arc::new(Mutex::new(MacWindowState { handle, executor, @@ -617,7 +601,7 @@ impl MacWindow { renderer_context, native_window as *mut _, native_view as *mut _, - window_size, + bounds.size.map(|pixels| pixels.0), window_background != WindowBackgroundAppearance::Opaque, ), request_frame_callback: None, @@ -772,7 +756,7 @@ impl Drop for MacWindow { } impl PlatformWindow for MacWindow { - fn bounds(&self) -> Bounds { + fn bounds(&self) -> Bounds { self.0.as_ref().lock().bounds() } @@ -1580,20 +1564,17 @@ extern "C" fn view_did_change_backing_properties(this: &Object, _: Sel) { let window_state = unsafe { get_window_state(this) }; let mut lock = window_state.as_ref().lock(); - let scale_factor = lock.scale_factor() as f64; + let scale_factor = lock.scale_factor(); let size = lock.content_size(); - let drawable_size: NSSize = NSSize { - width: f64::from(size.width) * scale_factor, - height: f64::from(size.height) * scale_factor, - }; + let drawable_size = size.to_device_pixels(scale_factor); unsafe { let _: () = msg_send![ lock.renderer.layer(), - setContentsScale: scale_factor + setContentsScale: scale_factor as f64 ]; } - lock.update_drawable_size(drawable_size); + lock.renderer.update_drawable_size(drawable_size); if let Some(mut callback) = lock.resize_callback.take() { let content_size = lock.content_size(); @@ -1608,7 +1589,8 @@ extern "C" fn set_frame_size(this: &Object, _: Sel, size: NSSize) { let window_state = unsafe { get_window_state(this) }; let mut lock = window_state.as_ref().lock(); - if lock.content_size() == size.into() { + let new_size = Size::::from(size); + if lock.content_size() == new_size { return; } @@ -1616,16 +1598,10 @@ extern "C" fn set_frame_size(this: &Object, _: Sel, size: NSSize) { let _: () = msg_send![super(this, class!(NSView)), setFrameSize: size]; } - let scale_factor = lock.scale_factor() as f64; - let drawable_size: NSSize = NSSize { - width: size.width * scale_factor, - height: size.height * scale_factor, - }; + let scale_factor = lock.scale_factor(); + let drawable_size = new_size.to_device_pixels(scale_factor); + lock.renderer.update_drawable_size(drawable_size); - lock.update_drawable_size(drawable_size); - - drop(lock); - let mut lock = window_state.lock(); if let Some(mut callback) = lock.resize_callback.take() { let content_size = lock.content_size(); let scale_factor = lock.scale_factor(); diff --git a/crates/gpui/src/platform/test/display.rs b/crates/gpui/src/platform/test/display.rs index 4e2e9dbae6..7a8f075c01 100644 --- a/crates/gpui/src/platform/test/display.rs +++ b/crates/gpui/src/platform/test/display.rs @@ -1,12 +1,11 @@ +use crate::{px, Bounds, DisplayId, Pixels, PlatformDisplay, Point}; use anyhow::{Ok, Result}; -use crate::{Bounds, DevicePixels, DisplayId, PlatformDisplay, Point}; - #[derive(Debug)] pub(crate) struct TestDisplay { id: DisplayId, uuid: uuid::Uuid, - bounds: Bounds, + bounds: Bounds, } impl TestDisplay { @@ -14,10 +13,7 @@ impl TestDisplay { TestDisplay { id: DisplayId(1), uuid: uuid::Uuid::new_v4(), - bounds: Bounds::from_corners( - Point::default(), - Point::new(DevicePixels(1920), DevicePixels(1080)), - ), + bounds: Bounds::from_corners(Point::default(), Point::new(px(1920.), px(1080.))), } } } @@ -31,7 +27,7 @@ impl PlatformDisplay for TestDisplay { Ok(self.uuid) } - fn bounds(&self) -> crate::Bounds { + fn bounds(&self) -> crate::Bounds { self.bounds } } diff --git a/crates/gpui/src/platform/test/window.rs b/crates/gpui/src/platform/test/window.rs index 822fdd714b..5946256a8d 100644 --- a/crates/gpui/src/platform/test/window.rs +++ b/crates/gpui/src/platform/test/window.rs @@ -1,8 +1,8 @@ use crate::{ - AnyWindowHandle, AtlasKey, AtlasTextureId, AtlasTile, Bounds, DevicePixels, - DispatchEventResult, Pixels, PlatformAtlas, PlatformDisplay, PlatformInput, - PlatformInputHandler, PlatformWindow, Point, Size, TestPlatform, TileId, WindowAppearance, - WindowBackgroundAppearance, WindowBounds, WindowParams, + AnyWindowHandle, AtlasKey, AtlasTextureId, AtlasTile, Bounds, DispatchEventResult, Pixels, + PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow, Point, + Size, TestPlatform, TileId, WindowAppearance, WindowBackgroundAppearance, WindowBounds, + WindowParams, }; use collections::HashMap; use parking_lot::Mutex; @@ -13,7 +13,7 @@ use std::{ }; pub(crate) struct TestWindowState { - pub(crate) bounds: Bounds, + pub(crate) bounds: Bounds, pub(crate) handle: AnyWindowHandle, display: Rc, pub(crate) title: Option, @@ -79,7 +79,7 @@ impl TestWindow { let Some(mut callback) = lock.resize_callback.take() else { return; }; - lock.bounds.size = size.map(|pixels| (pixels.0 as i32).into()); + lock.bounds.size = size; drop(lock); callback(size, scale_factor); self.0.lock().resize_callback = Some(callback); @@ -108,7 +108,7 @@ impl TestWindow { } impl PlatformWindow for TestWindow { - fn bounds(&self) -> Bounds { + fn bounds(&self) -> Bounds { self.0.lock().bounds } @@ -121,7 +121,7 @@ impl PlatformWindow for TestWindow { } fn content_size(&self) -> Size { - self.bounds().size.into() + self.bounds().size } fn scale_factor(&self) -> f32 { diff --git a/crates/gpui/src/platform/windows/display.rs b/crates/gpui/src/platform/windows/display.rs index e1e7b1e225..e333269cdc 100644 --- a/crates/gpui/src/platform/windows/display.rs +++ b/crates/gpui/src/platform/windows/display.rs @@ -8,13 +8,13 @@ use windows::{ Win32::{Foundation::*, Graphics::Gdi::*}, }; -use crate::{Bounds, DevicePixels, DisplayId, PlatformDisplay, Point, Size}; +use crate::{px, Bounds, DisplayId, Pixels, PlatformDisplay, Point, Size}; #[derive(Debug, Clone, Copy)] pub(crate) struct WindowsDisplay { pub handle: HMONITOR, pub display_id: DisplayId, - bounds: Bounds, + bounds: Bounds, uuid: Uuid, } @@ -34,12 +34,12 @@ impl WindowsDisplay { display_id, bounds: Bounds { origin: Point { - x: DevicePixels(size.left), - y: DevicePixels(size.top), + x: px(size.left as f32), + y: px(size.top as f32), }, size: Size { - width: DevicePixels(size.right - size.left), - height: DevicePixels(size.bottom - size.top), + width: px((size.right - size.left) as f32), + height: px((size.bottom - size.top) as f32), }, }, uuid, @@ -60,12 +60,12 @@ impl WindowsDisplay { display_id: DisplayId(display_id as _), bounds: Bounds { origin: Point { - x: DevicePixels(size.left as i32), - y: DevicePixels(size.top as i32), + x: px(size.left as f32), + y: px(size.top as f32), }, size: Size { - width: DevicePixels((size.right - size.left) as i32), - height: DevicePixels((size.bottom - size.top) as i32), + width: px((size.right - size.left) as f32), + height: px((size.bottom - size.top) as f32), }, }, uuid, @@ -82,12 +82,12 @@ impl WindowsDisplay { display_id, bounds: Bounds { origin: Point { - x: DevicePixels(size.left as i32), - y: DevicePixels(size.top as i32), + x: px(size.left as f32), + y: px(size.top as f32), }, size: Size { - width: DevicePixels((size.right - size.left) as i32), - height: DevicePixels((size.bottom - size.top) as i32), + width: px((size.right - size.left) as f32), + height: px((size.bottom - size.top) as f32), }, }, uuid, @@ -109,11 +109,11 @@ impl WindowsDisplay { } /// Check if the center point of given bounds is inside this monitor - pub fn check_given_bounds(&self, bounds: Bounds) -> bool { + pub fn check_given_bounds(&self, bounds: Bounds) -> bool { let center = bounds.center(); let center = POINT { - x: center.x.0, - y: center.y.0, + x: center.x.0 as i32, + y: center.y.0 as i32, }; let monitor = unsafe { MonitorFromPoint(center, MONITOR_DEFAULTTONULL) }; if monitor.is_invalid() { @@ -167,7 +167,7 @@ impl PlatformDisplay for WindowsDisplay { Ok(self.uuid) } - fn bounds(&self) -> Bounds { + fn bounds(&self) -> Bounds { self.bounds } } diff --git a/crates/gpui/src/platform/windows/events.rs b/crates/gpui/src/platform/windows/events.rs index 1b00d5e59c..560f2d39aa 100644 --- a/crates/gpui/src/platform/windows/events.rs +++ b/crates/gpui/src/platform/windows/events.rs @@ -98,13 +98,13 @@ fn handle_move_msg( lparam: LPARAM, state_ptr: Rc, ) -> Option { - let x = lparam.signed_loword() as i32; - let y = lparam.signed_hiword() as i32; + let x = lparam.signed_loword() as f32; + let y = lparam.signed_hiword() as f32; let mut lock = state_ptr.state.borrow_mut(); - lock.origin = point(x.into(), y.into()); + lock.origin = point(px(x), px(y)); let size = lock.physical_size; - let center_x = x + size.width.0 / 2; - let center_y = y + size.height.0 / 2; + let center_x = x + size.width.0 / 2.; + let center_y = y + size.height.0 / 2.; let monitor_bounds = lock.display.bounds(); if center_x < monitor_bounds.left().0 || center_x > monitor_bounds.right().0 @@ -131,18 +131,15 @@ fn handle_move_msg( fn handle_size_msg(lparam: LPARAM, state_ptr: Rc) -> Option { let width = lparam.loword().max(1) as i32; let height = lparam.hiword().max(1) as i32; - let new_physical_size = size(width.into(), height.into()); let mut lock = state_ptr.state.borrow_mut(); + let new_size = size(DevicePixels(width), DevicePixels(height)); let scale_factor = lock.scale_factor; - lock.physical_size = new_physical_size; - lock.renderer.update_drawable_size(Size { - width: width as f64, - height: height as f64, - }); + lock.renderer.update_drawable_size(new_size); + let new_size = new_size.to_pixels(lock.scale_factor); + lock.physical_size = new_size; if let Some(mut callback) = lock.callbacks.resize.take() { drop(lock); - let logical_size = logical_size(new_physical_size, scale_factor); - callback(logical_size, scale_factor); + callback(new_size, scale_factor); state_ptr.state.borrow_mut().callbacks.resize = Some(callback); } Some(0) diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index 99ff1cda9a..40415e8f17 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -27,14 +27,14 @@ use windows::{ }; use crate::platform::blade::BladeRenderer; -use crate::*; +use crate::{Pixels, *}; pub(crate) struct WindowsWindow(pub Rc); pub struct WindowsWindowState { - pub origin: Point, - pub physical_size: Size, - pub fullscreen_restore_bounds: Bounds, + pub origin: Point, + pub physical_size: Size, + pub fullscreen_restore_bounds: Bounds, pub scale_factor: f32, pub callbacks: Callbacks, @@ -68,8 +68,8 @@ impl WindowsWindowState { current_cursor: HCURSOR, display: WindowsDisplay, ) -> Self { - let origin = point(cs.x.into(), cs.y.into()); - let physical_size = size(cs.cx.into(), cs.cy.into()); + let origin = point(px(cs.x as f32), px(cs.y as f32)); + let physical_size = size(px(cs.cx as f32), px(cs.cy as f32)); let fullscreen_restore_bounds = Bounds { origin, size: physical_size, @@ -113,7 +113,7 @@ impl WindowsWindowState { !self.is_fullscreen() && unsafe { IsZoomed(self.hwnd) }.as_bool() } - fn bounds(&self) -> Bounds { + fn bounds(&self) -> Bounds { Bounds { origin: self.origin, size: self.physical_size, @@ -131,12 +131,12 @@ impl WindowsWindowState { }; let bounds = Bounds { origin: point( - DevicePixels(placement.rcNormalPosition.left), - DevicePixels(placement.rcNormalPosition.top), + px(placement.rcNormalPosition.left as f32), + px(placement.rcNormalPosition.top as f32), ), size: size( - DevicePixels(placement.rcNormalPosition.right - placement.rcNormalPosition.left), - DevicePixels(placement.rcNormalPosition.bottom - placement.rcNormalPosition.top), + px((placement.rcNormalPosition.right - placement.rcNormalPosition.left) as f32), + px((placement.rcNormalPosition.bottom - placement.rcNormalPosition.top) as f32), ), }; @@ -154,7 +154,7 @@ impl WindowsWindowState { /// Currently, GPUI uses logical size of the app to handle mouse interactions (such as /// whether the mouse collides with other elements of GPUI). fn content_size(&self) -> Size { - logical_size(self.physical_size, self.scale_factor) + self.physical_size } fn title_bar_padding(&self) -> Pixels { @@ -306,6 +306,7 @@ impl WindowsWindow { } else { display.default_bounds() }; + let bounds = bounds.to_device_pixels(wnd.0.state.borrow().scale_factor); placement.rcNormalPosition.left = bounds.left().0; placement.rcNormalPosition.right = bounds.right().0; placement.rcNormalPosition.top = bounds.top().0; @@ -353,7 +354,7 @@ impl Drop for WindowsWindow { } impl PlatformWindow for WindowsWindow { - fn bounds(&self) -> Bounds { + fn bounds(&self) -> Bounds { self.0.state.borrow().bounds() } @@ -554,10 +555,10 @@ impl PlatformWindow for WindowsWindow { unsafe { GetWindowRect(state_ptr.hwnd, &mut rc) }.log_err(); let _ = lock.fullscreen.insert(StyleAndBounds { style, - x: rc.left, - y: rc.top, - cx: rc.right - rc.left, - cy: rc.bottom - rc.top, + x: px(rc.left as f32), + y: px(rc.top as f32), + cx: px((rc.right - rc.left) as f32), + cy: px((rc.bottom - rc.top) as f32), }); let style = style & !(WS_THICKFRAME @@ -568,10 +569,10 @@ impl PlatformWindow for WindowsWindow { let bounds = lock.display.bounds(); StyleAndBounds { style, - x: bounds.left().0, - y: bounds.top().0, - cx: bounds.size.width.0, - cy: bounds.size.height.0, + x: bounds.left(), + y: bounds.top(), + cx: bounds.size.width, + cy: bounds.size.height, } }; drop(lock); @@ -580,10 +581,10 @@ impl PlatformWindow for WindowsWindow { SetWindowPos( state_ptr.hwnd, HWND::default(), - x, - y, - cx, - cy, + x.0 as i32, + y.0 as i32, + cx.0 as i32, + cy.0 as i32, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER, ) } @@ -836,10 +837,10 @@ impl ClickState { struct StyleAndBounds { style: WINDOW_STYLE, - x: i32, - y: i32, - cx: i32, - cy: i32, + x: Pixels, + y: Pixels, + cx: Pixels, + cy: Pixels, } fn register_wnd_class(icon_handle: HICON) -> PCWSTR { diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 0c19e76529..13dfc543f5 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -52,8 +52,7 @@ mod prompts; pub use prompts::*; -pub(crate) const DEFAULT_WINDOW_SIZE: Size = - size(DevicePixels(1024), DevicePixels(700)); +pub(crate) const DEFAULT_WINDOW_SIZE: Size = size(px(1024.), px(700.)); /// Represents the two different phases when dispatching events. #[derive(Default, Copy, Clone, Debug, Eq, PartialEq)] @@ -581,8 +580,8 @@ pub(crate) struct ElementStateBox { pub(crate) type_name: &'static str, } -fn default_bounds(display_id: Option, cx: &mut AppContext) -> Bounds { - const DEFAULT_WINDOW_OFFSET: Point = point(DevicePixels(0), DevicePixels(35)); +fn default_bounds(display_id: Option, cx: &mut AppContext) -> Bounds { + const DEFAULT_WINDOW_OFFSET: Point = point(px(0.), px(35.)); cx.active_window() .and_then(|w| w.update(cx, |_, cx| cx.bounds()).ok()) @@ -594,9 +593,7 @@ fn default_bounds(display_id: Option, cx: &mut AppContext) -> Bounds< display .map(|display| display.default_bounds()) - .unwrap_or_else(|| { - Bounds::new(point(DevicePixels(0), DevicePixels(0)), DEFAULT_WINDOW_SIZE) - }) + .unwrap_or_else(|| Bounds::new(point(px(0.), px(0.)), DEFAULT_WINDOW_SIZE)) }) } @@ -1145,7 +1142,7 @@ impl<'a> WindowContext<'a> { } /// Returns the bounds of the current window in the global coordinate space, which could span across multiple displays. - pub fn bounds(&self) -> Bounds { + pub fn bounds(&self) -> Bounds { self.window.platform_window.bounds() } diff --git a/crates/workspace/src/persistence.rs b/crates/workspace/src/persistence.rs index 03bc9ca961..f533233eca 100644 --- a/crates/workspace/src/persistence.rs +++ b/crates/workspace/src/persistence.rs @@ -12,6 +12,7 @@ use sqlez::{ statement::Statement, }; +use ui::px; use util::ResultExt; use uuid::Uuid; @@ -77,10 +78,10 @@ impl Bind for SerializedWindowBounds { let next_index = statement.bind(&"Windowed", start_index)?; statement.bind( &( - SerializedDevicePixels(bounds.origin.x), - SerializedDevicePixels(bounds.origin.y), - SerializedDevicePixels(bounds.size.width), - SerializedDevicePixels(bounds.size.height), + SerializedPixels(bounds.origin.x), + SerializedPixels(bounds.origin.y), + SerializedPixels(bounds.size.width), + SerializedPixels(bounds.size.height), ), next_index, ) @@ -89,10 +90,10 @@ impl Bind for SerializedWindowBounds { let next_index = statement.bind(&"Maximized", start_index)?; statement.bind( &( - SerializedDevicePixels(bounds.origin.x), - SerializedDevicePixels(bounds.origin.y), - SerializedDevicePixels(bounds.size.width), - SerializedDevicePixels(bounds.size.height), + SerializedPixels(bounds.origin.x), + SerializedPixels(bounds.origin.y), + SerializedPixels(bounds.size.width), + SerializedPixels(bounds.size.height), ), next_index, ) @@ -101,10 +102,10 @@ impl Bind for SerializedWindowBounds { let next_index = statement.bind(&"FullScreen", start_index)?; statement.bind( &( - SerializedDevicePixels(bounds.origin.x), - SerializedDevicePixels(bounds.origin.y), - SerializedDevicePixels(bounds.size.width), - SerializedDevicePixels(bounds.size.height), + SerializedPixels(bounds.origin.x), + SerializedPixels(bounds.origin.y), + SerializedPixels(bounds.size.width), + SerializedPixels(bounds.size.height), ), next_index, ) @@ -116,40 +117,17 @@ impl Bind for SerializedWindowBounds { impl Column for SerializedWindowBounds { fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> { let (window_state, next_index) = String::column(statement, start_index)?; + let ((x, y, width, height), _): ((i32, i32, i32, i32), _) = + Column::column(statement, next_index)?; + let bounds = Bounds { + origin: point(px(x as f32), px(y as f32)), + size: size(px(width as f32), px(height as f32)), + }; + let status = match window_state.as_str() { - "Windowed" | "Fixed" => { - let ((x, y, width, height), _) = Column::column(statement, next_index)?; - let x: i32 = x; - let y: i32 = y; - let width: i32 = width; - let height: i32 = height; - SerializedWindowBounds(WindowBounds::Windowed(Bounds { - origin: point(x.into(), y.into()), - size: size(width.into(), height.into()), - })) - } - "Maximized" => { - let ((x, y, width, height), _) = Column::column(statement, next_index)?; - let x: i32 = x; - let y: i32 = y; - let width: i32 = width; - let height: i32 = height; - SerializedWindowBounds(WindowBounds::Maximized(Bounds { - origin: point(x.into(), y.into()), - size: size(width.into(), height.into()), - })) - } - "FullScreen" => { - let ((x, y, width, height), _) = Column::column(statement, next_index)?; - let x: i32 = x; - let y: i32 = y; - let width: i32 = width; - let height: i32 = height; - SerializedWindowBounds(WindowBounds::Fullscreen(Bounds { - origin: point(x.into(), y.into()), - size: size(width.into(), height.into()), - })) - } + "Windowed" | "Fixed" => SerializedWindowBounds(WindowBounds::Windowed(bounds)), + "Maximized" => SerializedWindowBounds(WindowBounds::Maximized(bounds)), + "FullScreen" => SerializedWindowBounds(WindowBounds::Fullscreen(bounds)), _ => bail!("Window State did not have a valid string"), }; @@ -158,16 +136,16 @@ impl Column for SerializedWindowBounds { } #[derive(Clone, Debug, PartialEq)] -struct SerializedDevicePixels(gpui::DevicePixels); -impl sqlez::bindable::StaticColumnCount for SerializedDevicePixels {} +struct SerializedPixels(gpui::Pixels); +impl sqlez::bindable::StaticColumnCount for SerializedPixels {} -impl sqlez::bindable::Bind for SerializedDevicePixels { +impl sqlez::bindable::Bind for SerializedPixels { fn bind( &self, statement: &sqlez::statement::Statement, start_index: i32, ) -> anyhow::Result { - let this: i32 = self.0.into(); + let this: i32 = self.0 .0 as i32; this.bind(statement, start_index) } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index d883fa4b7e..83a88bbc6b 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -28,10 +28,10 @@ use futures::{ }; use gpui::{ actions, canvas, impl_actions, point, relative, size, Action, AnyElement, AnyView, AnyWeakView, - AppContext, AsyncAppContext, AsyncWindowContext, Bounds, DevicePixels, DragMoveEvent, - Entity as _, EntityId, EventEmitter, FocusHandle, FocusableView, Global, KeyContext, Keystroke, - ManagedView, Model, ModelContext, PathPromptOptions, Point, PromptLevel, Render, Size, - Subscription, Task, View, WeakView, WindowBounds, WindowHandle, WindowOptions, + AppContext, AsyncAppContext, AsyncWindowContext, Bounds, DragMoveEvent, Entity as _, EntityId, + EventEmitter, FocusHandle, FocusableView, Global, KeyContext, Keystroke, ManagedView, Model, + ModelContext, PathPromptOptions, Point, PromptLevel, Render, Size, Subscription, Task, View, + WeakView, WindowBounds, WindowHandle, WindowOptions, }; use item::{ FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, PreviewTabsSettings, @@ -79,7 +79,7 @@ use theme::{ActiveTheme, SystemAppearance, ThemeSettings}; pub use toolbar::{Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView}; pub use ui; use ui::{ - div, h_flex, Context as _, Div, FluentBuilder, InteractiveElement as _, IntoElement, + div, h_flex, px, Context as _, Div, FluentBuilder, InteractiveElement as _, IntoElement, ParentElement as _, Pixels, SharedString, Styled as _, ViewContext, VisualContext as _, WindowContext, }; @@ -96,11 +96,11 @@ use crate::persistence::{ use crate::{notifications::NotificationId, persistence::model::LocalPathsOrder}; lazy_static! { - static ref ZED_WINDOW_SIZE: Option> = env::var("ZED_WINDOW_SIZE") + static ref ZED_WINDOW_SIZE: Option> = env::var("ZED_WINDOW_SIZE") .ok() .as_deref() .and_then(parse_pixel_size_env_var); - static ref ZED_WINDOW_POSITION: Option> = env::var("ZED_WINDOW_POSITION") + static ref ZED_WINDOW_POSITION: Option> = env::var("ZED_WINDOW_POSITION") .ok() .as_deref() .and_then(parse_pixel_position_env_var); @@ -3981,7 +3981,7 @@ impl Workspace { } } -fn window_bounds_env_override() -> Option> { +fn window_bounds_env_override() -> Option> { ZED_WINDOW_POSITION .zip(*ZED_WINDOW_SIZE) .map(|(position, size)| Bounds { @@ -5158,18 +5158,18 @@ pub fn reload(reload: &Reload, cx: &mut AppContext) { .detach_and_log_err(cx); } -fn parse_pixel_position_env_var(value: &str) -> Option> { +fn parse_pixel_position_env_var(value: &str) -> Option> { let mut parts = value.split(','); let x: usize = parts.next()?.parse().ok()?; let y: usize = parts.next()?.parse().ok()?; - Some(point((x as i32).into(), (y as i32).into())) + Some(point(px(x as f32), px(y as f32))) } -fn parse_pixel_size_env_var(value: &str) -> Option> { +fn parse_pixel_size_env_var(value: &str) -> Option> { let mut parts = value.split(','); let width: usize = parts.next()?.parse().ok()?; let height: usize = parts.next()?.parse().ok()?; - Some(size((width as i32).into(), (height as i32).into())) + Some(size(px(width as f32), px(height as f32))) } #[cfg(test)]