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 on-long-touch option #534

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
21 changes: 21 additions & 0 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ void init_default_style(struct mako_style *style) {
style->button_bindings.right.action = MAKO_BINDING_DISMISS;
style->button_bindings.middle.action = MAKO_BINDING_NONE;
style->touch_binding.action = MAKO_BINDING_DISMISS;
style->long_touch_binding.action = MAKO_BINDING_INVOKE_ACTION;
style->long_touch_binding.action_name = strdup(DEFAULT_ACTION_KEY);
style->long_press_duration = 500;

// Everything in the default config is explicitly specified.
memset(&style->spec, true, sizeof(struct mako_style_spec));
Expand All @@ -148,6 +151,7 @@ void finish_style(struct mako_style *style) {
finish_binding(&style->button_bindings.middle);
finish_binding(&style->button_bindings.right);
finish_binding(&style->touch_binding);
finish_binding(&style->long_touch_binding);
finish_binding(&style->notify_binding);
free(style->icon_path);
free(style->font);
Expand Down Expand Up @@ -385,6 +389,16 @@ bool apply_style(struct mako_style *target, const struct mako_style *style) {
target->spec.touch_binding = true;
}

if (style->spec.long_touch_binding) {
copy_binding(&target->long_touch_binding, &style->long_touch_binding);
target->spec.long_touch_binding = true;
}

if (style->spec.long_press_duration) {
target->long_press_duration = style->long_press_duration;
target->spec.long_press_duration = true;
}

if (style->spec.notify_binding) {
copy_binding(&target->notify_binding, &style->notify_binding);
target->spec.notify_binding = true;
Expand Down Expand Up @@ -660,6 +674,8 @@ static bool apply_style_option(struct mako_style *style, const char *name,
return true;
} else if (strcmp(name, "anchor") == 0) {
return spec->anchor = parse_anchor(value, &style->anchor);
} else if (strcmp(name, "long-press-duration") == 0) {
return spec->long_press_duration = parse_int_ge(value, &style->long_press_duration, 0);
} else if (has_prefix(name, "on-")) {
struct mako_binding binding = {0};
if (strcmp(value, "none") == 0) {
Expand Down Expand Up @@ -697,6 +713,9 @@ static bool apply_style_option(struct mako_style *style, const char *name,
} else if (strcmp(name, "on-touch") == 0) {
copy_binding(&style->touch_binding, &binding);
style->spec.touch_binding = true;
} else if (strcmp(name, "on-long-touch") == 0) {
copy_binding(&style->long_touch_binding, &binding);
style->spec.long_touch_binding = true;
} else if (strcmp(name, "on-notify") == 0) {
copy_binding(&style->notify_binding, &binding);
style->spec.notify_binding = true;
Expand Down Expand Up @@ -886,6 +905,8 @@ int parse_config_arguments(struct mako_config *config, int argc, char **argv) {
{"on-button-right", required_argument, 0, 0},
{"on-button-middle", required_argument, 0, 0},
{"on-touch", required_argument, 0, 0},
{"on-long-touch", required_argument, 0, 0},
{"long-press-duration", required_argument, 0, 0},
{0},
};

Expand Down
15 changes: 14 additions & 1 deletion doc/mako.5.scd
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,23 @@ Supported options:
Default: dismiss

*on-touch*=_action_
Performs the action when tapped via a touch device.
Performs the action when tapped via a touch device if the tap
duration is less than *long-press-duration*.

Default: dismiss

*on-long-touch*=_action_
Performs the action when tapped via a touch device if the press
duration is greater or equal to *long-press-duration*.

Default: invoke-default-action

*long-press-duration*=_time_
Specifies the cutoff time (in milliseconds) for a press to be
considered a long press.

Default: 500

*on-notify*=_action_
Performs the action when the notification is opened.

Expand Down
7 changes: 4 additions & 3 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ struct mako_style_spec {
bool width, height, outer_margin, margin, padding, border_size, border_radius, font,
markup, format, text_alignment, actions, default_timeout, ignore_timeout,
icons, max_icon_size, icon_path, group_criteria_spec, invisible, history,
icon_location, max_visible, layer, output, anchor;
icon_location, max_visible, layer, output, anchor, long_press_duration;
struct {
bool background, text, border, progress;
} colors;
struct {
bool left, right, middle;
} button_bindings;
bool touch_binding, notify_binding;
bool touch_binding, long_touch_binding, notify_binding;
};


Expand Down Expand Up @@ -98,7 +98,8 @@ struct mako_style {
struct {
struct mako_binding left, right, middle;
} button_bindings;
struct mako_binding touch_binding, notify_binding;
struct mako_binding touch_binding, long_touch_binding, notify_binding;
int32_t long_press_duration;
};

struct mako_config {
Expand Down
18 changes: 11 additions & 7 deletions include/notification.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ struct mako_hotspot {
int32_t width, height;
};

struct mako_binding_context {
struct mako_surface *surface;
struct mako_seat *seat;
uint32_t serial;
};

struct mako_notification {
struct mako_state *state;
struct mako_surface *surface;
Expand All @@ -38,6 +44,8 @@ struct mako_notification {
char *body;
int32_t requested_timeout;
struct wl_list actions; // mako_action::link
struct mako_timer *long_press_timer;
struct mako_binding_context long_press_ctx;

enum mako_notification_urgency urgency;
char *category;
Expand Down Expand Up @@ -70,12 +78,6 @@ struct mako_hidden_format_data {
size_t count;
};

struct mako_binding_context {
struct mako_surface *surface;
struct mako_seat *seat;
uint32_t serial;
};

typedef char *(*mako_format_func_t)(char variable, bool *markup, void *data);

bool hotspot_at(struct mako_hotspot *hotspot, int32_t x, int32_t y);
Expand All @@ -100,8 +102,10 @@ 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_touch(struct mako_notification *notif,
void notification_handle_touch_start(struct mako_notification *notif,
const struct mako_binding_context *ctx);
void notification_handle_touch(struct mako_notification *notif,
const struct mako_binding_context *ctx, int32_t duration_ms);
void notification_execute_binding(struct mako_notification *notif,
const struct mako_binding *binding, const struct mako_binding_context *ctx);
void insert_notification(struct mako_state *state, struct mako_notification *notif);
Expand Down
2 changes: 2 additions & 0 deletions include/wayland.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <stdbool.h>
#include <wayland-client-protocol.h>
#include "mako.h"

#define MAX_TOUCHPOINTS 10

Expand Down Expand Up @@ -35,6 +36,7 @@ struct mako_seat {
struct wl_touch *wl_touch;
struct {
int32_t x, y;
uint32_t time;
struct mako_surface *surface;
} pts[MAX_TOUCHPOINTS];
} touch;
Expand Down
28 changes: 27 additions & 1 deletion notification.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ void reset_notification(struct mako_notification *notif) {

destroy_timer(notif->timer);
notif->timer = NULL;
destroy_timer(notif->long_press_timer);
notif->long_press_timer = NULL;

free(notif->app_name);
free(notif->app_icon);
Expand Down Expand Up @@ -446,8 +448,32 @@ void notification_handle_button(struct mako_notification *notif, uint32_t button
}

void notification_handle_touch(struct mako_notification *notif,
const struct mako_binding_context *ctx, int32_t duration_ms) {
destroy_timer(notif->long_press_timer);
notif->long_press_timer = NULL;
if (duration_ms >= notif->style.long_press_duration) {
notification_execute_binding(notif, &notif->style.long_touch_binding, ctx);
} else {
notification_execute_binding(notif, &notif->style.touch_binding, ctx);
}
}

void handle_notification_touch_timer(void *data) {
struct mako_notification *notif = data;
notif->long_press_timer = NULL;
struct mako_binding_context ctx = notif->long_press_ctx;
notification_execute_binding(notif, &notif->style.long_touch_binding, &ctx);
set_dirty(ctx.surface);
}

void notification_handle_touch_start(struct mako_notification *notif,
const struct mako_binding_context *ctx) {
notification_execute_binding(notif, &notif->style.touch_binding, ctx);
if (notif->long_press_timer) {
return;
}
notif->long_press_ctx = *ctx;
notif->long_press_timer = add_event_loop_timer(&notif->state->event_loop, 500,
handle_notification_touch_timer, notif);
}

/*
Expand Down
18 changes: 16 additions & 2 deletions wayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,23 @@ static void touch_handle_down(void *data, struct wl_touch *wl_touch,
if (id >= MAX_TOUCHPOINTS) {
return;
}
struct mako_state *state = seat->state;
seat->touch.pts[id].x = wl_fixed_to_int(surface_x);
seat->touch.pts[id].y = wl_fixed_to_int(surface_y);
seat->touch.pts[id].surface = get_surface(seat->state, wl_surface);
seat->touch.pts[id].time = time;
seat->touch.pts[id].surface = get_surface(state, wl_surface);

struct mako_notification *notif;
const struct mako_binding_context ctx = {
.surface = seat->touch.pts[id].surface,
.seat = seat,
.serial = serial,
};
wl_list_for_each(notif, &state->notifications, link) {
if (hotspot_at(&notif->hotspot, seat->touch.pts[id].x, seat->touch.pts[id].y)) {
notification_handle_touch_start(notif, &ctx);
}
}
}

static void touch_handle_up(void *data, struct wl_touch *wl_touch,
Expand All @@ -144,7 +158,7 @@ static void touch_handle_up(void *data, struct wl_touch *wl_touch,
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);
notification_handle_touch(notif, &ctx, time - seat->touch.pts[id].time);
set_dirty(surface);
break;
}
Expand Down