emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/pgtk 4ff3a70 1/2: Merge remote-tracking branch 'origin/master' i


From: Po Lu
Subject: feature/pgtk 4ff3a70 1/2: Merge remote-tracking branch 'origin/master' into feature/pgtk
Date: Sat, 18 Dec 2021 07:59:46 -0500 (EST)

branch: feature/pgtk
commit 4ff3a70153ac1716bf0767fbbf92b04fdb3b1c80
Merge: 7ab1b71 4544651
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Merge remote-tracking branch 'origin/master' into feature/pgtk
---
 doc/lispref/display.texi        |  8 +++-
 etc/NEWS                        |  6 +++
 lisp/emacs-lisp/multisession.el | 45 ++++++++++++---------
 src/haikufns.c                  |  3 +-
 src/w32fns.c                    |  3 +-
 src/xdisp.c                     | 49 ++++++++++++++++-------
 src/xfns.c                      |  3 +-
 src/xterm.c                     | 88 ++++++++++++++++++++++++-----------------
 8 files changed, 131 insertions(+), 74 deletions(-)

diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index dd996fb..98a1540 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.
diff --git a/etc/NEWS b/etc/NEWS
index bd1ed4d..e3665b9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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 bce888a..6ef0da1 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 868fc71..737b033 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 65463b5..02a6d78 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 2d45a8d..3a1bc16 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 dc25d7b..30ed358 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 03f509b..7456b3b 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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]