Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 86 additions & 88 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@ futures = "0.3.34"
gix = { version = "0.89.0", default-features = false, features = ["max-performance-safe", "comfort", "basic", "status", "blame", "sha1", "sha256"] }
# Already in the tree via gix; Git-compatible quoting for attribute patterns.
gix-quote = "0.10.0"
gpui = { package = "gpui-ce", git = "https://github.com/Havunen/gpui-ce.git", rev = "0665fb07d59cf7af185e58f44b9f890590abe204" }
gpui_platform = { package = "gpui_ce_platform", git = "https://github.com/Havunen/gpui-ce.git", rev = "0665fb07d59cf7af185e58f44b9f890590abe204", features = ["font-kit"] }
gpui_wgpu = { package = "gpui_ce_wgpu", git = "https://github.com/Havunen/gpui-ce.git", rev = "0665fb07d59cf7af185e58f44b9f890590abe204" }
gpui_parley = { package = "gpui_ce_parley", git = "https://github.com/Havunen/gpui-ce.git", rev = "0665fb07d59cf7af185e58f44b9f890590abe204", default-features = false }
gpui_shared_string = { package = "gpui_ce_shared_string", git = "https://github.com/Havunen/gpui-ce.git", rev = "0665fb07d59cf7af185e58f44b9f890590abe204" }
gpui_sum_tree = { package = "gpui_ce_sum_tree", git = "https://github.com/Havunen/gpui-ce.git", rev = "0665fb07d59cf7af185e58f44b9f890590abe204" }
gpui = { package = "gpui-ce", git = "https://github.com/Havunen/gpui-ce.git", rev = "f76fe5dc0387cdbeab6db3b05e6cf73ab0caf6ca" }
gpui_platform = { package = "gpui_ce_platform", git = "https://github.com/Havunen/gpui-ce.git", rev = "f76fe5dc0387cdbeab6db3b05e6cf73ab0caf6ca", features = ["font-kit"] }
gpui_wgpu = { package = "gpui_ce_wgpu", git = "https://github.com/Havunen/gpui-ce.git", rev = "f76fe5dc0387cdbeab6db3b05e6cf73ab0caf6ca" }
gpui_parley = { package = "gpui_ce_parley", git = "https://github.com/Havunen/gpui-ce.git", rev = "f76fe5dc0387cdbeab6db3b05e6cf73ab0caf6ca", default-features = false }
gpui_shared_string = { package = "gpui_ce_shared_string", git = "https://github.com/Havunen/gpui-ce.git", rev = "f76fe5dc0387cdbeab6db3b05e6cf73ab0caf6ca" }
gpui_sum_tree = { package = "gpui_ce_sum_tree", git = "https://github.com/Havunen/gpui-ce.git", rev = "f76fe5dc0387cdbeab6db3b05e6cf73ab0caf6ca" }
image = "0.25.10"
fast_image_resize = { version = "6.1.0", features = ["image"] }
# Already in the dependency graph; merges sorted reference streams lazily.
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ To install GnuPG, trust GitHub's signing key, and configure SSH allowed signers,

Choose **Settings → Diff → Diff Engine** to make Difftastic the default, or use the diff viewer's cog for a temporary override. Both Split and Inline layouts support it. See [Difftastic](docs/difftastic.md) for partial staging and fallbacks.

### Graphics renderer

On Linux and Windows, choose **Settings → General → Graphics → Graphics renderer**
to change the renderer for the next launch. See the [Linux](docs/linux-renderer.md) and
[Windows](docs/windows-renderer.md) guides for backend choices and diagnostic
overrides.

### Themes

GitComet supports built-in themes and user-provided custom themes.
Expand Down
6 changes: 5 additions & 1 deletion crates/gitcomet-state/src/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub struct UiSession {
pub image_smooth_filter: Option<String>,
pub window_controls_mode: Option<String>,
pub windows_renderer: Option<String>,
pub linux_renderer: Option<String>,
pub browser_open_target: Option<String>,
pub ui_density: Option<String>,
pub ui_font_size_px: Option<u32>,
Expand Down Expand Up @@ -193,6 +194,8 @@ pub(crate) struct UiSessionFile {
#[serde(default, deserialize_with = "lenient")]
windows_renderer: Option<String>,
#[serde(default, deserialize_with = "lenient")]
linux_renderer: Option<String>,
#[serde(default, deserialize_with = "lenient")]
browser_open_target: Option<String>,
#[serde(default, deserialize_with = "lenient")]
ui_density: Option<String>,
Expand Down Expand Up @@ -497,6 +500,7 @@ pub fn load_from_path(path: &Path) -> UiSession {
image_smooth_filter: file.image_smooth_filter,
window_controls_mode: file.window_controls_mode,
windows_renderer: file.windows_renderer,
linux_renderer: file.linux_renderer,
browser_open_target: file.browser_open_target,
ui_density: file.ui_density,
ui_font_size_px: file.ui_font_size_px,
Expand Down Expand Up @@ -785,7 +789,7 @@ fn persist_to_path(path: &Path, session: &impl Serialize) -> io::Result<()> {
gitcomet_core::fs_utils::write_private_file(path, &contents)
}

fn default_session_file_path() -> Option<PathBuf> {
pub fn default_session_file_path() -> Option<PathBuf> {
#[cfg(test)]
if let Some(path) = test_session_file_path_override() {
return path;
Expand Down
2 changes: 2 additions & 0 deletions crates/gitcomet-state/src/session/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct UiSettings {
pub image_smooth_filter: Option<String>,
pub window_controls_mode: Option<String>,
pub windows_renderer: Option<String>,
pub linux_renderer: Option<String>,
pub browser_open_target: Option<String>,
pub ui_density: Option<String>,
pub ui_font_size_px: Option<u32>,
Expand Down Expand Up @@ -121,6 +122,7 @@ pub fn persist_ui_settings_to_path(settings: UiSettings, path: &Path) -> io::Res
apply_setting!(settings, file, image_smooth_filter);
apply_setting!(settings, file, window_controls_mode);
apply_setting!(settings, file, windows_renderer);
apply_setting!(settings, file, linux_renderer);
apply_setting!(settings, file, browser_open_target);
apply_setting!(settings, file, ui_density);
apply_setting!(settings, file, ui_font_size_px);
Expand Down
55 changes: 55 additions & 0 deletions crates/gitcomet-state/src/session/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3066,6 +3066,61 @@ fn persist_ui_settings_round_trips_window_controls_mode() {
assert_eq!(loaded.browser_open_target.as_deref(), Some("new_window"));
}

#[test]
fn linux_renderer_roundtrips_without_changing_the_windows_preference() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("session.json");
assert_eq!(load_from_path(&path).linux_renderer, None);
persist_ui_settings_to_path(
UiSettings {
windows_renderer: Some("dx11".into()),
theme_mode: Some("dark".into()),
..Default::default()
},
&path,
)
.unwrap();
for value in ["gl", "vulkan", "auto"] {
persist_ui_settings_to_path(
UiSettings {
linux_renderer: Some(value.into()),
..Default::default()
},
&path,
)
.unwrap();
let loaded = load_from_path(&path);
assert_eq!(loaded.linux_renderer.as_deref(), Some(value));
assert_eq!(loaded.windows_renderer.as_deref(), Some("dx11"));
assert_eq!(loaded.theme_mode.as_deref(), Some("dark"));
}
}

#[test]
fn linux_renderer_survives_settings_and_workspace_writes() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("session.json");
std::fs::write(
&path,
r#"{"version":6,"linux_renderer":"gl","windows_renderer":"dx11","extensions":{"example":{"draft":"keep"}}}"#,
)
.unwrap();
persist_ui_settings_to_path(
UiSettings {
theme_mode: Some("dark".into()),
..Default::default()
},
&path,
)
.unwrap();
persist_workspaces_to_path(&[Workspace::new(vec![dir.path().to_path_buf()])], &path).unwrap();
let json: serde_json::Value = serde_json::from_slice(&std::fs::read(&path).unwrap()).unwrap();
assert_eq!(json["linux_renderer"], "gl");
assert_eq!(json["windows_renderer"], "dx11");
assert_eq!(json["extensions"]["example"]["draft"], "keep");
assert_eq!(load_from_path(&path).workspaces.len(), 1);
}

#[test]
fn windows_renderer_fallback_survives_other_settings_and_workspace_writes() {
let dir = tempfile::tempdir().unwrap();
Expand Down
33 changes: 16 additions & 17 deletions crates/gitcomet-ui-gpui/assets/open_source_licenses.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ backtrace 0.3.76 MIT OR Apache-2.0
base64 0.22.1 MIT OR Apache-2.0
base64 0.23.1 MIT OR Apache-2.0
bindgen 0.73.2 BSD-3-Clause
bit-set 0.10.0 Apache-2.0 OR MIT
bit-set 0.11.1 Apache-2.0 OR MIT
bit-set 0.8.0 Apache-2.0 OR MIT
bit-set 0.9.1 Apache-2.0 OR MIT
bit-vec 0.10.1 Apache-2.0 OR MIT
bit-vec 0.8.0 Apache-2.0 OR MIT
bit-vec 0.9.1 Apache-2.0 OR MIT
Expand Down Expand Up @@ -178,7 +178,7 @@ diff 0.1.13 MIT OR Apache-2.0
difftastic 0.71.0 MIT
digest 0.10.7 MIT OR Apache-2.0
digest 0.11.3 MIT OR Apache-2.0
dirs 6.0.0 MIT OR Apache-2.0
dirs 7.0.0 MIT OR Apache-2.0
dirs-sys 0.5.0 MIT OR Apache-2.0
dispatch2 0.3.1 Zlib OR Apache-2.0 OR MIT
displaydoc 0.2.7 MIT OR Apache-2.0
Expand Down Expand Up @@ -312,8 +312,6 @@ glob 0.3.4 MIT OR Apache-2.0
glow 0.17.0 MIT OR Apache-2.0 OR Zlib
glutin_wgl_sys 0.6.1 Apache-2.0
gpu-allocator 0.28.0 MIT OR Apache-2.0
gpu-descriptor 0.3.2 MIT OR Apache-2.0
gpu-descriptor-types 0.2.0 MIT OR Apache-2.0
gpui-ce 0.2.2 Apache-2.0
gpui_ce_apple 0.1.0 Apache-2.0
gpui_ce_collections 0.2.2 Apache-2.0
Expand Down Expand Up @@ -452,7 +450,8 @@ miow 0.6.1 MIT OR Apache-2.0
moxcms 0.8.1 BSD-3-Clause OR Apache-2.0
multiversion_no_op 1.0.0 Apache-2.0 OR MIT
naga 24.0.0 MIT OR Apache-2.0
naga 29.0.4 MIT OR Apache-2.0
naga 30.0.1 MIT OR Apache-2.0
naga-types 30.0.1 MIT OR Apache-2.0
ndk-sys 0.6.0+11769913 MIT OR Apache-2.0
new_debug_unreachable 1.0.6 MIT
nix 0.31.3 MIT
Expand Down Expand Up @@ -864,18 +863,18 @@ web-sys 0.3.106 MIT OR Apache-2.0
web-time 1.1.0 MIT OR Apache-2.0
webpki-roots 1.0.10 CDLA-Permissive-2.0
weezl 0.1.12 MIT OR Apache-2.0
wgpu 29.0.4 MIT OR Apache-2.0
wgpu-core 29.0.4 MIT OR Apache-2.0
wgpu-core-deps-apple 29.0.4 MIT OR Apache-2.0
wgpu-core-deps-emscripten 29.0.4 MIT OR Apache-2.0
wgpu-core-deps-wasm 29.0.4 MIT OR Apache-2.0
wgpu-core-deps-windows-linux-android 29.0.4 MIT OR Apache-2.0
wgpu-hal 29.0.4 MIT OR Apache-2.0
wgpu-naga-bridge 29.0.4 MIT OR Apache-2.0
wgpu-types 29.0.4 MIT OR Apache-2.0
wgsl-rs 0.1.0 MIT
wgsl-rs-ir 0.1.0 MIT
wgsl-rs-macros 0.1.0 MIT
wgpu 30.0.1 MIT OR Apache-2.0
wgpu-core 30.0.1 MIT OR Apache-2.0
wgpu-core-deps-apple 30.0.1 MIT OR Apache-2.0
wgpu-core-deps-emscripten 30.0.1 MIT OR Apache-2.0
wgpu-core-deps-wasm 30.0.1 MIT OR Apache-2.0
wgpu-core-deps-windows-linux-android 30.0.1 MIT OR Apache-2.0
wgpu-hal 30.0.1 MIT OR Apache-2.0
wgpu-naga-bridge 30.0.1 MIT OR Apache-2.0
wgpu-types 30.0.1 MIT OR Apache-2.0
wgsl-rs 0.1.0-beta.6 MIT
wgsl-rs-ir 0.1.0-beta.6 MIT
wgsl-rs-macros 0.1.0-beta.6 MIT
which 8.0.6 MIT
winapi 0.3.9 MIT/Apache-2.0
winapi-i686-pc-windows-gnu 0.4.0 MIT/Apache-2.0
Expand Down
34 changes: 25 additions & 9 deletions crates/gitcomet-ui-gpui/src/app/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,11 @@ pub(super) fn run_windowed_app(
let (application, renderer_session) = crate::windows_renderer::application(
launch.view_config.view_mode == GitCometViewMode::Normal,
);
#[cfg(not(target_os = "windows"))]
#[cfg(target_os = "linux")]
let (application, renderer_session) = crate::linux_renderer::application(
launch.view_config.view_mode == GitCometViewMode::Normal,
);
#[cfg(not(any(target_os = "windows", target_os = "linux")))]
let application = gpui_platform::application();
let application = application
.with_assets(GitCometAssets::with_extensions(extensions.assets()))
Expand Down Expand Up @@ -504,7 +508,7 @@ pub(super) fn run_windowed_app(

application.run(move |cx: &mut App| {
cx.set_global(clean_shutdown_tracker);
#[cfg(target_os = "windows")]
#[cfg(any(target_os = "windows", target_os = "linux"))]
cx.set_global(renderer_session);
crate::ui_probe::start_if_enabled(cx);
crate::environment::initialize(cx);
Expand Down Expand Up @@ -785,13 +789,14 @@ pub(super) fn open_gitcomet_window(
)
})
.unwrap_or_else(|err| {
let name = identity::current().display_name();
panic!(
"failed to open main {name} window: {err}\n\
This is usually a GPU/display problem, not a {name} bug. \
If you just updated your system (kernel, mesa, or vulkan drivers), reboot. \
For diagnostics, include the crash report from the next launch."
)
#[cfg(target_os = "linux")]
let renderer_help = cx
.try_global::<crate::linux_renderer::RendererSession>()
.map(|session| session.0.borrow().startup_failure_help())
.unwrap_or_default();
#[cfg(not(target_os = "linux"))]
let renderer_help = String::new();
panic!("{}", window_open_failure_message(&err, &renderer_help))
});

#[cfg(target_os = "macos")]
Expand All @@ -803,6 +808,17 @@ pub(super) fn open_gitcomet_window(
window
}

pub(super) fn window_open_failure_message(err: &anyhow::Error, renderer_help: &str) -> String {
let name = identity::current().display_name();
let mut message = format!("failed to open main {name} window: {err:#}");
if !renderer_help.is_empty() {
message.push('\n');
message.push_str(renderer_help);
}
message.push_str("\nFor diagnostics, include the crash report from the next launch.");
message
}

/// Client-side decorations inset a rounded frame into the surface; the pixels
/// outside it must show the desktop, not a solid fill, so every platform but
/// macOS asks for a transparent surface.
Expand Down
24 changes: 21 additions & 3 deletions crates/gitcomet-ui-gpui/src/app/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,32 @@ use std::time::{Duration, Instant};

struct TestBackend;

#[cfg(target_os = "windows")]
#[test]
fn window_startup_failure_retains_the_gpu_cause_and_renderer_recovery_help() {
let err = anyhow::anyhow!("Gl: No GPU adapter found that can configure the display surface")
.context("failed to initialize a GPU context");
let message = launch::window_open_failure_message(&err, "renderer recovery instructions");
assert!(message.contains("failed to initialize a GPU context"));
assert!(message.contains("Gl: No GPU adapter found that can configure the display surface"));
assert!(message.contains("renderer recovery instructions"));
assert!(!message.contains("not a GitComet bug"));
}

#[cfg(any(target_os = "windows", target_os = "linux"))]
#[gpui::test]
fn dismissing_a_restart_terminal_guard_retains_the_saved_renderer(cx: &mut gpui::TestAppContext) {
#[cfg(target_os = "linux")]
use crate::linux_renderer::{RendererPreference, RendererSession, RendererState};
#[cfg(target_os = "windows")]
use crate::windows_renderer::{RendererPreference, RendererSession, RendererState};
#[cfg(target_os = "linux")]
let saved = RendererPreference::Gl;
#[cfg(target_os = "windows")]
let saved = RendererPreference::Dx11;
let renderer = RendererSession(std::rc::Rc::new(std::cell::RefCell::new(
RendererState::new(RendererPreference::Auto, true),
)));
renderer.0.borrow_mut().saved = RendererPreference::Dx11;
renderer.0.borrow_mut().saved = saved;
cx.update(|app| {
app.set_global(renderer.clone());
app.set_global(windows::PendingRestart(true));
Expand Down Expand Up @@ -47,7 +65,7 @@ fn dismissing_a_restart_terminal_guard_retains_the_saved_renderer(cx: &mut gpui:
window_cx.run_until_parked();
window_cx.update(|_, app| {
assert!(!app.global::<windows::PendingRestart>().0);
assert_eq!(renderer.0.borrow().saved, RendererPreference::Dx11);
assert_eq!(renderer.0.borrow().saved, saved);
assert!(renderer.0.borrow().restart_required());
assert_eq!(app.windows().len(), 1);
});
Expand Down
25 changes: 23 additions & 2 deletions crates/gitcomet-ui-gpui/src/app/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,10 +585,14 @@ pub(crate) fn close_active_window_or_warn(cx: &mut App) {
pub(crate) struct PendingRestart(pub(crate) bool);
impl gpui::Global for PendingRestart {}

#[cfg(target_os = "windows")]
#[cfg(any(target_os = "windows", target_os = "linux"))]
pub(crate) fn request_restart(cx: &mut App) {
#[cfg(target_os = "linux")]
use crate::linux_renderer::RendererSession;
#[cfg(target_os = "windows")]
use crate::windows_renderer::RendererSession;
if cx
.try_global::<crate::windows_renderer::RendererSession>()
.try_global::<RendererSession>()
.is_none_or(|session| !session.0.borrow().restart_allowed)
{
return;
Expand Down Expand Up @@ -813,4 +817,21 @@ mod restart_tests {
assert!(session.0.borrow().restart_required());
});
}

#[cfg(target_os = "linux")]
#[gpui::test]
fn focused_renderer_changes_cannot_request_an_application_restart(
cx: &mut gpui::TestAppContext,
) {
use crate::linux_renderer::{RendererPreference, RendererSession, RendererState};
cx.update(|cx| {
let mut state = RendererState::new(RendererPreference::Auto, false);
state.saved = RendererPreference::Gl;
let session = RendererSession(std::rc::Rc::new(std::cell::RefCell::new(state)));
cx.set_global(session.clone());
request_restart(cx);
assert!(cx.try_global::<PendingRestart>().is_none());
assert_eq!(session.0.borrow().saved, RendererPreference::Gl);
});
}
}
2 changes: 2 additions & 0 deletions crates/gitcomet-ui-gpui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ mod environment;
mod external_editor;
pub mod http;
mod launch_guard;
#[cfg(target_os = "linux")]
mod linux_renderer;
mod menu_labels;
#[doc(hidden)]
pub mod perf_alloc;
Expand Down
Loading