Reputation: 2087
I am writing a component which has to monitor changes in CLIPBOARD for a X11 window.
auto display = XOpenDisplay(NULL);
auto screen = DefaultScreen(mdisplay);
auto root_window = RootWindow(display, screen);
clipboard = XInternAtom(display, "CLIPBOARD", 0);
window = XCreateSimpleWindow(mdisplay, root_window, 0, 0, 1, 1, 0, 0, 0);
while(true) {
XEvent event = {0};
XNextEvent(display, &event);
switch(event.type) {
case SelectionNotify: {
// do something
}
break;
case SelectionRequest: { // triggered after performing copy
auto target_name = XGetAtomName(display, event.xselectionrequest.target);
auto selection_name = XGetAtomName(display, event.xselectionrequest.selection);
auto property_name = XGetAtomName(display, event.xselectionrequest.property);
Log("Event SelectionRequest: owner: %ld, requestor: %ld, selection: %s, target: %s(%d), property: %s",
event.xselectionrequest.owner,
event.xselectionrequest.requestor,
selection_name,
target_name,
event.xselectionrequest.target,
property_name);
if(x_event.xselectionrequest.selection != clipboard) {
Log("%s: Warning: event selection not matching\n", __func__);
break;
}
}
break;
}
}
Problem is that when I try to check event SelectionRequest
all I see is
Event SelectionRequest: owner: 33554433, requestor: 18874649, selection: CLIPBOARD, target: TARGETS(344), property: GDK_SELECTION
The action I am performing is copying some text from Chrome browser. Can anyone tell me why I am not seeing this text, unicode, string types, but rather GDK_SELECTION
?
PS: It happens to be I just saw those formats only once (text, unicode, string types), but never again.
Upvotes: 0
Views: 317
Reputation: 1
For reading data in clipboard you need:
XConvertSelection
with TARGETS as target atomSelectionNotify
event and read available targets using XGetWindowProperty
XConvertSelection
with preferred targetSelectionNotify
event and read available data using XGetWindowProperty
For more info check this answer
Posting hear naive implementation only for describe main idea.
// gcc -o xclipget xclipget.c -lX11
#include <stdio.h>
#include <limits.h>
#include <X11/Xlib.h>
Bool PrintSelection(Display *display, Window window, const char *bufname, const char *fmtname)
{
char *result;
unsigned long ressize, restail;
int resbits;
Atom bufid = XInternAtom(display, bufname, False),
fmtid = XInternAtom(display, fmtname, False),
propid = XInternAtom(display, "XSEL_DATA", False),
incrid = XInternAtom(display, "INCR", False);
XEvent event;
XConvertSelection(display, bufid, fmtid, propid, window, CurrentTime);
do {
XNextEvent(display, &event);
} while (event.type != SelectionNotify || event.xselection.selection != bufid);
if (event.xselection.property)
{
XGetWindowProperty(display, window, propid, 0, LONG_MAX/4, False, AnyPropertyType,
&fmtid, &resbits, &ressize, &restail, (unsigned char**)&result);
if (fmtid == incrid)
printf("Buffer is too large and INCR reading is not implemented yet.\n");
else
printf("%.*s", (int)ressize, result);
XFree(result);
return True;
}
else // request failed, e.g. owner can't convert to the target format
return False;
}
int main()
{
Display *display = XOpenDisplay(NULL);
unsigned long color = BlackPixel(display, DefaultScreen(display));
Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0,0, 1,1, 0, color, color);
Bool result = PrintSelection(display, window, "CLIPBOARD", "UTF8_STRING") ||
PrintSelection(display, window, "CLIPBOARD", "STRING");
XDestroyWindow(display, window);
XCloseDisplay(display);
return !result;
}
Upvotes: 0