Hello community,

here is the log from the commit of package slurp for openSUSE:Factory checked 
in at 2019-06-04 12:14:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/slurp (Old)
 and      /work/SRC/openSUSE:Factory/.slurp.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "slurp"

Tue Jun  4 12:14:25 2019 rev:4 rq:707381 version:1.2.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/slurp/slurp.changes      2019-02-25 
17:58:40.706218280 +0100
+++ /work/SRC/openSUSE:Factory/.slurp.new.5148/slurp.changes    2019-06-04 
12:14:29.743779422 +0200
@@ -1,0 +2,10 @@
+Tue Jun  4 06:12:14 UTC 2019 - [email protected]
+
+- Update to 1.2.0:
+  * It's now possible to provide a list of predefined
+    regions to choose from
+  * A single-pixel selection mode has been added
+  * Check out the README for some examples:
+     https://github.com/emersion/slurp#example-usage
+
+-------------------------------------------------------------------

Old:
----
  v1.1.0.tar.gz

New:
----
  v1.2.0.tar.gz

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

Other differences:
------------------
++++++ slurp.spec ++++++
--- /var/tmp/diff_new_pack.LrP5BX/_old  2019-06-04 12:14:31.207778942 +0200
+++ /var/tmp/diff_new_pack.LrP5BX/_new  2019-06-04 12:14:31.207778942 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           slurp
-Version:        1.1.0
+Version:        1.2.0
 Release:        0
 Summary:        Wayland region selector
 License:        MIT

++++++ v1.1.0.tar.gz -> v1.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slurp-1.1.0/README.md new/slurp-1.2.0/README.md
--- old/slurp-1.1.0/README.md   2019-02-23 19:47:52.000000000 +0100
+++ new/slurp-1.2.0/README.md   2019-06-02 12:07:19.000000000 +0200
@@ -21,6 +21,32 @@
 build/slurp
 ```
 
+## Example usage
+
+Select a region and print it to stdout:
+
+```sh
+slurp
+```
+
+Select a single point instead of a region:
+
+```sh
+slurp -p
+```
+
+Select an output under Sway, using `swaymsg` and `jq`:
+
+```sh
+swaymsg -t get_outputs | jq -r '.[] | select(.active) | .rect | "\(.x),\(.y) 
\(.width)x\(.height)"' | slurp
+```
+
+Select a window under Sway, using `swaymsg` and `jq`:
+
+```sh
+swaymsg -t get_tree | jq -r '.. | (.nodes? // empty)[] | select(.pid and 
.visible) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp
+```
+
 ## Contributing
 
 Either [send GitHub pull requests][1] or [send patches on the mailing list][2].
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slurp-1.1.0/include/slurp.h 
new/slurp-1.2.0/include/slurp.h
--- old/slurp-1.1.0/include/slurp.h     2019-02-23 19:47:52.000000000 +0100
+++ new/slurp-1.2.0/include/slurp.h     2019-06-02 12:07:19.000000000 +0200
@@ -12,6 +12,7 @@
 struct slurp_box {
        int32_t x, y;
        int32_t width, height;
+       struct wl_list link;
 };
 
 struct slurp_state {
@@ -34,6 +35,8 @@
 
        uint32_t border_weight;
        bool display_dimensions;
+       bool single_point;
+       struct wl_list boxes; // slurp_box::link
 
        struct slurp_box result;
 };
@@ -78,8 +81,9 @@
        struct slurp_output *current_output;
        int32_t x, y;
        int32_t pressed_x, pressed_y;
+       struct slurp_box selection;
+       bool has_selection;
 };
 
-void seat_get_box(struct slurp_seat *seat, struct slurp_box *result);
 bool box_intersect(const struct slurp_box *a, const struct slurp_box *b);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slurp-1.1.0/main.c new/slurp-1.2.0/main.c
--- old/slurp-1.1.0/main.c      2019-02-23 19:47:52.000000000 +0100
+++ new/slurp-1.2.0/main.c      2019-06-02 12:07:19.000000000 +0200
@@ -18,10 +18,10 @@
 static void set_output_dirty(struct slurp_output *output);
 
 bool box_intersect(const struct slurp_box *a, const struct slurp_box *b) {
-       return (a->x < b->x + b->width &&
-               a->x + a->width > b->x &&
-               a->y < b->y + b->height &&
-               a->height + a->y > b->y);
+       return a->x < b->x + b->width &&
+               a->x + a->width > b->x &&
+               a->y < b->y + b->height &&
+               a->height + a->y > b->y;
 }
 
 static struct slurp_output *output_from_surface(struct slurp_state *state,
@@ -59,28 +59,67 @@
 }
 
 static void seat_set_outputs_dirty(struct slurp_seat *seat) {
-       struct slurp_box box;
-       seat_get_box(seat, &box);
        struct slurp_output *output;
        wl_list_for_each(output, &seat->state->outputs, link) {
-               if (box_intersect(&output->logical_geometry, &box)) {
+               if (box_intersect(&output->logical_geometry, &seat->selection)) 
{
                        set_output_dirty(output);
                }
        }
 }
 
+static bool in_box(const struct slurp_box *box, int32_t x, int32_t y) {
+       return box->x <= x
+               && box->x + box->width >= x
+               && box->y <= y
+               && box->y + box->height >= y;
+}
+
+static int32_t box_size(const struct slurp_box *box) {
+       return box->width * box->height;
+}
+
+static int min(int a, int b) {
+       return (a < b) ? a : b;
+}
+
 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) {
        struct slurp_seat *seat = data;
        // the places the cursor moved away from are also dirty
-       if (seat->button_state == WL_POINTER_BUTTON_STATE_PRESSED) {
+       if (seat->has_selection) {
                seat_set_outputs_dirty(seat);
        }
 
        seat->x = wl_fixed_to_int(surface_x) + 
seat->current_output->logical_geometry.x;
        seat->y = wl_fixed_to_int(surface_y) + 
seat->current_output->logical_geometry.y;
 
-       if (seat->button_state == WL_POINTER_BUTTON_STATE_PRESSED) {
+       switch (seat->button_state) {
+       case WL_POINTER_BUTTON_STATE_RELEASED:
+               seat->has_selection = false;
+
+               // find smallest box intersecting the cursor
+               struct slurp_box *box;
+               wl_list_for_each(box, &seat->state->boxes, link) {
+                       if (in_box(box, seat->x, seat->y)) {
+                               if (seat->has_selection &&
+                                               box_size(&seat->selection) < 
box_size(box)) {
+                                       continue;
+                               }
+                               seat->selection = *box;
+                               seat->has_selection = true;
+                       }
+               }
+               break;
+       case WL_POINTER_BUTTON_STATE_PRESSED:
+               seat->has_selection = true;
+               seat->selection.x = min(seat->pressed_x, seat->x);
+               seat->selection.y = min(seat->pressed_y, seat->y);
+               seat->selection.width = abs(seat->x - seat->pressed_x);
+               seat->selection.height = abs(seat->y - seat->pressed_y);
+               break;
+       }
+
+       if (seat->has_selection) {
                seat_set_outputs_dirty(seat);
        }
 }
@@ -95,11 +134,23 @@
 
        switch (button_state) {
        case WL_POINTER_BUTTON_STATE_PRESSED:
-               seat->pressed_x = seat->x;
-               seat->pressed_y = seat->y;
+               if (state->single_point) {
+                       state->result.x = seat->x;
+                       state->result.y = seat->y;
+                       state->result.width = state->result.height = 1;
+                       state->running = false;
+               } else {
+                       seat->pressed_x = seat->x;
+                       seat->pressed_y = seat->y;
+               }
                break;
        case WL_POINTER_BUTTON_STATE_RELEASED:
-               seat_get_box(seat, &state->result);
+               if (state->single_point) {
+                       break;
+               }
+               if (seat->has_selection) {
+                       state->result = seat->selection;
+               }
                state->running = false;
                break;
        }
@@ -113,23 +164,13 @@
        .axis = noop,
 };
 
-static int min(int a, int b) {
-       return (a < b) ? a : b;
-}
-
-void seat_get_box(struct slurp_seat *seat, struct slurp_box *result) {
-       result->x = min(seat->pressed_x, seat->x);
-       result->y = min(seat->pressed_y, seat->y);
-       result->width = abs(seat->x - seat->pressed_x);
-       result->height = abs(seat->y - seat->pressed_y);
-}
-
 static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
                uint32_t serial, uint32_t time, uint32_t key, uint32_t 
key_state) {
        struct slurp_seat *seat = data;
        struct slurp_state *state = seat->state;
        if (key_state == WL_KEYBOARD_KEY_STATE_PRESSED) {
                if (key == KEY_ESC) {
+                       seat->has_selection = false;
                        state->running = false;
                }
        }
@@ -299,7 +340,8 @@
 
        // Schedule a frame in case the output becomes dirty again
        output->frame_callback = wl_surface_frame(output->surface);
-       wl_callback_add_listener(output->frame_callback, 
&output_frame_listener, output);
+       wl_callback_add_listener(output->frame_callback,
+               &output_frame_listener, output);
 
        wl_surface_attach(output->surface, output->current_buffer->buffer, 0, 
0);
        wl_surface_damage(output->surface, 0, 0, output->width, output->height);
@@ -331,7 +373,8 @@
        }
 
        output->frame_callback = wl_surface_frame(output->surface);
-       wl_callback_add_listener(output->frame_callback, 
&output_frame_listener, output);
+       wl_callback_add_listener(output->frame_callback,
+               &output_frame_listener, output);
        wl_surface_commit(output->surface);
 }
 
@@ -394,7 +437,8 @@
                        wl_registry_bind(registry, name, &wl_output_interface, 
3);
                create_output(state, wl_output);
        } else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 
0) {
-               state->xdg_output_manager = wl_registry_bind(registry, name, 
&zxdg_output_manager_v1_interface, 1);
+               state->xdg_output_manager = wl_registry_bind(registry, name,
+                       &zxdg_output_manager_v1_interface, 1);
        }
 }
 
@@ -412,7 +456,8 @@
        "  -c #rrggbbaa Set border color.\n"
        "  -s #rrggbbaa Set selection color.\n"
        "  -w n         Set border weight.\n"
-       "  -f s         Set output format.\n";
+       "  -f s         Set output format.\n"
+       "  -p           Select a single point.\n";
 
 uint32_t parse_color(const char *color) {
        if (color[0] == '#') {
@@ -432,12 +477,13 @@
        return res;
 }
 
-static void print_formatted_result(const struct slurp_box *result, const char 
*format) {
-       for (size_t i = 0; format[i] != 0; i++) {
+static void print_formatted_result(const struct slurp_box *result,
+               const char *format) {
+       for (size_t i = 0; format[i] != '\0'; i++) {
                char c = format[i];
                if (c == '%') {
                        char next = format[i + 1];
-                       
+
                        i++; // Skip the next character (x, y, w or h)
                        switch (next) {
                        case 'x':
@@ -452,14 +498,28 @@
                        case 'h':
                                printf("%u", result->height);
                                continue;
+                       default:
+                               // If no case was executed, revert i back - we 
don't need to
+                               // skip the next character.
+                               i--;
                        }
-                       i--; // If no case was executed, revert i back - we 
don't need to skip the next character.
                }
                printf("%c", c);
        }
        printf("\n");
 }
 
+static void add_choice_box(struct slurp_state *state,
+               const struct slurp_box *box) {
+       struct slurp_box *b = calloc(1, sizeof(struct slurp_box));
+       if (b == NULL) {
+               fprintf(stderr, "allocation failed\n");
+               return;
+       }
+       *b = *box;
+       wl_list_insert(state->boxes.prev, &b->link);
+}
+
 int main(int argc, char *argv[]) {
        struct slurp_state state = {
                .colors = {
@@ -473,7 +533,7 @@
 
        int opt;
        char *format = "%x,%y %wx%h";
-       while ((opt = getopt(argc, argv, "hdb:c:s:w:f:")) != -1) {
+       while ((opt = getopt(argc, argv, "hdb:c:s:w:pf:")) != -1) {
                switch (opt) {
                case 'h':
                        printf("%s", usage);
@@ -502,6 +562,9 @@
                                exit(EXIT_FAILURE);
                        }
                        break;
+               case 'p':
+                       state.single_point = true;
+                       break;
                }
                default:
                        printf("%s", usage);
@@ -509,6 +572,14 @@
                }
        }
 
+       wl_list_init(&state.boxes);
+       if (!isatty(STDIN_FILENO) && !state.single_point) {
+               struct slurp_box in_box = {0};
+               while (fscanf(stdin, "%d,%d %dx%d\n", &in_box.x, &in_box.y,
+                               &in_box.width, &in_box.height) == 4) {
+                       add_choice_box(&state, &in_box);
+               }
+       }
        wl_list_init(&state.outputs);
        wl_list_init(&state.seats);
 
@@ -520,7 +591,6 @@
 
        state.registry = wl_display_get_registry(state.display);
        wl_registry_add_listener(state.registry, &registry_listener, &state);
-       wl_display_dispatch(state.display);
        wl_display_roundtrip(state.display);
 
        if (state.compositor == NULL) {
@@ -536,13 +606,27 @@
                return EXIT_FAILURE;
        }
        if (state.xdg_output_manager == NULL) {
-               fprintf(stderr, "compositor doesn't support xdg-output. 
Guessing geometry from physical output size.\n");
+               fprintf(stderr, "compositor doesn't support xdg-output. "
+                       "Guessing geometry from physical output size.\n");
        }
        if (wl_list_empty(&state.outputs)) {
                fprintf(stderr, "no wl_output\n");
                return EXIT_FAILURE;
        }
 
+       const char *cursor_theme = getenv("XCURSOR_THEME");
+       const char *cursor_size_str = getenv("XCURSOR_SIZE");
+       int cursor_size = 24;
+       if (cursor_size_str != NULL) {
+               char *end;
+               errno = 0;
+               cursor_size = strtol(cursor_size_str, &end, 10);
+               if (errno != 0 || cursor_size_str[0] == '\0' || end[0] != '\0') 
{
+                       fprintf(stderr, "invalid XCURSOR_SIZE value\n");
+                       return EXIT_FAILURE;
+               }
+       }
+
        struct slurp_output *output;
        wl_list_for_each(output, &state.outputs, link) {
                output->surface = 
wl_compositor_create_surface(state.compositor);
@@ -557,7 +641,8 @@
                if (state.xdg_output_manager) {
                        output->xdg_output = 
zxdg_output_manager_v1_get_xdg_output(
                                state.xdg_output_manager, output->wl_output);
-                       zxdg_output_v1_add_listener(output->xdg_output, 
&xdg_output_listener, output);
+                       zxdg_output_v1_add_listener(output->xdg_output,
+                               &xdg_output_listener, output);
                } else {
                        // guess
                        output->logical_geometry = output->geometry;
@@ -574,8 +659,8 @@
                zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, 
-1);
                wl_surface_commit(output->surface);
 
-               output->cursor_theme =
-                       wl_cursor_theme_load(NULL, 24 * output->scale, 
state.shm);
+               output->cursor_theme = wl_cursor_theme_load(cursor_theme,
+                       cursor_size * output->scale, state.shm);
                if (output->cursor_theme == NULL) {
                        fprintf(stderr, "failed to load cursor theme\n");
                        return EXIT_FAILURE;
@@ -620,11 +705,20 @@
        wl_display_roundtrip(state.display);
 
        zwlr_layer_shell_v1_destroy(state.layer_shell);
+       if (state.xdg_output_manager != NULL) {
+               zxdg_output_manager_v1_destroy(state.xdg_output_manager);
+       }
        wl_compositor_destroy(state.compositor);
        wl_shm_destroy(state.shm);
        wl_registry_destroy(state.registry);
        wl_display_disconnect(state.display);
 
+       struct slurp_box *box, *box_tmp;
+       wl_list_for_each_safe(box, box_tmp, &state.boxes, link) {
+               wl_list_remove(&box->link);
+               free(box);
+       }
+
        if (state.result.width == 0 && state.result.height == 0) {
                fprintf(stderr, "selection cancelled\n");
                return EXIT_FAILURE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slurp-1.1.0/render.c new/slurp-1.2.0/render.c
--- old/slurp-1.1.0/render.c    2019-02-23 19:47:52.000000000 +0100
+++ new/slurp-1.2.0/render.c    2019-06-02 12:07:19.000000000 +0200
@@ -28,15 +28,14 @@
        struct slurp_seat *seat;
        wl_list_for_each(seat, &state->seats, link) {
                if (!seat->wl_pointer) continue;
-               if (seat->button_state != WL_POINTER_BUTTON_STATE_PRESSED) {
+               if (!seat->has_selection) {
                        continue;
                }
 
-               struct slurp_box b;
-               seat_get_box(seat, &b);
-               if (!box_intersect(&output->logical_geometry, &b)) {
+               if(!box_intersect(&output->logical_geometry, &seat->selection)) 
{
                        continue;
                }
+               struct slurp_box b = seat->selection;
                b.x -= output->logical_geometry.x;
                b.y -= output->logical_geometry.y;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slurp-1.1.0/slurp.1.scd new/slurp-1.2.0/slurp.1.scd
--- old/slurp-1.1.0/slurp.1.scd 2019-02-23 19:47:52.000000000 +0100
+++ new/slurp-1.2.0/slurp.1.scd 2019-06-02 12:07:19.000000000 +0200
@@ -14,6 +14,10 @@
 which support the layer-shell protocol. It lets the user hold the pointer to
 select, or click to cancel the selection.
 
+If the standard input is not a TTY, slurp will read a list of predefined
+rectangles for quick selection. Each line must be in the form
+"<x>,<y> <width>x<height>".
+
 # OPTIONS
 
 *-h*
@@ -37,6 +41,10 @@
 *-f* _format_
        Set format. See *FORMAT* for more detail.
 
+*-p*
+       Select a single pixel instead of a rectangle. This mode ignores any
+       predefined rectangles read from the standard input.
+
 # COLORS
 
 Colors may be specified in #RRGGBB or #RRGGBBAA format. The # is optional.


Reply via email to