Fix issues where screen and window sizes contained Pixels, but were declared as DevicePixels (#12991)

On most platforms, things were working correctly, but had the wrong
type. On X11, there were some problems with window and display size
calculations.

Release Notes:

- Fixed issues with window positioning on X11

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
Max Brunsfeld
2024-06-13 10:48:37 -07:00
committed by GitHub
co-authored by Conrad Irwin Mikayla
parent 22dc88ed3d
commit da281d6d8f
25 changed files with 331 additions and 367 deletions
+4 -7
View File
@@ -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<DevicePixels> {
fn bounds(&self) -> Bounds<Pixels> {
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)),
}
}
}
@@ -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<f64>) {
pub fn update_drawable_size(&mut self, size: Size<DevicePixels>) {
let size = NSSize {
width: size.width.0 as f64,
height: size.height.0 as f64,
};
unsafe {
let _: () = msg_send![
self.layer(),
+22 -46
View File
@@ -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<DevicePixels>,
fullscreen_restore_bounds: Bounds<Pixels>,
}
impl MacWindowState {
@@ -439,7 +438,7 @@ impl MacWindowState {
}
}
fn bounds(&self) -> Bounds<DevicePixels> {
fn bounds(&self) -> Bounds<Pixels> {
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<DevicePixels> {
fn bounds(&self) -> Bounds<Pixels> {
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::<Pixels>::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();