diff options
| author | Philip Kaludercic | 2022-10-20 20:00:32 +0200 |
|---|---|---|
| committer | Philip Kaludercic | 2022-10-20 20:00:32 +0200 |
| commit | 37bfb623e4b253443e8280c3de4ff91f8db5f51b (patch) | |
| tree | 39e48d687ace2d9b88b10bf82412301c4e723743 /src | |
| parent | e08e9bc40f2c309bf119659a6496759493bd35e1 (diff) | |
| parent | 937ae0cf55d31c332fba3d96061e2ac3653e5437 (diff) | |
| download | emacs-37bfb623e4b253443e8280c3de4ff91f8db5f51b.tar.gz emacs-37bfb623e4b253443e8280c3de4ff91f8db5f51b.zip | |
Merge remote-tracking branch 'origin/master' into feature/package+vc
Diffstat (limited to 'src')
| -rw-r--r-- | src/window.c | 17 | ||||
| -rw-r--r-- | src/xterm.c | 146 |
2 files changed, 153 insertions, 10 deletions
diff --git a/src/window.c b/src/window.c index 4e8b352e164..f116b9a9d72 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -5441,12 +5441,13 @@ window_wants_mode_line (struct window *w) | |||
| 5441 | * Return 1 if window W wants a header line and is high enough to | 5441 | * Return 1 if window W wants a header line and is high enough to |
| 5442 | * accommodate it, 0 otherwise. | 5442 | * accommodate it, 0 otherwise. |
| 5443 | * | 5443 | * |
| 5444 | * W wants a header line if it's a leaf window and neither a minibuffer | 5444 | * W wants a header line if it's a leaf window and neither a |
| 5445 | * nor a pseudo window. Moreover, its 'window-mode-line-format' | 5445 | * minibuffer nor a pseudo window. Moreover, its |
| 5446 | * parameter must not be 'none' and either that parameter or W's | 5446 | * 'window-header-line-format' parameter must not be 'none' and either |
| 5447 | * buffer's 'mode-line-format' value must be non-nil. Finally, W must | 5447 | * that parameter or W's buffer's 'header-line-format' value must be |
| 5448 | * be higher than its frame's canonical character height and be able to | 5448 | * non-nil. Finally, W must be higher than its frame's canonical |
| 5449 | * accommodate a mode line too if necessary (the mode line prevails). | 5449 | * character height and be able to accommodate a mode line too if |
| 5450 | * necessary (the mode line prevails). | ||
| 5450 | */ | 5451 | */ |
| 5451 | bool | 5452 | bool |
| 5452 | window_wants_header_line (struct window *w) | 5453 | window_wants_header_line (struct window *w) |
| @@ -5474,9 +5475,9 @@ window_wants_header_line (struct window *w) | |||
| 5474 | * accommodate it, 0 otherwise. | 5475 | * accommodate it, 0 otherwise. |
| 5475 | * | 5476 | * |
| 5476 | * W wants a tab line if it's a leaf window and neither a minibuffer | 5477 | * W wants a tab line if it's a leaf window and neither a minibuffer |
| 5477 | * nor a pseudo window. Moreover, its 'window-mode-line-format' | 5478 | * nor a pseudo window. Moreover, its 'window-tab-line-format' |
| 5478 | * parameter must not be 'none' and either that parameter or W's | 5479 | * parameter must not be 'none' and either that parameter or W's |
| 5479 | * buffer's 'mode-line-format' value must be non-nil. Finally, W must | 5480 | * buffer's 'tab-line-format' value must be non-nil. Finally, W must |
| 5480 | * be higher than its frame's canonical character height and be able | 5481 | * be higher than its frame's canonical character height and be able |
| 5481 | * to accommodate a mode line and a header line too if necessary (the | 5482 | * to accommodate a mode line and a header line too if necessary (the |
| 5482 | * mode line and a header line prevail). | 5483 | * mode line and a header line prevail). |
diff --git a/src/xterm.c b/src/xterm.c index 7c3ab87e87b..8b3d6f77a6c 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -17857,7 +17857,7 @@ x_handle_wm_state (struct frame *f, struct input_event *ie) | |||
| 17857 | 17857 | ||
| 17858 | static bool | 17858 | static bool |
| 17859 | x_handle_selection_monitor_event (struct x_display_info *dpyinfo, | 17859 | x_handle_selection_monitor_event (struct x_display_info *dpyinfo, |
| 17860 | XEvent *event) | 17860 | const XEvent *event) |
| 17861 | { | 17861 | { |
| 17862 | XFixesSelectionNotifyEvent *notify; | 17862 | XFixesSelectionNotifyEvent *notify; |
| 17863 | int i; | 17863 | int i; |
| @@ -17940,7 +17940,11 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17940 | GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display); | 17940 | GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display); |
| 17941 | #endif | 17941 | #endif |
| 17942 | int dx, dy; | 17942 | int dx, dy; |
| 17943 | |||
| 17944 | /* Avoid warnings when SAFE_ALLOCA is not actually used. */ | ||
| 17945 | #if defined HAVE_XINPUT2 || defined HAVE_XKB || defined HAVE_X_I18N | ||
| 17943 | USE_SAFE_ALLOCA; | 17946 | USE_SAFE_ALLOCA; |
| 17947 | #endif | ||
| 17944 | 17948 | ||
| 17945 | /* This function is not reentrant, so input should be blocked before | 17949 | /* This function is not reentrant, so input should be blocked before |
| 17946 | it is called. */ | 17950 | it is called. */ |
| @@ -24220,7 +24224,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 24220 | count++; | 24224 | count++; |
| 24221 | } | 24225 | } |
| 24222 | 24226 | ||
| 24227 | #if defined HAVE_XINPUT2 || defined HAVE_XKB || defined HAVE_X_I18N | ||
| 24223 | SAFE_FREE (); | 24228 | SAFE_FREE (); |
| 24229 | #endif | ||
| 24230 | |||
| 24224 | return count; | 24231 | return count; |
| 24225 | } | 24232 | } |
| 24226 | 24233 | ||
| @@ -25691,6 +25698,14 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) | |||
| 25691 | 25698 | ||
| 25692 | #ifdef HAVE_X11R6 | 25699 | #ifdef HAVE_X11R6 |
| 25693 | 25700 | ||
| 25701 | /* HAVE_X11R6 means Xlib conforms to the R6 specification or later. | ||
| 25702 | HAVE_X11R6_XIM, OTOH, means that Emacs should try to use R6-style | ||
| 25703 | callback driven input method initialization. They are separate | ||
| 25704 | because Sun apparently ships buggy Xlib with some versions of | ||
| 25705 | Solaris... */ | ||
| 25706 | |||
| 25707 | #ifdef HAVE_X11R6_XIM | ||
| 25708 | |||
| 25694 | /* If preedit text is set on F, cancel preedit, free the text, and | 25709 | /* If preedit text is set on F, cancel preedit, free the text, and |
| 25695 | generate the appropriate events to cancel the preedit display. | 25710 | generate the appropriate events to cancel the preedit display. |
| 25696 | 25711 | ||
| @@ -25756,6 +25771,8 @@ xim_destroy_callback (XIM xim, XPointer client_data, XPointer call_data) | |||
| 25756 | unblock_input (); | 25771 | unblock_input (); |
| 25757 | } | 25772 | } |
| 25758 | 25773 | ||
| 25774 | #endif | ||
| 25775 | |||
| 25759 | #endif /* HAVE_X11R6 */ | 25776 | #endif /* HAVE_X11R6 */ |
| 25760 | 25777 | ||
| 25761 | /* Open the connection to the XIM server on display DPYINFO. | 25778 | /* Open the connection to the XIM server on display DPYINFO. |
| @@ -27117,6 +27134,64 @@ xembed_request_focus (struct frame *f) | |||
| 27117 | XEMBED_REQUEST_FOCUS, 0, 0, 0); | 27134 | XEMBED_REQUEST_FOCUS, 0, 0, 0); |
| 27118 | } | 27135 | } |
| 27119 | 27136 | ||
| 27137 | static Bool | ||
| 27138 | server_timestamp_predicate (Display *display, XEvent *xevent, | ||
| 27139 | XPointer arg) | ||
| 27140 | { | ||
| 27141 | XID *args = (XID *) arg; | ||
| 27142 | |||
| 27143 | if (xevent->type == PropertyNotify | ||
| 27144 | && xevent->xproperty.window == args[0] | ||
| 27145 | && xevent->xproperty.atom == args[1]) | ||
| 27146 | return True; | ||
| 27147 | |||
| 27148 | return False; | ||
| 27149 | } | ||
| 27150 | |||
| 27151 | /* Get the server time. The X server is guaranteed to deliver the | ||
| 27152 | PropertyNotify event, so there is no reason to use x_if_event. */ | ||
| 27153 | |||
| 27154 | static Time | ||
| 27155 | x_get_server_time (struct frame *f) | ||
| 27156 | { | ||
| 27157 | Atom property_atom; | ||
| 27158 | XEvent property_dummy; | ||
| 27159 | struct x_display_info *dpyinfo; | ||
| 27160 | XID client_data[2]; | ||
| 27161 | #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME | ||
| 27162 | uint_fast64_t current_monotonic_time; | ||
| 27163 | #endif | ||
| 27164 | |||
| 27165 | /* If the server time is the same as the monotonic time, avoid a | ||
| 27166 | roundtrip by using that instead. */ | ||
| 27167 | |||
| 27168 | #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME | ||
| 27169 | if (FRAME_DISPLAY_INFO (f)->server_time_monotonic_p) | ||
| 27170 | { | ||
| 27171 | current_monotonic_time = x_sync_current_monotonic_time (); | ||
| 27172 | |||
| 27173 | if (current_monotonic_time) | ||
| 27174 | /* Truncate the time to CARD32. */ | ||
| 27175 | return (current_monotonic_time / 1000) & X_ULONG_MAX; | ||
| 27176 | } | ||
| 27177 | #endif | ||
| 27178 | |||
| 27179 | dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 27180 | property_atom = dpyinfo->Xatom_EMACS_SERVER_TIME_PROP; | ||
| 27181 | client_data[0] = FRAME_OUTER_WINDOW (f); | ||
| 27182 | client_data[1] = property_atom; | ||
| 27183 | |||
| 27184 | XChangeProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f), | ||
| 27185 | property_atom, XA_ATOM, 32, | ||
| 27186 | PropModeReplace, | ||
| 27187 | (unsigned char *) &property_atom, 1); | ||
| 27188 | |||
| 27189 | XIfEvent (dpyinfo->display, &property_dummy, | ||
| 27190 | server_timestamp_predicate, (XPointer) client_data); | ||
| 27191 | |||
| 27192 | return property_dummy.xproperty.time; | ||
| 27193 | } | ||
| 27194 | |||
| 27120 | /* Activate frame with Extended Window Manager Hints */ | 27195 | /* Activate frame with Extended Window Manager Hints */ |
| 27121 | 27196 | ||
| 27122 | static void | 27197 | static void |
| @@ -27124,6 +27199,7 @@ x_ewmh_activate_frame (struct frame *f) | |||
| 27124 | { | 27199 | { |
| 27125 | XEvent msg; | 27200 | XEvent msg; |
| 27126 | struct x_display_info *dpyinfo; | 27201 | struct x_display_info *dpyinfo; |
| 27202 | Time time; | ||
| 27127 | 27203 | ||
| 27128 | dpyinfo = FRAME_DISPLAY_INFO (f); | 27204 | dpyinfo = FRAME_DISPLAY_INFO (f); |
| 27129 | 27205 | ||
| @@ -27144,6 +27220,43 @@ x_ewmh_activate_frame (struct frame *f) | |||
| 27144 | msg.xclient.data.l[3] = 0; | 27220 | msg.xclient.data.l[3] = 0; |
| 27145 | msg.xclient.data.l[4] = 0; | 27221 | msg.xclient.data.l[4] = 0; |
| 27146 | 27222 | ||
| 27223 | /* No frame is currently focused on that display, so apply any | ||
| 27224 | bypass for focus stealing prevention that the user has | ||
| 27225 | specified. */ | ||
| 27226 | if (!dpyinfo->x_focus_frame) | ||
| 27227 | { | ||
| 27228 | if (EQ (Vx_allow_focus_stealing, Qimitate_pager)) | ||
| 27229 | msg.xclient.data.l[0] = 2; | ||
| 27230 | else if (EQ (Vx_allow_focus_stealing, Qnewer_time)) | ||
| 27231 | { | ||
| 27232 | block_input (); | ||
| 27233 | time = x_get_server_time (f); | ||
| 27234 | #ifdef USE_GTK | ||
| 27235 | x_set_gtk_user_time (f, time); | ||
| 27236 | #endif | ||
| 27237 | /* Temporarily override dpyinfo->x_focus_frame so the | ||
| 27238 | user time property is set on the right window. */ | ||
| 27239 | dpyinfo->x_focus_frame = f; | ||
| 27240 | x_display_set_last_user_time (dpyinfo, time, true, true); | ||
| 27241 | dpyinfo->x_focus_frame = NULL; | ||
| 27242 | unblock_input (); | ||
| 27243 | |||
| 27244 | msg.xclient.data.l[1] = time; | ||
| 27245 | } | ||
| 27246 | else if (EQ (Vx_allow_focus_stealing, Qraise_and_focus)) | ||
| 27247 | { | ||
| 27248 | time = x_get_server_time (f); | ||
| 27249 | |||
| 27250 | x_ignore_errors_for_next_request (dpyinfo); | ||
| 27251 | XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 27252 | RevertToParent, time); | ||
| 27253 | XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); | ||
| 27254 | x_stop_ignoring_errors (dpyinfo); | ||
| 27255 | |||
| 27256 | return; | ||
| 27257 | } | ||
| 27258 | } | ||
| 27259 | |||
| 27147 | XSendEvent (dpyinfo->display, dpyinfo->root_window, | 27260 | XSendEvent (dpyinfo->display, dpyinfo->root_window, |
| 27148 | False, (SubstructureRedirectMask | 27261 | False, (SubstructureRedirectMask |
| 27149 | | SubstructureNotifyMask), &msg); | 27262 | | SubstructureNotifyMask), &msg); |
| @@ -30281,7 +30394,7 @@ mark_xterm (void) | |||
| 30281 | { | 30394 | { |
| 30282 | Lisp_Object val; | 30395 | Lisp_Object val; |
| 30283 | #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \ | 30396 | #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \ |
| 30284 | || defined HAVE_XRANDR || defined USE_GTK | 30397 | || defined HAVE_XRANDR || defined USE_GTK || defined HAVE_X_I18N |
| 30285 | struct x_display_info *dpyinfo; | 30398 | struct x_display_info *dpyinfo; |
| 30286 | #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS | 30399 | #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS |
| 30287 | int i; | 30400 | int i; |
| @@ -30505,8 +30618,14 @@ x_get_keyboard_modifiers (struct x_display_info *dpyinfo) | |||
| 30505 | /* This sometimes happens when the function is called during display | 30618 | /* This sometimes happens when the function is called during display |
| 30506 | initialization, which can happen while obtaining vendor specific | 30619 | initialization, which can happen while obtaining vendor specific |
| 30507 | keysyms. */ | 30620 | keysyms. */ |
| 30621 | |||
| 30622 | #ifdef HAVE_XKB | ||
| 30508 | if (!dpyinfo->xkb_desc && !dpyinfo->modmap) | 30623 | if (!dpyinfo->xkb_desc && !dpyinfo->modmap) |
| 30509 | x_find_modifier_meanings (dpyinfo); | 30624 | x_find_modifier_meanings (dpyinfo); |
| 30625 | #else | ||
| 30626 | if (!dpyinfo->modmap) | ||
| 30627 | x_find_modifier_meanings (dpyinfo); | ||
| 30628 | #endif | ||
| 30510 | 30629 | ||
| 30511 | return list5 (make_uint (dpyinfo->hyper_mod_mask), | 30630 | return list5 (make_uint (dpyinfo->hyper_mod_mask), |
| 30512 | make_uint (dpyinfo->super_mod_mask), | 30631 | make_uint (dpyinfo->super_mod_mask), |
| @@ -30626,6 +30745,9 @@ With MS Windows, Haiku windowing or Nextstep, the value is t. */); | |||
| 30626 | Fput (Qsuper, Qmodifier_value, make_fixnum (super_modifier)); | 30745 | Fput (Qsuper, Qmodifier_value, make_fixnum (super_modifier)); |
| 30627 | DEFSYM (QXdndSelection, "XdndSelection"); | 30746 | DEFSYM (QXdndSelection, "XdndSelection"); |
| 30628 | DEFSYM (Qx_selection_alias_alist, "x-selection-alias-alist"); | 30747 | DEFSYM (Qx_selection_alias_alist, "x-selection-alias-alist"); |
| 30748 | DEFSYM (Qimitate_pager, "imitate-pager"); | ||
| 30749 | DEFSYM (Qnewer_time, "newer-time"); | ||
| 30750 | DEFSYM (Qraise_and_focus, "raise-and-focus"); | ||
| 30629 | 30751 | ||
| 30630 | DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym, | 30752 | DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym, |
| 30631 | doc: /* Which keys Emacs uses for the ctrl modifier. | 30753 | doc: /* Which keys Emacs uses for the ctrl modifier. |
| @@ -30879,4 +31001,24 @@ connection setup. */); | |||
| 30879 | /* The default value of this variable is chosen so that updating the | 31001 | /* The default value of this variable is chosen so that updating the |
| 30880 | tool bar does not require a call to _XReply. */ | 31002 | tool bar does not require a call to _XReply. */ |
| 30881 | Vx_fast_selection_list = list1 (QCLIPBOARD); | 31003 | Vx_fast_selection_list = list1 (QCLIPBOARD); |
| 31004 | |||
| 31005 | DEFVAR_LISP ("x-allow-focus-stealing", Vx_allow_focus_stealing, | ||
| 31006 | doc: /* How to bypass window manager focus stealing prevention. | ||
| 31007 | |||
| 31008 | Some window managers prevent `x-focus-frame' from activating the given | ||
| 31009 | frame when Emacs is in the background, which is especially prone to | ||
| 31010 | cause problems when the Emacs server wants to activate itself. This | ||
| 31011 | variable specifies the strategy used to activate frames when that is | ||
| 31012 | the case, and has several valid values (any other value means to not | ||
| 31013 | bypass window manager focus stealing prevention): | ||
| 31014 | |||
| 31015 | - The symbol `imitate-pager', which means to pretend that Emacs is a | ||
| 31016 | pager. | ||
| 31017 | |||
| 31018 | - The symbol `newer-time', which means to fetch the current time | ||
| 31019 | from the X server and use it to activate the frame. | ||
| 31020 | |||
| 31021 | - The symbol `raise-and-focus', which means to raise the window and | ||
| 31022 | focus it manually. */); | ||
| 31023 | Vx_allow_focus_stealing = Qnewer_time; | ||
| 30882 | } | 31024 | } |