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 {
|
test {
|
||||||
@import("std").testing.refAllDecls(@This());
|
@import("std").testing.refAllDecls(@This());
|
||||||
|
|
||||||
|
_ = @import("gtk/inspector.zig");
|
||||||
_ = @import("gtk/key.zig");
|
_ = @import("gtk/key.zig");
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ const Surface = @import("Surface.zig");
|
|||||||
const Window = @import("Window.zig");
|
const Window = @import("Window.zig");
|
||||||
const ConfigErrorsWindow = @import("ConfigErrorsWindow.zig");
|
const ConfigErrorsWindow = @import("ConfigErrorsWindow.zig");
|
||||||
const c = @import("c.zig");
|
const c = @import("c.zig");
|
||||||
|
const inspector = @import("inspector.zig");
|
||||||
const key = @import("key.zig");
|
const key = @import("key.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.gtk);
|
const log = std.log.scoped(.gtk);
|
||||||
@ -262,6 +263,12 @@ pub fn run(self: *App) !void {
|
|||||||
log.warn("error handling configuration changes err={}", .{err});
|
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) {
|
while (self.running) {
|
||||||
_ = c.g_main_context_iteration(self.ctx, 1);
|
_ = c.g_main_context_iteration(self.ctx, 1);
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ const CoreSurface = @import("../../Surface.zig");
|
|||||||
|
|
||||||
const App = @import("App.zig");
|
const App = @import("App.zig");
|
||||||
const Surface = @import("Surface.zig");
|
const Surface = @import("Surface.zig");
|
||||||
|
const icon = @import("icon.zig");
|
||||||
const c = @import("c.zig");
|
const c = @import("c.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.gtk);
|
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
|
/// The resources directory for the icon (if any). We need to retain a
|
||||||
/// pointer to this because GTK can use it at any time.
|
/// 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 {
|
pub fn create(alloc: Allocator, app: *App) !*Window {
|
||||||
// Allocate a fixed pointer for our window. We try to minimize
|
// 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
|
// Set up our own state
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.app = app,
|
.app = app,
|
||||||
|
.icon = undefined,
|
||||||
.window = undefined,
|
.window = undefined,
|
||||||
.notebook = 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
|
// 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.
|
// to the search path and see if we can find it there.
|
||||||
const icon_name = "com.mitchellh.ghostty";
|
self.icon = try icon.appIcon(self.app, window);
|
||||||
const icon_theme = c.gtk_icon_theme_get_for_display(c.gtk_widget_get_display(window));
|
c.gtk_window_set_icon_name(gtk_window, self.icon.name);
|
||||||
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);
|
|
||||||
|
|
||||||
// Apply background opacity if we have it
|
// Apply background opacity if we have it
|
||||||
if (app.config.@"background-opacity" < 1) {
|
if (app.config.@"background-opacity" < 1) {
|
||||||
@ -185,7 +167,7 @@ fn initActions(self: *Window) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(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.
|
/// 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