diff options
| author | Vladimir Panteleev | 2022-02-04 01:54:45 +0000 |
|---|---|---|
| committer | Po Lu | 2022-02-05 09:07:00 +0800 |
| commit | de687e8983f57c975e902af6eb484d9115ca0733 (patch) | |
| tree | 3d4b1300e738ae23517208ebe76cbb00286d044c /src | |
| parent | d52c929e31f60ff0462371bfe27ebd479e3e82bd (diff) | |
| download | emacs-de687e8983f57c975e902af6eb484d9115ca0733.tar.gz emacs-de687e8983f57c975e902af6eb484d9115ca0733.zip | |
Do not delete the MULTIPLE property after reading it
Per the ICCCM spec:
> The requestor should delete [...] the property specified in the
> MULTIPLE request when it has copied all the data.
We are not the requestor, so we should not be deleting this property
(which is what x_get_window_property_as_lisp_data does). The property
needs to remain available as the requestor will generally want to read
it back to see which conversions succeeded or not.
* src/xselect.c (x_get_window_property_as_lisp_data): Add flag which
skips deleting the read property, or handling INCR (which does not
make sense for MULTIPLE).
(x_handle_selection_request): Enable the flag.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xselect.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/xselect.c b/src/xselect.c index cfe028a1696..537be2ddd54 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -52,7 +52,7 @@ static void unexpect_property_change (struct prop_location *); | |||
| 52 | static void wait_for_property_change (struct prop_location *); | 52 | static void wait_for_property_change (struct prop_location *); |
| 53 | static Lisp_Object x_get_window_property_as_lisp_data (struct x_display_info *, | 53 | static Lisp_Object x_get_window_property_as_lisp_data (struct x_display_info *, |
| 54 | Window, Atom, | 54 | Window, Atom, |
| 55 | Lisp_Object, Atom); | 55 | Lisp_Object, Atom, bool); |
| 56 | static Lisp_Object selection_data_to_lisp_data (struct x_display_info *, | 56 | static Lisp_Object selection_data_to_lisp_data (struct x_display_info *, |
| 57 | const unsigned char *, | 57 | const unsigned char *, |
| 58 | ptrdiff_t, Atom, int); | 58 | ptrdiff_t, Atom, int); |
| @@ -799,7 +799,7 @@ x_handle_selection_request (struct selection_input_event *event) | |||
| 799 | if (property == None) goto DONE; | 799 | if (property == None) goto DONE; |
| 800 | multprop | 800 | multprop |
| 801 | = x_get_window_property_as_lisp_data (dpyinfo, requestor, property, | 801 | = x_get_window_property_as_lisp_data (dpyinfo, requestor, property, |
| 802 | QMULTIPLE, selection); | 802 | QMULTIPLE, selection, true); |
| 803 | 803 | ||
| 804 | if (!VECTORP (multprop) || ASIZE (multprop) % 2) | 804 | if (!VECTORP (multprop) || ASIZE (multprop) % 2) |
| 805 | goto DONE; | 805 | goto DONE; |
| @@ -1210,7 +1210,7 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, | |||
| 1210 | return | 1210 | return |
| 1211 | x_get_window_property_as_lisp_data (dpyinfo, requestor_window, | 1211 | x_get_window_property_as_lisp_data (dpyinfo, requestor_window, |
| 1212 | target_property, target_type, | 1212 | target_property, target_type, |
| 1213 | selection_atom); | 1213 | selection_atom, false); |
| 1214 | } | 1214 | } |
| 1215 | 1215 | ||
| 1216 | /* Subroutines of x_get_window_property_as_lisp_data */ | 1216 | /* Subroutines of x_get_window_property_as_lisp_data */ |
| @@ -1461,7 +1461,8 @@ static Lisp_Object | |||
| 1461 | x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo, | 1461 | x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo, |
| 1462 | Window window, Atom property, | 1462 | Window window, Atom property, |
| 1463 | Lisp_Object target_type, | 1463 | Lisp_Object target_type, |
| 1464 | Atom selection_atom) | 1464 | Atom selection_atom, |
| 1465 | bool for_multiple) | ||
| 1465 | { | 1466 | { |
| 1466 | Atom actual_type; | 1467 | Atom actual_type; |
| 1467 | int actual_format; | 1468 | int actual_format; |
| @@ -1477,6 +1478,8 @@ x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo, | |||
| 1477 | &actual_type, &actual_format, &actual_size); | 1478 | &actual_type, &actual_format, &actual_size); |
| 1478 | if (! data) | 1479 | if (! data) |
| 1479 | { | 1480 | { |
| 1481 | if (for_multiple) | ||
| 1482 | return Qnil; | ||
| 1480 | block_input (); | 1483 | block_input (); |
| 1481 | bool there_is_a_selection_owner | 1484 | bool there_is_a_selection_owner |
| 1482 | = XGetSelectionOwner (display, selection_atom) != 0; | 1485 | = XGetSelectionOwner (display, selection_atom) != 0; |
| @@ -1499,7 +1502,7 @@ x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo, | |||
| 1499 | } | 1502 | } |
| 1500 | } | 1503 | } |
| 1501 | 1504 | ||
| 1502 | if (actual_type == dpyinfo->Xatom_INCR) | 1505 | if (!for_multiple && actual_type == dpyinfo->Xatom_INCR) |
| 1503 | { | 1506 | { |
| 1504 | /* That wasn't really the data, just the beginning. */ | 1507 | /* That wasn't really the data, just the beginning. */ |
| 1505 | 1508 | ||
| @@ -1515,11 +1518,14 @@ x_get_window_property_as_lisp_data (struct x_display_info *dpyinfo, | |||
| 1515 | &actual_size); | 1518 | &actual_size); |
| 1516 | } | 1519 | } |
| 1517 | 1520 | ||
| 1518 | block_input (); | 1521 | if (!for_multiple) |
| 1519 | TRACE1 (" Delete property %s", XGetAtomName (display, property)); | 1522 | { |
| 1520 | XDeleteProperty (display, window, property); | 1523 | block_input (); |
| 1521 | XFlush (display); | 1524 | TRACE1 (" Delete property %s", XGetAtomName (display, property)); |
| 1522 | unblock_input (); | 1525 | XDeleteProperty (display, window, property); |
| 1526 | XFlush (display); | ||
| 1527 | unblock_input (); | ||
| 1528 | } | ||
| 1523 | 1529 | ||
| 1524 | /* It's been read. Now convert it to a lisp object in some semi-rational | 1530 | /* It's been read. Now convert it to a lisp object in some semi-rational |
| 1525 | manner. */ | 1531 | manner. */ |