diff options
| author | Po Lu | 2022-03-23 09:21:04 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-23 09:21:04 +0800 |
| commit | 8b853b3f98a9e6a81a2d41a668d560cc9105836f (patch) | |
| tree | 85612df06e180ea6361dd3aef125d172b7b0858d /src | |
| parent | eb25ae3f2db2543bc4c31fbddb4c719e43913ff8 (diff) | |
| download | emacs-8b853b3f98a9e6a81a2d41a668d560cc9105836f.tar.gz emacs-8b853b3f98a9e6a81a2d41a668d560cc9105836f.zip | |
Reported taken action correctly when dragging to another frame on X
* src/xterm.c (x_dnd_cleanup_drag_and_drop, x_dnd_update_state)
(x_free_frame_resources, handle_one_xevent): Set
`x_dnd_end_window'.
(x_dnd_begin_drag_and_drop): Return `XdndActionPrivate' if the
drop landed on one of our own frames.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 383 |
1 files changed, 205 insertions, 178 deletions
diff --git a/src/xterm.c b/src/xterm.c index a7d84455024..550515aeff7 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -805,6 +805,7 @@ static int x_dnd_return_frame; | |||
| 805 | static struct frame *x_dnd_return_frame_object; | 805 | static struct frame *x_dnd_return_frame_object; |
| 806 | 806 | ||
| 807 | static Window x_dnd_last_seen_window; | 807 | static Window x_dnd_last_seen_window; |
| 808 | static Window x_dnd_end_window; | ||
| 808 | static int x_dnd_last_protocol_version; | 809 | static int x_dnd_last_protocol_version; |
| 809 | static Time x_dnd_selection_timestamp; | 810 | static Time x_dnd_selection_timestamp; |
| 810 | 811 | ||
| @@ -1173,6 +1174,8 @@ x_dnd_cleanup_drag_and_drop (void *frame) | |||
| 1173 | x_dnd_last_seen_window); | 1174 | x_dnd_last_seen_window); |
| 1174 | unblock_input (); | 1175 | unblock_input (); |
| 1175 | 1176 | ||
| 1177 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 1178 | x_dnd_last_seen_window = None; | ||
| 1176 | x_dnd_in_progress = false; | 1179 | x_dnd_in_progress = false; |
| 1177 | x_set_dnd_targets (NULL, 0); | 1180 | x_set_dnd_targets (NULL, 0); |
| 1178 | } | 1181 | } |
| @@ -1194,184 +1197,6 @@ x_dnd_cleanup_drag_and_drop (void *frame) | |||
| 1194 | x_dnd_frame = NULL; | 1197 | x_dnd_frame = NULL; |
| 1195 | } | 1198 | } |
| 1196 | 1199 | ||
| 1197 | Lisp_Object | ||
| 1198 | x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | ||
| 1199 | bool return_frame_p) | ||
| 1200 | { | ||
| 1201 | #ifndef USE_GTK | ||
| 1202 | XEvent next_event; | ||
| 1203 | int finish; | ||
| 1204 | #endif | ||
| 1205 | XWindowAttributes root_window_attrs; | ||
| 1206 | |||
| 1207 | struct input_event hold_quit; | ||
| 1208 | char *atom_name; | ||
| 1209 | Lisp_Object action, ltimestamp; | ||
| 1210 | specpdl_ref ref; | ||
| 1211 | |||
| 1212 | if (!FRAME_VISIBLE_P (f)) | ||
| 1213 | error ("Frame is invisible"); | ||
| 1214 | |||
| 1215 | if (x_dnd_in_progress || x_dnd_waiting_for_finish) | ||
| 1216 | error ("A drag-and-drop session is already in progress"); | ||
| 1217 | |||
| 1218 | ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f), | ||
| 1219 | QXdndSelection); | ||
| 1220 | |||
| 1221 | if (NILP (ltimestamp)) | ||
| 1222 | error ("No local value for XdndSelection"); | ||
| 1223 | |||
| 1224 | if (BIGNUMP (ltimestamp)) | ||
| 1225 | x_dnd_selection_timestamp = bignum_to_intmax (ltimestamp); | ||
| 1226 | else | ||
| 1227 | x_dnd_selection_timestamp = XFIXNUM (ltimestamp); | ||
| 1228 | |||
| 1229 | x_dnd_in_progress = true; | ||
| 1230 | x_dnd_frame = f; | ||
| 1231 | x_dnd_last_seen_window = FRAME_X_WINDOW (f); | ||
| 1232 | x_dnd_last_protocol_version = -1; | ||
| 1233 | x_dnd_mouse_rect_target = None; | ||
| 1234 | x_dnd_action = None; | ||
| 1235 | x_dnd_wanted_action = xaction; | ||
| 1236 | x_dnd_return_frame = 0; | ||
| 1237 | x_dnd_waiting_for_finish = false; | ||
| 1238 | |||
| 1239 | if (return_frame_p) | ||
| 1240 | x_dnd_return_frame = 1; | ||
| 1241 | |||
| 1242 | #ifdef USE_GTK | ||
| 1243 | current_count = 0; | ||
| 1244 | #endif | ||
| 1245 | |||
| 1246 | /* Now select for SubstructureNotifyMask and PropertyNotifyMask on | ||
| 1247 | the root window, so we can get notified when window stacking | ||
| 1248 | changes, a common operation during drag-and-drop. */ | ||
| 1249 | |||
| 1250 | block_input (); | ||
| 1251 | XGetWindowAttributes (FRAME_X_DISPLAY (f), | ||
| 1252 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 1253 | &root_window_attrs); | ||
| 1254 | |||
| 1255 | XSelectInput (FRAME_X_DISPLAY (f), | ||
| 1256 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 1257 | root_window_attrs.your_event_mask | ||
| 1258 | | SubstructureNotifyMask | ||
| 1259 | | PropertyChangeMask); | ||
| 1260 | |||
| 1261 | while (x_dnd_in_progress || x_dnd_waiting_for_finish) | ||
| 1262 | { | ||
| 1263 | hold_quit.kind = NO_EVENT; | ||
| 1264 | #ifdef USE_GTK | ||
| 1265 | current_finish = X_EVENT_NORMAL; | ||
| 1266 | current_hold_quit = &hold_quit; | ||
| 1267 | #endif | ||
| 1268 | |||
| 1269 | #ifndef USE_GTK | ||
| 1270 | XNextEvent (FRAME_X_DISPLAY (f), &next_event); | ||
| 1271 | |||
| 1272 | #ifdef HAVE_X_I18N | ||
| 1273 | #ifdef HAVE_XINPUT2 | ||
| 1274 | if (next_event.type != GenericEvent | ||
| 1275 | || !FRAME_DISPLAY_INFO (f)->supports_xi2 | ||
| 1276 | || (next_event.xgeneric.extension | ||
| 1277 | != FRAME_DISPLAY_INFO (f)->xi2_opcode)) | ||
| 1278 | { | ||
| 1279 | #endif | ||
| 1280 | if (!x_filter_event (FRAME_DISPLAY_INFO (f), &next_event)) | ||
| 1281 | handle_one_xevent (FRAME_DISPLAY_INFO (f), | ||
| 1282 | &next_event, &finish, &hold_quit); | ||
| 1283 | #ifdef HAVE_XINPUT2 | ||
| 1284 | } | ||
| 1285 | else | ||
| 1286 | handle_one_xevent (FRAME_DISPLAY_INFO (f), | ||
| 1287 | &next_event, &finish, &hold_quit); | ||
| 1288 | #endif | ||
| 1289 | #else | ||
| 1290 | handle_one_xevent (FRAME_DISPLAY_INFO (f), | ||
| 1291 | &next_event, &finish, &hold_quit); | ||
| 1292 | #endif | ||
| 1293 | #else | ||
| 1294 | gtk_main_iteration (); | ||
| 1295 | #endif | ||
| 1296 | |||
| 1297 | if (hold_quit.kind != NO_EVENT) | ||
| 1298 | { | ||
| 1299 | if (hold_quit.kind == SELECTION_REQUEST_EVENT) | ||
| 1300 | { | ||
| 1301 | x_dnd_old_window_attrs = root_window_attrs; | ||
| 1302 | x_dnd_unwind_flag = true; | ||
| 1303 | |||
| 1304 | ref = SPECPDL_INDEX (); | ||
| 1305 | record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f); | ||
| 1306 | x_handle_selection_event ((struct selection_input_event *) &hold_quit); | ||
| 1307 | x_dnd_unwind_flag = false; | ||
| 1308 | unbind_to (ref, Qnil); | ||
| 1309 | continue; | ||
| 1310 | } | ||
| 1311 | |||
| 1312 | if (x_dnd_in_progress) | ||
| 1313 | { | ||
| 1314 | if (x_dnd_last_seen_window != None | ||
| 1315 | && x_dnd_last_protocol_version != -1) | ||
| 1316 | x_dnd_send_leave (f, x_dnd_last_seen_window); | ||
| 1317 | |||
| 1318 | x_dnd_in_progress = false; | ||
| 1319 | x_dnd_frame = NULL; | ||
| 1320 | x_set_dnd_targets (NULL, 0); | ||
| 1321 | x_dnd_waiting_for_finish = false; | ||
| 1322 | } | ||
| 1323 | |||
| 1324 | FRAME_DISPLAY_INFO (f)->grabbed = 0; | ||
| 1325 | #ifdef USE_GTK | ||
| 1326 | current_hold_quit = NULL; | ||
| 1327 | #endif | ||
| 1328 | /* Restore the old event mask. */ | ||
| 1329 | XSelectInput (FRAME_X_DISPLAY (f), | ||
| 1330 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 1331 | root_window_attrs.your_event_mask); | ||
| 1332 | unblock_input (); | ||
| 1333 | quit (); | ||
| 1334 | } | ||
| 1335 | } | ||
| 1336 | x_set_dnd_targets (NULL, 0); | ||
| 1337 | x_dnd_waiting_for_finish = false; | ||
| 1338 | |||
| 1339 | #ifdef USE_GTK | ||
| 1340 | current_hold_quit = NULL; | ||
| 1341 | #endif | ||
| 1342 | |||
| 1343 | /* Restore the old event mask. */ | ||
| 1344 | XSelectInput (FRAME_X_DISPLAY (f), | ||
| 1345 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 1346 | root_window_attrs.your_event_mask); | ||
| 1347 | |||
| 1348 | unblock_input (); | ||
| 1349 | |||
| 1350 | if (x_dnd_return_frame == 3) | ||
| 1351 | { | ||
| 1352 | x_dnd_return_frame_object->mouse_moved = true; | ||
| 1353 | |||
| 1354 | XSETFRAME (action, x_dnd_return_frame_object); | ||
| 1355 | return action; | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | FRAME_DISPLAY_INFO (f)->grabbed = 0; | ||
| 1359 | |||
| 1360 | if (x_dnd_action != None) | ||
| 1361 | { | ||
| 1362 | block_input (); | ||
| 1363 | atom_name = XGetAtomName (FRAME_X_DISPLAY (f), | ||
| 1364 | x_dnd_action); | ||
| 1365 | action = intern (atom_name); | ||
| 1366 | XFree (atom_name); | ||
| 1367 | unblock_input (); | ||
| 1368 | |||
| 1369 | return action; | ||
| 1370 | } | ||
| 1371 | |||
| 1372 | return Qnil; | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | /* Flush display of frame F. */ | 1200 | /* Flush display of frame F. */ |
| 1376 | 1201 | ||
| 1377 | static void | 1202 | static void |
| @@ -7112,6 +6937,198 @@ x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc) | |||
| 7112 | 6937 | ||
| 7113 | #endif /* USE_X_TOOLKIT || USE_GTK */ | 6938 | #endif /* USE_X_TOOLKIT || USE_GTK */ |
| 7114 | 6939 | ||
| 6940 | /* This function is defined far away from the rest of the XDND code so | ||
| 6941 | it can utilize `x_any_window_to_frame'. */ | ||
| 6942 | |||
| 6943 | Lisp_Object | ||
| 6944 | x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | ||
| 6945 | bool return_frame_p) | ||
| 6946 | { | ||
| 6947 | #ifndef USE_GTK | ||
| 6948 | XEvent next_event; | ||
| 6949 | int finish; | ||
| 6950 | #endif | ||
| 6951 | XWindowAttributes root_window_attrs; | ||
| 6952 | |||
| 6953 | struct input_event hold_quit; | ||
| 6954 | char *atom_name; | ||
| 6955 | Lisp_Object action, ltimestamp; | ||
| 6956 | specpdl_ref ref; | ||
| 6957 | |||
| 6958 | if (!FRAME_VISIBLE_P (f)) | ||
| 6959 | error ("Frame is invisible"); | ||
| 6960 | |||
| 6961 | if (x_dnd_in_progress || x_dnd_waiting_for_finish) | ||
| 6962 | error ("A drag-and-drop session is already in progress"); | ||
| 6963 | |||
| 6964 | ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f), | ||
| 6965 | QXdndSelection); | ||
| 6966 | |||
| 6967 | if (NILP (ltimestamp)) | ||
| 6968 | error ("No local value for XdndSelection"); | ||
| 6969 | |||
| 6970 | if (BIGNUMP (ltimestamp)) | ||
| 6971 | x_dnd_selection_timestamp = bignum_to_intmax (ltimestamp); | ||
| 6972 | else | ||
| 6973 | x_dnd_selection_timestamp = XFIXNUM (ltimestamp); | ||
| 6974 | |||
| 6975 | x_dnd_in_progress = true; | ||
| 6976 | x_dnd_frame = f; | ||
| 6977 | x_dnd_last_seen_window = FRAME_X_WINDOW (f); | ||
| 6978 | x_dnd_last_protocol_version = -1; | ||
| 6979 | x_dnd_mouse_rect_target = None; | ||
| 6980 | x_dnd_action = None; | ||
| 6981 | x_dnd_wanted_action = xaction; | ||
| 6982 | x_dnd_return_frame = 0; | ||
| 6983 | x_dnd_waiting_for_finish = false; | ||
| 6984 | x_dnd_end_window = None; | ||
| 6985 | |||
| 6986 | if (return_frame_p) | ||
| 6987 | x_dnd_return_frame = 1; | ||
| 6988 | |||
| 6989 | #ifdef USE_GTK | ||
| 6990 | current_count = 0; | ||
| 6991 | #endif | ||
| 6992 | |||
| 6993 | /* Now select for SubstructureNotifyMask and PropertyNotifyMask on | ||
| 6994 | the root window, so we can get notified when window stacking | ||
| 6995 | changes, a common operation during drag-and-drop. */ | ||
| 6996 | |||
| 6997 | block_input (); | ||
| 6998 | XGetWindowAttributes (FRAME_X_DISPLAY (f), | ||
| 6999 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 7000 | &root_window_attrs); | ||
| 7001 | |||
| 7002 | XSelectInput (FRAME_X_DISPLAY (f), | ||
| 7003 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 7004 | root_window_attrs.your_event_mask | ||
| 7005 | | SubstructureNotifyMask | ||
| 7006 | | PropertyChangeMask); | ||
| 7007 | |||
| 7008 | while (x_dnd_in_progress || x_dnd_waiting_for_finish) | ||
| 7009 | { | ||
| 7010 | hold_quit.kind = NO_EVENT; | ||
| 7011 | #ifdef USE_GTK | ||
| 7012 | current_finish = X_EVENT_NORMAL; | ||
| 7013 | current_hold_quit = &hold_quit; | ||
| 7014 | #endif | ||
| 7015 | |||
| 7016 | #ifndef USE_GTK | ||
| 7017 | XNextEvent (FRAME_X_DISPLAY (f), &next_event); | ||
| 7018 | |||
| 7019 | #ifdef HAVE_X_I18N | ||
| 7020 | #ifdef HAVE_XINPUT2 | ||
| 7021 | if (next_event.type != GenericEvent | ||
| 7022 | || !FRAME_DISPLAY_INFO (f)->supports_xi2 | ||
| 7023 | || (next_event.xgeneric.extension | ||
| 7024 | != FRAME_DISPLAY_INFO (f)->xi2_opcode)) | ||
| 7025 | { | ||
| 7026 | #endif | ||
| 7027 | if (!x_filter_event (FRAME_DISPLAY_INFO (f), &next_event)) | ||
| 7028 | handle_one_xevent (FRAME_DISPLAY_INFO (f), | ||
| 7029 | &next_event, &finish, &hold_quit); | ||
| 7030 | #ifdef HAVE_XINPUT2 | ||
| 7031 | } | ||
| 7032 | else | ||
| 7033 | handle_one_xevent (FRAME_DISPLAY_INFO (f), | ||
| 7034 | &next_event, &finish, &hold_quit); | ||
| 7035 | #endif | ||
| 7036 | #else | ||
| 7037 | handle_one_xevent (FRAME_DISPLAY_INFO (f), | ||
| 7038 | &next_event, &finish, &hold_quit); | ||
| 7039 | #endif | ||
| 7040 | #else | ||
| 7041 | gtk_main_iteration (); | ||
| 7042 | #endif | ||
| 7043 | |||
| 7044 | if (hold_quit.kind != NO_EVENT) | ||
| 7045 | { | ||
| 7046 | if (hold_quit.kind == SELECTION_REQUEST_EVENT) | ||
| 7047 | { | ||
| 7048 | x_dnd_old_window_attrs = root_window_attrs; | ||
| 7049 | x_dnd_unwind_flag = true; | ||
| 7050 | |||
| 7051 | ref = SPECPDL_INDEX (); | ||
| 7052 | record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f); | ||
| 7053 | x_handle_selection_event ((struct selection_input_event *) &hold_quit); | ||
| 7054 | x_dnd_unwind_flag = false; | ||
| 7055 | unbind_to (ref, Qnil); | ||
| 7056 | continue; | ||
| 7057 | } | ||
| 7058 | |||
| 7059 | if (x_dnd_in_progress) | ||
| 7060 | { | ||
| 7061 | if (x_dnd_last_seen_window != None | ||
| 7062 | && x_dnd_last_protocol_version != -1) | ||
| 7063 | x_dnd_send_leave (f, x_dnd_last_seen_window); | ||
| 7064 | |||
| 7065 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 7066 | x_dnd_last_seen_window = None; | ||
| 7067 | x_dnd_in_progress = false; | ||
| 7068 | x_dnd_frame = NULL; | ||
| 7069 | x_set_dnd_targets (NULL, 0); | ||
| 7070 | x_dnd_waiting_for_finish = false; | ||
| 7071 | } | ||
| 7072 | |||
| 7073 | FRAME_DISPLAY_INFO (f)->grabbed = 0; | ||
| 7074 | #ifdef USE_GTK | ||
| 7075 | current_hold_quit = NULL; | ||
| 7076 | #endif | ||
| 7077 | /* Restore the old event mask. */ | ||
| 7078 | XSelectInput (FRAME_X_DISPLAY (f), | ||
| 7079 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 7080 | root_window_attrs.your_event_mask); | ||
| 7081 | unblock_input (); | ||
| 7082 | quit (); | ||
| 7083 | } | ||
| 7084 | } | ||
| 7085 | x_set_dnd_targets (NULL, 0); | ||
| 7086 | x_dnd_waiting_for_finish = false; | ||
| 7087 | |||
| 7088 | #ifdef USE_GTK | ||
| 7089 | current_hold_quit = NULL; | ||
| 7090 | #endif | ||
| 7091 | |||
| 7092 | /* Restore the old event mask. */ | ||
| 7093 | XSelectInput (FRAME_X_DISPLAY (f), | ||
| 7094 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 7095 | root_window_attrs.your_event_mask); | ||
| 7096 | |||
| 7097 | unblock_input (); | ||
| 7098 | |||
| 7099 | if (x_dnd_return_frame == 3) | ||
| 7100 | { | ||
| 7101 | x_dnd_return_frame_object->mouse_moved = true; | ||
| 7102 | |||
| 7103 | XSETFRAME (action, x_dnd_return_frame_object); | ||
| 7104 | return action; | ||
| 7105 | } | ||
| 7106 | |||
| 7107 | FRAME_DISPLAY_INFO (f)->grabbed = 0; | ||
| 7108 | |||
| 7109 | /* Emacs can't respond to DND events inside the nested event | ||
| 7110 | loop, so when dragging items to itself, always return | ||
| 7111 | XdndActionPrivate. */ | ||
| 7112 | if (x_dnd_end_window != None | ||
| 7113 | && (x_any_window_to_frame (FRAME_DISPLAY_INFO (f), | ||
| 7114 | x_dnd_end_window) != f)) | ||
| 7115 | return QXdndActionPrivate; | ||
| 7116 | |||
| 7117 | if (x_dnd_action != None) | ||
| 7118 | { | ||
| 7119 | block_input (); | ||
| 7120 | atom_name = XGetAtomName (FRAME_X_DISPLAY (f), | ||
| 7121 | x_dnd_action); | ||
| 7122 | action = intern (atom_name); | ||
| 7123 | XFree (atom_name); | ||
| 7124 | unblock_input (); | ||
| 7125 | |||
| 7126 | return action; | ||
| 7127 | } | ||
| 7128 | |||
| 7129 | return Qnil; | ||
| 7130 | } | ||
| 7131 | |||
| 7115 | /* The focus may have changed. Figure out if it is a real focus change, | 7132 | /* The focus may have changed. Figure out if it is a real focus change, |
| 7116 | by checking both FocusIn/Out and Enter/LeaveNotify events. | 7133 | by checking both FocusIn/Out and Enter/LeaveNotify events. |
| 7117 | 7134 | ||
| @@ -10698,6 +10715,8 @@ x_dnd_update_state (struct x_display_info *dpyinfo) | |||
| 10698 | if (x_dnd_return_frame == 2 | 10715 | if (x_dnd_return_frame == 2 |
| 10699 | && x_any_window_to_frame (dpyinfo, target)) | 10716 | && x_any_window_to_frame (dpyinfo, target)) |
| 10700 | { | 10717 | { |
| 10718 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 10719 | x_dnd_last_seen_window = None; | ||
| 10701 | x_dnd_in_progress = false; | 10720 | x_dnd_in_progress = false; |
| 10702 | x_dnd_return_frame_object | 10721 | x_dnd_return_frame_object |
| 10703 | = x_any_window_to_frame (dpyinfo, target); | 10722 | = x_any_window_to_frame (dpyinfo, target); |
| @@ -10728,6 +10747,8 @@ x_dnd_update_state (struct x_display_info *dpyinfo) | |||
| 10728 | x_dnd_send_leave (x_dnd_frame, | 10747 | x_dnd_send_leave (x_dnd_frame, |
| 10729 | x_dnd_last_seen_window); | 10748 | x_dnd_last_seen_window); |
| 10730 | 10749 | ||
| 10750 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 10751 | x_dnd_last_seen_window = None; | ||
| 10731 | x_dnd_in_progress = false; | 10752 | x_dnd_in_progress = false; |
| 10732 | x_dnd_frame = NULL; | 10753 | x_dnd_frame = NULL; |
| 10733 | } | 10754 | } |
| @@ -12047,6 +12068,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12047 | if (x_dnd_return_frame == 2 | 12068 | if (x_dnd_return_frame == 2 |
| 12048 | && x_any_window_to_frame (dpyinfo, target)) | 12069 | && x_any_window_to_frame (dpyinfo, target)) |
| 12049 | { | 12070 | { |
| 12071 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 12072 | x_dnd_last_seen_window = None; | ||
| 12050 | x_dnd_in_progress = false; | 12073 | x_dnd_in_progress = false; |
| 12051 | x_dnd_return_frame_object | 12074 | x_dnd_return_frame_object |
| 12052 | = x_any_window_to_frame (dpyinfo, target); | 12075 | = x_any_window_to_frame (dpyinfo, target); |
| @@ -12439,6 +12462,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12439 | 12462 | ||
| 12440 | if (dnd_grab && event->xbutton.type == ButtonRelease) | 12463 | if (dnd_grab && event->xbutton.type == ButtonRelease) |
| 12441 | { | 12464 | { |
| 12465 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 12442 | x_dnd_in_progress = false; | 12466 | x_dnd_in_progress = false; |
| 12443 | 12467 | ||
| 12444 | if (x_dnd_last_seen_window != None | 12468 | if (x_dnd_last_seen_window != None |
| @@ -13436,6 +13460,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 13436 | if (!dnd_grab | 13460 | if (!dnd_grab |
| 13437 | && xev->evtype == XI_ButtonRelease) | 13461 | && xev->evtype == XI_ButtonRelease) |
| 13438 | { | 13462 | { |
| 13463 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 13439 | x_dnd_in_progress = false; | 13464 | x_dnd_in_progress = false; |
| 13440 | 13465 | ||
| 13441 | if (x_dnd_last_seen_window != None | 13466 | if (x_dnd_last_seen_window != None |
| @@ -17571,6 +17596,8 @@ x_free_frame_resources (struct frame *f) | |||
| 17571 | x_dnd_send_leave (f, x_dnd_last_seen_window); | 17596 | x_dnd_send_leave (f, x_dnd_last_seen_window); |
| 17572 | unblock_input (); | 17597 | unblock_input (); |
| 17573 | 17598 | ||
| 17599 | x_dnd_end_window = x_dnd_last_seen_window; | ||
| 17600 | x_dnd_last_seen_window = None; | ||
| 17574 | x_dnd_in_progress = false; | 17601 | x_dnd_in_progress = false; |
| 17575 | x_dnd_waiting_for_finish = false; | 17602 | x_dnd_waiting_for_finish = false; |
| 17576 | x_dnd_frame = NULL; | 17603 | x_dnd_frame = NULL; |