Skip to content

Commit

Permalink
Widget: Add pasted event
Browse files Browse the repository at this point in the history
Widget_pasted() fires for a widget that currently owns a selection when
the content of this selection was requested by another X11 client.
  • Loading branch information
Zirias committed Jul 26, 2024
1 parent b2b373e commit fc2105f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/bin/xmoji/widget.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct Widget
Tooltip *tooltip;
PSC_Event *shown;
PSC_Event *hidden;
PSC_Event *pasted;
PSC_Event *activated;
PSC_Event *sizeRequested;
PSC_Event *sizeChanged;
Expand Down Expand Up @@ -71,6 +72,7 @@ static void destroy(void *obj)
PSC_Event_destroy(self->sizeChanged);
PSC_Event_destroy(self->sizeRequested);
PSC_Event_destroy(self->activated);
PSC_Event_destroy(self->pasted);
PSC_Event_destroy(self->hidden);
PSC_Event_destroy(self->shown);
Tooltip_destroy(self->tooltip);
Expand Down Expand Up @@ -145,6 +147,7 @@ Widget *Widget_createBase(void *derived, const char *name, void *parent)
else self->resname = Object_className(self);
self->shown = PSC_Event_create(self);
self->hidden = PSC_Event_create(self);
self->pasted = PSC_Event_create(self);
self->activated = PSC_Event_create(self);
self->sizeRequested = PSC_Event_create(self);
self->sizeChanged = PSC_Event_create(self);
Expand Down Expand Up @@ -193,6 +196,12 @@ PSC_Event *Widget_hidden(void *self)
return w->hidden;
}

PSC_Event *Widget_pasted(void *self)
{
Widget *w = Object_instance(self);
return w->pasted;
}

PSC_Event *Widget_activated(void *self)
{
Widget *w = Object_instance(self);
Expand Down Expand Up @@ -998,6 +1007,14 @@ void Widget_setSelection(void *self, XSelectionName name,
XSelection_publish(selection, Object_instance(self), content);
}

void Widget_raisePasted(void *self, XSelectionName name,
XSelectionContent content)
{
Widget *w = Object_instance(self);
PastedEventArgs ea = { name, content };
PSC_Event_raise(w->pasted, 0, &ea);
}

const Rect *Widget_damages(const void *self, int *num)
{
const Widget *w = Object_instance(self);
Expand Down
9 changes: 9 additions & 0 deletions src/bin/xmoji/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ typedef struct WidgetEventArgs
int external;
} WidgetEventArgs;

typedef struct PastedEventArgs
{
XSelectionName name;
XSelectionContent content;
} PastedEventArgs;

typedef struct SizeChangedEventArgs
{
int external;
Expand All @@ -123,6 +129,7 @@ const char *Widget_name(const void *self) CMETHOD;
const char *Widget_resname(const void *self) CMETHOD ATTR_RETNONNULL;
PSC_Event *Widget_shown(void *self) CMETHOD ATTR_RETNONNULL;
PSC_Event *Widget_hidden(void *self) CMETHOD ATTR_RETNONNULL;
PSC_Event *Widget_pasted(void *self) CMETHOD ATTR_RETNONNULL;
PSC_Event *Widget_activated(void *self) CMETHOD ATTR_RETNONNULL;
PSC_Event *Widget_sizeRequested(void *self) CMETHOD ATTR_RETNONNULL;
PSC_Event *Widget_sizeChanged(void *self) CMETHOD ATTR_RETNONNULL;
Expand Down Expand Up @@ -197,6 +204,8 @@ void Widget_requestPaste(void *self, XSelectionName name,
XSelectionType type) CMETHOD;
void Widget_setSelection(void *self, XSelectionName name,
XSelectionContent content) CMETHOD;
void Widget_raisePasted(void *self, XSelectionName name,
XSelectionContent content) CMETHOD;
const Rect *Widget_damages(const void *self, int *num) CMETHOD;

#endif
10 changes: 10 additions & 0 deletions src/bin/xmoji/xselection.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ static XSelectionRequest *XSelectionRequest_create(XSelection *selection,
|| (ev->target == A(UTF8_STRING)
&& selection->content.type == XST_TEXT))
{
int notify = 1;
XSelectionRequest *self = PSC_malloc(sizeof *self);
self->selection = selection;
self->next = 0;
Expand All @@ -452,13 +453,15 @@ static XSelectionRequest *XSelectionRequest_create(XSelection *selection,
self->timeout = 0;
if (ev->target == A(MULTIPLE))
{
notify = 0;
self->data = 0;
self->datalen = 0;
self->proptype = A(ATOM_PAIR);
self->propformat = 32;
}
else if (ev->target == A(TARGETS))
{
notify = 0;
xcb_atom_t *targets;
switch (selection->content.type)
{
Expand Down Expand Up @@ -487,6 +490,7 @@ static XSelectionRequest *XSelectionRequest_create(XSelection *selection,
}
else if (ev->target == A(TIMESTAMP))
{
notify = 0;
self->data = PSC_malloc(sizeof selection->ownedTime);
memcpy(self->data, &selection->ownedTime,
sizeof selection->ownedTime);
Expand Down Expand Up @@ -514,6 +518,12 @@ static XSelectionRequest *XSelectionRequest_create(XSelection *selection,
self->requestor = ev->requestor;
self->time = ev->time;
self->subidx = 0;
if (notify && selection->owner)
{
Widget_raisePasted(selection->owner,
selection->name == XCB_ATOM_PRIMARY
? XSN_PRIMARY : XSN_CLIPBOARD, selection->content);
}
return self;
}
if (!parent) XSelectionRequest_reject(selection,
Expand Down

0 comments on commit fc2105f

Please sign in to comment.