aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-03-16 17:03:19 +0800
committerPo Lu2022-03-16 17:03:19 +0800
commite8d7139b4e069f4641a7e11261541acb4c5fff7b (patch)
treed70f006c6e91a65071079f374e9634b43a08bd5a /src
parent1babe5fb2d7575fb15e515fffd3387d60a975553 (diff)
downloademacs-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.c116
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
798static int x_dnd_get_window_proto (struct x_display_info *, Window);
799static Window x_dnd_get_window_proxy (struct x_display_info *, Window);
800
798static Window 801static Window
799x_dnd_get_target_window (struct x_display_info *dpyinfo, 802x_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, 880static Window
858 0, 1, False, XA_WINDOW, 881x_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
885static int 919static 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,