multi-seat: re-enable selection support (excluding OSC 52)

This commit is contained in:
Daniel Eklöf 2020-07-08 18:41:09 +02:00
parent 04e566492c
commit 4c7d29f7eb
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 104 additions and 109 deletions

31
input.c
View file

@ -33,8 +33,8 @@
#include "vt.h"
static void
execute_binding(struct terminal *term, enum bind_action_normal action,
uint32_t serial)
execute_binding(struct seat *seat, struct terminal *term,
enum bind_action_normal action, uint32_t serial)
{
switch (action) {
case BIND_ACTION_NONE:
@ -49,16 +49,16 @@ execute_binding(struct terminal *term, enum bind_action_normal action,
break;
case BIND_ACTION_CLIPBOARD_COPY:
selection_to_clipboard(term, serial);
selection_to_clipboard(seat, term, serial);
break;
case BIND_ACTION_CLIPBOARD_PASTE:
selection_from_clipboard(term, serial);
selection_from_clipboard(seat, term, serial);
term_reset_view(term);
break;
case BIND_ACTION_PRIMARY_PASTE:
selection_from_primary(term);
selection_from_primary(seat, term);
break;
case BIND_ACTION_SEARCH_START:
@ -580,14 +580,14 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
/* Match symbol */
if (it->item.bind.sym == sym) {
execute_binding(term, it->item.action, serial);
execute_binding(seat, term, it->item.action, serial);
goto maybe_repeat;
}
/* Match raw key code */
tll_foreach(it->item.bind.key_codes, code) {
if (code->item == key) {
execute_binding(term, it->item.action, serial);
execute_binding(seat, term, it->item.action, serial);
goto maybe_repeat;
}
}
@ -1197,20 +1197,23 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
break;
case 2:
selection_mark_word(term, seat->mouse.col, seat->mouse.row,
seat->kbd.ctrl, serial);
selection_mark_word(
seat, term, seat->mouse.col, seat->mouse.row,
seat->kbd.ctrl, serial);
break;
case 3:
selection_mark_row(term, seat->mouse.row, serial);
selection_mark_row(seat, term, seat->mouse.row, serial);
break;
}
}
}
else if (button == BTN_RIGHT && seat->mouse.count == 1) {
if (selection_enabled(term))
selection_extend(term, seat->mouse.col, seat->mouse.row, serial);
if (selection_enabled(term)) {
selection_extend(
seat, term, seat->mouse.col, seat->mouse.row, serial);
}
}
else {
@ -1228,7 +1231,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
continue;
}
execute_binding(term, binding->action, serial);
execute_binding(seat, term, binding->action, serial);
break;
}
}
@ -1241,7 +1244,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
case WL_POINTER_BUTTON_STATE_RELEASED:
if (button == BTN_LEFT && term->selection.end.col != -1)
selection_finalize(term, serial);
selection_finalize(seat, term, serial);
term_mouse_up(
term, button, seat->mouse.row, seat->mouse.col,

View file

@ -591,7 +591,8 @@ selection_extend_block(struct terminal *term, int col, int row, uint32_t serial)
}
void
selection_extend(struct terminal *term, int col, int row, uint32_t serial)
selection_extend(struct seat *seat, struct terminal *term,
int col, int row, uint32_t serial)
{
if (term->selection.start.row < 0 || term->selection.end.row < 0) {
/* No existing selection */
@ -621,13 +622,13 @@ selection_extend(struct terminal *term, int col, int row, uint32_t serial)
break;
}
selection_to_primary(term, serial);
selection_to_primary(seat, term, serial);
}
//static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener;
void
selection_finalize(struct terminal *term, uint32_t serial)
selection_finalize(struct seat *seat, struct terminal *term, uint32_t serial)
{
if (term->selection.start.row < 0 || term->selection.end.row < 0)
return;
@ -645,7 +646,7 @@ selection_finalize(struct terminal *term, uint32_t serial)
}
assert(term->selection.start.row <= term->selection.end.row);
selection_to_primary(term, serial);
selection_to_primary(seat, term, serial);
}
void
@ -668,8 +669,8 @@ selection_cancel(struct terminal *term)
}
void
selection_mark_word(struct terminal *term, int col, int row, bool spaces_only,
uint32_t serial)
selection_mark_word(struct seat *seat, struct terminal *term, int col, int row,
bool spaces_only, uint32_t serial)
{
selection_cancel(term);
@ -730,19 +731,19 @@ selection_mark_word(struct terminal *term, int col, int row, bool spaces_only,
selection_start(term, start.col, start.row, SELECTION_NORMAL);
selection_update(term, end.col, end.row);
selection_finalize(term, serial);
selection_finalize(seat, term, serial);
}
void
selection_mark_row(struct terminal *term, int row, uint32_t serial)
selection_mark_row(
struct seat *seat, struct terminal *term, int row, uint32_t serial)
{
selection_start(term, 0, row, SELECTION_NORMAL);
selection_update(term, term->cols - 1, row);
selection_finalize(term, serial);
selection_finalize(seat, term, serial);
}
#if 0
static void
target(void *data, struct wl_data_source *wl_data_source, const char *mime_type)
{
@ -788,8 +789,8 @@ static void
send(void *data, struct wl_data_source *wl_data_source, const char *mime_type,
int32_t fd)
{
struct wayland *wayl = data;
const struct wl_clipboard *clipboard = &wayl->clipboard;
struct seat *seat = data;
const struct wl_clipboard *clipboard = &seat->clipboard;
assert(clipboard != NULL);
assert(clipboard->text != NULL);
@ -817,7 +818,7 @@ send(void *data, struct wl_data_source *wl_data_source, const char *mime_type,
.idx = async_idx,
};
if (fdm_add(wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx))
if (fdm_add(seat->wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx))
return;
free(ctx->data);
@ -841,8 +842,8 @@ send(void *data, struct wl_data_source *wl_data_source, const char *mime_type,
static void
cancelled(void *data, struct wl_data_source *wl_data_source)
{
struct wayland *wayl = data;
struct wl_clipboard *clipboard = &wayl->clipboard;
struct seat *seat = data;
struct wl_clipboard *clipboard = &seat->clipboard;
assert(clipboard->data_source == wl_data_source);
wl_data_source_destroy(clipboard->data_source);
@ -867,9 +868,7 @@ static void
action(void *data, struct wl_data_source *wl_data_source, uint32_t dnd_action)
{
}
#endif
#if 0
static const struct wl_data_source_listener data_source_listener = {
.target = &target,
.send = &send,
@ -878,15 +877,14 @@ static const struct wl_data_source_listener data_source_listener = {
.dnd_finished = &dnd_finished,
.action = &action,
};
#endif
#if 0
static void
primary_send(void *data,
struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1,
const char *mime_type, int32_t fd)
{
struct wayland *wayl = data;
const struct wl_primary *primary = &wayl->primary;
struct seat *seat = data;
const struct wl_primary *primary = &seat->primary;
assert(primary != NULL);
assert(primary->text != NULL);
@ -912,7 +910,7 @@ primary_send(void *data,
.idx = async_idx,
};
if (fdm_add(wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx))
if (fdm_add(seat->wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx))
return;
free(ctx->data);
@ -937,8 +935,8 @@ static void
primary_cancelled(void *data,
struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1)
{
struct wayland *wayl = data;
struct wl_primary *primary = &wayl->primary;
struct seat *seat = data;
struct wl_primary *primary = &seat->primary;
zwp_primary_selection_source_v1_destroy(primary->data_source);
primary->data_source = NULL;
@ -947,24 +945,21 @@ primary_cancelled(void *data,
free(primary->text);
primary->text = NULL;
}
#endif
#if 0
static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = {
.send = &primary_send,
.cancelled = &primary_cancelled,
};
#endif
bool
text_to_clipboard(struct terminal *term, char *text, uint32_t serial)
text_to_clipboard(struct seat *seat, struct terminal *term, char *text, uint32_t serial)
{
#if 0
struct wl_clipboard *clipboard = &term->wl->clipboard;
struct wl_clipboard *clipboard = &seat->clipboard;
if (clipboard->data_source != NULL) {
/* Kill previous data source */
assert(clipboard->serial != 0);
wl_data_device_set_selection(term->wl->data_device, NULL, clipboard->serial);
wl_data_device_set_selection(seat->data_device, NULL, clipboard->serial);
wl_data_source_destroy(clipboard->data_source);
free(clipboard->text);
@ -984,26 +979,24 @@ text_to_clipboard(struct terminal *term, char *text, uint32_t serial)
/* Configure source */
wl_data_source_offer(clipboard->data_source, "text/plain;charset=utf-8");
wl_data_source_add_listener(clipboard->data_source, &data_source_listener, term->wl);
wl_data_device_set_selection(term->wl->data_device, clipboard->data_source, serial);
wl_data_source_add_listener(clipboard->data_source, &data_source_listener, seat);
wl_data_device_set_selection(seat->data_device, clipboard->data_source, serial);
/* Needed when sending the selection to other client */
assert(serial != 0);
clipboard->serial = serial;
return true;
#endif
return false;
}
void
selection_to_clipboard(struct terminal *term, uint32_t serial)
selection_to_clipboard(struct seat *seat, struct terminal *term, uint32_t serial)
{
if (term->selection.start.row < 0 || term->selection.end.row < 0)
return;
/* Get selection as a string */
char *text = extract_selection(term);
if (!text_to_clipboard(term, text, serial))
if (!text_to_clipboard(seat, term, text, serial))
free(text);
}
@ -1014,7 +1007,7 @@ struct clipboard_receive {
void *user;
};
#if 0
static bool
fdm_receive(struct fdm *fdm, int fd, int events, void *data)
{
@ -1064,8 +1057,7 @@ done:
free(ctx);
return true;
}
#endif
#if 0
static void
begin_receive_clipboard(struct terminal *term, int read_fd,
void (*cb)(const char *data, size_t size, void *user),
@ -1093,14 +1085,13 @@ begin_receive_clipboard(struct terminal *term, int read_fd,
done(user);
}
}
#endif
void
text_from_clipboard(struct terminal *term, uint32_t serial,
text_from_clipboard(struct seat *seat, struct terminal *term, uint32_t serial,
void (*cb)(const char *data, size_t size, void *user),
void (*done)(void *user), void *user)
{
#if 0
struct wl_clipboard *clipboard = &term->wl->clipboard;
struct wl_clipboard *clipboard = &seat->clipboard;
if (clipboard->data_offer == NULL)
return done(user);
@ -1122,18 +1113,15 @@ text_from_clipboard(struct terminal *term, uint32_t serial,
close(write_fd);
begin_receive_clipboard(term, read_fd, cb, done, user);
#endif
}
#if 0
static void
from_clipboard_cb(const char *data, size_t size, void *user)
{
struct terminal *term = user;
term_to_slave(term, data, size);
}
#endif
#if 0
static void
from_clipboard_done(void *user)
{
@ -1142,12 +1130,11 @@ from_clipboard_done(void *user)
if (term->bracketed_paste)
term_to_slave(term, "\033[201~", 6);
}
#endif
void
selection_from_clipboard(struct terminal *term, uint32_t serial)
selection_from_clipboard(struct seat *seat, struct terminal *term, uint32_t serial)
{
#if 0
struct wl_clipboard *clipboard = &term->wl->clipboard;
struct wl_clipboard *clipboard = &seat->clipboard;
if (clipboard->data_offer == NULL)
return;
@ -1155,26 +1142,24 @@ selection_from_clipboard(struct terminal *term, uint32_t serial)
term_to_slave(term, "\033[200~", 6);
text_from_clipboard(
term, serial, &from_clipboard_cb, &from_clipboard_done, term);
#endif
seat, term, serial, &from_clipboard_cb, &from_clipboard_done, term);
}
bool
text_to_primary(struct terminal *term, char *text, uint32_t serial)
text_to_primary(struct seat *seat, struct terminal *term, char *text, uint32_t serial)
{
#if 0
if (term->wl->primary_selection_device_manager == NULL)
return false;
struct wl_primary *primary = &term->wl->primary;
struct wl_primary *primary = &seat->primary;
/* TODO: somehow share code with the clipboard equivalent */
if (term->wl->primary.data_source != NULL) {
if (seat->primary.data_source != NULL) {
/* Kill previous data source */
assert(primary->serial != 0);
zwp_primary_selection_device_v1_set_selection(
term->wl->primary_selection_device, NULL, primary->serial);
seat->primary_selection_device, NULL, primary->serial);
zwp_primary_selection_source_v1_destroy(primary->data_source);
free(primary->text);
@ -1196,39 +1181,36 @@ text_to_primary(struct terminal *term, char *text, uint32_t serial)
/* 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->wl);
zwp_primary_selection_device_v1_set_selection(term->wl->primary_selection_device, primary->data_source, serial);
zwp_primary_selection_source_v1_add_listener(primary->data_source, &primary_selection_source_listener, seat);
zwp_primary_selection_device_v1_set_selection(seat->primary_selection_device, primary->data_source, serial);
/* Needed when sending the selection to other client */
primary->serial = serial;
return true;
#endif
return false;
}
void
selection_to_primary(struct terminal *term, uint32_t serial)
selection_to_primary(struct seat *seat, struct terminal *term, uint32_t serial)
{
if (term->wl->primary_selection_device_manager == NULL)
return;
/* Get selection as a string */
char *text = extract_selection(term);
if (!text_to_primary(term, text, serial))
if (!text_to_primary(seat, term, text, serial))
free(text);
}
void
text_from_primary(
struct terminal *term,
struct seat *seat, struct terminal *term,
void (*cb)(const char *data, size_t size, void *user),
void (*done)(void *user), void *user)
{
#if 0
if (term->wl->primary_selection_device_manager == NULL)
return done(user);
struct wl_primary *primary = &term->wl->primary;
struct wl_primary *primary = &seat->primary;
if (primary->data_offer == NULL)
return done(user);
@ -1250,25 +1232,22 @@ text_from_primary(
close(write_fd);
begin_receive_clipboard(term, read_fd, cb, done, user);
#endif
}
void
selection_from_primary(struct terminal *term)
selection_from_primary(struct seat *seat, struct terminal *term)
{
#if 0
if (term->wl->primary_selection_device_manager == NULL)
return;
struct wl_clipboard *clipboard = &term->wl->clipboard;
struct wl_clipboard *clipboard = &seat->clipboard;
if (clipboard->data_offer == NULL)
return;
if (term->bracketed_paste)
term_to_slave(term, "\033[200~", 6);
text_from_primary(term, &from_clipboard_cb, &from_clipboard_done, term);
#endif
text_from_primary(seat, term, &from_clipboard_cb, &from_clipboard_done, term);
}
#if 0
@ -1328,11 +1307,10 @@ static void
selection(void *data, struct wl_data_device *wl_data_device,
struct wl_data_offer *id)
{
#if 0
/* Selection offer from other client */
struct wayland *wayl = data;
struct wl_clipboard *clipboard = &wayl->clipboard;
struct seat *seat = data;
struct wl_clipboard *clipboard = &seat->clipboard;
if (clipboard->data_offer != NULL)
wl_data_offer_destroy(clipboard->data_offer);
@ -1342,7 +1320,6 @@ selection(void *data, struct wl_data_device *wl_data_device,
if (id != NULL)
wl_data_offer_add_listener(id, &data_offer_listener, term);
#endif
#endif
}
const struct wl_data_device_listener data_device_listener = {
@ -1379,11 +1356,10 @@ primary_selection(void *data,
struct zwp_primary_selection_device_v1 *zwp_primary_selection_device,
struct zwp_primary_selection_offer_v1 *id)
{
#if 0
/* Selection offer from other client, for primary */
struct wayland *wayl = data;
struct wl_primary *primary = &wayl->primary;
struct seat *seat = data;
struct wl_primary *primary = &seat->primary;
if (primary->data_offer != NULL)
zwp_primary_selection_offer_v1_destroy(primary->data_offer);
@ -1395,7 +1371,6 @@ primary_selection(void *data,
id, &primary_selection_offer_listener, term);
}
#endif
#endif
}
const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = {

View file

@ -12,28 +12,37 @@ bool selection_enabled(const struct terminal *term);
void selection_start(
struct terminal *term, int col, int row, enum selection_kind kind);
void selection_update(struct terminal *term, int col, int row);
void selection_finalize(struct terminal *term, uint32_t serial);
void selection_finalize(
struct seat *seat, struct terminal *term, uint32_t serial);
void selection_dirty_cells(struct terminal *term);
void selection_cancel(struct terminal *term);
void selection_extend(struct terminal *term, int col, int row, uint32_t serial);
void selection_extend( struct seat *seat, struct terminal *term,
int col, int row, uint32_t serial);
bool selection_on_rows(const struct terminal *term, int start, int end);
void selection_view_up(struct terminal *term, int new_view);
void selection_view_down(struct terminal *term, int new_view);
void selection_mark_word(struct terminal *term, int col, int row,
bool spaces_only, uint32_t serial);
void selection_mark_row(struct terminal *term, int row, uint32_t serial);
void selection_mark_word(
struct seat *seat, struct terminal *term, int col, int row,
bool spaces_only, uint32_t serial);
void selection_mark_row(
struct seat *seat, struct terminal *term, int row, uint32_t serial);
void selection_to_clipboard(struct terminal *term, uint32_t serial);
void selection_from_clipboard(struct terminal *term, uint32_t serial);
void selection_to_primary(struct terminal *term, uint32_t serial);
void selection_from_primary(struct terminal *term);
void selection_to_clipboard(
struct seat *seat, struct terminal *term, uint32_t serial);
void selection_from_clipboard(
struct seat *seat, struct terminal *term, uint32_t serial);
void selection_to_primary(
struct seat *seat, struct terminal *term, uint32_t serial);
void selection_from_primary(struct seat *seat, struct terminal *term);
/* Copy text *to* primary/clipboard */
bool text_to_clipboard(struct terminal *term, char *text, uint32_t serial);
bool text_to_primary(struct terminal *term, char *text, uint32_t serial);
bool text_to_clipboard(
struct seat *seat, struct terminal *term, char *text, uint32_t serial);
bool text_to_primary(
struct seat *seat, struct terminal *term, char *text, uint32_t serial);
/*
* Copy text *from* primary/clipboard
@ -50,11 +59,11 @@ bool text_to_primary(struct terminal *term, char *text, uint32_t serial);
* point).
*/
void text_from_clipboard(
struct terminal *term, uint32_t serial,
struct seat *seat, struct terminal *term, uint32_t serial,
void (*cb)(const char *data, size_t size, void *user),
void (*done)(void *user), void *user);
void text_from_primary(
struct terminal *term,
struct seat *seat, struct terminal *term,
void (*cb)(const char *data, size_t size, void *user),
void (*dont)(void *user), void *user);

View file

@ -106,6 +106,14 @@ seat_destroy(struct seat *seat)
if (seat->pointer.xcursor_callback != NULL)
wl_callback_destroy(seat->pointer.xcursor_callback);
if (seat->clipboard.data_source != NULL)
wl_data_source_destroy(seat->clipboard.data_source);
if (seat->clipboard.data_offer != NULL)
wl_data_offer_destroy(seat->clipboard.data_offer);
if (seat->primary.data_source != NULL)
zwp_primary_selection_source_v1_destroy(seat->primary.data_source);
if (seat->primary.data_offer != NULL)
zwp_primary_selection_offer_v1_destroy(seat->primary.data_offer);
if (seat->primary_selection_device != NULL)
zwp_primary_selection_device_v1_destroy(seat->primary_selection_device);
if (seat->data_device != NULL)