mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 08:16:13 +03:00
gtk: use GtkDrawingArea to dim unfocused split
Refactor the GTK unfocused split code to use a GtkDrawingArea widget to dim the unfocused split. The GtkDrawingArea is added to the overlay and a CSS style is used to give it a background color and opacity. This aligns with the macOS design of drawing on top of the surface. In GTK, we don't need to actually draw a rectangle because we can apply CSS directly to the widget.
This commit is contained in:
@ -392,10 +392,8 @@ fn loadRuntimeCss(config: *const Config, provider: *c.GtkCssProvider) !void {
|
||||
const fmt =
|
||||
\\widget.unfocused-split {{
|
||||
\\ opacity: {d:.2};
|
||||
\\}}
|
||||
\\.ghostty-surface>stack {{
|
||||
\\ background-color: rgb({d},{d},{d});
|
||||
\\}}"
|
||||
\\}}
|
||||
;
|
||||
// The length required is always less than the length of the pre-formatted string:
|
||||
// -> '{d:.2}' gets replaced with max 4 bytes (0.00)
|
||||
@ -413,7 +411,7 @@ fn loadRuntimeCss(config: *const Config, provider: *c.GtkCssProvider) !void {
|
||||
},
|
||||
);
|
||||
// Clears any previously loaded CSS from this provider
|
||||
c.gtk_css_provider_load_from_string(provider, css);
|
||||
c.gtk_css_provider_load_from_data(provider, css, @intCast(css.len));
|
||||
}
|
||||
|
||||
/// Called by CoreApp to wake up the event loop.
|
||||
|
@ -325,6 +325,9 @@ gl_area: *c.GtkGLArea,
|
||||
/// If non-null this is the widget on the overlay that shows the URL.
|
||||
url_widget: ?URLWidget = null,
|
||||
|
||||
/// If non-null this is the widget on the overlay which dims the surface when it is unfocused
|
||||
unfocused_widget: ?*c.GtkWidget = null,
|
||||
|
||||
/// Any active cursor we may have
|
||||
cursor: ?*c.GdkCursor = null,
|
||||
|
||||
@ -590,6 +593,10 @@ pub fn deinit(self: *Surface) void {
|
||||
// Free all our GTK stuff
|
||||
c.g_object_unref(self.im_context);
|
||||
if (self.cursor) |cursor| c.g_object_unref(cursor);
|
||||
if (self.unfocused_widget) |widget| {
|
||||
c.gtk_overlay_remove_overlay(self.overlay, widget);
|
||||
self.unfocused_widget = null;
|
||||
}
|
||||
}
|
||||
|
||||
// unref removes the long-held reference to the gl_area and kicks off the
|
||||
@ -1809,8 +1816,11 @@ fn gtkFocusEnter(_: *c.GtkEventControllerFocus, ud: ?*anyopaque) callconv(.C) vo
|
||||
// Notify our IM context
|
||||
c.gtk_im_context_focus_in(self.im_context);
|
||||
|
||||
// Unconditionally remove the unfocused split css class
|
||||
c.gtk_widget_remove_css_class(@ptrCast(@alignCast(self.gl_area)), "unfocused-split");
|
||||
// Remove the unfocused widget overlay, if we have one
|
||||
if (self.unfocused_widget) |widget| {
|
||||
c.gtk_overlay_remove_overlay(self.overlay, widget);
|
||||
self.unfocused_widget = null;
|
||||
}
|
||||
|
||||
// Notify our surface
|
||||
self.core_surface.focusCallback(true) catch |err| {
|
||||
@ -1826,11 +1836,16 @@ fn gtkFocusLeave(_: *c.GtkEventControllerFocus, ud: ?*anyopaque) callconv(.C) vo
|
||||
// Notify our IM context
|
||||
c.gtk_im_context_focus_out(self.im_context);
|
||||
|
||||
// We only add the unfocused-split class if we are actually a split
|
||||
// We only add the unfocused-split widget if we are actually a split
|
||||
switch (self.container) {
|
||||
.split_br,
|
||||
.split_tl,
|
||||
=> c.gtk_widget_add_css_class(@ptrCast(@alignCast(self.gl_area)), "unfocused-split"),
|
||||
=> blk: {
|
||||
if (self.unfocused_widget != null) break :blk;
|
||||
self.unfocused_widget = c.gtk_drawing_area_new();
|
||||
c.gtk_widget_add_css_class(self.unfocused_widget.?, "unfocused-split");
|
||||
c.gtk_overlay_add_overlay(self.overlay, self.unfocused_widget.?);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user