Merge pull request #2194 from zed-industries/window-position-env-vars
Fix handling of ZED_WINDOW_{SIZE,POSITION} env vars
This commit is contained in:
commit
ecf77a510a
3 changed files with 67 additions and 55 deletions
|
@ -34,7 +34,10 @@ use futures::{
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
elements::*,
|
elements::*,
|
||||||
geometry::vector::Vector2F,
|
geometry::{
|
||||||
|
rect::RectF,
|
||||||
|
vector::{vec2f, Vector2F},
|
||||||
|
},
|
||||||
impl_actions, impl_internal_actions,
|
impl_actions, impl_internal_actions,
|
||||||
keymap_matcher::KeymapContext,
|
keymap_matcher::KeymapContext,
|
||||||
platform::{CursorStyle, WindowOptions},
|
platform::{CursorStyle, WindowOptions},
|
||||||
|
@ -47,7 +50,7 @@ use language::LanguageRegistry;
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
cmp,
|
cmp, env,
|
||||||
future::Future,
|
future::Future,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
|
@ -58,6 +61,7 @@ use crate::{
|
||||||
notifications::simple_message_notification::{MessageNotification, OsOpen},
|
notifications::simple_message_notification::{MessageNotification, OsOpen},
|
||||||
persistence::model::{SerializedPane, SerializedPaneGroup, SerializedWorkspace},
|
persistence::model::{SerializedPane, SerializedPaneGroup, SerializedWorkspace},
|
||||||
};
|
};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use notifications::NotificationHandle;
|
use notifications::NotificationHandle;
|
||||||
pub use pane::*;
|
pub use pane::*;
|
||||||
|
@ -79,6 +83,17 @@ use theme::{Theme, ThemeRegistry};
|
||||||
pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
|
pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref ZED_WINDOW_SIZE: Option<Vector2F> = env::var("ZED_WINDOW_SIZE")
|
||||||
|
.ok()
|
||||||
|
.as_deref()
|
||||||
|
.and_then(parse_pixel_position_env_var);
|
||||||
|
static ref ZED_WINDOW_POSITION: Option<Vector2F> = env::var("ZED_WINDOW_POSITION")
|
||||||
|
.ok()
|
||||||
|
.as_deref()
|
||||||
|
.and_then(parse_pixel_position_env_var);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct RemoveWorktreeFromProject(pub WorktreeId);
|
pub struct RemoveWorktreeFromProject(pub WorktreeId);
|
||||||
|
|
||||||
|
@ -684,28 +699,47 @@ impl Workspace {
|
||||||
DB.next_id().await.unwrap_or(0)
|
DB.next_id().await.unwrap_or(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (bounds, display) = serialized_workspace
|
let window_bounds_override =
|
||||||
.as_ref()
|
ZED_WINDOW_POSITION
|
||||||
.and_then(|sw| sw.bounds.zip(sw.display))
|
.zip(*ZED_WINDOW_SIZE)
|
||||||
.and_then(|(mut bounds, display)| {
|
.map(|(position, size)| {
|
||||||
// Stored bounds are relative to the containing display. So convert back to global coordinates if that screen still exists
|
WindowBounds::Fixed(RectF::new(
|
||||||
if let WindowBounds::Fixed(mut window_bounds) = bounds {
|
cx.platform().screens()[0].bounds().origin() + position,
|
||||||
if let Some(screen) = cx.platform().screen_by_id(display) {
|
size,
|
||||||
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))
|
let (bounds, display) = if let Some(bounds) = window_bounds_override {
|
||||||
})
|
(Some(bounds), None)
|
||||||
.unzip();
|
} else {
|
||||||
|
serialized_workspace
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|serialized_workspace| {
|
||||||
|
let display = serialized_workspace.display?;
|
||||||
|
let mut bounds = serialized_workspace.bounds?;
|
||||||
|
|
||||||
|
// 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(
|
||||||
|
@ -2848,6 +2882,13 @@ pub fn open_new(app_state: &Arc<AppState>, cx: &mut MutableAppContext) -> Task<(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_pixel_position_env_var(value: &str) -> Option<Vector2F> {
|
||||||
|
let mut parts = value.split(',');
|
||||||
|
let width: usize = parts.next()?.parse().ok()?;
|
||||||
|
let height: usize = parts.next()?.parse().ok()?;
|
||||||
|
Some(vec2f(width as f32, height as f32))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
|
@ -17,16 +17,12 @@ use feedback::{
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
geometry::{
|
geometry::vector::vec2f,
|
||||||
rect::RectF,
|
|
||||||
vector::{vec2f, Vector2F},
|
|
||||||
},
|
|
||||||
impl_actions,
|
impl_actions,
|
||||||
platform::{WindowBounds, WindowOptions},
|
platform::{WindowBounds, WindowOptions},
|
||||||
AssetSource, AsyncAppContext, Platform, PromptLevel, TitlebarOptions, ViewContext, WindowKind,
|
AssetSource, AsyncAppContext, Platform, PromptLevel, TitlebarOptions, ViewContext, WindowKind,
|
||||||
};
|
};
|
||||||
use language::Rope;
|
use language::Rope;
|
||||||
use lazy_static::lazy_static;
|
|
||||||
pub use lsp;
|
pub use lsp;
|
||||||
pub use project;
|
pub use project;
|
||||||
use project_panel::ProjectPanel;
|
use project_panel::ProjectPanel;
|
||||||
|
@ -76,17 +72,6 @@ actions!(
|
||||||
|
|
||||||
const MIN_FONT_SIZE: f32 = 6.0;
|
const MIN_FONT_SIZE: f32 = 6.0;
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
static ref ZED_WINDOW_SIZE: Option<Vector2F> = env::var("ZED_WINDOW_SIZE")
|
|
||||||
.ok()
|
|
||||||
.as_deref()
|
|
||||||
.and_then(parse_pixel_position_env_var);
|
|
||||||
static ref ZED_WINDOW_POSITION: Option<Vector2F> = env::var("ZED_WINDOW_POSITION")
|
|
||||||
.ok()
|
|
||||||
.as_deref()
|
|
||||||
.and_then(parse_pixel_position_env_var);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
|
pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
|
||||||
cx.add_action(about);
|
cx.add_action(about);
|
||||||
cx.add_global_action(|_: &Hide, cx: &mut gpui::MutableAppContext| {
|
cx.add_global_action(|_: &Hide, cx: &mut gpui::MutableAppContext| {
|
||||||
|
@ -379,14 +364,7 @@ pub fn build_window_options(
|
||||||
display: Option<Uuid>,
|
display: Option<Uuid>,
|
||||||
platform: &dyn Platform,
|
platform: &dyn Platform,
|
||||||
) -> WindowOptions<'static> {
|
) -> WindowOptions<'static> {
|
||||||
let bounds = bounds
|
let bounds = bounds.unwrap_or(WindowBounds::Maximized);
|
||||||
.or_else(|| {
|
|
||||||
ZED_WINDOW_POSITION
|
|
||||||
.zip(*ZED_WINDOW_SIZE)
|
|
||||||
.map(|(position, size)| WindowBounds::Fixed(RectF::new(position, size)))
|
|
||||||
})
|
|
||||||
.unwrap_or(WindowBounds::Maximized);
|
|
||||||
|
|
||||||
let screen = display.and_then(|display| platform.screen_by_id(display));
|
let screen = display.and_then(|display| platform.screen_by_id(display));
|
||||||
|
|
||||||
WindowOptions {
|
WindowOptions {
|
||||||
|
@ -688,13 +666,6 @@ fn schema_file_match(path: &Path) -> &Path {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pixel_position_env_var(value: &str) -> Option<Vector2F> {
|
|
||||||
let mut parts = value.split(',');
|
|
||||||
let width: usize = parts.next()?.parse().ok()?;
|
|
||||||
let height: usize = parts.next()?.parse().ok()?;
|
|
||||||
Some(vec2f(width as f32, height as f32))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -31,7 +31,7 @@ scale_factor=1
|
||||||
if [[ $resolution_line =~ Retina ]]; then scale_factor=2; fi
|
if [[ $resolution_line =~ Retina ]]; then scale_factor=2; fi
|
||||||
width=$(expr ${screen_size[0]} / 2 / $scale_factor)
|
width=$(expr ${screen_size[0]} / 2 / $scale_factor)
|
||||||
height=${screen_size[1] / $scale_factor}
|
height=${screen_size[1] / $scale_factor}
|
||||||
y=$(expr $height / 2)
|
y=0
|
||||||
|
|
||||||
position_1=0,${y}
|
position_1=0,${y}
|
||||||
position_2=${width},${y}
|
position_2=${width},${y}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue