diff options
author | Po Lu <luangruo@yahoo.com> | 2021-12-18 20:58:44 +0800 |
---|---|---|
committer | Po Lu <luangruo@yahoo.com> | 2021-12-18 20:58:44 +0800 |
commit | 4ff3a70153ac1716bf0767fbbf92b04fdb3b1c80 (patch) | |
tree | e89cdddc6e7a923bb99998f75ed974883f002272 | |
parent | 7ab1b71c0dd878daa6806ce3a01d429dc5af646c (diff) | |
parent | 4544651b3f62ce4a104a058e8c6aee42c23b76bc (diff) | |
download | emacs-4ff3a70153ac1716bf0767fbbf92b04fdb3b1c80.tar.gz emacs-4ff3a70153ac1716bf0767fbbf92b04fdb3b1c80.tar.bz2 emacs-4ff3a70153ac1716bf0767fbbf92b04fdb3b1c80.zip |
Merge remote-tracking branch 'origin/master' into feature/pgtk
-rw-r--r-- | doc/lispref/display.texi | 8 | ||||
-rw-r--r-- | etc/NEWS | 6 | ||||
-rw-r--r-- | lisp/emacs-lisp/multisession.el | 45 | ||||
-rw-r--r-- | src/haikufns.c | 3 | ||||
-rw-r--r-- | src/w32fns.c | 3 | ||||
-rw-r--r-- | src/xdisp.c | 49 | ||||
-rw-r--r-- | src/xfns.c | 3 | ||||
-rw-r--r-- | src/xterm.c | 88 |
8 files changed, 131 insertions, 74 deletions
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index dd996fbe4a8..98a15404f91 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2086,7 +2086,7 @@ displayed in a given window. This function is used by (@pxref{Resizing Windows}) to make a window exactly as large as the text it contains. -@defun window-text-pixel-size &optional window from to x-limit y-limit mode-lines +@defun window-text-pixel-size &optional window from to x-limit y-limit mode-lines ignore-line-at-end This function returns the size of the text of @var{window}'s buffer in pixels. @var{window} must be a live window and defaults to the selected one. The return value is a cons of the maximum pixel-width @@ -2136,6 +2136,12 @@ line, if present, in the return value. If it is @code{t}, include the height of all of these lines, if present, in the return value. @end defun +The optional argument @var{ignore-line-at-end} controls whether or +not to count the height of text in @var{to}'s screen line as part of +the returned pixel-height. This is useful if your Lisp program is +only interested in the dimensions of text up to and excluding the +visual beginning of @var{to}'s screen line. + @code{window-text-pixel-size} treats the text displayed in a window as a whole and does not care about the size of individual lines. The following function does. @@ -984,6 +984,12 @@ when they have changed. This can be used to check whether a specific font has a glyph for a character. ++++ +** 'window-text-pixel-size' now accepts a new argument 'ignore-line-at-end'. +This controls whether or not the last screen line of the text being +measured will be counted for the purpose of calculating the text +dimensions. + ** XDG support *** New function 'xdg-state-home' returns 'XDG_STATE_HOME' environment variable. diff --git a/lisp/emacs-lisp/multisession.el b/lisp/emacs-lisp/multisession.el index bce888acc68..6ef0da10f77 100644 --- a/lisp/emacs-lisp/multisession.el +++ b/lisp/emacs-lisp/multisession.el @@ -250,23 +250,30 @@ DOC should be a doc string, and ARGS are keywords as applicable to (defun multisession--encode-file-name (name) (url-hexify-string name)) -(defun multisession--update-file-value (file object) - (condition-case nil - (with-temp-buffer - (let* ((time (file-attribute-modification-time - (file-attributes file))) - (coding-system-for-read 'utf-8)) - (insert-file-contents file) - (let ((stored (read (current-buffer)))) - (setf (multisession--cached-value object) stored - (multisession--cached-sequence object) time) - stored))) - ;; If the file is contended (could happen with file locking in - ;; Windws) or unreadable, just return the current value. - (error - (if (eq (multisession--cached-value object) multisession--unbound) - (multisession--initial-value object) - (multisession--cached-value object))))) +(defun multisession--read-file-value (file object) + (catch 'done + (let ((i 0) + last-error) + (while (< i 10) + (condition-case err + (throw 'done + (with-temp-buffer + (let* ((time (file-attribute-modification-time + (file-attributes file))) + (coding-system-for-read 'utf-8)) + (insert-file-contents file) + (let ((stored (read (current-buffer)))) + (setf (multisession--cached-value object) stored + (multisession--cached-sequence object) time) + stored)))) + ;; Windows uses OS-level file locking that may preclude + ;; reading the file in some circumstances. So when that + ;; happens, wait a bit and try again. + (file-error + (setq i (1+ i) + last-error err) + (sleep-for (+ 0.1 (/ (float (random 10)) 10)))))) + (signal (car last-error) (cdr last-error))))) (defun multisession--object-file-name (object) (expand-file-name @@ -283,7 +290,7 @@ DOC should be a doc string, and ARGS are keywords as applicable to ;; We have no value yet; see whether it's stored. ((eq (multisession--cached-value object) multisession--unbound) (if (file-exists-p file) - (multisession--update-file-value file object) + (multisession--read-file-value file object) ;; Nope; return the initial value. (multisession--initial-value object))) ;; We have a value, but we want to update in case some other @@ -293,7 +300,7 @@ DOC should be a doc string, and ARGS are keywords as applicable to (time-less-p (multisession--cached-sequence object) (file-attribute-modification-time (file-attributes file)))) - (multisession--update-file-value file object) + (multisession--read-file-value file object) ;; Nothing, return the cached value. (multisession--cached-value object))) ;; Just return the cached value. diff --git a/src/haikufns.c b/src/haikufns.c index 868fc71f979..737b0338994 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -1970,7 +1970,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE); /* Calculate size of tooltip window. */ size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil, - make_fixnum (w->pixel_height), Qnil); + make_fixnum (w->pixel_height), Qnil, + Qnil); /* Add the frame's internal border to calculated size. */ width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); diff --git a/src/w32fns.c b/src/w32fns.c index 65463b52616..02a6d78b51c 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -7525,7 +7525,8 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE); /* Calculate size of tooltip window. */ size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil, - make_fixnum (w->pixel_height), Qnil); + make_fixnum (w->pixel_height), Qnil, + Qnil); /* Add the frame's internal border to calculated size. */ width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); diff --git a/src/xdisp.c b/src/xdisp.c index 2d45a8d6b9f..3a1bc1613f7 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -5361,9 +5361,6 @@ handle_display_prop (struct it *it) if (!it->string_from_display_prop_p) it->area = TEXT_AREA; - if (!STRINGP (it->string)) - object = it->w->contents; - propval = get_char_property_and_overlay (make_fixnum (position->charpos), Qdisplay, object, &overlay); @@ -5377,6 +5374,9 @@ handle_display_prop (struct it *it) /* Now OVERLAY is the overlay that gave us this property, or nil if it was a text property. */ + if (!STRINGP (it->string)) + object = it->w->contents; + display_replaced = handle_display_spec (it, propval, object, overlay, position, bufpos, FRAME_WINDOW_P (it->f)); @@ -10832,8 +10832,9 @@ in_display_vector_p (struct it *it) set WINDOW's buffer to the buffer specified by its BUFFER_OR_NAME argument. */ static Lisp_Object -window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, - Lisp_Object y_limit, Lisp_Object mode_lines) +window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, + Lisp_Object x_limit, Lisp_Object y_limit, + Lisp_Object mode_lines, Lisp_Object ignore_line_at_end) { struct window *w = decode_live_window (window); struct it it; @@ -10841,6 +10842,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Li struct text_pos startp; void *itdata = NULL; int c, max_x = 0, max_y = 0, x = 0, y = 0; + int doff = 0; if (NILP (from)) { @@ -10969,8 +10971,16 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Li if (IT_CHARPOS (it) == end) { x += it.pixel_width; - it.max_ascent = max (it.max_ascent, it.ascent); - it.max_descent = max (it.max_descent, it.descent); + + /* DTRT if ignore_line_at_end is t. */ + if (!NILP (ignore_line_at_end)) + doff = (max (it.max_ascent, it.ascent) + + max (it.max_descent, it.descent)); + else + { + it.max_ascent = max (it.max_ascent, it.ascent); + it.max_descent = max (it.max_descent, it.descent); + } } } else @@ -10991,8 +11001,14 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Li /* Subtract height of header-line and tab-line which was counted automatically by start_display. */ - y = it.current_y + it.max_ascent + it.max_descent - - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w); + if (!NILP (ignore_line_at_end)) + y = (it.current_y + doff + - WINDOW_TAB_LINE_HEIGHT (w) + - WINDOW_HEADER_LINE_HEIGHT (w)); + else + y = (it.current_y + it.max_ascent + it.max_descent + doff + - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w)); + /* Don't return more than Y-LIMIT. */ if (y > max_y) y = max_y; @@ -11039,7 +11055,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Li return Fcons (make_fixnum (x - start_x), make_fixnum (y)); } -DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0, +DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0, doc: /* Return the size of the text of WINDOW's buffer in pixels. WINDOW must be a live window and defaults to the selected one. The return value is a cons of the maximum pixel-width of any text line @@ -11086,9 +11102,12 @@ Optional argument MODE-LINES nil or omitted means do not include the height of the mode-, tab- or header-line of WINDOW in the return value. If it is the symbol `mode-line', 'tab-line' or `header-line', include only the height of that line, if present, in the return value. If t, -include the height of any of these, if present, in the return value. */) +include the height of any of these, if present, in the return value. + +IGNORE-LINE-AT-END, if non-nil, means to not add the height of the +screen line that includes TO to the returned height of the text. */) (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, - Lisp_Object y_limit, Lisp_Object mode_lines) + Lisp_Object y_limit, Lisp_Object mode_lines, Lisp_Object ignore_line_at_end) { struct window *w = decode_live_window (window); struct buffer *b = XBUFFER (w->contents); @@ -11101,7 +11120,8 @@ include the height of any of these, if present, in the return value. */) set_buffer_internal_1 (b); } - value = window_text_pixel_size (window, from, to, x_limit, y_limit, mode_lines); + value = window_text_pixel_size (window, from, to, x_limit, y_limit, mode_lines, + ignore_line_at_end); if (old_b) set_buffer_internal_1 (old_b); @@ -11151,7 +11171,8 @@ WINDOW. */) set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE); } - value = window_text_pixel_size (window, Qnil, Qnil, x_limit, y_limit, Qnil); + value = window_text_pixel_size (window, Qnil, Qnil, x_limit, y_limit, Qnil, + Qnil); unbind_to (count, Qnil); diff --git a/src/xfns.c b/src/xfns.c index dc25d7bfca2..30ed358fb28 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -7169,7 +7169,8 @@ Text larger than the specified size is clipped. */) try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE); /* Calculate size of tooltip window. */ size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil, - make_fixnum (w->pixel_height), Qnil); + make_fixnum (w->pixel_height), Qnil, + Qnil); /* Add the frame's internal border to calculated size. */ width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); diff --git a/src/xterm.c b/src/xterm.c index 03f509ba868..7456b3b6beb 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -579,7 +579,7 @@ xi_link_touch_point (struct xi_device_t *device, device->touchpoints = touchpoint; } -static void +static bool xi_unlink_touch_point (int detail, struct xi_device_t *device) { @@ -596,9 +596,11 @@ xi_unlink_touch_point (int detail, last->next = tem->next; xfree (tem); - return; + return true; } } + + return false; } static struct xi_touch_point_t * @@ -10887,37 +10889,45 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (f && device->direct_p) { - xi_link_touch_point (device, xev->detail, xev->event_x, - xev->event_y); + x_catch_errors (dpyinfo->display); + XIAllowTouchEvents (dpyinfo->display, xev->deviceid, + xev->detail, xev->event, XIAcceptTouch); + if (!x_had_errors_p (dpyinfo->display)) + { + xi_link_touch_point (device, xev->detail, xev->event_x, + xev->event_y); #ifdef HAVE_GTK3 - if (FRAME_X_OUTPUT (f)->menubar_widget - && xg_event_is_for_menubar (f, event)) - { - bool was_waiting_for_input = waiting_for_input; - /* This hack was adopted from the NS port. Whether - or not it is actually safe is a different story - altogether. */ - if (waiting_for_input) - waiting_for_input = 0; - set_frame_menubar (f, true); - waiting_for_input = was_waiting_for_input; - } + if (FRAME_X_OUTPUT (f)->menubar_widget + && xg_event_is_for_menubar (f, event)) + { + bool was_waiting_for_input = waiting_for_input; + /* This hack was adopted from the NS port. Whether + or not it is actually safe is a different story + altogether. */ + if (waiting_for_input) + waiting_for_input = 0; + set_frame_menubar (f, true); + waiting_for_input = was_waiting_for_input; + } #endif - inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT; - inev.ie.timestamp = xev->time; - XSETFRAME (inev.ie.frame_or_window, f); - XSETINT (inev.ie.x, lrint (xev->event_x)); - XSETINT (inev.ie.y, lrint (xev->event_y)); - XSETINT (inev.ie.arg, xev->detail); - - XIAllowTouchEvents (dpyinfo->display, xev->deviceid, - xev->detail, xev->event, XIAcceptTouch); + inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT; + inev.ie.timestamp = xev->time; + XSETFRAME (inev.ie.frame_or_window, f); + XSETINT (inev.ie.x, lrint (xev->event_x)); + XSETINT (inev.ie.y, lrint (xev->event_y)); + XSETINT (inev.ie.arg, xev->detail); + } + x_uncatch_errors_after_check (); } else - XIAllowTouchEvents (dpyinfo->display, xev->deviceid, - xev->detail, xev->event, XIRejectTouch); + { + x_catch_errors (dpyinfo->display); + XIAllowTouchEvents (dpyinfo->display, xev->deviceid, + xev->detail, xev->event, XIRejectTouch); + x_uncatch_errors (); + } goto XI_OTHER; } @@ -10965,24 +10975,28 @@ handle_one_xevent (struct x_display_info *dpyinfo, case XI_TouchEnd: { struct xi_device_t *device; + bool unlinked_p; device = xi_device_from_id (dpyinfo, xev->deviceid); if (!device) goto XI_OTHER; - xi_unlink_touch_point (xev->detail, device); - - f = x_any_window_to_frame (dpyinfo, xev->event); + unlinked_p = xi_unlink_touch_point (xev->detail, device); - if (f && device->direct_p) + if (unlinked_p) { - inev.ie.kind = TOUCHSCREEN_END_EVENT; - inev.ie.timestamp = xev->time; - XSETFRAME (inev.ie.frame_or_window, f); - XSETINT (inev.ie.x, lrint (xev->event_x)); - XSETINT (inev.ie.y, lrint (xev->event_y)); - XSETINT (inev.ie.arg, xev->detail); + f = x_any_window_to_frame (dpyinfo, xev->event); + + if (f && device->direct_p) + { + inev.ie.kind = TOUCHSCREEN_END_EVENT; + inev.ie.timestamp = xev->time; + XSETFRAME (inev.ie.frame_or_window, f); + XSETINT (inev.ie.x, lrint (xev->event_x)); + XSETINT (inev.ie.y, lrint (xev->event_y)); + XSETINT (inev.ie.arg, xev->detail); + } } goto XI_OTHER; |