Compare commits
24 Commits
fix-git-ht
...
v0.140.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5f6c402c8 | ||
|
|
2b3adae15c | ||
|
|
2eb28fffff | ||
|
|
29245ffca6 | ||
|
|
ac63c74651 | ||
|
|
f41926fa0a | ||
|
|
b4736dbb23 | ||
|
|
eea4e7b7bf | ||
|
|
2e3410b242 | ||
|
|
6f4c119450 | ||
|
|
96336b2654 | ||
|
|
eab19a8e2d | ||
|
|
1e6ee30845 | ||
|
|
69cbb124f6 | ||
|
|
5d6a4a158d | ||
|
|
705e754249 | ||
|
|
ed1f803637 | ||
|
|
10698c0840 | ||
|
|
1ba2909cdf | ||
|
|
4a6d8f61c2 | ||
|
|
1b07cce2b6 | ||
|
|
55426a344f | ||
|
|
2b936fe5a8 | ||
|
|
3977b8574b |
@@ -4,3 +4,11 @@ rustflags = ["-C", "symbol-mangling-version=v0", "--cfg", "tokio_unstable"]
|
||||
|
||||
[alias]
|
||||
xtask = "run --package xtask --"
|
||||
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
linker = "clang"
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
||||
|
||||
[target.aarch64-unknown-linux-gnu]
|
||||
linker = "clang"
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
||||
|
||||
83
.github/workflows/ci.yml
vendored
83
.github/workflows/ci.yml
vendored
@@ -325,3 +325,86 @@ jobs:
|
||||
body: ""
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
bundle-linux-aarch64:
|
||||
timeout-minutes: 60
|
||||
name: Create arm64 Linux bundle
|
||||
runs-on:
|
||||
- hosted-linux-arm-1
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
|
||||
needs: [linux_tests]
|
||||
env:
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: false
|
||||
- name: "Setup jq"
|
||||
uses: dcarbone/install-jq-action@v2
|
||||
|
||||
- name: Set up Clang
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y llvm-10 clang-10 build-essential cmake pkg-config libasound2-dev libfontconfig-dev libwayland-dev libxkbcommon-x11-dev libssl-dev libzstd-dev libvulkan1 libgit2-dev
|
||||
echo "/usr/lib/llvm-10/bin" >> $GITHUB_PATH
|
||||
|
||||
- uses: rui314/setup-mold@v1
|
||||
with:
|
||||
mold_version: 2.32.0
|
||||
|
||||
- name: rustup
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Limit target directory size
|
||||
run: script/clear-target-dir-if-larger-than 100
|
||||
|
||||
- name: Determine version and release channel
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
version=$(script/get-crate-version zed)
|
||||
channel=$(cat crates/zed/RELEASE_CHANNEL)
|
||||
echo "Publishing version: ${version} on release channel ${channel}"
|
||||
echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
|
||||
|
||||
expected_tag_name=""
|
||||
case ${channel} in
|
||||
stable)
|
||||
expected_tag_name="v${version}";;
|
||||
preview)
|
||||
expected_tag_name="v${version}-pre";;
|
||||
nightly)
|
||||
expected_tag_name="v${version}-nightly";;
|
||||
*)
|
||||
echo "can't publish a release on channel ${channel}"
|
||||
exit 1;;
|
||||
esac
|
||||
if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
|
||||
echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create and upload Linux .tar.gz bundle
|
||||
run: script/bundle-linux
|
||||
|
||||
- name: Upload Linux bundle to workflow run if main branch or specific label
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
|
||||
with:
|
||||
name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz
|
||||
path: target/release/zed-*.tar.gz
|
||||
|
||||
- name: Upload app bundle to release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: ${{ env.RELEASE_CHANNEL == 'preview' }}
|
||||
with:
|
||||
draft: true
|
||||
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
|
||||
files: target/release/zed-linux-aarch64.tar.gz
|
||||
body: ""
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -2241,6 +2241,7 @@ dependencies = [
|
||||
"url",
|
||||
"util",
|
||||
"windows 0.56.0",
|
||||
"worktree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -13182,7 +13183,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.140.0"
|
||||
version = "0.140.5"
|
||||
dependencies = [
|
||||
"activity_indicator",
|
||||
"anyhow",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -51,6 +51,7 @@ time.workspace = true
|
||||
tiny_http = "0.8"
|
||||
url.workspace = true
|
||||
util.workspace = true
|
||||
worktree.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
clock = { workspace = true, features = ["test-support"] }
|
||||
|
||||
@@ -3,6 +3,7 @@ mod event_coalescer;
|
||||
use crate::{ChannelId, TelemetrySettings};
|
||||
use chrono::{DateTime, Utc};
|
||||
use clock::SystemClock;
|
||||
use collections::{HashMap, HashSet};
|
||||
use futures::Future;
|
||||
use gpui::{AppContext, BackgroundExecutor, Task};
|
||||
use http::{self, HttpClient, HttpClientWithUrl, Method};
|
||||
@@ -23,6 +24,7 @@ use tempfile::NamedTempFile;
|
||||
#[cfg(not(debug_assertions))]
|
||||
use util::ResultExt;
|
||||
use util::TryFutureExt;
|
||||
use worktree::{UpdatedEntriesSet, WorktreeId};
|
||||
|
||||
use self::event_coalescer::EventCoalescer;
|
||||
|
||||
@@ -47,12 +49,31 @@ struct TelemetryState {
|
||||
first_event_date_time: Option<DateTime<Utc>>,
|
||||
event_coalescer: EventCoalescer,
|
||||
max_queue_size: usize,
|
||||
worktree_id_map: WorktreeIdMap,
|
||||
|
||||
os_name: String,
|
||||
app_version: String,
|
||||
os_version: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct WorktreeIdMap(HashMap<String, ProjectCache>);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ProjectCache {
|
||||
name: String,
|
||||
worktree_ids_reported: HashSet<WorktreeId>,
|
||||
}
|
||||
|
||||
impl ProjectCache {
|
||||
fn new(name: String) -> Self {
|
||||
Self {
|
||||
name,
|
||||
worktree_ids_reported: HashSet::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
const MAX_QUEUE_LEN: usize = 5;
|
||||
|
||||
@@ -180,6 +201,16 @@ impl Telemetry {
|
||||
first_event_date_time: None,
|
||||
event_coalescer: EventCoalescer::new(clock.clone()),
|
||||
max_queue_size: MAX_QUEUE_LEN,
|
||||
worktree_id_map: WorktreeIdMap(HashMap::from_iter([
|
||||
(
|
||||
"yarn.lock".to_string(),
|
||||
ProjectCache::new("yarn".to_string()),
|
||||
),
|
||||
(
|
||||
"package.json".to_string(),
|
||||
ProjectCache::new("node".to_string()),
|
||||
),
|
||||
])),
|
||||
|
||||
os_version: None,
|
||||
os_name: os_name(),
|
||||
@@ -256,7 +287,7 @@ impl Telemetry {
|
||||
state.installation_id = installation_id.map(|id| id.into());
|
||||
state.session_id = Some(session_id);
|
||||
state.app_version = release_channel::AppVersion::global(cx).to_string();
|
||||
state.os_name = os_version();
|
||||
state.os_name = os_name();
|
||||
|
||||
drop(state);
|
||||
|
||||
@@ -450,6 +481,52 @@ impl Telemetry {
|
||||
self.report_event(event)
|
||||
}
|
||||
|
||||
pub fn report_discovered_project_events(
|
||||
self: &Arc<Self>,
|
||||
worktree_id: WorktreeId,
|
||||
updated_entries_set: &UpdatedEntriesSet,
|
||||
) {
|
||||
let project_names: Vec<String> = {
|
||||
let mut state = self.state.lock();
|
||||
state
|
||||
.worktree_id_map
|
||||
.0
|
||||
.iter_mut()
|
||||
.filter_map(|(project_file_name, project_type_telemetry)| {
|
||||
if project_type_telemetry
|
||||
.worktree_ids_reported
|
||||
.contains(&worktree_id)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let project_file_found = updated_entries_set.iter().any(|(path, _, _)| {
|
||||
path.as_ref()
|
||||
.file_name()
|
||||
.and_then(|name| name.to_str())
|
||||
.map(|name_str| name_str == project_file_name)
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
if !project_file_found {
|
||||
return None;
|
||||
}
|
||||
|
||||
project_type_telemetry
|
||||
.worktree_ids_reported
|
||||
.insert(worktree_id);
|
||||
|
||||
Some(project_type_telemetry.name.clone())
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
// Done on purpose to avoid calling `self.state.lock()` multiple times
|
||||
for project_name in project_names {
|
||||
self.report_app_event(format!("open {} project", project_name));
|
||||
}
|
||||
}
|
||||
|
||||
fn report_event(self: &Arc<Self>, event: Event) {
|
||||
let mut state = self.state.lock();
|
||||
|
||||
@@ -513,10 +590,6 @@ impl Telemetry {
|
||||
return;
|
||||
}
|
||||
|
||||
if ZED_CLIENT_CHECKSUM_SEED.is_none() {
|
||||
return;
|
||||
};
|
||||
|
||||
let this = self.clone();
|
||||
self.executor
|
||||
.spawn(
|
||||
@@ -552,9 +625,7 @@ impl Telemetry {
|
||||
serde_json::to_writer(&mut json_bytes, &request_body)?;
|
||||
}
|
||||
|
||||
let Some(checksum) = calculate_json_checksum(&json_bytes) else {
|
||||
return Ok(());
|
||||
};
|
||||
let checksum = calculate_json_checksum(&json_bytes).unwrap_or("".to_string());
|
||||
|
||||
let request = http::Request::builder()
|
||||
.method(Method::POST)
|
||||
|
||||
@@ -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<dyn PlatformDisplay>,
|
||||
window_size: Size<Pixels>,
|
||||
size: Size<Pixels>,
|
||||
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<DevicePixels> = window_size.into();
|
||||
|
||||
let bounds = gpui::Bounds::<DevicePixels> {
|
||||
origin: screen_bounds.upper_right()
|
||||
let bounds = gpui::Bounds::<Pixels> {
|
||||
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();
|
||||
|
||||
@@ -476,6 +476,42 @@ fn test_canceling_pending_selection(cx: &mut TestAppContext) {
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_movement_actions_with_pending_selection(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
let view = cx.add_window(|cx| {
|
||||
let buffer = MultiBuffer::build_simple("aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx);
|
||||
build_editor(buffer, cx)
|
||||
});
|
||||
|
||||
_ = view.update(cx, |view, cx| {
|
||||
view.begin_selection(DisplayPoint::new(DisplayRow(2), 2), false, 1, cx);
|
||||
assert_eq!(
|
||||
view.selections.display_ranges(cx),
|
||||
[DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(2), 2)]
|
||||
);
|
||||
|
||||
view.move_down(&Default::default(), cx);
|
||||
assert_eq!(
|
||||
view.selections.display_ranges(cx),
|
||||
[DisplayPoint::new(DisplayRow(3), 2)..DisplayPoint::new(DisplayRow(3), 2)]
|
||||
);
|
||||
|
||||
view.begin_selection(DisplayPoint::new(DisplayRow(2), 2), false, 1, cx);
|
||||
assert_eq!(
|
||||
view.selections.display_ranges(cx),
|
||||
[DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(2), 2)]
|
||||
);
|
||||
|
||||
view.move_up(&Default::default(), cx);
|
||||
assert_eq!(
|
||||
view.selections.display_ranges(cx),
|
||||
[DisplayPoint::new(DisplayRow(1), 2)..DisplayPoint::new(DisplayRow(1), 2)]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_clone(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
@@ -7654,8 +7690,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()
|
||||
},
|
||||
|
||||
@@ -256,7 +256,10 @@ impl SelectionsCollection {
|
||||
}
|
||||
|
||||
pub fn first_anchor(&self) -> Selection<Anchor> {
|
||||
self.disjoint[0].clone()
|
||||
self.pending
|
||||
.as_ref()
|
||||
.map(|pending| pending.selection.clone())
|
||||
.unwrap_or_else(|| self.disjoint.first().cloned().unwrap())
|
||||
}
|
||||
|
||||
pub fn first<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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<DevicePixels> = window_size.into();
|
||||
|
||||
let bounds = gpui::Bounds::<DevicePixels> {
|
||||
origin: screen_bounds.upper_right()
|
||||
- point(size.width + popup_margin_width, popup_margin_height),
|
||||
size: window_size.into(),
|
||||
let bounds = gpui::Bounds::<Pixels> {
|
||||
origin: screen.bounds().upper_right()
|
||||
- point(size.width + margin_right, margin_height),
|
||||
size,
|
||||
};
|
||||
|
||||
WindowOptions {
|
||||
|
||||
@@ -363,15 +363,6 @@ pub struct Size<T: Clone + Default + Debug> {
|
||||
pub height: T,
|
||||
}
|
||||
|
||||
impl From<Size<DevicePixels>> for Size<Pixels> {
|
||||
fn from(size: Size<DevicePixels>) -> Self {
|
||||
Size {
|
||||
width: Pixels(size.width.0 as f32),
|
||||
height: Pixels(size.height.0 as f32),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a new `Size<T>` with the provided width and height.
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -633,15 +624,6 @@ impl<T: Clone + Default + Debug> From<Point<T>> for Size<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Size<Pixels>> for Size<DevicePixels> {
|
||||
fn from(size: Size<Pixels>) -> Self {
|
||||
Size {
|
||||
width: DevicePixels(size.width.0 as i32),
|
||||
height: DevicePixels(size.height.0 as i32),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Size<Pixels>> for Size<DefiniteLength> {
|
||||
fn from(size: Size<Pixels>) -> Self {
|
||||
Size {
|
||||
@@ -722,28 +704,27 @@ pub struct Bounds<T: Clone + Default + Debug> {
|
||||
pub size: Size<T>,
|
||||
}
|
||||
|
||||
impl Bounds<DevicePixels> {
|
||||
impl Bounds<Pixels> {
|
||||
/// Generate a centered bounds for the given display or primary display if none is provided
|
||||
pub fn centered(
|
||||
display_id: Option<DisplayId>,
|
||||
size: impl Into<Size<DevicePixels>>,
|
||||
size: Size<Pixels>,
|
||||
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<DevicePixels> {
|
||||
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<T: PartialOrd + Default + Debug + Clone> Bounds<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Size<DevicePixels> {
|
||||
/// Converts the size from physical to logical pixels.
|
||||
pub(crate) fn to_pixels(self, scale_factor: f32) -> Size<Pixels> {
|
||||
size(
|
||||
px(self.width.0 as f32 / scale_factor),
|
||||
px(self.height.0 as f32 / scale_factor),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Size<Pixels> {
|
||||
/// Converts the size from physical to logical pixels.
|
||||
pub(crate) fn to_device_pixels(self, scale_factor: f32) -> Size<DevicePixels> {
|
||||
size(
|
||||
DevicePixels((self.width.0 * scale_factor) as i32),
|
||||
DevicePixels((self.height.0 * scale_factor) as i32),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Bounds<Pixels> {
|
||||
/// Scales the bounds by a given factor, typically used to adjust for display scaling.
|
||||
///
|
||||
@@ -1346,6 +1347,30 @@ impl Bounds<Pixels> {
|
||||
size: self.size.scale(factor),
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the bounds from logical pixels to physical pixels
|
||||
pub fn to_device_pixels(&self, factor: f32) -> Bounds<DevicePixels> {
|
||||
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<DevicePixels> {
|
||||
/// Convert the bounds from physical pixels to logical pixels
|
||||
pub fn to_pixels(self, scale_factor: f32) -> Bounds<Pixels> {
|
||||
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<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
|
||||
|
||||
@@ -187,12 +187,12 @@ pub trait PlatformDisplay: Send + Sync + Debug {
|
||||
fn uuid(&self) -> Result<Uuid>;
|
||||
|
||||
/// Get the bounds for this display
|
||||
fn bounds(&self) -> Bounds<DevicePixels>;
|
||||
fn bounds(&self) -> Bounds<Pixels>;
|
||||
|
||||
/// Get the default bounds for this display to place a window
|
||||
fn default_bounds(&self) -> Bounds<DevicePixels> {
|
||||
fn default_bounds(&self) -> Bounds<Pixels> {
|
||||
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<DevicePixels>;
|
||||
fn bounds(&self) -> Bounds<Pixels>;
|
||||
fn is_maximized(&self) -> bool;
|
||||
fn window_bounds(&self) -> WindowBounds;
|
||||
fn content_size(&self) -> Size<Pixels>;
|
||||
@@ -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<DevicePixels>,
|
||||
pub bounds: Bounds<Pixels>,
|
||||
|
||||
/// The titlebar configuration of the window
|
||||
pub titlebar: Option<TitlebarOptions>,
|
||||
@@ -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<DevicePixels>),
|
||||
Windowed(Bounds<Pixels>),
|
||||
/// Indicates that the window should open in a maximized state.
|
||||
/// The bounds provided here represent the restore size of the window.
|
||||
Maximized(Bounds<DevicePixels>),
|
||||
Maximized(Bounds<Pixels>),
|
||||
/// Indicates that the window should open in fullscreen mode.
|
||||
/// The bounds provided here represent the restore size of the window.
|
||||
Fullscreen(Bounds<DevicePixels>),
|
||||
Fullscreen(Bounds<Pixels>),
|
||||
}
|
||||
|
||||
impl Default for WindowBounds {
|
||||
@@ -614,7 +614,7 @@ impl Default for WindowBounds {
|
||||
|
||||
impl WindowBounds {
|
||||
/// Retrieve the inner bounds
|
||||
pub fn get_bounds(&self) -> Bounds<DevicePixels> {
|
||||
pub fn get_bounds(&self) -> Bounds<Pixels> {
|
||||
match self {
|
||||
WindowBounds::Windowed(bounds) => *bounds,
|
||||
WindowBounds::Maximized(bounds) => *bounds,
|
||||
|
||||
@@ -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<f64>) {
|
||||
pub fn update_drawable_size(&mut self, size: Size<DevicePixels>) {
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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<dyn PlatformDisplay>
|
||||
})
|
||||
.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<dyn PlatformDisplay>
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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<String>,
|
||||
pub bounds: Bounds<DevicePixels>,
|
||||
pub bounds: Bounds<Pixels>,
|
||||
}
|
||||
|
||||
impl Hash for WaylandDisplay {
|
||||
@@ -35,7 +35,7 @@ impl PlatformDisplay for WaylandDisplay {
|
||||
}
|
||||
}
|
||||
|
||||
fn bounds(&self) -> Bounds<DevicePixels> {
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
self.bounds
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<u32>,
|
||||
bounds: Bounds<Pixels>,
|
||||
scale: f32,
|
||||
input_handler: Option<PlatformInputHandler>,
|
||||
decoration_state: WaylandDecorationState,
|
||||
fullscreen: bool,
|
||||
maximized: bool,
|
||||
windowed_bounds: Bounds<DevicePixels>,
|
||||
windowed_bounds: Bounds<Pixels>,
|
||||
client: WaylandClientStatePtr,
|
||||
handle: AnyWindowHandle,
|
||||
active: bool,
|
||||
@@ -108,8 +107,6 @@ impl WaylandWindowState {
|
||||
globals: Globals,
|
||||
options: WindowParams,
|
||||
) -> anyhow::Result<Self> {
|
||||
let bounds = options.bounds.map(|p| p.0 as u32);
|
||||
|
||||
let raw = RawWindow {
|
||||
window: surface.id().as_ptr().cast::<c_void>(),
|
||||
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<NonZeroU32>,
|
||||
height: Option<NonZeroU32>,
|
||||
scale: Option<f32>,
|
||||
) {
|
||||
let (width, height, scale) = {
|
||||
pub fn set_size_and_scale(&self, size: Option<Size<Pixels>>, scale: Option<f32>) {
|
||||
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<NonZeroU32>, height: Option<NonZeroU32>) {
|
||||
self.set_size_and_scale(width, height, None);
|
||||
pub fn resize(&self, size: Size<Pixels>) {
|
||||
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<DevicePixels> {
|
||||
self.borrow().bounds.map(|p| DevicePixels(p as i32))
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
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<Pixels> {
|
||||
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<Rc<dyn PlatformDisplay>> {
|
||||
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<dyn PlatformDisplay>
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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<dyn PlatformDisplay>)
|
||||
Some(Rc::new(X11Display::new(
|
||||
&state.xcb_connection,
|
||||
state.scale_factor,
|
||||
root_id,
|
||||
)?) as Rc<dyn PlatformDisplay>)
|
||||
})
|
||||
.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,
|
||||
)?))
|
||||
}
|
||||
|
||||
@@ -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<DevicePixels>,
|
||||
bounds: Bounds<Pixels>,
|
||||
uuid: Uuid,
|
||||
}
|
||||
|
||||
impl X11Display {
|
||||
pub(crate) fn new(xc: &XCBConnection, x_screen_index: usize) -> Option<Self> {
|
||||
pub(crate) fn new(
|
||||
xc: &XCBConnection,
|
||||
scale_factor: f32,
|
||||
x_screen_index: usize,
|
||||
) -> Option<Self> {
|
||||
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<DevicePixels> {
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
self.bounds
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<i32>,
|
||||
bounds: Bounds<Pixels>,
|
||||
scale_factor: f32,
|
||||
renderer: BladeRenderer,
|
||||
display: Rc<dyn PlatformDisplay>,
|
||||
@@ -256,7 +256,6 @@ impl X11WindowState {
|
||||
};
|
||||
|
||||
let win_aux = xproto::CreateWindowAux::new()
|
||||
.background_pixel(x11rb::NONE)
|
||||
// https://stackoverflow.com/questions/43218127/x11-xlib-xcb-creating-a-window-requires-border-pixel-if-specifying-colormap-wh
|
||||
.border_pixel(visual_set.black_pixel)
|
||||
.colormap(colormap)
|
||||
@@ -273,10 +272,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,
|
||||
@@ -335,7 +334,6 @@ impl X11WindowState {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
xcb_connection.map_window(x_window).unwrap();
|
||||
xcb_connection.flush().unwrap();
|
||||
|
||||
let raw = RawWindow {
|
||||
@@ -366,14 +364,17 @@ impl X11WindowState {
|
||||
size: query_render_extent(xcb_connection, x_window),
|
||||
transparent: params.window_background != WindowBackgroundAppearance::Opaque,
|
||||
};
|
||||
xcb_connection.map_window(x_window).unwrap();
|
||||
|
||||
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 +628,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 +643,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 +681,8 @@ impl X11WindowStatePtr {
|
||||
}
|
||||
|
||||
impl PlatformWindow for X11Window {
|
||||
fn bounds(&self) -> Bounds<DevicePixels> {
|
||||
self.0.state.borrow().bounds.map(|v| v.into())
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
self.0.state.borrow().bounds
|
||||
}
|
||||
|
||||
fn is_maximized(&self) -> bool {
|
||||
@@ -693,7 +696,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<Pixels> {
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<DevicePixels>,
|
||||
bounds: Bounds<Pixels>,
|
||||
}
|
||||
|
||||
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<crate::DevicePixels> {
|
||||
fn bounds(&self) -> crate::Bounds<crate::Pixels> {
|
||||
self.bounds
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<DevicePixels>,
|
||||
pub(crate) bounds: Bounds<Pixels>,
|
||||
pub(crate) handle: AnyWindowHandle,
|
||||
display: Rc<dyn PlatformDisplay>,
|
||||
pub(crate) title: Option<String>,
|
||||
@@ -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<DevicePixels> {
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
self.0.lock().bounds
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ impl PlatformWindow for TestWindow {
|
||||
}
|
||||
|
||||
fn content_size(&self) -> Size<Pixels> {
|
||||
self.bounds().size.into()
|
||||
self.bounds().size
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f32 {
|
||||
|
||||
@@ -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<DevicePixels>,
|
||||
bounds: Bounds<Pixels>,
|
||||
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<DevicePixels>) -> bool {
|
||||
pub fn check_given_bounds(&self, bounds: Bounds<Pixels>) -> 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<DevicePixels> {
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
self.bounds
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,13 +96,13 @@ fn handle_move_msg(
|
||||
lparam: LPARAM,
|
||||
state_ptr: Rc<WindowsWindowStatePtr>,
|
||||
) -> Option<isize> {
|
||||
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
|
||||
@@ -129,18 +129,15 @@ fn handle_move_msg(
|
||||
fn handle_size_msg(lparam: LPARAM, state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
|
||||
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)
|
||||
|
||||
@@ -27,14 +27,14 @@ use windows::{
|
||||
};
|
||||
|
||||
use crate::platform::blade::BladeRenderer;
|
||||
use crate::*;
|
||||
use crate::{Pixels, *};
|
||||
|
||||
pub(crate) struct WindowsWindow(pub Rc<WindowsWindowStatePtr>);
|
||||
|
||||
pub struct WindowsWindowState {
|
||||
pub origin: Point<DevicePixels>,
|
||||
pub physical_size: Size<DevicePixels>,
|
||||
pub fullscreen_restore_bounds: Bounds<DevicePixels>,
|
||||
pub origin: Point<Pixels>,
|
||||
pub physical_size: Size<Pixels>,
|
||||
pub fullscreen_restore_bounds: Bounds<Pixels>,
|
||||
pub scale_factor: f32,
|
||||
|
||||
pub callbacks: Callbacks,
|
||||
@@ -67,8 +67,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,
|
||||
@@ -110,7 +110,7 @@ impl WindowsWindowState {
|
||||
!self.is_fullscreen() && unsafe { IsZoomed(self.hwnd) }.as_bool()
|
||||
}
|
||||
|
||||
fn bounds(&self) -> Bounds<DevicePixels> {
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
Bounds {
|
||||
origin: self.origin,
|
||||
size: self.physical_size,
|
||||
@@ -128,12 +128,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),
|
||||
),
|
||||
};
|
||||
|
||||
@@ -151,7 +151,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<Pixels> {
|
||||
logical_size(self.physical_size, self.scale_factor)
|
||||
self.physical_size
|
||||
}
|
||||
|
||||
fn title_bar_padding(&self) -> Pixels {
|
||||
@@ -303,6 +303,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;
|
||||
@@ -350,7 +351,7 @@ impl Drop for WindowsWindow {
|
||||
}
|
||||
|
||||
impl PlatformWindow for WindowsWindow {
|
||||
fn bounds(&self) -> Bounds<DevicePixels> {
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
self.0.state.borrow().bounds()
|
||||
}
|
||||
|
||||
@@ -551,10 +552,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
|
||||
@@ -565,10 +566,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);
|
||||
@@ -577,10 +578,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,
|
||||
)
|
||||
}
|
||||
@@ -833,10 +834,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 {
|
||||
|
||||
@@ -52,8 +52,7 @@ mod prompts;
|
||||
|
||||
pub use prompts::*;
|
||||
|
||||
pub(crate) const DEFAULT_WINDOW_SIZE: Size<DevicePixels> =
|
||||
size(DevicePixels(1024), DevicePixels(700));
|
||||
pub(crate) const DEFAULT_WINDOW_SIZE: Size<Pixels> = 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<DisplayId>, cx: &mut AppContext) -> Bounds<DevicePixels> {
|
||||
const DEFAULT_WINDOW_OFFSET: Point<DevicePixels> = point(DevicePixels(0), DevicePixels(35));
|
||||
fn default_bounds(display_id: Option<DisplayId>, cx: &mut AppContext) -> Bounds<Pixels> {
|
||||
const DEFAULT_WINDOW_OFFSET: Point<Pixels> = 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<DisplayId>, 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<DevicePixels> {
|
||||
pub fn bounds(&self) -> Bounds<Pixels> {
|
||||
self.window.platform_window.bounds()
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ edition = "2021"
|
||||
publish = false
|
||||
license = "GPL-3.0-or-later"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
path = "src/ollama.rs"
|
||||
|
||||
|
||||
1
crates/ollama/LICENSE-GPL
Symbolic link
1
crates/ollama/LICENSE-GPL
Symbolic link
@@ -0,0 +1 @@
|
||||
../../LICENSE-GPL
|
||||
@@ -230,7 +230,6 @@ pub struct Project {
|
||||
hosted_project_id: Option<ProjectId>,
|
||||
dev_server_project_id: Option<client::DevServerProjectId>,
|
||||
search_history: SearchHistory,
|
||||
yarn_worktree_ids_reported: Vec<WorktreeId>,
|
||||
}
|
||||
|
||||
pub enum LanguageServerToQuery {
|
||||
@@ -790,7 +789,6 @@ impl Project {
|
||||
hosted_project_id: None,
|
||||
dev_server_project_id: None,
|
||||
search_history: Self::new_search_history(),
|
||||
yarn_worktree_ids_reported: Vec::new(),
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -955,7 +953,6 @@ impl Project {
|
||||
.dev_server_project_id
|
||||
.map(|dev_server_project_id| DevServerProjectId(dev_server_project_id)),
|
||||
search_history: Self::new_search_history(),
|
||||
yarn_worktree_ids_reported: Vec::new(),
|
||||
};
|
||||
this.set_role(role, cx);
|
||||
for worktree in worktrees {
|
||||
@@ -2496,8 +2493,9 @@ impl Project {
|
||||
}
|
||||
|
||||
let abs_path = file.abs_path(cx);
|
||||
let uri = lsp::Url::from_file_path(&abs_path)
|
||||
.unwrap_or_else(|()| panic!("Failed to register file {abs_path:?}"));
|
||||
let Some(uri) = lsp::Url::from_file_path(&abs_path).log_err() else {
|
||||
return;
|
||||
};
|
||||
let initial_snapshot = buffer.text_snapshot();
|
||||
let language = buffer.language().cloned();
|
||||
let worktree_id = file.worktree_id(cx);
|
||||
@@ -7757,7 +7755,10 @@ impl Project {
|
||||
changes.clone(),
|
||||
));
|
||||
|
||||
this.report_yarn_project(&worktree, changes, cx);
|
||||
let worktree_id = worktree.update(cx, |worktree, _| worktree.id());
|
||||
this.client()
|
||||
.telemetry()
|
||||
.report_discovered_project_events(worktree_id, changes);
|
||||
}
|
||||
worktree::Event::UpdatedGitRepositories(updated_repos) => {
|
||||
if is_local {
|
||||
@@ -7810,32 +7811,6 @@ impl Project {
|
||||
self.metadata_changed(cx);
|
||||
}
|
||||
|
||||
fn report_yarn_project(
|
||||
&mut self,
|
||||
worktree: &Model<Worktree>,
|
||||
updated_entries_set: &UpdatedEntriesSet,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
let worktree_id = worktree.update(cx, |worktree, _| worktree.id());
|
||||
|
||||
if !self.yarn_worktree_ids_reported.contains(&worktree_id) {
|
||||
let is_yarn_project = updated_entries_set.iter().any(|(path, _, _)| {
|
||||
path.as_ref()
|
||||
.file_name()
|
||||
.and_then(|name| name.to_str())
|
||||
.map(|name_str| name_str == "yarn.lock")
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
if is_yarn_project {
|
||||
self.client()
|
||||
.telemetry()
|
||||
.report_app_event("open yarn project".to_string());
|
||||
self.yarn_worktree_ids_reported.push(worktree_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_local_worktree_buffers(
|
||||
&mut self,
|
||||
worktree_handle: &Model<Worktree>,
|
||||
|
||||
@@ -1792,6 +1792,10 @@ impl ProjectPanel {
|
||||
.unwrap_or(&[]);
|
||||
|
||||
let entry_range = range.start.saturating_sub(ix)..end_ix - ix;
|
||||
let entries = visible_worktree_entries
|
||||
.iter()
|
||||
.map(|e| (e.path.clone()))
|
||||
.collect();
|
||||
for entry in visible_worktree_entries[entry_range].iter() {
|
||||
let status = git_status_setting.then(|| entry.git_status).flatten();
|
||||
let is_expanded = expanded_entry_ids.binary_search(&entry.id).is_ok();
|
||||
@@ -1812,10 +1816,8 @@ impl ProjectPanel {
|
||||
}
|
||||
};
|
||||
|
||||
let (depth, difference) = ProjectPanel::calculate_depth_and_difference(
|
||||
entry,
|
||||
visible_worktree_entries,
|
||||
);
|
||||
let (depth, difference) =
|
||||
ProjectPanel::calculate_depth_and_difference(entry, &entries);
|
||||
|
||||
let filename = match difference {
|
||||
diff if diff > 1 => entry
|
||||
@@ -1888,32 +1890,21 @@ impl ProjectPanel {
|
||||
|
||||
fn calculate_depth_and_difference(
|
||||
entry: &Entry,
|
||||
visible_worktree_entries: &Vec<Entry>,
|
||||
visible_worktree_entries: &HashSet<Arc<Path>>,
|
||||
) -> (usize, usize) {
|
||||
let visible_worktree_paths: HashSet<Arc<Path>> = visible_worktree_entries
|
||||
.iter()
|
||||
.map(|e| e.path.clone())
|
||||
.collect();
|
||||
|
||||
let (depth, difference) = entry
|
||||
.path
|
||||
.ancestors()
|
||||
.skip(1) // Skip the entry itself
|
||||
.find_map(|ancestor| {
|
||||
if visible_worktree_paths.contains(ancestor) {
|
||||
let parent_entry = visible_worktree_entries
|
||||
.iter()
|
||||
.find(|&e| &*e.path == ancestor)
|
||||
.unwrap();
|
||||
|
||||
if let Some(parent_entry) = visible_worktree_entries.get(ancestor) {
|
||||
let entry_path_components_count = entry.path.components().count();
|
||||
let parent_path_components_count = parent_entry.path.components().count();
|
||||
let parent_path_components_count = parent_entry.components().count();
|
||||
let difference = entry_path_components_count - parent_path_components_count;
|
||||
let depth = parent_entry
|
||||
.path
|
||||
.ancestors()
|
||||
.skip(1)
|
||||
.filter(|ancestor| visible_worktree_paths.contains(*ancestor))
|
||||
.filter(|ancestor| visible_worktree_entries.contains(*ancestor))
|
||||
.count();
|
||||
Some((depth + 1, difference))
|
||||
} else {
|
||||
|
||||
@@ -775,6 +775,7 @@ impl BufferSearchBar {
|
||||
if let Some(matches) = self
|
||||
.searchable_items_with_matches
|
||||
.get(&searchable_item.downgrade())
|
||||
.filter(|matches| !matches.is_empty())
|
||||
{
|
||||
let new_match_index = searchable_item
|
||||
.match_index_for_direction(matches, index, direction, count, cx);
|
||||
|
||||
@@ -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<i32> {
|
||||
let this: i32 = self.0.into();
|
||||
let this: i32 = self.0 .0 as i32;
|
||||
this.bind(statement, start_index)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Size<DevicePixels>> = env::var("ZED_WINDOW_SIZE")
|
||||
static ref ZED_WINDOW_SIZE: Option<Size<Pixels>> = env::var("ZED_WINDOW_SIZE")
|
||||
.ok()
|
||||
.as_deref()
|
||||
.and_then(parse_pixel_size_env_var);
|
||||
static ref ZED_WINDOW_POSITION: Option<Point<DevicePixels>> = env::var("ZED_WINDOW_POSITION")
|
||||
static ref ZED_WINDOW_POSITION: Option<Point<Pixels>> = 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<Bounds<DevicePixels>> {
|
||||
fn window_bounds_env_override() -> Option<Bounds<Pixels>> {
|
||||
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<Point<DevicePixels>> {
|
||||
fn parse_pixel_position_env_var(value: &str) -> Option<Point<Pixels>> {
|
||||
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<Size<DevicePixels>> {
|
||||
fn parse_pixel_size_env_var(value: &str) -> Option<Size<Pixels>> {
|
||||
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)]
|
||||
|
||||
@@ -3751,6 +3751,7 @@ impl BackgroundScanner {
|
||||
statuses,
|
||||
});
|
||||
}
|
||||
self.watcher.add(child_abs_path.as_ref()).log_err();
|
||||
} else if child_name == *GITIGNORE {
|
||||
match build_gitignore(&child_abs_path, self.fs.as_ref()).await {
|
||||
Ok(ignore) => {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
description = "The fast, collaborative code editor."
|
||||
edition = "2021"
|
||||
name = "zed"
|
||||
version = "0.140.0"
|
||||
version = "0.140.5"
|
||||
publish = false
|
||||
license = "GPL-3.0-or-later"
|
||||
authors = ["Zed Team <hi@zed.dev>"]
|
||||
|
||||
@@ -1 +1 @@
|
||||
dev
|
||||
stable
|
||||
@@ -499,6 +499,7 @@ fn handle_open_request(request: OpenRequest, app_state: Arc<AppState>, cx: &mut
|
||||
let app_state = app_state.clone();
|
||||
cx.spawn(move |cx| handle_cli_connection(connection, app_state, cx))
|
||||
.detach();
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(e) = init_ui(app_state.clone(), cx) {
|
||||
|
||||
@@ -72,6 +72,7 @@ actions!(
|
||||
ShowAll,
|
||||
ToggleFullScreen,
|
||||
Zoom,
|
||||
TestPanic,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -83,6 +84,10 @@ pub fn init(cx: &mut AppContext) {
|
||||
#[cfg(target_os = "macos")]
|
||||
cx.on_action(|_: &ShowAll, cx| cx.unhide_other_apps());
|
||||
cx.on_action(quit);
|
||||
|
||||
if ReleaseChannel::global(cx) == ReleaseChannel::Dev {
|
||||
cx.on_action(test_panic);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_window_options(display_uuid: Option<Uuid>, cx: &mut AppContext) -> WindowOptions {
|
||||
@@ -472,6 +477,10 @@ fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn test_panic(_: &TestPanic, _: &mut AppContext) {
|
||||
panic!("Ran the TestPanic action")
|
||||
}
|
||||
|
||||
fn quit(_: &Quit, cx: &mut AppContext) {
|
||||
let should_confirm = WorkspaceSettings::get_global(cx).confirm_quit;
|
||||
cx.spawn(|mut cx| async move {
|
||||
|
||||
@@ -43,8 +43,8 @@ cargo build --release --target "${target_triple}" --package zed --package cli
|
||||
|
||||
# Strip the binary of all debug symbols
|
||||
# Later, we probably want to do something like this: https://github.com/GabrielMajeri/separate-symbols
|
||||
strip "target/${target_triple}/release/zed"
|
||||
strip "target/${target_triple}/release/cli"
|
||||
strip --strip-debug "target/${target_triple}/release/zed"
|
||||
strip --strip-debug "target/${target_triple}/release/cli"
|
||||
|
||||
suffix=""
|
||||
if [ "$channel" != "stable" ]; then
|
||||
|
||||
@@ -17,6 +17,7 @@ echo -e "# ###### CODE LICENSES ######\n" >> $OUTPUT_FILE
|
||||
[[ "$(cargo about --version)" == "cargo-about 0.6.1" ]] || cargo install cargo-about@0.6.1
|
||||
|
||||
echo "Generating cargo licenses"
|
||||
cargo install cargo-about
|
||||
cargo about generate --fail -c script/licenses/zed-licenses.toml script/licenses/template.hbs.md >> $OUTPUT_FILE
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ main() {
|
||||
}
|
||||
|
||||
linux() {
|
||||
if [[ -n "${ZED_BUNDLE_PATH:-}" ]]; then
|
||||
if [ -n "${ZED_BUNDLE_PATH:-}" ]; then
|
||||
cp "$ZED_BUNDLE_PATH" "$temp/zed-linux-$arch.tar.gz"
|
||||
else
|
||||
echo "Downloading Zed"
|
||||
|
||||
@@ -20,6 +20,7 @@ if [[ -n $apt ]]; then
|
||||
libwayland-dev
|
||||
libxkbcommon-x11-dev
|
||||
libssl-dev
|
||||
libstdc++-12-dev
|
||||
libzstd-dev
|
||||
libvulkan1
|
||||
libgit2-dev
|
||||
|
||||
Reference in New Issue
Block a user