gtk: keep buffer of surface title, update if focused

This commit is contained in:
Thorsten Ball
2023-11-01 07:52:24 +01:00
committed by Mitchell Hashimoto
parent b1e3685664
commit b60133fd34
4 changed files with 38 additions and 24 deletions

View File

@ -87,11 +87,7 @@ pub fn setParent(self: *Paned, parent: Parent) void {
pub fn focusFirstSurfaceInPosition(self: *Paned, position: Position) void {
const child = self.childInPosition(position);
switch (child) {
.surface => |s| {
const widget = @as(*c.GtkWidget, @ptrCast(s.gl_area));
s.tab.focus_child = s;
_ = c.gtk_widget_grab_focus(widget);
},
.surface => |s| s.grabFocus(),
.paned => |p| p.focusFirstSurfaceInPosition(position),
.none => {
log.warn("attempted to focus on first surface, found none", .{});

View File

@ -90,6 +90,11 @@ cursor: ?*c.GdkCursor = null,
/// Our title label (if there is one).
title: Title,
/// Our title. The raw value of the title. This will be kept up to date and
/// .title will be updated if we have focus.
/// TODO: what's a big enough value?
titleText: [4096]u8,
/// The core surface backing this surface
core_surface: CoreSurface,
@ -175,6 +180,7 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
.title = if (opts.title_label) |label| .{
.label = label,
} else .{ .none = {} },
.titleText = undefined,
.core_surface = undefined,
.font_size = opts.font_size,
.parentSurface = opts.parentSurface,
@ -445,24 +451,38 @@ pub fn setSizeLimits(self: *Surface, min: apprt.SurfaceSize, max_: ?apprt.Surfac
_ = max_;
}
pub fn setTitle(self: *Surface, slice: [:0]const u8) !void {
pub fn grabFocus(self: *Surface) void {
self.updateTitleLabels();
self.tab.focus_child = self;
const widget = @as(*c.GtkWidget, @ptrCast(self.gl_area));
_ = c.gtk_widget_grab_focus(widget);
}
fn updateTitleLabels(self: *Surface) void {
switch (self.title) {
.none => {},
.label => |label| {
c.gtk_label_set_text(label, slice.ptr);
const widget = @as(*c.GtkWidget, @ptrCast(self.gl_area));
if (c.gtk_widget_is_focus(widget) == 1) {
const slice: []u8 = std.mem.sliceTo(&self.titleText, 0);
// Check whether there's even something in the buffer yet.
// TODO: This check is really bad.
if (slice.len != self.titleText.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));
}
},
}
}
// const root = c.gtk_widget_get_root(@ptrCast(
// *c.GtkWidget,
// self.gl_area,
// ));
pub fn setTitle(self: *Surface, slice: [:0]const u8) !void {
// TODO: I'm sure there has to be a better way than this in Zig.
const len = @min(self.titleText.len - 1, slice.len);
@memcpy(self.titleText[0..len], slice[0..]);
self.titleText[len] = 0;
const widget = @as(*c.GtkWidget, @ptrCast(self.gl_area));
if (c.gtk_widget_is_focus(widget) == 1) {
self.updateTitleLabels();
}
}
pub fn setParent(self: *Surface, parent: Parent) void {
@ -838,6 +858,10 @@ fn gtkMouseDown(
if (c.gtk_widget_has_focus(gl_widget) == 0) {
self.tab.focus_child = self;
_ = c.gtk_widget_grab_focus(gl_widget);
// If we have siblings, we also update the title, since it means
// another sibling might have updated the title.
if (self.parent != Parent.tab) self.updateTitleLabels();
}
self.core_surface.mouseButtonCallback(.press, button, mods) catch |err| {
@ -1267,6 +1291,7 @@ fn gtkInputCommit(
fn gtkFocusEnter(_: *c.GtkEventControllerFocus, ud: ?*anyopaque) callconv(.C) void {
const self = userdataSelf(ud.?);
// Notify our IM context
c.gtk_im_context_focus_in(self.im_context);

View File

@ -120,9 +120,6 @@ pub fn init(self: *Tab, window: *Window, parent_: ?*CoreSurface) !void {
c.gtk_notebook_set_show_tabs(window.notebook, 1);
}
// TODO: This needs to happen before we show the page
self.focus_child = surface;
// Set the userdata of the box to point to this tab.
c.g_object_set_data(@ptrCast(box_widget), GHOSTTY_TAB, self);
@ -131,7 +128,7 @@ pub fn init(self: *Tab, window: *Window, parent_: ?*CoreSurface) !void {
// We need to grab focus after Surface and Tab is added to the window. When
// creating a Tab we want to always focus on the widget.
_ = c.gtk_widget_grab_focus(gl_area_widget);
surface.grabFocus();
}
/// Allocates and initializes a new Surface, but doesn't add it to the Tab yet.

View File

@ -314,11 +314,7 @@ fn closeSurfaceInPaned(self: *Window, surface: *Surface, paned: *Paned, position
}
switch (sibling_child) {
.surface => |s| {
s.tab.focus_child = s;
const widget = @as(*c.GtkWidget, @ptrCast(s.gl_area));
_ = c.gtk_widget_grab_focus(widget);
},
.surface => |s| s.grabFocus(),
.paned => |p| {
// Focus on first surface in sibling Paned
p.focusFirstSurfaceInPosition(position);