diff options
| author | Po Lu | 2022-03-16 17:03:19 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-16 17:03:19 +0800 |
| commit | e8d7139b4e069f4641a7e11261541acb4c5fff7b (patch) | |
| tree | d70f006c6e91a65071079f374e9634b43a08bd5a /src | |
| parent | 1babe5fb2d7575fb15e515fffd3387d60a975553 (diff) | |
| download | emacs-e8d7139b4e069f4641a7e11261541acb4c5fff7b.tar.gz emacs-e8d7139b4e069f4641a7e11261541acb4c5fff7b.zip | |
Fix minor bugs with XDND support
* lisp/mouse.el (mouse-drag-and-drop-region): Report more
selection targets for the benefit of Qt and Mozilla.
* lisp/select.el (xselect--encode-string)
(selection-converter-alist): Add new selection targets.
* src/xterm.c (x_dnd_get_window_proxy): New function.
(x_dnd_get_target_window): New argument proto_out, and return
first window with XdndAware instead of bottommost window.
(handle_one_xevent): Use new argument `proto_out'.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 116 |
1 files changed, 76 insertions, 40 deletions
diff --git a/src/xterm.c b/src/xterm.c index d01d3e7cce3..83651376bfd 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -795,23 +795,21 @@ static struct frame *x_dnd_frame; | |||
| 795 | 795 | ||
| 796 | #define X_DND_SUPPORTED_VERSION 5 | 796 | #define X_DND_SUPPORTED_VERSION 5 |
| 797 | 797 | ||
| 798 | static int x_dnd_get_window_proto (struct x_display_info *, Window); | ||
| 799 | static Window x_dnd_get_window_proxy (struct x_display_info *, Window); | ||
| 800 | |||
| 798 | static Window | 801 | static Window |
| 799 | x_dnd_get_target_window (struct x_display_info *dpyinfo, | 802 | x_dnd_get_target_window (struct x_display_info *dpyinfo, |
| 800 | int root_x, int root_y) | 803 | int root_x, int root_y, int *proto_out) |
| 801 | { | 804 | { |
| 802 | Window child_return, child, dummy, proxy; | 805 | Window child_return, child, dummy, proxy; |
| 803 | int dest_x_return, dest_y_return; | 806 | int dest_x_return, dest_y_return, rc, proto; |
| 804 | int rc; | ||
| 805 | int actual_format; | ||
| 806 | unsigned long actual_size, bytes_remaining; | ||
| 807 | unsigned char *tmp_data; | ||
| 808 | XWindowAttributes attrs; | ||
| 809 | Atom actual_type; | ||
| 810 | |||
| 811 | child_return = dpyinfo->root_window; | 807 | child_return = dpyinfo->root_window; |
| 812 | dest_x_return = root_x; | 808 | dest_x_return = root_x; |
| 813 | dest_y_return = root_y; | 809 | dest_y_return = root_y; |
| 814 | 810 | ||
| 811 | proto = -1; | ||
| 812 | |||
| 815 | /* Not strictly necessary, but satisfies GCC. */ | 813 | /* Not strictly necessary, but satisfies GCC. */ |
| 816 | child = dpyinfo->root_window; | 814 | child = dpyinfo->root_window; |
| 817 | 815 | ||
| @@ -832,8 +830,33 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, | |||
| 832 | break; | 830 | break; |
| 833 | } | 831 | } |
| 834 | 832 | ||
| 833 | proxy = x_dnd_get_window_proxy (dpyinfo, child_return); | ||
| 834 | |||
| 835 | if (proxy != None) | ||
| 836 | { | ||
| 837 | proto = x_dnd_get_window_proto (dpyinfo, proxy); | ||
| 838 | |||
| 839 | if (proto != -1) | ||
| 840 | { | ||
| 841 | *proto_out = proto; | ||
| 842 | |||
| 843 | x_uncatch_errors_after_check (); | ||
| 844 | return proxy; | ||
| 845 | } | ||
| 846 | } | ||
| 847 | |||
| 835 | if (child_return) | 848 | if (child_return) |
| 836 | { | 849 | { |
| 850 | proto = x_dnd_get_window_proto (dpyinfo, child_return); | ||
| 851 | |||
| 852 | if (proto != -1) | ||
| 853 | { | ||
| 854 | *proto_out = proto; | ||
| 855 | x_uncatch_errors_after_check (); | ||
| 856 | |||
| 857 | return child_return; | ||
| 858 | } | ||
| 859 | |||
| 837 | rc = XTranslateCoordinates (dpyinfo->display, | 860 | rc = XTranslateCoordinates (dpyinfo->display, |
| 838 | child, child_return, | 861 | child, child_return, |
| 839 | dest_x_return, dest_y_return, | 862 | dest_x_return, dest_y_return, |
| @@ -850,36 +873,47 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, | |||
| 850 | x_uncatch_errors_after_check (); | 873 | x_uncatch_errors_after_check (); |
| 851 | } | 874 | } |
| 852 | 875 | ||
| 853 | if (child != None) | 876 | *proto_out = x_dnd_get_window_proto (dpyinfo, child); |
| 854 | { | 877 | return child; |
| 855 | x_catch_errors (dpyinfo->display); | 878 | } |
| 856 | rc = XGetWindowProperty (dpyinfo->display, child, | 879 | |
| 857 | dpyinfo->Xatom_XdndProxy, | 880 | static Window |
| 858 | 0, 1, False, XA_WINDOW, | 881 | x_dnd_get_window_proxy (struct x_display_info *dpyinfo, Window wdesc) |
| 859 | &actual_type, &actual_format, | 882 | { |
| 860 | &actual_size, &bytes_remaining, | 883 | int rc, actual_format; |
| 861 | &tmp_data); | 884 | unsigned long actual_size, bytes_remaining; |
| 862 | 885 | unsigned char *tmp_data; | |
| 863 | if (!x_had_errors_p (dpyinfo->display) | 886 | XWindowAttributes attrs; |
| 864 | && rc == Success | 887 | Atom actual_type; |
| 865 | && actual_type == XA_WINDOW | 888 | Window proxy; |
| 866 | && actual_format == 32 | ||
| 867 | && actual_size == 1) | ||
| 868 | { | ||
| 869 | proxy = *(Window *) tmp_data; | ||
| 870 | XFree (tmp_data); | ||
| 871 | 889 | ||
| 872 | /* Verify the proxy window exists. */ | 890 | proxy = None; |
| 873 | XGetWindowAttributes (dpyinfo->display, proxy, &attrs); | 891 | x_catch_errors (dpyinfo->display); |
| 892 | rc = XGetWindowProperty (dpyinfo->display, wdesc, | ||
| 893 | dpyinfo->Xatom_XdndProxy, | ||
| 894 | 0, 1, False, XA_WINDOW, | ||
| 895 | &actual_type, &actual_format, | ||
| 896 | &actual_size, &bytes_remaining, | ||
| 897 | &tmp_data); | ||
| 874 | 898 | ||
| 875 | if (!x_had_errors_p (dpyinfo->display)) | 899 | if (!x_had_errors_p (dpyinfo->display) |
| 876 | child = proxy; | 900 | && rc == Success |
| 877 | } | 901 | && actual_type == XA_WINDOW |
| 902 | && actual_format == 32 | ||
| 903 | && actual_size == 1) | ||
| 904 | { | ||
| 905 | proxy = *(Window *) tmp_data; | ||
| 906 | XFree (tmp_data); | ||
| 878 | 907 | ||
| 879 | x_uncatch_errors_after_check (); | 908 | /* Verify the proxy window exists. */ |
| 909 | XGetWindowAttributes (dpyinfo->display, proxy, &attrs); | ||
| 910 | |||
| 911 | if (x_had_errors_p (dpyinfo->display)) | ||
| 912 | proxy = None; | ||
| 880 | } | 913 | } |
| 914 | x_uncatch_errors_after_check (); | ||
| 881 | 915 | ||
| 882 | return child; | 916 | return proxy; |
| 883 | } | 917 | } |
| 884 | 918 | ||
| 885 | static int | 919 | static int |
| @@ -11616,10 +11650,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 11616 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) | 11650 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) |
| 11617 | { | 11651 | { |
| 11618 | Window target; | 11652 | Window target; |
| 11653 | int target_proto; | ||
| 11619 | 11654 | ||
| 11620 | target = x_dnd_get_target_window (dpyinfo, | 11655 | target = x_dnd_get_target_window (dpyinfo, |
| 11621 | event->xmotion.x_root, | 11656 | event->xmotion.x_root, |
| 11622 | event->xmotion.y_root); | 11657 | event->xmotion.y_root, |
| 11658 | &target_proto); | ||
| 11623 | 11659 | ||
| 11624 | if (target != x_dnd_last_seen_window) | 11660 | if (target != x_dnd_last_seen_window) |
| 11625 | { | 11661 | { |
| @@ -11643,8 +11679,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 11643 | 11679 | ||
| 11644 | x_dnd_wanted_action = None; | 11680 | x_dnd_wanted_action = None; |
| 11645 | x_dnd_last_seen_window = target; | 11681 | x_dnd_last_seen_window = target; |
| 11646 | x_dnd_last_protocol_version | 11682 | x_dnd_last_protocol_version = target_proto; |
| 11647 | = x_dnd_get_window_proto (dpyinfo, target); | ||
| 11648 | 11683 | ||
| 11649 | if (target != None && x_dnd_last_protocol_version != -1) | 11684 | if (target != None && x_dnd_last_protocol_version != -1) |
| 11650 | x_dnd_send_enter (x_dnd_frame, target, | 11685 | x_dnd_send_enter (x_dnd_frame, target, |
| @@ -12849,10 +12884,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12849 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) | 12884 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) |
| 12850 | { | 12885 | { |
| 12851 | Window target; | 12886 | Window target; |
| 12887 | int target_proto; | ||
| 12852 | 12888 | ||
| 12853 | target = x_dnd_get_target_window (dpyinfo, | 12889 | target = x_dnd_get_target_window (dpyinfo, |
| 12854 | xev->root_x, | 12890 | xev->root_x, |
| 12855 | xev->root_y); | 12891 | xev->root_y, |
| 12892 | &target_proto); | ||
| 12856 | 12893 | ||
| 12857 | if (target != x_dnd_last_seen_window) | 12894 | if (target != x_dnd_last_seen_window) |
| 12858 | { | 12895 | { |
| @@ -12875,8 +12912,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12875 | } | 12912 | } |
| 12876 | 12913 | ||
| 12877 | x_dnd_last_seen_window = target; | 12914 | x_dnd_last_seen_window = target; |
| 12878 | x_dnd_last_protocol_version | 12915 | x_dnd_last_protocol_version = target_proto; |
| 12879 | = x_dnd_get_window_proto (dpyinfo, target); | ||
| 12880 | 12916 | ||
| 12881 | if (target != None && x_dnd_last_protocol_version != -1) | 12917 | if (target != None && x_dnd_last_protocol_version != -1) |
| 12882 | x_dnd_send_enter (x_dnd_frame, target, | 12918 | x_dnd_send_enter (x_dnd_frame, target, |