diff options
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 250 |
1 files changed, 218 insertions, 32 deletions
diff --git a/src/xterm.c b/src/xterm.c index ab43a8ec517..5047f3066be 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -1398,6 +1398,15 @@ static int x_dnd_last_tooltip_x, x_dnd_last_tooltip_y; | |||
| 1398 | /* Whether or not those values are actually known yet. */ | 1398 | /* Whether or not those values are actually known yet. */ |
| 1399 | static bool x_dnd_last_tooltip_valid; | 1399 | static bool x_dnd_last_tooltip_valid; |
| 1400 | 1400 | ||
| 1401 | #ifdef HAVE_XINPUT2 | ||
| 1402 | /* The master pointer device being used for the drag-and-drop | ||
| 1403 | operation. */ | ||
| 1404 | static int x_dnd_pointer_device; | ||
| 1405 | |||
| 1406 | /* The keyboard device attached to that pointer device. */ | ||
| 1407 | static int x_dnd_keyboard_device; | ||
| 1408 | #endif | ||
| 1409 | |||
| 1401 | /* Structure describing a single window that can be the target of | 1410 | /* Structure describing a single window that can be the target of |
| 1402 | drag-and-drop operations. */ | 1411 | drag-and-drop operations. */ |
| 1403 | struct x_client_list_window | 1412 | struct x_client_list_window |
| @@ -4705,6 +4714,67 @@ x_restore_events_after_dnd (struct frame *f, XWindowAttributes *wa) | |||
| 4705 | dpyinfo->Xatom_XdndTypeList); | 4714 | dpyinfo->Xatom_XdndTypeList); |
| 4706 | } | 4715 | } |
| 4707 | 4716 | ||
| 4717 | #ifdef HAVE_XINPUT2 | ||
| 4718 | |||
| 4719 | /* Cancel the current drag-and-drop operation, sending leave messages | ||
| 4720 | to any relevant toplevels. This is called from the event loop when | ||
| 4721 | an event is received telling Emacs to gracefully cancel the | ||
| 4722 | drag-and-drop operation. */ | ||
| 4723 | |||
| 4724 | static void | ||
| 4725 | x_dnd_cancel_dnd_early (void) | ||
| 4726 | { | ||
| 4727 | struct frame *f; | ||
| 4728 | xm_drop_start_message dmsg; | ||
| 4729 | |||
| 4730 | eassert (x_dnd_frame && x_dnd_in_progress); | ||
| 4731 | |||
| 4732 | f = x_dnd_frame; | ||
| 4733 | |||
| 4734 | if (x_dnd_last_seen_window != None | ||
| 4735 | && x_dnd_last_protocol_version != -1) | ||
| 4736 | x_dnd_send_leave (x_dnd_frame, | ||
| 4737 | x_dnd_last_seen_window); | ||
| 4738 | else if (x_dnd_last_seen_window != None | ||
| 4739 | && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style) | ||
| 4740 | && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE | ||
| 4741 | && x_dnd_motif_setup_p) | ||
| 4742 | { | ||
| 4743 | dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR, | ||
| 4744 | XM_DRAG_REASON_DROP_START); | ||
| 4745 | dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST; | ||
| 4746 | dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time; | ||
| 4747 | dmsg.side_effects | ||
| 4748 | = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), | ||
| 4749 | x_dnd_wanted_action), | ||
| 4750 | XM_DROP_SITE_VALID, x_dnd_motif_operations, | ||
| 4751 | XM_DROP_ACTION_DROP_CANCEL); | ||
| 4752 | dmsg.x = 0; | ||
| 4753 | dmsg.y = 0; | ||
| 4754 | dmsg.index_atom = x_dnd_motif_atom; | ||
| 4755 | dmsg.source_window = FRAME_X_WINDOW (f); | ||
| 4756 | |||
| 4757 | x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f, | ||
| 4758 | x_dnd_last_seen_window, | ||
| 4759 | FRAME_DISPLAY_INFO (f)->last_user_time); | ||
| 4760 | xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f), | ||
| 4761 | x_dnd_last_seen_window, &dmsg); | ||
| 4762 | } | ||
| 4763 | |||
| 4764 | x_dnd_last_seen_window = None; | ||
| 4765 | x_dnd_last_seen_toplevel = None; | ||
| 4766 | x_dnd_in_progress = false; | ||
| 4767 | x_dnd_waiting_for_finish = false; | ||
| 4768 | x_dnd_return_frame_object = NULL; | ||
| 4769 | x_dnd_movement_frame = NULL; | ||
| 4770 | x_dnd_wheel_frame = NULL; | ||
| 4771 | x_dnd_frame = NULL; | ||
| 4772 | x_dnd_action = None; | ||
| 4773 | x_dnd_action_symbol = Qnil; | ||
| 4774 | } | ||
| 4775 | |||
| 4776 | #endif | ||
| 4777 | |||
| 4708 | static void | 4778 | static void |
| 4709 | x_dnd_cleanup_drag_and_drop (void *frame) | 4779 | x_dnd_cleanup_drag_and_drop (void *frame) |
| 4710 | { | 4780 | { |
| @@ -11909,6 +11979,9 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 11909 | struct x_display_info *event_display; | 11979 | struct x_display_info *event_display; |
| 11910 | #endif | 11980 | #endif |
| 11911 | unsigned int additional_mask; | 11981 | unsigned int additional_mask; |
| 11982 | #ifdef HAVE_XINPUT2 | ||
| 11983 | struct xi_device_t *device; | ||
| 11984 | #endif | ||
| 11912 | 11985 | ||
| 11913 | base = SPECPDL_INDEX (); | 11986 | base = SPECPDL_INDEX (); |
| 11914 | 11987 | ||
| @@ -12089,6 +12162,33 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 12089 | x_dnd_wheel_frame = NULL; | 12162 | x_dnd_wheel_frame = NULL; |
| 12090 | x_dnd_init_type_lists = false; | 12163 | x_dnd_init_type_lists = false; |
| 12091 | x_dnd_need_send_drop = false; | 12164 | x_dnd_need_send_drop = false; |
| 12165 | |||
| 12166 | #ifdef HAVE_XINPUT2 | ||
| 12167 | |||
| 12168 | if (FRAME_DISPLAY_INFO (f)->supports_xi2) | ||
| 12169 | { | ||
| 12170 | /* Only accept input from the last master pointer to have interacted | ||
| 12171 | with Emacs. This prevents another pointer device getting our | ||
| 12172 | idea of the button state messed up. */ | ||
| 12173 | if (FRAME_DISPLAY_INFO (f)->client_pointer_device != -1) | ||
| 12174 | x_dnd_pointer_device | ||
| 12175 | = FRAME_DISPLAY_INFO (f)->client_pointer_device; | ||
| 12176 | else | ||
| 12177 | /* This returns Bool but cannot actually fail. */ | ||
| 12178 | XIGetClientPointer (FRAME_X_DISPLAY (f), None, | ||
| 12179 | &x_dnd_pointer_device); | ||
| 12180 | |||
| 12181 | x_dnd_keyboard_device = -1; | ||
| 12182 | |||
| 12183 | device = xi_device_from_id (FRAME_DISPLAY_INFO (f), | ||
| 12184 | x_dnd_pointer_device); | ||
| 12185 | |||
| 12186 | if (device) | ||
| 12187 | x_dnd_keyboard_device = device->attachment; | ||
| 12188 | } | ||
| 12189 | |||
| 12190 | #endif | ||
| 12191 | |||
| 12092 | #ifdef HAVE_XKB | 12192 | #ifdef HAVE_XKB |
| 12093 | x_dnd_keyboard_state = 0; | 12193 | x_dnd_keyboard_state = 0; |
| 12094 | 12194 | ||
| @@ -12882,6 +12982,13 @@ xi_disable_devices (struct x_display_info *dpyinfo, | |||
| 12882 | { | 12982 | { |
| 12883 | if (to_disable[j] == dpyinfo->devices[i].device_id) | 12983 | if (to_disable[j] == dpyinfo->devices[i].device_id) |
| 12884 | { | 12984 | { |
| 12985 | if (x_dnd_in_progress | ||
| 12986 | /* If the drag-and-drop pointer device is being | ||
| 12987 | disabled, then cancel the drag and drop | ||
| 12988 | operation. */ | ||
| 12989 | && to_disable[j] == x_dnd_pointer_device) | ||
| 12990 | x_dnd_cancel_dnd_early (); | ||
| 12991 | |||
| 12885 | /* Free any scroll valuators that might be on this | 12992 | /* Free any scroll valuators that might be on this |
| 12886 | device. */ | 12993 | device. */ |
| 12887 | #ifdef HAVE_XINPUT2_1 | 12994 | #ifdef HAVE_XINPUT2_1 |
| @@ -14164,11 +14271,13 @@ x_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part, | |||
| 14164 | ev->window = FRAME_X_WINDOW (f); | 14271 | ev->window = FRAME_X_WINDOW (f); |
| 14165 | ev->format = 32; | 14272 | ev->format = 32; |
| 14166 | 14273 | ||
| 14167 | /* A 32-bit X client on a 64-bit X server can pass a window pointer | 14274 | /* A 32-bit X client can pass a window pointer through the X server |
| 14168 | as-is. A 64-bit client on a 32-bit X server is in trouble | 14275 | as-is. |
| 14169 | because a pointer does not fit and would be truncated while | 14276 | |
| 14170 | passing through the server. So use two slots and hope that X12 | 14277 | A 64-bit client is in trouble because a pointer does not fit in |
| 14171 | will resolve such issues someday. */ | 14278 | the 32 bits given for ClientMessage data and will be truncated by |
| 14279 | Xlib. So use two slots and hope that X12 will resolve such | ||
| 14280 | issues someday. */ | ||
| 14172 | ev->data.l[0] = iw >> 31 >> 1; | 14281 | ev->data.l[0] = iw >> 31 >> 1; |
| 14173 | ev->data.l[1] = sign_shift <= 0 ? iw : iw << sign_shift >> sign_shift; | 14282 | ev->data.l[1] = sign_shift <= 0 ? iw : iw << sign_shift >> sign_shift; |
| 14174 | ev->data.l[2] = part; | 14283 | ev->data.l[2] = part; |
| @@ -17316,6 +17425,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17316 | union buffered_input_event inev; | 17425 | union buffered_input_event inev; |
| 17317 | int count = 0; | 17426 | int count = 0; |
| 17318 | int do_help = 0; | 17427 | int do_help = 0; |
| 17428 | #ifdef HAVE_XINPUT2 | ||
| 17429 | struct xi_device_t *gen_help_device; | ||
| 17430 | Time gen_help_time; | ||
| 17431 | #endif | ||
| 17319 | ptrdiff_t nbytes = 0; | 17432 | ptrdiff_t nbytes = 0; |
| 17320 | struct frame *any, *f = NULL; | 17433 | struct frame *any, *f = NULL; |
| 17321 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; | 17434 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; |
| @@ -17345,6 +17458,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17345 | EVENT_INIT (inev.ie); | 17458 | EVENT_INIT (inev.ie); |
| 17346 | inev.ie.kind = NO_EVENT; | 17459 | inev.ie.kind = NO_EVENT; |
| 17347 | inev.ie.arg = Qnil; | 17460 | inev.ie.arg = Qnil; |
| 17461 | #ifdef HAVE_XINPUT2 | ||
| 17462 | gen_help_device = NULL; | ||
| 17463 | #endif | ||
| 17348 | 17464 | ||
| 17349 | /* Ignore events coming from various extensions, such as XFIXES and | 17465 | /* Ignore events coming from various extensions, such as XFIXES and |
| 17350 | XKB. */ | 17466 | XKB. */ |
| @@ -17870,6 +17986,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17870 | if (!x_window_to_frame (dpyinfo, event->xselection.requestor)) | 17986 | if (!x_window_to_frame (dpyinfo, event->xselection.requestor)) |
| 17871 | goto OTHER; | 17987 | goto OTHER; |
| 17872 | #endif /* not USE_X_TOOLKIT and not USE_GTK */ | 17988 | #endif /* not USE_X_TOOLKIT and not USE_GTK */ |
| 17989 | #ifdef HAVE_GTK3 | ||
| 17990 | /* GTK 3 apparently chokes on these events since they have no | ||
| 17991 | associated device. (bug#56869, another bug as well that I | ||
| 17992 | can't find) */ | ||
| 17993 | *finish = X_EVENT_DROP; | ||
| 17994 | #endif | ||
| 17873 | x_handle_selection_notify (&event->xselection); | 17995 | x_handle_selection_notify (&event->xselection); |
| 17874 | break; | 17996 | break; |
| 17875 | 17997 | ||
| @@ -17878,6 +18000,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17878 | if (!x_window_to_frame (dpyinfo, event->xselectionclear.window)) | 18000 | if (!x_window_to_frame (dpyinfo, event->xselectionclear.window)) |
| 17879 | goto OTHER; | 18001 | goto OTHER; |
| 17880 | #endif /* not USE_X_TOOLKIT and not USE_GTK */ | 18002 | #endif /* not USE_X_TOOLKIT and not USE_GTK */ |
| 18003 | #ifdef HAVE_GTK3 | ||
| 18004 | *finish = X_EVENT_DROP; | ||
| 18005 | #endif | ||
| 17881 | { | 18006 | { |
| 17882 | const XSelectionClearEvent *eventp = &event->xselectionclear; | 18007 | const XSelectionClearEvent *eventp = &event->xselectionclear; |
| 17883 | 18008 | ||
| @@ -17904,6 +18029,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17904 | if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner)) | 18029 | if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner)) |
| 17905 | goto OTHER; | 18030 | goto OTHER; |
| 17906 | #endif /* USE_X_TOOLKIT */ | 18031 | #endif /* USE_X_TOOLKIT */ |
| 18032 | #ifdef HAVE_GTK3 | ||
| 18033 | *finish = X_EVENT_DROP; | ||
| 18034 | #endif | ||
| 17907 | { | 18035 | { |
| 17908 | const XSelectionRequestEvent *eventp = &event->xselectionrequest; | 18036 | const XSelectionRequestEvent *eventp = &event->xselectionrequest; |
| 17909 | 18037 | ||
| @@ -18446,6 +18574,11 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 18446 | #endif | 18574 | #endif |
| 18447 | 18575 | ||
| 18448 | if (x_dnd_in_progress | 18576 | if (x_dnd_in_progress |
| 18577 | /* When _NET_WM_CLIENT_LIST stacking is being used, changes | ||
| 18578 | in that property are watched for, and it's not necessary | ||
| 18579 | to update the state in response to ordinary window | ||
| 18580 | substructure events. */ | ||
| 18581 | && !x_dnd_use_toplevels | ||
| 18449 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) | 18582 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) |
| 18450 | x_dnd_update_state (dpyinfo, dpyinfo->last_user_time); | 18583 | x_dnd_update_state (dpyinfo, dpyinfo->last_user_time); |
| 18451 | 18584 | ||
| @@ -20280,6 +20413,11 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 20280 | 20413 | ||
| 20281 | case CirculateNotify: | 20414 | case CirculateNotify: |
| 20282 | if (x_dnd_in_progress | 20415 | if (x_dnd_in_progress |
| 20416 | /* When _NET_WM_CLIENT_LIST stacking is being used, changes | ||
| 20417 | in that property are watched for, and it's not necessary | ||
| 20418 | to update the state in response to ordinary window | ||
| 20419 | substructure events. */ | ||
| 20420 | && !x_dnd_use_toplevels | ||
| 20283 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) | 20421 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) |
| 20284 | x_dnd_update_state (dpyinfo, dpyinfo->last_user_time); | 20422 | x_dnd_update_state (dpyinfo, dpyinfo->last_user_time); |
| 20285 | goto OTHER; | 20423 | goto OTHER; |
| @@ -20876,6 +21014,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 20876 | operation, don't send an event. We only have | 21014 | operation, don't send an event. We only have |
| 20877 | to set the user time. */ | 21015 | to set the user time. */ |
| 20878 | if (x_dnd_in_progress | 21016 | if (x_dnd_in_progress |
| 21017 | /* If another master device moved the | ||
| 21018 | pointer, we should put a wheel event on | ||
| 21019 | the keyboard buffer as usual. It will be | ||
| 21020 | run once the drag-and-drop operation | ||
| 21021 | completes. */ | ||
| 21022 | && xev->deviceid == x_dnd_pointer_device | ||
| 20879 | && (command_loop_level + minibuf_level | 21023 | && (command_loop_level + minibuf_level |
| 20880 | <= x_dnd_recursion_depth) | 21024 | <= x_dnd_recursion_depth) |
| 20881 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) | 21025 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) |
| @@ -20968,6 +21112,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 20968 | `x-dnd-movement-function`. */ | 21112 | `x-dnd-movement-function`. */ |
| 20969 | && (command_loop_level + minibuf_level | 21113 | && (command_loop_level + minibuf_level |
| 20970 | <= x_dnd_recursion_depth) | 21114 | <= x_dnd_recursion_depth) |
| 21115 | && xev->deviceid == x_dnd_pointer_device | ||
| 20971 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) | 21116 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) |
| 20972 | { | 21117 | { |
| 20973 | Window target, toplevel; | 21118 | Window target, toplevel; |
| @@ -21270,7 +21415,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21270 | has changed, generate a HELP_EVENT. */ | 21415 | has changed, generate a HELP_EVENT. */ |
| 21271 | if (!NILP (help_echo_string) | 21416 | if (!NILP (help_echo_string) |
| 21272 | || !NILP (previous_help_echo_string)) | 21417 | || !NILP (previous_help_echo_string)) |
| 21273 | do_help = 1; | 21418 | { |
| 21419 | /* Also allow the focus and client pointer to be | ||
| 21420 | adjusted accordingly, in case a help tooltip is | ||
| 21421 | shown. */ | ||
| 21422 | gen_help_device = device; | ||
| 21423 | gen_help_time = xev->time; | ||
| 21424 | |||
| 21425 | do_help = 1; | ||
| 21426 | } | ||
| 21274 | goto XI_OTHER; | 21427 | goto XI_OTHER; |
| 21275 | } | 21428 | } |
| 21276 | 21429 | ||
| @@ -21294,6 +21447,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21294 | if (x_dnd_in_progress | 21447 | if (x_dnd_in_progress |
| 21295 | && (command_loop_level + minibuf_level | 21448 | && (command_loop_level + minibuf_level |
| 21296 | <= x_dnd_recursion_depth) | 21449 | <= x_dnd_recursion_depth) |
| 21450 | && xev->deviceid == x_dnd_pointer_device | ||
| 21297 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) | 21451 | && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) |
| 21298 | { | 21452 | { |
| 21299 | f = mouse_or_wdesc_frame (dpyinfo, xev->event); | 21453 | f = mouse_or_wdesc_frame (dpyinfo, xev->event); |
| @@ -21333,6 +21487,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21333 | } | 21487 | } |
| 21334 | #endif | 21488 | #endif |
| 21335 | 21489 | ||
| 21490 | if (f && device) | ||
| 21491 | xi_handle_interaction (dpyinfo, f, device, | ||
| 21492 | xev->time); | ||
| 21493 | |||
| 21336 | if (xev->evtype == XI_ButtonPress | 21494 | if (xev->evtype == XI_ButtonPress |
| 21337 | && x_dnd_last_seen_window != None) | 21495 | && x_dnd_last_seen_window != None) |
| 21338 | { | 21496 | { |
| @@ -21579,11 +21737,19 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21579 | xev->send_event); | 21737 | xev->send_event); |
| 21580 | 21738 | ||
| 21581 | source = xi_device_from_id (dpyinfo, xev->sourceid); | 21739 | source = xi_device_from_id (dpyinfo, xev->sourceid); |
| 21740 | device = xi_device_from_id (dpyinfo, xev->deviceid); | ||
| 21582 | 21741 | ||
| 21583 | #ifdef HAVE_XWIDGETS | 21742 | #ifdef HAVE_XWIDGETS |
| 21584 | xvw = xwidget_view_from_window (xev->event); | 21743 | xvw = xwidget_view_from_window (xev->event); |
| 21585 | if (xvw) | 21744 | if (xvw) |
| 21586 | { | 21745 | { |
| 21746 | /* If the user interacts with a frame that's focused | ||
| 21747 | on another device, but not the current focus | ||
| 21748 | frame, make it the focus frame. */ | ||
| 21749 | if (device) | ||
| 21750 | xi_handle_interaction (dpyinfo, xvw->frame, | ||
| 21751 | device, xev->time); | ||
| 21752 | |||
| 21587 | xwidget_button (xvw, xev->evtype == XI_ButtonPress, | 21753 | xwidget_button (xvw, xev->evtype == XI_ButtonPress, |
| 21588 | lrint (xev->event_x), lrint (xev->event_y), | 21754 | lrint (xev->event_x), lrint (xev->event_y), |
| 21589 | xev->detail, xi_convert_event_state (xev), | 21755 | xev->detail, xi_convert_event_state (xev), |
| @@ -21603,8 +21769,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21603 | } | 21769 | } |
| 21604 | #endif | 21770 | #endif |
| 21605 | 21771 | ||
| 21606 | device = xi_device_from_id (dpyinfo, xev->deviceid); | ||
| 21607 | |||
| 21608 | if (!device) | 21772 | if (!device) |
| 21609 | goto XI_OTHER; | 21773 | goto XI_OTHER; |
| 21610 | 21774 | ||
| @@ -22162,7 +22326,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 22162 | inev.ie.modifiers = x_x_to_emacs_modifiers (dpyinfo, state); | 22326 | inev.ie.modifiers = x_x_to_emacs_modifiers (dpyinfo, state); |
| 22163 | 22327 | ||
| 22164 | #ifdef XK_F1 | 22328 | #ifdef XK_F1 |
| 22165 | if (x_dnd_in_progress && keysym == XK_F1) | 22329 | if (x_dnd_in_progress |
| 22330 | && xev->deviceid == x_dnd_keyboard_device | ||
| 22331 | && keysym == XK_F1) | ||
| 22166 | { | 22332 | { |
| 22167 | x_dnd_xm_use_help = true; | 22333 | x_dnd_xm_use_help = true; |
| 22168 | goto xi_done_keysym; | 22334 | goto xi_done_keysym; |
| @@ -22426,11 +22592,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 22426 | 22592 | ||
| 22427 | case XI_HierarchyChanged: | 22593 | case XI_HierarchyChanged: |
| 22428 | { | 22594 | { |
| 22429 | XIHierarchyEvent *hev = (XIHierarchyEvent *) xi_event; | 22595 | XIHierarchyEvent *hev; |
| 22430 | XIDeviceInfo *info; | 22596 | XIDeviceInfo *info; |
| 22431 | int i, ndevices, n_disabled, *disabled; | 22597 | int i, ndevices, n_disabled, *disabled; |
| 22432 | struct xi_device_t *device; | 22598 | struct xi_device_t *device; |
| 22599 | bool any_changed; | ||
| 22433 | 22600 | ||
| 22601 | any_changed = false; | ||
| 22602 | hev = (XIHierarchyEvent *) xi_event; | ||
| 22434 | disabled = SAFE_ALLOCA (sizeof *disabled * hev->num_info); | 22603 | disabled = SAFE_ALLOCA (sizeof *disabled * hev->num_info); |
| 22435 | n_disabled = 0; | 22604 | n_disabled = 0; |
| 22436 | 22605 | ||
| @@ -22440,8 +22609,17 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 22440 | { | 22609 | { |
| 22441 | /* Handle all disabled devices now, to prevent | 22610 | /* Handle all disabled devices now, to prevent |
| 22442 | things happening out-of-order later. */ | 22611 | things happening out-of-order later. */ |
| 22443 | xi_disable_devices (dpyinfo, disabled, n_disabled); | 22612 | |
| 22444 | n_disabled = 0; | 22613 | if (ndevices) |
| 22614 | { | ||
| 22615 | xi_disable_devices (dpyinfo, disabled, n_disabled); | ||
| 22616 | n_disabled = 0; | ||
| 22617 | |||
| 22618 | /* This flag really just means that disabled | ||
| 22619 | devices were handled early and should be | ||
| 22620 | used in conjunction with n_disabled. */ | ||
| 22621 | any_changed = true; | ||
| 22622 | } | ||
| 22445 | 22623 | ||
| 22446 | x_catch_errors (dpyinfo->display); | 22624 | x_catch_errors (dpyinfo->display); |
| 22447 | info = XIQueryDevice (dpyinfo->display, hev->info[i].deviceid, | 22625 | info = XIQueryDevice (dpyinfo->display, hev->info[i].deviceid, |
| @@ -22492,9 +22670,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 22492 | event. */ | 22670 | event. */ |
| 22493 | xi_disable_devices (dpyinfo, disabled, n_disabled); | 22671 | xi_disable_devices (dpyinfo, disabled, n_disabled); |
| 22494 | 22672 | ||
| 22495 | /* Now that the device hierarchy has been changed, | 22673 | /* If the device hierarchy has been changed, recompute |
| 22496 | recompute focus. */ | 22674 | focus. This might seem like a micro-optimization but |
| 22497 | xi_handle_focus_change (dpyinfo); | 22675 | it actually keeps the focus from changing in some |
| 22676 | cases where it would be undesierable. */ | ||
| 22677 | if (any_changed || n_disabled) | ||
| 22678 | xi_handle_focus_change (dpyinfo); | ||
| 22498 | 22679 | ||
| 22499 | goto XI_OTHER; | 22680 | goto XI_OTHER; |
| 22500 | } | 22681 | } |
| @@ -23182,6 +23363,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 23182 | if (do_help > 0) | 23363 | if (do_help > 0) |
| 23183 | { | 23364 | { |
| 23184 | any_help_event_p = true; | 23365 | any_help_event_p = true; |
| 23366 | #ifdef HAVE_XINPUT2 | ||
| 23367 | if (gen_help_device) | ||
| 23368 | xi_handle_interaction (dpyinfo, f, | ||
| 23369 | gen_help_device, | ||
| 23370 | gen_help_time); | ||
| 23371 | #endif | ||
| 23185 | gen_help_event (help_echo_string, frame, help_echo_window, | 23372 | gen_help_event (help_echo_string, frame, help_echo_window, |
| 23186 | help_echo_object, help_echo_pos); | 23373 | help_echo_object, help_echo_pos); |
| 23187 | } | 23374 | } |
| @@ -25947,27 +26134,25 @@ x_set_window_size (struct frame *f, bool change_gravity, | |||
| 25947 | void | 26134 | void |
| 25948 | frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y) | 26135 | frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y) |
| 25949 | { | 26136 | { |
| 25950 | block_input (); | ||
| 25951 | #ifdef HAVE_XINPUT2 | 26137 | #ifdef HAVE_XINPUT2 |
| 25952 | int deviceid; | 26138 | int deviceid; |
| 25953 | 26139 | ||
| 25954 | if (FRAME_DISPLAY_INFO (f)->supports_xi2) | 26140 | deviceid = FRAME_DISPLAY_INFO (f)->client_pointer_device; |
| 26141 | |||
| 26142 | if (FRAME_DISPLAY_INFO (f)->supports_xi2 | ||
| 26143 | && deviceid != -1) | ||
| 25955 | { | 26144 | { |
| 25956 | if (XIGetClientPointer (FRAME_X_DISPLAY (f), | 26145 | block_input (); |
| 25957 | FRAME_X_WINDOW (f), | 26146 | x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f)); |
| 25958 | &deviceid)) | 26147 | XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None, |
| 25959 | { | 26148 | FRAME_X_WINDOW (f), 0, 0, 0, 0, pix_x, pix_y); |
| 25960 | x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f)); | 26149 | x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f)); |
| 25961 | XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None, | 26150 | unblock_input (); |
| 25962 | FRAME_X_WINDOW (f), 0, 0, 0, 0, pix_x, pix_y); | ||
| 25963 | x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f)); | ||
| 25964 | } | ||
| 25965 | } | 26151 | } |
| 25966 | else | 26152 | else |
| 25967 | #endif | 26153 | #endif |
| 25968 | XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f), | 26154 | XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f), |
| 25969 | 0, 0, 0, 0, pix_x, pix_y); | 26155 | 0, 0, 0, 0, pix_x, pix_y); |
| 25970 | unblock_input (); | ||
| 25971 | } | 26156 | } |
| 25972 | 26157 | ||
| 25973 | /* Raise frame F. */ | 26158 | /* Raise frame F. */ |
| @@ -28955,7 +29140,7 @@ void | |||
| 28955 | x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, | 29140 | x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, |
| 28956 | Lisp_Object current_owner) | 29141 | Lisp_Object current_owner) |
| 28957 | { | 29142 | { |
| 28958 | Lisp_Object tail, frame, new_owner, tem; | 29143 | Lisp_Object tail, frame, new_owner; |
| 28959 | Time timestamp; | 29144 | Time timestamp; |
| 28960 | Window *owners; | 29145 | Window *owners; |
| 28961 | Atom *names; | 29146 | Atom *names; |
| @@ -28985,7 +29170,7 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, | |||
| 28985 | 29170 | ||
| 28986 | FOR_EACH_TAIL_SAFE (tail) | 29171 | FOR_EACH_TAIL_SAFE (tail) |
| 28987 | { | 29172 | { |
| 28988 | tem = XCAR (tail); | 29173 | Lisp_Object tem = XCAR (tail); |
| 28989 | ++nowners; | 29174 | ++nowners; |
| 28990 | 29175 | ||
| 28991 | /* The selection is really lost (since we cannot find a new | 29176 | /* The selection is really lost (since we cannot find a new |
| @@ -29019,7 +29204,7 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, | |||
| 29019 | 29204 | ||
| 29020 | FOR_EACH_TAIL_SAFE (tail) | 29205 | FOR_EACH_TAIL_SAFE (tail) |
| 29021 | { | 29206 | { |
| 29022 | tem = XCAR (tail); | 29207 | Lisp_Object tem = XCAR (tail); |
| 29023 | 29208 | ||
| 29024 | /* Now check if we still don't own that selection, which can | 29209 | /* Now check if we still don't own that selection, which can |
| 29025 | happen if another program set itself as the owner. */ | 29210 | happen if another program set itself as the owner. */ |
| @@ -29039,9 +29224,10 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, | |||
| 29039 | 29224 | ||
| 29040 | FOR_EACH_TAIL_SAFE (tail) | 29225 | FOR_EACH_TAIL_SAFE (tail) |
| 29041 | { | 29226 | { |
| 29227 | Lisp_Object tem = XCAR (tail); | ||
| 29228 | |||
| 29042 | reply = xcb_get_selection_owner_reply (dpyinfo->xcb_connection, | 29229 | reply = xcb_get_selection_owner_reply (dpyinfo->xcb_connection, |
| 29043 | cookies[nowners++], &error); | 29230 | cookies[nowners++], &error); |
| 29044 | |||
| 29045 | if (reply) | 29231 | if (reply) |
| 29046 | owners[nowners - 1] = reply->owner; | 29232 | owners[nowners - 1] = reply->owner; |
| 29047 | else | 29233 | else |
| @@ -29071,7 +29257,7 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, | |||
| 29071 | 29257 | ||
| 29072 | FOR_EACH_TAIL_SAFE (tail) | 29258 | FOR_EACH_TAIL_SAFE (tail) |
| 29073 | { | 29259 | { |
| 29074 | tem = XCAR (tail); | 29260 | Lisp_Object tem = XCAR (tail); |
| 29075 | 29261 | ||
| 29076 | /* If the selection isn't owned by us anymore, note that the | 29262 | /* If the selection isn't owned by us anymore, note that the |
| 29077 | selection was lost. */ | 29263 | selection was lost. */ |