mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
gtk: put gl area in notebook
This commit is contained in:
@ -126,7 +126,7 @@ pub const App = struct {
|
|||||||
|
|
||||||
// Tick the terminal app
|
// Tick the terminal app
|
||||||
const should_quit = try self.core_app.tick(self);
|
const should_quit = try self.core_app.tick(self);
|
||||||
if (should_quit) return;
|
if (false and should_quit) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,22 +152,37 @@ pub const App = struct {
|
|||||||
var surface = try self.core_app.alloc.create(Surface);
|
var surface = try self.core_app.alloc.create(Surface);
|
||||||
errdefer self.core_app.alloc.destroy(surface);
|
errdefer self.core_app.alloc.destroy(surface);
|
||||||
|
|
||||||
|
// Create the window
|
||||||
const window = c.gtk_application_window_new(self.app);
|
const window = c.gtk_application_window_new(self.app);
|
||||||
const gtk_window = @ptrCast(*c.GtkWindow, window);
|
const gtk_window = @ptrCast(*c.GtkWindow, window);
|
||||||
|
errdefer c.gtk_window_destroy(gtk_window);
|
||||||
c.gtk_window_set_title(gtk_window, "Ghostty");
|
c.gtk_window_set_title(gtk_window, "Ghostty");
|
||||||
c.gtk_window_set_default_size(gtk_window, 200, 200);
|
c.gtk_window_set_default_size(gtk_window, 200, 200);
|
||||||
c.gtk_widget_show(window);
|
c.gtk_widget_show(window);
|
||||||
|
|
||||||
|
// Create a notebook to hold our tabs.
|
||||||
|
const notebook_widget = c.gtk_notebook_new();
|
||||||
|
const notebook = @ptrCast(*c.GtkNotebook, notebook_widget);
|
||||||
|
c.gtk_notebook_set_tab_pos(notebook, c.GTK_POS_TOP);
|
||||||
|
|
||||||
// Initialize the GtkGLArea and attach it to our surface.
|
// Initialize the GtkGLArea and attach it to our surface.
|
||||||
// The surface starts in the "unrealized" state because we have to
|
// The surface starts in the "unrealized" state because we have to
|
||||||
// wait for the "realize" callback from GTK to know that the OpenGL
|
// wait for the "realize" callback from GTK to know that the OpenGL
|
||||||
// context is ready. See Surface docs for more info.
|
// context is ready. See Surface docs for more info.
|
||||||
const gl_area = c.gtk_gl_area_new();
|
const gl_area = c.gtk_gl_area_new();
|
||||||
|
const label = c.gtk_label_new("Ghostty");
|
||||||
try surface.init(self, .{
|
try surface.init(self, .{
|
||||||
.gl_area = @ptrCast(*c.GtkGLArea, gl_area),
|
.gl_area = @ptrCast(*c.GtkGLArea, gl_area),
|
||||||
|
.title_label = @ptrCast(*c.GtkLabel, label),
|
||||||
});
|
});
|
||||||
errdefer surface.deinit();
|
errdefer surface.deinit();
|
||||||
c.gtk_window_set_child(gtk_window, gl_area);
|
if (c.gtk_notebook_append_page(notebook, gl_area, label) < 0) {
|
||||||
|
log.warn("failed to add surface to notebook", .{});
|
||||||
|
return error.GtkAppendPageFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The notebook is our main child
|
||||||
|
c.gtk_window_set_child(gtk_window, notebook_widget);
|
||||||
|
|
||||||
// We need to grab focus after it is added to the window. When
|
// We need to grab focus after it is added to the window. When
|
||||||
// creating a window we want to always focus on the widget.
|
// creating a window we want to always focus on the widget.
|
||||||
@ -194,6 +209,16 @@ pub const Surface = struct {
|
|||||||
|
|
||||||
pub const Options = struct {
|
pub const Options = struct {
|
||||||
gl_area: *c.GtkGLArea,
|
gl_area: *c.GtkGLArea,
|
||||||
|
|
||||||
|
/// The label to use as the title of this surface. This will be
|
||||||
|
/// modified with setTitle.
|
||||||
|
title_label: ?*c.GtkLabel = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Where the title of this surface will go.
|
||||||
|
const Title = union(enum) {
|
||||||
|
none: void,
|
||||||
|
label: *c.GtkLabel,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Whether the surface has been realized or not yet. When a surface is
|
/// Whether the surface has been realized or not yet. When a surface is
|
||||||
@ -207,6 +232,9 @@ pub const Surface = struct {
|
|||||||
/// Our GTK area
|
/// Our GTK area
|
||||||
gl_area: *c.GtkGLArea,
|
gl_area: *c.GtkGLArea,
|
||||||
|
|
||||||
|
/// Our title label (if there is one).
|
||||||
|
title: Title,
|
||||||
|
|
||||||
/// The core surface backing this surface
|
/// The core surface backing this surface
|
||||||
core_surface: CoreSurface,
|
core_surface: CoreSurface,
|
||||||
|
|
||||||
@ -286,6 +314,9 @@ pub const Surface = struct {
|
|||||||
self.* = .{
|
self.* = .{
|
||||||
.app = app,
|
.app = app,
|
||||||
.gl_area = opts.gl_area,
|
.gl_area = opts.gl_area,
|
||||||
|
.title = if (opts.title_label) |label| .{
|
||||||
|
.label = label,
|
||||||
|
} else .{ .none = {} },
|
||||||
.core_surface = undefined,
|
.core_surface = undefined,
|
||||||
.size = .{ .width = 800, .height = 600 },
|
.size = .{ .width = 800, .height = 600 },
|
||||||
.cursor_pos = .{ .x = 0, .y = 0 },
|
.cursor_pos = .{ .x = 0, .y = 0 },
|
||||||
@ -378,14 +409,18 @@ pub const Surface = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn setTitle(self: *Surface, slice: [:0]const u8) !void {
|
pub fn setTitle(self: *Surface, slice: [:0]const u8) !void {
|
||||||
const root = c.gtk_widget_get_root(@ptrCast(
|
switch (self.title) {
|
||||||
*c.GtkWidget,
|
.none => {},
|
||||||
self.gl_area,
|
|
||||||
));
|
|
||||||
|
|
||||||
// TODO: we need a way to check if the type is a window
|
.label => |label| {
|
||||||
_ = root;
|
c.gtk_label_set_text(label, slice.ptr);
|
||||||
_ = slice;
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// const root = c.gtk_widget_get_root(@ptrCast(
|
||||||
|
// *c.GtkWidget,
|
||||||
|
// self.gl_area,
|
||||||
|
// ));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getClipboardString(self: *Surface) ![:0]const u8 {
|
pub fn getClipboardString(self: *Surface) ![:0]const u8 {
|
||||||
@ -496,12 +531,18 @@ pub const Surface = struct {
|
|||||||
_: c.gdouble,
|
_: c.gdouble,
|
||||||
ud: ?*anyopaque,
|
ud: ?*anyopaque,
|
||||||
) callconv(.C) void {
|
) callconv(.C) void {
|
||||||
|
const self = userdataSelf(ud.?);
|
||||||
const button = translateMouseButton(c.gtk_gesture_single_get_current_button(@ptrCast(
|
const button = translateMouseButton(c.gtk_gesture_single_get_current_button(@ptrCast(
|
||||||
*c.GtkGestureSingle,
|
*c.GtkGestureSingle,
|
||||||
gesture,
|
gesture,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
const self = userdataSelf(ud.?);
|
// If we don't have focus, grab it.
|
||||||
|
const gl_widget = @ptrCast(*c.GtkWidget, self.gl_area);
|
||||||
|
if (c.gtk_widget_has_focus(gl_widget) == 0) {
|
||||||
|
_ = c.gtk_widget_grab_focus(gl_widget);
|
||||||
|
}
|
||||||
|
|
||||||
self.core_surface.mouseButtonCallback(.press, button, .{}) catch |err| {
|
self.core_surface.mouseButtonCallback(.press, button, .{}) catch |err| {
|
||||||
log.err("error in key callback err={}", .{err});
|
log.err("error in key callback err={}", .{err});
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user