diff options
| author | Philip Kaludercic | 2022-10-18 21:53:25 +0200 |
|---|---|---|
| committer | Philip Kaludercic | 2022-10-18 21:53:25 +0200 |
| commit | 65fa87329ce577d1ee907c0716b48aac8c0d7d27 (patch) | |
| tree | 9593429442e7e4fa4f522a9b62a102d9c1cf3fed /src | |
| parent | 5ceb88e6ebf14cee3f97b0c7b8557e4b1e23de5b (diff) | |
| parent | ab1b491f8373742a051aaf554c4604f2b976b414 (diff) | |
| download | emacs-65fa87329ce577d1ee907c0716b48aac8c0d7d27.tar.gz emacs-65fa87329ce577d1ee907c0716b48aac8c0d7d27.zip | |
Merge remote-tracking branch 'origin/master' into feature/package+vc
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp.c | 17 | ||||
| -rw-r--r-- | src/dispnew.c | 9 | ||||
| -rw-r--r-- | src/haikuterm.c | 32 | ||||
| -rw-r--r-- | src/haikuterm.h | 5 | ||||
| -rw-r--r-- | src/xfns.c | 115 | ||||
| -rw-r--r-- | src/xmenu.c | 45 | ||||
| -rw-r--r-- | src/xselect.c | 25 | ||||
| -rw-r--r-- | src/xterm.c | 379 | ||||
| -rw-r--r-- | src/xterm.h | 55 |
9 files changed, 501 insertions, 181 deletions
diff --git a/src/comp.c b/src/comp.c index b7541c5d9f7..14012634ccc 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -5868,8 +5868,21 @@ The last directory of this list is assumed to be the system one. */); | |||
| 5868 | Vnative_comp_eln_load_path = Fcons (build_string ("../native-lisp/"), Qnil); | 5868 | Vnative_comp_eln_load_path = Fcons (build_string ("../native-lisp/"), Qnil); |
| 5869 | 5869 | ||
| 5870 | DEFVAR_BOOL ("comp-enable-subr-trampolines", comp_enable_subr_trampolines, | 5870 | DEFVAR_BOOL ("comp-enable-subr-trampolines", comp_enable_subr_trampolines, |
| 5871 | doc: /* If non-nil enable primitive trampoline synthesis. | 5871 | doc: /* If non-nil, enable primitive trampoline synthesis. |
| 5872 | This makes primitive functions redefinable or advisable effectively. */); | 5872 | This makes Emacs respect redefinition or advises of primitive functions |
| 5873 | when they are called from Lisp code natively-compiled at `native-comp-speed' | ||
| 5874 | of 2. | ||
| 5875 | |||
| 5876 | By default, this is enabled, and when Emacs sees a redefined or advised | ||
| 5877 | primitive called from natively-compiled Lisp, it generates a trampoline | ||
| 5878 | for it on-the-fly. | ||
| 5879 | |||
| 5880 | Disabling this, when a trampoline for a redefined or advised primitive is | ||
| 5881 | not available from previous compilations, means that such redefinition | ||
| 5882 | or advise will not have effect on calls from natively-compiled Lisp code. | ||
| 5883 | That is, calls to primitives without existing trampolines from | ||
| 5884 | natively-compiled Lisp will behave as if the primitive was called | ||
| 5885 | directly from C. */); | ||
| 5873 | 5886 | ||
| 5874 | DEFVAR_LISP ("comp-installed-trampolines-h", Vcomp_installed_trampolines_h, | 5887 | DEFVAR_LISP ("comp-installed-trampolines-h", Vcomp_installed_trampolines_h, |
| 5875 | doc: /* Hash table subr-name -> installed trampoline. | 5888 | doc: /* Hash table subr-name -> installed trampoline. |
diff --git a/src/dispnew.c b/src/dispnew.c index 2568ba1086a..5a9ba8909e3 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -3152,10 +3152,19 @@ redraw_frame (struct frame *f) | |||
| 3152 | update_begin (f); | 3152 | update_begin (f); |
| 3153 | if (FRAME_MSDOS_P (f)) | 3153 | if (FRAME_MSDOS_P (f)) |
| 3154 | FRAME_TERMINAL (f)->set_terminal_modes_hook (FRAME_TERMINAL (f)); | 3154 | FRAME_TERMINAL (f)->set_terminal_modes_hook (FRAME_TERMINAL (f)); |
| 3155 | |||
| 3156 | if (FRAME_WINDOW_P (f)) | ||
| 3157 | /* Garbage the frame now. Otherwise, platforms that support | ||
| 3158 | double buffering will display the blank contents of the frame | ||
| 3159 | even though the frame should be redrawn at some point in the | ||
| 3160 | future. */ | ||
| 3161 | SET_FRAME_GARBAGED (f); | ||
| 3162 | |||
| 3155 | clear_frame (f); | 3163 | clear_frame (f); |
| 3156 | clear_current_matrices (f); | 3164 | clear_current_matrices (f); |
| 3157 | update_end (f); | 3165 | update_end (f); |
| 3158 | fset_redisplay (f); | 3166 | fset_redisplay (f); |
| 3167 | |||
| 3159 | /* Mark all windows as inaccurate, so that every window will have | 3168 | /* Mark all windows as inaccurate, so that every window will have |
| 3160 | its redisplay done. */ | 3169 | its redisplay done. */ |
| 3161 | mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0); | 3170 | mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0); |
diff --git a/src/haikuterm.c b/src/haikuterm.c index 838eb128fa6..4e32b747160 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c | |||
| @@ -232,6 +232,9 @@ haiku_frame_up_to_date (struct frame *f) | |||
| 232 | be_evict_font_cache (); | 232 | be_evict_font_cache (); |
| 233 | up_to_date_count = 0; | 233 | up_to_date_count = 0; |
| 234 | } | 234 | } |
| 235 | |||
| 236 | /* Mark the frame as complete. */ | ||
| 237 | FRAME_COMPLETE_P (f) = true; | ||
| 235 | unblock_input (); | 238 | unblock_input (); |
| 236 | } | 239 | } |
| 237 | 240 | ||
| @@ -265,6 +268,8 @@ haiku_clear_frame (struct frame *f) | |||
| 265 | 268 | ||
| 266 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); | 269 | mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); |
| 267 | 270 | ||
| 271 | FRAME_COMPLETE_P (f) = false; | ||
| 272 | |||
| 268 | block_input (); | 273 | block_input (); |
| 269 | BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f), | 274 | BView_draw_lock (view, true, 0, 0, FRAME_PIXEL_WIDTH (f), |
| 270 | FRAME_PIXEL_HEIGHT (f)); | 275 | FRAME_PIXEL_HEIGHT (f)); |
| @@ -1436,6 +1441,9 @@ haiku_clip_to_row (struct window *w, struct glyph_row *row, | |||
| 1436 | static void | 1441 | static void |
| 1437 | haiku_update_begin (struct frame *f) | 1442 | haiku_update_begin (struct frame *f) |
| 1438 | { | 1443 | { |
| 1444 | /* Mark the frame as incomplete so it is not flushed upon handling | ||
| 1445 | input. */ | ||
| 1446 | FRAME_COMPLETE_P (f) = false; | ||
| 1439 | } | 1447 | } |
| 1440 | 1448 | ||
| 1441 | static void | 1449 | static void |
| @@ -2959,6 +2967,10 @@ haiku_flush (struct frame *f) | |||
| 2959 | if (FRAME_DIRTY_P (f) && !buffer_flipping_blocked_p ()) | 2967 | if (FRAME_DIRTY_P (f) && !buffer_flipping_blocked_p ()) |
| 2960 | haiku_flip_buffers (f); | 2968 | haiku_flip_buffers (f); |
| 2961 | 2969 | ||
| 2970 | /* The frame is complete again as its contents were just | ||
| 2971 | flushed. */ | ||
| 2972 | FRAME_COMPLETE_P (f) = true; | ||
| 2973 | |||
| 2962 | if (FRAME_VISIBLE_P (f) && !FRAME_TOOLTIP_P (f)) | 2974 | if (FRAME_VISIBLE_P (f) && !FRAME_TOOLTIP_P (f)) |
| 2963 | BWindow_Flush (FRAME_HAIKU_WINDOW (f)); | 2975 | BWindow_Flush (FRAME_HAIKU_WINDOW (f)); |
| 2964 | } | 2976 | } |
| @@ -3086,10 +3098,15 @@ haiku_make_fullscreen_consistent (struct frame *f) | |||
| 3086 | static void | 3098 | static void |
| 3087 | haiku_flush_dirty_back_buffer_on (struct frame *f) | 3099 | haiku_flush_dirty_back_buffer_on (struct frame *f) |
| 3088 | { | 3100 | { |
| 3089 | if (!FRAME_GARBAGED_P (f) | 3101 | if (FRAME_GARBAGED_P (f) |
| 3090 | && !buffer_flipping_blocked_p () | 3102 | || buffer_flipping_blocked_p () |
| 3091 | && FRAME_DIRTY_P (f)) | 3103 | /* If the frame is not already up to date, do not flush buffers |
| 3092 | haiku_flip_buffers (f); | 3104 | on input, as that will result in flicker. */ |
| 3105 | || !FRAME_COMPLETE_P (f) | ||
| 3106 | || !FRAME_DIRTY_P (f)) | ||
| 3107 | return; | ||
| 3108 | |||
| 3109 | haiku_flip_buffers (f); | ||
| 3093 | } | 3110 | } |
| 3094 | 3111 | ||
| 3095 | /* N.B. that support for TYPE must be explicitly added to | 3112 | /* N.B. that support for TYPE must be explicitly added to |
| @@ -3135,6 +3152,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 3135 | int button_or_motion_p, do_help; | 3152 | int button_or_motion_p, do_help; |
| 3136 | enum haiku_event_type type; | 3153 | enum haiku_event_type type; |
| 3137 | struct input_event inev, inev2; | 3154 | struct input_event inev, inev2; |
| 3155 | struct frame *mouse_frame; | ||
| 3138 | 3156 | ||
| 3139 | message_count = 0; | 3157 | message_count = 0; |
| 3140 | button_or_motion_p = 0; | 3158 | button_or_motion_p = 0; |
| @@ -3252,9 +3270,13 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 3252 | || !EQ (f->tool_bar_window, hlinfo->mouse_face_window) | 3270 | || !EQ (f->tool_bar_window, hlinfo->mouse_face_window) |
| 3253 | || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))) | 3271 | || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))) |
| 3254 | { | 3272 | { |
| 3273 | mouse_frame = hlinfo->mouse_face_mouse_frame; | ||
| 3274 | |||
| 3255 | clear_mouse_face (hlinfo); | 3275 | clear_mouse_face (hlinfo); |
| 3256 | hlinfo->mouse_face_hidden = true; | 3276 | hlinfo->mouse_face_hidden = true; |
| 3257 | haiku_flush_dirty_back_buffer_on (f); | 3277 | |
| 3278 | if (mouse_frame) | ||
| 3279 | haiku_flush_dirty_back_buffer_on (mouse_frame); | ||
| 3258 | } | 3280 | } |
| 3259 | 3281 | ||
| 3260 | inev.code = b->keysym ? b->keysym : b->multibyte_char; | 3282 | inev.code = b->keysym ? b->keysym : b->multibyte_char; |
diff --git a/src/haikuterm.h b/src/haikuterm.h index 86274fd42a3..70e8cf948bf 100644 --- a/src/haikuterm.h +++ b/src/haikuterm.h | |||
| @@ -174,6 +174,10 @@ struct haiku_output | |||
| 174 | displayed yet. */ | 174 | displayed yet. */ |
| 175 | bool_bf dirty_p : 1; | 175 | bool_bf dirty_p : 1; |
| 176 | 176 | ||
| 177 | /* Whether or not the frame is complete, i.e. safe to flush on | ||
| 178 | input. */ | ||
| 179 | bool_bf complete_p : 1; | ||
| 180 | |||
| 177 | struct font *font; | 181 | struct font *font; |
| 178 | 182 | ||
| 179 | /* The pending position we're waiting for. */ | 183 | /* The pending position we're waiting for. */ |
| @@ -275,6 +279,7 @@ struct scroll_bar | |||
| 275 | #define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec)) | 279 | #define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec)) |
| 276 | 280 | ||
| 277 | #define FRAME_DIRTY_P(f) (FRAME_OUTPUT_DATA (f)->dirty_p) | 281 | #define FRAME_DIRTY_P(f) (FRAME_OUTPUT_DATA (f)->dirty_p) |
| 282 | #define FRAME_COMPLETE_P(f) (FRAME_OUTPUT_DATA (f)->complete_p) | ||
| 278 | #define MAKE_FRAME_DIRTY(f) (FRAME_DIRTY_P (f) = 1) | 283 | #define MAKE_FRAME_DIRTY(f) (FRAME_DIRTY_P (f) = 1) |
| 279 | #define FRAME_OUTPUT_DATA(f) ((f)->output_data.haiku) | 284 | #define FRAME_OUTPUT_DATA(f) ((f)->output_data.haiku) |
| 280 | #define FRAME_HAIKU_WINDOW(f) (FRAME_OUTPUT_DATA (f)->window) | 285 | #define FRAME_HAIKU_WINDOW(f) (FRAME_OUTPUT_DATA (f)->window) |
diff --git a/src/xfns.c b/src/xfns.c index 91124488994..e8732986eb9 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -8443,7 +8443,17 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, | |||
| 8443 | unblock_input (); | 8443 | unblock_input (); |
| 8444 | 8444 | ||
| 8445 | XSETFRAME (frame, f); | 8445 | XSETFRAME (frame, f); |
| 8446 | attributes = Fx_display_monitor_attributes_list (frame); | 8446 | |
| 8447 | #if defined HAVE_XRANDR || defined USE_GTK | ||
| 8448 | if (!NILP (FRAME_DISPLAY_INFO (f)->last_monitor_attributes_list)) | ||
| 8449 | /* Use cached values if available to avoid fetching the | ||
| 8450 | monitor list from the X server. If XRandR is not | ||
| 8451 | available, then fetching the attributes will probably not | ||
| 8452 | sync anyway, and will thus be relatively harmless. */ | ||
| 8453 | attributes = FRAME_DISPLAY_INFO (f)->last_monitor_attributes_list; | ||
| 8454 | else | ||
| 8455 | #endif | ||
| 8456 | attributes = Fx_display_monitor_attributes_list (frame); | ||
| 8447 | 8457 | ||
| 8448 | /* Try to determine the monitor where the mouse pointer is and | 8458 | /* Try to determine the monitor where the mouse pointer is and |
| 8449 | its geometry. See bug#22549. */ | 8459 | its geometry. See bug#22549. */ |
| @@ -8693,9 +8703,6 @@ Text larger than the specified size is clipped. */) | |||
| 8693 | int old_windows_or_buffers_changed = windows_or_buffers_changed; | 8703 | int old_windows_or_buffers_changed = windows_or_buffers_changed; |
| 8694 | specpdl_ref count = SPECPDL_INDEX (); | 8704 | specpdl_ref count = SPECPDL_INDEX (); |
| 8695 | Lisp_Object window, size, tip_buf; | 8705 | Lisp_Object window, size, tip_buf; |
| 8696 | Window child; | ||
| 8697 | XWindowAttributes child_attrs; | ||
| 8698 | int dest_x_return, dest_y_return; | ||
| 8699 | bool displayed; | 8706 | bool displayed; |
| 8700 | #ifdef ENABLE_CHECKING | 8707 | #ifdef ENABLE_CHECKING |
| 8701 | struct glyph_row *row, *end; | 8708 | struct glyph_row *row, *end; |
| @@ -8946,41 +8953,6 @@ Text larger than the specified size is clipped. */) | |||
| 8946 | 8953 | ||
| 8947 | /* Show tooltip frame. */ | 8954 | /* Show tooltip frame. */ |
| 8948 | block_input (); | 8955 | block_input (); |
| 8949 | /* If the display is composited, then WM_TRANSIENT_FOR must be set | ||
| 8950 | as well, or else the compositing manager won't display | ||
| 8951 | decorations correctly, even though the tooltip window is override | ||
| 8952 | redirect. See | ||
| 8953 | https://specifications.freedesktop.org/wm-spec/1.4/ar01s08.html | ||
| 8954 | |||
| 8955 | Perhaps WM_TRANSIENT_FOR should be used in place of | ||
| 8956 | override-redirect anyway. The ICCCM only recommends | ||
| 8957 | override-redirect if the pointer will be grabbed. */ | ||
| 8958 | |||
| 8959 | if (XTranslateCoordinates (FRAME_X_DISPLAY (f), | ||
| 8960 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 8961 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 8962 | root_x, root_y, &dest_x_return, | ||
| 8963 | &dest_y_return, &child) | ||
| 8964 | && child != None) | ||
| 8965 | { | ||
| 8966 | /* But only if the child is not override-redirect, which can | ||
| 8967 | happen if the pointer is above a menu. */ | ||
| 8968 | |||
| 8969 | if (XGetWindowAttributes (FRAME_X_DISPLAY (f), | ||
| 8970 | child, &child_attrs) | ||
| 8971 | || child_attrs.override_redirect) | ||
| 8972 | XDeleteProperty (FRAME_X_DISPLAY (tip_f), | ||
| 8973 | FRAME_X_WINDOW (tip_f), | ||
| 8974 | FRAME_DISPLAY_INFO (tip_f)->Xatom_wm_transient_for); | ||
| 8975 | else | ||
| 8976 | XSetTransientForHint (FRAME_X_DISPLAY (tip_f), | ||
| 8977 | FRAME_X_WINDOW (tip_f), child); | ||
| 8978 | } | ||
| 8979 | else | ||
| 8980 | XDeleteProperty (FRAME_X_DISPLAY (tip_f), | ||
| 8981 | FRAME_X_WINDOW (tip_f), | ||
| 8982 | FRAME_DISPLAY_INFO (tip_f)->Xatom_wm_transient_for); | ||
| 8983 | |||
| 8984 | #ifndef USE_XCB | 8956 | #ifndef USE_XCB |
| 8985 | XMoveResizeWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f), | 8957 | XMoveResizeWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f), |
| 8986 | root_x, root_y, width, height); | 8958 | root_x, root_y, width, height); |
| @@ -9452,13 +9424,21 @@ usual X keysyms. Value is `lambda' if we cannot determine if both keys are | |||
| 9452 | present and mapped to the usual X keysyms. */) | 9424 | present and mapped to the usual X keysyms. */) |
| 9453 | (Lisp_Object frame) | 9425 | (Lisp_Object frame) |
| 9454 | { | 9426 | { |
| 9427 | #ifdef HAVE_XKB | ||
| 9428 | XkbDescPtr kb; | ||
| 9429 | struct frame *f; | ||
| 9430 | Display *dpy; | ||
| 9431 | Lisp_Object have_keys; | ||
| 9432 | int delete_keycode, backspace_keycode, i; | ||
| 9433 | #endif | ||
| 9434 | |||
| 9455 | #ifndef HAVE_XKB | 9435 | #ifndef HAVE_XKB |
| 9456 | return Qlambda; | 9436 | return Qlambda; |
| 9457 | #else | 9437 | #else |
| 9458 | XkbDescPtr kb; | 9438 | delete_keycode = 0; |
| 9459 | struct frame *f = decode_window_system_frame (frame); | 9439 | backspace_keycode = 0; |
| 9460 | Display *dpy = FRAME_X_DISPLAY (f); | 9440 | f = decode_window_system_frame (frame); |
| 9461 | Lisp_Object have_keys; | 9441 | dpy = FRAME_X_DISPLAY (f); |
| 9462 | 9442 | ||
| 9463 | if (!FRAME_DISPLAY_INFO (f)->supports_xkb) | 9443 | if (!FRAME_DISPLAY_INFO (f)->supports_xkb) |
| 9464 | return Qlambda; | 9444 | return Qlambda; |
| @@ -9474,50 +9454,39 @@ present and mapped to the usual X keysyms. */) | |||
| 9474 | XK_Delete are mapped to any key. But if any of those are mapped to | 9454 | XK_Delete are mapped to any key. But if any of those are mapped to |
| 9475 | some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the | 9455 | some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the |
| 9476 | user doesn't know about it, it is better to return false here. | 9456 | user doesn't know about it, it is better to return false here. |
| 9477 | It is more obvious to the user what to do if she/he has two keys | 9457 | It is more obvious to the user what to do if there are two keys |
| 9478 | clearly marked with names/symbols and one key does something not | 9458 | clearly marked with names/symbols and one key does something not |
| 9479 | expected (i.e. she/he then tries the other). | 9459 | expected (and the user then tries the other). |
| 9480 | The cases where Backspace/Delete is mapped to some other key combination | 9460 | The cases where Backspace/Delete is mapped to some other key combination |
| 9481 | are rare, and in those cases, normal-erase-is-backspace can be turned on | 9461 | are rare, and in those cases, normal-erase-is-backspace can be turned on |
| 9482 | manually. */ | 9462 | manually. */ |
| 9483 | 9463 | ||
| 9484 | have_keys = Qnil; | 9464 | have_keys = Qnil; |
| 9485 | kb = XkbGetMap (dpy, XkbAllMapComponentsMask, XkbUseCoreKbd); | 9465 | kb = FRAME_DISPLAY_INFO (f)->xkb_desc; |
| 9486 | if (kb) | 9466 | if (kb && kb->names) |
| 9487 | { | 9467 | { |
| 9488 | int delete_keycode = 0, backspace_keycode = 0, i; | 9468 | for (i = kb->min_key_code; (i < kb->max_key_code |
| 9489 | 9469 | && (delete_keycode == 0 | |
| 9490 | if (XkbGetNames (dpy, XkbAllNamesMask, kb) == Success) | 9470 | || backspace_keycode == 0)); |
| 9471 | ++i) | ||
| 9491 | { | 9472 | { |
| 9492 | for (i = kb->min_key_code; | 9473 | /* The XKB symbolic key names can be seen most easily in |
| 9493 | (i < kb->max_key_code | 9474 | the PS file generated by `xkbprint -label name |
| 9494 | && (delete_keycode == 0 || backspace_keycode == 0)); | 9475 | $DISPLAY'. */ |
| 9495 | ++i) | 9476 | if (!memcmp ("DELE", kb->names->keys[i].name, 4)) |
| 9496 | { | 9477 | delete_keycode = i; |
| 9497 | /* The XKB symbolic key names can be seen most easily in | 9478 | else if (!memcmp ("BKSP", kb->names->keys[i].name, 4)) |
| 9498 | the PS file generated by `xkbprint -label name | 9479 | backspace_keycode = i; |
| 9499 | $DISPLAY'. */ | ||
| 9500 | if (memcmp ("DELE", kb->names->keys[i].name, 4) == 0) | ||
| 9501 | delete_keycode = i; | ||
| 9502 | else if (memcmp ("BKSP", kb->names->keys[i].name, 4) == 0) | ||
| 9503 | backspace_keycode = i; | ||
| 9504 | } | ||
| 9505 | |||
| 9506 | XkbFreeNames (kb, 0, True); | ||
| 9507 | } | 9480 | } |
| 9508 | 9481 | ||
| 9509 | /* As of libX11-1.6.2, XkbGetMap manual says that you should use | 9482 | if (delete_keycode && backspace_keycode |
| 9510 | XkbFreeClientMap to free the data returned by XkbGetMap. But | ||
| 9511 | this function just frees the data referenced from KB and not | ||
| 9512 | KB itself. To free KB as well, call XkbFreeKeyboard. */ | ||
| 9513 | XkbFreeKeyboard (kb, XkbAllMapComponentsMask, True); | ||
| 9514 | |||
| 9515 | if (delete_keycode | ||
| 9516 | && backspace_keycode | ||
| 9517 | && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode | 9483 | && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode |
| 9518 | && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode) | 9484 | && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode) |
| 9519 | have_keys = Qt; | 9485 | have_keys = Qt; |
| 9520 | } | 9486 | } |
| 9487 | else | ||
| 9488 | /* The keyboard names couldn't be obtained for some reason. */ | ||
| 9489 | have_keys = Qlambda; | ||
| 9521 | unblock_input (); | 9490 | unblock_input (); |
| 9522 | return have_keys; | 9491 | return have_keys; |
| 9523 | #endif | 9492 | #endif |
diff --git a/src/xmenu.c b/src/xmenu.c index 1452b3c6d12..9d35e3529fb 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -1521,26 +1521,15 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, | |||
| 1521 | 1521 | ||
| 1522 | if (use_pos_func) | 1522 | if (use_pos_func) |
| 1523 | { | 1523 | { |
| 1524 | Window dummy_window; | ||
| 1525 | |||
| 1526 | /* Not invoked by a click. pop up at x/y. */ | 1524 | /* Not invoked by a click. pop up at x/y. */ |
| 1527 | pos_func = menu_position_func; | 1525 | pos_func = menu_position_func; |
| 1528 | 1526 | ||
| 1529 | /* Adjust coordinates to be root-window-relative. */ | 1527 | /* Adjust coordinates to be root-window-relative. */ |
| 1530 | block_input (); | 1528 | block_input (); |
| 1531 | XTranslateCoordinates (FRAME_X_DISPLAY (f), | 1529 | x_translate_coordinates_to_root (f, x, y, &x, &y); |
| 1532 | |||
| 1533 | /* From-window, to-window. */ | ||
| 1534 | FRAME_X_WINDOW (f), | ||
| 1535 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 1536 | |||
| 1537 | /* From-position, to-position. */ | ||
| 1538 | x, y, &x, &y, | ||
| 1539 | |||
| 1540 | /* Child of win. */ | ||
| 1541 | &dummy_window); | ||
| 1542 | #ifdef HAVE_GTK3 | 1530 | #ifdef HAVE_GTK3 |
| 1543 | /* Use window scaling factor to adjust position for hidpi screens. */ | 1531 | /* Use window scaling factor to adjust position for scaled |
| 1532 | outputs. */ | ||
| 1544 | x /= xg_get_scale (f); | 1533 | x /= xg_get_scale (f); |
| 1545 | y /= xg_get_scale (f); | 1534 | y /= xg_get_scale (f); |
| 1546 | #endif | 1535 | #endif |
| @@ -1743,7 +1732,6 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, | |||
| 1743 | XButtonPressedEvent *event = &(dummy.xbutton); | 1732 | XButtonPressedEvent *event = &(dummy.xbutton); |
| 1744 | LWLIB_ID menu_id; | 1733 | LWLIB_ID menu_id; |
| 1745 | Widget menu; | 1734 | Widget menu; |
| 1746 | Window dummy_window; | ||
| 1747 | #if defined HAVE_XINPUT2 && defined USE_MOTIF | 1735 | #if defined HAVE_XINPUT2 && defined USE_MOTIF |
| 1748 | XEvent property_dummy; | 1736 | XEvent property_dummy; |
| 1749 | Atom property_atom; | 1737 | Atom property_atom; |
| @@ -1775,17 +1763,7 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, | |||
| 1775 | /* Adjust coordinates to be root-window-relative. */ | 1763 | /* Adjust coordinates to be root-window-relative. */ |
| 1776 | block_input (); | 1764 | block_input (); |
| 1777 | x += FRAME_LEFT_SCROLL_BAR_AREA_WIDTH (f); | 1765 | x += FRAME_LEFT_SCROLL_BAR_AREA_WIDTH (f); |
| 1778 | XTranslateCoordinates (FRAME_X_DISPLAY (f), | 1766 | x_translate_coordinates_to_root (f, x, y, &x, &y); |
| 1779 | |||
| 1780 | /* From-window, to-window. */ | ||
| 1781 | FRAME_X_WINDOW (f), | ||
| 1782 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 1783 | |||
| 1784 | /* From-position, to-position. */ | ||
| 1785 | x, y, &x, &y, | ||
| 1786 | |||
| 1787 | /* Child of win. */ | ||
| 1788 | &dummy_window); | ||
| 1789 | unblock_input (); | 1767 | unblock_input (); |
| 1790 | 1768 | ||
| 1791 | event->x_root = x; | 1769 | event->x_root = x; |
| @@ -2569,9 +2547,6 @@ Lisp_Object | |||
| 2569 | x_menu_show (struct frame *f, int x, int y, int menuflags, | 2547 | x_menu_show (struct frame *f, int x, int y, int menuflags, |
| 2570 | Lisp_Object title, const char **error_name) | 2548 | Lisp_Object title, const char **error_name) |
| 2571 | { | 2549 | { |
| 2572 | #ifdef HAVE_X_WINDOWS | ||
| 2573 | Window dummy_window; | ||
| 2574 | #endif | ||
| 2575 | Window root; | 2550 | Window root; |
| 2576 | XMenu *menu; | 2551 | XMenu *menu; |
| 2577 | int pane, selidx, lpane, status; | 2552 | int pane, selidx, lpane, status; |
| @@ -2620,17 +2595,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags, | |||
| 2620 | inhibit_garbage_collection (); | 2595 | inhibit_garbage_collection (); |
| 2621 | 2596 | ||
| 2622 | #ifdef HAVE_X_WINDOWS | 2597 | #ifdef HAVE_X_WINDOWS |
| 2623 | XTranslateCoordinates (FRAME_X_DISPLAY (f), | 2598 | x_translate_coordinates_to_root (f, x, y, &x, &y); |
| 2624 | |||
| 2625 | /* From-window, to-window. */ | ||
| 2626 | FRAME_X_WINDOW (f), | ||
| 2627 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 2628 | |||
| 2629 | /* From-position, to-position. */ | ||
| 2630 | x, y, &x, &y, | ||
| 2631 | |||
| 2632 | /* Child of win. */ | ||
| 2633 | &dummy_window); | ||
| 2634 | #else | 2599 | #else |
| 2635 | /* MSDOS without X support. */ | 2600 | /* MSDOS without X support. */ |
| 2636 | x += f->left_pos; | 2601 | x += f->left_pos; |
diff --git a/src/xselect.c b/src/xselect.c index 66782d41723..498c28af536 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -2376,12 +2376,19 @@ On Nextstep, TERMINAL is unused. */) | |||
| 2376 | { | 2376 | { |
| 2377 | Window owner; | 2377 | Window owner; |
| 2378 | Atom atom; | 2378 | Atom atom; |
| 2379 | #ifdef HAVE_XFIXES | ||
| 2380 | Window temp_owner; | ||
| 2381 | #endif | ||
| 2379 | struct frame *f = frame_for_x_selection (terminal); | 2382 | struct frame *f = frame_for_x_selection (terminal); |
| 2380 | struct x_display_info *dpyinfo; | 2383 | struct x_display_info *dpyinfo; |
| 2381 | 2384 | ||
| 2382 | CHECK_SYMBOL (selection); | 2385 | CHECK_SYMBOL (selection); |
| 2383 | if (NILP (selection)) selection = QPRIMARY; | 2386 | |
| 2384 | if (EQ (selection, Qt)) selection = QSECONDARY; | 2387 | if (NILP (selection)) |
| 2388 | selection = QPRIMARY; | ||
| 2389 | |||
| 2390 | if (EQ (selection, Qt)) | ||
| 2391 | selection = QSECONDARY; | ||
| 2385 | 2392 | ||
| 2386 | if (!f) | 2393 | if (!f) |
| 2387 | return Qnil; | 2394 | return Qnil; |
| @@ -2392,10 +2399,22 @@ On Nextstep, TERMINAL is unused. */) | |||
| 2392 | return Qt; | 2399 | return Qt; |
| 2393 | 2400 | ||
| 2394 | atom = symbol_to_x_atom (dpyinfo, selection); | 2401 | atom = symbol_to_x_atom (dpyinfo, selection); |
| 2395 | if (atom == 0) return Qnil; | 2402 | |
| 2403 | if (!atom) | ||
| 2404 | return Qnil; | ||
| 2405 | |||
| 2406 | #ifdef HAVE_XFIXES | ||
| 2407 | /* See if this information can be obtained without a roundtrip. */ | ||
| 2408 | temp_owner = x_find_selection_owner (dpyinfo, atom); | ||
| 2409 | |||
| 2410 | if (temp_owner != X_INVALID_WINDOW) | ||
| 2411 | return (temp_owner != None ? Qt : Qnil); | ||
| 2412 | #endif | ||
| 2413 | |||
| 2396 | block_input (); | 2414 | block_input (); |
| 2397 | owner = XGetSelectionOwner (dpyinfo->display, atom); | 2415 | owner = XGetSelectionOwner (dpyinfo->display, atom); |
| 2398 | unblock_input (); | 2416 | unblock_input (); |
| 2417 | |||
| 2399 | return (owner ? Qt : Qnil); | 2418 | return (owner ? Qt : Qnil); |
| 2400 | } | 2419 | } |
| 2401 | 2420 | ||
diff --git a/src/xterm.c b/src/xterm.c index d35af7a8de2..7c3ab87e87b 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -7044,6 +7044,13 @@ x_update_begin (struct frame *f) | |||
| 7044 | #else | 7044 | #else |
| 7045 | /* Nothing to do. */ | 7045 | /* Nothing to do. */ |
| 7046 | #endif | 7046 | #endif |
| 7047 | |||
| 7048 | #ifdef HAVE_XDBE | ||
| 7049 | if (FRAME_X_DOUBLE_BUFFERED_P (f)) | ||
| 7050 | /* The frame is no longer complete, as it is in the midst of an | ||
| 7051 | update. */ | ||
| 7052 | FRAME_X_COMPLETE_P (f) = false; | ||
| 7053 | #endif | ||
| 7047 | } | 7054 | } |
| 7048 | 7055 | ||
| 7049 | /* Draw a vertical window border from (x,y0) to (x,y1) */ | 7056 | /* Draw a vertical window border from (x,y0) to (x,y1) */ |
| @@ -7190,6 +7197,10 @@ x_flip_and_flush (struct frame *f) | |||
| 7190 | #ifdef HAVE_XDBE | 7197 | #ifdef HAVE_XDBE |
| 7191 | if (FRAME_X_NEED_BUFFER_FLIP (f)) | 7198 | if (FRAME_X_NEED_BUFFER_FLIP (f)) |
| 7192 | show_back_buffer (f); | 7199 | show_back_buffer (f); |
| 7200 | |||
| 7201 | /* The frame is complete again as its contents were just | ||
| 7202 | flushed. */ | ||
| 7203 | FRAME_X_COMPLETE_P (f) = true; | ||
| 7193 | #endif | 7204 | #endif |
| 7194 | x_flush (f); | 7205 | x_flush (f); |
| 7195 | unblock_input (); | 7206 | unblock_input (); |
| @@ -7240,6 +7251,9 @@ XTframe_up_to_date (struct frame *f) | |||
| 7240 | if (!buffer_flipping_blocked_p () | 7251 | if (!buffer_flipping_blocked_p () |
| 7241 | && FRAME_X_NEED_BUFFER_FLIP (f)) | 7252 | && FRAME_X_NEED_BUFFER_FLIP (f)) |
| 7242 | show_back_buffer (f); | 7253 | show_back_buffer (f); |
| 7254 | |||
| 7255 | /* The frame is now complete, as its contents have been drawn. */ | ||
| 7256 | FRAME_X_COMPLETE_P (f) = true; | ||
| 7243 | #endif | 7257 | #endif |
| 7244 | 7258 | ||
| 7245 | #ifdef HAVE_XSYNC | 7259 | #ifdef HAVE_XSYNC |
| @@ -10806,6 +10820,7 @@ x_clear_frame (struct frame *f) | |||
| 10806 | /* We have to clear the scroll bars. If we have changed colors or | 10820 | /* We have to clear the scroll bars. If we have changed colors or |
| 10807 | something like that, then they should be notified. */ | 10821 | something like that, then they should be notified. */ |
| 10808 | x_scroll_bar_clear (f); | 10822 | x_scroll_bar_clear (f); |
| 10823 | |||
| 10809 | unblock_input (); | 10824 | unblock_input (); |
| 10810 | } | 10825 | } |
| 10811 | 10826 | ||
| @@ -10857,7 +10872,7 @@ x_show_hourglass (struct frame *f) | |||
| 10857 | (xcb_window_t) x->hourglass_window, | 10872 | (xcb_window_t) x->hourglass_window, |
| 10858 | parent, 0, 0, FRAME_PIXEL_WIDTH (f), | 10873 | parent, 0, 0, FRAME_PIXEL_WIDTH (f), |
| 10859 | FRAME_PIXEL_HEIGHT (f), 0, | 10874 | FRAME_PIXEL_HEIGHT (f), 0, |
| 10860 | XCB_WINDOW_CLASS_INPUT_OUTPUT, | 10875 | XCB_WINDOW_CLASS_INPUT_ONLY, |
| 10861 | XCB_COPY_FROM_PARENT, XCB_CW_CURSOR, | 10876 | XCB_COPY_FROM_PARENT, XCB_CW_CURSOR, |
| 10862 | &cursor); | 10877 | &cursor); |
| 10863 | #endif | 10878 | #endif |
| @@ -13644,6 +13659,43 @@ x_translate_coordinates (struct frame *f, int root_x, int root_y, | |||
| 13644 | } | 13659 | } |
| 13645 | } | 13660 | } |
| 13646 | 13661 | ||
| 13662 | /* Translate the given coordinates from the edit window of FRAME, | ||
| 13663 | taking into account any cached root window offsets. This is mainly | ||
| 13664 | used from the popup menu code. */ | ||
| 13665 | |||
| 13666 | void | ||
| 13667 | x_translate_coordinates_to_root (struct frame *f, int x, int y, | ||
| 13668 | int *x_out, int *y_out) | ||
| 13669 | { | ||
| 13670 | struct x_output *output; | ||
| 13671 | Window dummy; | ||
| 13672 | |||
| 13673 | output = FRAME_X_OUTPUT (f); | ||
| 13674 | |||
| 13675 | if (output->window_offset_certain_p) | ||
| 13676 | { | ||
| 13677 | /* Use the cached root window offset. */ | ||
| 13678 | *x_out = x + output->root_x; | ||
| 13679 | *y_out = y + output->root_y; | ||
| 13680 | |||
| 13681 | return; | ||
| 13682 | } | ||
| 13683 | |||
| 13684 | /* Otherwise, do the transform manually and compute and cache the | ||
| 13685 | root window position. */ | ||
| 13686 | if (!XTranslateCoordinates (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 13687 | FRAME_DISPLAY_INFO (f)->root_window, | ||
| 13688 | x, y, x_out, y_out, &dummy)) | ||
| 13689 | *x_out = 0, *y_out = 0; | ||
| 13690 | else | ||
| 13691 | { | ||
| 13692 | /* Cache the root window offset of the edit window. */ | ||
| 13693 | output->window_offset_certain_p = true; | ||
| 13694 | output->root_x = *x_out - x; | ||
| 13695 | output->root_y = *y_out - y; | ||
| 13696 | } | ||
| 13697 | } | ||
| 13698 | |||
| 13647 | /* The same, but for an XIDeviceEvent. */ | 13699 | /* The same, but for an XIDeviceEvent. */ |
| 13648 | 13700 | ||
| 13649 | #ifdef HAVE_XINPUT2 | 13701 | #ifdef HAVE_XINPUT2 |
| @@ -17033,18 +17085,21 @@ x_net_wm_state (struct frame *f, Window window) | |||
| 17033 | 17085 | ||
| 17034 | /* Flip back buffers on F if it has undrawn content. */ | 17086 | /* Flip back buffers on F if it has undrawn content. */ |
| 17035 | 17087 | ||
| 17036 | #ifdef HAVE_XDBE | ||
| 17037 | static void | 17088 | static void |
| 17038 | flush_dirty_back_buffer_on (struct frame *f) | 17089 | x_flush_dirty_back_buffer_on (struct frame *f) |
| 17039 | { | 17090 | { |
| 17040 | block_input (); | 17091 | #ifdef HAVE_XDBE |
| 17041 | if (!FRAME_GARBAGED_P (f) | 17092 | if (FRAME_GARBAGED_P (f) |
| 17042 | && !buffer_flipping_blocked_p () | 17093 | || buffer_flipping_blocked_p () |
| 17043 | && FRAME_X_NEED_BUFFER_FLIP (f)) | 17094 | /* If the frame is not already up to date, do not flush buffers |
| 17044 | show_back_buffer (f); | 17095 | on input, as that will result in flicker. */ |
| 17045 | unblock_input (); | 17096 | || !FRAME_X_COMPLETE_P (f) |
| 17046 | } | 17097 | || !FRAME_X_NEED_BUFFER_FLIP (f)) |
| 17098 | return; | ||
| 17099 | |||
| 17100 | show_back_buffer (f); | ||
| 17047 | #endif | 17101 | #endif |
| 17102 | } | ||
| 17048 | 17103 | ||
| 17049 | #ifdef HAVE_GTK3 | 17104 | #ifdef HAVE_GTK3 |
| 17050 | void | 17105 | void |
| @@ -17798,6 +17853,46 @@ x_handle_wm_state (struct frame *f, struct input_event *ie) | |||
| 17798 | XFree (data); | 17853 | XFree (data); |
| 17799 | } | 17854 | } |
| 17800 | 17855 | ||
| 17856 | #ifdef HAVE_XFIXES | ||
| 17857 | |||
| 17858 | static bool | ||
| 17859 | x_handle_selection_monitor_event (struct x_display_info *dpyinfo, | ||
| 17860 | XEvent *event) | ||
| 17861 | { | ||
| 17862 | XFixesSelectionNotifyEvent *notify; | ||
| 17863 | int i; | ||
| 17864 | |||
| 17865 | notify = (XFixesSelectionNotifyEvent *) event; | ||
| 17866 | |||
| 17867 | if (notify->window != dpyinfo->selection_tracking_window) | ||
| 17868 | return false; | ||
| 17869 | |||
| 17870 | for (i = 0; i < dpyinfo->n_monitored_selections; ++i) | ||
| 17871 | { | ||
| 17872 | /* We don't have to keep track of timestamps here. */ | ||
| 17873 | if (notify->selection == dpyinfo->monitored_selections[i].name) | ||
| 17874 | dpyinfo->monitored_selections[i].owner = notify->owner; | ||
| 17875 | } | ||
| 17876 | |||
| 17877 | return true; | ||
| 17878 | } | ||
| 17879 | |||
| 17880 | Window | ||
| 17881 | x_find_selection_owner (struct x_display_info *dpyinfo, Atom selection) | ||
| 17882 | { | ||
| 17883 | int i; | ||
| 17884 | |||
| 17885 | for (i = 0; i < dpyinfo->n_monitored_selections; ++i) | ||
| 17886 | { | ||
| 17887 | if (selection == dpyinfo->monitored_selections[i].name) | ||
| 17888 | return dpyinfo->monitored_selections[i].owner; | ||
| 17889 | } | ||
| 17890 | |||
| 17891 | return X_INVALID_WINDOW; | ||
| 17892 | } | ||
| 17893 | |||
| 17894 | #endif | ||
| 17895 | |||
| 17801 | /* Handles the XEvent EVENT on display DPYINFO. | 17896 | /* Handles the XEvent EVENT on display DPYINFO. |
| 17802 | 17897 | ||
| 17803 | *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. | 17898 | *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. |
| @@ -17824,7 +17919,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17824 | Time gen_help_time UNINIT; | 17919 | Time gen_help_time UNINIT; |
| 17825 | #endif | 17920 | #endif |
| 17826 | ptrdiff_t nbytes = 0; | 17921 | ptrdiff_t nbytes = 0; |
| 17827 | struct frame *any, *f = NULL; | 17922 | struct frame *any, *f = NULL, *mouse_frame; |
| 17828 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; | 17923 | Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; |
| 17829 | /* This holds the state XLookupString needs to implement dead keys | 17924 | /* This holds the state XLookupString needs to implement dead keys |
| 17830 | and other tricks known as "compose processing". _X Window System_ | 17925 | and other tricks known as "compose processing". _X Window System_ |
| @@ -19148,9 +19243,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 19148 | || !EQ (f->tab_bar_window, hlinfo->mouse_face_window)) | 19243 | || !EQ (f->tab_bar_window, hlinfo->mouse_face_window)) |
| 19149 | ) | 19244 | ) |
| 19150 | { | 19245 | { |
| 19151 | clear_mouse_face (hlinfo); | 19246 | mouse_frame = hlinfo->mouse_face_mouse_frame; |
| 19152 | hlinfo->mouse_face_hidden = true; | 19247 | |
| 19153 | } | 19248 | clear_mouse_face (hlinfo); |
| 19249 | hlinfo->mouse_face_hidden = true; | ||
| 19250 | |||
| 19251 | if (mouse_frame) | ||
| 19252 | x_flush_dirty_back_buffer_on (mouse_frame); | ||
| 19253 | } | ||
| 19154 | 19254 | ||
| 19155 | #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS | 19255 | #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS |
| 19156 | if (f == 0) | 19256 | if (f == 0) |
| @@ -19630,6 +19730,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 19630 | { | 19730 | { |
| 19631 | clear_mouse_face (hlinfo); | 19731 | clear_mouse_face (hlinfo); |
| 19632 | hlinfo->mouse_face_mouse_frame = 0; | 19732 | hlinfo->mouse_face_mouse_frame = 0; |
| 19733 | x_flush_dirty_back_buffer_on (xvw->frame); | ||
| 19633 | } | 19734 | } |
| 19634 | 19735 | ||
| 19635 | if (any_help_event_p) | 19736 | if (any_help_event_p) |
| @@ -19783,6 +19884,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 19783 | certainly no longer on any text in the frame. */ | 19884 | certainly no longer on any text in the frame. */ |
| 19784 | clear_mouse_face (hlinfo); | 19885 | clear_mouse_face (hlinfo); |
| 19785 | hlinfo->mouse_face_mouse_frame = 0; | 19886 | hlinfo->mouse_face_mouse_frame = 0; |
| 19887 | x_flush_dirty_back_buffer_on (f); | ||
| 19786 | } | 19888 | } |
| 19787 | 19889 | ||
| 19788 | /* Generate a nil HELP_EVENT to cancel a help-echo. | 19890 | /* Generate a nil HELP_EVENT to cancel a help-echo. |
| @@ -19840,7 +19942,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 19840 | help_echo_string = Qnil; | 19942 | help_echo_string = Qnil; |
| 19841 | 19943 | ||
| 19842 | if (hlinfo->mouse_face_hidden) | 19944 | if (hlinfo->mouse_face_hidden) |
| 19843 | { | 19945 | { |
| 19844 | hlinfo->mouse_face_hidden = false; | 19946 | hlinfo->mouse_face_hidden = false; |
| 19845 | clear_mouse_face (hlinfo); | 19947 | clear_mouse_face (hlinfo); |
| 19846 | } | 19948 | } |
| @@ -20171,6 +20273,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 20171 | if (!NILP (help_echo_string) | 20273 | if (!NILP (help_echo_string) |
| 20172 | || !NILP (previous_help_echo_string)) | 20274 | || !NILP (previous_help_echo_string)) |
| 20173 | do_help = 1; | 20275 | do_help = 1; |
| 20276 | |||
| 20277 | if (f) | ||
| 20278 | x_flush_dirty_back_buffer_on (f); | ||
| 20174 | goto OTHER; | 20279 | goto OTHER; |
| 20175 | } | 20280 | } |
| 20176 | 20281 | ||
| @@ -20467,7 +20572,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 20467 | { | 20572 | { |
| 20468 | int old_left = f->left_pos; | 20573 | int old_left = f->left_pos; |
| 20469 | int old_top = f->top_pos; | 20574 | int old_top = f->top_pos; |
| 20470 | Lisp_Object frame = Qnil; | 20575 | Lisp_Object frame; |
| 20471 | 20576 | ||
| 20472 | XSETFRAME (frame, f); | 20577 | XSETFRAME (frame, f); |
| 20473 | 20578 | ||
| @@ -20837,9 +20942,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 20837 | tab_bar_p = EQ (window, f->tab_bar_window); | 20942 | tab_bar_p = EQ (window, f->tab_bar_window); |
| 20838 | 20943 | ||
| 20839 | if (tab_bar_p) | 20944 | if (tab_bar_p) |
| 20840 | tab_bar_arg = handle_tab_bar_click | 20945 | { |
| 20841 | (f, x, y, event->xbutton.type == ButtonPress, | 20946 | tab_bar_arg = handle_tab_bar_click |
| 20842 | x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state)); | 20947 | (f, x, y, event->xbutton.type == ButtonPress, |
| 20948 | x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state)); | ||
| 20949 | x_flush_dirty_back_buffer_on (f); | ||
| 20950 | } | ||
| 20843 | } | 20951 | } |
| 20844 | 20952 | ||
| 20845 | #if ! defined (USE_GTK) | 20953 | #if ! defined (USE_GTK) |
| @@ -20857,9 +20965,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 20857 | || f->last_tool_bar_item != -1)); | 20965 | || f->last_tool_bar_item != -1)); |
| 20858 | 20966 | ||
| 20859 | if (tool_bar_p && event->xbutton.button < 4) | 20967 | if (tool_bar_p && event->xbutton.button < 4) |
| 20860 | handle_tool_bar_click | 20968 | { |
| 20861 | (f, x, y, event->xbutton.type == ButtonPress, | 20969 | handle_tool_bar_click |
| 20862 | x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state)); | 20970 | (f, x, y, event->xbutton.type == ButtonPress, |
| 20971 | x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state)); | ||
| 20972 | x_flush_dirty_back_buffer_on (f); | ||
| 20973 | } | ||
| 20863 | } | 20974 | } |
| 20864 | #endif /* !USE_GTK */ | 20975 | #endif /* !USE_GTK */ |
| 20865 | 20976 | ||
| @@ -21398,6 +21509,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21398 | certainly no longer on any text in the frame. */ | 21509 | certainly no longer on any text in the frame. */ |
| 21399 | clear_mouse_face (hlinfo); | 21510 | clear_mouse_face (hlinfo); |
| 21400 | hlinfo->mouse_face_mouse_frame = 0; | 21511 | hlinfo->mouse_face_mouse_frame = 0; |
| 21512 | x_flush_dirty_back_buffer_on (f); | ||
| 21401 | } | 21513 | } |
| 21402 | 21514 | ||
| 21403 | /* Generate a nil HELP_EVENT to cancel a help-echo. | 21515 | /* Generate a nil HELP_EVENT to cancel a help-echo. |
| @@ -22073,6 +22185,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 22073 | 22185 | ||
| 22074 | do_help = 1; | 22186 | do_help = 1; |
| 22075 | } | 22187 | } |
| 22188 | |||
| 22189 | if (f) | ||
| 22190 | x_flush_dirty_back_buffer_on (f); | ||
| 22076 | goto XI_OTHER; | 22191 | goto XI_OTHER; |
| 22077 | } | 22192 | } |
| 22078 | 22193 | ||
| @@ -22592,9 +22707,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 22592 | tab_bar_p = EQ (window, f->tab_bar_window); | 22707 | tab_bar_p = EQ (window, f->tab_bar_window); |
| 22593 | 22708 | ||
| 22594 | if (tab_bar_p) | 22709 | if (tab_bar_p) |
| 22595 | tab_bar_arg = handle_tab_bar_click | 22710 | { |
| 22596 | (f, x, y, xev->evtype == XI_ButtonPress, | 22711 | tab_bar_arg = handle_tab_bar_click |
| 22597 | x_x_to_emacs_modifiers (dpyinfo, bv.state)); | 22712 | (f, x, y, xev->evtype == XI_ButtonPress, |
| 22713 | x_x_to_emacs_modifiers (dpyinfo, bv.state)); | ||
| 22714 | x_flush_dirty_back_buffer_on (f); | ||
| 22715 | } | ||
| 22598 | } | 22716 | } |
| 22599 | 22717 | ||
| 22600 | #if ! defined (USE_GTK) | 22718 | #if ! defined (USE_GTK) |
| @@ -22619,10 +22737,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 22619 | || f->last_tool_bar_item != -1)); | 22737 | || f->last_tool_bar_item != -1)); |
| 22620 | 22738 | ||
| 22621 | if (tool_bar_p && xev->detail < 4) | 22739 | if (tool_bar_p && xev->detail < 4) |
| 22622 | handle_tool_bar_click_with_device | 22740 | { |
| 22623 | (f, x, y, xev->evtype == XI_ButtonPress, | 22741 | handle_tool_bar_click_with_device |
| 22624 | x_x_to_emacs_modifiers (dpyinfo, bv.state), | 22742 | (f, x, y, xev->evtype == XI_ButtonPress, |
| 22625 | source ? source->name : Qt); | 22743 | x_x_to_emacs_modifiers (dpyinfo, bv.state), |
| 22744 | source ? source->name : Qt); | ||
| 22745 | x_flush_dirty_back_buffer_on (f); | ||
| 22746 | } | ||
| 22626 | } | 22747 | } |
| 22627 | #endif /* !USE_GTK */ | 22748 | #endif /* !USE_GTK */ |
| 22628 | 22749 | ||
| @@ -22919,8 +23040,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 22919 | || !EQ (f->tab_bar_window, hlinfo->mouse_face_window)) | 23040 | || !EQ (f->tab_bar_window, hlinfo->mouse_face_window)) |
| 22920 | ) | 23041 | ) |
| 22921 | { | 23042 | { |
| 23043 | mouse_frame = hlinfo->mouse_face_mouse_frame; | ||
| 23044 | |||
| 22922 | clear_mouse_face (hlinfo); | 23045 | clear_mouse_face (hlinfo); |
| 22923 | hlinfo->mouse_face_hidden = true; | 23046 | hlinfo->mouse_face_hidden = true; |
| 23047 | |||
| 23048 | if (mouse_frame) | ||
| 23049 | x_flush_dirty_back_buffer_on (mouse_frame); | ||
| 22924 | } | 23050 | } |
| 22925 | 23051 | ||
| 22926 | if (f != 0) | 23052 | if (f != 0) |
| @@ -23299,7 +23425,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 23299 | /* Handle all disabled devices now, to prevent | 23425 | /* Handle all disabled devices now, to prevent |
| 23300 | things happening out-of-order later. */ | 23426 | things happening out-of-order later. */ |
| 23301 | 23427 | ||
| 23302 | if (ndevices) | 23428 | if (n_disabled) |
| 23303 | { | 23429 | { |
| 23304 | xi_disable_devices (dpyinfo, disabled, n_disabled); | 23430 | xi_disable_devices (dpyinfo, disabled, n_disabled); |
| 23305 | n_disabled = 0; | 23431 | n_disabled = 0; |
| @@ -23704,12 +23830,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 23704 | | XkbModifierMapMask | 23830 | | XkbModifierMapMask |
| 23705 | | XkbVirtualModsMask), | 23831 | | XkbVirtualModsMask), |
| 23706 | dpyinfo->xkb_desc) == Success) | 23832 | dpyinfo->xkb_desc) == Success) |
| 23707 | XkbGetNames (dpyinfo->display, | 23833 | XkbGetNames (dpyinfo->display, XkbAllNamesMask, |
| 23708 | XkbGroupNamesMask | XkbVirtualModNamesMask, | ||
| 23709 | dpyinfo->xkb_desc); | 23834 | dpyinfo->xkb_desc); |
| 23710 | else | 23835 | else |
| 23711 | { | 23836 | { |
| 23712 | XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True); | 23837 | XkbFreeKeyboard (dpyinfo->xkb_desc, |
| 23838 | XkbAllComponentsMask, True); | ||
| 23713 | dpyinfo->xkb_desc = NULL; | 23839 | dpyinfo->xkb_desc = NULL; |
| 23714 | } | 23840 | } |
| 23715 | } | 23841 | } |
| @@ -23723,8 +23849,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 23723 | XkbUseCoreKbd); | 23849 | XkbUseCoreKbd); |
| 23724 | 23850 | ||
| 23725 | if (dpyinfo->xkb_desc) | 23851 | if (dpyinfo->xkb_desc) |
| 23726 | XkbGetNames (dpyinfo->display, | 23852 | XkbGetNames (dpyinfo->display, XkbAllNamesMask, |
| 23727 | XkbGroupNamesMask | XkbVirtualModNamesMask, | ||
| 23728 | dpyinfo->xkb_desc); | 23853 | dpyinfo->xkb_desc); |
| 23729 | } | 23854 | } |
| 23730 | 23855 | ||
| @@ -24015,6 +24140,17 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 24015 | x_dnd_update_tooltip_now (); | 24140 | x_dnd_update_tooltip_now (); |
| 24016 | } | 24141 | } |
| 24017 | #endif | 24142 | #endif |
| 24143 | #ifdef HAVE_XFIXES | ||
| 24144 | if (dpyinfo->xfixes_supported_p | ||
| 24145 | && event->type == (dpyinfo->xfixes_event_base | ||
| 24146 | + XFixesSelectionNotify) | ||
| 24147 | && x_handle_selection_monitor_event (dpyinfo, event)) | ||
| 24148 | /* GTK 3 crashes if an XFixesSelectionNotify arrives with a | ||
| 24149 | window other than the root window, because it wants to know | ||
| 24150 | the screen in order to determine the compositing manager | ||
| 24151 | selection name. (bug#58584) */ | ||
| 24152 | *finish = X_EVENT_DROP; | ||
| 24153 | #endif | ||
| 24018 | OTHER: | 24154 | OTHER: |
| 24019 | #ifdef USE_X_TOOLKIT | 24155 | #ifdef USE_X_TOOLKIT |
| 24020 | if (*finish != X_EVENT_DROP) | 24156 | if (*finish != X_EVENT_DROP) |
| @@ -24084,18 +24220,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 24084 | count++; | 24220 | count++; |
| 24085 | } | 24221 | } |
| 24086 | 24222 | ||
| 24087 | /* Sometimes event processing draws to either F or ANY outside | ||
| 24088 | redisplay. To ensure that these changes become visible, draw | ||
| 24089 | them here. */ | ||
| 24090 | |||
| 24091 | #ifdef HAVE_XDBE | ||
| 24092 | if (f) | ||
| 24093 | flush_dirty_back_buffer_on (f); | ||
| 24094 | |||
| 24095 | if (any && any != f) | ||
| 24096 | flush_dirty_back_buffer_on (any); | ||
| 24097 | #endif | ||
| 24098 | |||
| 24099 | SAFE_FREE (); | 24223 | SAFE_FREE (); |
| 24100 | return count; | 24224 | return count; |
| 24101 | } | 24225 | } |
| @@ -28527,6 +28651,27 @@ xi_check_toolkit (Display *display) | |||
| 28527 | 28651 | ||
| 28528 | #endif | 28652 | #endif |
| 28529 | 28653 | ||
| 28654 | #ifdef HAVE_XFIXES | ||
| 28655 | |||
| 28656 | /* Create and return a special window for receiving events such as | ||
| 28657 | selection notify events. The window is an 1x1 unmapped | ||
| 28658 | override-redirect InputOnly window at -1, -1, which should prevent | ||
| 28659 | it from doing anything. */ | ||
| 28660 | |||
| 28661 | static Window | ||
| 28662 | x_create_special_window (struct x_display_info *dpyinfo) | ||
| 28663 | { | ||
| 28664 | XSetWindowAttributes attrs; | ||
| 28665 | |||
| 28666 | attrs.override_redirect = True; | ||
| 28667 | |||
| 28668 | return XCreateWindow (dpyinfo->display, dpyinfo->root_window, | ||
| 28669 | -1, -1, 1, 1, 0, CopyFromParent, InputOnly, | ||
| 28670 | CopyFromParent, CWOverrideRedirect, &attrs); | ||
| 28671 | } | ||
| 28672 | |||
| 28673 | #endif | ||
| 28674 | |||
| 28530 | /* Open a connection to X display DISPLAY_NAME, and return the | 28675 | /* Open a connection to X display DISPLAY_NAME, and return the |
| 28531 | structure that describes the open display. If obtaining the XCB | 28676 | structure that describes the open display. If obtaining the XCB |
| 28532 | connection or toolkit-specific display fails, return NULL. Signal | 28677 | connection or toolkit-specific display fails, return NULL. Signal |
| @@ -28548,6 +28693,22 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 28548 | GdkDisplay *gdpy; | 28693 | GdkDisplay *gdpy; |
| 28549 | GdkScreen *gscr; | 28694 | GdkScreen *gscr; |
| 28550 | #endif | 28695 | #endif |
| 28696 | #ifdef HAVE_XFIXES | ||
| 28697 | Lisp_Object tem, lisp_name; | ||
| 28698 | int num_fast_selections; | ||
| 28699 | Atom selection_name; | ||
| 28700 | #ifdef USE_XCB | ||
| 28701 | xcb_get_selection_owner_cookie_t *selection_cookies; | ||
| 28702 | xcb_get_selection_owner_reply_t *selection_reply; | ||
| 28703 | xcb_generic_error_t *selection_error; | ||
| 28704 | #endif | ||
| 28705 | #endif | ||
| 28706 | int i; | ||
| 28707 | |||
| 28708 | USE_SAFE_ALLOCA; | ||
| 28709 | |||
| 28710 | /* Avoid warnings when SAFE_ALLOCA is not actually used. */ | ||
| 28711 | ((void) SAFE_ALLOCA (0)); | ||
| 28551 | 28712 | ||
| 28552 | block_input (); | 28713 | block_input (); |
| 28553 | 28714 | ||
| @@ -28700,12 +28861,14 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 28700 | #endif | 28861 | #endif |
| 28701 | 28862 | ||
| 28702 | unblock_input (); | 28863 | unblock_input (); |
| 28864 | |||
| 28865 | SAFE_FREE (); | ||
| 28703 | return 0; | 28866 | return 0; |
| 28704 | } | 28867 | } |
| 28705 | 28868 | ||
| 28706 | #ifdef USE_XCB | 28869 | #ifdef USE_XCB |
| 28707 | xcb_conn = XGetXCBConnection (dpy); | 28870 | xcb_conn = XGetXCBConnection (dpy); |
| 28708 | if (xcb_conn == 0) | 28871 | if (!xcb_conn) |
| 28709 | { | 28872 | { |
| 28710 | #ifdef USE_GTK | 28873 | #ifdef USE_GTK |
| 28711 | xg_display_close (dpy); | 28874 | xg_display_close (dpy); |
| @@ -28718,6 +28881,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 28718 | #endif /* ! USE_GTK */ | 28881 | #endif /* ! USE_GTK */ |
| 28719 | 28882 | ||
| 28720 | unblock_input (); | 28883 | unblock_input (); |
| 28884 | |||
| 28885 | SAFE_FREE (); | ||
| 28721 | return 0; | 28886 | return 0; |
| 28722 | } | 28887 | } |
| 28723 | #endif | 28888 | #endif |
| @@ -29270,8 +29435,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 29270 | XkbUseCoreKbd); | 29435 | XkbUseCoreKbd); |
| 29271 | 29436 | ||
| 29272 | if (dpyinfo->xkb_desc) | 29437 | if (dpyinfo->xkb_desc) |
| 29273 | XkbGetNames (dpyinfo->display, | 29438 | XkbGetNames (dpyinfo->display, XkbAllNamesMask, |
| 29274 | XkbGroupNamesMask | XkbVirtualModNamesMask, | ||
| 29275 | dpyinfo->xkb_desc); | 29439 | dpyinfo->xkb_desc); |
| 29276 | 29440 | ||
| 29277 | XkbSelectEvents (dpyinfo->display, XkbUseCoreKbd, | 29441 | XkbSelectEvents (dpyinfo->display, XkbUseCoreKbd, |
| @@ -29281,9 +29445,10 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 29281 | #endif | 29445 | #endif |
| 29282 | 29446 | ||
| 29283 | #ifdef HAVE_XFIXES | 29447 | #ifdef HAVE_XFIXES |
| 29284 | int xfixes_event_base, xfixes_error_base; | 29448 | int xfixes_error_base; |
| 29285 | dpyinfo->xfixes_supported_p | 29449 | dpyinfo->xfixes_supported_p |
| 29286 | = XFixesQueryExtension (dpyinfo->display, &xfixes_event_base, | 29450 | = XFixesQueryExtension (dpyinfo->display, |
| 29451 | &dpyinfo->xfixes_event_base, | ||
| 29287 | &xfixes_error_base); | 29452 | &xfixes_error_base); |
| 29288 | 29453 | ||
| 29289 | if (dpyinfo->xfixes_supported_p) | 29454 | if (dpyinfo->xfixes_supported_p) |
| @@ -29334,7 +29499,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 29334 | XScreenNumberOfScreen (dpyinfo->screen)); | 29499 | XScreenNumberOfScreen (dpyinfo->screen)); |
| 29335 | 29500 | ||
| 29336 | { | 29501 | { |
| 29337 | int i; | ||
| 29338 | enum { atom_count = ARRAYELTS (x_atom_refs) }; | 29502 | enum { atom_count = ARRAYELTS (x_atom_refs) }; |
| 29339 | /* 1 for _XSETTINGS_SN. */ | 29503 | /* 1 for _XSETTINGS_SN. */ |
| 29340 | enum { total_atom_count = 2 + atom_count }; | 29504 | enum { total_atom_count = 2 + atom_count }; |
| @@ -29502,8 +29666,100 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 29502 | dpyinfo->protected_windows_max = 256; | 29666 | dpyinfo->protected_windows_max = 256; |
| 29503 | #endif | 29667 | #endif |
| 29504 | 29668 | ||
| 29669 | #ifdef HAVE_XFIXES | ||
| 29670 | /* Initialize selection tracking for the selections in | ||
| 29671 | x-fast-selection-list. */ | ||
| 29672 | |||
| 29673 | if (CONSP (Vx_fast_selection_list) | ||
| 29674 | && dpyinfo->xfixes_supported_p | ||
| 29675 | && dpyinfo->xfixes_major >= 1) | ||
| 29676 | { | ||
| 29677 | num_fast_selections = 0; | ||
| 29678 | tem = Vx_fast_selection_list; | ||
| 29679 | |||
| 29680 | FOR_EACH_TAIL_SAFE (tem) | ||
| 29681 | { | ||
| 29682 | if (!SYMBOLP (XCAR (tem))) | ||
| 29683 | continue; | ||
| 29684 | |||
| 29685 | num_fast_selections++; | ||
| 29686 | } | ||
| 29687 | |||
| 29688 | dpyinfo->n_monitored_selections = num_fast_selections; | ||
| 29689 | dpyinfo->selection_tracking_window | ||
| 29690 | = x_create_special_window (dpyinfo); | ||
| 29691 | dpyinfo->monitored_selections | ||
| 29692 | = xmalloc (num_fast_selections | ||
| 29693 | * sizeof *dpyinfo->monitored_selections); | ||
| 29694 | |||
| 29695 | num_fast_selections = 0; | ||
| 29696 | tem = Vx_fast_selection_list; | ||
| 29697 | |||
| 29698 | FOR_EACH_TAIL_SAFE (tem) | ||
| 29699 | { | ||
| 29700 | lisp_name = XCAR (tem); | ||
| 29701 | |||
| 29702 | if (!SYMBOLP (lisp_name)) | ||
| 29703 | continue; | ||
| 29704 | |||
| 29705 | selection_name = symbol_to_x_atom (dpyinfo, lisp_name); | ||
| 29706 | dpyinfo->monitored_selections[num_fast_selections++].name | ||
| 29707 | = selection_name; | ||
| 29708 | dpyinfo->monitored_selections[num_fast_selections - 1].owner | ||
| 29709 | = X_INVALID_WINDOW; | ||
| 29710 | |||
| 29711 | /* Select for selection input. */ | ||
| 29712 | XFixesSelectSelectionInput (dpyinfo->display, | ||
| 29713 | dpyinfo->selection_tracking_window, | ||
| 29714 | selection_name, | ||
| 29715 | (XFixesSetSelectionOwnerNotifyMask | ||
| 29716 | | XFixesSetSelectionOwnerNotifyMask | ||
| 29717 | | XFixesSelectionClientCloseNotifyMask)); | ||
| 29718 | } | ||
| 29719 | |||
| 29720 | #ifdef USE_XCB | ||
| 29721 | selection_cookies = SAFE_ALLOCA (sizeof *selection_cookies | ||
| 29722 | * num_fast_selections); | ||
| 29723 | #endif | ||
| 29724 | |||
| 29725 | /* Now, ask for the current owners of all those selections. */ | ||
| 29726 | for (i = 0; i < num_fast_selections; ++i) | ||
| 29727 | { | ||
| 29728 | #ifdef USE_XCB | ||
| 29729 | selection_cookies[i] | ||
| 29730 | = xcb_get_selection_owner (dpyinfo->xcb_connection, | ||
| 29731 | dpyinfo->monitored_selections[i].name); | ||
| 29732 | #else | ||
| 29733 | dpyinfo->monitored_selections[i].owner | ||
| 29734 | = XGetSelectionOwner (dpyinfo->display, | ||
| 29735 | dpyinfo->monitored_selections[i].name); | ||
| 29736 | #endif | ||
| 29737 | } | ||
| 29738 | |||
| 29739 | #ifdef USE_XCB | ||
| 29740 | for (i = 0; i < num_fast_selections; ++i) | ||
| 29741 | { | ||
| 29742 | selection_reply | ||
| 29743 | = xcb_get_selection_owner_reply (dpyinfo->xcb_connection, | ||
| 29744 | selection_cookies[i], | ||
| 29745 | &selection_error); | ||
| 29746 | |||
| 29747 | if (selection_reply) | ||
| 29748 | { | ||
| 29749 | dpyinfo->monitored_selections[i].owner | ||
| 29750 | = selection_reply->owner; | ||
| 29751 | free (selection_reply); | ||
| 29752 | } | ||
| 29753 | else if (selection_error) | ||
| 29754 | free (selection_error); | ||
| 29755 | } | ||
| 29756 | #endif | ||
| 29757 | } | ||
| 29758 | #endif | ||
| 29759 | |||
| 29505 | unblock_input (); | 29760 | unblock_input (); |
| 29506 | 29761 | ||
| 29762 | SAFE_FREE (); | ||
| 29507 | return dpyinfo; | 29763 | return dpyinfo; |
| 29508 | } | 29764 | } |
| 29509 | 29765 | ||
| @@ -29639,6 +29895,10 @@ x_delete_display (struct x_display_info *dpyinfo) | |||
| 29639 | xfree (dpyinfo->x_id_name); | 29895 | xfree (dpyinfo->x_id_name); |
| 29640 | xfree (dpyinfo->x_dnd_atoms); | 29896 | xfree (dpyinfo->x_dnd_atoms); |
| 29641 | xfree (dpyinfo->color_cells); | 29897 | xfree (dpyinfo->color_cells); |
| 29898 | #ifdef HAVE_XFIXES | ||
| 29899 | if (dpyinfo->monitored_selections) | ||
| 29900 | xfree (dpyinfo->monitored_selections); | ||
| 29901 | #endif | ||
| 29642 | #ifdef USE_TOOLKIT_SCROLL_BARS | 29902 | #ifdef USE_TOOLKIT_SCROLL_BARS |
| 29643 | xfree (dpyinfo->protected_windows); | 29903 | xfree (dpyinfo->protected_windows); |
| 29644 | #endif | 29904 | #endif |
| @@ -30606,4 +30866,17 @@ It should accept a single argument, a string describing the locale of | |||
| 30606 | the input method, and return a coding system that can decode keyboard | 30866 | the input method, and return a coding system that can decode keyboard |
| 30607 | input generated by said input method. */); | 30867 | input generated by said input method. */); |
| 30608 | Vx_input_coding_function = Qnil; | 30868 | Vx_input_coding_function = Qnil; |
| 30869 | |||
| 30870 | DEFVAR_LISP ("x-fast-selection-list", Vx_fast_selection_list, | ||
| 30871 | doc: /* List of selections for which `x-selection-exists-p' should be fast. | ||
| 30872 | |||
| 30873 | List of selection names as atoms that will be monitored by Emacs for | ||
| 30874 | ownership changes when the X server supports the XFIXES extension. | ||
| 30875 | The result of the monitoring is then used by `x-selection-exists-p' to | ||
| 30876 | avoid a server round trip, which is important as it is called while | ||
| 30877 | updating the tool bar. The value of this variable is only read upon | ||
| 30878 | connection setup. */); | ||
| 30879 | /* The default value of this variable is chosen so that updating the | ||
| 30880 | tool bar does not require a call to _XReply. */ | ||
| 30881 | Vx_fast_selection_list = list1 (QCLIPBOARD); | ||
| 30609 | } | 30882 | } |
diff --git a/src/xterm.h b/src/xterm.h index b68a234faa5..0f00dc42f79 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -308,6 +308,22 @@ struct x_failable_request | |||
| 308 | unsigned long end; | 308 | unsigned long end; |
| 309 | }; | 309 | }; |
| 310 | 310 | ||
| 311 | #ifdef HAVE_XFIXES | ||
| 312 | |||
| 313 | struct x_monitored_selection | ||
| 314 | { | ||
| 315 | /* The name of the selection. */ | ||
| 316 | Atom name; | ||
| 317 | |||
| 318 | /* The current owner of the selection. */ | ||
| 319 | Window owner; | ||
| 320 | }; | ||
| 321 | |||
| 322 | /* An invalid window. */ | ||
| 323 | #define X_INVALID_WINDOW 0xffffffff | ||
| 324 | |||
| 325 | #endif | ||
| 326 | |||
| 311 | 327 | ||
| 312 | /* For each X display, we have a structure that records | 328 | /* For each X display, we have a structure that records |
| 313 | information about it. */ | 329 | information about it. */ |
| @@ -778,6 +794,7 @@ struct x_display_info | |||
| 778 | bool xfixes_supported_p; | 794 | bool xfixes_supported_p; |
| 779 | int xfixes_major; | 795 | int xfixes_major; |
| 780 | int xfixes_minor; | 796 | int xfixes_minor; |
| 797 | int xfixes_event_base; | ||
| 781 | #endif | 798 | #endif |
| 782 | 799 | ||
| 783 | #ifdef HAVE_XSYNC | 800 | #ifdef HAVE_XSYNC |
| @@ -828,6 +845,17 @@ struct x_display_info | |||
| 828 | /* Pointer to the next request in `failable_requests'. */ | 845 | /* Pointer to the next request in `failable_requests'. */ |
| 829 | struct x_failable_request *next_failable_request; | 846 | struct x_failable_request *next_failable_request; |
| 830 | 847 | ||
| 848 | #ifdef HAVE_XFIXES | ||
| 849 | /* Array of selections being monitored and their owners. */ | ||
| 850 | struct x_monitored_selection *monitored_selections; | ||
| 851 | |||
| 852 | /* Window used to monitor those selections. */ | ||
| 853 | Window selection_tracking_window; | ||
| 854 | |||
| 855 | /* The number of those selections. */ | ||
| 856 | int n_monitored_selections; | ||
| 857 | #endif | ||
| 858 | |||
| 831 | /* The pending drag-and-drop time for middle-click based | 859 | /* The pending drag-and-drop time for middle-click based |
| 832 | drag-and-drop emulation. */ | 860 | drag-and-drop emulation. */ |
| 833 | Time pending_dnd_time; | 861 | Time pending_dnd_time; |
| @@ -916,11 +944,6 @@ struct x_output | |||
| 916 | Picture picture; | 944 | Picture picture; |
| 917 | #endif | 945 | #endif |
| 918 | 946 | ||
| 919 | /* Flag that indicates whether we've modified the back buffer and | ||
| 920 | need to publish our modifications to the front buffer at a | ||
| 921 | convenient time. */ | ||
| 922 | bool need_buffer_flip; | ||
| 923 | |||
| 924 | /* The X window used for the bitmap icon; | 947 | /* The X window used for the bitmap icon; |
| 925 | or 0 if we don't have a bitmap icon. */ | 948 | or 0 if we don't have a bitmap icon. */ |
| 926 | Window icon_desc; | 949 | Window icon_desc; |
| @@ -1091,6 +1114,18 @@ struct x_output | |||
| 1091 | and inactive states. */ | 1114 | and inactive states. */ |
| 1092 | bool_bf alpha_identical_p : 1; | 1115 | bool_bf alpha_identical_p : 1; |
| 1093 | 1116 | ||
| 1117 | #ifdef HAVE_XDBE | ||
| 1118 | /* Flag that indicates whether we've modified the back buffer and | ||
| 1119 | need to publish our modifications to the front buffer at a | ||
| 1120 | convenient time. */ | ||
| 1121 | bool_bf need_buffer_flip : 1; | ||
| 1122 | |||
| 1123 | /* Flag that indicates whether or not the frame contents are | ||
| 1124 | complete and can be safely flushed while handling async | ||
| 1125 | input. */ | ||
| 1126 | bool_bf complete : 1; | ||
| 1127 | #endif | ||
| 1128 | |||
| 1094 | #ifdef HAVE_X_I18N | 1129 | #ifdef HAVE_X_I18N |
| 1095 | /* Input context (currently, this means Compose key handler setup). */ | 1130 | /* Input context (currently, this means Compose key handler setup). */ |
| 1096 | XIC xic; | 1131 | XIC xic; |
| @@ -1248,6 +1283,10 @@ extern void x_mark_frame_dirty (struct frame *f); | |||
| 1248 | 1283 | ||
| 1249 | /* Return the need-buffer-flip flag for frame F. */ | 1284 | /* Return the need-buffer-flip flag for frame F. */ |
| 1250 | #define FRAME_X_NEED_BUFFER_FLIP(f) ((f)->output_data.x->need_buffer_flip) | 1285 | #define FRAME_X_NEED_BUFFER_FLIP(f) ((f)->output_data.x->need_buffer_flip) |
| 1286 | |||
| 1287 | /* Return whether or not the frame F has been completely drawn. Used | ||
| 1288 | while handling async input. */ | ||
| 1289 | #define FRAME_X_COMPLETE_P(f) ((f)->output_data.x->complete) | ||
| 1251 | #endif | 1290 | #endif |
| 1252 | 1291 | ||
| 1253 | /* Return the outermost X window associated with the frame F. */ | 1292 | /* Return the outermost X window associated with the frame F. */ |
| @@ -1645,6 +1684,10 @@ extern void x_cr_draw_frame (cairo_t *, struct frame *); | |||
| 1645 | extern Lisp_Object x_cr_export_frames (Lisp_Object, cairo_surface_type_t); | 1684 | extern Lisp_Object x_cr_export_frames (Lisp_Object, cairo_surface_type_t); |
| 1646 | #endif | 1685 | #endif |
| 1647 | 1686 | ||
| 1687 | #ifdef HAVE_XFIXES | ||
| 1688 | extern Window x_find_selection_owner (struct x_display_info *, Atom); | ||
| 1689 | #endif | ||
| 1690 | |||
| 1648 | #ifdef HAVE_XRENDER | 1691 | #ifdef HAVE_XRENDER |
| 1649 | extern void x_xrender_color_from_gc_background (struct frame *, GC, | 1692 | extern void x_xrender_color_from_gc_background (struct frame *, GC, |
| 1650 | XRenderColor *, bool); | 1693 | XRenderColor *, bool); |
| @@ -1653,6 +1696,8 @@ extern void x_xr_apply_ext_clip (struct frame *, GC); | |||
| 1653 | extern void x_xr_reset_ext_clip (struct frame *); | 1696 | extern void x_xr_reset_ext_clip (struct frame *); |
| 1654 | #endif | 1697 | #endif |
| 1655 | 1698 | ||
| 1699 | extern void x_translate_coordinates_to_root (struct frame *, int, int, | ||
| 1700 | int *, int *); | ||
| 1656 | extern Bool x_query_pointer (Display *, Window, Window *, Window *, int *, | 1701 | extern Bool x_query_pointer (Display *, Window, Window *, Window *, int *, |
| 1657 | int *, int *, int *, unsigned int *); | 1702 | int *, int *, int *, unsigned int *); |
| 1658 | 1703 | ||