This is a common interface that can be used for all primary selection protocols, as discussed in [1]. A new function wlr_seat_set_primary_selection is added to set the primary selection for all protocols. The seat now owns again the source, and resets the selection to NULL when destroyed. [1]: https://github.com/swaywm/wlroots/issues/1367#issuecomment-442403454master
parent
658b590567
commit
9f0720c03a
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* This an unstable interface of wlroots. No guarantees are made regarding the
|
||||||
|
* future consistency of this API.
|
||||||
|
*/
|
||||||
|
#ifndef WLR_USE_UNSTABLE
|
||||||
|
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WLR_TYPES_WLR_PRIMARY_SELECTION_H
|
||||||
|
#define WLR_TYPES_WLR_PRIMARY_SELECTION_H
|
||||||
|
|
||||||
|
#include <wayland-server.h>
|
||||||
|
#include <wlr/types/wlr_seat.h>
|
||||||
|
|
||||||
|
struct wlr_primary_selection_source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data source implementation. Only the `send` function is mandatory.
|
||||||
|
*/
|
||||||
|
struct wlr_primary_selection_source_impl {
|
||||||
|
void (*send)(struct wlr_primary_selection_source *source,
|
||||||
|
const char *mime_type, int fd);
|
||||||
|
void (*destroy)(struct wlr_primary_selection_source *source);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A source is the sending side of a selection.
|
||||||
|
*/
|
||||||
|
struct wlr_primary_selection_source {
|
||||||
|
const struct wlr_primary_selection_source_impl *impl;
|
||||||
|
|
||||||
|
// source metadata
|
||||||
|
struct wl_array mime_types;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct wl_signal destroy;
|
||||||
|
} events;
|
||||||
|
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void wlr_primary_selection_source_init(
|
||||||
|
struct wlr_primary_selection_source *source,
|
||||||
|
const struct wlr_primary_selection_source_impl *impl);
|
||||||
|
void wlr_primary_selection_source_destroy(
|
||||||
|
struct wlr_primary_selection_source *source);
|
||||||
|
void wlr_primary_selection_source_send(
|
||||||
|
struct wlr_primary_selection_source *source, const char *mime_type,
|
||||||
|
int fd);
|
||||||
|
|
||||||
|
void wlr_seat_set_primary_selection(struct wlr_seat *seat,
|
||||||
|
struct wlr_primary_selection_source *source);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,69 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wlr/types/wlr_primary_selection.h>
|
||||||
|
#include "util/signal.h"
|
||||||
|
|
||||||
|
void wlr_primary_selection_source_init(
|
||||||
|
struct wlr_primary_selection_source *source,
|
||||||
|
const struct wlr_primary_selection_source_impl *impl) {
|
||||||
|
assert(impl->send);
|
||||||
|
wl_array_init(&source->mime_types);
|
||||||
|
wl_signal_init(&source->events.destroy);
|
||||||
|
source->impl = impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_primary_selection_source_destroy(
|
||||||
|
struct wlr_primary_selection_source *source) {
|
||||||
|
if (source == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_signal_emit_safe(&source->events.destroy, source);
|
||||||
|
|
||||||
|
char **p;
|
||||||
|
wl_array_for_each(p, &source->mime_types) {
|
||||||
|
free(*p);
|
||||||
|
}
|
||||||
|
wl_array_release(&source->mime_types);
|
||||||
|
|
||||||
|
if (source->impl->destroy) {
|
||||||
|
source->impl->destroy(source);
|
||||||
|
} else {
|
||||||
|
free(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_primary_selection_source_send(
|
||||||
|
struct wlr_primary_selection_source *source, const char *mime_type,
|
||||||
|
int32_t fd) {
|
||||||
|
source->impl->send(source, mime_type, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void seat_handle_primary_selection_source_destroy(
|
||||||
|
struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_seat *seat =
|
||||||
|
wl_container_of(listener, seat, primary_selection_source_destroy);
|
||||||
|
wl_list_remove(&seat->primary_selection_source_destroy.link);
|
||||||
|
seat->primary_selection_source = NULL;
|
||||||
|
wlr_signal_emit_safe(&seat->events.primary_selection, seat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_seat_set_primary_selection(struct wlr_seat *seat,
|
||||||
|
struct wlr_primary_selection_source *source) {
|
||||||
|
if (seat->primary_selection_source != NULL) {
|
||||||
|
wl_list_remove(&seat->primary_selection_source_destroy.link);
|
||||||
|
wlr_primary_selection_source_destroy(seat->primary_selection_source);
|
||||||
|
seat->primary_selection_source = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
seat->primary_selection_source = source;
|
||||||
|
if (source != NULL) {
|
||||||
|
seat->primary_selection_source_destroy.notify =
|
||||||
|
seat_handle_primary_selection_source_destroy;
|
||||||
|
wl_signal_add(&source->events.destroy,
|
||||||
|
&seat->primary_selection_source_destroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_signal_emit_safe(&seat->events.primary_selection, seat);
|
||||||
|
}
|
Loading…
Reference in new issue