window position restoration working
This commit is contained in:
parent
a369fb8033
commit
1593b1e13d
3 changed files with 66 additions and 33 deletions
|
@ -42,31 +42,16 @@ impl RectFExt for RectF {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_ns_rect(&self) -> NSRect {
|
fn to_ns_rect(&self) -> NSRect {
|
||||||
dbg!(&self);
|
|
||||||
NSRect::new(
|
NSRect::new(
|
||||||
NSPoint::new(
|
NSPoint::new(
|
||||||
dbg!(self.origin_x() as f64),
|
self.origin_x() as f64,
|
||||||
dbg!(-(self.origin_y() - self.height()) as f64),
|
-(self.origin_y() + self.height()) as f64,
|
||||||
),
|
),
|
||||||
NSSize::new(self.width() as f64, 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 {
|
pub trait NSRectExt {
|
||||||
/// Converts self to a RectF with y axis pointing down.
|
/// Converts self to a RectF with y axis pointing down.
|
||||||
/// The resulting RectF will have an origin at the top left of the rectangle.
|
/// 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.
|
/// 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
|
/// Unlike to_screen_ns_rect, coordinates are not converted and are assumed to already be in screen scale
|
||||||
fn to_rectf(&self) -> RectF;
|
fn to_rectf(&self) -> RectF;
|
||||||
|
|
||||||
|
fn intersects(&self, other: Self) -> bool;
|
||||||
}
|
}
|
||||||
impl NSRectExt for NSRect {
|
impl NSRectExt for NSRect {
|
||||||
fn to_window_rectf(&self, native_window: id) -> RectF {
|
fn to_window_rectf(&self, native_window: id) -> RectF {
|
||||||
unsafe {
|
unsafe {
|
||||||
dbg!(self.origin.x);
|
self.origin.x;
|
||||||
let rect: NSRect = native_window.convertRectFromScreen_(*self);
|
let rect: NSRect = native_window.convertRectFromScreen_(*self);
|
||||||
rect.to_rectf()
|
rect.to_rectf()
|
||||||
}
|
}
|
||||||
|
@ -90,10 +77,21 @@ impl NSRectExt for NSRect {
|
||||||
fn to_rectf(&self) -> RectF {
|
fn to_rectf(&self) -> RectF {
|
||||||
RectF::new(
|
RectF::new(
|
||||||
vec2f(
|
vec2f(
|
||||||
dbg!(self.origin.x as f32),
|
self.origin.x as f32,
|
||||||
dbg!(-(self.origin.y - self.size.height) as f32),
|
-(self.origin.y + self.size.height) as f32,
|
||||||
),
|
),
|
||||||
vec2f(self.size.width as f32, 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;
|
return WindowBounds::Fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
let screen_frame = self
|
|
||||||
.native_window
|
|
||||||
.screen()
|
|
||||||
.visibleFrame()
|
|
||||||
.to_window_rectf(self.native_window);
|
|
||||||
let window_frame = self.frame();
|
let window_frame = self.frame();
|
||||||
|
if window_frame == self.native_window.screen().visibleFrame().to_rectf() {
|
||||||
if screen_frame == window_frame {
|
|
||||||
WindowBounds::Maximized
|
WindowBounds::Maximized
|
||||||
} else {
|
} else {
|
||||||
WindowBounds::Fixed(window_frame)
|
WindowBounds::Fixed(window_frame)
|
||||||
|
@ -388,7 +382,10 @@ impl WindowState {
|
||||||
|
|
||||||
// Returns the window bounds in window coordinates
|
// Returns the window bounds in window coordinates
|
||||||
fn frame(&self) -> RectF {
|
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 {
|
fn content_size(&self) -> Vector2F {
|
||||||
|
@ -474,7 +471,13 @@ impl Window {
|
||||||
native_window.setFrame_display_(screen.visibleFrame(), YES);
|
native_window.setFrame_display_(screen.visibleFrame(), YES);
|
||||||
}
|
}
|
||||||
WindowBounds::Fixed(rect) => {
|
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)
|
DB.next_id().await.unwrap_or(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (bounds, display) = dbg!(serialized_workspace
|
let (bounds, display) = serialized_workspace
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|sw| sw.bounds.zip(sw.display))
|
.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
|
// Use the serialized workspace to construct the new window
|
||||||
let (_, workspace) = cx.add_window(
|
let (_, workspace) = cx.add_window(
|
||||||
|
@ -699,9 +717,23 @@ impl Workspace {
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
(app_state.initialize_workspace)(&mut workspace, &app_state, 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()
|
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_and_log_err(cx);
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue