mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-25 13:16:11 +03:00
apprt/gtk-ng: child exited overlay
This commit is contained in:
@ -39,6 +39,7 @@ pub const blueprints: []const Blueprint = &.{
|
|||||||
.{ .major = 1, .minor = 2, .name = "config-errors-dialog" },
|
.{ .major = 1, .minor = 2, .name = "config-errors-dialog" },
|
||||||
.{ .major = 1, .minor = 2, .name = "resize-overlay" },
|
.{ .major = 1, .minor = 2, .name = "resize-overlay" },
|
||||||
.{ .major = 1, .minor = 2, .name = "surface" },
|
.{ .major = 1, .minor = 2, .name = "surface" },
|
||||||
|
.{ .major = 1, .minor = 3, .name = "surface-child-exited" },
|
||||||
.{ .major = 1, .minor = 5, .name = "window" },
|
.{ .major = 1, .minor = 5, .name = "window" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -485,6 +485,8 @@ pub const Application = extern struct {
|
|||||||
|
|
||||||
.set_title => Action.setTitle(target, value),
|
.set_title => Action.setTitle(target, value),
|
||||||
|
|
||||||
|
.show_child_exited => return Action.showChildExited(target, value),
|
||||||
|
|
||||||
.show_gtk_inspector => Action.showGtkInspector(),
|
.show_gtk_inspector => Action.showGtkInspector(),
|
||||||
|
|
||||||
// Unimplemented but todo on gtk-ng branch
|
// Unimplemented but todo on gtk-ng branch
|
||||||
@ -514,7 +516,6 @@ pub const Application = extern struct {
|
|||||||
.ring_bell,
|
.ring_bell,
|
||||||
.toggle_command_palette,
|
.toggle_command_palette,
|
||||||
.open_url,
|
.open_url,
|
||||||
.show_child_exited,
|
|
||||||
.close_all_windows,
|
.close_all_windows,
|
||||||
.float_window,
|
.float_window,
|
||||||
.toggle_visibility,
|
.toggle_visibility,
|
||||||
@ -1141,6 +1142,16 @@ const Action = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn showChildExited(
|
||||||
|
target: apprt.Target,
|
||||||
|
value: apprt.surface.Message.ChildExited,
|
||||||
|
) bool {
|
||||||
|
return switch (target) {
|
||||||
|
.app => false,
|
||||||
|
.surface => |v| v.rt_surface.surface.childExited(value),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn showGtkInspector() void {
|
pub fn showGtkInspector() void {
|
||||||
gtk.Window.setInteractiveDebugging(@intFromBool(true));
|
gtk.Window.setInteractiveDebugging(@intFromBool(true));
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ const Common = @import("../class.zig").Common;
|
|||||||
const Application = @import("application.zig").Application;
|
const Application = @import("application.zig").Application;
|
||||||
const Config = @import("config.zig").Config;
|
const Config = @import("config.zig").Config;
|
||||||
const ResizeOverlay = @import("resize_overlay.zig").ResizeOverlay;
|
const ResizeOverlay = @import("resize_overlay.zig").ResizeOverlay;
|
||||||
|
const ChildExited = @import("surface_child_exited.zig").SurfaceChildExited;
|
||||||
const ClipboardConfirmationDialog = @import("clipboard_confirmation_dialog.zig").ClipboardConfirmationDialog;
|
const ClipboardConfirmationDialog = @import("clipboard_confirmation_dialog.zig").ClipboardConfirmationDialog;
|
||||||
|
|
||||||
const log = std.log.scoped(.gtk_ghostty_surface);
|
const log = std.log.scoped(.gtk_ghostty_surface);
|
||||||
@ -57,6 +58,26 @@ pub const Surface = extern struct {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const @"child-exited" = struct {
|
||||||
|
pub const name = "child-exited";
|
||||||
|
const impl = gobject.ext.defineProperty(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
bool,
|
||||||
|
.{
|
||||||
|
.nick = "Child Exited",
|
||||||
|
.blurb = "True when the child process has exited.",
|
||||||
|
.default = false,
|
||||||
|
.accessor = gobject.ext.privateFieldAccessor(
|
||||||
|
Self,
|
||||||
|
Private,
|
||||||
|
&Private.offset,
|
||||||
|
"child_exited",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
pub const focused = struct {
|
pub const focused = struct {
|
||||||
pub const name = "focused";
|
pub const name = "focused";
|
||||||
const impl = gobject.ext.defineProperty(
|
const impl = gobject.ext.defineProperty(
|
||||||
@ -284,7 +305,11 @@ pub const Surface = extern struct {
|
|||||||
/// True when we have a precision scroll in progress
|
/// True when we have a precision scroll in progress
|
||||||
precision_scroll: bool = false,
|
precision_scroll: bool = false,
|
||||||
|
|
||||||
|
/// True when the child has exited.
|
||||||
|
child_exited: bool = false,
|
||||||
|
|
||||||
// Template binds
|
// Template binds
|
||||||
|
child_exited_overlay: *ChildExited,
|
||||||
drop_target: *gtk.DropTarget,
|
drop_target: *gtk.DropTarget,
|
||||||
|
|
||||||
pub var offset: c_int = 0;
|
pub var offset: c_int = 0;
|
||||||
@ -634,6 +659,26 @@ pub const Surface = extern struct {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn childExited(
|
||||||
|
self: *Self,
|
||||||
|
data: apprt.surface.Message.ChildExited,
|
||||||
|
) bool {
|
||||||
|
// If we have the noop child exited overlay then we don't do anything
|
||||||
|
// for child exited. The false return will force libghostty to show
|
||||||
|
// the normal text-based message.
|
||||||
|
if (comptime @hasDecl(ChildExited, "noop")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const priv = self.private();
|
||||||
|
priv.child_exited = true;
|
||||||
|
priv.child_exited_overlay.setData(&data);
|
||||||
|
self.as(gobject.Object).notifyByPspec(
|
||||||
|
properties.@"child-exited".impl.param_spec,
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cgroupPath(self: *Self) ?[]const u8 {
|
pub fn cgroupPath(self: *Self) ?[]const u8 {
|
||||||
return self.private().cgroup_path;
|
return self.private().cgroup_path;
|
||||||
}
|
}
|
||||||
@ -1015,6 +1060,14 @@ pub const Surface = extern struct {
|
|||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Signal Handlers
|
// Signal Handlers
|
||||||
|
|
||||||
|
fn childExitedClose(
|
||||||
|
_: *ChildExited,
|
||||||
|
self: *Self,
|
||||||
|
) callconv(.c) void {
|
||||||
|
// This closes the surface with no confirmation.
|
||||||
|
self.close(false);
|
||||||
|
}
|
||||||
|
|
||||||
fn dtDrop(
|
fn dtDrop(
|
||||||
_: *gtk.DropTarget,
|
_: *gtk.DropTarget,
|
||||||
value: *gobject.Value,
|
value: *gobject.Value,
|
||||||
@ -1762,6 +1815,7 @@ pub const Surface = extern struct {
|
|||||||
|
|
||||||
fn init(class: *Class) callconv(.C) void {
|
fn init(class: *Class) callconv(.C) void {
|
||||||
gobject.ext.ensureType(ResizeOverlay);
|
gobject.ext.ensureType(ResizeOverlay);
|
||||||
|
gobject.ext.ensureType(ChildExited);
|
||||||
gtk.Widget.Class.setTemplateFromResource(
|
gtk.Widget.Class.setTemplateFromResource(
|
||||||
class.as(gtk.Widget.Class),
|
class.as(gtk.Widget.Class),
|
||||||
comptime gresource.blueprint(.{
|
comptime gresource.blueprint(.{
|
||||||
@ -1775,6 +1829,7 @@ pub const Surface = extern struct {
|
|||||||
class.bindTemplateChildPrivate("gl_area", .{});
|
class.bindTemplateChildPrivate("gl_area", .{});
|
||||||
class.bindTemplateChildPrivate("url_left", .{});
|
class.bindTemplateChildPrivate("url_left", .{});
|
||||||
class.bindTemplateChildPrivate("url_right", .{});
|
class.bindTemplateChildPrivate("url_right", .{});
|
||||||
|
class.bindTemplateChildPrivate("child_exited_overlay", .{});
|
||||||
class.bindTemplateChildPrivate("resize_overlay", .{});
|
class.bindTemplateChildPrivate("resize_overlay", .{});
|
||||||
class.bindTemplateChildPrivate("drop_target", .{});
|
class.bindTemplateChildPrivate("drop_target", .{});
|
||||||
class.bindTemplateChildPrivate("im_context", .{});
|
class.bindTemplateChildPrivate("im_context", .{});
|
||||||
@ -1802,6 +1857,7 @@ pub const Surface = extern struct {
|
|||||||
class.bindTemplateCallback("im_commit", &imCommit);
|
class.bindTemplateCallback("im_commit", &imCommit);
|
||||||
class.bindTemplateCallback("url_mouse_enter", &ecUrlMouseEnter);
|
class.bindTemplateCallback("url_mouse_enter", &ecUrlMouseEnter);
|
||||||
class.bindTemplateCallback("url_mouse_leave", &ecUrlMouseLeave);
|
class.bindTemplateCallback("url_mouse_leave", &ecUrlMouseLeave);
|
||||||
|
class.bindTemplateCallback("child_exited_close", &childExitedClose);
|
||||||
class.bindTemplateCallback("notify_config", &propConfig);
|
class.bindTemplateCallback("notify_config", &propConfig);
|
||||||
class.bindTemplateCallback("notify_mouse_hover_url", &propMouseHoverUrl);
|
class.bindTemplateCallback("notify_mouse_hover_url", &propMouseHoverUrl);
|
||||||
class.bindTemplateCallback("notify_mouse_hidden", &propMouseHidden);
|
class.bindTemplateCallback("notify_mouse_hidden", &propMouseHidden);
|
||||||
@ -1810,6 +1866,7 @@ pub const Surface = extern struct {
|
|||||||
// Properties
|
// Properties
|
||||||
gobject.ext.registerProperties(class, &.{
|
gobject.ext.registerProperties(class, &.{
|
||||||
properties.config.impl,
|
properties.config.impl,
|
||||||
|
properties.@"child-exited".impl,
|
||||||
properties.focused.impl,
|
properties.focused.impl,
|
||||||
properties.@"mouse-shape".impl,
|
properties.@"mouse-shape".impl,
|
||||||
properties.@"mouse-hidden".impl,
|
properties.@"mouse-hidden".impl,
|
||||||
|
272
src/apprt/gtk-ng/class/surface_child_exited.zig
Normal file
272
src/apprt/gtk-ng/class/surface_child_exited.zig
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
const adw = @import("adw");
|
||||||
|
const glib = @import("glib");
|
||||||
|
const gobject = @import("gobject");
|
||||||
|
const gtk = @import("gtk");
|
||||||
|
|
||||||
|
const adw_version = @import("../adw_version.zig");
|
||||||
|
const apprt = @import("../../../apprt.zig");
|
||||||
|
const gresource = @import("../build/gresource.zig");
|
||||||
|
const i18n = @import("../../../os/main.zig").i18n;
|
||||||
|
const Common = @import("../class.zig").Common;
|
||||||
|
|
||||||
|
const log = std.log.scoped(.gtk_ghostty_surface_child_exited);
|
||||||
|
|
||||||
|
pub const SurfaceChildExited = if (adw_version.supportsBanner())
|
||||||
|
SurfaceChildExitedBanner
|
||||||
|
else
|
||||||
|
SurfaceChildExitedNoop;
|
||||||
|
|
||||||
|
/// Child exited overlay based on adw.Banner introduced in
|
||||||
|
/// Adwaita 1.3.
|
||||||
|
const SurfaceChildExitedBanner = extern struct {
|
||||||
|
const Self = @This();
|
||||||
|
parent_instance: Parent,
|
||||||
|
pub const Parent = adw.Bin;
|
||||||
|
pub const getGObjectType = gobject.ext.defineClass(Self, .{
|
||||||
|
.name = "GhosttySurfaceChildExited",
|
||||||
|
.instanceInit = &init,
|
||||||
|
.classInit = &Class.init,
|
||||||
|
.parent_class = &Class.parent,
|
||||||
|
.private = .{ .Type = Private, .offset = &Private.offset },
|
||||||
|
});
|
||||||
|
|
||||||
|
pub const properties = struct {
|
||||||
|
pub const data = struct {
|
||||||
|
pub const name = "data";
|
||||||
|
const impl = gobject.ext.defineProperty(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
?*apprt.surface.Message.ChildExited,
|
||||||
|
.{
|
||||||
|
.nick = "Data",
|
||||||
|
.blurb = "The child exit data.",
|
||||||
|
.accessor = gobject.ext.privateFieldAccessor(
|
||||||
|
Self,
|
||||||
|
Private,
|
||||||
|
&Private.offset,
|
||||||
|
"data",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const signals = struct {
|
||||||
|
/// Emitted when the banner would like to be closed.
|
||||||
|
pub const @"close-request" = struct {
|
||||||
|
pub const name = "close-request";
|
||||||
|
pub const connect = impl.connect;
|
||||||
|
const impl = gobject.ext.defineSignal(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
&.{},
|
||||||
|
void,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const Private = struct {
|
||||||
|
/// The child exited data sent by the apprt.
|
||||||
|
data: ?*apprt.surface.Message.ChildExited = null,
|
||||||
|
|
||||||
|
// Template bindings
|
||||||
|
banner: *adw.Banner,
|
||||||
|
|
||||||
|
pub var offset: c_int = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn init(self: *Self, _: *Class) callconv(.C) void {
|
||||||
|
gtk.Widget.initTemplate(self.as(gtk.Widget));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setData(
|
||||||
|
self: *Self,
|
||||||
|
data_: ?*const apprt.surface.Message.ChildExited,
|
||||||
|
) void {
|
||||||
|
const priv = self.private();
|
||||||
|
if (priv.data) |v| glib.ext.destroy(v);
|
||||||
|
const data = data_ orelse {
|
||||||
|
priv.data = null;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ptr = glib.ext.create(apprt.surface.Message.ChildExited);
|
||||||
|
ptr.* = data.*;
|
||||||
|
priv.data = ptr;
|
||||||
|
self.as(gobject.Object).notifyByPspec(properties.data.impl.param_spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
|
// Signal handlers
|
||||||
|
|
||||||
|
fn propData(
|
||||||
|
self: *Self,
|
||||||
|
_: *gobject.ParamSpec,
|
||||||
|
_: ?*anyopaque,
|
||||||
|
) callconv(.c) void {
|
||||||
|
const priv = self.private();
|
||||||
|
const banner = priv.banner;
|
||||||
|
const data = priv.data orelse {
|
||||||
|
// Not localized on purpose.
|
||||||
|
banner.as(adw.Banner).setTitle("This is a bug in Ghostty. Please report it.");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if (data.exit_code == 0) {
|
||||||
|
banner.as(adw.Banner).setTitle(i18n._("Command succeeded"));
|
||||||
|
self.as(gtk.Widget).addCssClass("normal");
|
||||||
|
self.as(gtk.Widget).removeCssClass("abnormal");
|
||||||
|
} else {
|
||||||
|
banner.as(adw.Banner).setTitle(i18n._("Command failed"));
|
||||||
|
self.as(gtk.Widget).removeCssClass("normal");
|
||||||
|
self.as(gtk.Widget).addCssClass("abnormal");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn closeButtonClicked(
|
||||||
|
_: *adw.Banner,
|
||||||
|
self: *Self,
|
||||||
|
) callconv(.c) void {
|
||||||
|
signals.@"close-request".impl.emit(
|
||||||
|
self,
|
||||||
|
null,
|
||||||
|
.{},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------
|
||||||
|
// Virtual methods
|
||||||
|
|
||||||
|
fn dispose(self: *Self) callconv(.C) void {
|
||||||
|
gtk.Widget.disposeTemplate(
|
||||||
|
self.as(gtk.Widget),
|
||||||
|
getGObjectType(),
|
||||||
|
);
|
||||||
|
|
||||||
|
gobject.Object.virtual_methods.dispose.call(
|
||||||
|
Class.parent,
|
||||||
|
self.as(Parent),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finalize(self: *Self) callconv(.C) void {
|
||||||
|
const priv = self.private();
|
||||||
|
if (priv.data) |v| {
|
||||||
|
glib.ext.destroy(v);
|
||||||
|
priv.data = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
gobject.Object.virtual_methods.finalize.call(
|
||||||
|
Class.parent,
|
||||||
|
self.as(Parent),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const C = Common(Self, Private);
|
||||||
|
pub const as = C.as;
|
||||||
|
pub const ref = C.ref;
|
||||||
|
pub const unref = C.unref;
|
||||||
|
const private = C.private;
|
||||||
|
|
||||||
|
pub const Class = extern struct {
|
||||||
|
parent_class: Parent.Class,
|
||||||
|
var parent: *Parent.Class = undefined;
|
||||||
|
pub const Instance = Self;
|
||||||
|
|
||||||
|
fn init(class: *Class) callconv(.C) void {
|
||||||
|
gtk.Widget.Class.setTemplateFromResource(
|
||||||
|
class.as(gtk.Widget.Class),
|
||||||
|
comptime gresource.blueprint(.{
|
||||||
|
.major = 1,
|
||||||
|
.minor = 3,
|
||||||
|
.name = "surface-child-exited",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Template bindings
|
||||||
|
class.bindTemplateChildPrivate("banner", .{});
|
||||||
|
class.bindTemplateCallback("clicked", &closeButtonClicked);
|
||||||
|
class.bindTemplateCallback("notify_data", &propData);
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
gobject.ext.registerProperties(class, &.{
|
||||||
|
properties.data.impl,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Signals
|
||||||
|
signals.@"close-request".impl.register(.{});
|
||||||
|
|
||||||
|
// Virtual methods
|
||||||
|
gobject.Object.virtual_methods.dispose.implement(class, &dispose);
|
||||||
|
gobject.Object.virtual_methods.finalize.implement(class, &finalize);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const as = C.Class.as;
|
||||||
|
pub const bindTemplateChildPrivate = C.Class.bindTemplateChildPrivate;
|
||||||
|
pub const bindTemplateCallback = C.Class.bindTemplateCallback;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Empty widget that does nothing if we don't have a new enough
|
||||||
|
/// Adwaita version to support the child exited banner.
|
||||||
|
const SurfaceChildExitedNoop = extern struct {
|
||||||
|
/// Can be detected at comptime
|
||||||
|
pub const noop = true;
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
parent_instance: Parent,
|
||||||
|
pub const Parent = gtk.Widget;
|
||||||
|
pub const getGObjectType = gobject.ext.defineClass(Self, .{
|
||||||
|
.name = "GhosttySurfaceChildExited",
|
||||||
|
.classInit = &Class.init,
|
||||||
|
.parent_class = &Class.parent,
|
||||||
|
});
|
||||||
|
|
||||||
|
pub const signals = struct {
|
||||||
|
pub const @"close-request" = struct {
|
||||||
|
pub const name = "close-request";
|
||||||
|
pub const connect = impl.connect;
|
||||||
|
const impl = gobject.ext.defineSignal(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
&.{},
|
||||||
|
void,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn setData(
|
||||||
|
self: *Self,
|
||||||
|
_: ?*const apprt.surface.Message.ChildExited,
|
||||||
|
) void {
|
||||||
|
signals.@"close-request".impl.emit(
|
||||||
|
self,
|
||||||
|
null,
|
||||||
|
.{},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const C = Common(Self, null);
|
||||||
|
pub const as = C.as;
|
||||||
|
pub const ref = C.ref;
|
||||||
|
pub const unref = C.unref;
|
||||||
|
const private = C.private;
|
||||||
|
|
||||||
|
pub const Class = extern struct {
|
||||||
|
parent_class: Parent.Class,
|
||||||
|
var parent: *Parent.Class = undefined;
|
||||||
|
pub const Instance = Self;
|
||||||
|
|
||||||
|
fn init(class: *Class) callconv(.C) void {
|
||||||
|
_ = class;
|
||||||
|
signals.@"close-request".impl.register(.{});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const as = C.Class.as;
|
||||||
|
pub const bindTemplateChildPrivate = C.Class.bindTemplateChildPrivate;
|
||||||
|
pub const bindTemplateCallback = C.Class.bindTemplateCallback;
|
||||||
|
};
|
||||||
|
};
|
@ -69,3 +69,18 @@ label.url-overlay.right {
|
|||||||
.clipboard-confirmation-dialog .clipboard-contents.blurred {
|
.clipboard-confirmation-dialog .clipboard-contents.blurred {
|
||||||
filter: blur(5px);
|
filter: blur(5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Child Exited Overlay
|
||||||
|
*/
|
||||||
|
.child-exited.normal revealer widget {
|
||||||
|
background-color: rgba(38, 162, 105, 0.5);
|
||||||
|
/* after GTK 4.16 is a requirement, switch to the following:
|
||||||
|
/* background-color: color-mix(in srgb, var(--success-bg-color), transparent 50%); */
|
||||||
|
}
|
||||||
|
|
||||||
|
.child-exited.abnormal revealer widget {
|
||||||
|
background-color: rgba(192, 28, 40, 0.5);
|
||||||
|
/* after GTK 4.16 is a requirement, switch to the following:
|
||||||
|
/* background-color: color-mix(in srgb, var(--error-bg-color), transparent 50%); */
|
||||||
|
}
|
||||||
|
@ -25,6 +25,12 @@ template $GhosttySurface: Adw.Bin {
|
|||||||
use-es: false;
|
use-es: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[overlay]
|
||||||
|
$GhosttySurfaceChildExited child_exited_overlay {
|
||||||
|
visible: bind template.child-exited;
|
||||||
|
close-request => $child_exited_close();
|
||||||
|
}
|
||||||
|
|
||||||
[overlay]
|
[overlay]
|
||||||
$GhosttyResizeOverlay resize_overlay {
|
$GhosttyResizeOverlay resize_overlay {
|
||||||
styles [
|
styles [
|
||||||
|
22
src/apprt/gtk-ng/ui/1.3/surface-child-exited.blp
Normal file
22
src/apprt/gtk-ng/ui/1.3/surface-child-exited.blp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using Gtk 4.0;
|
||||||
|
using Adw 1;
|
||||||
|
|
||||||
|
template $GhosttySurfaceChildExited: Adw.Bin {
|
||||||
|
styles [
|
||||||
|
"child-exited",
|
||||||
|
]
|
||||||
|
|
||||||
|
notify::data => $notify_data();
|
||||||
|
|
||||||
|
Adw.Bin {
|
||||||
|
Adw.Banner banner {
|
||||||
|
button-clicked => $clicked();
|
||||||
|
revealed: true;
|
||||||
|
// Not localized on purpose because it should never be seen.
|
||||||
|
title: "This is a bug in Ghostty. Please report it.";
|
||||||
|
button-label: _("Close");
|
||||||
|
halign: fill;
|
||||||
|
valign: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ const std = @import("std");
|
|||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const apprt = @import("../apprt.zig");
|
const apprt = @import("../apprt.zig");
|
||||||
|
const build_config = @import("../build_config.zig");
|
||||||
const App = @import("../App.zig");
|
const App = @import("../App.zig");
|
||||||
const Surface = @import("../Surface.zig");
|
const Surface = @import("../Surface.zig");
|
||||||
const renderer = @import("../renderer.zig");
|
const renderer = @import("../renderer.zig");
|
||||||
@ -107,6 +108,18 @@ pub const Message = union(enum) {
|
|||||||
pub const ChildExited = extern struct {
|
pub const ChildExited = extern struct {
|
||||||
exit_code: u32,
|
exit_code: u32,
|
||||||
runtime_ms: u64,
|
runtime_ms: u64,
|
||||||
|
|
||||||
|
/// Make this a valid gobject if we're in a GTK environment.
|
||||||
|
pub const getGObjectType = switch (build_config.app_runtime) {
|
||||||
|
.gtk,
|
||||||
|
.@"gtk-ng",
|
||||||
|
=> @import("gobject").ext.defineBoxed(
|
||||||
|
ChildExited,
|
||||||
|
.{ .name = "GhosttyApprtChildExited" },
|
||||||
|
),
|
||||||
|
|
||||||
|
.none => void,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -82,6 +82,18 @@
|
|||||||
fun:main
|
fun:main
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
VMware Graphics Driver
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: possible
|
||||||
|
...
|
||||||
|
fun:vmw_fence_create
|
||||||
|
fun:vmw_ioctl_command
|
||||||
|
fun:vmw_swc_flush
|
||||||
|
fun:svga_context_flush
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
GSK Renderer GPU Stuff
|
GSK Renderer GPU Stuff
|
||||||
Memcheck:Leak
|
Memcheck:Leak
|
||||||
|
Reference in New Issue
Block a user