diff options
| author | Po Lu | 2022-05-30 14:04:43 +0800 |
|---|---|---|
| committer | Po Lu | 2022-05-30 14:05:30 +0800 |
| commit | fd510f12392fcb2bf34eb08262ddda20d8a3c221 (patch) | |
| tree | bd293cd92a1338e9aab3b80d23e26127485f8cce /src/xselect.c | |
| parent | 52d41f2750c0f66d7f7ba8e198832734fe750fa5 (diff) | |
| download | emacs-fd510f12392fcb2bf34eb08262ddda20d8a3c221.tar.gz emacs-fd510f12392fcb2bf34eb08262ddda20d8a3c221.zip | |
Fix hangs when x-get-selection is called inside a popup menu
* src/xselect.c (wait_for_property_change):
(x_get_foreign_selection): Use `x_wait_for_cell_change' if input
is blocked. (bug#22214)
* src/xterm.c (x_wait_for_cell_change): New function.
* src/xterm.h: Update prototypes.
Diffstat (limited to 'src/xselect.c')
| -rw-r--r-- | src/xselect.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/xselect.c b/src/xselect.c index bfd081b1e28..a4148735945 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -1148,8 +1148,13 @@ wait_for_property_change (struct prop_location *location) | |||
| 1148 | intmax_t secs = timeout / 1000; | 1148 | intmax_t secs = timeout / 1000; |
| 1149 | int nsecs = (timeout % 1000) * 1000000; | 1149 | int nsecs = (timeout % 1000) * 1000000; |
| 1150 | TRACE2 (" Waiting %"PRIdMAX" secs, %d nsecs", secs, nsecs); | 1150 | TRACE2 (" Waiting %"PRIdMAX" secs, %d nsecs", secs, nsecs); |
| 1151 | wait_reading_process_output (secs, nsecs, 0, false, | 1151 | |
| 1152 | property_change_reply, NULL, 0); | 1152 | if (!input_blocked_p ()) |
| 1153 | wait_reading_process_output (secs, nsecs, 0, false, | ||
| 1154 | property_change_reply, NULL, 0); | ||
| 1155 | else | ||
| 1156 | x_wait_for_cell_change (property_change_reply, | ||
| 1157 | make_timespec (secs, nsecs)); | ||
| 1153 | 1158 | ||
| 1154 | if (NILP (XCAR (property_change_reply))) | 1159 | if (NILP (XCAR (property_change_reply))) |
| 1155 | { | 1160 | { |
| @@ -1256,8 +1261,17 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, | |||
| 1256 | intmax_t secs = timeout / 1000; | 1261 | intmax_t secs = timeout / 1000; |
| 1257 | int nsecs = (timeout % 1000) * 1000000; | 1262 | int nsecs = (timeout % 1000) * 1000000; |
| 1258 | TRACE1 (" Start waiting %"PRIdMAX" secs for SelectionNotify", secs); | 1263 | TRACE1 (" Start waiting %"PRIdMAX" secs for SelectionNotify", secs); |
| 1259 | wait_reading_process_output (secs, nsecs, 0, false, | 1264 | /* This function can be called with input blocked inside Xt or GTK |
| 1260 | reading_selection_reply, NULL, 0); | 1265 | timeouts run inside popup menus, so use a function that works |
| 1266 | when input is blocked. Prefer wait_reading_process_output | ||
| 1267 | otherwise, or the toolkit might not get some events. | ||
| 1268 | (bug#22214) */ | ||
| 1269 | if (!input_blocked_p ()) | ||
| 1270 | wait_reading_process_output (secs, nsecs, 0, false, | ||
| 1271 | reading_selection_reply, NULL, 0); | ||
| 1272 | else | ||
| 1273 | x_wait_for_cell_change (reading_selection_reply, | ||
| 1274 | make_timespec (secs, nsecs)); | ||
| 1261 | TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply))); | 1275 | TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply))); |
| 1262 | 1276 | ||
| 1263 | if (NILP (XCAR (reading_selection_reply))) | 1277 | if (NILP (XCAR (reading_selection_reply))) |