diff options
| author | Po Lu | 2022-03-31 21:53:04 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-31 21:53:04 +0800 |
| commit | 948181df9cbdcc8845fc3662e2007d8e09f48c71 (patch) | |
| tree | b958de406affe93d2584793483f88e7c51b663d2 /src | |
| parent | 1bd14387027d5fa93ccbc38b6e4ce715c916bbc6 (diff) | |
| download | emacs-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.c | 99 |
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 | ||
| 2144 | static int | ||
| 2145 | x_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 | |||
| 2144 | static Window | 2230 | static Window |
| 2145 | x_dnd_get_target_window (struct x_display_info *dpyinfo, | 2231 | x_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) |