mirror of
https://github.com/jtheoof/swappy.git
synced 2024-08-16 18:20:45 +03:00
feat(clipboard): use wl-copy if present
This commit is contained in:
parent
f48f36e7fe
commit
51b27d768e
@ -77,7 +77,7 @@ swappy -g "$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .re
|
||||
|
||||
## Limitations
|
||||
|
||||
- **Copy**: 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](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, Paste your Swappshot where you want to before you close the app.
|
||||
- **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.
|
||||
|
||||
## Installation
|
||||
|
||||
@ -118,4 +118,5 @@ MIT
|
||||
[slurp]: https://github.com/emersion/slurp
|
||||
[grim]: https://github.com/emersion/grim
|
||||
[sway]: https://github.com/swaywm/sway
|
||||
[wl-clipboard]: https://github.com/bugaevc/wl-clipboard
|
||||
[wlr-screencopy-unstable-v1]: https://github.com/swaywm/wlr-protocols/blob/master/unstable/wlr-screencopy-unstable-v1.xml
|
||||
|
@ -1,16 +1,80 @@
|
||||
#include "clipboard.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "notification.h"
|
||||
#include "util.h"
|
||||
|
||||
#define gtk_clipboard_t GtkClipboard
|
||||
#define gdk_pixbuf_t GdkPixbuf
|
||||
|
||||
static gboolean send_pixbuf_to_wl_copy(gdk_pixbuf_t *pixbuf) {
|
||||
pid_t clipboard_process = 0;
|
||||
int pipefd[2];
|
||||
int status;
|
||||
gsize size;
|
||||
gchar *buffer = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
if (pipe(pipefd) < 0) {
|
||||
g_warning("unable to pipe for copy process to work");
|
||||
return false;
|
||||
}
|
||||
clipboard_process = fork();
|
||||
if (clipboard_process == -1) {
|
||||
g_warning("unable to fork process for copy");
|
||||
return false;
|
||||
}
|
||||
if (clipboard_process == 0) {
|
||||
close(pipefd[1]);
|
||||
dup2(pipefd[0], STDIN_FILENO);
|
||||
close(pipefd[0]);
|
||||
execlp("wl-copy", "wl-copy", NULL);
|
||||
g_warning(
|
||||
"Unable to copy contents to clipboard. Please make sure you have "
|
||||
"`wl-clipboard`, `xclip`, or `xsel` installed.");
|
||||
exit(1);
|
||||
}
|
||||
close(pipefd[0]);
|
||||
|
||||
gdk_pixbuf_save_to_buffer(pixbuf, &buffer, &size, "png", &error, NULL);
|
||||
|
||||
if (error != NULL) {
|
||||
g_critical("unable to save pixbuf to buffer for copy: %s", error->message);
|
||||
g_error_free(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
write(pipefd[1], buffer, size);
|
||||
close(pipefd[1]);
|
||||
g_free(buffer);
|
||||
waitpid(clipboard_process, &status, 0);
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
return WEXITSTATUS(status) == 0; // Make sure the child exited properly
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void send_pixbuf_to_gdk_clipboard(gdk_pixbuf_t *pixbuf) {
|
||||
gtk_clipboard_t *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
gtk_clipboard_set_image(clipboard, pixbuf);
|
||||
gtk_clipboard_store(clipboard); // Does not work for Wayland gdk backend
|
||||
}
|
||||
|
||||
bool clipboard_copy_drawing_area_to_selection(struct swappy_state *state) {
|
||||
GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
int width = gtk_widget_get_allocated_width(state->ui->area);
|
||||
int height = gtk_widget_get_allocated_height(state->ui->area);
|
||||
GdkPixbuf *pixbuf =
|
||||
gdk_pixbuf_t *pixbuf =
|
||||
gdk_pixbuf_get_from_surface(state->cairo_surface, 0, 0, width, height);
|
||||
|
||||
gtk_clipboard_set_image(clipboard, pixbuf);
|
||||
gtk_clipboard_store(clipboard);
|
||||
// Try `wl-copy` first and fall back to gtk function. See README.md.
|
||||
if (!send_pixbuf_to_wl_copy(pixbuf)) {
|
||||
send_pixbuf_to_gdk_clipboard(pixbuf);
|
||||
}
|
||||
|
||||
char message[MAX_PATH];
|
||||
snprintf(message, MAX_PATH, "Swappshot copied to clipboard\n");
|
||||
|
Loading…
Reference in New Issue
Block a user