mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
apprt/gtk-ng: surface inheritance, new window
This makes the `new_window` action properly inherit properties from the parent surface that initiated the action. Today, that is only the pwd and font size.
This commit is contained in:
@ -1085,9 +1085,7 @@ const Action = struct {
|
||||
self: *Application,
|
||||
parent: ?*CoreSurface,
|
||||
) !void {
|
||||
_ = parent;
|
||||
|
||||
const win = Window.new(self);
|
||||
const win = Window.new(self, parent);
|
||||
gtk.Window.present(win.as(gtk.Window));
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ const gobject = @import("gobject");
|
||||
const gtk = @import("gtk");
|
||||
|
||||
const apprt = @import("../../../apprt.zig");
|
||||
const font = @import("../../../font/main.zig");
|
||||
const input = @import("../../../input.zig");
|
||||
const internal_os = @import("../../../os/main.zig");
|
||||
const renderer = @import("../../../renderer.zig");
|
||||
@ -79,6 +80,25 @@ pub const Surface = extern struct {
|
||||
);
|
||||
};
|
||||
|
||||
pub const @"font-size-request" = struct {
|
||||
pub const name = "font-size-request";
|
||||
const impl = gobject.ext.defineProperty(
|
||||
name,
|
||||
Self,
|
||||
?*font.face.DesiredSize,
|
||||
.{
|
||||
.nick = "Desired Font Size",
|
||||
.blurb = "The desired font size, only affects initialization.",
|
||||
.accessor = gobject.ext.privateFieldAccessor(
|
||||
Self,
|
||||
Private,
|
||||
&Private.offset,
|
||||
"font_size_request",
|
||||
),
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
pub const focused = struct {
|
||||
pub const name = "focused";
|
||||
const impl = gobject.ext.defineProperty(
|
||||
@ -261,6 +281,10 @@ pub const Surface = extern struct {
|
||||
/// if `Application.transient_cgroup_base` is set.
|
||||
cgroup_path: ?[]const u8 = null,
|
||||
|
||||
/// The requested font size. This only applies to initialization
|
||||
/// and has no effect later.
|
||||
font_size_request: ?*font.face.DesiredSize = null,
|
||||
|
||||
/// The mouse shape to show for the surface.
|
||||
mouse_shape: terminal.MouseShape = .default,
|
||||
|
||||
@ -273,6 +297,10 @@ pub const Surface = extern struct {
|
||||
/// The current working directory. This has to be reported externally,
|
||||
/// usually by shell integration which then talks to libghostty
|
||||
/// which triggers this property.
|
||||
///
|
||||
/// If this is set prior to initialization then the surface will
|
||||
/// start in this pwd. If it is set after, it has no impact on the
|
||||
/// core surface.
|
||||
pwd: ?[:0]const u8 = null,
|
||||
|
||||
/// The title of this surface, if any has been set.
|
||||
@ -349,6 +377,38 @@ pub const Surface = extern struct {
|
||||
return &priv.rt_surface;
|
||||
}
|
||||
|
||||
/// Set the parent of this surface. This will extract the information
|
||||
/// required to initialize this surface with the proper values but doesn't
|
||||
/// retain any memory.
|
||||
///
|
||||
/// If the surface is already realized this does nothing.
|
||||
pub fn setParent(
|
||||
self: *Self,
|
||||
parent: *CoreSurface,
|
||||
) void {
|
||||
const priv = self.private();
|
||||
|
||||
// This is a mistake! We can only set a parent before surface
|
||||
// realization. We log this because this is probably a logic error.
|
||||
if (priv.core_surface != null) {
|
||||
log.warn("setParent called after surface is already realized", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup our font size
|
||||
const font_size_ptr = glib.ext.create(font.face.DesiredSize);
|
||||
errdefer glib.ext.destroy(font_size_ptr);
|
||||
font_size_ptr.* = parent.font_size;
|
||||
priv.font_size_request = font_size_ptr;
|
||||
self.as(gobject.Object).notifyByPspec(properties.@"font-size-request".impl.param_spec);
|
||||
|
||||
// Setup our pwd
|
||||
if (parent.rt_surface.surface.getPwd()) |pwd| {
|
||||
priv.pwd = glib.ext.dupeZ(u8, pwd);
|
||||
self.as(gobject.Object).notifyByPspec(properties.pwd.impl.param_spec);
|
||||
}
|
||||
}
|
||||
|
||||
/// Force the surface to redraw itself. Ghostty often will only redraw
|
||||
/// the terminal in reaction to internal changes. If there are external
|
||||
/// events that invalidate the surface, such as the widget moving parents,
|
||||
@ -1029,6 +1089,10 @@ pub const Surface = extern struct {
|
||||
glib.free(@constCast(@ptrCast(v)));
|
||||
priv.mouse_hover_url = null;
|
||||
}
|
||||
if (priv.font_size_request) |v| {
|
||||
glib.ext.destroy(v);
|
||||
priv.font_size_request = null;
|
||||
}
|
||||
if (priv.pwd) |v| {
|
||||
glib.free(@constCast(@ptrCast(v)));
|
||||
priv.pwd = null;
|
||||
@ -1053,6 +1117,11 @@ pub const Surface = extern struct {
|
||||
return self.private().title;
|
||||
}
|
||||
|
||||
/// Returns the pwd property without a copy.
|
||||
pub fn getPwd(self: *Self) ?[:0]const u8 {
|
||||
return self.private().pwd;
|
||||
}
|
||||
|
||||
fn propConfig(
|
||||
self: *Self,
|
||||
_: *gobject.ParamSpec,
|
||||
@ -1893,6 +1962,10 @@ pub const Surface = extern struct {
|
||||
);
|
||||
defer config.deinit();
|
||||
|
||||
// Properties that can impact surface init
|
||||
if (priv.font_size_request) |size| config.@"font-size" = size.points;
|
||||
if (priv.pwd) |pwd| config.@"working-directory" = pwd;
|
||||
|
||||
// Initialize the surface
|
||||
surface.init(
|
||||
alloc,
|
||||
@ -1996,6 +2069,7 @@ pub const Surface = extern struct {
|
||||
gobject.ext.registerProperties(class, &.{
|
||||
properties.config.impl,
|
||||
properties.@"child-exited".impl,
|
||||
properties.@"font-size-request".impl,
|
||||
properties.focused.impl,
|
||||
properties.@"mouse-shape".impl,
|
||||
properties.@"mouse-hidden".impl,
|
||||
|
@ -4,6 +4,7 @@ const adw = @import("adw");
|
||||
const gobject = @import("gobject");
|
||||
const gtk = @import("gtk");
|
||||
|
||||
const CoreSurface = @import("../../../Surface.zig");
|
||||
const gresource = @import("../build/gresource.zig");
|
||||
const Common = @import("../class.zig").Common;
|
||||
const Application = @import("application.zig").Application;
|
||||
@ -30,8 +31,17 @@ pub const Window = extern struct {
|
||||
pub var offset: c_int = 0;
|
||||
};
|
||||
|
||||
pub fn new(app: *Application) *Self {
|
||||
return gobject.ext.newInstance(Self, .{ .application = app });
|
||||
pub fn new(app: *Application, parent_: ?*CoreSurface) *Self {
|
||||
const self = gobject.ext.newInstance(Self, .{
|
||||
.application = app,
|
||||
});
|
||||
|
||||
if (parent_) |parent| {
|
||||
const priv = self.private();
|
||||
priv.surface.setParent(parent);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
fn init(self: *Self, _: *Class) callconv(.C) void {
|
||||
|
@ -1,5 +1,6 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const build_config = @import("../build_config.zig");
|
||||
const options = @import("main.zig").options;
|
||||
const Metrics = @import("main.zig").Metrics;
|
||||
const config = @import("../config.zig");
|
||||
@ -55,6 +56,16 @@ pub const DesiredSize = struct {
|
||||
// 1 point = 1/72 inch
|
||||
return @intFromFloat(@round((self.points * @as(f32, @floatFromInt(self.ydpi))) / 72));
|
||||
}
|
||||
|
||||
/// Make this a valid gobject if we're in a GTK environment.
|
||||
pub const getGObjectType = switch (build_config.app_runtime) {
|
||||
.gtk, .@"gtk-ng" => @import("gobject").ext.defineBoxed(
|
||||
DesiredSize,
|
||||
.{ .name = "GhosttyFontDesiredSize" },
|
||||
),
|
||||
|
||||
.none => void,
|
||||
};
|
||||
};
|
||||
|
||||
/// A font variation setting. The best documentation for this I know of
|
||||
|
Reference in New Issue
Block a user