Skip to content

Commit

Permalink
sels: Return CM_SEL_INVALID on invalid sel
Browse files Browse the repository at this point in the history
die() is too much here -- in the early code who we could get
notifications from was tightly contained, but now not so much.
  • Loading branch information
cdown committed Nov 10, 2024
1 parent ec23470 commit d034810
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
30 changes: 24 additions & 6 deletions src/clipmenud.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,19 @@ static void handle_signalfd_event(void) {
* desired property type.
*/
static void handle_xfixes_selection_notify(XFixesSelectionNotifyEvent *se) {
enum selection_type sel =
selection_atom_to_selection_type(se->selection, sels);
if (sel == CM_SEL_INVALID) {
dbg("Received XFixesSelectionNotify for unknown sel\n");
return;
}

_drop_(XFree) char *win_title = get_window_title(dpy, se->owner);
if (is_clipserve(win_title) || is_ignored_window(win_title)) {
dbg("Ignoring clip from window titled '%s'\n", win_title);
return;
}

enum selection_type sel =
selection_atom_to_selection_type(se->selection, sels);
dbg("Notified about selection update. Selection: %s, Owner: '%s' (0x%lx)\n",
cfg.selections[sel].name, strnull(win_title), (unsigned long)se->owner);
XConvertSelection(dpy, se->selection,
Expand All @@ -189,6 +194,10 @@ static int handle_selection_notify(const XSelectionEvent *se) {
if (se->property == None) {
enum selection_type sel =
selection_atom_to_selection_type(se->selection, sels);
if (sel == CM_SEL_INVALID) {
dbg("Received no owner notification for unknown sel\n");
return 0;
}
dbg("X reports that %s has no current owner\n",
cfg.selections[sel].name);
return -ENOENT;
Expand Down Expand Up @@ -246,6 +255,13 @@ static uint64_t store_clip(char *text) {
* Process the final data collected during an INCR transfer.
*/
static void incr_receive_finish(struct incr_transfer *it) {
enum selection_type sel =
storage_atom_to_selection_type(it->property, sels);
if (sel == CM_SEL_INVALID) {
it_dbg(it, "Received INCR finish for unknown sel\n");
return;
}

it_dbg(it, "Finished (bytes buffered: %zu)\n", it->data_size);
_drop_(free) char *text = malloc(it->data_size + 1);
expect(text);
Expand All @@ -259,8 +275,6 @@ static void incr_receive_finish(struct incr_transfer *it) {
if (is_salient_text(text)) {
uint64_t hash = store_clip(text);
maybe_trim();
enum selection_type sel =
storage_atom_to_selection_type(it->property, sels);
if (cfg.owned_selections[sel].active && cfg.own_clipboard) {
run_clipserve(hash);
}
Expand Down Expand Up @@ -347,6 +361,12 @@ static int handle_property_notify(const XPropertyEvent *pe) {
return -EINVAL;
}

enum selection_type sel = storage_atom_to_selection_type(pe->atom, sels);
if (sel == CM_SEL_INVALID) {
dbg("Received PropertyNotify for unknown sel\n");
return -EINVAL;
}

// Check if this property corresponds to an INCR transfer in progress
struct incr_transfer *it = it_list;
while (it) {
Expand Down Expand Up @@ -398,8 +418,6 @@ static int handle_property_notify(const XPropertyEvent *pe) {
* 2. urxvt and some other terminal emulators will unhilight on
* PRIMARY ownership being taken away from them
*/
enum selection_type sel =
storage_atom_to_selection_type(pe->atom, sels);
if (cfg.owned_selections[sel].active && cfg.own_clipboard) {
run_clipserve(hash);
}
Expand Down
14 changes: 12 additions & 2 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,22 +357,32 @@ void setup_selections(Display *dpy, struct cm_selections *sels) {
XInternAtom(dpy, "CLIPMENUD_CUR_SECONDARY", False);
}

/**
* Maps an Atom to a selection_type based on the selection atoms in the
* provided cm_selections struct. Returns CM_SEL_INVALID on error if the
* selection type is not found.
*/
enum selection_type
selection_atom_to_selection_type(Atom atom, const struct cm_selections *sels) {
for (size_t i = 0; i < CM_SEL_MAX; ++i) {
if (sels[i].selection == atom) {
return i;
}
}
die("Unreachable\n");
return CM_SEL_INVALID;
}

/**
* Maps an Atom to a selection_type based on the storage atoms in the provided
* cm_selections struct. Returns CM_SEL_INVALID on error if the storage type is
* not found.
*/
enum selection_type
storage_atom_to_selection_type(Atom atom, const struct cm_selections *sels) {
for (size_t i = 0; i < CM_SEL_MAX; ++i) {
if (sels[i].storage == atom) {
return i;
}
}
die("Unreachable\n");
return CM_SEL_INVALID;
}
3 changes: 2 additions & 1 deletion src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ enum selection_type {
CM_SEL_CLIPBOARD,
CM_SEL_PRIMARY,
CM_SEL_SECONDARY,
CM_SEL_MAX
CM_SEL_MAX,
CM_SEL_INVALID
};
struct cm_selections {
Atom selection;
Expand Down

0 comments on commit d034810

Please sign in to comment.