Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package slurp for openSUSE:Factory checked in at 2022-12-06 14:24:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/slurp (Old) and /work/SRC/openSUSE:Factory/.slurp.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "slurp" Tue Dec 6 14:24:13 2022 rev:8 rq:1040531 version:1.4.0 Changes: -------- --- /work/SRC/openSUSE:Factory/slurp/slurp.changes 2021-04-19 21:06:58.632117331 +0200 +++ /work/SRC/openSUSE:Factory/.slurp.new.1835/slurp.changes 2022-12-06 14:24:27.814183475 +0100 @@ -1,0 +2,15 @@ +Mon Dec 5 21:59:59 UTC 2022 - Dirk Müller <[email protected]> + +- update to 1.4.0: + * Fix busying the buffer + * Add option to enforce a specific aspect ratio of the selection (#77) + * man: fix wrong section headers + * render: Allow the user to specify which font family to use + * Mark moved-away from outputs as dirty (#89) + * has_selection is true only after moving the mouse (#88) + * Render dimensions with same color as border + * readme: IRC channel has moved to Libera Chat + * Use cairo_scale instead of multiplying by the scale everywhere + * Print output local coordinates + +------------------------------------------------------------------- Old: ---- v1.3.2.tar.gz New: ---- v1.4.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ slurp.spec ++++++ --- /var/tmp/diff_new_pack.DG8o7A/_old 2022-12-06 14:24:28.250187192 +0100 +++ /var/tmp/diff_new_pack.DG8o7A/_new 2022-12-06 14:24:28.258187260 +0100 @@ -1,7 +1,7 @@ # # spec file for package slurp # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: slurp -Version: 1.3.2 +Version: 1.4.0 Release: 0 Summary: Wayland region selector License: MIT ++++++ v1.3.2.tar.gz -> v1.4.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slurp-1.3.2/README.md new/slurp-1.4.0/README.md --- old/slurp-1.3.2/README.md 2021-04-17 19:39:34.000000000 +0200 +++ new/slurp-1.4.0/README.md 2022-12-05 13:02:22.000000000 +0100 @@ -3,13 +3,12 @@ Select a region in a Wayland compositor and print it to the standard output. Works well with [grim](https://github.com/emersion/grim). -It currently works on Sway 1.0. - -Join the IRC channel: ##emersion on Freenode. +Join the IRC channel: #emersion on Libera Chat. ## Building Install dependencies: + * meson * wayland * cairo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slurp-1.3.2/include/slurp.h new/slurp-1.4.0/include/slurp.h --- old/slurp-1.3.2/include/slurp.h 2021-04-17 19:39:34.000000000 +0200 +++ new/slurp-1.4.0/include/slurp.h 2022-12-05 13:02:22.000000000 +0100 @@ -48,11 +48,15 @@ uint32_t choice; } colors; + const char *font_family; + uint32_t border_weight; bool display_dimensions; bool single_point; bool restrict_selection; struct wl_list boxes; // slurp_box::link + bool fixed_aspect_ratio; + double aspect_ratio; // h / w struct slurp_box result; }; @@ -110,4 +114,10 @@ }; bool box_intersect(const struct slurp_box *a, const struct slurp_box *b); + +static inline struct slurp_selection *slurp_seat_current_selection(struct slurp_seat *seat) { + return seat->touch_selection.has_selection ? + &seat->touch_selection : + &seat->pointer_selection; +} #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slurp-1.3.2/main.c new/slurp-1.4.0/main.c --- old/slurp-1.3.2/main.c 2021-04-17 19:39:34.000000000 +0200 +++ new/slurp-1.4.0/main.c 2022-12-05 13:02:22.000000000 +0100 @@ -1,5 +1,6 @@ #define _POSIX_C_SOURCE 200809L +#include <assert.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -16,6 +17,7 @@ #define BG_COLOR 0xFFFFFF40 #define BORDER_COLOR 0x000000FF #define SELECTION_COLOR 0x00000000 +#define FONT_FAMILY "sans-serif" static void noop() { // This space intentionally left blank @@ -41,6 +43,10 @@ return box->width * box->height; } +static int max(int a, int b) { + return (a > b) ? a : b; +} + static int min(int a, int b) { return (a < b) ? a : b; } @@ -89,7 +95,7 @@ wl_list_for_each(output, &seat->state->outputs, link) { if (box_intersect(&output->logical_geometry, &seat->pointer_selection.selection) || - box_intersect(&output->logical_geometry, + box_intersect(&output->logical_geometry, &seat->touch_selection.selection)) { set_output_dirty(output); } @@ -97,15 +103,27 @@ } static void handle_active_selection_motion(struct slurp_seat *seat, struct slurp_selection *current_selection) { + if(seat->state->restrict_selection){ + return; + } + int32_t anchor_x = current_selection->anchor_x; int32_t anchor_y = current_selection->anchor_y; - current_selection->selection.x = min(anchor_x, current_selection->x); - current_selection->selection.y = min(anchor_y, current_selection->y); + int32_t dist_x = current_selection->x - anchor_x; + int32_t dist_y = current_selection->y - anchor_y; + + current_selection->has_selection = true; // selection includes the seat and anchor positions - current_selection->selection.width = - abs(current_selection->x - anchor_x) + 1; - current_selection->selection.height = - abs(current_selection->y - anchor_y) + 1; + int32_t width = abs(dist_x) + 1; + int32_t height = abs(dist_y) + 1; + if (seat->state->aspect_ratio) { + width = max(width, height / seat->state->aspect_ratio); + height = max(height, width * seat->state->aspect_ratio); + } + current_selection->selection.x = dist_x > 0 ? anchor_x : anchor_x - (width - 1); + current_selection->selection.y = dist_y > 0 ? anchor_y : anchor_y - (height - 1); + current_selection->selection.width = width; + current_selection->selection.height = height; } static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, @@ -116,6 +134,12 @@ if (output == NULL) { return; } + + // the places the cursor moved away from are also dirty + if (seat->pointer_selection.has_selection) { + seat_set_outputs_dirty(seat); + } + // TODO: handle multiple overlapping outputs seat->pointer_selection.current_output = output; @@ -188,7 +212,6 @@ state->running = false; } } else { - current_selection->has_selection = true; current_selection->anchor_x = current_selection->x; current_selection->anchor_y = current_selection->y; } @@ -259,6 +282,15 @@ seat->xkb_state = xkb_state_new(seat->xkb_keymap); } +// Recompute the selection if the aspect ratio changed. +static void recompute_selection(struct slurp_seat *seat) { + struct slurp_selection *current = slurp_seat_current_selection(seat); + if (current->has_selection) { + handle_active_selection_motion(seat, slurp_seat_current_selection(seat)); + seat_set_outputs_dirty(seat); + } +} + static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, const uint32_t serial, const uint32_t time, const uint32_t key, const uint32_t key_state) { @@ -283,12 +315,22 @@ } state->edit_anchor = true; break; + case XKB_KEY_Shift_L: + case XKB_KEY_Shift_R: + if (!state->fixed_aspect_ratio) { + state->aspect_ratio = 1; + recompute_selection(seat); + } + break; } break; case WL_KEYBOARD_KEY_STATE_RELEASED: if (keysym == XKB_KEY_space) { state->edit_anchor = false; + } else if (!state->fixed_aspect_ratio && (keysym == XKB_KEY_Shift_L || keysym == XKB_KEY_Shift_R)) { + state->aspect_ratio = 0; + recompute_selection(seat); } break; } @@ -531,6 +573,10 @@ if (output->current_buffer == NULL) { return; } + output->current_buffer->busy = true; + + cairo_identity_matrix(output->current_buffer->cairo); + cairo_scale(output->current_buffer->cairo, output->scale, output->scale); render(output); @@ -652,11 +698,13 @@ " -c #rrggbbaa Set border color.\n" " -s #rrggbbaa Set selection color.\n" " -B #rrggbbaa Set option box color.\n" + " -F s Set the font family for the dimensions.\n" " -w n Set border weight.\n" " -f s Set output format.\n" " -o Select a display output.\n" " -p Select a single point.\n" - " -r Restrict selection to predefined boxes.\n"; + " -r Restrict selection to predefined boxes.\n" + " -a w:h Force aspect ratio.\n"; uint32_t parse_color(const char *color) { if (color[0] == '#') { @@ -676,24 +724,32 @@ return res; } -static void print_output_name(FILE *stream, const struct slurp_box *result, struct wl_list *outputs) { +static struct slurp_output *output_from_box(const struct slurp_box *box, struct wl_list *outputs) { struct slurp_output *output; wl_list_for_each(output, outputs, link) { + struct slurp_box *geometry = &output->logical_geometry; // For now just use the top-left corner + if (in_box(geometry, box->x, box->y)) { + return output; + } + } + return NULL; +} + +static void print_output_name(FILE *stream, const struct slurp_box *result, struct wl_list *outputs) { + struct slurp_output *output = output_from_box(result, outputs); + if (output) { struct slurp_box *geometry = &output->logical_geometry; - if (in_box(geometry, result->x, result->y)) { - if (geometry->label) { - fprintf(stream, "%s", geometry->label); - return; - } - break; + if (geometry->label) { + fprintf(stream, "%s", geometry->label); + return; } } fprintf(stream, "<unknown>"); } -static void print_formatted_result(FILE *stream, const struct slurp_box *result, struct wl_list *outputs, - const char *format) { +static void print_formatted_result(FILE *stream, struct slurp_state *state , const char *format) { + struct slurp_output *output = output_from_box(&state->result, &state->outputs); for (size_t i = 0; format[i] != '\0'; i++) { char c = format[i]; if (c == '%') { @@ -702,24 +758,40 @@ i++; // Skip the next character (x, y, w or h) switch (next) { case 'x': - fprintf(stream, "%d", result->x); + fprintf(stream, "%d", state->result.x); continue; case 'y': - fprintf(stream, "%d", result->y); + fprintf(stream, "%d", state->result.y); continue; case 'w': - fprintf(stream, "%d", result->width); + fprintf(stream, "%d", state->result.width); continue; case 'h': - fprintf(stream, "%d", result->height); + fprintf(stream, "%d", state->result.height); + continue; + case 'X': + assert(output); + fprintf(stream, "%d", state->result.x - output->logical_geometry.x); + continue; + case 'Y': + assert(output); + fprintf(stream, "%d", state->result.y - output->logical_geometry.y); + continue; + case 'W': + assert(output); + fprintf(stream, "%d", min(state->result.width, output->logical_geometry.x + output->logical_geometry.width - state->result.x)); + continue; + case 'H': + assert(output); + fprintf(stream, "%d", min(state->result.height, output->logical_geometry.y + output->logical_geometry.height - state->result.y)); continue; case 'l': - if (result->label) { - fprintf(stream, "%s", result->label); + if (state->result.label) { + fprintf(stream, "%s", state->result.label); } continue; case 'o': - print_output_name(stream, result, outputs); + print_output_name(stream, &state->result, &state->outputs); continue; default: // If no case was executed, revert i back - we don't need to @@ -763,12 +835,16 @@ .border_weight = 2, .display_dimensions = false, .restrict_selection = false, + .fixed_aspect_ratio = false, + .aspect_ratio = 0, + .font_family = FONT_FAMILY }; int opt; char *format = "%x,%y %wx%h\n"; bool output_boxes = false; - while ((opt = getopt(argc, argv, "hdb:c:s:B:w:prof:")) != -1) { + int w, h; + while ((opt = getopt(argc, argv, "hdb:c:s:B:w:proa:f:F:")) != -1) { switch (opt) { case 'h': printf("%s", usage); @@ -791,6 +867,9 @@ case 'f': format = optarg; break; + case 'F': + state.font_family = optarg; + break; case 'w': { errno = 0; char *endptr; @@ -810,6 +889,18 @@ case 'r': state.restrict_selection = true; break; + case 'a': + if (sscanf(optarg, "%d:%d", &w, &h) != 2) { + fprintf(stderr, "invalid aspect ratio\n"); + return EXIT_FAILURE; + } + if (w <= 0 || h <= 0) { + fprintf(stderr, "width and height of aspect ratio must be greater than zero\n"); + return EXIT_FAILURE; + } + state.fixed_aspect_ratio = true; + state.aspect_ratio = (double) h / w; + break; default: printf("%s", usage); return EXIT_FAILURE; @@ -965,7 +1056,7 @@ fprintf(stderr, "selection cancelled\n"); status = EXIT_FAILURE; } else { - print_formatted_result(stream, &state.result, &state.outputs, format); + print_formatted_result(stream, &state, format); fclose(stream); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slurp-1.3.2/meson.build new/slurp-1.4.0/meson.build --- old/slurp-1.3.2/meson.build 2021-04-17 19:39:34.000000000 +0200 +++ new/slurp-1.4.0/meson.build 2022-12-05 13:02:22.000000000 +0100 @@ -1,16 +1,14 @@ project( - 'slurp', - 'c', -version : '1.3.2', -license : 'MIT', -meson_version : '>=0.48.0', -default_options : ['c_std=c11', 'warning_level=2', 'werror=true'] + 'slurp', + 'c', + version: '1.4.0', + license: 'MIT', + meson_version: '>=0.59.0', + default_options: ['c_std=c11', 'warning_level=2', 'werror=true'], ) add_project_arguments('-Wno-unused-parameter', language: 'c') -slurp_inc = include_directories('include') - cc = meson.get_compiler('c') cairo = dependency('cairo') @@ -24,32 +22,28 @@ executable( 'slurp', - files([ + [ 'main.c', 'pool-buffer.c', 'render.c', - ]), + protos_src, + ], dependencies: [ cairo, - client_protos, realtime, wayland_client, wayland_cursor, xkbcommon, ], - include_directories: [slurp_inc], + include_directories: 'include', install: true, ) scdoc = find_program('scdoc', required: get_option('man-pages')) if scdoc.found() - sh = find_program('sh') - man_pages = ['slurp.1.scd'] - mandir = get_option('mandir') - foreach src : man_pages topic = src.split('.')[0] section = src.split('.')[1] @@ -59,11 +53,11 @@ output, input: src, output: output, - command: [ - sh, '-c', '@0@ < @INPUT@ > @1@'.format(scdoc.path(), output) - ], + command: scdoc, + feed: true, + capture: true, install: true, - install_dir: '@0@/man@1@'.format(mandir, section) + install_dir: get_option('mandir') / 'man' + section, ) endforeach endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slurp-1.3.2/protocol/meson.build new/slurp-1.4.0/protocol/meson.build --- old/slurp-1.3.2/protocol/meson.build 2021-04-17 19:39:34.000000000 +0200 +++ new/slurp-1.4.0/protocol/meson.build 2022-12-05 13:02:22.000000000 +0100 @@ -1,18 +1,12 @@ -wl_protocol_dir = wayland_protos.get_pkgconfig_variable('pkgdatadir') +wayland_scanner = dependency('wayland-scanner', native: true, version: '>=1.14.91') +wayland_scanner = find_program(wayland_scanner.get_variable('wayland_scanner'), native: true) -wayland_scanner = find_program('wayland-scanner') - -# should check wayland_scanner's version, but it is hard to get -if wayland_client.version().version_compare('>=1.14.91') - code_type = 'private-code' -else - code_type = 'code' -endif +wl_protocol_dir = wayland_protos.get_variable('pkgdatadir') wayland_scanner_code = generator( wayland_scanner, output: '@[email protected]', - arguments: [code_type, '@INPUT@', '@OUTPUT@'], + arguments: ['private-code', '@INPUT@', '@OUTPUT@'], ) wayland_scanner_client = generator( @@ -22,27 +16,13 @@ ) client_protocols = [ - [wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'], - [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], - ['wlr-layer-shell-unstable-v1.xml'], + wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', + wl_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml', + 'wlr-layer-shell-unstable-v1.xml', ] -client_protos_src = [] -client_protos_headers = [] - -foreach p : client_protocols - xml = join_paths(p) - client_protos_src += wayland_scanner_code.process(xml) - client_protos_headers += wayland_scanner_client.process(xml) +protos_src = [] +foreach xml : client_protocols + protos_src += wayland_scanner_code.process(xml) + protos_src += wayland_scanner_client.process(xml) endforeach - -lib_client_protos = static_library( - 'client_protos', - client_protos_src + client_protos_headers, - dependencies: [wayland_client] -) # for the include directory - -client_protos = declare_dependency( - link_with: lib_client_protos, - sources: client_protos_headers, -) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slurp-1.3.2/render.c new/slurp-1.4.0/render.c --- old/slurp-1.3.2/render.c 2021-04-17 19:39:34.000000000 +0200 +++ new/slurp-1.4.0/render.c 2022-12-05 13:02:22.000000000 +0100 @@ -13,10 +13,10 @@ (color >> (0 * 8) & 0xFF) / 255.0); } -static void draw_rect(cairo_t *cairo, struct slurp_box *box, uint32_t color, int32_t scale) { +static void draw_rect(cairo_t *cairo, struct slurp_box *box, uint32_t color) { set_source_u32(cairo, color); - cairo_rectangle(cairo, box->x * scale, box->y * scale, - box->width * scale, box->height * scale); + cairo_rectangle(cairo, box->x, box->y, + box->width, box->height); } static void box_layout_to_output(struct slurp_box *box, struct slurp_output *output) { @@ -28,7 +28,6 @@ struct slurp_state *state = output->state; struct pool_buffer *buffer = output->current_buffer; cairo_t *cairo = buffer->cairo; - int32_t scale = output->scale; // Clear cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); @@ -42,7 +41,7 @@ choice_box)) { struct slurp_box b = *choice_box; box_layout_to_output(&b, output); - draw_rect(cairo, &b, state->colors.choice, scale); + draw_rect(cairo, &b, state->colors.choice); cairo_fill(cairo); } } @@ -50,9 +49,7 @@ struct slurp_seat *seat; wl_list_for_each(seat, &state->seats, link) { struct slurp_selection *current_selection = - seat->touch_selection.has_selection ? - &seat->touch_selection : - &seat->pointer_selection; + slurp_seat_current_selection(seat); if (!current_selection->has_selection) { continue; @@ -65,25 +62,26 @@ struct slurp_box b = current_selection->selection; box_layout_to_output(&b, output); - draw_rect(cairo, &b, state->colors.selection, scale); + draw_rect(cairo, &b, state->colors.selection); cairo_fill(cairo); // Draw border - cairo_set_line_width(cairo, state->border_weight * scale); - draw_rect(cairo, &b, state->colors.border, scale); + cairo_set_line_width(cairo, state->border_weight); + draw_rect(cairo, &b, state->colors.border); cairo_stroke(cairo); if (state->display_dimensions) { - cairo_select_font_face(cairo, "Sans", + cairo_select_font_face(cairo, state->font_family, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - cairo_set_font_size(cairo, 14 * scale); + cairo_set_font_size(cairo, 14); + set_source_u32(cairo, state->colors.border); // buffer of 12 can hold selections up to 99999x99999 char dimensions[12]; snprintf(dimensions, sizeof(dimensions), "%ix%i", b.width, b.height); - cairo_move_to(cairo, (b.x + b.width + 10) * scale, - (b.y + b.height + 20) * scale); + cairo_move_to(cairo, b.x + b.width + 10, + b.y + b.height + 20); cairo_show_text(cairo, dimensions); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/slurp-1.3.2/slurp.1.scd new/slurp-1.4.0/slurp.1.scd --- old/slurp-1.3.2/slurp.1.scd 2021-04-17 19:39:34.000000000 +0200 +++ new/slurp-1.4.0/slurp.1.scd 2022-12-05 13:02:22.000000000 +0100 @@ -4,11 +4,11 @@ slurp - select a region in a Wayland compositor -# DESCRIPTION +# SYNOPSIS *slurp* [options...] -# SYNOPSIS +# DESCRIPTION slurp is a command-line utility to select a region from Wayland compositors which support the layer-shell protocol. It lets the user hold the pointer to @@ -44,6 +44,12 @@ Set color for highlighting predefined rectangles from standard input when not selected. +*-F* _font family_ + Set the font family name when displaying the dimensions box. Only useful + when combined with the -d option. The available font family names guaranteed + to work are the standard generic CSS2 options: serif, sans-serif, + monospace, cursive and fantasy. It defaults to the sans-serif family name. + *-w* _weight_ Set border weight. @@ -63,6 +69,10 @@ from standard input, if *-o* is used, the rectangles of all display outputs. This option conflicts with *-p*. +*-a* _width_:_height_ + Force selections to have the given aspect ratio. This constraint is not + applied to the predefined rectangles specified using *-o*. + # COLORS Colors may be specified in #RRGGBB or #RRGGBBAA format. The # is optional. @@ -79,6 +89,18 @@ %h The height of the selection +%X The x-coordinate of the selection with coordinates relative to the output + containing the top left corner. + +%Y The y-coordinate of the selection with coordinates relative to the output + containing the top left corner. + +%W The width of the selection cropped to the output containing the top left + corner. + +%H The height of the selection cropped to the output containing the top left + corner. + %l Label included with region from stdin %o The name of the output containing the top left corner, or "<unknown>" if @@ -86,6 +108,22 @@ The default format is "%x,%y %wx%h\\n". +# KEYBOARD CONTROLS + +The following keyboard actions can be used during selection: + +*Escape* Cancel the selection and exit slurp + +*Space* If currently making a selection, while space is held down, move the +entire selection rather than change the selection's size as you move the +pointer. + +*Shift* Experimental. If the *-a* option wasn't specified, then set the aspect +ratio to 1:1 while shift is held down, releasing it restores the un-constrained +aspect ratio. *Note:* This behavior may change in the future depending on +feedback. + + # AUTHORS Maintained by Simon Ser <[email protected]>, who is assisted by other
