aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-03-26 12:14:52 +0800
committerPo Lu2022-03-26 12:14:52 +0800
commit98952340bd225d34a0f2f5f32a385dda30e87909 (patch)
tree77437c11adb086cf01a07a73bde83b24ebff0782 /src
parent66f6324a58a9580f8a3f2f53532838c463581999 (diff)
downloademacs-98952340bd225d34a0f2f5f32a385dda30e87909.tar.gz
emacs-98952340bd225d34a0f2f5f32a385dda30e87909.zip
Avoid excessive synchronization when initiating drag-and-drop
* src/xterm.c (x_dnd_compute_toplevels): Use XCB to get WM state, attributes, geometry and to translate coordinates. This avoids 4 calls to XSync.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c142
1 files changed, 138 insertions, 4 deletions
diff --git a/src/xterm.c b/src/xterm.c
index deb6d62a27e..e20efd67c79 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -887,12 +887,31 @@ static int
887x_dnd_compute_toplevels (struct x_display_info *dpyinfo) 887x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
888{ 888{
889 Atom type; 889 Atom type;
890 Window *toplevels, child; 890 Window *toplevels;
891 int format, rc, dest_x, dest_y; 891 int format, rc;
892 unsigned long nitems, wmstate_items, bytes_after, *wmstate; 892 unsigned long nitems, bytes_after;
893 unsigned char *data = NULL, *wmstate_data = NULL;
894 unsigned long i; 893 unsigned long i;
894 unsigned char *data = NULL;
895
896#ifndef USE_XCB
897 int dest_x, dest_y;
898 unsigned long *wmstate;
899 unsigned long wmstate_items;
900 unsigned char *wmstate_data = NULL;
895 XWindowAttributes attrs; 901 XWindowAttributes attrs;
902 Window child;
903#else
904 uint32_t *wmstate;
905 xcb_get_window_attributes_cookie_t *window_attribute_cookies;
906 xcb_translate_coordinates_cookie_t *translate_coordinate_cookies;
907 xcb_get_property_cookie_t *get_property_cookies;
908 xcb_get_geometry_cookie_t *get_geometry_cookies;
909 xcb_get_window_attributes_reply_t attrs, *attrs_reply;
910 xcb_translate_coordinates_reply_t *coordinates_reply;
911 xcb_get_property_reply_t *property_reply;
912 xcb_get_geometry_reply_t *geometry_reply;
913 xcb_generic_error_t *error;
914#endif
896 struct x_client_list_window *tem; 915 struct x_client_list_window *tem;
897#ifdef HAVE_XSHAPE 916#ifdef HAVE_XSHAPE
898 int count, ordering; 917 int count, ordering;
@@ -915,10 +934,40 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
915 934
916 toplevels = (Window *) data; 935 toplevels = (Window *) data;
917 936
937#ifdef USE_XCB
938 window_attribute_cookies
939 = alloca (sizeof *window_attribute_cookies * nitems);
940 translate_coordinate_cookies
941 = alloca (sizeof *translate_coordinate_cookies * nitems);
942 get_property_cookies
943 = alloca (sizeof *get_property_cookies * nitems);
944 get_geometry_cookies
945 = alloca (sizeof *get_geometry_cookies * nitems);
946
947 for (i = 0; i < nitems; ++i)
948 {
949 window_attribute_cookies[i]
950 = xcb_get_window_attributes (dpyinfo->xcb_connection,
951 (xcb_window_t) toplevels[i]);
952 translate_coordinate_cookies[i]
953 = xcb_translate_coordinates (dpyinfo->xcb_connection,
954 (xcb_window_t) toplevels[i],
955 (xcb_window_t) dpyinfo->root_window,
956 0, 0);
957 get_property_cookies[i]
958 = xcb_get_property (dpyinfo->xcb_connection, 0, (xcb_window_t) toplevels[i],
959 (xcb_atom_t) dpyinfo->Xatom_wm_state, XCB_ATOM_ANY,
960 0, 2);
961 get_geometry_cookies[i]
962 = xcb_get_geometry (dpyinfo->xcb_connection, (xcb_window_t) toplevels[i]);
963 }
964#endif
965
918 /* Actually right because _NET_CLIENT_LIST_STACKING has bottom-up 966 /* Actually right because _NET_CLIENT_LIST_STACKING has bottom-up
919 order. */ 967 order. */
920 for (i = 0; i < nitems; ++i) 968 for (i = 0; i < nitems; ++i)
921 { 969 {
970#ifndef USE_XCB
922 x_catch_errors (dpyinfo->display); 971 x_catch_errors (dpyinfo->display);
923 rc = (XGetWindowAttributes (dpyinfo->display, 972 rc = (XGetWindowAttributes (dpyinfo->display,
924 toplevels[i], &attrs) 973 toplevels[i], &attrs)
@@ -941,27 +990,98 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
941 && !x_had_errors_p (dpyinfo->display) 990 && !x_had_errors_p (dpyinfo->display)
942 && wmstate_data && wmstate_items == 2 && format == 32); 991 && wmstate_data && wmstate_items == 2 && format == 32);
943 x_uncatch_errors_after_check (); 992 x_uncatch_errors_after_check ();
993#else
994 rc = true;
995
996 attrs_reply
997 = xcb_get_window_attributes_reply (dpyinfo->xcb_connection,
998 window_attribute_cookies[i],
999 &error);
1000
1001 if (!attrs_reply)
1002 {
1003 rc = false;
1004 free (error);
1005 }
1006
1007 coordinates_reply
1008 = xcb_translate_coordinates_reply (dpyinfo->xcb_connection,
1009 translate_coordinate_cookies[i],
1010 &error);
1011
1012 if (!coordinates_reply)
1013 {
1014 rc = false;
1015 free (error);
1016 }
1017
1018 property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
1019 get_property_cookies[i],
1020 &error);
1021
1022 if (!property_reply)
1023 {
1024 rc = false;
1025 free (error);
1026 }
1027
1028 if (xcb_get_property_value_length (property_reply) != 8
1029 || property_reply->format != 32)
1030 rc = false;
1031
1032 geometry_reply = xcb_get_geometry_reply (dpyinfo->xcb_connection,
1033 get_geometry_cookies[i],
1034 &error);
1035
1036 if (!geometry_reply)
1037 {
1038 rc = false;
1039 free (error);
1040 }
1041#endif
944 1042
945 if (rc) 1043 if (rc)
946 { 1044 {
1045#ifdef USE_XCB
1046 wmstate = (uint32_t *) xcb_get_property_value (property_reply);
1047 attrs = *attrs_reply;
1048#else
947 wmstate = (unsigned long *) wmstate_data; 1049 wmstate = (unsigned long *) wmstate_data;
1050#endif
948 1051
949 tem = xmalloc (sizeof *tem); 1052 tem = xmalloc (sizeof *tem);
950 tem->window = toplevels[i]; 1053 tem->window = toplevels[i];
951 tem->dpy = dpyinfo->display; 1054 tem->dpy = dpyinfo->display;
1055#ifndef USE_XCB
952 tem->x = dest_x; 1056 tem->x = dest_x;
953 tem->y = dest_y; 1057 tem->y = dest_y;
954 tem->width = attrs.width + attrs.border_width; 1058 tem->width = attrs.width + attrs.border_width;
955 tem->height = attrs.height + attrs.border_width; 1059 tem->height = attrs.height + attrs.border_width;
1060#else
1061 tem->x = (coordinates_reply->dst_x
1062 - geometry_reply->border_width);
1063 tem->y = (coordinates_reply->dst_y
1064 - geometry_reply->border_width);
1065 tem->width = (geometry_reply->width
1066 + geometry_reply->border_width);
1067 tem->height = (geometry_reply->height
1068 + geometry_reply->border_width);
1069#endif
956 tem->mapped_p = (attrs.map_state != IsUnmapped); 1070 tem->mapped_p = (attrs.map_state != IsUnmapped);
957 tem->next = x_dnd_toplevels; 1071 tem->next = x_dnd_toplevels;
958 tem->previous_event_mask = attrs.your_event_mask; 1072 tem->previous_event_mask = attrs.your_event_mask;
959 tem->wm_state = wmstate[0]; 1073 tem->wm_state = wmstate[0];
960 1074
1075#ifndef USE_XCB
961 XFree (wmstate_data); 1076 XFree (wmstate_data);
1077#endif
962 1078
963#ifdef HAVE_XSHAPE 1079#ifdef HAVE_XSHAPE
1080#ifndef USE_XCB
964 tem->border_width = attrs.border_width; 1081 tem->border_width = attrs.border_width;
1082#else
1083 tem->border_width = geometry_reply->border_width;
1084#endif
965 tem->n_bounding_rects = -1; 1085 tem->n_bounding_rects = -1;
966 tem->n_input_rects = -1; 1086 tem->n_input_rects = -1;
967 1087
@@ -1044,6 +1164,20 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
1044 1164
1045 x_dnd_toplevels = tem; 1165 x_dnd_toplevels = tem;
1046 } 1166 }
1167
1168#ifdef USE_XCB
1169 if (attrs_reply)
1170 free (attrs_reply);
1171
1172 if (coordinates_reply)
1173 free (coordinates_reply);
1174
1175 if (property_reply)
1176 free (property_reply);
1177
1178 if (geometry_reply)
1179 free (geometry_reply);
1180#endif
1047 } 1181 }
1048 1182
1049 return 0; 1183 return 0;