mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-05 07:15:30 -04:00
selection: implement copy *to* primary
This commit is contained in:
parent
703aeecb95
commit
66e067082b
3 changed files with 91 additions and 8 deletions
2
input.c
2
input.c
|
|
@ -369,7 +369,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
if (button == BTN_LEFT && term->selection.end.col == -1)
|
if (button == BTN_LEFT && term->selection.end.col == -1)
|
||||||
selection_cancel(term);
|
selection_cancel(term);
|
||||||
else
|
else
|
||||||
selection_finalize(term);
|
selection_finalize(term, serial);
|
||||||
|
|
||||||
term->mouse.button = 0; /* For motion events */
|
term->mouse.button = 0; /* For motion events */
|
||||||
term_mouse_up(term, button, term->mouse.row, term->mouse.col,
|
term_mouse_up(term, button, term->mouse.row, term->mouse.col,
|
||||||
|
|
|
||||||
95
selection.c
95
selection.c
|
|
@ -133,8 +133,10 @@ selection_update(struct terminal *term, int col, int row)
|
||||||
grid_render(term);
|
grid_render(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener;
|
||||||
|
|
||||||
void
|
void
|
||||||
selection_finalize(struct terminal *term)
|
selection_finalize(struct terminal *term, uint32_t serial)
|
||||||
{
|
{
|
||||||
if (!selection_enabled(term))
|
if (!selection_enabled(term))
|
||||||
return;
|
return;
|
||||||
|
|
@ -145,11 +147,43 @@ selection_finalize(struct terminal *term)
|
||||||
assert(term->selection.start.row != -1);
|
assert(term->selection.start.row != -1);
|
||||||
assert(term->selection.end.row != -1);
|
assert(term->selection.end.row != -1);
|
||||||
|
|
||||||
/* Kill old primary selection */
|
/* TODO: somehow share code with the clipboard equivalent */
|
||||||
free(term->selection.primary.text);
|
if (term->selection.primary.data_source != NULL) {
|
||||||
|
/* Kill previous data source */
|
||||||
|
struct primary *primary = &term->selection.primary;
|
||||||
|
|
||||||
/* TODO: primary data source */
|
assert(primary->serial != 0);
|
||||||
term->selection.primary.text = extract_selection(term);
|
zwp_primary_selection_device_v1_set_selection(
|
||||||
|
term->wl.primary_selection_device, NULL, primary->serial);
|
||||||
|
zwp_primary_selection_source_v1_destroy(primary->data_source);
|
||||||
|
free(primary->text);
|
||||||
|
|
||||||
|
primary->data_source = NULL;
|
||||||
|
primary->serial = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct primary *primary = &term->selection.primary;
|
||||||
|
|
||||||
|
primary->data_source
|
||||||
|
= zwp_primary_selection_device_manager_v1_create_source(
|
||||||
|
term->wl.primary_selection_device_manager);
|
||||||
|
|
||||||
|
if (primary->data_source == NULL) {
|
||||||
|
LOG_ERR("failed to create clipboard data source");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get selection as a string */
|
||||||
|
primary->text = extract_selection(term);
|
||||||
|
|
||||||
|
/* Configure source */
|
||||||
|
zwp_primary_selection_source_v1_offer(primary->data_source, "text/plain;charset=utf-8");
|
||||||
|
zwp_primary_selection_source_v1_add_listener(primary->data_source, &primary_selection_source_listener, term);
|
||||||
|
zwp_primary_selection_device_v1_set_selection(term->wl.primary_selection_device, primary->data_source, serial);
|
||||||
|
zwp_primary_selection_source_v1_set_user_data(primary->data_source, primary);
|
||||||
|
|
||||||
|
/* Needed when sending the selection to other client */
|
||||||
|
primary->serial = serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -251,6 +285,56 @@ static const struct wl_data_source_listener data_source_listener = {
|
||||||
.action = &action,
|
.action = &action,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_send(void *data,
|
||||||
|
struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1,
|
||||||
|
const char *mime_type, int32_t fd)
|
||||||
|
{
|
||||||
|
const struct primary *primary
|
||||||
|
= zwp_primary_selection_source_v1_get_user_data(zwp_primary_selection_source_v1);
|
||||||
|
|
||||||
|
assert(primary != NULL);
|
||||||
|
assert(primary->text != NULL);
|
||||||
|
|
||||||
|
size_t left = strlen(primary->text);
|
||||||
|
size_t idx = 0;
|
||||||
|
|
||||||
|
while (left > 0) {
|
||||||
|
ssize_t ret = write(fd, &primary->text[idx], left);
|
||||||
|
|
||||||
|
if (ret == -1 && errno != EINTR) {
|
||||||
|
LOG_ERRNO("failed to write to clipboard");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
left -= ret;
|
||||||
|
idx += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_cancelled(void *data,
|
||||||
|
struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1)
|
||||||
|
{
|
||||||
|
struct primary *primary = zwp_primary_selection_source_v1_get_user_data(
|
||||||
|
zwp_primary_selection_source_v1);
|
||||||
|
//assert(primary->data_source == zwp_primary_selection_source_v1);
|
||||||
|
|
||||||
|
zwp_primary_selection_source_v1_destroy(primary->data_source);
|
||||||
|
primary->data_source = NULL;
|
||||||
|
primary->serial = 0;
|
||||||
|
|
||||||
|
free(primary->text);
|
||||||
|
primary->text = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = {
|
||||||
|
.send = &primary_send,
|
||||||
|
.cancelled = &primary_cancelled,
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
selection_to_clipboard(struct terminal *term, uint32_t serial)
|
selection_to_clipboard(struct terminal *term, uint32_t serial)
|
||||||
{
|
{
|
||||||
|
|
@ -341,7 +425,6 @@ selection_from_clipboard(struct terminal *term, uint32_t serial)
|
||||||
void
|
void
|
||||||
selection_from_primary(struct terminal *term)
|
selection_from_primary(struct terminal *term)
|
||||||
{
|
{
|
||||||
LOG_WARN("selection from PRIMARY");
|
|
||||||
struct primary *primary = &term->selection.primary;
|
struct primary *primary = &term->selection.primary;
|
||||||
if (primary->data_offer == NULL)
|
if (primary->data_offer == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ extern const struct zwp_primary_selection_device_v1_listener primary_selection_d
|
||||||
|
|
||||||
void selection_start(struct terminal *term, int col, int row);
|
void selection_start(struct terminal *term, int col, int row);
|
||||||
void selection_update(struct terminal *term, int col, int row);
|
void selection_update(struct terminal *term, int col, int row);
|
||||||
void selection_finalize(struct terminal *term);
|
void selection_finalize(struct terminal *term, uint32_t serial);
|
||||||
void selection_cancel(struct terminal *term);
|
void selection_cancel(struct terminal *term);
|
||||||
|
|
||||||
void selection_to_clipboard(struct terminal *term, uint32_t serial);
|
void selection_to_clipboard(struct terminal *term, uint32_t serial);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue