mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
GTK: implement banner informing about existing crash reports
This commit is contained in:
@ -14,6 +14,7 @@ const configpkg = @import("../../config.zig");
|
|||||||
const font = @import("../../font/main.zig");
|
const font = @import("../../font/main.zig");
|
||||||
const input = @import("../../input.zig");
|
const input = @import("../../input.zig");
|
||||||
const CoreSurface = @import("../../Surface.zig");
|
const CoreSurface = @import("../../Surface.zig");
|
||||||
|
const crash = @import("../../crash/main.zig");
|
||||||
|
|
||||||
const App = @import("App.zig");
|
const App = @import("App.zig");
|
||||||
const Color = configpkg.Config.Color;
|
const Color = configpkg.Config.Color;
|
||||||
@ -248,9 +249,94 @@ pub fn init(self: *Window, app: *App) !void {
|
|||||||
}
|
}
|
||||||
c.gtk_widget_add_css_class(@ptrCast(gtk_window), "devel");
|
c.gtk_widget_add_css_class(@ptrCast(gtk_window), "devel");
|
||||||
c.gtk_widget_add_css_class(@ptrCast(warning_box), "background");
|
c.gtk_widget_add_css_class(@ptrCast(warning_box), "background");
|
||||||
|
c.gtk_widget_add_css_class(@ptrCast(warning_box), "banner-box");
|
||||||
c.gtk_box_append(@ptrCast(box), warning_box);
|
c.gtk_box_append(@ptrCast(box), warning_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display a banner informing about crash reports if any exist
|
||||||
|
{
|
||||||
|
var crash_dir = try crash.defaultDir(self.app.core_app.alloc);
|
||||||
|
defer self.app.core_app.alloc.free(crash_dir.path);
|
||||||
|
var it = try crash_dir.iterator();
|
||||||
|
defer it.deinit();
|
||||||
|
|
||||||
|
if (try it.next()) |_| {
|
||||||
|
const warning_text = try std.fmt.allocPrintZ(
|
||||||
|
self.app.core_app.alloc,
|
||||||
|
\\ There are existing crash reports located at <a href="file://{s}">{s}</a>.
|
||||||
|
\\ If possible, <a href="https://github.com/ghostty-org/ghostty?tab=readme-ov-file#crash-reports">report them to the developers</a> to help improve the application.
|
||||||
|
,
|
||||||
|
.{crash_dir.path, crash_dir.path}
|
||||||
|
);
|
||||||
|
defer self.app.core_app.alloc.free(warning_text);
|
||||||
|
const warning_box = c.gtk_box_new(c.GTK_ORIENTATION_VERTICAL, 0);
|
||||||
|
|
||||||
|
if ((comptime adwaita.versionAtLeast(1, 3, 0)) and
|
||||||
|
adwaita.enabled(&app.config) and
|
||||||
|
adwaita.versionAtLeast(1, 3, 0))
|
||||||
|
{
|
||||||
|
const banner = c.adw_banner_new(warning_text.ptr);
|
||||||
|
c.adw_banner_set_revealed(@ptrCast(banner), 1);
|
||||||
|
c.adw_banner_set_use_markup(@ptrCast(banner), 1);
|
||||||
|
|
||||||
|
c.adw_banner_set_button_label(@ptrCast(banner), "Dismiss");
|
||||||
|
const close_banner_callback = struct {
|
||||||
|
fn callback(_: ?*c.GtkWidget, data: ?*anyopaque) callconv(.C) void {
|
||||||
|
const widget: *c.AdwBanner = @ptrCast(data);
|
||||||
|
c.adw_banner_set_revealed(widget, c.FALSE);
|
||||||
|
}
|
||||||
|
}.callback;
|
||||||
|
_ = c.g_signal_connect_data(
|
||||||
|
banner,
|
||||||
|
"button-clicked",
|
||||||
|
c.G_CALLBACK(&close_banner_callback),
|
||||||
|
banner,
|
||||||
|
null,
|
||||||
|
c.G_CONNECT_DEFAULT,
|
||||||
|
);
|
||||||
|
|
||||||
|
c.gtk_box_append(@ptrCast(warning_box), @ptrCast(banner));
|
||||||
|
} else {
|
||||||
|
const hbox = c.gtk_box_new(c.GTK_ORIENTATION_HORIZONTAL, 5);
|
||||||
|
c.gtk_widget_set_halign(@ptrCast(hbox), c.GTK_ALIGN_CENTER);
|
||||||
|
|
||||||
|
const message = c.gtk_label_new(null);
|
||||||
|
c.gtk_label_set_markup(@ptrCast(message), warning_text.ptr);
|
||||||
|
c.gtk_label_set_use_markup(@ptrCast(message), 1);
|
||||||
|
c.gtk_widget_set_margin_top(@ptrCast(message), 10);
|
||||||
|
c.gtk_widget_set_margin_bottom(@ptrCast(message), 10);
|
||||||
|
|
||||||
|
c.gtk_box_append(@ptrCast(hbox), message);
|
||||||
|
|
||||||
|
const close_button = c.gtk_button_new_from_icon_name("window-close-symbolic");
|
||||||
|
c.gtk_widget_set_margin_top(@ptrCast(close_button), 10);
|
||||||
|
c.gtk_widget_set_margin_bottom(@ptrCast(close_button), 10);
|
||||||
|
|
||||||
|
const close_warning_callback = struct {
|
||||||
|
fn callback(_: ?*c.GtkWidget, data: ?*anyopaque) callconv(.C) void {
|
||||||
|
const widget: *c.GtkWidget = @ptrCast(@alignCast(data));
|
||||||
|
c.gtk_widget_set_visible(widget, c.FALSE);
|
||||||
|
}
|
||||||
|
}.callback;
|
||||||
|
_ = c.g_signal_connect_data(
|
||||||
|
close_button,
|
||||||
|
"clicked",
|
||||||
|
c.G_CALLBACK(&close_warning_callback),
|
||||||
|
warning_box,
|
||||||
|
null,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
c.gtk_box_append(@ptrCast(hbox), close_button);
|
||||||
|
c.gtk_box_append(@ptrCast(warning_box), @ptrCast(hbox));
|
||||||
|
}
|
||||||
|
|
||||||
|
c.gtk_widget_add_css_class(@ptrCast(warning_box), "background");
|
||||||
|
c.gtk_widget_add_css_class(@ptrCast(warning_box), "banner-box");
|
||||||
|
c.gtk_box_append(@ptrCast(box), warning_box);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Setup our toast overlay if we have one
|
// Setup our toast overlay if we have one
|
||||||
self.toast_overlay = if (adwaita.enabled(&self.app.config)) toast: {
|
self.toast_overlay = if (adwaita.enabled(&self.app.config)) toast: {
|
||||||
const toast_overlay = c.adw_toast_overlay_new();
|
const toast_overlay = c.adw_toast_overlay_new();
|
||||||
|
@ -45,3 +45,7 @@ window.without-window-decoration-and-with-titlebar {
|
|||||||
background-color: rgba(250, 250, 250, 1);
|
background-color: rgba(250, 250, 250, 1);
|
||||||
background-clip: content-box;
|
background-clip: content-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.banner-box:not(:first-child) {
|
||||||
|
border-top: 1px solid alpha(@borders, 0.2);
|
||||||
|
}
|
||||||
|
@ -38,7 +38,7 @@ pub const ReportIterator = struct {
|
|||||||
it: std.fs.Dir.Iterator = undefined,
|
it: std.fs.Dir.Iterator = undefined,
|
||||||
|
|
||||||
pub fn deinit(self: *ReportIterator) void {
|
pub fn deinit(self: *ReportIterator) void {
|
||||||
if (self.dir) |dir| dir.close();
|
if (self.dir) |*dir| dir.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(self: *ReportIterator) !?Report {
|
pub fn next(self: *ReportIterator) !?Report {
|
||||||
|
Reference in New Issue
Block a user