Detailed changes
@@ -42,31 +42,16 @@ impl RectFExt for RectF {
}
fn to_ns_rect(&self) -> NSRect {
- dbg!(&self);
NSRect::new(
NSPoint::new(
- dbg!(self.origin_x() as f64),
- dbg!(-(self.origin_y() - self.height()) as f64),
+ self.origin_x() as f64,
+ -(self.origin_y() + self.height()) as f64,
),
NSSize::new(self.width() as f64, self.height() as f64),
)
}
}
-pub trait NSPointExt {
- /// Converts self to a Vector2F with y axis pointing down.
- /// Also takes care of converting from window scaled coordinates to screen coordinates
- fn to_window_vector2f(&self, native_window: id) -> Vector2F;
-}
-impl NSPointExt for NSPoint {
- fn to_window_vector2f(&self, native_window: id) -> Vector2F {
- unsafe {
- let point: NSPoint = msg_send![native_window, convertPointFromScreen: self];
- vec2f(point.x as f32, -point.y as f32)
- }
- }
-}
-
pub trait NSRectExt {
/// Converts self to a RectF with y axis pointing down.
/// The resulting RectF will have an origin at the top left of the rectangle.
@@ -77,11 +62,13 @@ pub trait NSRectExt {
/// The resulting RectF will have an origin at the top left of the rectangle.
/// Unlike to_screen_ns_rect, coordinates are not converted and are assumed to already be in screen scale
fn to_rectf(&self) -> RectF;
+
+ fn intersects(&self, other: Self) -> bool;
}
impl NSRectExt for NSRect {
fn to_window_rectf(&self, native_window: id) -> RectF {
unsafe {
- dbg!(self.origin.x);
+ self.origin.x;
let rect: NSRect = native_window.convertRectFromScreen_(*self);
rect.to_rectf()
}
@@ -90,10 +77,21 @@ impl NSRectExt for NSRect {
fn to_rectf(&self) -> RectF {
RectF::new(
vec2f(
- dbg!(self.origin.x as f32),
- dbg!(-(self.origin.y - self.size.height) as f32),
+ self.origin.x as f32,
+ -(self.origin.y + self.size.height) as f32,
),
vec2f(self.size.width as f32, self.size.height as f32),
)
}
+
+ fn intersects(&self, other: Self) -> bool {
+ self.size.width > 0.
+ && self.size.height > 0.
+ && other.size.width > 0.
+ && other.size.height > 0.
+ && self.origin.x <= other.origin.x + other.size.width
+ && self.origin.x + self.size.width >= other.origin.x
+ && self.origin.y <= other.origin.y + other.size.height
+ && self.origin.y + self.size.height >= other.origin.y
+ }
}
@@ -371,14 +371,8 @@ impl WindowState {
return WindowBounds::Fullscreen;
}
- let screen_frame = self
- .native_window
- .screen()
- .visibleFrame()
- .to_window_rectf(self.native_window);
let window_frame = self.frame();
-
- if screen_frame == window_frame {
+ if window_frame == self.native_window.screen().visibleFrame().to_rectf() {
WindowBounds::Maximized
} else {
WindowBounds::Fixed(window_frame)
@@ -388,7 +382,10 @@ impl WindowState {
// Returns the window bounds in window coordinates
fn frame(&self) -> RectF {
- unsafe { NSWindow::frame(self.native_window).to_window_rectf(self.native_window) }
+ unsafe {
+ let ns_frame = NSWindow::frame(self.native_window);
+ ns_frame.to_rectf()
+ }
}
fn content_size(&self) -> Vector2F {
@@ -474,7 +471,13 @@ impl Window {
native_window.setFrame_display_(screen.visibleFrame(), YES);
}
WindowBounds::Fixed(rect) => {
- native_window.setFrame_display_(rect.to_screen_ns_rect(native_window), YES);
+ let screen_frame = screen.visibleFrame();
+ let ns_rect = rect.to_ns_rect();
+ if ns_rect.intersects(screen_frame) {
+ native_window.setFrame_display_(ns_rect, YES);
+ } else {
+ native_window.setFrame_display_(screen_frame, YES);
+ }
}
}
@@ -682,10 +682,28 @@ impl Workspace {
DB.next_id().await.unwrap_or(0)
};
- let (bounds, display) = dbg!(serialized_workspace
+ let (bounds, display) = serialized_workspace
.as_ref()
.and_then(|sw| sw.bounds.zip(sw.display))
- .unzip());
+ .and_then(|(mut bounds, display)| {
+ // Stored bounds are relative to the containing display. So convert back to global coordinates if that screen still exists
+ if let WindowBounds::Fixed(mut window_bounds) = bounds {
+ if let Some(screen) = cx.platform().screen_by_id(display) {
+ let screen_bounds = screen.bounds();
+ window_bounds
+ .set_origin_x(window_bounds.origin_x() + screen_bounds.origin_x());
+ window_bounds
+ .set_origin_y(window_bounds.origin_y() + screen_bounds.origin_y());
+ bounds = WindowBounds::Fixed(window_bounds);
+ } else {
+ // Screen no longer exists. Return none here.
+ return None;
+ }
+ }
+
+ Some((bounds, display))
+ })
+ .unzip();
// Use the serialized workspace to construct the new window
let (_, workspace) = cx.add_window(
@@ -699,9 +717,23 @@ impl Workspace {
cx,
);
(app_state.initialize_workspace)(&mut workspace, &app_state, cx);
- cx.observe_window_bounds(move |_, bounds, display, cx| {
+ cx.observe_window_bounds(move |_, mut bounds, display, cx| {
+ // Transform fixed bounds to be stored in terms of the containing display
+ if let WindowBounds::Fixed(mut window_bounds) = bounds {
+ if let Some(screen) = cx.platform().screen_by_id(display) {
+ let screen_bounds = screen.bounds();
+ window_bounds.set_origin_x(
+ window_bounds.origin_x() - screen_bounds.origin_x(),
+ );
+ window_bounds.set_origin_y(
+ window_bounds.origin_y() - screen_bounds.origin_y(),
+ );
+ bounds = WindowBounds::Fixed(window_bounds);
+ }
+ }
+
cx.background()
- .spawn(DB.set_window_bounds(workspace_id, dbg!(bounds), dbg!(display)))
+ .spawn(DB.set_window_bounds(workspace_id, bounds, display))
.detach_and_log_err(cx);
})
.detach();