Skip to content

Commit

Permalink
feat(i3wm): rounded corners
Browse files Browse the repository at this point in the history
Signed-off-by: Joseph Benden <joe@benden.us>
  • Loading branch information
jbenden committed Feb 18, 2024
1 parent 910e585 commit dcbdc6d
Show file tree
Hide file tree
Showing 20 changed files with 406 additions and 16 deletions.
2 changes: 2 additions & 0 deletions docs/ipc
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ type (string)::
border (string)::
Can be either "normal", "none" or "pixel", depending on the
container’s border style.
border_radius (integer)::
Number of pixels of the border radius.
current_border_width (integer)::
Number of pixels of the border width.
layout (string)::
Expand Down
3 changes: 3 additions & 0 deletions i3-save-tree
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ my %allowed_keys = map { ($_, 1) } qw(
fullscreen_mode
layout
border
border_radius
current_border_width
floating
percent
Expand Down Expand Up @@ -122,6 +123,8 @@ sub strip_containers {

delete $tree->{current_border_width} if $tree->{current_border_width} == -1;

delete $tree->{border_radius} if $tree->{border_radius} == 0;

for my $key (keys %$tree) {
delete $tree->{$key} unless exists($allowed_keys{$key});
}
Expand Down
6 changes: 6 additions & 0 deletions include/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ void cmd_resize(I3_CMD, const char *way, const char *direction, long resize_px,
*/
void cmd_border(I3_CMD, const char *border_style_str, long border_width);

/**
* Implementation of 'border_radius [all] <px>'.
*
*/
void cmd_border_radius(I3_CMD, long border_radius, const char *border_radius_target);

/**
* Implementation of 'nop <comment>'.
*
Expand Down
6 changes: 6 additions & 0 deletions include/con.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,3 +587,9 @@ void con_merge_into(Con *old, Con *new);
*
*/
bool con_inside_stacked_or_tabbed(Con *con);

/**
* Returns true if the containers has no configured outer gap.
*
*/
bool has_outer_gaps(gaps_t gaps);
1 change: 1 addition & 0 deletions include/config_directives.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ CFGFUN(for_window, const char *command);
CFGFUN(gaps, const char *workspace, const char *type, const long value);
CFGFUN(smart_borders, const char *enable);
CFGFUN(smart_gaps, const char *enable);
CFGFUN(border_radius, const long radius);
CFGFUN(floating_minimum_size, const long width, const long height);
CFGFUN(floating_maximum_size, const long width, const long height);
CFGFUN(default_orientation, const char *orientation);
Expand Down
3 changes: 3 additions & 0 deletions include/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@ struct Config {

/* Disable gaps if there is only one container on the workspace */
smart_gaps_t smart_gaps;

/* Border radius specified in pixel units */
int32_t border_radius;
};

/**
Expand Down
3 changes: 3 additions & 0 deletions include/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -805,4 +805,7 @@ struct Con {

/* The colormap for this con if a custom one is used. */
xcb_colormap_t colormap;

/* Border radius specified in pixel units */
uint32_t border_radius;
};
13 changes: 13 additions & 0 deletions parser-specs/commands.spec
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ state INITIAL:
'reload' -> call cmd_reload()
'shmlog' -> SHMLOG
'debuglog' -> DEBUGLOG
'border_radius' -> BORDER_RADIUS
'border' -> BORDER
'layout' -> LAYOUT
'append_layout' -> APPEND_LAYOUT
Expand Down Expand Up @@ -120,6 +121,18 @@ state BORDER_WIDTH:
border_width = number
-> call cmd_border($border_style, &border_width)

# border_radius <px>
# border_radius all <px>
state BORDER_RADIUS:
target = 'all'
-> BORDER_RADIUS_WITH_TARGET
argument = number
-> call cmd_border_radius(&argument, NULL)

state BORDER_RADIUS_WITH_TARGET:
argument = number
-> call cmd_border_radius(&argument, $target)

# gaps inner|outer|horizontal|vertical|top|right|bottom|left [current] [set|plus|minus|toggle] <px>
state GAPS:
type = 'inner', 'outer', 'horizontal', 'vertical', 'top', 'right', 'bottom', 'left'
Expand Down
6 changes: 6 additions & 0 deletions parser-specs/config.spec
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ state INITIAL:
'gaps' -> GAPS
'smart_borders' -> SMART_BORDERS
'smart_gaps' -> SMART_GAPS
'border_radius' -> BORDER_RADIUS
'floating_minimum_size' -> FLOATING_MINIMUM_SIZE_WIDTH
'floating_maximum_size' -> FLOATING_MAXIMUM_SIZE_WIDTH
'floating_modifier' -> FLOATING_MODIFIER
Expand Down Expand Up @@ -105,6 +106,11 @@ state INCLUDE:
pattern = string
-> call cfg_include($pattern)

# border_radius <radius>
state BORDER_RADIUS:
radius = number
-> call cfg_border_radius(&radius)

# floating_minimum_size <width> x <height>
state FLOATING_MINIMUM_SIZE_WIDTH:
width = number
Expand Down
29 changes: 29 additions & 0 deletions src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,35 @@ void cmd_border(I3_CMD, const char *border_style_str, long border_width) {
ysuccess(true);
}

/*
* Implementation of 'border_radius [all] <px>'.
*
*/
void cmd_border_radius(I3_CMD, long border_radius, const char *target) {
DLOG("border radius should be changed to %ld for %s\n", border_radius, target);

HANDLE_EMPTY_MATCH;

if (target && strcmp(target, "all") == 0) {
Con *con;
TAILQ_FOREACH (con, &all_cons, all_cons) {
DLOG("matching: %p / %s\n", con, con->name);

con->border_radius = border_radius;
}
} else {
owindow *current;
TAILQ_FOREACH (current, &owindows, owindows) {
DLOG("matching: %p / %s\n", current->con, current->con->name);

current->con->border_radius = border_radius;
}
}

cmd_output->needs_tree_render = true;
ysuccess(true);
}

/*
* Implementation of 'nop <comment>'.
*
Expand Down
4 changes: 3 additions & 1 deletion src/con.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Con *con_new_skeleton(Con *parent, i3Window *window) {
new->border_style = new->max_user_border_style = config.default_border;
new->current_border_width = -1;
new->window_icon_padding = -1;
new->border_radius = config.border_radius;
if (window) {
new->depth = window->depth;
} else {
Expand Down Expand Up @@ -1802,7 +1803,7 @@ Con *con_descend_direction(Con *con, direction_t direction) {
return con_descend_direction(most, direction);
}

static bool has_outer_gaps(gaps_t gaps) {
bool has_outer_gaps(gaps_t gaps) {
return gaps.top > 0 ||
gaps.right > 0 ||
gaps.bottom > 0 ||
Expand Down Expand Up @@ -1875,6 +1876,7 @@ static Rect con_border_style_rect_without_title(Con *con) {
if (borders_to_hide & ADJ_LOWER_SCREEN_EDGE) {
result.height += border_width;
}

return result;
}

Expand Down
2 changes: 2 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ bool load_configuration(const char *override_configpath, config_load_t load_type
config.gaps.bottom = 0;
config.gaps.left = 0;

config.border_radius = 0;

/* Set default urgency reset delay to 500ms */
if (config.workspace_urgency_timer == 0) {
config.workspace_urgency_timer = 0.5;
Expand Down
4 changes: 4 additions & 0 deletions src/config_directives.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,10 @@ CFGFUN(smart_gaps, const char *enable) {
}
}

CFGFUN(border_radius, const long radius) {
config.border_radius = radius;
}

CFGFUN(floating_minimum_size, const long width, const long height) {
config.floating_minimum_width = width;
config.floating_minimum_height = height;
Expand Down
3 changes: 3 additions & 0 deletions src/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
ystr("current_border_width");
y(integer, con->current_border_width);

ystr("border_radius");
y(integer, con->border_radius);

dump_rect(gen, "rect", con->rect);
if (con_draw_decoration_into_frame(con)) {
Rect simulated_deco_rect = con->deco_rect;
Expand Down
12 changes: 10 additions & 2 deletions src/load_layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,12 @@ static int json_string(void *ctx, const unsigned char *val, size_t len) {
LOG("Unhandled \"border\": %s\n", buf);
}
free(buf);
} else if (strcasecmp(last_key, "border_radius") == 0) {
long r;
if (!parse_long((const char *)val, &r, 10)) {
LOG("Unhandled \"border_radius\": %s\n", val);
}
json_node->border_radius = r;
} else if (strcasecmp(last_key, "type") == 0) {
char *buf = NULL;
sasprintf(&buf, "%.*s", (int)len, val);
Expand Down Expand Up @@ -493,9 +499,11 @@ static int json_int(void *ctx, long long val) {
json_node->num = val;
}

if (strcasecmp(last_key, "current_border_width") == 0) {
if (strcasecmp(last_key, "border_radius") == 0)
json_node->border_radius = val;

if (strcasecmp(last_key, "current_border_width") == 0)
json_node->current_border_width = val;
}

if (strcasecmp(last_key, "window_icon_padding") == 0) {
json_node->window_icon_padding = val;
Expand Down

0 comments on commit dcbdc6d

Please sign in to comment.