GTK Fix unfocused-split-fill (#8813)
Attempts a resolution for https://github.com/ghostty-org/ghostty/discussions/8572 This matches the behavior of the old GTK apprt where unfocused-split-fill /opacity doesn't apply when there is only one active surface.pull/8858/head
commit
e951dedc66
|
|
@ -112,6 +112,25 @@ pub const SplitTree = extern struct {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const @"is-split" = struct {
|
||||||
|
pub const name = "is-split";
|
||||||
|
const impl = gobject.ext.defineProperty(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
bool,
|
||||||
|
.{
|
||||||
|
.default = false,
|
||||||
|
.accessor = gobject.ext.typedAccessor(
|
||||||
|
Self,
|
||||||
|
bool,
|
||||||
|
.{
|
||||||
|
.getter = getIsSplit,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const signals = struct {
|
pub const signals = struct {
|
||||||
|
|
@ -210,6 +229,14 @@ pub const SplitTree = extern struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind is-split property for new surface
|
||||||
|
_ = self.as(gobject.Object).bindProperty(
|
||||||
|
"is-split",
|
||||||
|
surface.as(gobject.Object),
|
||||||
|
"is-split",
|
||||||
|
.{ .sync_create = true },
|
||||||
|
);
|
||||||
|
|
||||||
// Create our tree
|
// Create our tree
|
||||||
var single_tree = try Surface.Tree.init(alloc, surface);
|
var single_tree = try Surface.Tree.init(alloc, surface);
|
||||||
defer single_tree.deinit();
|
defer single_tree.deinit();
|
||||||
|
|
@ -511,6 +538,18 @@ pub const SplitTree = extern struct {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getIsSplit(self: *Self) bool {
|
||||||
|
const tree: *const Surface.Tree = self.private().tree orelse &.empty;
|
||||||
|
if (tree.isEmpty()) return false;
|
||||||
|
|
||||||
|
const root_handle: Surface.Tree.Node.Handle = .root;
|
||||||
|
const root = tree.nodes[root_handle.idx()];
|
||||||
|
return switch (root) {
|
||||||
|
.leaf => false,
|
||||||
|
.split => true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Virtual methods
|
// Virtual methods
|
||||||
|
|
||||||
|
|
@ -816,6 +855,9 @@ pub const SplitTree = extern struct {
|
||||||
v.grabFocus();
|
v.grabFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Our split status may have changed
|
||||||
|
self.as(gobject.Object).notifyByPspec(properties.@"is-split".impl.param_spec);
|
||||||
|
|
||||||
// Our active surface may have changed
|
// Our active surface may have changed
|
||||||
self.as(gobject.Object).notifyByPspec(properties.@"active-surface".impl.param_spec);
|
self.as(gobject.Object).notifyByPspec(properties.@"active-surface".impl.param_spec);
|
||||||
|
|
||||||
|
|
@ -873,6 +915,7 @@ pub const SplitTree = extern struct {
|
||||||
properties.@"has-surfaces".impl,
|
properties.@"has-surfaces".impl,
|
||||||
properties.@"is-zoomed".impl,
|
properties.@"is-zoomed".impl,
|
||||||
properties.tree.impl,
|
properties.tree.impl,
|
||||||
|
properties.@"is-split".impl,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bindings
|
// Bindings
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,24 @@ pub const Surface = extern struct {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const @"is-split" = struct {
|
||||||
|
pub const name = "is-split";
|
||||||
|
const impl = gobject.ext.defineProperty(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
bool,
|
||||||
|
.{
|
||||||
|
.default = false,
|
||||||
|
.accessor = gobject.ext.privateFieldAccessor(
|
||||||
|
Self,
|
||||||
|
Private,
|
||||||
|
&Private.offset,
|
||||||
|
"is_split",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const signals = struct {
|
pub const signals = struct {
|
||||||
|
|
@ -503,6 +521,10 @@ pub const Surface = extern struct {
|
||||||
/// A weak reference to an inspector window.
|
/// A weak reference to an inspector window.
|
||||||
inspector: ?*InspectorWindow = null,
|
inspector: ?*InspectorWindow = null,
|
||||||
|
|
||||||
|
// True if the current surface is a split, this is used to apply
|
||||||
|
// unfocused-split-* options
|
||||||
|
is_split: bool = false,
|
||||||
|
|
||||||
// Template binds
|
// Template binds
|
||||||
child_exited_overlay: *ChildExited,
|
child_exited_overlay: *ChildExited,
|
||||||
context_menu: *gtk.PopoverMenu,
|
context_menu: *gtk.PopoverMenu,
|
||||||
|
|
@ -601,6 +623,16 @@ pub const Surface = extern struct {
|
||||||
return @intFromBool(config.@"bell-features".border);
|
return @intFromBool(config.@"bell-features".border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Callback used to determine whether unfocused-split-fill / unfocused-split-opacity
|
||||||
|
/// should be applied to the surface
|
||||||
|
fn closureShouldUnfocusedSplitBeShown(
|
||||||
|
_: *Self,
|
||||||
|
focused: c_int,
|
||||||
|
is_split: c_int,
|
||||||
|
) callconv(.c) c_int {
|
||||||
|
return @intFromBool(focused == 0 and is_split != 0);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn toggleFullscreen(self: *Self) void {
|
pub fn toggleFullscreen(self: *Self) void {
|
||||||
signals.@"toggle-fullscreen".impl.emit(
|
signals.@"toggle-fullscreen".impl.emit(
|
||||||
self,
|
self,
|
||||||
|
|
@ -2829,6 +2861,7 @@ pub const Surface = extern struct {
|
||||||
class.bindTemplateCallback("notify_mouse_shape", &propMouseShape);
|
class.bindTemplateCallback("notify_mouse_shape", &propMouseShape);
|
||||||
class.bindTemplateCallback("notify_bell_ringing", &propBellRinging);
|
class.bindTemplateCallback("notify_bell_ringing", &propBellRinging);
|
||||||
class.bindTemplateCallback("should_border_be_shown", &closureShouldBorderBeShown);
|
class.bindTemplateCallback("should_border_be_shown", &closureShouldBorderBeShown);
|
||||||
|
class.bindTemplateCallback("should_unfocused_split_be_shown", &closureShouldUnfocusedSplitBeShown);
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
gobject.ext.registerProperties(class, &.{
|
gobject.ext.registerProperties(class, &.{
|
||||||
|
|
@ -2847,6 +2880,7 @@ pub const Surface = extern struct {
|
||||||
properties.title.impl,
|
properties.title.impl,
|
||||||
properties.@"title-override".impl,
|
properties.@"title-override".impl,
|
||||||
properties.zoom.impl,
|
properties.zoom.impl,
|
||||||
|
properties.@"is-split".impl,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,20 @@ Overlay terminal_page {
|
||||||
label: bind template.mouse-hover-url;
|
label: bind template.mouse-hover-url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[overlay]
|
||||||
|
// Apply unfocused-split-fill and unfocused-split-opacity to current surface
|
||||||
|
// this is only applied when a tab has more than one surface
|
||||||
|
Revealer {
|
||||||
|
reveal-child: bind $should_unfocused_split_be_shown(template.focused, template.is-split) as <bool>;
|
||||||
|
transition-duration: 0;
|
||||||
|
|
||||||
|
DrawingArea {
|
||||||
|
styles [
|
||||||
|
"unfocused-split",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Event controllers for interactivity
|
// Event controllers for interactivity
|
||||||
EventControllerFocus {
|
EventControllerFocus {
|
||||||
enter => $focus_enter();
|
enter => $focus_enter();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue