summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOrestis Floros <orestisflo@gmail.com>2021-09-09 09:27:30 +0200
committerGitHub <noreply@github.com>2021-09-09 09:27:30 +0200
commitce2c21885dcf270bd029bfe202bb00ace3a4ba25 (patch)
tree3e28ff74e7b2942ba8dc2bc654ad1b723ae9e9e3
parent579973b1ef25278be6d43721da9dfff36fc11e4c (diff)
parentcc44d9a99918d5a92766b5db9e0ba034935298bb (diff)
downloadi3-ce2c21885dcf270bd029bfe202bb00ace3a4ba25.tar.gz
i3-ce2c21885dcf270bd029bfe202bb00ace3a4ba25.zip
Merge pull request #4497 from orestisfl/icons-title-align
Make window icons follow title alignment
-rw-r--r--src/x.c81
1 files changed, 44 insertions, 37 deletions
diff --git a/src/x.c b/src/x.c
index 55dc63a0..cdc29876 100644
--- a/src/x.c
+++ b/src/x.c
@@ -614,33 +614,11 @@ void x_draw_decoration(Con *con) {
/* 6: draw the icon and title */
int text_offset_y = (con->deco_rect.height - config.font.height) / 2;
- int text_offset_x = 0;
struct Window *win = con->window;
- const int title_padding = logical_px(2);
const int deco_width = (int)con->deco_rect.width;
-
- /* Draw the icon */
- if (con->window_icon_padding > -1 && win && win->icon) {
- /* icon_padding is applied horizontally only,
- * the icon will always use all available vertical space. */
- const int icon_padding = logical_px(1 + con->window_icon_padding);
-
- const uint16_t icon_size = con->deco_rect.height - 2 * logical_px(1);
-
- const int icon_offset_y = logical_px(1);
-
- text_offset_x += icon_size + 2 * icon_padding;
-
- draw_util_image(
- win->icon,
- &(parent->frame_buffer),
- con->deco_rect.x + icon_padding,
- con->deco_rect.y + icon_offset_y,
- icon_size,
- icon_size);
- }
+ const int title_padding = logical_px(2);
int mark_width = 0;
if (config.show_marks && !TAILQ_EMPTY(&(con->marks_head))) {
@@ -699,33 +677,62 @@ void x_draw_decoration(Con *con) {
goto copy_pixmaps;
}
+ /* icon_padding is applied horizontally only, the icon will always use all
+ * available vertical space. */
+ int icon_size = max(0, con->deco_rect.height - logical_px(2));
+ int icon_padding = logical_px(max(1, con->window_icon_padding));
+ int total_icon_space = icon_size + 2 * icon_padding;
+ const bool has_icon = (con->window_icon_padding > -1) && win && win->icon && (total_icon_space < deco_width);
+ if (!has_icon) {
+ icon_size = icon_padding = total_icon_space = 0;
+ }
+ /* Determine x offsets according to title alignment */
+ int icon_offset_x;
int title_offset_x;
switch (config.title_align) {
case ALIGN_LEFT:
- /* (pad)[text ](pad)[mark + its pad) */
- title_offset_x = title_padding;
+ /* (pad)[(pad)(icon)(pad)][text ](pad)[mark + its pad)
+ * ^ ^--- title_offset_x
+ * ^--- icon_offset_x */
+ icon_offset_x = icon_padding;
+ title_offset_x = title_padding + total_icon_space;
break;
case ALIGN_CENTER:
- /* (pad)[ text ](pad)[mark + its pad)
- * To center the text inside its allocated space, the surface
- * between the brackets, we use the formula
- * (surface_width - predict_text_width) / 2
- * where surface_width = deco_width - 2 * pad - mark_width
- * so, offset = pad + (surface_width - predict_text_width) / 2 =
- * = … = (deco_width - mark_width - predict_text_width) / 2 */
- title_offset_x = max(title_padding, (deco_width - mark_width - predict_text_width(title)) / 2);
+ /* (pad)[ ][(pad)(icon)(pad)][text ](pad)[mark + its pad)
+ * ^ ^--- title_offset_x
+ * ^--- icon_offset_x
+ * Text should come right after the icon (+padding). We calculate
+ * the offset for the icon (white space in the title) by dividing
+ * by two the total available area. That's the decoration width
+ * minus the elements that come after icon_offset_x (icon, its
+ * padding, text, marks). */
+ icon_offset_x = max(icon_padding, (deco_width - icon_padding - icon_size - predict_text_width(title) - title_padding - mark_width) / 2);
+ title_offset_x = max(title_padding, icon_offset_x + icon_padding + icon_size);
break;
case ALIGN_RIGHT:
- /* [mark + its pad](pad)[ text](pad) */
- title_offset_x = max(title_padding + mark_width, deco_width - title_padding - predict_text_width(title));
+ /* [mark + its pad](pad)[ text][(pad)(icon)(pad)](pad)
+ * ^ ^--- icon_offset_x
+ * ^--- title_offset_x */
+ title_offset_x = max(title_padding + mark_width, deco_width - title_padding - predict_text_width(title) - total_icon_space);
+ /* Make sure the icon does not escape title boundaries */
+ icon_offset_x = min(deco_width - icon_size - icon_padding - title_padding, title_offset_x + predict_text_width(title) + icon_padding);
break;
}
draw_util_text(title, &(parent->frame_buffer),
p->color->text, p->color->background,
- con->deco_rect.x + text_offset_x + title_offset_x,
+ con->deco_rect.x + title_offset_x,
con->deco_rect.y + text_offset_y,
- deco_width - text_offset_x - mark_width - 2 * title_padding);
+ deco_width - mark_width - 2 * title_padding - total_icon_space);
+ if (has_icon) {
+ draw_util_image(
+ win->icon,
+ &(parent->frame_buffer),
+ con->deco_rect.x + icon_offset_x,
+ con->deco_rect.y + logical_px(1),
+ icon_size,
+ icon_size);
+ }
if (win == NULL || con->title_format != NULL) {
I3STRING_FREE(title);