aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-03-20 09:53:52 +0800
committerPo Lu2022-03-20 09:53:52 +0800
commit77f5eb874b70ab78ca4daf3adf30f18d002db439 (patch)
treedec5e7d164ef4565af0ade2be1c9852982e7e24e /src
parentd2ac7447db52f492f9cbb52566de2e452c8bc65d (diff)
downloademacs-77f5eb874b70ab78ca4daf3adf30f18d002db439.tar.gz
emacs-77f5eb874b70ab78ca4daf3adf30f18d002db439.zip
Improve behaviour of drag-n-drop during window manager operations
* src/xterm.c (x_dnd_begin_drag_and_drop): Select for some events on the root window. (x_dnd_update_state): New function. (handle_one_xevent): Call that function when we get some events from the root window substructure or the window manager. (x_term_init): New atom `_NET_CLIENT_LIST_STACKING'. * src/xterm.h (struct x_display_info): New atom `_NET_CLIENT_LIST_STACKING'.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c107
-rw-r--r--src/xterm.h2
2 files changed, 108 insertions, 1 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 4f8accbda3a..3e888407b3b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1149,6 +1149,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
1149#ifdef HAVE_X_I18N 1149#ifdef HAVE_X_I18N
1150 XIC ic = FRAME_XIC (f); 1150 XIC ic = FRAME_XIC (f);
1151#endif 1151#endif
1152 XWindowAttributes root_window_attrs;
1152 1153
1153 struct input_event hold_quit; 1154 struct input_event hold_quit;
1154 char *atom_name; 1155 char *atom_name;
@@ -1187,7 +1188,21 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
1187 current_count = 0; 1188 current_count = 0;
1188#endif 1189#endif
1189 1190
1191 /* Now select for SubstructureNotifyMask and PropertyNotifyMask on
1192 the root window, so we can get notified when window stacking
1193 changes, a common operation during drag-and-drop. */
1194
1190 block_input (); 1195 block_input ();
1196 XGetWindowAttributes (FRAME_X_DISPLAY (f),
1197 FRAME_DISPLAY_INFO (f)->root_window,
1198 &root_window_attrs);
1199
1200 XSelectInput (FRAME_X_DISPLAY (f),
1201 FRAME_DISPLAY_INFO (f)->root_window,
1202 root_window_attrs.your_event_mask
1203 | SubstructureNotifyMask
1204 | PropertyChangeMask);
1205
1191#ifdef HAVE_X_I18N 1206#ifdef HAVE_X_I18N
1192 /* Make sure no events get filtered when XInput 2 is enabled. 1207 /* Make sure no events get filtered when XInput 2 is enabled.
1193 Otherwise, the ibus XIM server gets very confused. */ 1208 Otherwise, the ibus XIM server gets very confused. */
@@ -1230,6 +1245,10 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
1230#ifdef HAVE_X_I18N 1245#ifdef HAVE_X_I18N
1231 FRAME_XIC (f) = ic; 1246 FRAME_XIC (f) = ic;
1232#endif 1247#endif
1248 /* Restore the old event mask. */
1249 XSelectInput (FRAME_X_DISPLAY (f),
1250 FRAME_DISPLAY_INFO (f)->root_window,
1251 root_window_attrs.your_event_mask);
1233 unblock_input (); 1252 unblock_input ();
1234 quit (); 1253 quit ();
1235 } 1254 }
@@ -1243,6 +1262,11 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
1243 current_hold_quit = NULL; 1262 current_hold_quit = NULL;
1244#endif 1263#endif
1245 1264
1265 /* Restore the old event mask. */
1266 XSelectInput (FRAME_X_DISPLAY (f),
1267 FRAME_DISPLAY_INFO (f)->root_window,
1268 root_window_attrs.your_event_mask);
1269
1246 unblock_input (); 1270 unblock_input ();
1247 1271
1248 if (x_dnd_return_frame == 3) 1272 if (x_dnd_return_frame == 3)
@@ -10566,6 +10590,74 @@ mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc)
10566 } 10590 }
10567} 10591}
10568 10592
10593/* Get the window underneath the pointer, see if it moved, and update
10594 the DND state accordingly. */
10595static void
10596x_dnd_update_state (struct x_display_info *dpyinfo)
10597{
10598 int root_x, root_y, dummy_x, dummy_y, target_proto;
10599 unsigned int dummy_mask;
10600 Window dummy, dummy_child, target;
10601
10602 puts ("us");
10603
10604 if (XQueryPointer (dpyinfo->display,
10605 dpyinfo->root_window,
10606 &dummy, &dummy_child,
10607 &root_x, &root_y,
10608 &dummy_x, &dummy_y,
10609 &dummy_mask))
10610 {
10611 target = x_dnd_get_target_window (dpyinfo, root_x,
10612 root_y, &target_proto);
10613
10614 if (target != x_dnd_last_seen_window)
10615 {
10616 if (x_dnd_last_seen_window != None
10617 && x_dnd_last_protocol_version != -1
10618 && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame))
10619 x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window);
10620
10621 if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame)
10622 && x_dnd_return_frame == 1)
10623 x_dnd_return_frame = 2;
10624
10625 if (x_dnd_return_frame == 2
10626 && x_any_window_to_frame (dpyinfo, target))
10627 {
10628 x_dnd_in_progress = false;
10629 x_dnd_return_frame_object
10630 = x_any_window_to_frame (dpyinfo, target);
10631 x_dnd_return_frame = 3;
10632 }
10633
10634 x_dnd_last_seen_window = target;
10635 x_dnd_last_protocol_version = target_proto;
10636
10637 if (target != None && x_dnd_last_protocol_version != -1)
10638 x_dnd_send_enter (x_dnd_frame, target,
10639 x_dnd_last_protocol_version);
10640 }
10641
10642 if (x_dnd_last_protocol_version != -1 && target != None)
10643 x_dnd_send_position (x_dnd_frame, target,
10644 x_dnd_last_protocol_version,
10645 root_x, root_y, x_dnd_selection_timestamp,
10646 dpyinfo->Xatom_XdndActionCopy);
10647 }
10648 /* The pointer moved out of the screen. */
10649 else if (x_dnd_last_protocol_version)
10650 {
10651 if (x_dnd_last_seen_window != None
10652 && x_dnd_last_protocol_version != -1)
10653 x_dnd_send_leave (x_dnd_frame,
10654 x_dnd_last_seen_window);
10655
10656 x_dnd_in_progress = false;
10657 x_dnd_frame = NULL;
10658 }
10659}
10660
10569/* Handles the XEvent EVENT on display DPYINFO. 10661/* Handles the XEvent EVENT on display DPYINFO.
10570 10662
10571 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. 10663 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
@@ -11006,6 +11098,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
11006 } 11098 }
11007 } 11099 }
11008 11100
11101 if (event->xproperty.window == dpyinfo->root_window
11102 && (event->xproperty.atom == dpyinfo->Xatom_net_client_list_stacking
11103 || event->xproperty.atom == dpyinfo->Xatom_net_current_desktop)
11104 && x_dnd_in_progress)
11105 x_dnd_update_state (dpyinfo);
11106
11009 x_handle_property_notify (&event->xproperty); 11107 x_handle_property_notify (&event->xproperty);
11010 xft_settings_event (dpyinfo, event); 11108 xft_settings_event (dpyinfo, event);
11011 goto OTHER; 11109 goto OTHER;
@@ -11219,6 +11317,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
11219 if (xg_is_menu_window (dpyinfo->display, event->xmap.window)) 11317 if (xg_is_menu_window (dpyinfo->display, event->xmap.window))
11220 popup_activated_flag = 1; 11318 popup_activated_flag = 1;
11221#endif 11319#endif
11320
11321 if (x_dnd_in_progress)
11322 x_dnd_update_state (dpyinfo);
11222 /* We use x_top_window_to_frame because map events can 11323 /* We use x_top_window_to_frame because map events can
11223 come for sub-windows and they don't mean that the 11324 come for sub-windows and they don't mean that the
11224 frame is visible. */ 11325 frame is visible. */
@@ -12181,6 +12282,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
12181#endif 12282#endif
12182 12283
12183 } 12284 }
12285
12286 if (x_dnd_in_progress)
12287 x_dnd_update_state (dpyinfo);
12184 goto OTHER; 12288 goto OTHER;
12185 12289
12186 case ButtonRelease: 12290 case ButtonRelease:
@@ -12460,6 +12564,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
12460 break; 12564 break;
12461 12565
12462 case CirculateNotify: 12566 case CirculateNotify:
12567 if (x_dnd_in_progress)
12568 x_dnd_update_state (dpyinfo);
12463 goto OTHER; 12569 goto OTHER;
12464 12570
12465 case CirculateRequest: 12571 case CirculateRequest:
@@ -18801,6 +18907,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
18801 ATOM_REFS_INIT ("_NET_WM_FRAME_DRAWN", Xatom_net_wm_frame_drawn) 18907 ATOM_REFS_INIT ("_NET_WM_FRAME_DRAWN", Xatom_net_wm_frame_drawn)
18802 ATOM_REFS_INIT ("_NET_WM_USER_TIME", Xatom_net_wm_user_time) 18908 ATOM_REFS_INIT ("_NET_WM_USER_TIME", Xatom_net_wm_user_time)
18803 ATOM_REFS_INIT ("_NET_WM_USER_TIME_WINDOW", Xatom_net_wm_user_time_window) 18909 ATOM_REFS_INIT ("_NET_WM_USER_TIME_WINDOW", Xatom_net_wm_user_time_window)
18910 ATOM_REFS_INIT ("_NET_CLIENT_LIST_STACKING", Xatom_net_client_list_stacking)
18804 /* Session management */ 18911 /* Session management */
18805 ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID) 18912 ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID)
18806 ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop) 18913 ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop)
diff --git a/src/xterm.h b/src/xterm.h
index ed612c3c1e9..2a11f87e167 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -550,7 +550,7 @@ struct x_display_info
550 Xatom_net_workarea, Xatom_net_wm_opaque_region, Xatom_net_wm_ping, 550 Xatom_net_workarea, Xatom_net_wm_opaque_region, Xatom_net_wm_ping,
551 Xatom_net_wm_sync_request, Xatom_net_wm_sync_request_counter, 551 Xatom_net_wm_sync_request, Xatom_net_wm_sync_request_counter,
552 Xatom_net_wm_frame_drawn, Xatom_net_wm_user_time, 552 Xatom_net_wm_frame_drawn, Xatom_net_wm_user_time,
553 Xatom_net_wm_user_time_window; 553 Xatom_net_wm_user_time_window, Xatom_net_client_list_stacking;
554 554
555 /* XSettings atoms and windows. */ 555 /* XSettings atoms and windows. */
556 Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr; 556 Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;