From: Po Lu Date: Thu, 26 May 2022 13:00:17 +0000 (+0800) Subject: Handle alternate actions for Motif drop targets X-Git-Tag: emacs-29.0.90~1910^2~415 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e490b80a105b82870e5571eaa3cfa5bc3ad936b0;p=emacs.git Handle alternate actions for Motif drop targets * src/xterm.c (xm_side_effect_from_action): Handle `XdndActionAsk'. (xm_operations_from_actions): New function. (xm_send_top_level_leave_message, x_dnd_cleanup_drag_and_drop) (x_dnd_update_state, handle_one_xevent, x_connection_closed): Use those actions when building a side effect. (x_dnd_begin_drag_and_drop): Keep track of the set of alternative drag-and-drop actions. --- diff --git a/src/xterm.c b/src/xterm.c index 9826f2fbd85..d949439d188 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1119,6 +1119,14 @@ static Atom x_dnd_action; in `x_dnd_action' upon completion of a drop. */ static Atom x_dnd_wanted_action; +/* The set of optional actions available to a Motif drop target + computed at the start of the drag-and-drop operation. */ +static uint8_t x_dnd_motif_operations; + +/* The preferred optional action out of that set. Only takes effect + if `x_dnd_action' is XdndAsk. */ +static uint8_t x_dnd_first_motif_operation; + /* Array of selection targets available to the drop target. */ static Atom *x_dnd_targets = NULL; @@ -1405,10 +1413,34 @@ xm_side_effect_from_action (struct x_display_info *dpyinfo, Atom action) return XM_DRAG_MOVE; else if (action == dpyinfo->Xatom_XdndActionLink) return XM_DRAG_LINK; + else if (action == dpyinfo->Xatom_XdndActionAsk) + return x_dnd_first_motif_operation; return XM_DRAG_NOOP; } +static uint8_t +xm_operations_from_actions (struct x_display_info *dpyinfo, + Atom *ask_actions, int n_ask_actions) +{ + int i; + uint8_t flags; + + flags = 0; + + for (i = 0; i < n_ask_actions; ++i) + { + if (ask_actions[i] == dpyinfo->Xatom_XdndActionCopy) + flags |= XM_DRAG_COPY; + else if (ask_actions[i] == dpyinfo->Xatom_XdndActionMove) + flags |= XM_DRAG_MOVE; + else if (ask_actions[i] == dpyinfo->Xatom_XdndActionLink) + flags |= XM_DRAG_LINK; + } + + return flags; +} + static int xm_read_targets_table_header (uint8_t *bytes, ptrdiff_t length, xm_targets_table_header *header_return, @@ -2038,7 +2070,7 @@ xm_send_top_level_leave_message (struct x_display_info *dpyinfo, Window source, mmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST; mmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, x_dnd_wanted_action), - XM_DROP_SITE_NONE, XM_DRAG_NOOP, + XM_DROP_SITE_NONE, x_dnd_motif_operations, XM_DROP_ACTION_DROP_CANCEL); mmsg.timestamp = dmsg->timestamp; mmsg.x = 65535; @@ -3904,9 +3936,7 @@ x_dnd_cleanup_drag_and_drop (void *frame) dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, XM_DROP_ACTION_DROP_CANCEL); dmsg.x = 0; dmsg.y = 0; @@ -10361,8 +10391,21 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, else x_dnd_selection_timestamp = XFIXNUM (ltimestamp); + x_dnd_motif_operations + = xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), xaction); + + x_dnd_first_motif_operation = XM_DRAG_NOOP; + if (n_ask_actions) { + x_dnd_motif_operations + = xm_operations_from_actions (FRAME_DISPLAY_INFO (f), + ask_action_list, + n_ask_actions); + x_dnd_first_motif_operation + = xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), + ask_action_list[0]); + ask_actions = NULL; end = 0; count = SPECPDL_INDEX (); @@ -10609,9 +10652,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, XM_DROP_ACTION_DROP_CANCEL); dmsg.x = 0; dmsg.y = 0; @@ -10683,9 +10724,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, XM_DROP_ACTION_DROP_CANCEL); dmsg.x = 0; dmsg.y = 0; @@ -14643,9 +14682,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp) dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (dpyinfo, - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, (!x_dnd_xm_use_help ? XM_DROP_ACTION_DROP : XM_DROP_ACTION_DROP_HELP)); @@ -14677,9 +14714,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp) dsmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (dpyinfo, - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, XM_DROP_ACTION_DROP_CANCEL); dsmsg.x = 0; dsmsg.y = 0; @@ -16579,7 +16614,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST; dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, x_dnd_wanted_action), - XM_DROP_SITE_NONE, XM_DRAG_NOOP, + XM_DROP_SITE_NONE, x_dnd_motif_operations, XM_DROP_ACTION_DROP_CANCEL); dmsg.timestamp = event->xmotion.time; dmsg.x = event->xmotion.x_root; @@ -16648,9 +16683,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST; dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (dpyinfo, - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, (!x_dnd_xm_use_help ? XM_DROP_ACTION_DROP : XM_DROP_ACTION_DROP_HELP)); @@ -17182,9 +17215,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (dpyinfo, - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, (!x_dnd_xm_use_help ? XM_DROP_ACTION_DROP : XM_DROP_ACTION_DROP_HELP)); @@ -18204,7 +18235,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, x_dnd_wanted_action), - XM_DROP_SITE_NONE, XM_DRAG_NOOP, + XM_DROP_SITE_NONE, x_dnd_motif_operations, XM_DROP_ACTION_DROP_CANCEL); dmsg.timestamp = xev->time; dmsg.x = lrint (xev->root_x); @@ -18287,9 +18318,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (dpyinfo, - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, (!x_dnd_xm_use_help ? XM_DROP_ACTION_DROP : XM_DROP_ACTION_DROP_HELP)); @@ -18480,9 +18509,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo, x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (dpyinfo, - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, (!x_dnd_xm_use_help ? XM_DROP_ACTION_DROP : XM_DROP_ACTION_DROP_HELP)); @@ -21311,9 +21338,7 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), x_dnd_wanted_action), - XM_DROP_SITE_VALID, - xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), - x_dnd_wanted_action), + XM_DROP_SITE_VALID, x_dnd_motif_operations, XM_DROP_ACTION_DROP_CANCEL); dmsg.x = 0; dmsg.y = 0;