Hello community,

here is the log from the commit of package mako for openSUSE:Factory checked in 
at 2019-07-22 12:21:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mako (Old)
 and      /work/SRC/openSUSE:Factory/.mako.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mako"

Mon Jul 22 12:21:37 2019 rev:3 rq:717447 version:1.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/mako/mako.changes        2019-04-23 
14:37:14.301519484 +0200
+++ /work/SRC/openSUSE:Factory/.mako.new.4126/mako.changes      2019-07-22 
12:21:39.639644369 +0200
@@ -1,0 +2,11 @@
+Sat Jul 20 17:41:42 UTC 2019 - Michael Aquilina <michaelaquil...@gmail.com>
+
+- Update to 1.4
+  * Icon support is now complete
+  * Touchscreens are now supported
+  * makoctl can now list current notifications
+  * makoctl can now list and invoke notification actions
+  * A D-Bus service file has been added
+  * Various bug fixes
+
+-------------------------------------------------------------------

Old:
----
  v1.3.tar.gz

New:
----
  v1.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mako.spec ++++++
--- /var/tmp/diff_new_pack.Oen5Wd/_old  2019-07-22 12:21:40.211644220 +0200
+++ /var/tmp/diff_new_pack.Oen5Wd/_new  2019-07-22 12:21:40.215644218 +0200
@@ -12,12 +12,12 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           mako
-Version:        1.3
+Version:        1.4
 Release:        0
 Summary:        A Wayland notification daemon
 License:        MIT
@@ -50,6 +50,9 @@
 %files
 %license LICENSE
 %doc README.md
+%dir %{_datadir}/dbus-1/
+%dir %{_datadir}/dbus-1/services/
+%{_datadir}/dbus-1/services/fr.emersion.mako.service
 %{_bindir}/%{name}*
 %{_mandir}/man?/%{name}*
 

++++++ v1.3.tar.gz -> v1.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/README.md new/mako-1.4/README.md
--- old/mako-1.3/README.md      2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/README.md      2019-07-19 12:57:01.000000000 +0200
@@ -6,6 +6,8 @@
   <img src="https://sr.ht/meoc.png"; alt="mako screenshot">
 </p>
 
+Feel free to join the IRC channel: ##emersion on irc.freenode.net.
+
 ## Running
 
 If you're using Sway you can start mako on launch by putting `exec mako` in
@@ -23,7 +25,8 @@
 * pango
 * cairo
 * systemd or elogind (for the sd-bus library)
-* dbus (with user-session support)
+* gdk-pixbuf (optional, for icons support)
+* dbus (runtime dependency, user-session support is required)
 
 Then run:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/config.c new/mako-1.4/config.c
--- old/mako-1.3/config.c       2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/config.c       2019-07-19 12:57:01.000000000 +0200
@@ -58,9 +58,10 @@
        config->sort_criteria = MAKO_SORT_CRITERIA_TIME;
        config->sort_asc = 0;
 
-       config->button_bindings.left = 
MAKO_BUTTON_BINDING_INVOKE_DEFAULT_ACTION;
-       config->button_bindings.right = MAKO_BUTTON_BINDING_DISMISS;
-       config->button_bindings.middle = MAKO_BUTTON_BINDING_NONE;
+       config->button_bindings.left = MAKO_BINDING_INVOKE_DEFAULT_ACTION;
+       config->button_bindings.right = MAKO_BINDING_DISMISS;
+       config->button_bindings.middle = MAKO_BINDING_NONE;
+       config->touch = MAKO_BINDING_DISMISS;
 
        config->anchor =
                ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | 
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/criteria.c new/mako-1.4/criteria.c
--- old/mako-1.3/criteria.c     2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/criteria.c     2019-07-19 12:57:01.000000000 +0200
@@ -262,8 +262,13 @@
                        }
                        criteria->spec.group_index = true;
                        return true;
+               } else if (strcmp(key, "summary") == 0) {
+                       // TODO: convert to regex, currently only exact matching
+                       criteria->summary = strdup(value);
+                       criteria->spec.summary = true;
+                       return true;
                } else {
-                       // TODO: summary + body, once we support regex and 
they're useful.
+                       // TODO: body, once we support regex and they're useful.
                        // Anything left must be one of the boolean fields, 
defined using
                        // standard syntax. Continue on.
                }
@@ -305,7 +310,7 @@
        assert(false && "Criteria parser fell through");
 }
 
-// Retreive the global critiera from a given mako_config. This just so happens
+// Retreive the global criteria from a given mako_config. This just so happens
 // to be the first criteria in the list.
 struct mako_criteria *global_criteria(struct mako_config *config) {
        struct mako_criteria *criteria =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/dbus/dbus.c new/mako-1.4/dbus/dbus.c
--- old/mako-1.3/dbus/dbus.c    2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/dbus/dbus.c    2019-07-19 12:57:01.000000000 +0200
@@ -32,6 +32,9 @@
        ret = sd_bus_request_name(state->bus, service_name, 0);
        if (ret < 0) {
                fprintf(stderr, "Failed to acquire service name: %s\n", 
strerror(-ret));
+               if (ret == -EEXIST) {
+                       fprintf(stderr, "Is a notification daemon already 
running?\n");
+               }
                goto error;
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/dbus/mako.c new/mako-1.4/dbus/mako.c
--- old/mako-1.3/dbus/mako.c    2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/dbus/mako.c    2019-07-19 12:57:01.000000000 +0200
@@ -45,22 +45,31 @@
                sd_bus_error *ret_error) {
        struct mako_state *state = data;
 
+       uint32_t id = 0;
        const char *action_key;
-       int ret = sd_bus_message_read(msg, "s", &action_key);
+       int ret = sd_bus_message_read(msg, "us", &id, &action_key);
        if (ret < 0) {
                return ret;
        }
 
+       if (id == 0) {
+               id = state->last_id;
+       }
+
        if (wl_list_empty(&state->notifications)) {
                goto done;
        }
 
-       struct mako_notification *notif =
-               wl_container_of(state->notifications.next, notif, link);
-       struct mako_action *action;
-       wl_list_for_each(action, &notif->actions, link) {
-               if (strcmp(action->key, action_key) == 0) {
-                       notify_action_invoked(action);
+       struct mako_notification *notif;
+       wl_list_for_each(notif, &state->notifications, link) {
+               if (notif->id == id) {
+                       struct mako_action *action;
+                       wl_list_for_each(action, &notif->actions, link) {
+                               if (strcmp(action->key, action_key) == 0) {
+                                       notify_action_invoked(action);
+                                       break;
+                               }
+                       }
                        break;
                }
        }
@@ -69,6 +78,121 @@
        return sd_bus_reply_method_return(msg, "");
 }
 
+static int handle_list_notifications(sd_bus_message *msg, void *data,
+               sd_bus_error *ret_error) {
+       struct mako_state *state = data;
+
+       sd_bus_message *reply = NULL;
+       int ret = sd_bus_message_new_method_return(msg, &reply);
+       if (ret < 0) {
+               return ret;
+       }
+
+       ret = sd_bus_message_open_container(reply, 'a', "a{sv}");
+       if (ret < 0) {
+               return ret;
+       }
+
+       struct mako_notification *notif;
+       wl_list_for_each(notif, &state->notifications, link) {
+               ret = sd_bus_message_open_container(reply, 'a', "{sv}");
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_append(reply, "{sv}", "app-name",
+                       "s", notif->app_name);
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_append(reply, "{sv}", "app-icon",
+                       "s", notif->app_icon);
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_append(reply, "{sv}", "summary",
+                       "s", notif->summary);
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_append(reply, "{sv}", "body",
+                       "s", notif->body);
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_append(reply, "{sv}", "id",
+                       "u", notif->id);
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_open_container(reply, 'e', "sv");
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_append_basic(reply, 's', "actions");
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_open_container(reply, 'v', "a{ss}");
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_open_container(reply, 'a', "{ss}");
+               if (ret < 0) {
+                       return ret;
+               }
+
+               struct mako_action *action;
+               wl_list_for_each(action, &notif->actions, link) {
+                       ret = sd_bus_message_append(reply, "{ss}", action->key, 
action->title);
+                       if (ret < 0) {
+                               return ret;
+                       }
+               }
+
+               ret = sd_bus_message_close_container(reply);
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_close_container(reply);
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_close_container(reply);
+               if (ret < 0) {
+                       return ret;
+               }
+
+               ret = sd_bus_message_close_container(reply);
+               if (ret < 0) {
+                       return ret;
+               }
+       }
+
+       ret = sd_bus_message_close_container(reply);
+       if (ret < 0) {
+               return ret;
+       }
+
+       ret = sd_bus_send(NULL, reply, NULL);
+       if (ret < 0) {
+               return ret;
+       }
+
+       sd_bus_message_unref(reply);
+       return 0;
+}
+
 static int handle_reload(sd_bus_message *msg, void *data,
                sd_bus_error *ret_error) {
        struct mako_state *state = data;
@@ -110,7 +234,8 @@
        SD_BUS_VTABLE_START(0),
        SD_BUS_METHOD("DismissAllNotifications", "", "", 
handle_dismiss_all_notifications, SD_BUS_VTABLE_UNPRIVILEGED),
        SD_BUS_METHOD("DismissLastNotification", "", "", 
handle_dismiss_last_notification, SD_BUS_VTABLE_UNPRIVILEGED),
-       SD_BUS_METHOD("InvokeAction", "s", "", handle_invoke_action, 
SD_BUS_VTABLE_UNPRIVILEGED),
+       SD_BUS_METHOD("InvokeAction", "us", "", handle_invoke_action, 
SD_BUS_VTABLE_UNPRIVILEGED),
+       SD_BUS_METHOD("ListNotifications", "", "aa{sv}", 
handle_list_notifications, SD_BUS_VTABLE_UNPRIVILEGED),
        SD_BUS_METHOD("Reload", "", "", handle_reload, 
SD_BUS_VTABLE_UNPRIVILEGED),
        SD_BUS_VTABLE_END
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/dbus/xdg.c new/mako-1.4/dbus/xdg.c
--- old/mako-1.3/dbus/xdg.c     2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/dbus/xdg.c     2019-07-19 12:57:01.000000000 +0200
@@ -217,6 +217,83 @@
                                return ret;
                        }
                        notif->progress = progress;
+               } else if (strcmp(hint, "image-data") == 0 || strcmp(hint, 
"icon_data") == 0) {
+                       ret = sd_bus_message_enter_container(msg, 'v', 
"(iiibiiay)");
+                       if (ret < 0) {
+                               return ret;
+                       }
+
+                       ret = sd_bus_message_enter_container(msg, 'r', 
"iiibiiay");
+                       if (ret < 0) {
+                               return ret;
+                       }
+
+                       struct mako_image_data *image_data = calloc(1, 
sizeof(struct mako_image_data));
+                       if (image_data == NULL) {
+                               return -1;
+                       }
+
+                       ret = sd_bus_message_read(msg, "iiibii", 
&image_data->width,
+                                       &image_data->height, 
&image_data->rowstride,
+                                       &image_data->has_alpha, 
&image_data->bits_per_sample,
+                                       &image_data->channels);
+                       if (ret < 0) {
+                               free(image_data);
+                               return ret;
+                       }
+
+                       // Calculate the expected useful data length without 
padding in last row
+                       // len = size before last row + size of last row
+                       //     = (height - 1) * rowstride + width * 
ceil(channels * bits_pre_sample / 8.0)
+                       size_t image_len = (image_data->height - 1) * 
image_data->rowstride +
+                               image_data->width * ((image_data->channels *
+                               image_data->bits_per_sample + 7) / 8);
+                       uint8_t *data = calloc(image_len, sizeof(uint8_t));
+                       if (data == NULL) {
+                               free(image_data);
+                               return -1;
+                       }
+
+                       ret = sd_bus_message_enter_container(msg, 'a', "y");
+                       if (ret < 0) {
+                               free(data);
+                               free(image_data);
+                               return ret;
+                       }
+
+                       // Ignore the extra padding bytes in the last row if 
exist
+                       for (size_t index = 0; index < image_len; index++) {
+                               uint8_t tmp;
+                               ret = sd_bus_message_read(msg, "y", &tmp);
+                               if (ret < 0){
+                                       free(data);
+                                       free(image_data);
+                                       return ret;
+                               }
+                               data[index] = tmp;
+                       }
+
+                       image_data->data = data;
+                       if (notif->image_data != NULL) {
+                               free(notif->image_data->data);
+                               free(notif->image_data);
+                       }
+                       notif->image_data = image_data;
+
+                       ret = sd_bus_message_exit_container(msg);
+                       if (ret < 0) {
+                               return ret;
+                       }
+
+                       ret = sd_bus_message_exit_container(msg);
+                       if (ret < 0) {
+                               return ret;
+                       }
+
+                       ret = sd_bus_message_exit_container(msg);
+                       if (ret < 0) {
+                               return ret;
+                       }
                } else {
                        ret = sd_bus_message_skip(msg, "v");
                        if (ret < 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/fr.emersion.mako.service.in 
new/mako-1.4/fr.emersion.mako.service.in
--- old/mako-1.3/fr.emersion.mako.service.in    1970-01-01 01:00:00.000000000 
+0100
+++ new/mako-1.4/fr.emersion.mako.service.in    2019-07-19 12:57:01.000000000 
+0200
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.freedesktop.Notifications
+Exec=@bindir@/mako
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/icon.c new/mako-1.4/icon.c
--- old/mako-1.3/icon.c 2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/icon.c 2019-07-19 12:57:01.000000000 +0200
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <ctype.h>
 #include <cairo/cairo.h>
 
 #include "mako.h"
@@ -33,11 +34,46 @@
        return pixbuf;
 }
 
+static GdkPixbuf *load_image_data(struct mako_image_data *image_data) {
+       GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(image_data->data, 
GDK_COLORSPACE_RGB,
+                       image_data->has_alpha, image_data->bits_per_sample, 
image_data->width,
+                       image_data->height, image_data->rowstride, NULL, NULL);
+       if (!pixbuf) {
+               fprintf(stderr, "Failed to load icon\n");
+               return NULL;
+       }
+       return pixbuf;
+}
+
 static double fit_to_square(int width, int height, int square_size) {
        double longest = width > height ? width : height;
        return longest > square_size ? square_size/longest : 1.0;
 }
 
+static char hex_val(char digit) {
+       assert(isxdigit(digit));
+       if (digit >= 'a') {
+               return digit - 'a' + 10;
+       } else if (digit >= 'A') {
+               return digit - 'A' + 10;
+       } else {
+               return digit - '0';
+       }
+}
+
+static void url_decode(char *dst, const char *src) {
+       while (src[0]) {
+               if (src[0] == '%' && isxdigit(src[1]) && isxdigit(src[2])) {
+                       dst[0] = 16*hex_val(src[1]) + hex_val(src[2]);
+                       dst++; src += 3;
+               } else {
+                       dst[0] = src[0];
+                       dst++; src++;
+               }
+       }
+       dst[0] = '\0';
+}
+
 // Attempt to find a full path for a notification's icon_name, which may be:
 // - An absolute path, which will simply be returned (as a new string)
 // - A file:// URI, which will be converted to an absolute path
@@ -56,8 +92,14 @@
                return strdup(icon_name);
        }
        if (strstr(icon_name, "file://") == icon_name) {
-               // Just chop off the scheme.
-               return strdup(icon_name + strlen("file://"));
+               // Chop off the scheme and URL decode
+               char *icon_path = malloc(strlen(icon_name) + 1 - 
strlen("file://"));
+               if (icon_path == NULL) {
+                       return icon_path;
+               }
+
+               url_decode(icon_path, icon_name + strlen("file://"));
+               return icon_path;
        }
 
        // Determine the largest scale factor of any attached output.
@@ -184,16 +226,24 @@
 }
 
 struct mako_icon *create_icon(struct mako_notification *notif) {
-       char *path = resolve_icon(notif);
-       if (path == NULL) {
-               return NULL;
+       GdkPixbuf *image = NULL;
+       if (notif->image_data != NULL) {
+               image = load_image_data(notif->image_data);
        }
 
-       GdkPixbuf *image = load_image(path);
-       free(path);
        if (image == NULL) {
-               return NULL;
+               char *path = resolve_icon(notif);
+               if (path == NULL) {
+                       return NULL;
+               }
+
+               image = load_image(path);
+               free(path);
+               if (image == NULL) {
+                       return NULL;
+               }
        }
+
        int image_width = gdk_pixbuf_get_width(image);
        int image_height = gdk_pixbuf_get_height(image);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/include/config.h 
new/mako-1.4/include/config.h
--- old/mako-1.3/include/config.h       2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/include/config.h       2019-07-19 12:57:01.000000000 +0200
@@ -7,11 +7,11 @@
 #include "types.h"
 #include "wlr-layer-shell-unstable-v1-client-protocol.h"
 
-enum mako_button_binding {
-       MAKO_BUTTON_BINDING_NONE,
-       MAKO_BUTTON_BINDING_DISMISS,
-       MAKO_BUTTON_BINDING_DISMISS_ALL,
-       MAKO_BUTTON_BINDING_INVOKE_DEFAULT_ACTION,
+enum mako_binding {
+       MAKO_BINDING_NONE,
+       MAKO_BINDING_DISMISS,
+       MAKO_BINDING_DISMISS_ALL,
+       MAKO_BINDING_INVOKE_DEFAULT_ACTION,
 };
 
 enum mako_sort_criteria {
@@ -81,8 +81,10 @@
        struct mako_style superstyle;
 
        struct {
-               enum mako_button_binding left, right, middle;
+               enum mako_binding left, right, middle;
        } button_bindings;
+
+       enum mako_binding touch;
 };
 
 void init_default_config(struct mako_config *config);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/include/icon.h new/mako-1.4/include/icon.h
--- old/mako-1.3/include/icon.h 2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/include/icon.h 2019-07-19 12:57:01.000000000 +0200
@@ -11,6 +11,16 @@
        cairo_surface_t *image;
 };
 
+struct mako_image_data {
+       int32_t width;
+       int32_t height;
+       int32_t rowstride;
+       uint32_t has_alpha;
+       int32_t bits_per_sample;
+       int32_t channels;
+       uint8_t *data;
+};
+
 struct mako_icon *create_icon(struct mako_notification *notif);
 void destroy_icon(struct mako_icon *icon);
 void draw_icon(cairo_t *cairo, struct mako_icon *icon,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/include/notification.h 
new/mako-1.4/include/notification.h
--- old/mako-1.3/include/notification.h 2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/include/notification.h 2019-07-19 12:57:01.000000000 +0200
@@ -40,6 +40,7 @@
        char *category;
        char *desktop_entry;
        int32_t progress;
+       struct mako_image_data *image_data;
 
        struct mako_hotspot hotspot;
        struct mako_timer *timer;
@@ -87,6 +88,9 @@
        char *buf);
 void notification_handle_button(struct mako_notification *notif, uint32_t 
button,
        enum wl_pointer_button_state state);
+void notification_handle_touch(struct mako_notification *notif);
+void notification_execute_binding(struct mako_notification *notif,
+       enum mako_binding binding);
 void insert_notification(struct mako_state *state, struct mako_notification 
*notif);
 int group_notifications(struct mako_state *state, struct mako_criteria 
*criteria);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/include/wayland.h 
new/mako-1.4/include/wayland.h
--- old/mako-1.3/include/wayland.h      2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/include/wayland.h      2019-07-19 12:57:01.000000000 +0200
@@ -27,6 +27,11 @@
                struct wl_pointer *wl_pointer;
                int32_t x, y;
        } pointer;
+
+       struct {
+               struct wl_touch *wl_touch;
+               int32_t x, y;
+       } touch;
 };
 
 bool init_wayland(struct mako_state *state);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/mako.1.scd new/mako-1.4/mako.1.scd
--- old/mako-1.3/mako.1.scd     2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/mako.1.scd     2019-07-19 12:57:01.000000000 +0200
@@ -114,7 +114,7 @@
 
 *--progress-color* [over|source] _color_
        Set popup progress indicator color to _color_. See *COLOR* for more
-       information. To draw the progess indicator on top of the background
+       information. To draw the progress indicator on top of the background
        color, use the *over* attribute. To replace the background color, use
        the *source* attribute (this can be useful when the notification is
        semi-transparent).
@@ -203,7 +203,9 @@
 
        key=value
 
-Is equivalent to passing *--key=value* to mako from the command line.
+Is equivalent to passing *--key=value* to mako from the command line. Note that
+any quotes used within your shell are unnecessary and also invalid in the
+config file.
 
 Empty lines and lines that begin with # are ignored.
 
@@ -224,10 +226,12 @@
 meaning that if multiple criteria match a notification, the last occurrence of
 any given style option will "win".
 
-The following fields are available in critiera:
+The following fields are available in criteria:
 
 - _app-name_ (string)
 - _app-icon_ (string)
+- _summary_ (string)
+       - An exact match on the summary of the notification.
 - _urgency_ (one of "low", "normal", "high")
 - _category_ (string)
 - _desktop-entry_ (string)
@@ -249,7 +253,7 @@
 
        \[app-name=Google\\ Chrome\]
 
-Quotes within quotes may also be escaped, and a literal backslack may be
+Quotes within quotes may also be escaped, and a literal backslash may be
 specified as \\\\. No spaces are allowed around the equal sign. Escaping equal
 signs within values is unnecessary.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/makoctl new/mako-1.4/makoctl
--- old/mako-1.3/makoctl        2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/makoctl        2019-07-19 12:57:01.000000000 +0200
@@ -1,30 +1,32 @@
-#!/bin/sh
-
-set -e
+#!/bin/sh -eu
 
 usage() {
        echo "Usage: makoctl <command> [options...]"
        echo ""
        echo "Commands:"
-       echo "  dismiss [-a|--all] Dismiss the last or all notifications"
-       echo "  invoke [action]    Invoke an action on the last notification"
-       echo "  reload             Reload the configuration file"
-       echo "  help               Show this help"
+       echo "  dismiss [-a|--all]       Dismiss the last or all notifications"
+       echo "  invoke [-n id] [action]  Invoke an action on the notification"
+       echo "                           with the given id, or the last"
+       echo "                           notification if none is given"
+       echo "  list                     List notifications"
+       echo "  reload                   Reload the configuration file"
+       echo "  help                     Show this help"
 }
 
 call() {
-       busctl --user call org.freedesktop.Notifications /fr/emersion/Mako \
+       busctl -j --user call org.freedesktop.Notifications /fr/emersion/Mako \
                fr.emersion.Mako "$@"
 }
 
-if [ $# -eq 0 ] || [ $# -gt 2 ]; then
+if [ $# -eq 0 ] || [ $# -gt 5 ]; then
    usage
    exit 1
 fi
 
 case "$1" in
 "dismiss")
-       case "$2" in
+       [ $# -lt 2 ] && action="" || action="$2"
+       case "$action" in
        "-a"|"--all")
                call DismissAllNotifications
                ;;
@@ -38,11 +40,21 @@
        esac
        ;;
 "invoke")
-       action="$2"
-       if [ -z "$action" ] ; then
-               action="default"
+       id=0
+       if [ $# -gt 1 ] && [ $2 == "-n" ]; then
+               id="$3"
+               shift 2
+       fi
+
+       action="default"
+       if [ $# -gt 1 ]; then
+               action="$2"
        fi
-       call InvokeAction "s" "$action"
+
+       call InvokeAction "us" "$id" "$action"
+       ;;
+"list")
+       call ListNotifications
        ;;
 "reload")
        call Reload
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/makoctl.1.scd new/mako-1.4/makoctl.1.scd
--- old/mako-1.3/makoctl.1.scd  2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/makoctl.1.scd  2019-07-19 12:57:01.000000000 +0200
@@ -26,6 +26,9 @@
        Invokes an action on the first notification. If _action_ is not 
specified,
        invokes the default action.
 
+*list*
+       Retrieve a list of current notifications.
+
 *reload*
        Reloads the configuration file.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/meson.build new/mako-1.4/meson.build
--- old/mako-1.3/meson.build    2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/meson.build    2019-07-19 12:57:01.000000000 +0200
@@ -1,7 +1,7 @@
 project(
        'mako',
        'c',
-       version: '1.2.0',
+       version: '1.3.0',
        license: 'MIT',
        meson_version: '>=0.47.0',
        default_options: [
@@ -92,6 +92,16 @@
        install_mode: 'rwxr-xr-x',
 )
 
+conf_data = configuration_data()
+conf_data.set('bindir', join_paths(get_option('prefix'), get_option('bindir')))
+
+configure_file(
+       configuration: conf_data,
+       input: 'fr.emersion.mako.service.in',
+       output: '@BASENAME@',
+       install_dir: datadir + '/dbus-1/services',
+)
+
 scdoc = find_program('scdoc', required: get_option('man-pages'))
 
 if scdoc.found()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/notification.c new/mako-1.4/notification.c
--- old/mako-1.3/notification.c 2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/notification.c 2019-07-19 12:57:01.000000000 +0200
@@ -48,6 +48,10 @@
        free(notif->body);
        free(notif->category);
        free(notif->desktop_entry);
+       if (notif->image_data != NULL) {
+               free(notif->image_data->data);
+               free(notif->image_data);
+       }
 
        notif->app_name = NULL;
        notif->app_icon = NULL;
@@ -55,6 +59,7 @@
        notif->body = NULL;
        notif->category = NULL;
        notif->desktop_entry = NULL;
+       notif->image_data = NULL;
 
        destroy_icon(notif->icon);
        notif->icon = NULL;
@@ -183,9 +188,9 @@
        struct mako_hidden_format_data *format_data = data;
        switch (variable) {
        case 'h':
-               return mako_asprintf("%d", format_data->hidden);
+               return mako_asprintf("%zu", format_data->hidden);
        case 't':
-               return mako_asprintf("%d", format_data->count);
+               return mako_asprintf("%zu", format_data->count);
        }
        return NULL;
 }
@@ -264,7 +269,7 @@
        return len;
 }
 
-static enum mako_button_binding get_button_binding(struct mako_config *config,
+static enum mako_binding get_binding(struct mako_config *config,
                uint32_t button) {
        switch (button) {
        case BTN_LEFT:
@@ -274,25 +279,21 @@
        case BTN_MIDDLE:
                return config->button_bindings.middle;
        }
-       return MAKO_BUTTON_BINDING_NONE;
+       return MAKO_BINDING_NONE;
 }
 
-void notification_handle_button(struct mako_notification *notif, uint32_t 
button,
-               enum wl_pointer_button_state state) {
-       if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
-               return;
-       }
-
-       switch (get_button_binding(&notif->state->config, button)) {
-       case MAKO_BUTTON_BINDING_NONE:
+void notification_execute_binding(struct mako_notification *notif,
+               enum mako_binding binding) {
+       switch (binding) {
+       case MAKO_BINDING_NONE:
                break;
-       case MAKO_BUTTON_BINDING_DISMISS:
+       case MAKO_BINDING_DISMISS:
                close_notification(notif, MAKO_NOTIFICATION_CLOSE_DISMISSED);
                break;
-       case MAKO_BUTTON_BINDING_DISMISS_ALL:
+       case MAKO_BINDING_DISMISS_ALL:
                close_all_notifications(notif->state, 
MAKO_NOTIFICATION_CLOSE_DISMISSED);
                break;
-       case MAKO_BUTTON_BINDING_INVOKE_DEFAULT_ACTION:;
+       case MAKO_BINDING_INVOKE_DEFAULT_ACTION:;
                struct mako_action *action;
                wl_list_for_each(action, &notif->actions, link) {
                        if (strcmp(action->key, DEFAULT_ACTION_KEY) == 0) {
@@ -305,6 +306,21 @@
        }
 }
 
+void notification_handle_button(struct mako_notification *notif, uint32_t 
button,
+               enum wl_pointer_button_state state) {
+       if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
+               return;
+       }
+
+       notification_execute_binding(notif,
+               get_binding(&notif->state->config, button));
+}
+
+void notification_handle_touch(struct mako_notification *notif) {
+       notification_execute_binding(notif,
+               notif->state->config.touch);
+}
+
 /*
  * Searches through the notifications list and returns the next position at
  * which to insert. If no results for the specified urgency are found,
@@ -388,7 +404,7 @@
        }
 
        // If count is zero, we don't need to worry about changing anything. The
-       // notification's style has its grouping critiera set to none.
+       // notification's style has its grouping criteria set to none.
 
        if (count == 1) {
                // If we matched a single notification, it means that it has 
grouping
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mako-1.3/wayland.c new/mako-1.4/wayland.c
--- old/mako-1.3/wayland.c      2019-04-19 04:32:04.000000000 +0200
+++ new/mako-1.4/wayland.c      2019-07-19 12:57:01.000000000 +0200
@@ -96,6 +96,37 @@
        free(output);
 }
 
+static void touch_handle_motion(void *data, struct wl_touch *wl_touch,
+               uint32_t time, int32_t id,
+               wl_fixed_t surface_x, wl_fixed_t surface_y) {
+       struct mako_seat *seat = data;
+       seat->touch.x = wl_fixed_to_int(surface_x);
+       seat->touch.y = wl_fixed_to_int(surface_y);
+}
+
+static void touch_handle_down(void *data, struct wl_touch *wl_touch,
+               uint32_t serial, uint32_t time, struct wl_surface *sfc, int32_t 
id,
+               wl_fixed_t surface_x, wl_fixed_t surface_y) {
+       struct mako_seat *seat = data;
+       seat->touch.x = wl_fixed_to_int(surface_x);
+       seat->touch.y = wl_fixed_to_int(surface_y);
+}
+
+static void touch_handle_up(void *data, struct wl_touch *wl_touch,
+               uint32_t serial, uint32_t time, int32_t id) {
+       struct mako_seat *seat = data;
+       struct mako_state *state = seat->state;
+
+       struct mako_notification *notif;
+       wl_list_for_each(notif, &state->notifications, link) {
+               if (hotspot_at(&notif->hotspot, seat->touch.x, seat->touch.y)) {
+                       notification_handle_touch(notif);
+                       break;
+               }
+       }
+
+       set_dirty(state);
+}
 
 static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
                uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
@@ -129,6 +160,15 @@
        .axis = noop,
 };
 
+static const struct wl_touch_listener touch_listener = {
+       .down = touch_handle_down,
+       .up = touch_handle_up,
+       .motion = touch_handle_motion,
+       .frame = noop,
+       .cancel = noop,
+       .shape = noop,
+       .orientation = noop,
+};
 
 static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
                uint32_t capabilities) {
@@ -143,6 +183,15 @@
                wl_pointer_add_listener(seat->pointer.wl_pointer,
                        &pointer_listener, seat);
        }
+       if (seat->touch.wl_touch != NULL) {
+               wl_touch_release(seat->touch.wl_touch);
+               seat->touch.wl_touch = NULL;
+       }
+       if (capabilities & WL_SEAT_CAPABILITY_TOUCH) {
+               seat->touch.wl_touch = wl_seat_get_touch(wl_seat);
+               wl_touch_add_listener(seat->touch.wl_touch,
+                       &touch_listener, seat);
+       }
 }
 
 static const struct wl_seat_listener seat_listener = {


Reply via email to