mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-22 19:56:08 +03:00
apprt/gtk: new surface options down to just a couple
This commit is contained in:
@ -4,6 +4,7 @@
|
|||||||
const Surface = @This();
|
const Surface = @This();
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
const configpkg = @import("../../config.zig");
|
const configpkg = @import("../../config.zig");
|
||||||
const apprt = @import("../../apprt.zig");
|
const apprt = @import("../../apprt.zig");
|
||||||
const font = @import("../../font/main.zig");
|
const font = @import("../../font/main.zig");
|
||||||
@ -28,21 +29,12 @@ const log = std.log.scoped(.gtk_surface);
|
|||||||
pub const opengl_single_threaded_draw = true;
|
pub const opengl_single_threaded_draw = true;
|
||||||
|
|
||||||
pub const Options = struct {
|
pub const Options = struct {
|
||||||
|
/// The parent surface to inherit settings such as font size, working
|
||||||
|
/// directory, etc. from.
|
||||||
|
parent2: ?*CoreSurface = null,
|
||||||
|
|
||||||
/// The parent this surface is created under.
|
/// The parent this surface is created under.
|
||||||
parent: Parent,
|
parent: Parent,
|
||||||
|
|
||||||
/// The GL area that this surface should draw to.
|
|
||||||
gl_area: *c.GtkGLArea,
|
|
||||||
|
|
||||||
/// A font size to set on the surface once it is initialized.
|
|
||||||
font_size: ?font.face.DesiredSize = null,
|
|
||||||
|
|
||||||
/// True if this surface has a parent. This is a bit of a hack currently
|
|
||||||
/// to work around newConfig unconditinally inheriting the working
|
|
||||||
/// directory. The proper long term fix is to have the working directory
|
|
||||||
/// inherited upstream likely at the point where this field would be set,
|
|
||||||
/// then remove this field.
|
|
||||||
parentSurface: bool = false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The container that this surface is directly attached to.
|
/// The container that this surface is directly attached to.
|
||||||
@ -129,12 +121,24 @@ im_composing: bool = false,
|
|||||||
im_buf: [128]u8 = undefined,
|
im_buf: [128]u8 = undefined,
|
||||||
im_len: u7 = 0,
|
im_len: u7 = 0,
|
||||||
|
|
||||||
|
pub fn create(alloc: Allocator, app: *App, opts: Options) !*Surface {
|
||||||
|
var surface = try alloc.create(Surface);
|
||||||
|
errdefer alloc.destroy(surface);
|
||||||
|
try surface.init(app, opts);
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
||||||
const widget = @as(*c.GtkWidget, @ptrCast(opts.gl_area));
|
const widget: *c.GtkWidget = c.gtk_gl_area_new();
|
||||||
c.gtk_gl_area_set_required_version(opts.gl_area, 3, 3);
|
const gl_area: *c.GtkGLArea = @ptrCast(widget);
|
||||||
c.gtk_gl_area_set_has_stencil_buffer(opts.gl_area, 0);
|
c.gtk_widget_set_hexpand(widget, 1);
|
||||||
c.gtk_gl_area_set_has_depth_buffer(opts.gl_area, 0);
|
c.gtk_widget_set_vexpand(widget, 1);
|
||||||
c.gtk_gl_area_set_use_es(opts.gl_area, 0);
|
|
||||||
|
c.gtk_widget_set_cursor_from_name(@ptrCast(gl_area), "text");
|
||||||
|
c.gtk_gl_area_set_required_version(gl_area, 3, 3);
|
||||||
|
c.gtk_gl_area_set_has_stencil_buffer(gl_area, 0);
|
||||||
|
c.gtk_gl_area_set_has_depth_buffer(gl_area, 0);
|
||||||
|
c.gtk_gl_area_set_use_es(gl_area, 0);
|
||||||
|
|
||||||
// Key event controller will tell us about raw keypress events.
|
// Key event controller will tell us about raw keypress events.
|
||||||
const ec_key = c.gtk_event_controller_key_new();
|
const ec_key = c.gtk_event_controller_key_new();
|
||||||
@ -184,17 +188,24 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
|||||||
c.gtk_widget_set_focusable(widget, 1);
|
c.gtk_widget_set_focusable(widget, 1);
|
||||||
c.gtk_widget_set_focus_on_click(widget, 1);
|
c.gtk_widget_set_focus_on_click(widget, 1);
|
||||||
|
|
||||||
|
// Inherit the parent's font size if we have a parent.
|
||||||
|
const font_size: ?font.face.DesiredSize = font_size: {
|
||||||
|
if (!app.config.@"window-inherit-font-size") break :font_size null;
|
||||||
|
const parent = opts.parent2 orelse break :font_size null;
|
||||||
|
break :font_size parent.font_size;
|
||||||
|
};
|
||||||
|
|
||||||
// Build our result
|
// Build our result
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.app = app,
|
.app = app,
|
||||||
.container = .{ .none = {} },
|
.container = .{ .none = {} },
|
||||||
.parent = opts.parent,
|
.parent = opts.parent,
|
||||||
.gl_area = opts.gl_area,
|
.gl_area = gl_area,
|
||||||
.title_text_buf = undefined,
|
.title_text_buf = undefined,
|
||||||
.title_text_buf_len = 0,
|
.title_text_buf_len = 0,
|
||||||
.core_surface = undefined,
|
.core_surface = undefined,
|
||||||
.font_size = opts.font_size,
|
.font_size = font_size,
|
||||||
.parentSurface = opts.parentSurface,
|
.parentSurface = opts.parent2 != null,
|
||||||
.size = .{ .width = 800, .height = 600 },
|
.size = .{ .width = 800, .height = 600 },
|
||||||
.cursor_pos = .{ .x = 0, .y = 0 },
|
.cursor_pos = .{ .x = 0, .y = 0 },
|
||||||
.im_context = im_context,
|
.im_context = im_context,
|
||||||
@ -205,11 +216,11 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
|||||||
try self.setMouseShape(.text);
|
try self.setMouseShape(.text);
|
||||||
|
|
||||||
// GL events
|
// GL events
|
||||||
_ = c.g_signal_connect_data(opts.gl_area, "realize", c.G_CALLBACK(>kRealize), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(gl_area, "realize", c.G_CALLBACK(>kRealize), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(opts.gl_area, "unrealize", c.G_CALLBACK(>kUnrealize), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(gl_area, "unrealize", c.G_CALLBACK(>kUnrealize), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(opts.gl_area, "destroy", c.G_CALLBACK(>kDestroy), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(gl_area, "destroy", c.G_CALLBACK(>kDestroy), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(opts.gl_area, "render", c.G_CALLBACK(>kRender), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(gl_area, "render", c.G_CALLBACK(>kRender), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(opts.gl_area, "resize", c.G_CALLBACK(>kResize), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(gl_area, "resize", c.G_CALLBACK(>kResize), self, null, c.G_CONNECT_DEFAULT);
|
||||||
|
|
||||||
_ = c.g_signal_connect_data(ec_key_press, "key-pressed", c.G_CALLBACK(>kKeyPressed), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(ec_key_press, "key-pressed", c.G_CALLBACK(>kKeyPressed), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(ec_key_press, "key-released", c.G_CALLBACK(>kKeyReleased), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(ec_key_press, "key-released", c.G_CALLBACK(>kKeyReleased), self, null, c.G_CONNECT_DEFAULT);
|
||||||
@ -267,6 +278,11 @@ fn realize(self: *Surface) !void {
|
|||||||
self.realized = true;
|
self.realized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *Surface, alloc: Allocator) void {
|
||||||
|
self.deinit();
|
||||||
|
alloc.free(self);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Surface) void {
|
pub fn deinit(self: *Surface) void {
|
||||||
// We don't allocate anything if we aren't realized.
|
// We don't allocate anything if we aren't realized.
|
||||||
if (!self.realized) return;
|
if (!self.realized) return;
|
||||||
|
@ -148,33 +148,14 @@ pub fn deinit(self: *Tab) void {
|
|||||||
/// Allocates and initializes a new Surface, but doesn't add it to the Tab yet.
|
/// Allocates and initializes a new Surface, but doesn't add it to the Tab yet.
|
||||||
/// Can also be added to a Paned.
|
/// Can also be added to a Paned.
|
||||||
pub fn newSurface(self: *Tab, parent_: ?*CoreSurface) !*Surface {
|
pub fn newSurface(self: *Tab, parent_: ?*CoreSurface) !*Surface {
|
||||||
// Grab a surface allocation we'll need it later.
|
const alloc = self.window.app.core_app.alloc;
|
||||||
var surface = try self.window.app.core_app.alloc.create(Surface);
|
var surface = try Surface.create(alloc, self.window.app, .{
|
||||||
errdefer self.window.app.core_app.alloc.destroy(surface);
|
.parent2 = parent_,
|
||||||
|
|
||||||
// Inherit the parent's font size if we are configured to.
|
|
||||||
const font_size: ?font.face.DesiredSize = font_size: {
|
|
||||||
if (!self.window.app.config.@"window-inherit-font-size") break :font_size null;
|
|
||||||
const parent = parent_ orelse break :font_size null;
|
|
||||||
break :font_size parent.font_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialize the GtkGLArea and attach it to our surface.
|
|
||||||
// The surface starts in the "unrealized" state because we have to
|
|
||||||
// wait for the "realize" callback from GTK to know that the OpenGL
|
|
||||||
// context is ready. See Surface docs for more info.
|
|
||||||
const gl_area = c.gtk_gl_area_new();
|
|
||||||
c.gtk_widget_set_hexpand(gl_area, 1);
|
|
||||||
c.gtk_widget_set_vexpand(gl_area, 1);
|
|
||||||
|
|
||||||
try surface.init(self.window.app, .{
|
|
||||||
.parent = .{
|
.parent = .{
|
||||||
.tab = self,
|
.tab = self,
|
||||||
},
|
},
|
||||||
.parentSurface = parent_ != null,
|
|
||||||
.gl_area = @ptrCast(gl_area),
|
|
||||||
.font_size = font_size,
|
|
||||||
});
|
});
|
||||||
|
errdefer surface.destroy(alloc);
|
||||||
surface.setContainer(.{ .tab_ = self });
|
surface.setContainer(.{ .tab_ = self });
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
|
Reference in New Issue
Block a user