aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-03-31 21:53:04 +0800
committerPo Lu2022-03-31 21:53:04 +0800
commit948181df9cbdcc8845fc3662e2007d8e09f48c71 (patch)
treeb958de406affe93d2584793483f88e7c51b663d2 /src
parent1bd14387027d5fa93ccbc38b6e4ce715c916bbc6 (diff)
downloademacs-948181df9cbdcc8845fc3662e2007d8e09f48c71.tar.gz
emacs-948181df9cbdcc8845fc3662e2007d8e09f48c71.zip
Fix Motif DND on window managers that don't support client lists
* src/xterm.c (x_dnd_compute_toplevels): Fix usage of `x_uncatch_errors_after_check'. (x_dnd_get_wm_state_and_proto): New function. (x_dnd_get_target_window): Also return first toplevel window found.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c99
1 files changed, 98 insertions, 1 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 2f53bb469b3..df9fe1fe8c7 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1674,7 +1674,7 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
1674 == Success) 1674 == Success)
1675 && !x_had_errors_p (dpyinfo->display) 1675 && !x_had_errors_p (dpyinfo->display)
1676 && wmstate_data && wmstate_items == 2 && format == 32); 1676 && wmstate_data && wmstate_items == 2 && format == 32);
1677 x_uncatch_errors_after_check (); 1677 x_uncatch_errors ();
1678#else 1678#else
1679 rc = true; 1679 rc = true;
1680 1680
@@ -2141,6 +2141,92 @@ x_dnd_get_target_window_1 (struct x_display_info *dpyinfo,
2141 return None; 2141 return None;
2142} 2142}
2143 2143
2144static int
2145x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo,
2146 Window window, int *wmstate_out,
2147 int *proto_out)
2148{
2149#ifndef USE_XCB
2150 Atom type;
2151 int format, rc;
2152 unsigned long nitems, bytes_after;
2153 unsigned char *data = NULL;
2154
2155 x_catch_errors (dpyinfo->display);
2156 rc = ((XGetWindowProperty (dpyinfo->display, window,
2157 dpyinfo->Xatom_wm_state,
2158 0, 2, False, AnyPropertyType,
2159 &type, &format, &nitems,
2160 &bytes_after, &data)
2161 == Success)
2162 && !x_had_errors_p (dpyinfo->display)
2163 && data && nitems == 2 && format == 32);
2164 x_uncatch_errors ();
2165
2166 if (rc)
2167 {
2168 *wmstate_out = *(unsigned long *) data;
2169 *proto_out = x_dnd_get_window_proto (dpyinfo, window);
2170 }
2171
2172 if (data)
2173 XFree (data);
2174
2175 return rc;
2176#else
2177 xcb_get_property_cookie_t wmstate_cookie;
2178 xcb_get_property_cookie_t xdnd_proto_cookie;
2179 xcb_get_property_reply_t *reply;
2180 xcb_generic_error_t *error;
2181 int rc;
2182
2183 rc = true;
2184
2185 wmstate_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
2186 (xcb_window_t) window,
2187 (xcb_atom_t) dpyinfo->Xatom_wm_state,
2188 XCB_ATOM_ANY, 0, 2);
2189 xdnd_proto_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
2190 (xcb_window_t) window,
2191 (xcb_atom_t) dpyinfo->Xatom_XdndAware,
2192 XCB_ATOM_ATOM, 0, 1);
2193
2194 reply = xcb_get_property_reply (dpyinfo->xcb_connection,
2195 wmstate_cookie, &error);
2196
2197 if (!reply)
2198 free (error), rc = false;
2199 else
2200 {
2201 if (reply->format != 32
2202 || xcb_get_property_value_length (reply) != 8)
2203 rc = false;
2204 else
2205 *wmstate_out = *(uint32_t *) xcb_get_property_value (reply);
2206
2207 free (reply);
2208 }
2209
2210 reply = xcb_get_property_reply (dpyinfo->xcb_connection,
2211 xdnd_proto_cookie, &error);
2212
2213 if (!reply)
2214 free (error);
2215 else
2216 {
2217 if (reply->format == 32
2218 && xcb_get_property_value_length (reply) >= 4)
2219 *proto_out = *(uint32_t *) xcb_get_property_value (reply);
2220 else
2221 *proto_out = -1;
2222
2223 free (reply);
2224 }
2225
2226 return rc;
2227#endif
2228}
2229
2144static Window 2230static Window
2145x_dnd_get_target_window (struct x_display_info *dpyinfo, 2231x_dnd_get_target_window (struct x_display_info *dpyinfo,
2146 int root_x, int root_y, int *proto_out) 2232 int root_x, int root_y, int *proto_out)
@@ -2151,6 +2237,8 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo,
2151 Window overlay_window; 2237 Window overlay_window;
2152 XWindowAttributes attrs; 2238 XWindowAttributes attrs;
2153#endif 2239#endif
2240 int wmstate;
2241
2154 child_return = dpyinfo->root_window; 2242 child_return = dpyinfo->root_window;
2155 dest_x_return = root_x; 2243 dest_x_return = root_x;
2156 dest_y_return = root_y; 2244 dest_y_return = root_y;
@@ -2270,6 +2358,15 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo,
2270 2358
2271 if (child_return) 2359 if (child_return)
2272 { 2360 {
2361 if (x_dnd_get_wm_state_and_proto (dpyinfo, child_return,
2362 &wmstate, &proto))
2363 {
2364 *proto_out = proto;
2365 x_uncatch_errors ();
2366
2367 return child_return;
2368 }
2369
2273 proto = x_dnd_get_window_proto (dpyinfo, child_return); 2370 proto = x_dnd_get_window_proto (dpyinfo, child_return);
2274 2371
2275 if (proto != -1) 2372 if (proto != -1)