Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add progress bar #775

Merged
merged 2 commits into from
Nov 10, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 12 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ struct settings defaults = {
.markup = MARKUP_NO,
.colors_norm.bg = "#1793D1",
.colors_norm.fg = "#DDDDDD",
.colors_norm.highlight = "#1745d1",
.colors_crit.bg = "#ffaaaa",
.colors_crit.fg = "#000000",
.colors_crit.highlight = "#ff6666",
.colors_low.bg = "#aaaaff",
.colors_low.fg = "#000000",
.colors_low.highlight = "#7f7fff",
.format = "%s %b", /* default format */

.timeouts = { S2US(10), S2US(10), S2US(0) }, /* low, normal, critical */
Expand Down Expand Up @@ -110,6 +113,15 @@ struct settings defaults = {

.mouse_right_click = (enum mouse_action []){MOUSE_CLOSE_ALL, -1},

.progress_bar_height = 10,

.progress_bar_min_width = 150,

.progress_bar_max_width = 300,

.progress_bar_frame_width = 1,

.progress_bar = true,
};

struct rule default_rules[] = {
Expand Down
43 changes: 40 additions & 3 deletions docs/dunst.pod
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,32 @@ the notification on the left border of the screen while a horizontal offset of

=back

=item B<progress_bar> (values: [true/false], default: true)

When an integer value is passed to dunst as a hint (see B<NOTIFY-SEND>), a
progress bar will be drawn at the bottom of the notification. This
behavior can be turned off by setting this setting to false.

=item B<progress_bar_height> (default: 10)

The height of the progress bar in pixel. This includes the frame. Make sure
this value is bigger than twice the frame width.

=item B<progress_bar_min_width> (default: 150)

The minimum width of the progress bar in pixels. The notification is rescaled
to fit the bar.

=item B<progress_bar_max_width> (default: 300)

The maximum width of the progress bar in pixels. The notification is resized
to fit the progress bar.

=item B<progress_bar_frame_width> (default: 1)

The frame width of the progress bar in pixels. This value should be smaller
than half of the progress bar height.

=item B<indicate_hidden> (values: [true/false], default: true)

If this is set to true, a notification indicating how many notifications are
Expand Down Expand Up @@ -561,8 +587,8 @@ Specifies the keyboard shortcut that opens the context menu.

The urgency sections work in a similar way to rules and can be used to specify
attributes for the different urgency levels of notifications (low, normal,
critical). Currently only the background, foreground, timeout, frame_color and
icon attributes can be modified.
critical). Currently only the background, foreground, hightlight, timeout,
frame_color and icon attributes can be modified.

The urgency sections are urgency_low, urgency_normal, urgency_critical for low,
normal and critical urgency respectively.
Expand Down Expand Up @@ -595,6 +621,12 @@ Defines the background color for low, normal and critical notifications respecti

See COLORS for the value format.

=item B<-lh/nh/ch color>

Defines the highlight color for low, normal and critical notifications respectively.

See COLORS for the value format.

=item B<-lfr/nfr/cfr color>

Defines the frame color for low, normal and critical notifications respectively.
Expand Down Expand Up @@ -725,7 +757,12 @@ The background color of the notification. See COLORS for possible values.

=item C<foreground>

The background color of the notification. See COLORS for possible values.
The foreground color of the notification. See COLORS for possible values.

=item C<highlight>

The highlight color of the notification. This color is used for coloring the
progress bar. See COLORS for possible values.

=item C<format>

Expand Down
19 changes: 18 additions & 1 deletion dunstrc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,24 @@
# The width can be negative. In this case the actual width is the
# screen width minus the width defined in within the geometry option.
geometry = "300x5-30+20"


# Turn on the progess bar
progress_bar = true

# Set the progress bar height. This includes the frame, so make sure
# it's at least twice as big as the frame width.
progress_bar_height = 10

# Set the frame width of the progress bar
progress_bar_frame_width = 1

# Set the minimum width for the progress bar
progress_bar_min_width = 150

# Set the maximum width for the progress bar
progress_bar_max_width = 300


# Show how many messages are currently hidden (because of geometry).
indicate_hidden = yes

Expand Down
73 changes: 66 additions & 7 deletions src/draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct colored_layout {
PangoLayout *l;
struct color fg;
struct color bg;
struct color highlight;
struct color frame;
char *text;
PangoAttrList *attr;
Expand Down Expand Up @@ -166,6 +167,11 @@ static bool have_dynamic_width(void)
return (settings.geometry.width_set && settings.geometry.w == 0);
}

static bool have_progress_bar(const struct notification *n)
{
return (n->progress >= 0 && settings.progress_bar == true);
}

static struct dimensions calculate_dimensions(GSList *layouts)
{
struct dimensions dim = { 0 };
Expand Down Expand Up @@ -237,6 +243,11 @@ static struct dimensions calculate_dimensions(GSList *layouts)
text_width = MAX(w, text_width);
}

if (have_progress_bar(cl->n)){
dim.h += settings.progress_bar_height + settings.padding;
dim.w = MAX(dim.w, settings.progress_bar_min_width);
}

dim.corner_radius = MIN(dim.corner_radius, h/2);
}

Expand Down Expand Up @@ -299,6 +310,7 @@ static struct colored_layout *layout_init_shared(cairo_t *c, const struct notifi

cl->fg = string_to_color(n->colors.fg);
cl->bg = string_to_color(n->colors.bg);
cl->highlight = string_to_color(n->colors.highlight);
cl->frame = string_to_color(n->colors.frame);

cl->n = n;
Expand Down Expand Up @@ -354,7 +366,13 @@ static struct colored_layout *layout_from_notification(cairo_t *c, struct notifi

pango_layout_get_pixel_size(cl->l, NULL, &(n->displayed_height));
if (cl->icon) n->displayed_height = MAX(cairo_image_surface_get_height(cl->icon), n->displayed_height);
n->displayed_height = MAX(settings.notification_height, n->displayed_height + settings.padding * 2);

n->displayed_height = n->displayed_height + settings.padding * 2;

// progress bar
if (have_progress_bar(n)) n->displayed_height += settings.progress_bar_height + settings.padding;
fwsmit marked this conversation as resolved.
Show resolved Hide resolved

n->displayed_height = MAX(settings.notification_height, n->displayed_height);

n->first_render = false;
return cl;
Expand Down Expand Up @@ -397,11 +415,16 @@ static int layout_get_height(struct colored_layout *cl)
{
int h;
int h_icon = 0;
int h_progress_bar = 0;
pango_layout_get_pixel_size(cl->l, NULL, &h);
if (cl->icon)
h_icon = cairo_image_surface_get_height(cl->icon);
if (have_progress_bar(cl->n)){
h_progress_bar = settings.progress_bar_height + settings.padding;
}

return MAX(h, h_icon);
int res = MAX(h, h_icon) + h_progress_bar;
return res;
}

/* Attempt to make internal radius more organic.
Expand Down Expand Up @@ -563,19 +586,23 @@ static cairo_surface_t *render_background(cairo_surface_t *srf,
static void render_content(cairo_t *c, struct colored_layout *cl, int width)
{
const int h = layout_get_height(cl);
int h_without_progress_bar = h;
if (have_progress_bar(cl->n)){
h_without_progress_bar -= settings.progress_bar_height + settings.padding;
}
int h_text;
pango_layout_get_pixel_size(cl->l, NULL, &h_text);

int text_x = settings.h_padding,
text_y = settings.padding + h / 2 - h_text / 2;
text_y = settings.padding + h_without_progress_bar / 2 - h_text / 2;

// text positioning
if (cl->icon) {
// vertical alignment
if (settings.vertical_alignment == VERTICAL_TOP) {
text_y = settings.padding;
} else if (settings.vertical_alignment == VERTICAL_BOTTOM) {
text_y = h + settings.padding - h_text;
text_y = h_without_progress_bar + settings.padding - h_text;
if (text_y < 0)
text_y = settings.padding;
} // else VERTICAL_CENTER
Expand All @@ -597,14 +624,14 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width)
unsigned int image_width = cairo_image_surface_get_width(cl->icon),
image_height = cairo_image_surface_get_height(cl->icon),
image_x = width - settings.h_padding - image_width,
image_y = settings.padding + h/2 - image_height/2;
image_y = settings.padding + h_without_progress_bar/2 - image_height/2;

// vertical alignment
if (settings.vertical_alignment == VERTICAL_TOP) {
image_y = settings.padding;
} else if (settings.vertical_alignment == VERTICAL_BOTTOM) {
image_y = h + settings.padding - image_height;
if (image_y < settings.padding || image_y > h)
image_y = h_without_progress_bar + settings.padding - image_height;
if (image_y < settings.padding || image_y > h_without_progress_bar)
image_y = settings.padding;
} // else VERTICAL_CENTER

Expand All @@ -618,6 +645,38 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width)
cairo_fill(c);
}

// progress bar positioning
if (have_progress_bar(cl->n)){
int progress = MIN(cl->n->progress, 100);
unsigned int frame_width = settings.progress_bar_frame_width,
progress_width = MIN(width - 2 * settings.h_padding, settings.progress_bar_max_width),
progress_height = settings.progress_bar_height - frame_width,
frame_x = settings.h_padding,
frame_y = settings.padding + h - settings.progress_bar_height,
progress_width_without_frame = progress_width - 2 * frame_width,
progress_width_1 = progress_width_without_frame * progress / 100,
progress_width_2 = progress_width_without_frame - progress_width_1,
x_bar_1 = frame_x + frame_width,
x_bar_2 = x_bar_1 + progress_width_1;

double half_frame_width = frame_width / 2.0;

// draw progress bar
// Note: the bar could be drawn a bit smaller, because the frame is drawn on top
// left side
cairo_set_source_rgba(c, cl->highlight.r, cl->highlight.g, cl->highlight.b, cl->highlight.a);
cairo_rectangle(c, x_bar_1, frame_y, progress_width_1, progress_height);
cairo_fill(c);
// right side
cairo_set_source_rgba(c, cl->bg.r, cl->bg.g, cl->bg.b, cl->bg.a);
cairo_rectangle(c, x_bar_2, frame_y, progress_width_2, progress_height);
cairo_fill(c);
// border
cairo_set_source_rgba(c, cl->frame.r, cl->frame.g, cl->frame.b, cl->frame.a);
cairo_rectangle(c, frame_x + half_frame_width, frame_y + half_frame_width, progress_width - frame_width, progress_height);
cairo_set_line_width(c, frame_width);
cairo_stroke(c);
}
}

static struct dimensions layout_render(cairo_surface_t *srf,
Expand Down
4 changes: 4 additions & 0 deletions src/notification.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void notification_print(const struct notification *n)
printf("\tformatted: '%s'\n", n->msg);
printf("\tfg: %s\n", n->colors.fg);
printf("\tbg: %s\n", n->colors.bg);
printf("\thighlight: %s\n", n->colors.highlight);
printf("\tframe: %s\n", n->colors.frame);
printf("\tfullscreen: %s\n", enum_to_string_fullscreen(n->fullscreen));
printf("\tprogress: %d\n", n->progress);
Expand Down Expand Up @@ -236,6 +237,7 @@ void notification_unref(struct notification *n)
g_free(n->urls);
g_free(n->colors.fg);
g_free(n->colors.bg);
g_free(n->colors.highlight);
g_free(n->colors.frame);
g_free(n->stack_tag);
g_free(n->desktop_entry);
Expand Down Expand Up @@ -393,6 +395,8 @@ void notification_init(struct notification *n)
n->colors.fg = g_strdup(defcolors.fg);
if (!n->colors.bg)
n->colors.bg = g_strdup(defcolors.bg);
if (!n->colors.highlight)
n->colors.highlight = g_strdup(defcolors.highlight);
if (!n->colors.frame)
n->colors.frame = g_strdup(defcolors.frame);

Expand Down
1 change: 1 addition & 0 deletions src/notification.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct notification_colors {
char *frame;
char *bg;
char *fg;
char *highlight;
};

struct notification {
Expand Down
4 changes: 4 additions & 0 deletions src/rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ void rule_apply(struct rule *r, struct notification *n)
g_free(n->colors.bg);
n->colors.bg = g_strdup(r->bg);
}
if (r->highlight) {
g_free(n->colors.highlight);
n->colors.highlight = g_strdup(r->highlight);
}
if (r->fc) {
g_free(n->colors.frame);
n->colors.frame = g_strdup(r->fc);
Expand Down
1 change: 1 addition & 0 deletions src/rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct rule {
char *new_icon;
char *fg;
char *bg;
char *highlight;
char *fc;
const char *format;
const char *script;
Expand Down
Loading