Skip to content

Commit f362ef2

Browse files
committed
fix(platform): correct the thread cancelation in x11clipboard
1 parent 0f21dc8 commit f362ef2

File tree

1 file changed

+38
-31
lines changed

1 file changed

+38
-31
lines changed

lib/platform/src/linux/linux_x11clipboard.c

+38-31
Original file line numberDiff line numberDiff line change
@@ -52,54 +52,58 @@ static struct x11_clipboard_module_t {
5252
Atom xa_string;
5353
Atom xa_targets;
5454
Atom xa_text;
55-
// Observer thread
55+
5656
thread_t observer_thread;
57+
bool observer_thread_active;
5758
} x11_clipboard;
5859

59-
void x11_clipboard_execute_action(bool timed_out)
60+
void x11_clipboard_notify(clipboard_t *cb)
6061
{
61-
wchar_t *wstr = NULL;
62-
clipboard_t clipboard_data = { 0 };
6362
clipboard_action_t *action = x11_clipboard.action;
6463

65-
if (!timed_out) {
66-
logger_debug("Didn't time out canceling observer thread\n");
67-
thread_cancel(x11_clipboard.observer_thread);
68-
}
69-
7064
if (!action->running) {
71-
logger_debug("Tried to x11_clipboard_execute_action before "
65+
logger_debug("Tried to x11_clipboard_notify before "
7266
"copying started\n");
7367
return;
7468
}
75-
if (timed_out) {
76-
logger_debug("action timed out\n");
77-
} else {
78-
size_t len = x11_clipboard.text_len + 1;
79-
wstr = malloc(sizeof(wchar_t) * len);
80-
len = decode_utf8(wstr, x11_clipboard.text, len);
81-
wstr[len] = 0;
82-
// Assign the data
83-
clipboard_data.text = wstr;
84-
clipboard_data.len = len;
85-
clipboard_data.image = NULL;
86-
}
87-
action->callback(&clipboard_data, action->arg);
88-
if (wstr != NULL) {
89-
free(wstr);
90-
}
69+
action->callback(cb, action->arg);
9170
// Reset properties, so if something goes wrongly, we crash
9271
// instead of having undefined behaviour
9372
action->arg = NULL;
9473
action->callback = NULL;
9574
action->running = false;
9675
}
9776

77+
void x11_clipboard_execute_action(void)
78+
{
79+
clipboard_t clipboard_data = { 0 };
80+
size_t len = x11_clipboard.text_len + 1;
81+
wchar_t *wstr = malloc(sizeof(wchar_t) * len);
82+
83+
len = decode_utf8(wstr, x11_clipboard.text, len);
84+
wstr[len] = 0;
85+
// Assign the data
86+
clipboard_data.text = wstr;
87+
clipboard_data.len = len;
88+
clipboard_data.image = NULL;
89+
x11_clipboard.observer_thread_active = false;
90+
x11_clipboard_notify(&clipboard_data);
91+
free(wstr);
92+
}
93+
9894
void x11_clipboard_request_timeout(void *arg)
9995
{
100-
sleep_ms(CLIPBOARD_TIMEOUT);
101-
if (x11_clipboard.action->running) {
102-
x11_clipboard_execute_action(true);
96+
int ms;
97+
clipboard_t clipboard_data = { 0 };
98+
99+
for (ms = 0;
100+
ms <= CLIPBOARD_TIMEOUT && x11_clipboard.observer_thread_active;
101+
ms += 100) {
102+
sleep_ms(100);
103+
}
104+
if (x11_clipboard.observer_thread_active) {
105+
logger_debug("action timed out\n");
106+
x11_clipboard_notify(&clipboard_data);
103107
}
104108
}
105109

@@ -168,13 +172,14 @@ int x11_clipboard_request_text(clipboard_callback_t callback, void *arg)
168172
// This branch will only get executed once we implement copy event
169173
if (clipboard_owner == window) {
170174
logger_debug("Clipboard owned by self\n");
171-
x11_clipboard_execute_action(false);
175+
x11_clipboard_execute_action();
172176
return 0;
173177
}
174178
if (clipboard_owner == None) {
175179
logger_debug("Clipboard owner not found\n");
176180
return 1;
177181
}
182+
x11_clipboard.observer_thread_active = true;
178183
// @WhoAteDaCake
179184
// TODO: needs error handling if we can't access the clipboard?
180185
// TODO: some other implementations will try XA_STRING if no text was
@@ -220,7 +225,7 @@ static void x11_clipboard_on_notify(app_native_event_t *ev, void *arg)
220225
XDeleteProperty(x_ev->xselection.display,
221226
x_ev->xselection.requestor,
222227
x_ev->xselection.property);
223-
x11_clipboard_execute_action(false);
228+
x11_clipboard_execute_action();
224229
}
225230
}
226231

@@ -318,6 +323,8 @@ void x11_clipboard_destroy(void)
318323
app_off_native_event(SelectionNotify, x11_clipboard_on_notify);
319324
app_off_native_event(SelectionClear, x11_clipboard_on_clear);
320325
app_off_native_event(SelectionRequest, x11_clipboard_on_request);
326+
x11_clipboard.observer_thread_active = false;
327+
thread_join(x11_clipboard.observer_thread, NULL);
321328
}
322329

323330
#endif

0 commit comments

Comments
 (0)