mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
apprt/gtk: empty inspector window
This commit is contained in:
@ -6,5 +6,6 @@ pub const Surface = @import("gtk/Surface.zig");
|
||||
test {
|
||||
@import("std").testing.refAllDecls(@This());
|
||||
|
||||
_ = @import("gtk/inspector.zig");
|
||||
_ = @import("gtk/key.zig");
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ const Surface = @import("Surface.zig");
|
||||
const Window = @import("Window.zig");
|
||||
const ConfigErrorsWindow = @import("ConfigErrorsWindow.zig");
|
||||
const c = @import("c.zig");
|
||||
const inspector = @import("inspector.zig");
|
||||
const key = @import("key.zig");
|
||||
|
||||
const log = std.log.scoped(.gtk);
|
||||
@ -262,6 +263,12 @@ pub fn run(self: *App) !void {
|
||||
log.warn("error handling configuration changes err={}", .{err});
|
||||
};
|
||||
|
||||
// TODO: temporary, remove: show our inspector window
|
||||
{
|
||||
const win = try inspector.Window.create(self.core_app.alloc, self);
|
||||
_ = win;
|
||||
}
|
||||
|
||||
while (self.running) {
|
||||
_ = c.g_main_context_iteration(self.ctx, 1);
|
||||
|
||||
|
@ -12,6 +12,7 @@ const CoreSurface = @import("../../Surface.zig");
|
||||
|
||||
const App = @import("App.zig");
|
||||
const Surface = @import("Surface.zig");
|
||||
const icon = @import("icon.zig");
|
||||
const c = @import("c.zig");
|
||||
|
||||
const log = std.log.scoped(.gtk);
|
||||
@ -28,7 +29,7 @@ notebook: *c.GtkNotebook,
|
||||
|
||||
/// The resources directory for the icon (if any). We need to retain a
|
||||
/// pointer to this because GTK can use it at any time.
|
||||
icon_search_dir: ?[:0]const u8 = null,
|
||||
icon: icon.Icon,
|
||||
|
||||
pub fn create(alloc: Allocator, app: *App) !*Window {
|
||||
// Allocate a fixed pointer for our window. We try to minimize
|
||||
@ -48,6 +49,7 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
// Set up our own state
|
||||
self.* = .{
|
||||
.app = app,
|
||||
.icon = undefined,
|
||||
.window = undefined,
|
||||
.notebook = undefined,
|
||||
};
|
||||
@ -62,28 +64,8 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
|
||||
// If we don't have the icon then we'll try to add our resources dir
|
||||
// to the search path and see if we can find it there.
|
||||
const icon_name = "com.mitchellh.ghostty";
|
||||
const icon_theme = c.gtk_icon_theme_get_for_display(c.gtk_widget_get_display(window));
|
||||
if (c.gtk_icon_theme_has_icon(icon_theme, icon_name) == 0) icon: {
|
||||
const base = self.app.core_app.resources_dir orelse {
|
||||
log.info("gtk app missing Ghostty icon and no resources dir detected", .{});
|
||||
log.info("gtk app will not have Ghostty icon", .{});
|
||||
break :icon;
|
||||
};
|
||||
|
||||
// Note that this method for adding the icon search path is
|
||||
// a fallback mechanism. The recommended mechanism is the
|
||||
// Freedesktop Icon Theme Specification. We distribute a ".desktop"
|
||||
// file in zig-out/share that should be installed to the proper
|
||||
// place.
|
||||
const dir = try std.fmt.allocPrintZ(app.core_app.alloc, "{s}/icons", .{base});
|
||||
self.icon_search_dir = dir;
|
||||
c.gtk_icon_theme_add_search_path(icon_theme, dir.ptr);
|
||||
if (c.gtk_icon_theme_has_icon(icon_theme, icon_name) == 0) {
|
||||
log.warn("Ghostty icon for gtk app not found", .{});
|
||||
}
|
||||
}
|
||||
c.gtk_window_set_icon_name(gtk_window, icon_name);
|
||||
self.icon = try icon.appIcon(self.app, window);
|
||||
c.gtk_window_set_icon_name(gtk_window, self.icon.name);
|
||||
|
||||
// Apply background opacity if we have it
|
||||
if (app.config.@"background-opacity" < 1) {
|
||||
@ -185,7 +167,7 @@ fn initActions(self: *Window) void {
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Window) void {
|
||||
if (self.icon_search_dir) |ptr| self.app.core_app.alloc.free(ptr);
|
||||
self.icon.deinit(self.app);
|
||||
}
|
||||
|
||||
/// Add a new tab to this window.
|
||||
|
52
src/apprt/gtk/icon.zig
Normal file
52
src/apprt/gtk/icon.zig
Normal file
@ -0,0 +1,52 @@
|
||||
const std = @import("std");
|
||||
|
||||
const App = @import("App.zig");
|
||||
const c = @import("c.zig");
|
||||
|
||||
const log = std.log.scoped(.gtk_icon);
|
||||
|
||||
/// An icon. The icon may be associated with some allocated state so when
|
||||
/// the icon is no longer in use it should be deinitialized.
|
||||
pub const Icon = struct {
|
||||
name: [:0]const u8,
|
||||
state: ?[:0]const u8 = null,
|
||||
|
||||
pub fn deinit(self: *const Icon, app: *App) void {
|
||||
if (self.state) |v| app.core_app.alloc.free(v);
|
||||
}
|
||||
};
|
||||
|
||||
/// Returns the application icon that can be used anywhere. This attempts to
|
||||
/// find the icon in the theme and if it can't be found, it is loaded from
|
||||
/// the resources dir. If the resources dir can't be found, we'll log a warning
|
||||
/// and let GTK choose a fallback.
|
||||
pub fn appIcon(app: *App, widget: *c.GtkWidget) !Icon {
|
||||
const icon_name = "com.mitchellh.ghostty";
|
||||
var result: Icon = .{ .name = icon_name };
|
||||
|
||||
// If we don't have the icon then we'll try to add our resources dir
|
||||
// to the search path and see if we can find it there.
|
||||
const icon_theme = c.gtk_icon_theme_get_for_display(c.gtk_widget_get_display(widget));
|
||||
if (c.gtk_icon_theme_has_icon(icon_theme, icon_name) == 0) icon: {
|
||||
const base = app.core_app.resources_dir orelse {
|
||||
log.info("gtk app missing Ghostty icon and no resources dir detected", .{});
|
||||
log.info("gtk app will not have Ghostty icon", .{});
|
||||
break :icon;
|
||||
};
|
||||
|
||||
// Note that this method for adding the icon search path is
|
||||
// a fallback mechanism. The recommended mechanism is the
|
||||
// Freedesktop Icon Theme Specification. We distribute a ".desktop"
|
||||
// file in zig-out/share that should be installed to the proper
|
||||
// place.
|
||||
const dir = try std.fmt.allocPrintZ(app.core_app.alloc, "{s}/icons", .{base});
|
||||
errdefer app.core_app.alloc.free(dir);
|
||||
result.state = dir;
|
||||
c.gtk_icon_theme_add_search_path(icon_theme, dir.ptr);
|
||||
if (c.gtk_icon_theme_has_icon(icon_theme, icon_name) == 0) {
|
||||
log.warn("Ghostty icon for gtk app not found", .{});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
68
src/apprt/gtk/inspector.zig
Normal file
68
src/apprt/gtk/inspector.zig
Normal file
@ -0,0 +1,68 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const App = @import("App.zig");
|
||||
const TerminalWindow = @import("Window.zig");
|
||||
const c = @import("c.zig");
|
||||
const icon = @import("icon.zig");
|
||||
|
||||
const log = std.log.scoped(.inspector);
|
||||
|
||||
/// A window to hold a dedicated inspector instance.
|
||||
pub const Window = struct {
|
||||
/// Our app
|
||||
app: *App,
|
||||
|
||||
/// Our window
|
||||
window: *c.GtkWindow,
|
||||
|
||||
/// The window icon
|
||||
icon: icon.Icon,
|
||||
|
||||
pub fn create(alloc: Allocator, app: *App) !*Window {
|
||||
var window = try alloc.create(Window);
|
||||
errdefer alloc.destroy(window);
|
||||
try window.init(app);
|
||||
return window;
|
||||
}
|
||||
|
||||
pub fn init(self: *Window, app: *App) !void {
|
||||
// Initialize to undefined
|
||||
self.* = .{
|
||||
.app = app,
|
||||
.icon = undefined,
|
||||
.window = undefined,
|
||||
};
|
||||
|
||||
// Create the window
|
||||
const window = c.gtk_application_window_new(app.app);
|
||||
const gtk_window: *c.GtkWindow = @ptrCast(window);
|
||||
errdefer c.gtk_window_destroy(gtk_window);
|
||||
self.window = gtk_window;
|
||||
c.gtk_window_set_title(gtk_window, "Ghostty");
|
||||
c.gtk_window_set_default_size(gtk_window, 1000, 600);
|
||||
self.icon = try icon.appIcon(self.app, window);
|
||||
c.gtk_window_set_icon_name(gtk_window, self.icon.name);
|
||||
|
||||
// Signals
|
||||
_ = c.g_signal_connect_data(window, "destroy", c.G_CALLBACK(>kDestroy), self, null, c.G_CONNECT_DEFAULT);
|
||||
|
||||
// Show the window
|
||||
c.gtk_widget_show(window);
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Window) void {
|
||||
self.icon.deinit(self.app);
|
||||
}
|
||||
|
||||
/// "destroy" signal for the window
|
||||
fn gtkDestroy(v: *c.GtkWidget, ud: ?*anyopaque) callconv(.C) void {
|
||||
_ = v;
|
||||
log.debug("window destroy", .{});
|
||||
|
||||
const self: *Window = @ptrCast(@alignCast(ud.?));
|
||||
const alloc = self.app.core_app.alloc;
|
||||
self.deinit();
|
||||
alloc.destroy(self);
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user