diff options
| author | Po Lu | 2022-03-17 08:54:30 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-17 08:55:16 +0800 |
| commit | c223e2aefcabc7ad29c4be186fc07825bbcce196 (patch) | |
| tree | edfea0ef55b7fda8be85b411a41643c1c5591fe6 /src | |
| parent | f7e0e5b7aeb928353065a3667c5231c4e4559d28 (diff) | |
| download | emacs-c223e2aefcabc7ad29c4be186fc07825bbcce196.tar.gz emacs-c223e2aefcabc7ad29c4be186fc07825bbcce196.zip | |
Improve GTK support for X11 drag-n-drop
* src/xterm.c (x_dnd_begin_drag_and_drop): Run nested GTK event
loop instead, so GTK gets the correct events.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/src/xterm.c b/src/xterm.c index 46a22d8dc1b..59c3cefd598 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -702,6 +702,19 @@ static Lisp_Object xg_default_icon_file; | |||
| 702 | static char emacs_class[] = EMACS_CLASS; | 702 | static char emacs_class[] = EMACS_CLASS; |
| 703 | #endif | 703 | #endif |
| 704 | 704 | ||
| 705 | #ifdef USE_GTK | ||
| 706 | static int current_count; | ||
| 707 | static int current_finish; | ||
| 708 | static struct input_event *current_hold_quit; | ||
| 709 | #endif | ||
| 710 | |||
| 711 | enum | ||
| 712 | { | ||
| 713 | X_EVENT_NORMAL, | ||
| 714 | X_EVENT_GOTO_OUT, | ||
| 715 | X_EVENT_DROP | ||
| 716 | }; | ||
| 717 | |||
| 705 | enum xembed_info | 718 | enum xembed_info |
| 706 | { | 719 | { |
| 707 | XEMBED_MAPPED = 1 << 0 | 720 | XEMBED_MAPPED = 1 << 0 |
| @@ -1072,9 +1085,11 @@ Lisp_Object | |||
| 1072 | x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | 1085 | x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, |
| 1073 | bool return_frame_p) | 1086 | bool return_frame_p) |
| 1074 | { | 1087 | { |
| 1088 | #ifndef USE_GTK | ||
| 1075 | XEvent next_event; | 1089 | XEvent next_event; |
| 1076 | struct input_event hold_quit; | ||
| 1077 | int finish; | 1090 | int finish; |
| 1091 | #endif | ||
| 1092 | struct input_event hold_quit; | ||
| 1078 | char *atom_name; | 1093 | char *atom_name; |
| 1079 | Lisp_Object action, ltimestamp; | 1094 | Lisp_Object action, ltimestamp; |
| 1080 | 1095 | ||
| @@ -1104,15 +1119,25 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 1104 | if (return_frame_p) | 1119 | if (return_frame_p) |
| 1105 | x_dnd_return_frame = 1; | 1120 | x_dnd_return_frame = 1; |
| 1106 | 1121 | ||
| 1122 | current_count = 0; | ||
| 1123 | |||
| 1107 | while (x_dnd_in_progress) | 1124 | while (x_dnd_in_progress) |
| 1108 | { | 1125 | { |
| 1126 | #ifdef USE_GTK | ||
| 1109 | hold_quit.kind = NO_EVENT; | 1127 | hold_quit.kind = NO_EVENT; |
| 1128 | current_finish = X_EVENT_NORMAL; | ||
| 1129 | current_hold_quit = &hold_quit; | ||
| 1130 | #endif | ||
| 1110 | 1131 | ||
| 1111 | block_input (); | 1132 | block_input (); |
| 1133 | #ifndef USE_GTK | ||
| 1112 | XNextEvent (FRAME_X_DISPLAY (f), &next_event); | 1134 | XNextEvent (FRAME_X_DISPLAY (f), &next_event); |
| 1113 | 1135 | ||
| 1114 | handle_one_xevent (FRAME_DISPLAY_INFO (f), | 1136 | handle_one_xevent (FRAME_DISPLAY_INFO (f), |
| 1115 | &next_event, &finish, &hold_quit); | 1137 | &next_event, &finish, &hold_quit); |
| 1138 | #else | ||
| 1139 | gtk_main_iteration (); | ||
| 1140 | #endif | ||
| 1116 | unblock_input (); | 1141 | unblock_input (); |
| 1117 | 1142 | ||
| 1118 | if (hold_quit.kind != NO_EVENT) | 1143 | if (hold_quit.kind != NO_EVENT) |
| @@ -1130,10 +1155,17 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 1130 | } | 1155 | } |
| 1131 | 1156 | ||
| 1132 | FRAME_DISPLAY_INFO (f)->grabbed = 0; | 1157 | FRAME_DISPLAY_INFO (f)->grabbed = 0; |
| 1158 | #ifdef USE_GTK | ||
| 1159 | current_hold_quit = NULL; | ||
| 1160 | #endif | ||
| 1133 | quit (); | 1161 | quit (); |
| 1134 | } | 1162 | } |
| 1135 | } | 1163 | } |
| 1136 | 1164 | ||
| 1165 | #ifdef USE_GTK | ||
| 1166 | current_hold_quit = NULL; | ||
| 1167 | #endif | ||
| 1168 | |||
| 1137 | if (x_dnd_return_frame == 3) | 1169 | if (x_dnd_return_frame == 3) |
| 1138 | { | 1170 | { |
| 1139 | x_dnd_return_frame_object->mouse_moved = true; | 1171 | x_dnd_return_frame_object->mouse_moved = true; |
| @@ -10125,13 +10157,6 @@ static struct x_display_info *XTread_socket_fake_io_error; | |||
| 10125 | 10157 | ||
| 10126 | static struct x_display_info *next_noop_dpyinfo; | 10158 | static struct x_display_info *next_noop_dpyinfo; |
| 10127 | 10159 | ||
| 10128 | enum | ||
| 10129 | { | ||
| 10130 | X_EVENT_NORMAL, | ||
| 10131 | X_EVENT_GOTO_OUT, | ||
| 10132 | X_EVENT_DROP | ||
| 10133 | }; | ||
| 10134 | |||
| 10135 | /* Filter events for the current X input method. | 10160 | /* Filter events for the current X input method. |
| 10136 | DPYINFO is the display this event is for. | 10161 | DPYINFO is the display this event is for. |
| 10137 | EVENT is the X event to filter. | 10162 | EVENT is the X event to filter. |
| @@ -10207,10 +10232,6 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event) | |||
| 10207 | #endif | 10232 | #endif |
| 10208 | 10233 | ||
| 10209 | #ifdef USE_GTK | 10234 | #ifdef USE_GTK |
| 10210 | static int current_count; | ||
| 10211 | static int current_finish; | ||
| 10212 | static struct input_event *current_hold_quit; | ||
| 10213 | |||
| 10214 | /* This is the filter function invoked by the GTK event loop. | 10235 | /* This is the filter function invoked by the GTK event loop. |
| 10215 | It is invoked before the XEvent is translated to a GdkEvent, | 10236 | It is invoked before the XEvent is translated to a GdkEvent, |
| 10216 | so we have a chance to act on the event before GTK. */ | 10237 | so we have a chance to act on the event before GTK. */ |