Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions data/Application.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

dock {
background: alpha(@bg_color, 0.8);
border-radius: 9px;
box-shadow:
inset 0 -1px 0 0 alpha(@highlight_color, 0.4),
inset 0 1px 0 0 alpha(@highlight_color, 0.6),
Expand All @@ -15,7 +14,13 @@ dock {
0 1px 3px alpha(black, 0.2),
0 3px 9px alpha(black, 0.3);
opacity: 0.6;
padding: 9px;

border-radius: 9px;
/* This is required to correctly get border-radius
* If the size on startup is < border-radius * 2, the blur radius will be set incorrectly
*/
min-width: 18px;
min-height: 18px;
}

.reduce-transparency dock {
Expand Down
15 changes: 12 additions & 3 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public class Dock.MainWindow : Gtk.ApplicationWindow {

// Matches top margin in Launcher.css
private const int TOP_MARGIN = 64;
private const int BORDER_RADIUS = 9;

private Settings transparency_settings;
private static Settings settings = new Settings ("io.elementary.dock");
Expand All @@ -31,6 +30,7 @@ public class Dock.MainWindow : Gtk.ApplicationWindow {
private WindowDragManager window_drag_manager;
private BottomMargin bottom_margin;
private bool initialized_blur = false;
private int border_radius = 0;

class construct {
set_css_name ("dock-window");
Expand Down Expand Up @@ -144,10 +144,19 @@ public class Dock.MainWindow : Gtk.ApplicationWindow {
Graphene.Rect bounds;
bottom_margin.compute_bounds (bottom_margin, out bounds);

var new_snapshot = new Gtk.Snapshot ();
snapshot (new_snapshot);

var widget_border_radius = RenderNodeWalker.get_first_border_radius (new_snapshot.free_to_node (), null);

if (widget_border_radius != null) {
border_radius = widget_border_radius;
}

initialized_blur = true;

if (panel != null) {
panel.add_blur (0, 0, 0, (int) bounds.get_height (), BORDER_RADIUS);
panel.add_blur (0, 0, 0, (int) bounds.get_height (), border_radius);
} else {
update_panel_x11 ();
}
Expand Down Expand Up @@ -185,7 +194,7 @@ public class Dock.MainWindow : Gtk.ApplicationWindow {
if (initialized_blur) {
Graphene.Rect bounds;
bottom_margin.compute_bounds (bottom_margin, out bounds);
value += ":blur=0,0,0,%d,%d".printf ((int) bounds.get_height (), BORDER_RADIUS);
value += ":blur=0,0,0,%d,%d".printf ((int) bounds.get_height (), border_radius);
}

xdisplay.change_property (window, prop, X.XA_STRING, 8, 0, (uchar[]) value, value.length);
Expand Down
207 changes: 207 additions & 0 deletions src/RenderNodeWalker.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*
* SPDX-License-Identifier: GPL-3.0
* SPDX-FileCopyrightText: 2025 elementary, Inc. (https://elementary.io)
*/

public class Dock.RenderNodeWalker : GLib.Object {
public static int? get_first_border_radius (Gsk.RenderNode main_node, out int depth) {
depth = 0;

var main_node_type = main_node.get_node_type ();

if (main_node_type == Gsk.RenderNodeType.ROUNDED_CLIP_NODE) {
return (int) ((Gsk.RoundedClipNode) main_node).get_clip ().corner[0].width;
}

depth++;

if (main_node_type == Gsk.RenderNodeType.CONTAINER_NODE) {
var container_node = (Gsk.ContainerNode) main_node;

var min_child_depth = int.MAX;
int? min_border_radius = null;

for (var i = 0; i < container_node.get_n_children (); i++) {
var child_node = container_node.get_child (i);

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (child_depth < min_child_depth && border_radius != null) {
min_child_depth = child_depth;
min_border_radius = border_radius;
}
}

depth += min_child_depth;
return min_border_radius;
}

if (main_node_type == Gsk.RenderNodeType.GL_SHADER_NODE) {
var gl_shader_node = (Gsk.GLShaderNode) main_node;

var min_child_depth = int.MAX;
int? min_border_radius = null;

for (var i = 0; i < gl_shader_node.get_n_children (); i++) {
var child_node = gl_shader_node.get_child (i);

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (child_depth < min_child_depth && border_radius != null) {
min_child_depth = child_depth;
min_border_radius = border_radius;
}
}

depth += min_child_depth;
return min_border_radius;
}

if (main_node_type == Gsk.RenderNodeType.TRANSFORM_NODE) {
var child_node = ((Gsk.TransformNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.OPACITY_NODE) {
var child_node = ((Gsk.OpacityNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.COLOR_MATRIX_NODE) {
var child_node = ((Gsk.ColorMatrixNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.REPEAT_NODE) {
var child_node = ((Gsk.RepeatNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.CLIP_NODE) {
var child_node = ((Gsk.ClipNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.SHADOW_NODE) {
var child_node = ((Gsk.ShadowNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.BLUR_NODE) {
var child_node = ((Gsk.BlurNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.DEBUG_NODE) {
var child_node = ((Gsk.DebugNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.FILL_NODE) {
var child_node = ((Gsk.FillNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.STROKE_NODE) {
var child_node = ((Gsk.StrokeNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

if (main_node_type == Gsk.RenderNodeType.SUBSURFACE_NODE) {
var child_node = ((Gsk.SubsurfaceNode) main_node).get_child ();

int child_depth;
var border_radius = get_first_border_radius (child_node, out child_depth);

if (border_radius != null) {
depth += child_depth;
}

return border_radius;
}

return null;
}
}
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ sources = [
'BaseItem.vala',
'ItemManager.vala',
'MainWindow.vala',
'RenderNodeWalker.vala',
'AppSystem' / 'App.vala',
'AppSystem' / 'AppSystem.vala',
'AppSystem' / 'Launcher.vala',
Expand Down