Skip to content
Open
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
3 changes: 3 additions & 0 deletions include/notification.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct mako_notification {
uint32_t id;
int group_index;
int group_count;
int group_focus_index;
bool hidden;

char *app_name;
Expand Down Expand Up @@ -100,6 +101,8 @@ size_t format_notification(struct mako_notification *notif, const char *format,
char *buf);
void notification_handle_button(struct mako_notification *notif, uint32_t button,
enum wl_pointer_button_state state, const struct mako_binding_context *ctx);
void notification_handle_axis(struct mako_notification *notif, uint32_t axis,
wl_fixed_t value, const struct mako_binding_context *ctx);
void notification_handle_touch(struct mako_notification *notif,
const struct mako_binding_context *ctx);
void notification_execute_binding(struct mako_notification *notif,
Expand Down
52 changes: 49 additions & 3 deletions notification.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ struct mako_notification *create_notification(struct mako_state *state) {

// Start ungrouped.
notif->group_index = -1;
notif->group_focus_index = 0;

return notif;
}
Expand All @@ -111,12 +112,24 @@ void close_notification(struct mako_notification *notif,
bool add_to_history) {
struct mako_state *state = notif->state;

// If last member of a group, decrease the focus
struct mako_criteria *notif_criteria = create_criteria_from_notification(
notif, &notif->style.group_criteria_spec);
if (notif_criteria) {
if (notif->group_index == notif->group_count - 1) {
struct mako_notification *iter;
wl_list_for_each(iter, &notif->state->notifications, link) {
if (match_criteria(notif_criteria, iter)) {
iter->group_focus_index--;
}
}
}
}

notify_notification_closed(notif, reason);
wl_list_remove(&notif->link); // Remove so regrouping works...
wl_list_init(&notif->link); // ...but destroy will remove again.

struct mako_criteria *notif_criteria = create_criteria_from_notification(
notif, &notif->style.group_criteria_spec);
if (notif_criteria) {
group_notifications(state, notif_criteria);
destroy_criteria(notif_criteria);
Expand Down Expand Up @@ -282,7 +295,7 @@ char *format_notif_text(char variable, bool *markup, void *data) {
*markup = notif->style.markup;
return strdup(notif->body);
case 'g':
return mako_asprintf("%d", notif->group_count);
return mako_asprintf("%d/%d", notif->group_index + 1, notif->group_count);
}
return NULL;
}
Expand Down Expand Up @@ -450,6 +463,36 @@ void notification_handle_button(struct mako_notification *notif, uint32_t button
}
}

void notification_handle_axis(struct mako_notification *notif, uint32_t axis, wl_fixed_t value, const struct mako_binding_context *ctx) {
// If notification is not part of a group, return
if (notif->group_index == -1)
return;

// Create criteria to find other group members
struct mako_criteria *criteria = create_criteria_from_notification(notif, &notif->style.group_criteria_spec);
if (!criteria)
return;

if (value < 0 && notif->group_focus_index > 0) {
// On scroll up
struct mako_notification *iter;
wl_list_for_each(iter, &notif->state->notifications, link) {
if (match_criteria(criteria, iter)) {
iter->group_focus_index--;
}
}
} else if (value > 0 && notif->group_focus_index < notif->group_count - 1) {
// On scroll down
struct mako_notification *iter;
wl_list_for_each(iter, &notif->state->notifications, link) {
if (match_criteria(criteria, iter)) {
iter->group_focus_index++;
}
}
}
destroy_criteria(criteria);
}

void notification_handle_touch(struct mako_notification *notif,
const struct mako_binding_context *ctx) {
notification_execute_binding(notif, &notif->style.touch_binding, ctx);
Expand Down Expand Up @@ -523,6 +566,7 @@ int group_notifications(struct mako_state *state, struct mako_criteria *criteria
// is technically unnecessary, since it will go back in the same place, but
// it makes the rest of this logic nicer.
struct wl_list *location = NULL; // The place we're going to reinsert them.
int group_visible = 0;
struct mako_notification *notif = NULL, *tmp = NULL;
size_t count = 0;
wl_list_for_each_safe(notif, tmp, &state->notifications, link) {
Expand All @@ -532,6 +576,7 @@ int group_notifications(struct mako_state *state, struct mako_criteria *criteria

if (!location) {
location = notif->link.prev;
group_visible = notif->group_focus_index;
}

wl_list_remove(&notif->link);
Expand Down Expand Up @@ -564,6 +609,7 @@ int group_notifications(struct mako_state *state, struct mako_criteria *criteria
// anymore.
wl_list_for_each(notif, &matches, link) {
notif->group_count = count;
notif->group_focus_index = group_visible;
}

// Place all of the matches back into the list where the first one was
Expand Down
6 changes: 5 additions & 1 deletion render.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,11 @@ void render(struct mako_surface *surface, struct pool_buffer *buffer, int scale,
continue;
}

if (style->invisible) {
if (style->invisible && notif->group_index != notif->group_focus_index) {
continue;
}

if (notif->group_index > -1 && notif->group_index != notif->group_focus_index) {
continue;
}

Expand Down
44 changes: 35 additions & 9 deletions wayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,12 @@ static void touch_handle_up(void *data, struct wl_touch *wl_touch,
struct mako_notification *notif;
wl_list_for_each(notif, &state->notifications, link) {
if (hotspot_at(&notif->hotspot, seat->touch.pts[id].x, seat->touch.pts[id].y)) {
struct mako_surface *surface = notif->surface;
notification_handle_touch(notif, &ctx);
set_dirty(surface);
break;
if (notif->group_index == -1 || notif->group_index == notif->group_focus_index) {
struct mako_surface *surface = notif->surface;
notification_handle_touch(notif, &ctx);
set_dirty(surface);
break;
}
}
}

Expand Down Expand Up @@ -259,10 +261,34 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
struct mako_notification *notif;
wl_list_for_each(notif, &state->notifications, link) {
if (hotspot_at(&notif->hotspot, seat->pointer.x, seat->pointer.y)) {
struct mako_surface *surface = notif->surface;
notification_handle_button(notif, button, button_state, &ctx);
set_dirty(surface);
break;
if (notif->group_index == -1 || notif->group_index == notif->group_focus_index) {
struct mako_surface *surface = notif->surface;
notification_handle_button(notif, button, button_state, &ctx);
set_dirty(surface);
break;
}
}
}
}

static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {
struct mako_seat *seat = data;
struct mako_state *state = seat->state;

const struct mako_binding_context ctx = {
.surface = seat->pointer.surface,
.seat = seat,
};

struct mako_notification *notif;
wl_list_for_each(notif, &state->notifications, link) {
if (hotspot_at(&notif->hotspot, seat->pointer.x, seat->pointer.y)) {
if (notif->group_index == -1 || notif->group_index == notif->group_focus_index) {
struct mako_surface *surface = notif->surface;
notification_handle_axis(notif, axis, value, &ctx);
set_dirty(surface);
break;
}
}
}
}
Expand All @@ -272,7 +298,7 @@ static const struct wl_pointer_listener pointer_listener = {
.leave = pointer_handle_leave,
.motion = pointer_handle_motion,
.button = pointer_handle_button,
.axis = noop,
.axis = pointer_handle_axis,
};

static const struct wl_touch_listener touch_listener = {
Expand Down