mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
apprt/gtk: remove Window from Surface, use container only
This commit is contained in:
@ -100,7 +100,7 @@ pub fn splitSurfaceInPosition(self: *Paned, position: Position, direction: input
|
||||
// Create new Paned
|
||||
// NOTE: We cannot use `replaceChildInPosition` here because we need to
|
||||
// first remove the surface before we create a new pane.
|
||||
const paned = try Paned.create(surface.window.app.core_app.alloc, surface, direction);
|
||||
const paned = try Paned.create(surface.app.core_app.alloc, surface, direction);
|
||||
switch (position) {
|
||||
.start => self.addChild1(.{ .paned = paned }),
|
||||
.end => self.addChild2(.{ .paned = paned }),
|
||||
|
@ -21,16 +21,13 @@ const inspector = @import("inspector.zig");
|
||||
const gtk_key = @import("key.zig");
|
||||
const c = @import("c.zig");
|
||||
|
||||
const log = std.log.scoped(.gtk);
|
||||
const log = std.log.scoped(.gtk_surface);
|
||||
|
||||
/// This is detected by the OpenGL renderer to move to a single-threaded
|
||||
/// draw operation. This basically puts locks around our draw path.
|
||||
pub const opengl_single_threaded_draw = true;
|
||||
|
||||
pub const Options = struct {
|
||||
/// The window that this surface is attached to.
|
||||
window: *Window,
|
||||
|
||||
/// The tab that this surface is attached to.
|
||||
tab: *Tab,
|
||||
|
||||
@ -108,9 +105,6 @@ container: Container = .{ .none = {} },
|
||||
/// The app we're part of
|
||||
app: *App,
|
||||
|
||||
/// The window we're part of
|
||||
window: *Window,
|
||||
|
||||
/// The parent we belong to
|
||||
parent: Parent,
|
||||
|
||||
@ -209,7 +203,6 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
||||
// Build our result
|
||||
self.* = .{
|
||||
.app = app,
|
||||
.window = opts.window,
|
||||
.container = .{ .tab_ = opts.tab },
|
||||
.parent = opts.parent,
|
||||
.gl_area = opts.gl_area,
|
||||
@ -329,14 +322,20 @@ pub fn redraw(self: *Surface) void {
|
||||
|
||||
/// Close this surface.
|
||||
pub fn close(self: *Surface, processActive: bool) void {
|
||||
// If we are not currently in a window, then we don't need to do any
|
||||
// cleanup. If we are in a window, we need to potentially confirm,
|
||||
// remove ourselves from the view hierarchy, etc.
|
||||
const window = self.container.window() orelse return;
|
||||
|
||||
if (!processActive) {
|
||||
self.window.closeSurface(self);
|
||||
// TODO: change to container doing this directly
|
||||
window.closeSurface(self);
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup our basic message
|
||||
const alert = c.gtk_message_dialog_new(
|
||||
self.window.window,
|
||||
window.window,
|
||||
c.GTK_DIALOG_MODAL,
|
||||
c.GTK_MESSAGE_QUESTION,
|
||||
c.GTK_BUTTONS_YES_NO,
|
||||
@ -396,7 +395,15 @@ pub fn controlInspector(self: *Surface, mode: input.InspectorMode) void {
|
||||
}
|
||||
|
||||
pub fn toggleFullscreen(self: *Surface, mac_non_native: configpkg.NonNativeFullscreen) void {
|
||||
self.window.toggleFullscreen(mac_non_native);
|
||||
const window = self.container.window() orelse {
|
||||
log.info(
|
||||
"toggleFullscreen invalid for container={s}",
|
||||
.{@tagName(self.container)},
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
window.toggleFullscreen(mac_non_native);
|
||||
}
|
||||
|
||||
pub fn getTitleLabel(self: *Surface) ?*c.GtkWidget {
|
||||
@ -427,23 +434,53 @@ pub fn newSplit(self: *Surface, direction: input.SplitDirection) !void {
|
||||
}
|
||||
|
||||
pub fn newTab(self: *Surface) !void {
|
||||
try self.window.newTab(&self.core_surface);
|
||||
const window = self.container.window() orelse {
|
||||
log.info("surface cannot create new tab when not attached to a window", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
try window.newTab(&self.core_surface);
|
||||
}
|
||||
|
||||
pub fn hasTabs(self: *const Surface) bool {
|
||||
return self.window.hasTabs();
|
||||
const window = self.container.window() orelse return false;
|
||||
return window.hasTabs();
|
||||
}
|
||||
|
||||
pub fn gotoPreviousTab(self: *Surface) void {
|
||||
self.window.gotoPreviousTab(self);
|
||||
const window = self.container.window() orelse {
|
||||
log.info(
|
||||
"gotoPreviousTab invalid for container={s}",
|
||||
.{@tagName(self.container)},
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
window.gotoPreviousTab(self);
|
||||
}
|
||||
|
||||
pub fn gotoNextTab(self: *Surface) void {
|
||||
self.window.gotoNextTab(self);
|
||||
const window = self.container.window() orelse {
|
||||
log.info(
|
||||
"gotoNextTab invalid for container={s}",
|
||||
.{@tagName(self.container)},
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
window.gotoNextTab(self);
|
||||
}
|
||||
|
||||
pub fn gotoTab(self: *Surface, n: usize) void {
|
||||
self.window.gotoTab(n);
|
||||
const window = self.container.window() orelse {
|
||||
log.info(
|
||||
"gotoTab invalid for container={s}",
|
||||
.{@tagName(self.container)},
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
window.gotoTab(n);
|
||||
}
|
||||
|
||||
pub fn setShouldClose(self: *Surface) void {
|
||||
@ -467,10 +504,13 @@ pub fn getSize(self: *const Surface) !apprt.SurfaceSize {
|
||||
}
|
||||
|
||||
pub fn setInitialWindowSize(self: *const Surface, width: u32, height: u32) !void {
|
||||
// This operation only makes sense if we're within a window view hierarchy.
|
||||
const window = self.container.window() orelse return;
|
||||
|
||||
// Note: this doesn't properly take into account the window decorations.
|
||||
// I'm not currently sure how to do that.
|
||||
c.gtk_window_set_default_size(
|
||||
@ptrCast(self.window.window),
|
||||
@ptrCast(window.window),
|
||||
@intCast(width),
|
||||
@intCast(height),
|
||||
);
|
||||
@ -504,7 +544,10 @@ fn updateTitleLabels(self: *Surface) void {
|
||||
|
||||
const slice: []u8 = self.title_text_buf[0..self.title_text_buf_len];
|
||||
c.gtk_label_set_text(label, @as([*c]const u8, @ptrCast(slice)));
|
||||
c.gtk_window_set_title(self.window.window, c.gtk_label_get_text(label));
|
||||
c.gtk_window_set_title(
|
||||
self.container.window().?.window, // TODO: messy
|
||||
c.gtk_label_get_text(label),
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -810,8 +853,8 @@ fn gtkResize(area: *c.GtkGLArea, width: c.gint, height: c.gint, ud: ?*anyopaque)
|
||||
};
|
||||
|
||||
const window_scale_factor = scale: {
|
||||
const window = @as(*c.GtkNative, @ptrCast(self.window.window));
|
||||
const gdk_surface = c.gtk_native_get_surface(window);
|
||||
const window = self.container.window() orelse break :scale 0;
|
||||
const gdk_surface = c.gtk_native_get_surface(@ptrCast(window.window));
|
||||
break :scale c.gdk_surface_get_scale_factor(gdk_surface);
|
||||
};
|
||||
|
||||
@ -1359,7 +1402,8 @@ fn gtkCloseConfirmation(
|
||||
c.gtk_window_destroy(@ptrCast(alert));
|
||||
if (response == c.GTK_RESPONSE_YES) {
|
||||
const self = userdataSelf(ud.?);
|
||||
self.window.closeSurface(self);
|
||||
const window = self.container.window() orelse return;
|
||||
window.closeSurface(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,6 @@ pub fn newSurface(self: *Tab, parent_: ?*CoreSurface) !*Surface {
|
||||
c.gtk_widget_set_vexpand(gl_area, 1);
|
||||
|
||||
try surface.init(self.window.app, .{
|
||||
.window = self.window,
|
||||
.tab = self,
|
||||
.parent = .{
|
||||
.tab = self,
|
||||
|
@ -258,7 +258,7 @@ pub fn closeTab(self: *Window, tab: *Tab) void {
|
||||
|
||||
/// Close the surface. This surface must be definitely part of this window.
|
||||
pub fn closeSurface(self: *Window, surface: *Surface) void {
|
||||
assert(surface.window == self);
|
||||
assert(surface.container.window().? == self);
|
||||
|
||||
switch (surface.parent) {
|
||||
.none => unreachable,
|
||||
@ -485,8 +485,9 @@ fn gtkCloseRequest(v: *c.GtkWindow, ud: ?*anyopaque) callconv(.C) bool {
|
||||
|
||||
// If none of our surfaces need confirmation, we can just exit.
|
||||
for (self.app.core_app.surfaces.items) |surface| {
|
||||
if (surface.window == self) {
|
||||
if (surface.core_surface.needsConfirmQuit()) break;
|
||||
if (surface.container.window()) |window| {
|
||||
if (window == self and
|
||||
surface.core_surface.needsConfirmQuit()) break;
|
||||
}
|
||||
} else {
|
||||
c.gtk_window_destroy(self.window);
|
||||
|
Reference in New Issue
Block a user