Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package swappy for openSUSE:Factory checked in at 2025-08-28 17:19:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/swappy (Old) and /work/SRC/openSUSE:Factory/.swappy.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "swappy" Thu Aug 28 17:19:54 2025 rev:9 rq:1301789 version:1.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/swappy/swappy.changes 2025-08-19 16:46:29.407789262 +0200 +++ /work/SRC/openSUSE:Factory/.swappy.new.1977/swappy.changes 2025-08-28 17:20:31.087866485 +0200 @@ -1,0 +2,13 @@ +Thu Aug 28 11:14:59 UTC 2025 - Michael Vetter <mvet...@suse.com> + +- Update to 1.8.0: + Features: + * config: add left hand friendly keybinds (e3b8bf6) + * ui: add transparency feature (0416812) + * ui: support input method when edit text (5e3808c) + * ui: text supports pasting using Ctrl-v (59dca02) + Bug Fixes: + * application: bring back output option (061155c), closes #202 + * application: save twice if auto_save and -o option (e5cde68) + +------------------------------------------------------------------- Old: ---- swappy-1.7.1.tar.gz.sig v1.7.1.tar.gz New: ---- swappy-1.8.0.tar.gz.sig v1.8.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ swappy.spec ++++++ --- /var/tmp/diff_new_pack.3LC48q/_old 2025-08-28 17:20:31.627889116 +0200 +++ /var/tmp/diff_new_pack.3LC48q/_new 2025-08-28 17:20:31.631889284 +0200 @@ -17,7 +17,7 @@ Name: swappy -Version: 1.7.1 +Version: 1.8.0 Release: 0 Summary: Wayland compositor screenshot editor License: MIT ++++++ v1.7.1.tar.gz -> v1.8.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/.gitignore new/swappy-1.8.0/.gitignore --- old/swappy-1.7.1/.gitignore 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/.gitignore 2025-08-27 21:34:53.000000000 +0200 @@ -57,3 +57,4 @@ # Build folders build/ release/ +.cache/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/CHANGELOG.md new/swappy-1.8.0/CHANGELOG.md --- old/swappy-1.7.1/CHANGELOG.md 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/CHANGELOG.md 2025-08-27 21:34:53.000000000 +0200 @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.8.0](https://github.com/jtheoof/swappy/compare/v1.7.1...v1.8.0) (2025-08-27) + + +### Features + +* **config:** add left hand friendly keybinds ([e3b8bf6](https://github.com/jtheoof/swappy/commit/e3b8bf610fa64d21e053a8e25fb74acda334ba3d)) +* **ui:** add transparency feature ([0416812](https://github.com/jtheoof/swappy/commit/0416812d63453d3f23e1e1e354882032ef86590b)) +* **ui:** support input method when edit text ([5e3808c](https://github.com/jtheoof/swappy/commit/5e3808c7a3631c948c701a34de455cfaa3550757)) +* **ui:** text supports pasting using Ctrl-v ([59dca02](https://github.com/jtheoof/swappy/commit/59dca0244906cf276a69ed11f21b5ed635690766)) + + +### Bug Fixes + +* **application:** bring back output option ([061155c](https://github.com/jtheoof/swappy/commit/061155c9dee96c6dc4e7c3a4b4dc03d45e7fe192)), closes [#202](https://github.com/jtheoof/swappy/issues/202) +* **application:** save twice if auto_save and -o option ([e5cde68](https://github.com/jtheoof/swappy/commit/e5cde680e6c5180e35c80c0868effda1b5b8b1d9)) + ### [1.7.1](https://github.com/jtheoof/swappy/compare/v1.7.0...v1.7.1) (2025-08-18) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/README.md new/swappy-1.8.0/README.md --- old/swappy-1.7.1/README.md 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/README.md 2025-08-27 21:34:53.000000000 +0200 @@ -53,6 +53,8 @@ fill_shape=false auto_save=false custom_color=rgba(193,125,17,1) +transparent=false +transparency=50 ``` - `save_dir` is where swappshots will be saved, can contain env variables, when it does not exist, swappy attempts to create it first, but does not abort if directory creation fails @@ -66,6 +68,8 @@ - `fill_shape` is used to toggle shape filling (for the rectangle and ellipsis tools) on or off upon startup - `auto_save` is used to toggle auto saving of final buffer to `save_dir` upon exit - `custom_color` is used to set a default value for the custom color +- `transparency` is used to set transparency of everything that is drawn during startup +- `transparent` is used to toggle transparency during startup ## Keyboard Shortcuts @@ -75,9 +79,9 @@ <hr> - `b`: Switch to Brush -- `t`: Switch to Text -- `r`: Switch to Rectangle -- `o`: Switch to Ellipse +- `e` `t`: Switch to Text (Editor) +- `r` `s`: Switch to Rectangle (Square) +- `c` `o`: Switch to Ellipse (Circle) - `a`: Switch to Arrow - `d`: Switch to Blur (`d` stands for droplet) @@ -91,7 +95,8 @@ - `Plus`: Increase Stroke Size - `Equal`: Reset Stroke Size - `f`: Toggle Shape Filling -- `k`: Clear Paints (cannot be undone) +- `x` `k`: Clear Paints (cannot be undone) +- `T`: Toggle Transparency <hr> @@ -109,6 +114,7 @@ - **Copy**: If you don't have [wl-clipboard] installed, copy to clipboard won't work if you close swappy (the content of the clipboard is lost). This because GTK 3.24 [has not implemented persistent storage on wayland backend yet](https://gitlab.gnome.org/GNOME/gtk/blob/3.24.13/gdk/wayland/gdkdisplay-wayland.c#L857). We need to do it on the [Wayland level](https://github.com/swaywm/wlr-protocols/blob/master/unstable/wlr-data-control-unstable-v1.xml), or wait for GTK 4. For now, we use `wl-copy` if installed and revert to `gtk` clipboard if not found. - **Fonts**: Swappy relies on Font Awesome 5 being present to properly render the icons. On Arch you can simply install those with: `sudo pacman -S otf-font-awesome` +- **Output Format**: Only PNG is supported. ## Installation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/include/application.h new/swappy-1.8.0/include/application.h --- old/swappy-1.7.1/include/application.h 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/include/application.h 2025-08-27 21:34:53.000000000 +0200 @@ -57,3 +57,9 @@ void text_size_decrease_handler(GtkWidget *widget, struct swappy_state *state); void text_size_reset_handler(GtkWidget *widget, struct swappy_state *state); void text_size_increase_handler(GtkWidget *widget, struct swappy_state *state); + +void transparency_decrease_handler(GtkWidget *widget, + struct swappy_state *state); +void transparency_reset_handler(GtkWidget *widget, struct swappy_state *state); +void transparency_increase_handler(GtkWidget *widget, + struct swappy_state *state); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/include/config.h new/swappy-1.8.0/include/config.h --- old/swappy-1.7.1/include/config.h 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/include/config.h 2025-08-27 21:34:53.000000000 +0200 @@ -3,6 +3,7 @@ #define CONFIG_LINE_SIZE_DEFAULT 5 #define CONFIG_TEXT_FONT_DEFAULT "sans-serif" #define CONFIG_TEXT_SIZE_DEFAULT 20 +#define CONFIG_TRANSPARENCY_DEFAULT 50 #define CONFIG_SHOW_PANEL_DEFAULT false #define CONFIG_SAVE_FILENAME_FORMAT_DEFAULT "swappy-%Y%m%d_%H%M%S.png" #define CONFIG_PAINT_MODE_DEFAULT SWAPPY_PAINT_MODE_BRUSH @@ -10,6 +11,7 @@ #define CONFIG_FILL_SHAPE_DEFAULT false #define CONFIG_AUTO_SAVE_DEFAULT false #define CONFIG_CUSTOM_COLOR_DEFAULT "rgba(193,125,17,1)" +#define CONFIG_TRANSPARENT_DEFAULT false void config_load(struct swappy_state *state); void config_free(struct swappy_state *state); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/include/paint.h new/swappy-1.8.0/include/paint.h --- old/swappy-1.7.1/include/paint.h 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/include/paint.h 2025-08-27 21:34:53.000000000 +0200 @@ -10,6 +10,7 @@ double y, gboolean is_control_pressed); void paint_update_temporary_text(struct swappy_state *state, GdkEventKey *event); +void paint_update_temporary_str(struct swappy_state *state, char *event); void paint_update_temporary_text_clip(struct swappy_state *state, gdouble x, gdouble y); void paint_commit_temporary(struct swappy_state *state); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/include/swappy.h new/swappy-1.8.0/include/swappy.h --- old/swappy-1.7.1/include/swappy.h 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/include/swappy.h 2025-08-27 21:34:53.000000000 +0200 @@ -14,6 +14,9 @@ #define SWAPPY_TEXT_SIZE_MIN 10 #define SWAPPY_TEXT_SIZE_MAX 50 +#define SWAPPY_TRANSPARENCY_MIN 5 +#define SWAPPY_TRANSPARENCY_MAX 95 + enum swappy_paint_type { SWAPPY_PAINT_MODE_BRUSH = 0, /* Brush mode to draw arbitrary shapes */ SWAPPY_PAINT_MODE_TEXT, /* Mode to draw texts */ @@ -106,12 +109,15 @@ double a; double w; double t; + int32_t tr; }; struct swappy_state_ui { gboolean panel_toggled; GtkWindow *window; + GtkIMContext *im_context; + GtkWidget *area; GtkToggleButton *panel_toggle_button; @@ -137,8 +143,12 @@ GtkButton *line_size; GtkButton *text_size; + GtkButton *transparency; + GtkButton *transparency_plus; + GtkButton *transparency_minus; GtkToggleButton *fill_shape; + GtkToggleButton *transparent; }; struct swappy_config { @@ -147,9 +157,11 @@ char *save_filename_format; gint8 paint_mode; gboolean fill_shape; + gboolean transparent; gboolean show_panel; guint32 line_size; guint32 text_size; + guint32 transparency; char *text_font; gboolean early_exit; gboolean auto_save; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/meson.build new/swappy-1.8.0/meson.build --- old/swappy-1.7.1/meson.build 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/meson.build 2025-08-27 21:34:53.000000000 +0200 @@ -1,7 +1,7 @@ project( 'swappy', 'c', - version: '1.7.1', + version: '1.8.0', license: 'MIT', meson_version: '>=0.48.0', default_options: [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/package.json new/swappy-1.8.0/package.json --- old/swappy-1.7.1/package.json 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/package.json 2025-08-27 21:34:53.000000000 +0200 @@ -1,6 +1,6 @@ { "name": "swappy", - "version": "1.7.1", + "version": "1.8.0", "repository": { "type": "git", "url": "https://github.com/jtheoof/swappy.git" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/res/swappy.glade new/swappy-1.8.0/res/swappy.glade --- old/swappy-1.7.1/res/swappy.glade 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/res/swappy.glade 2025-08-27 21:34:53.000000000 +0200 @@ -57,6 +57,11 @@ <property name="can_focus">False</property> <property name="icon_name">zoom-out-symbolic</property> </object> + <object class="GtkImage" id="zoom-out2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">zoom-out-symbolic</property> + </object> <object class="GtkApplicationWindow" id="paint-window"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -586,6 +591,76 @@ <object class="GtkBox"> <property name="visible">True</property> <property name="can-focus">False</property> + <property name="margin-bottom">10</property> + <property name="spacing">2</property> + <property name="homogeneous">True</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes">Transparency</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="transparency-minus-button"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="image">zoom-out2</property> + <property name="always-show-image">True</property> + <signal name="clicked" handler="transparency_decrease_handler" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="transparency-button"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="always-show-image">True</property> + <signal name="clicked" handler="transparency_reset_handler" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkButton" id="transparency-plus-button"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="image">zoom-in2</property> + <property name="always-show-image">True</property> + <signal name="clicked" handler="transparency_increase_handler" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">5</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> <property name="homogeneous">True</property> <child> <object class="GtkToggleButton" id="fill-shape-toggle-button"> @@ -604,11 +679,28 @@ <property name="position">1</property> </packing> </child> + <child> + <object class="GtkToggleButton" id="transparent-toggle-button"> + <property name="label" translatable="yes">Transparent</property> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="focus-on-click">False</property> + <property name="receives-default">True</property> + <property name="tooltip-text" translatable="yes">Toggle transparency</property> + <property name="always-show-image">True</property> + <signal name="toggled" handler="transparent_toggled_handler" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">5</property> + <property name="position">6</property> </packing> </child> </object> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/application.c new/swappy-1.8.0/src/application.c --- old/swappy-1.7.1/src/application.c 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/application.c 2025-08-27 21:34:53.000000000 +0200 @@ -2,6 +2,7 @@ #include <glib-2.0/glib.h> #include <glib/gstdio.h> #include <gtk/gtk.h> +#include <inttypes.h> #include <stdio.h> #include <time.h> @@ -36,6 +37,13 @@ gtk_button_set_label(button, label); } +static void update_ui_transparency_widget(struct swappy_state *state) { + GtkButton *button = GTK_BUTTON(state->ui->transparency); + char label[255]; + g_snprintf(label, 255, "%" PRId32, state->settings.tr); + gtk_button_set_label(button, label); +} + static void update_ui_panel_toggle_button(struct swappy_state *state) { GtkWidget *painting_box = GTK_WIDGET(state->ui->painting_box); GtkToggleButton *button = GTK_TOGGLE_BUTTON(state->ui->panel_toggle_button); @@ -52,6 +60,16 @@ gtk_toggle_button_set_active(button, toggled); } +static void update_ui_transparent_toggle_button(struct swappy_state *state) { + GtkToggleButton *button = GTK_TOGGLE_BUTTON(state->ui->transparent); + gboolean toggled = state->config->transparent; + + gtk_toggle_button_set_active(button, toggled); + gtk_widget_set_sensitive(GTK_WIDGET(state->ui->transparency), toggled); + gtk_widget_set_sensitive(GTK_WIDGET(state->ui->transparency_minus), toggled); + gtk_widget_set_sensitive(GTK_WIDGET(state->ui->transparency_plus), toggled); +} + void application_finish(struct swappy_state *state) { g_debug("application finishing, cleaning up"); paint_free_all(state); @@ -68,6 +86,7 @@ g_free(state->file_str); g_free(state->geometry); g_free(state->window); + g_object_unref(state->ui->im_context); g_free(state->ui); g_object_unref(state->app); @@ -215,6 +234,38 @@ update_ui_text_size_widget(state); } +static void action_transparency_decrease(struct swappy_state *state) { + state->settings.tr -= 10; + + if (state->settings.tr < SWAPPY_TRANSPARENCY_MIN) { + state->settings.tr = SWAPPY_TRANSPARENCY_MIN; + } else { + // ceil to 10 + state->settings.tr += 5; + state->settings.tr /= 10; + state->settings.tr *= 10; + } + + update_ui_transparency_widget(state); +} +static void action_transparency_reset(struct swappy_state *state) { + state->settings.tr = state->config->transparency; + update_ui_transparency_widget(state); +} +static void action_transparency_increase(struct swappy_state *state) { + state->settings.tr += 10; + + if (state->settings.tr > SWAPPY_TRANSPARENCY_MAX) { + state->settings.tr = SWAPPY_TRANSPARENCY_MAX; + } else { + // floor to 10 + state->settings.tr /= 10; + state->settings.tr *= 10; + } + + update_ui_transparency_widget(state); +} + static void action_fill_shape_toggle(struct swappy_state *state, gboolean *toggled) { // Don't allow changing the state via a shortcut if the button can't be @@ -227,6 +278,14 @@ update_ui_fill_shape_toggle_button(state); } +static void action_transparent_toggle(struct swappy_state *state, + gboolean *toggled) { + gboolean toggle = (toggled == NULL) ? !state->config->transparent : *toggled; + state->config->transparent = toggle; + + update_ui_transparent_toggle_button(state); +} + static void save_state_to_file_or_folder(struct swappy_state *state, char *file) { GdkPixbuf *pixbuf = pixbuf_get_from_state(state); @@ -245,8 +304,14 @@ } } +// We might need to save twice, once for auto_save config +// and one for the output_file from -o CLI option. static void maybe_save_output_file(struct swappy_state *state) { if (state->config->auto_save) { + save_state_to_file_or_folder(state, NULL); + } + + if (state->output_file) { save_state_to_file_or_folder(state, state->output_file); } } @@ -338,10 +403,34 @@ } } +static void im_context_commit(GtkIMContext *imc, gchar *str, + gpointer user_data) { + struct swappy_state *state = (struct swappy_state *)(user_data); + if (state->temp_paint && state->mode == SWAPPY_PAINT_MODE_TEXT) { + paint_update_temporary_str(state, str); + render_state(state); + return; + } +} + +static void clipboard_paste_selection(struct swappy_state *state) { + GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gchar *text = gtk_clipboard_wait_for_text(clipboard); + if (text) { + paint_update_temporary_str(state, text); + g_free(text); + } +} + void window_keypress_handler(GtkWidget *widget, GdkEventKey *event, struct swappy_state *state) { if (state->temp_paint && state->mode == SWAPPY_PAINT_MODE_TEXT) { - paint_update_temporary_text(state, event); + /* ctrl-v: paste */ + if (event->state & GDK_CONTROL_MASK && event->keyval == GDK_KEY_v) { + clipboard_paste_selection(state); + } else { + paint_update_temporary_text(state, event); + } render_state(state); return; } @@ -380,15 +469,18 @@ switch_mode_to_brush(state); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->brush), true); break; + case GDK_KEY_e: case GDK_KEY_t: switch_mode_to_text(state); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->text), true); break; + case GDK_KEY_s: case GDK_KEY_r: switch_mode_to_rectangle(state); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->rectangle), true); break; + case GDK_KEY_c: case GDK_KEY_o: switch_mode_to_ellipse(state); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->ellipse), @@ -402,6 +494,7 @@ switch_mode_to_blur(state); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->blur), true); break; + case GDK_KEY_x: case GDK_KEY_k: action_clear(state); break; @@ -437,6 +530,9 @@ case GDK_KEY_f: action_fill_shape_toggle(state, NULL); break; + case GDK_KEY_T: + action_transparent_toggle(state, NULL); + break; default: break; } @@ -641,12 +737,31 @@ action_text_size_increase(state); } +void transparency_decrease_handler(GtkWidget *widget, + struct swappy_state *state) { + action_transparency_decrease(state); +} +void transparency_reset_handler(GtkWidget *widget, struct swappy_state *state) { + action_transparency_reset(state); +} +void transparency_increase_handler(GtkWidget *widget, + struct swappy_state *state) { + action_transparency_increase(state); +} + void fill_shape_toggled_handler(GtkWidget *widget, struct swappy_state *state) { GtkToggleButton *button = GTK_TOGGLE_BUTTON(widget); gboolean toggled = gtk_toggle_button_get_active(button); action_fill_shape_toggle(state, &toggled); } +void transparent_toggled_handler(GtkWidget *widget, + struct swappy_state *state) { + GtkToggleButton *button = GTK_TOGGLE_BUTTON(widget); + gboolean toggled = gtk_toggle_button_get_active(button); + action_transparent_toggle(state, &toggled); +} + static void compute_window_size_and_scaling_factor(struct swappy_state *state) { GdkRectangle workarea = {0}; GdkDisplay *display = gdk_display_get_default(); @@ -741,6 +856,12 @@ GtkWindow *window = GTK_WINDOW(gtk_builder_get_object(builder, "paint-window")); + GtkIMContext *im_context = gtk_im_multicontext_new(); + gtk_im_context_set_client_window(im_context, + gtk_widget_get_window(GTK_WIDGET(window))); + g_signal_connect(G_OBJECT(im_context), "commit", + G_CALLBACK(im_context_commit), state); + state->ui->im_context = im_context; g_signal_connect(window, "destroy", G_CALLBACK(on_destroy), state); @@ -783,12 +904,20 @@ GTK_BUTTON(gtk_builder_get_object(builder, "stroke-size-button")); state->ui->text_size = GTK_BUTTON(gtk_builder_get_object(builder, "text-size-button")); + state->ui->transparency = + GTK_BUTTON(gtk_builder_get_object(builder, "transparency-button")); + state->ui->transparency_plus = + GTK_BUTTON(gtk_builder_get_object(builder, "transparency-plus-button")); + state->ui->transparency_minus = + GTK_BUTTON(gtk_builder_get_object(builder, "transparency-minus-button")); state->ui->fill_shape = GTK_TOGGLE_BUTTON( gtk_builder_get_object(builder, "fill-shape-toggle-button")); gdk_rgba_parse(&color, state->config->custom_color); gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(state->ui->color), &color); + state->ui->transparent = GTK_TOGGLE_BUTTON( + gtk_builder_get_object(builder, "transparent-toggle-button")); state->ui->brush = brush; state->ui->text = text; @@ -859,9 +988,11 @@ update_ui_stroke_size_widget(state); update_ui_text_size_widget(state); + update_ui_transparency_widget(state); update_ui_undo_redo(state); update_ui_panel_toggle_button(state); update_ui_fill_shape_toggle_button(state); + update_ui_transparent_toggle_button(state); return true; } @@ -881,6 +1012,7 @@ state->settings.a = 1; state->settings.w = state->config->line_size; state->settings.t = state->config->text_size; + state->settings.tr = state->config->transparency; state->mode = state->config->paint_mode; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/config.c new/swappy-1.8.0/src/config.c --- old/swappy-1.7.1/src/config.c 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/config.c 2025-08-27 21:34:53.000000000 +0200 @@ -19,11 +19,13 @@ g_info("line_size: %d", config->line_size); g_info("text_font: %s", config->text_font); g_info("text_size: %d", config->text_size); + g_info("transparency: %d", config->transparency); g_info("paint_mode: %d", config->paint_mode); g_info("early_exit: %d", config->early_exit); g_info("fill_shape: %d", config->fill_shape); g_info("auto_save: %d", config->auto_save); g_info("custom_color: %s", config->custom_color); + g_info("transparent: %d", config->transparent); } static char *get_default_save_dir() { @@ -79,12 +81,14 @@ gboolean show_panel; gchar *save_dir_expanded = NULL; guint64 line_size, text_size; + guint64 transparency; gchar *text_font = NULL; gchar *paint_mode = NULL; gboolean early_exit; gboolean fill_shape; gboolean auto_save; gchar *custom_color = NULL; + gboolean transparent; GError *error = NULL; if (file == NULL) { @@ -180,6 +184,23 @@ error = NULL; } + transparency = g_key_file_get_uint64(gkf, group, "transparency", &error); + + if (error == NULL) { + if (transparency >= SWAPPY_TRANSPARENCY_MIN && + transparency <= SWAPPY_TRANSPARENCY_MAX) { + config->transparency = transparency; + } else { + g_warning("transparency is not a valid value: %" PRIu64 + " - see man page for details", + transparency); + } + } else { + g_info("transparency is missing in %s (%s)", file, error->message); + g_error_free(error); + error = NULL; + } + show_panel = g_key_file_get_boolean(gkf, group, "show_panel", &error); if (error == NULL) { @@ -256,6 +277,16 @@ error = NULL; } + transparent = g_key_file_get_boolean(gkf, group, "transparent", &error); + + if (error == NULL) { + config->transparent = transparent; + } else { + g_info("transparent is missing in %s (%s)", file, error->message); + g_error_free(error); + error = NULL; + } + g_key_file_free(gkf); } @@ -275,6 +306,8 @@ config->fill_shape = CONFIG_FILL_SHAPE_DEFAULT; config->auto_save = CONFIG_AUTO_SAVE_DEFAULT; config->custom_color = g_strdup(CONFIG_CUSTOM_COLOR_DEFAULT); + config->transparent = CONFIG_TRANSPARENT_DEFAULT; + config->transparency = CONFIG_TRANSPARENCY_DEFAULT; } void config_load(struct swappy_state *state) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/paint.c new/swappy-1.8.0/src/paint.c --- old/swappy-1.7.1/src/paint.c 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/paint.c 2025-08-27 21:34:53.000000000 +0200 @@ -1,7 +1,9 @@ #include "paint.h" #include <glib.h> +#include <stdio.h> +#include "gtk/gtk.h" #include "util.h" static void cursor_move_backward(struct swappy_paint_text *text) { @@ -68,6 +70,8 @@ double w = state->settings.w; double t = state->settings.t; + if (state->config->transparent) a *= (1 - state->settings.tr / 100.0); + paint->type = type; paint->is_committed = false; @@ -192,6 +196,22 @@ } } +void paint_update_temporary_str(struct swappy_state *state, char *str) { + struct swappy_paint *paint = state->temp_paint; + struct swappy_paint_text *text; + char *new_text; + if (!paint || paint->type != SWAPPY_PAINT_MODE_TEXT) { + g_warning("trying to update text but not in text mode"); + return; + } + + text = &paint->content.text; + new_text = string_insert_chars_at(text->text, str, text->cursor); + g_free(text->text); + text->text = new_text; + text->cursor += g_utf8_strlen(str, -1); +} + void paint_update_temporary_text(struct swappy_state *state, GdkEventKey *event) { struct swappy_paint *paint = state->temp_paint; @@ -232,6 +252,9 @@ case GDK_KEY_Right: cursor_move_forward(text); break; + case GDK_KEY_V: + cursor_move_forward(text); + break; default: unicode = gdk_keyval_to_unicode(event->keyval); if (unicode != 0) { @@ -260,6 +283,7 @@ paint->can_draw = true; paint->content.text.to.x = x; paint->content.text.to.y = y; + gtk_im_context_focus_in(state->ui->im_context); } void paint_commit_temporary(struct swappy_state *state) { @@ -287,6 +311,7 @@ state->paints = g_list_prepend(state->paints, paint); } + gtk_im_context_focus_out(state->ui->im_context); // Set the temporary paint to NULL but keep the content in memory // because it's now part of the GList. state->temp_paint = NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/pixbuf.c new/swappy-1.8.0/src/pixbuf.c --- old/swappy-1.7.1/src/pixbuf.c 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/pixbuf.c 2025-08-27 21:34:53.000000000 +0200 @@ -93,8 +93,7 @@ GdkPixbuf *image = state->original_image; gtk_widget_get_allocation(widget, alloc); - gboolean has_alpha = gdk_pixbuf_get_has_alpha(image); - cairo_format_t format = has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24; + cairo_format_t format = CAIRO_FORMAT_ARGB32; gint image_width = gdk_pixbuf_get_width(image); gint image_height = gdk_pixbuf_get_height(image); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/po/de.po new/swappy-1.8.0/src/po/de.po --- old/swappy-1.7.1/src/po/de.po 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/po/de.po 2025-08-27 21:34:53.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: swappy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-18 16:07-0500\n" +"POT-Creation-Date: 2024-11-06 23:00+0100\n" "PO-Revision-Date: 2020-11-19 18:03+0300\n" "Last-Translator: Brodi <m...@brodi.ml>\n" "Language-Team: none\n" @@ -17,42 +17,54 @@ "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: res/swappy.glade:456 +#: res/swappy.glade:461 msgid "Line Width" msgstr "Linienstärke" -#: res/swappy.glade:526 +#: res/swappy.glade:531 msgid "Text Size" msgstr "Textgröße" -#: res/swappy.glade:592 +#: res/swappy.glade:601 +msgid "Transparency" +msgstr "" + +#: res/swappy.glade:667 msgid "Fill shape" msgstr "" -#: res/swappy.glade:597 +#: res/swappy.glade:672 msgid "Toggle shape filling" msgstr "" -#: res/swappy.glade:671 +#: res/swappy.glade:684 +msgid "Transparent" +msgstr "" + +#: res/swappy.glade:689 +msgid "Toggle transparency" +msgstr "" + +#: res/swappy.glade:763 msgid "Toggle Paint Panel" msgstr "Farbtafel umschalten" -#: res/swappy.glade:697 +#: res/swappy.glade:789 msgid "Undo Last Paint" msgstr "Letzte Bemalung rückgängig machen" -#: res/swappy.glade:716 +#: res/swappy.glade:808 msgid "Redo Previous Paint" msgstr "Vorherige Bemalung wiederherstellen" -#: res/swappy.glade:735 +#: res/swappy.glade:827 msgid "Clear Paints" msgstr "Bemalung löschen" -#: res/swappy.glade:763 +#: res/swappy.glade:855 msgid "Copy Surface" msgstr "Fläche kopieren" -#: res/swappy.glade:779 +#: res/swappy.glade:871 msgid "Save Surface" msgstr "Fläche speichern" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/po/en.po new/swappy-1.8.0/src/po/en.po --- old/swappy-1.7.1/src/po/en.po 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/po/en.po 2025-08-27 21:34:53.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: swappy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-18 16:07-0500\n" +"POT-Creation-Date: 2024-11-06 23:00+0100\n" "PO-Revision-Date: 2020-06-21 21:57-0400\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,42 +17,54 @@ "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: res/swappy.glade:456 +#: res/swappy.glade:461 msgid "Line Width" msgstr "Line Width" -#: res/swappy.glade:526 +#: res/swappy.glade:531 msgid "Text Size" msgstr "Text Size" -#: res/swappy.glade:592 +#: res/swappy.glade:601 +msgid "Transparency" +msgstr "" + +#: res/swappy.glade:667 msgid "Fill shape" msgstr "Fill shape" -#: res/swappy.glade:597 +#: res/swappy.glade:672 msgid "Toggle shape filling" msgstr "Toggle shape filling" -#: res/swappy.glade:671 +#: res/swappy.glade:684 +msgid "Transparent" +msgstr "" + +#: res/swappy.glade:689 +msgid "Toggle transparency" +msgstr "" + +#: res/swappy.glade:763 msgid "Toggle Paint Panel" msgstr "Toggle Paint Panel" -#: res/swappy.glade:697 +#: res/swappy.glade:789 msgid "Undo Last Paint" msgstr "Undo Last Paint" -#: res/swappy.glade:716 +#: res/swappy.glade:808 msgid "Redo Previous Paint" msgstr "Redo Previous Paint" -#: res/swappy.glade:735 +#: res/swappy.glade:827 msgid "Clear Paints" msgstr "Clear Paints" -#: res/swappy.glade:763 +#: res/swappy.glade:855 msgid "Copy Surface" msgstr "Copy Surface" -#: res/swappy.glade:779 +#: res/swappy.glade:871 msgid "Save Surface" msgstr "Save Surface" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/po/fr.po new/swappy-1.8.0/src/po/fr.po --- old/swappy-1.7.1/src/po/fr.po 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/po/fr.po 2025-08-27 21:34:53.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: swappy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-18 16:07-0500\n" +"POT-Creation-Date: 2024-11-06 23:00+0100\n" "PO-Revision-Date: 2021-02-20 21:00-0500\n" "Last-Translator: Jeremy Attali <cont...@jtheoof.me>\n" "Language-Team: none\n" @@ -17,42 +17,54 @@ "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: res/swappy.glade:456 +#: res/swappy.glade:461 msgid "Line Width" msgstr "Epaisseur de ligne" -#: res/swappy.glade:526 +#: res/swappy.glade:531 msgid "Text Size" msgstr "Taille du texte" -#: res/swappy.glade:592 +#: res/swappy.glade:601 +msgid "Transparency" +msgstr "" + +#: res/swappy.glade:667 msgid "Fill shape" msgstr "Remplir la forme" -#: res/swappy.glade:597 +#: res/swappy.glade:672 msgid "Toggle shape filling" msgstr "Activer/Désactiver le remplissage de forme" -#: res/swappy.glade:671 +#: res/swappy.glade:684 +msgid "Transparent" +msgstr "" + +#: res/swappy.glade:689 +msgid "Toggle transparency" +msgstr "" + +#: res/swappy.glade:763 msgid "Toggle Paint Panel" msgstr "Afficher/Cacher le panneau de peinture" -#: res/swappy.glade:697 +#: res/swappy.glade:789 msgid "Undo Last Paint" msgstr "Annuler la dernière peinture" -#: res/swappy.glade:716 +#: res/swappy.glade:808 msgid "Redo Previous Paint" msgstr "Rétablir la dernière peinture" -#: res/swappy.glade:735 +#: res/swappy.glade:827 msgid "Clear Paints" msgstr "Supprimer les peintures" -#: res/swappy.glade:763 +#: res/swappy.glade:855 msgid "Copy Surface" msgstr "Copier la surface" -#: res/swappy.glade:779 +#: res/swappy.glade:871 msgid "Save Surface" msgstr "Sauvegarder la surface" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/po/pt_BR.po new/swappy-1.8.0/src/po/pt_BR.po --- old/swappy-1.7.1/src/po/pt_BR.po 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/po/pt_BR.po 2025-08-27 21:34:53.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: swappy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-18 16:07-0500\n" +"POT-Creation-Date: 2024-11-06 23:00+0100\n" "PO-Revision-Date: 2021-02-14 20:38-0300\n" "Last-Translator: Gustavo Costa <xfgu...@gmail.com>\n" "Language-Team: \n" @@ -18,42 +18,54 @@ "X-Generator: Poedit 2.4.2\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: res/swappy.glade:456 +#: res/swappy.glade:461 msgid "Line Width" msgstr "Espessura da linha" -#: res/swappy.glade:526 +#: res/swappy.glade:531 msgid "Text Size" msgstr "Tamanho do texto" -#: res/swappy.glade:592 +#: res/swappy.glade:601 +msgid "Transparency" +msgstr "" + +#: res/swappy.glade:667 msgid "Fill shape" msgstr "" -#: res/swappy.glade:597 +#: res/swappy.glade:672 msgid "Toggle shape filling" msgstr "" -#: res/swappy.glade:671 +#: res/swappy.glade:684 +msgid "Transparent" +msgstr "" + +#: res/swappy.glade:689 +msgid "Toggle transparency" +msgstr "" + +#: res/swappy.glade:763 msgid "Toggle Paint Panel" msgstr "Alternar painel de pintura" -#: res/swappy.glade:697 +#: res/swappy.glade:789 msgid "Undo Last Paint" msgstr "Desfazer última pintura" -#: res/swappy.glade:716 +#: res/swappy.glade:808 msgid "Redo Previous Paint" msgstr "Refazer pintura anterior" -#: res/swappy.glade:735 +#: res/swappy.glade:827 msgid "Clear Paints" msgstr "Limpar pinturas" -#: res/swappy.glade:763 +#: res/swappy.glade:855 msgid "Copy Surface" msgstr "Copiar superfície" -#: res/swappy.glade:779 +#: res/swappy.glade:871 msgid "Save Surface" msgstr "Salvar superfície" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/po/swappy.pot new/swappy-1.8.0/src/po/swappy.pot --- old/swappy-1.7.1/src/po/swappy.pot 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/po/swappy.pot 2025-08-27 21:34:53.000000000 +0200 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: swappy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-18 16:07-0500\n" +"POT-Creation-Date: 2024-11-06 23:00+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <l...@li.org>\n" @@ -17,42 +17,54 @@ "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: res/swappy.glade:456 +#: res/swappy.glade:461 msgid "Line Width" msgstr "" -#: res/swappy.glade:526 +#: res/swappy.glade:531 msgid "Text Size" msgstr "" -#: res/swappy.glade:592 +#: res/swappy.glade:601 +msgid "Transparency" +msgstr "" + +#: res/swappy.glade:667 msgid "Fill shape" msgstr "" -#: res/swappy.glade:597 +#: res/swappy.glade:672 msgid "Toggle shape filling" msgstr "" -#: res/swappy.glade:671 +#: res/swappy.glade:684 +msgid "Transparent" +msgstr "" + +#: res/swappy.glade:689 +msgid "Toggle transparency" +msgstr "" + +#: res/swappy.glade:763 msgid "Toggle Paint Panel" msgstr "" -#: res/swappy.glade:697 +#: res/swappy.glade:789 msgid "Undo Last Paint" msgstr "" -#: res/swappy.glade:716 +#: res/swappy.glade:808 msgid "Redo Previous Paint" msgstr "" -#: res/swappy.glade:735 +#: res/swappy.glade:827 msgid "Clear Paints" msgstr "" -#: res/swappy.glade:763 +#: res/swappy.glade:855 msgid "Copy Surface" msgstr "" -#: res/swappy.glade:779 +#: res/swappy.glade:871 msgid "Save Surface" msgstr "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/po/tr.po new/swappy-1.8.0/src/po/tr.po --- old/swappy-1.7.1/src/po/tr.po 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/po/tr.po 2025-08-27 21:34:53.000000000 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: swappy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-18 16:07-0500\n" +"POT-Creation-Date: 2024-11-06 23:00+0100\n" "PO-Revision-Date: 2022-11-25 10:36+0300\n" "Last-Translator: Oğuz Ersen <o...@ersen.moe>\n" "Language-Team: Turkish <tr>\n" @@ -17,42 +17,54 @@ "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: res/swappy.glade:456 +#: res/swappy.glade:461 msgid "Line Width" msgstr "Çizgi Genişliği" -#: res/swappy.glade:526 +#: res/swappy.glade:531 msgid "Text Size" msgstr "Metin Boyutu" -#: res/swappy.glade:592 +#: res/swappy.glade:601 +msgid "Transparency" +msgstr "" + +#: res/swappy.glade:667 msgid "Fill shape" msgstr "Şekli Doldur" -#: res/swappy.glade:597 +#: res/swappy.glade:672 msgid "Toggle shape filling" msgstr "Şekil Doldurmayı Aç/Kapat" -#: res/swappy.glade:671 +#: res/swappy.glade:684 +msgid "Transparent" +msgstr "" + +#: res/swappy.glade:689 +msgid "Toggle transparency" +msgstr "" + +#: res/swappy.glade:763 msgid "Toggle Paint Panel" msgstr "Boyama Panelini Aç/Kapat" -#: res/swappy.glade:697 +#: res/swappy.glade:789 msgid "Undo Last Paint" msgstr "Son Boyamayı Geri Al" -#: res/swappy.glade:716 +#: res/swappy.glade:808 msgid "Redo Previous Paint" msgstr "Önceki Boyamayı Tekrarla" -#: res/swappy.glade:735 +#: res/swappy.glade:827 msgid "Clear Paints" msgstr "Boyamaları Temizle" -#: res/swappy.glade:763 +#: res/swappy.glade:855 msgid "Copy Surface" msgstr "Yüzeyi Kopyala" -#: res/swappy.glade:779 +#: res/swappy.glade:871 msgid "Save Surface" msgstr "Yüzeyi Kaydet" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/po/zh_CN.po new/swappy-1.8.0/src/po/zh_CN.po --- old/swappy-1.7.1/src/po/zh_CN.po 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/po/zh_CN.po 2025-08-27 21:34:53.000000000 +0200 @@ -1,4 +1,3 @@ - # English translations for swappy package. # Copyright (C) 2020 THE swappy'S COPYRIGHT HOLDER # This file is distributed under the same license as the swappy package. @@ -8,7 +7,7 @@ msgstr "" "Project-Id-Version: swappy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-18 16:07-0500\n" +"POT-Creation-Date: 2024-11-06 23:00+0100\n" "PO-Revision-Date: 2020-06-21 21:57-0400\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -18,42 +17,54 @@ "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: res/swappy.glade:456 +#: res/swappy.glade:461 msgid "Line Width" msgstr "行宽" -#: res/swappy.glade:526 +#: res/swappy.glade:531 msgid "Text Size" msgstr "文本大小" -#: res/swappy.glade:592 +#: res/swappy.glade:601 +msgid "Transparency" +msgstr "" + +#: res/swappy.glade:667 msgid "Fill shape" msgstr "填充" -#: res/swappy.glade:597 +#: res/swappy.glade:672 msgid "Toggle shape filling" msgstr "切换填充状态" -#: res/swappy.glade:671 +#: res/swappy.glade:684 +msgid "Transparent" +msgstr "" + +#: res/swappy.glade:689 +msgid "Toggle transparency" +msgstr "" + +#: res/swappy.glade:763 msgid "Toggle Paint Panel" msgstr "切换绘图板状态" -#: res/swappy.glade:697 +#: res/swappy.glade:789 msgid "Undo Last Paint" msgstr "撤销" -#: res/swappy.glade:716 +#: res/swappy.glade:808 msgid "Redo Previous Paint" msgstr "恢复" -#: res/swappy.glade:735 +#: res/swappy.glade:827 msgid "Clear Paints" msgstr "清除绘图" -#: res/swappy.glade:763 +#: res/swappy.glade:855 msgid "Copy Surface" msgstr "复制" -#: res/swappy.glade:779 +#: res/swappy.glade:871 msgid "Save Surface" msgstr "保存" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/render.c new/swappy-1.8.0/src/render.c --- old/swappy-1.7.1/src/render.c 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/render.c 2025-08-27 21:34:53.000000000 +0200 @@ -179,7 +179,8 @@ box->height = pango_units_to_double(rectangle.height); } -static void render_text(cairo_t *cr, struct swappy_paint_text text) { +static void render_text(cairo_t *cr, struct swappy_paint_text text, + struct swappy_state *state) { char pango_font[255]; double x = fmin(text.from.x, text.to.x); double y = fmin(text.from.y, text.to.y); @@ -214,6 +215,9 @@ cairo_set_source_rgba(crt, 0.3, 0.3, 0.3, 1); cairo_line_to(crt, cursor_box.x, cursor_box.y + cursor_box.height); cairo_stroke(crt); + GdkRectangle area = {x + cursor_box.x, y + cursor_box.y + cursor_box.height, + 0, 0}; + gtk_im_context_set_cursor_location(state->ui->im_context, &area); } cairo_rectangle(crt, 0, 0, w, h); @@ -473,7 +477,8 @@ cairo_restore(cr); } -static void render_paint(cairo_t *cr, struct swappy_paint *paint) { +static void render_paint(cairo_t *cr, struct swappy_paint *paint, + struct swappy_state *state) { if (!paint->can_draw) { return; } @@ -490,7 +495,7 @@ render_shape(cr, paint->content.shape); break; case SWAPPY_PAINT_MODE_TEXT: - render_text(cr, paint->content.text); + render_text(cr, paint->content.text, state); break; default: g_info("unable to render paint with type: %d", paint->type); @@ -501,11 +506,11 @@ static void render_paints(cairo_t *cr, struct swappy_state *state) { for (GList *elem = g_list_last(state->paints); elem; elem = elem->prev) { struct swappy_paint *paint = elem->data; - render_paint(cr, paint); + render_paint(cr, paint, state); } if (state->temp_paint) { - render_paint(cr, state->temp_paint); + render_paint(cr, state->temp_paint, state); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/src/util.c new/swappy-1.8.0/src/util.c --- old/swappy-1.7.1/src/util.c 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/src/util.c 2025-08-27 21:34:53.000000000 +0200 @@ -5,6 +5,7 @@ gchar *string_remove_at(gchar *str, glong pos) { glong str_len = strlen(str); + glong ustr_len = g_utf8_strlen(str, -1); gchar *new_str = g_new0(gchar, MAX(str_len, 1)); gchar *buffer_source = str; gchar *buffer_copy = new_str; @@ -12,7 +13,7 @@ gint bytes; gunichar c; - if (pos <= str_len && g_utf8_validate(str, -1, NULL)) { + if (pos <= ustr_len && g_utf8_validate(str, -1, NULL)) { while (*buffer_source != '\0') { c = g_utf8_get_char(buffer_source); buffer_source = g_utf8_next_char(buffer_source); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/swappy-1.7.1/swappy.1.scd new/swappy-1.8.0/swappy.1.scd --- old/swappy-1.7.1/swappy.1.scd 2025-08-18 04:00:10.000000000 +0200 +++ new/swappy-1.8.0/swappy.1.scd 2025-08-27 21:34:53.000000000 +0200 @@ -68,6 +68,8 @@ fill_shape=false auto_save=false custom_color=rgba(192,125,17,1) + transparent=false + transparency=50 ``` - *save_dir* is where swappshots will be saved, can contain env variables, when it does not exist, swappy attempts to create it first, but does not abort if directory creation fails @@ -82,6 +84,8 @@ - *auto_save* is used to toggle auto saving of final buffer to *save_dir* upon exit - *custom_color* is used to set a default value for the custom color. Accepted formats are: standard name (one of: https://github.com/rgb-x/system/blob/master/root/etc/X11/rgb.txt), #rgb, #rrggbb, #rrrgggbbb, #rrrrggggbbbb, rgb(r,b,g), rgba(r,g,b,a) +- *transparency* is used to set transparency of everything that is drawn during startup +- *transparent* is used to toggle transparency during startup # KEY BINDINGS @@ -93,9 +97,9 @@ ## PAINT MODE - *b*: Switch to Brush -- *t*: Switch to Text -- *r*: Switch to Rectangle -- *o*: Switch to Ellipse +- `e` `t`: Switch to Text (Editor) +- `r` `s`: Switch to Rectangle (Square) +- `c` `o`: Switch to Ellipse (Circle) - *a*: Switch to Arrow - *d*: Switch to Blur (d stands for droplet) @@ -107,7 +111,8 @@ - *Plus*: Increase Stroke Size - *Equal*: Reset Stroke Size - *f*: Toggle Shape Filling -- *k*: Clear Paints (cannot be undone) +- *T*: Toggle Transparency +- `x` `k`: Clear Paints (cannot be undone) ## MODIFIERS