commit 9c70045f674b31db7a640d8a59939ce8df7ed37b (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Thu Apr 28 13:07:33 2022 +0800 Fix GTK build * src/xrdb.c (x_load_resources): Fix definitions of `helv'. diff --git a/src/xrdb.c b/src/xrdb.c index 67d9f57f7d..aa79d719c8 100644 --- a/src/xrdb.c +++ b/src/xrdb.c @@ -383,11 +383,6 @@ x_load_resources (Display *display, const char *xrm_string, XrmDatabase db; char line[256]; -#if !(defined USE_CAIRO || defined HAVE_XFT) \ - && !defined USE_MOTIF && !defined USE_LUCID - const char *helv = "-*-helvetica-medium-r-*--*-120-*-*-*-*-iso8859-1"; -#endif - x_rm_string = XrmStringToQuark (XrmStringType); #ifndef USE_X_TOOLKIT /* pmr@osf.org says this shouldn't be done if USE_X_TOOLKIT. @@ -414,9 +409,11 @@ x_load_resources (Display *display, const char *xrm_string, sprintf (line, "Emacs.dialog*.background: grey75"); XrmPutLineResource (&rdb, line); #if !(defined USE_CAIRO || defined HAVE_XFT) || !defined (USE_LUCID) - sprintf (line, "Emacs.dialog*.font: %s", helv); + sprintf (line, "Emacs.dialog*.font: %s", + "-*-helvetica-medium-r-*--*-120-*-*-*-*-iso8859-1"); XrmPutLineResource (&rdb, line); - sprintf (line, "*XlwMenu*font: %s", helv); + sprintf (line, "*XlwMenu*font: %s", + "-*-helvetica-medium-r-*--*-120-*-*-*-*-iso8859-1"); XrmPutLineResource (&rdb, line); #endif sprintf (line, "*XlwMenu*background: grey75"); commit 02ae85e8aa735b0d9a312f811d03204bf8fdbd51 Author: Po Lu Date: Thu Apr 28 10:50:18 2022 +0800 Stop overriding default Motif colors with our own * src/xrdb.c (x_load_resources): Instead of specifying the Motif defaults manually, let Motif set them itself. This makes palettes provided by color servers work again. diff --git a/src/xrdb.c b/src/xrdb.c index 56e07f74a2..67d9f57f7d 100644 --- a/src/xrdb.c +++ b/src/xrdb.c @@ -383,14 +383,11 @@ x_load_resources (Display *display, const char *xrm_string, XrmDatabase db; char line[256]; -#if defined USE_MOTIF || !(defined USE_CAIRO || defined HAVE_XFT) || !defined USE_LUCID +#if !(defined USE_CAIRO || defined HAVE_XFT) \ + && !defined USE_MOTIF && !defined USE_LUCID const char *helv = "-*-helvetica-medium-r-*--*-120-*-*-*-*-iso8859-1"; #endif -#ifdef USE_MOTIF - const char *courier = "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1"; -#endif - x_rm_string = XrmStringToQuark (XrmStringType); #ifndef USE_X_TOOLKIT /* pmr@osf.org says this shouldn't be done if USE_X_TOOLKIT. @@ -399,47 +396,7 @@ x_load_resources (Display *display, const char *xrm_string, #endif rdb = XrmGetStringDatabase (""); - /* Add some font defaults. If the font `helv' doesn't exist, widgets - will use some other default font. */ #ifdef USE_MOTIF - - sprintf (line, "%s.pane.background: grey75", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fontList: %s", myclass, helv); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*menu*background: grey75", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*menubar*background: grey75", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*verticalScrollBar.background: grey75", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*verticalScrollBar.troughColor: grey75", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*horizontalScrollBar.background: grey75", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*horizontalScrollBar.troughColor: grey75", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s.dialog*.background: grey75", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fsb.Text.background: white", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fsb.FilterText.background: white", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fsb*DirList.background: white", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fsb*ItemsList.background: white", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fsb*background: grey75", myclass); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fsb.Text.fontList: %s", myclass, courier); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fsb.FilterText.fontList: %s", myclass, courier); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fsb*ItemsList.fontList: %s", myclass, courier); - XrmPutLineResource (&rdb, line); - sprintf (line, "%s*fsb*DirList.fontList: %s", myclass, courier); - XrmPutLineResource (&rdb, line); - /* Set double click time of list boxes in the file selection dialog from `double-click-time'. */ if (FIXNUMP (Vdouble_click_time) && XFIXNUM (Vdouble_click_time) > 0) @@ -451,9 +408,9 @@ x_load_resources (Display *display, const char *xrm_string, myclass, XFIXNAT (Vdouble_click_time)); XrmPutLineResource (&rdb, line); } - #else /* not USE_MOTIF */ - + /* Add some font defaults. If the font `helv' doesn't exist, + widgets will use some other default font. */ sprintf (line, "Emacs.dialog*.background: grey75"); XrmPutLineResource (&rdb, line); #if !(defined USE_CAIRO || defined HAVE_XFT) || !defined (USE_LUCID) @@ -468,7 +425,6 @@ x_load_resources (Display *display, const char *xrm_string, XrmPutLineResource (&rdb, line); sprintf (line, "Emacs*horizontalScrollBar.background: grey75"); XrmPutLineResource (&rdb, line); - #endif /* not USE_MOTIF */ user_database = get_user_db (display); commit 22b2250732bcc1d8eecf11bb3cf490570d80497f Author: Po Lu Date: Thu Apr 28 09:31:29 2022 +0800 Handle display disconnects during DND * src/xterm.c (handle_one_xevent): Keep track of the display the drop target is on during DND finish. (x_connection_closed, x_delete_terminal): Handle display disconnects during DND correctly. diff --git a/src/xterm.c b/src/xterm.c index ff665acdf2..49e1ce1b84 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -875,6 +875,10 @@ struct frame *x_dnd_frame; important information. */ static bool x_dnd_waiting_for_finish; +/* The display the drop target that is supposed to send information is + on. */ +static Display *x_dnd_finish_display; + /* State of the Motif drop operation. 0 means nothing has happened, i.e. the event loop should not wait @@ -16123,6 +16127,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, = x_dnd_send_drop (x_dnd_frame, x_dnd_last_seen_window, x_dnd_selection_timestamp, x_dnd_last_protocol_version); + x_dnd_finish_display = dpyinfo->display; } else if (x_dnd_last_seen_window != None) { @@ -16171,6 +16176,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_waiting_for_finish = true; x_dnd_waiting_for_motif_finish_display = dpyinfo; x_dnd_waiting_for_motif_finish = 1; + x_dnd_finish_display = dpyinfo->display; } } else @@ -17388,6 +17394,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, = x_dnd_send_drop (x_dnd_frame, x_dnd_last_seen_window, x_dnd_selection_timestamp, x_dnd_last_protocol_version); + x_dnd_finish_display = dpyinfo->display; } else if (x_dnd_last_seen_window != None) { @@ -17445,6 +17452,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_waiting_for_finish = true; x_dnd_waiting_for_motif_finish_display = dpyinfo; x_dnd_waiting_for_motif_finish = 1; + x_dnd_finish_display = dpyinfo->display; } } else @@ -20026,6 +20034,30 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) /* Inhibit redisplay while frames are being deleted. */ specbind (Qinhibit_redisplay, Qt); + /* If drag-and-drop is in progress and the DND frame's display is + DPY, cancel drag-and-drop. Don't reset event masks or try to + send responses to other programs because the display is going + away. */ + + if ((x_dnd_in_progress || x_dnd_waiting_for_finish) + && dpy == (x_dnd_waiting_for_finish + ? x_dnd_finish_display + : FRAME_X_DISPLAY (x_dnd_frame))) + { + x_dnd_last_seen_window = None; + x_dnd_last_seen_toplevel = None; + x_dnd_in_progress = false; + x_set_dnd_targets (NULL, 0); + x_dnd_waiting_for_finish = false; + + if (x_dnd_use_toplevels) + x_dnd_free_toplevels (); + + x_dnd_return_frame_object = NULL; + x_dnd_movement_frame = NULL; + x_dnd_frame = NULL; + } + if (dpyinfo) { /* Protect display from being closed when we delete the last @@ -23935,6 +23967,27 @@ x_delete_terminal (struct terminal *terminal) image_destroy_all_bitmaps (dpyinfo); XSetCloseDownMode (dpyinfo->display, DestroyAll); + /* Get rid of any drag-and-drop operation that might be in + progress as well. */ + if ((x_dnd_in_progress || x_dnd_waiting_for_finish) + && dpyinfo->display == (x_dnd_waiting_for_finish + ? x_dnd_finish_display + : FRAME_X_DISPLAY (x_dnd_frame))) + { + x_dnd_last_seen_window = None; + x_dnd_last_seen_toplevel = None; + x_dnd_in_progress = false; + x_set_dnd_targets (NULL, 0); + x_dnd_waiting_for_finish = false; + + if (x_dnd_use_toplevels) + x_dnd_free_toplevels (); + + x_dnd_return_frame_object = NULL; + x_dnd_movement_frame = NULL; + x_dnd_frame = NULL; + } + /* Whether or not XCloseDisplay destroys the associated resource database depends on the version of libX11. To avoid both crash and memory leak, we dissociate the database from the commit 28b375a93142a13b36d397cf627097bde429b73f Author: Po Lu Date: Thu Apr 28 08:46:21 2022 +0800 Fix target display checks during Motif DND * src/xterm.c (handle_one_xevent): Check that the Motif DND completion message is actually from the right display before proceeding. diff --git a/src/xterm.c b/src/xterm.c index 891a242012..ff665acdf2 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -886,6 +886,10 @@ static bool x_dnd_waiting_for_finish; XmTRANSFER_SUCCESS or XmTRANSFER_FAILURE. */ static int x_dnd_waiting_for_motif_finish; +/* The display the Motif drag receiver will send response data + from. */ +struct x_display_info *x_dnd_waiting_for_motif_finish_display; + /* Whether or not F1 was pressed during the drag-and-drop operation. Motif programs rely on this to decide whether or not help @@ -14054,12 +14058,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, if ((event->xclient.message_type == dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE) - /* FIXME: There should probably be a check that the event - comes from the same display where the drop event was - sent, but there's no way to get that information here - safely. */ && x_dnd_waiting_for_finish - && x_dnd_waiting_for_motif_finish == 1) + && x_dnd_waiting_for_motif_finish == 1 + && dpyinfo == x_dnd_waiting_for_motif_finish_display) { xm_drop_start_reply reply; uint16_t operation, status, action; @@ -14417,6 +14418,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (x_dnd_waiting_for_finish && x_dnd_waiting_for_motif_finish == 2 + && dpyinfo == x_dnd_waiting_for_motif_finish_display && eventp->selection == dpyinfo->Xatom_XdndSelection && (eventp->target == dpyinfo->Xatom_XmTRANSFER_SUCCESS || eventp->target == dpyinfo->Xatom_XmTRANSFER_FAILURE)) @@ -16167,6 +16169,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_last_seen_window, &dmsg); x_dnd_waiting_for_finish = true; + x_dnd_waiting_for_motif_finish_display = dpyinfo; x_dnd_waiting_for_motif_finish = 1; } } @@ -17440,6 +17443,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_dnd_last_seen_window, &dmsg); x_dnd_waiting_for_finish = true; + x_dnd_waiting_for_motif_finish_display = dpyinfo; x_dnd_waiting_for_motif_finish = 1; } } commit afd3619b86ddf42c0591d394d95a7510758eaffb Author: Stefan Monnier Date: Wed Apr 27 18:14:56 2022 -0400 src/xdisp.c: Use same test in `redisplay_window` and `prepare_menu_bars` This consolidates the test made in those two functions so as to make sure they agree whether a window needs to be redisplayed. At the same time, change this test so it uses the window's point rather than the buffer's point when comparing to `w->last_point`. * src/xdisp.c (needs_no_redisplay): New function, extracted from `redisplay_window`. (redisplay_window, prepare_menu_bars): Use it. * src/window.c (window_point): New function, extracted from `Fwindow_point`. (Fwindow_point): Use it. * src/window.h (window_point): Declare it. diff --git a/src/window.c b/src/window.c index 4cca60e23d..48da783931 100644 --- a/src/window.c +++ b/src/window.c @@ -1692,6 +1692,14 @@ column 0. */) 0, false, false); } +ptrdiff_t +window_point (struct window *w) +{ + return (w == XWINDOW (selected_window) + ? BUF_PT (XBUFFER (w->contents)) + : XMARKER (w->pointm)->charpos); +} + DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0, doc: /* Return current value of point in WINDOW. WINDOW must be a live window and defaults to the selected one. @@ -1705,12 +1713,7 @@ correct to return the top-level value of `point', outside of any `save-excursion' forms. But that is hard to define. */) (Lisp_Object window) { - register struct window *w = decode_live_window (window); - - if (w == XWINDOW (selected_window)) - return make_fixnum (BUF_PT (XBUFFER (w->contents))); - else - return Fmarker_position (w->pointm); + return make_fixnum (window_point (decode_live_window (window))); } DEFUN ("window-old-point", Fwindow_old_point, Swindow_old_point, 0, 1, 0, diff --git a/src/window.h b/src/window.h index 94c9b7124f..387a3be36a 100644 --- a/src/window.h +++ b/src/window.h @@ -1191,6 +1191,7 @@ extern void replace_buffer_in_windows_safely (Lisp_Object); /* This looks like a setter, but it is a bit special. */ extern void wset_buffer (struct window *, Lisp_Object); extern bool window_outdated (struct window *); +extern ptrdiff_t window_point (struct window *w); extern void init_window_once (void); extern void init_window (void); extern void syms_of_window (void); diff --git a/src/xdisp.c b/src/xdisp.c index dccff9f2ea..6516f13c82 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13250,6 +13250,20 @@ gui_consider_frame_title (Lisp_Object frame) && (update_mode_lines == 0 \ || update_mode_lines == REDISPLAY_SOME)) +static bool +needs_no_redisplay (struct window *w) +{ + struct buffer *buffer = XBUFFER (w->contents); + struct frame *f = XFRAME (w->frame); + return (REDISPLAY_SOME_P () + && !w->redisplay + && !w->update_mode_line + && !f->face_change + && !f->redisplay + && !buffer->text->redisplay + && window_point (w) == w->last_point); +} + /* Prepare for redisplay by updating menu-bar item lists when appropriate. This can call eval. */ @@ -13271,13 +13285,8 @@ prepare_menu_bars (void) struct window *w = XWINDOW (this); /* Cf. conditions for redisplaying a window at the beginning of redisplay_window. */ - if (w->redisplay - || XFRAME (w->frame)->redisplay - || XBUFFER (w->contents)->text->redisplay - || BUF_PT (XBUFFER (w->contents)) != w->last_point) - { - windows = Fcons (this, windows); - } + if (!needs_no_redisplay (w)) + windows = Fcons (this, windows); } } safe__call1 (true, Vpre_redisplay_function, windows); @@ -18946,14 +18955,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) *w->desired_matrix->method = 0; #endif - if (!just_this_one_p - && REDISPLAY_SOME_P () - && !w->redisplay - && !w->update_mode_line - && !f->face_change - && !f->redisplay - && !buffer->text->redisplay - && BUF_PT (buffer) == w->last_point) + if (!just_this_one_p && needs_no_redisplay (w)) return; /* Make sure that both W's markers are valid. */ commit 134f4ff38b323af8892520200307e9d54ae90200 Author: Sean Whitton Date: Tue Apr 26 11:39:38 2022 -0700 New user option 'calc-kill-line-numbering' * lisp/calc/calc.el (calc-kill-line-numbering): New defcustom. * lisp/calc/calc-yank.el (calc-kill): Unless calc-kill-line-numbering is non-nil, do not include line numbering in copied text (bug#55133). * etc/NEWS: * doc/misc/calc.texi (Killing from the Stack): Document the change. diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi index d83edc15f3..9bda6af1c5 100644 --- a/doc/misc/calc.texi +++ b/doc/misc/calc.texi @@ -29877,6 +29877,12 @@ with no argument copies only the number itself into the kill ring, whereas @kbd{C-k} with a prefix argument of 1 copies the number with its trailing newline. +You can customize @code{calc-kill-line-numbering} to nil to exclude +line numbering from kills and copies made by @code{calc-kill} and +@code{calc-copy-as-kill}. This option does not affect calc kill and +copy commands which operate on the region, as that would not make +sense. + @node Yanking Into Stack @section Yanking into the Stack diff --git a/etc/NEWS b/etc/NEWS index e7502b1f16..70087f2629 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1311,6 +1311,12 @@ Lisp function. This frees you from having to keep track of whether commands are Lisp function or external when supplying absolute file name arguments. See "Electric forward slash" in the Eshell manual. +** Calc + ++++ +*** New user option 'calc-kill-line-numbering'. +This can be set to nil to exclude line numbering from kills and copies. + ** Miscellaneous +++ diff --git a/lisp/calc/calc-yank.el b/lisp/calc/calc-yank.el index 8c6d3f51e5..172ccf1adc 100644 --- a/lisp/calc/calc-yank.el +++ b/lisp/calc/calc-yank.el @@ -47,6 +47,8 @@ (calc-check-stack num) (let ((stuff (calc-top-list n (- num n -1)))) (calc-cursor-stack-index num) + (unless calc-kill-line-numbering + (re-search-forward "\\=[0-9]+:\\s-+" (point-at-eol) t)) (let ((first (point))) (calc-cursor-stack-index (- num n)) (if (null nn) diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el index 523f51533a..b03dcfeb5b 100644 --- a/lisp/calc/calc.el +++ b/lisp/calc/calc.el @@ -439,6 +439,14 @@ to be identified as that note." :version "24.1" :type 'string) +(defcustom calc-kill-line-numbering t + "If non-nil, calculator kills include any line numbering. + +This option does not affect calc kill and copy commands which +operate on the region, such as `calc-copy-region-as-kill'." + :version "29.1" + :type 'boolean) + (defvar math-format-date-cache) ; calc-forms.el (defface calc-nonselected-face commit 38d87c43c2ad727406dcfe316aac5e24e202c251 Author: Alan Mackenzie Date: Wed Apr 27 19:11:47 2022 +0000 CC Mode: "linux" style: set indent-tabs-mode to t * lisp/progmodes/cc-styles.el (c-style-alist): Add the setting of indent-tabs-mode to "linux" style. diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el index 8fe8402b1d..1cf14d52d5 100644 --- a/lisp/progmodes/cc-styles.el +++ b/lisp/progmodes/cc-styles.el @@ -180,6 +180,7 @@ (inclass . +) (inline-open . 0)))) ("linux" + (indent-tabs-mode . t) (c-basic-offset . 8) (c-comment-only-line-offset . 0) (c-hanging-braces-alist . ((brace-list-open) commit 2503387bf70592adced8eb2e04e4ff1b39e47f69 Author: Eli Zaretskii Date: Wed Apr 27 21:16:46 2022 +0300 ; Fix recently added documentation * etc/NEWS: Improve wording of entry about 'mouse-yank-at-point'. * doc/emacs/killing.texi (Secondary Selection): Fix a typo. diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi index 02a42a34fc..cc349a6a02 100644 --- a/doc/emacs/killing.texi +++ b/doc/emacs/killing.texi @@ -698,9 +698,9 @@ lines, much like @kbd{mouse-1}. If @code{mouse-yank-at-point} is non-@code{nil}, @kbd{M-mouse-2} yanks at point. Then it does not matter precisely where you click, or even which of the frame's windows you click on. @xref{Mouse Commands}. -This user option also as an effect on interactive search: If this -variable is non-@code{nil}, yanking with the mouse anywhere in the -frame will add the text to the search string. +This user option also effects interactive search: if it is +non-@code{nil}, yanking with the mouse anywhere in the frame will add +the text to the search string. @node Accumulating Text @section Accumulating Text diff --git a/etc/NEWS b/etc/NEWS index fc37ca68de..e7502b1f16 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -767,12 +767,11 @@ but doesn't exit the minibuffer. ** Isearch and Replace +++ -*** Changes in how isearch responds to 'mouse-yank-at-point'. +*** Changes in how Isearch responds to 'mouse-yank-at-point'. If a user does 'C-s' and then uses '' ('mouse-yank-primary') -outside the echo area, Emacs will, by default, end the isearch and -yank the text where the mouse cursor is. In Emacs 29, if -'mouse-yank-at-point' is non-nil, the text will be added to the -isearch instead. +outside the echo area, Emacs will, by default, end the Isearch and +yank the text at mouse cursor. But if 'mouse-yank-at-point' is +non-nil, the text will now be added to the Isearch instead. +++ *** New user option 'char-fold-override'. commit 77f00c019ce48ad90cccd1ffe9981b33b5e82416 Author: Michael Albinus Date: Wed Apr 27 20:15:07 2022 +0200 Improve tramp-test46-read-password * test/lisp/net/tramp-tests.el (tramp-test46-read-password): Add a further check. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index b27b735eb5..d870970945 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -7307,8 +7307,12 @@ process sentinels. They shall not disturb each other." :tags '(:expensive-test) (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-mock-p)) + ;; Not all read commands understand argument "-s" or "-p". + (skip-unless + (string-empty-p + (let ((shell-file-name "sh")) + (shell-command-to-string "read -s -p Password: pass")))) - (tramp--test-instrument-test-case 10 (let ((pass "secret") (mock-entry (copy-sequence (assoc "mock" tramp-methods))) mocked-input tramp-methods) @@ -7355,7 +7359,7 @@ process sentinels. They shall not disturb each other." "machine %s port mock password %s" (file-remote-p tramp-test-temporary-file-directory 'host) pass) (let ((auth-sources `(,netrc-file))) - (should (file-exists-p tramp-test-temporary-file-directory)))))))))) + (should (file-exists-p tramp-test-temporary-file-directory))))))))) ;; This test is inspired by Bug#29163. (ert-deftest tramp-test47-auto-load () commit 53e8f00111084b4d98e81a57e025f637835e20a8 Author: Eli Zaretskii Date: Wed Apr 27 21:06:55 2022 +0300 Emulate 'clock' for MS-Windows * src/w32.c (sys_clock): New function. (Bug#44674) * nt/inc/ms-w32.h (clock): Redirect to sys_clock. diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h index 3f4b2f3489..2dd9a9a476 100644 --- a/nt/inc/ms-w32.h +++ b/nt/inc/ms-w32.h @@ -295,6 +295,7 @@ extern int sys_unlink (const char *); #undef umask #define umask sys_umask extern int sys_umask (int); +#define clock sys_clock /* Subprocess calls that are emulated. */ #define spawnve sys_spawnve diff --git a/src/w32.c b/src/w32.c index 25f5555af3..1b10b9965f 100644 --- a/src/w32.c +++ b/src/w32.c @@ -71,6 +71,8 @@ along with GNU Emacs. If not, see . */ #undef localtime +#undef clock + char *sys_ctime (const time_t *); int sys_chdir (const char *); int sys_creat (const char *, int); @@ -87,6 +89,7 @@ struct tm *sys_localtime (const time_t *); compiler to emit a warning about sys_strerror having no prototype. */ char *sys_strerror (int); +clock_t sys_clock (void); #ifdef HAVE_MODULES extern void dynlib_reset_last_error (void); @@ -10155,6 +10158,32 @@ sys_localtime (const time_t *t) return localtime (t); } +/* The Windows CRT implementation of 'clock' doesn't really return CPU + time of the process (it returns the elapsed time since the process + started), so we provide a better emulation here, if possible. */ +clock_t +sys_clock (void) +{ + if (get_process_times_fn) + { + FILETIME create, exit, kernel, user; + HANDLE proc = GetCurrentProcess (); + if ((*get_process_times_fn) (proc, &create, &exit, &kernel, &user)) + { + LARGE_INTEGER user_int, kernel_int, total; + user_int.LowPart = user.dwLowDateTime; + user_int.HighPart = user.dwHighDateTime; + kernel_int.LowPart = kernel.dwLowDateTime; + kernel_int.HighPart = kernel.dwHighDateTime; + total.QuadPart = user_int.QuadPart + kernel_int.QuadPart; + /* We could redefine CLOCKS_PER_SEC to provide a finer + resolution, but with the basic 15.625 msec resolution of + the Windows clock, it doesn't really sound worth the hassle. */ + return total.QuadPart / (10000000 / CLOCKS_PER_SEC); + } + } + return clock (); +} /* Try loading LIBRARY_ID from the file(s) specified in commit 89519d0932b3f2961dfc74b9f945c3a5a21e70fd Author: Lars Ingebrigtsen Date: Wed Apr 27 20:03:25 2022 +0200 Make `C-M-x' use the original value of print-length while evalling * lisp/progmodes/elisp-mode.el (elisp--eval-defun): Eval the form with the original values of print-level and print-length (bug#135). diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 33f6902491..a4088fa467 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -1614,8 +1614,6 @@ Return the result of evaluation." ;; printing, not while evaluating. (defvar elisp--eval-defun-result) (let ((debug-on-error eval-expression-debug-on-error) - (print-length eval-expression-print-length) - (print-level eval-expression-print-level) elisp--eval-defun-result) (save-excursion ;; Arrange for eval-region to "read" the (possibly) altered form. @@ -1630,10 +1628,17 @@ Return the result of evaluation." (setq beg (point)) (setq form (funcall load-read-function (current-buffer))) (setq end (point))) - ;; Alter the form if necessary. - (let ((form (eval-sexp-add-defvars - (elisp--eval-defun-1 - (macroexpand form))))) + ;; Alter the form if necessary. We bind `print-level' (etc.) + ;; in the form itself, because we want evalling the form to + ;; use the original values, while we want the printing to use + ;; `eval-expression-print-length' (etc.). + (let ((form `(let ((print-level ,print-level) + (print-length ,print-length)) + ,(eval-sexp-add-defvars + (elisp--eval-defun-1 + (macroexpand form))))) + (print-length eval-expression-print-length) + (print-level eval-expression-print-level)) (eval-region beg end standard-output (lambda (_ignore) ;; Skipping to the end of the specified region commit f97d4460e007d7b37aa7defcf9113cb6bb8cab5a Author: Ken Brown Date: Wed Apr 27 10:46:57 2022 -0400 Implement system_process_attributes on Cygwin * src/sysdep.c (system_process_attributes) [CYGWIN]: Implement, using the /proc filesystem. The code is identical to the GNU/Linux code except for the 'ttname' attribute. (Bug#55153) * etc/NEWS: Mention the change. diff --git a/etc/NEWS b/etc/NEWS index 526afe27a5..fc37ca68de 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2154,6 +2154,11 @@ where those APIs are available. When 'w32-use-native-image-API' is non-nil, Emacs on MS-Windows now has built-in support for displaying BMP images. +** Cygwin + +--- +*** 'process-attributes' is now implemented. + ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/src/sysdep.c b/src/sysdep.c index 9c1e59c02b..95295e7e67 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -3193,7 +3193,7 @@ make_lisp_timeval (struct timeval t) #endif -#ifdef GNU_LINUX +#if defined (GNU_LINUX) || defined (CYGWIN) static Lisp_Object time_from_jiffies (unsigned long long ticks, Lisp_Object hz, Lisp_Object form) @@ -3241,6 +3241,7 @@ get_up_time (void) return up; } +# ifdef GNU_LINUX #define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff) #define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12)) @@ -3286,6 +3287,7 @@ procfs_ttyname (int rdev) unblock_input (); return build_string (name); } +# endif /* GNU_LINUX */ static uintmax_t procfs_get_total_memory (void) @@ -3434,7 +3436,9 @@ system_process_attributes (Lisp_Object pid) attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (ppid)), attrs); attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (pgrp)), attrs); attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (sess)), attrs); +# ifdef GNU_LINUX attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs); +# endif attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (tpgid)), attrs); attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (minflt)), attrs); attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (majflt)), attrs); @@ -3483,6 +3487,26 @@ system_process_attributes (Lisp_Object pid) } unbind_to (count, Qnil); +# ifdef CYGWIN + /* ttname */ + strcpy (procfn_end, "/ctty"); + fd = emacs_open (fn, O_RDONLY, 0); + if (fd < 0) + nread = 0; + else + { + record_unwind_protect_int (close_file_unwind, fd); + nread = emacs_read_quit (fd, procbuf, sizeof procbuf); + } + /* /proc//ctty should always end in newline. */ + if (0 < nread && procbuf[nread - 1] == '\n') + procbuf[nread - 1] = '\0'; + else + procbuf[0] = '\0'; + attrs = Fcons (Fcons (Qttname, build_string (procbuf)), attrs); + unbind_to (count, Qnil); +# endif /* CYGWIN */ + /* args */ strcpy (procfn_end, "/cmdline"); fd = emacs_open (fn, O_RDONLY, 0); commit 1110d7326f8b2b94f473244c5d2111324d06cd29 Author: Stefan Monnier Date: Wed Apr 27 19:20:41 2022 +0200 Add new function current-cpu-time * doc/lispref/os.texi (Time of Day): Document it. * src/timefns.c (Fcurrent_cpu_time): New function (bug#44674). diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 9e87b3840e..89ddf164a1 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1434,6 +1434,13 @@ as @samp{0.1} but is slightly greater than 1/10. @code{time-to-seconds} is an alias for this function. @end defun +@defun current-cpu-time +Return the current @acronym{CPU} time along with its resolution. The +return value is a pair @code{(CPU-TICKS . TICKS-PER-SEC)}. The +@var{CPU-TICKS} counter can wrap around, so values cannot be +meaningfully compared if too much time has passed between them. +@end defun + @node Time Zone Rules @section Time Zone Rules @cindex time zone rules diff --git a/etc/NEWS b/etc/NEWS index 2ecad81b11..526afe27a5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1513,6 +1513,11 @@ functions. * Lisp Changes in Emacs 29.1 +--- +** New function 'current-cpu-time'. +It gives access to the CPU time used by the Emacs process, for +example for benchmarking purposes. + --- ** New function 'string-edit'. This is meant to be used when the user has to edit a (potentially) diff --git a/src/timefns.c b/src/timefns.c index e7a2cd368e..651e0760e8 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -1775,6 +1775,18 @@ if you need this older timestamp form. */) return make_lisp_time (current_timespec ()); } +#ifdef CLOCKS_PER_SEC +DEFUN ("current-cpu-time", Fcurrent_cpu_time, Scurrent_cpu_time, 0, 0, 0, + doc: /* Return the current CPU time along with its resolution. +The return value is a pair (CPU-TICKS . TICKS-PER-SEC). +The CPU-TICKS counter can wrap around, so values cannot be meaningfully +compared if too much time has passed between them. */) + (void) +{ + return Fcons (make_int (clock ()), make_int (CLOCKS_PER_SEC)); +} +#endif + DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 2, 0, doc: /* Return the current local time, as a human-readable string. @@ -2014,6 +2026,9 @@ syms_of_timefns (void) DEFSYM (Qencode_time, "encode-time"); defsubr (&Scurrent_time); +#ifdef CLOCKS_PER_SEC + defsubr (&Scurrent_cpu_time); +#endif defsubr (&Stime_convert); defsubr (&Stime_add); defsubr (&Stime_subtract); commit 92dcd7562cd9e00b0b0ef3ec4eb399f362b1d982 Author: Lars Ingebrigtsen Date: Wed Apr 27 19:14:18 2022 +0200 Regenerated ldefs-boot.el diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 41a2b920b5..a049f65e4d 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -17362,9 +17362,10 @@ of a holiday list. The optional LABEL is used to label the buffer created. -The list of holiday lists is computed by the `holiday-lists', and -you can alter the results by redefining that function, or use -`add-function' to all values. +The list of holiday lists is computed by the +`holiday-available-holiday-lists' and you can alter the results +by redefining that function, or use `add-function' to add +values. \(fn Y1 &optional Y2 L LABEL)" t nil) @@ -32784,7 +32785,31 @@ Major-mode for writing SRecode macros. ;;;;;; 0 0 0)) ;;; Generated autoloads from textmodes/string-edit.el -(register-definition-prefixes "string-edit" '("read-string-from-buffer" "string-edit-")) +(autoload 'string-edit "string-edit" "\ +Switch to a new buffer to edit STRING. +When the user finishes editing (with \\\\[string-edit-done]), SUCCESS-CALLBACK +is called with the resulting string. + +If the user aborts (with \\\\[string-edit-abort]), ABORT-CALLBACK (if any) is +called with no parameters. + +PROMPT will be inserted at the start of the buffer, but won't be +included in the resulting string. If PROMPT is nil, no help text +will be inserted. + +\(fn PROMPT STRING SUCCESS-CALLBACK &key ABORT-CALLBACK)" nil nil) + +(autoload 'read-string-from-buffer "string-edit" "\ +Switch to a new buffer to edit STRING in a recursive edit. +The user finishes editing with \\\\[string-edit-done], or aborts with \\\\[string-edit-abort]). + +PROMPT will be inserted at the start of the buffer, but won't be +included in the resulting string. If nil, no prompt will be +inserted in the buffer. + +\(fn PROMPT STRING)" nil nil) + +(register-definition-prefixes "string-edit" '("string-edit-")) ;;;*** commit 9e24255bc5fb0ea0f53703a06b3b94981782468f Author: Lars Ingebrigtsen Date: Wed Apr 27 19:11:20 2022 +0200 Change parameter order for string-edit functions * lisp/textmodes/string-edit.el (string-edit) (read-string-from-buffer): Rework the function arguments so that they're more similar to `read-string'. Rename symbols throughout the file from help-text to prompt. diff --git a/lisp/textmodes/string-edit.el b/lisp/textmodes/string-edit.el index 00d6b61425..ab0b3b3bd7 100644 --- a/lisp/textmodes/string-edit.el +++ b/lisp/textmodes/string-edit.el @@ -25,7 +25,7 @@ (require 'cl-lib) -(defface string-edit-help-text +(defface string-edit-prompt '((t (:inherit font-lock-comment-face))) "Face used on `string-edit' help text." :group 'text @@ -35,8 +35,8 @@ (defvar string-edit--abort-callback) ;;;###autoload -(cl-defun string-edit (string success-callback - &key abort-callback help-text) +(cl-defun string-edit (prompt string success-callback + &key abort-callback) "Switch to a new buffer to edit STRING. When the user finishes editing (with \\\\[string-edit-done]), SUCCESS-CALLBACK is called with the resulting string. @@ -44,20 +44,21 @@ is called with the resulting string. If the user aborts (with \\\\[string-edit-abort]), ABORT-CALLBACK (if any) is called with no parameters. -If present, HELP-TEXT will be inserted at the start of the -buffer, but won't be included in the resulting string." +PROMPT will be inserted at the start of the buffer, but won't be +included in the resulting string. If PROMPT is nil, no help text +will be inserted." (pop-to-buffer-same-window (generate-new-buffer "*edit string*")) - (when help-text + (when prompt (let ((inhibit-read-only t)) - (insert help-text) + (insert prompt) (ensure-empty-lines 0) (add-text-properties (point-min) (point) (list 'intangible t - 'face 'string-edit-help-text + 'face 'string-edit-prompt 'read-only t)) (insert (propertize (make-separator-line) 'rear-nonsticky t)) (add-text-properties (point-min) (point) - (list 'string-edit--help-text t)))) + (list 'string-edit--prompt t)))) (let ((start (point))) (insert string) (goto-char start)) @@ -74,18 +75,19 @@ buffer, but won't be included in the resulting string." "Type \\\\[string-edit-done] when you've finished editing"))) ;;;###autoload -(defun read-string-from-buffer (string &optional help-text) +(defun read-string-from-buffer (prompt string) "Switch to a new buffer to edit STRING in a recursive edit. The user finishes editing with \\\\[string-edit-done], or aborts with \\\\[string-edit-abort]). -If present, HELP-TEXT will be inserted at the start of the -buffer, but won't be included in the resulting string." +PROMPT will be inserted at the start of the buffer, but won't be +included in the resulting string. If nil, no prompt will be +inserted in the buffer." (string-edit + prompt string (lambda (edited) (setq string edited) (exit-recursive-edit)) - :help-text help-text :abort-callback (lambda () (exit-recursive-edit) (error "Aborted edit"))) @@ -107,7 +109,7 @@ This will kill the current buffer." (goto-char (point-min)) ;; Skip past the help text. (when-let ((match (text-property-search-forward - 'string-edit--help-text nil t))) + 'string-edit--prompt nil t))) (goto-char (prop-match-beginning match))) (let ((string (buffer-substring (point) (point-max))) (callback string-edit--success-callback)) commit 1f659cd33628ba58d007aa35fdbfb88275429399 Author: Lars Ingebrigtsen Date: Wed Apr 27 19:03:49 2022 +0200 Add autoload cookies to string-edit * lisp/textmodes/string-edit.el (string-edit) (read-string-from-buffer): Autoload. diff --git a/lisp/textmodes/string-edit.el b/lisp/textmodes/string-edit.el index ff8a492401..00d6b61425 100644 --- a/lisp/textmodes/string-edit.el +++ b/lisp/textmodes/string-edit.el @@ -34,6 +34,7 @@ (defvar string-edit--success-callback) (defvar string-edit--abort-callback) +;;;###autoload (cl-defun string-edit (string success-callback &key abort-callback help-text) "Switch to a new buffer to edit STRING. @@ -72,6 +73,7 @@ buffer, but won't be included in the resulting string." (message "%s" (substitute-command-keys "Type \\\\[string-edit-done] when you've finished editing"))) +;;;###autoload (defun read-string-from-buffer (string &optional help-text) "Switch to a new buffer to edit STRING in a recursive edit. The user finishes editing with \\\\[string-edit-done], or aborts with \\\\[string-edit-abort]). commit cb5f7454273dcac10c00f5a869aa246ba3285a5f Author: Lars Ingebrigtsen Date: Wed Apr 27 18:48:16 2022 +0200 Fix some typos in the recent holidays change * lisp/calendar/holidays.el (holiday-available-holiday-lists): Fix typos. diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el index 89f8219edc..7e11044dbc 100644 --- a/lisp/calendar/holidays.el +++ b/lisp/calendar/holidays.el @@ -400,7 +400,7 @@ This function is suitable for execution in an init file." (displayed-year (calendar-extract-year date))) (calendar-list-holidays)))) -(defun holiday-available-holyday-lists () +(defun holiday-available-holiday-lists () "Return a list of all holiday lists. This is used by `list-holidays', and you can customize the return value by using `add-function'." @@ -454,8 +454,8 @@ of a holiday list. The optional LABEL is used to label the buffer created. The list of holiday lists is computed by the -`holiday-available-holyday-lists' and you can alter the results -by redefining that function, or use `add-function' to all +`holiday-available-holiday-lists' and you can alter the results +by redefining that function, or use `add-function' to add values." (interactive (let* ((start-year (calendar-read-sexp @@ -468,7 +468,7 @@ values." start-year start-year)) (completion-ignore-case t) - (lists (holiday-available-holyday-lists)) + (lists (holiday-available-holiday-lists)) (choice (capitalize (completing-read "List (TAB for choices): " lists nil t))) (which (if (string-equal choice "Ask") commit abc92b0d5609a9b2d3ef7d217ea25229db633ca2 Author: Michael Albinus Date: Wed Apr 27 16:32:24 2022 +0200 ; Fix previous change in test/Makefile.in diff --git a/test/Makefile.in b/test/Makefile.in index 9c61da9dde..e7df121d0e 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -223,9 +223,11 @@ define test_template ## dependencies, it is better than nothing. srcfile = $(patsubst %-tests,$(srcdir)/../%,$(1))$(if $(patsubst src/%,,$(patsubst lib-src/%,,$(1))),.el,.c) ifeq (,$(patsubst %-tests,,$(1))$(findstring -tests/,$(1))) + ifeq ($(shell test -e $(srcfile) && echo -n yes),yes) $(1).log: $(srcfile) $(notdir $(1).log): $(1).log endif + endif ## Short aliases that always re-run the tests, with no logging. ## Define both with and without the directory name for ease of use. commit 82fa112e8a6ca5a6b6d160e25134c6c4ab9a0bd7 Author: Lars Ingebrigtsen Date: Wed Apr 27 16:09:38 2022 +0200 Give better error message in dired-toggle-read-only on nonexisting dirs * lisp/dired.el (dired-toggle-read-only): Refuse to edit non-existent directories (bug#23276). diff --git a/lisp/dired.el b/lisp/dired.el index 2856c5d243..89fbd52aa6 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2533,6 +2533,8 @@ If the current buffer can be edited with Wdired, (i.e. the major mode is `dired-mode'), call `wdired-change-to-wdired-mode'. Otherwise, toggle `read-only-mode'." (interactive) + (unless (file-exists-p default-directory) + (user-error "The current directory no longer exists")) (when (and (not (file-writable-p default-directory)) (not (y-or-n-p "Directory isn't writable; edit anyway? "))) commit 0beb8fd663663dcaa1bda4df5995d10f1ef615fb Author: Lars Ingebrigtsen Date: Wed Apr 27 15:30:25 2022 +0200 Rename holiday-lists to holiday-available-holyday-lists * lisp/calendar/holidays.el (holiday-available-holyday-lists): Give holiday-lists a better name. diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el index ca7166c371..89f8219edc 100644 --- a/lisp/calendar/holidays.el +++ b/lisp/calendar/holidays.el @@ -400,7 +400,7 @@ This function is suitable for execution in an init file." (displayed-year (calendar-extract-year date))) (calendar-list-holidays)))) -(defun holiday-lists () +(defun holiday-available-holyday-lists () "Return a list of all holiday lists. This is used by `list-holidays', and you can customize the return value by using `add-function'." @@ -453,9 +453,10 @@ of a holiday list. The optional LABEL is used to label the buffer created. -The list of holiday lists is computed by the `holiday-lists', and -you can alter the results by redefining that function, or use -`add-function' to all values." +The list of holiday lists is computed by the +`holiday-available-holyday-lists' and you can alter the results +by redefining that function, or use `add-function' to all +values." (interactive (let* ((start-year (calendar-read-sexp "Starting year of holidays (>0)" @@ -467,7 +468,7 @@ you can alter the results by redefining that function, or use start-year start-year)) (completion-ignore-case t) - (lists (holiday-lists)) + (lists (holiday-available-holyday-lists)) (choice (capitalize (completing-read "List (TAB for choices): " lists nil t))) (which (if (string-equal choice "Ask") commit 7933775a1b98bd33daa438f13a843eac3326af56 Author: Lars Ingebrigtsen Date: Wed Apr 27 14:57:57 2022 +0200 Separate out the holiday lists into its own function * lisp/calendar/holidays.el (holiday-lists): Separated out into its own function so that it can be altered (bug#55140). (list-holidays): Use it. diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el index 2afa667a56..ca7166c371 100644 --- a/lisp/calendar/holidays.el +++ b/lisp/calendar/holidays.el @@ -400,6 +400,36 @@ This function is suitable for execution in an init file." (displayed-year (calendar-extract-year date))) (calendar-list-holidays)))) +(defun holiday-lists () + "Return a list of all holiday lists. +This is used by `list-holidays', and you can customize the return +value by using `add-function'." + (delq + nil + (list + (cons "All" calendar-holidays) + (cons "Equinoxes/Solstices" + (list (list 'solar-equinoxes-solstices))) + (if holiday-general-holidays + (cons "General" holiday-general-holidays)) + (if holiday-local-holidays + (cons "Local" holiday-local-holidays)) + (if holiday-other-holidays + (cons "Other" holiday-other-holidays)) + (if holiday-christian-holidays + (cons "Christian" holiday-christian-holidays)) + (if holiday-hebrew-holidays + (cons "Hebrew" holiday-hebrew-holidays)) + (if holiday-islamic-holidays + (cons "Islamic" holiday-islamic-holidays)) + (if holiday-bahai-holidays + (cons "Bahá’í" holiday-bahai-holidays)) + (if holiday-oriental-holidays + (cons "Oriental" holiday-oriental-holidays)) + (if holiday-solar-holidays + (cons "Solar" holiday-solar-holidays)) + (cons "Ask" nil)))) + ;; rms: "Emacs commands to display a list of something generally start ;; with `list-'. Please make `list-holidays' the principal name." ;;;###autoload @@ -421,7 +451,11 @@ documentation of `calendar-holidays' for a list of the variables that control the choices, as well as a description of the format of a holiday list. -The optional LABEL is used to label the buffer created." +The optional LABEL is used to label the buffer created. + +The list of holiday lists is computed by the `holiday-lists', and +you can alter the results by redefining that function, or use +`add-function' to all values." (interactive (let* ((start-year (calendar-read-sexp "Starting year of holidays (>0)" @@ -433,30 +467,7 @@ The optional LABEL is used to label the buffer created." start-year start-year)) (completion-ignore-case t) - (lists - (list - (cons "All" calendar-holidays) - (cons "Equinoxes/Solstices" - (list (list 'solar-equinoxes-solstices))) - (if holiday-general-holidays - (cons "General" holiday-general-holidays)) - (if holiday-local-holidays - (cons "Local" holiday-local-holidays)) - (if holiday-other-holidays - (cons "Other" holiday-other-holidays)) - (if holiday-christian-holidays - (cons "Christian" holiday-christian-holidays)) - (if holiday-hebrew-holidays - (cons "Hebrew" holiday-hebrew-holidays)) - (if holiday-islamic-holidays - (cons "Islamic" holiday-islamic-holidays)) - (if holiday-bahai-holidays - (cons "Bahá’í" holiday-bahai-holidays)) - (if holiday-oriental-holidays - (cons "Oriental" holiday-oriental-holidays)) - (if holiday-solar-holidays - (cons "Solar" holiday-solar-holidays)) - (cons "Ask" nil))) + (lists (holiday-lists)) (choice (capitalize (completing-read "List (TAB for choices): " lists nil t))) (which (if (string-equal choice "Ask") diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 93e8e14d1f..41a2b920b5 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -16110,19 +16110,22 @@ If this produces no string either, return nil." nil nil) (autoload 'display-local-help "help-at-pt" "\ Display local help in the echo area. -This displays a short help message, namely the string produced by -the `kbd-help' property at point. If `kbd-help' does not produce -a string, but the `help-echo' property does, then that string is -printed instead. +This command, by default, displays a short help message, namely +the string produced by the `kbd-help' property at point. If +`kbd-help' does not produce a string, but the `help-echo' +property does, then that string is printed instead. The string is passed through `substitute-command-keys' before it is displayed. -A numeric argument ARG prevents display of a message in case -there is no help. While ARG can be used interactively, it is -mainly meant for use from Lisp. +If INHIBIT-WARNING is non-nil, this prevents display of a message +in case there is no help. -\(fn &optional ARG)" t nil) +If DESCRIBE-BUTTON in non-nil (interactively, the prefix arg), and +there's a button/widget at point, pop a buffer describing that +button/widget instead. + +\(fn &optional INHIBIT-WARNING DESCRIBE-BUTTON)" t nil) (autoload 'help-at-pt-cancel-timer "help-at-pt" "\ Cancel any timer set by `help-at-pt-set-timer'. @@ -17359,6 +17362,10 @@ of a holiday list. The optional LABEL is used to label the buffer created. +The list of holiday lists is computed by the `holiday-lists', and +you can alter the results by redefining that function, or use +`add-function' to all values. + \(fn Y1 &optional Y2 L LABEL)" t nil) (defalias 'holiday-list 'list-holidays) @@ -32771,6 +32778,14 @@ Major-mode for writing SRecode macros. (register-definition-prefixes "srecode/table" '("object-sort-list" "srecode-")) +;;;*** + +;;;### (autoloads nil "string-edit" "textmodes/string-edit.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from textmodes/string-edit.el + +(register-definition-prefixes "string-edit" '("read-string-from-buffer" "string-edit-")) + ;;;*** ;;;### (autoloads nil "strokes" "strokes.el" (0 0 0 0)) commit da25daf7f74cfab558eb0f796d2fe33e6c4f06dd Author: Michael Albinus Date: Wed Apr 27 14:13:24 2022 +0200 Make test/Makefile more robust * test/Makefile.in (test_template): Do not fails if corresponding source file doesn't exist. diff --git a/test/Makefile.in b/test/Makefile.in index 3b6e116e65..9c61da9dde 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -221,9 +221,9 @@ define test_template ## The similar name is FOO.c if FOO begins with '{lib-,}src/', FOO.el ## otherwise. Although this heuristic does not identify all the ## dependencies, it is better than nothing. + srcfile = $(patsubst %-tests,$(srcdir)/../%,$(1))$(if $(patsubst src/%,,$(patsubst lib-src/%,,$(1))),.el,.c) ifeq (,$(patsubst %-tests,,$(1))$(findstring -tests/,$(1))) - $(1).log: $(patsubst %-tests,$(srcdir)/../%,$(1))$(if \ - $(patsubst src/%,,$(patsubst lib-src/%,,$(1))),.el,.c) + $(1).log: $(srcfile) $(notdir $(1).log): $(1).log endif commit 0613e7c33d75a2bc7185439598893ad0bb24e110 Author: Lars Ingebrigtsen Date: Wed Apr 27 14:08:49 2022 +0200 Add an instruction header line to string-edit * lisp/textmodes/string-edit.el (string-edit): Add a header line with instructions. diff --git a/lisp/textmodes/string-edit.el b/lisp/textmodes/string-edit.el index 7c3b570224..ff8a492401 100644 --- a/lisp/textmodes/string-edit.el +++ b/lisp/textmodes/string-edit.el @@ -66,6 +66,9 @@ buffer, but won't be included in the resulting string." (setq-local string-edit--success-callback success-callback) (when abort-callback (setq-local string-edit--abort-callback abort-callback)) + (setq-local header-line-format + (substitute-command-keys + "Type \\\\[string-edit-done] when you've finished editing or \\[string-edit-abort] to abort")) (message "%s" (substitute-command-keys "Type \\\\[string-edit-done] when you've finished editing"))) commit a7f2eb3054588ce627aeb6c24ca0b4c469f68914 Author: Lars Ingebrigtsen Date: Wed Apr 27 14:02:23 2022 +0200 Make isearch respond to 'mouse-yank-at-point' * doc/emacs/killing.texi (Secondary Selection): Document it. * lisp/isearch.el (isearch-mouse-2): Make isearch respond to mouse-yank-at-point (bug#7787). * lisp/mouse.el (mouse-yank-at-point): Mention it. diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi index e3de2bc2fa..02a42a34fc 100644 --- a/doc/emacs/killing.texi +++ b/doc/emacs/killing.texi @@ -698,6 +698,9 @@ lines, much like @kbd{mouse-1}. If @code{mouse-yank-at-point} is non-@code{nil}, @kbd{M-mouse-2} yanks at point. Then it does not matter precisely where you click, or even which of the frame's windows you click on. @xref{Mouse Commands}. +This user option also as an effect on interactive search: If this +variable is non-@code{nil}, yanking with the mouse anywhere in the +frame will add the text to the search string. @node Accumulating Text @section Accumulating Text diff --git a/etc/NEWS b/etc/NEWS index a2818c8bf7..2ecad81b11 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -766,6 +766,14 @@ but doesn't exit the minibuffer. ** Isearch and Replace ++++ +*** Changes in how isearch responds to 'mouse-yank-at-point'. +If a user does 'C-s' and then uses '' ('mouse-yank-primary') +outside the echo area, Emacs will, by default, end the isearch and +yank the text where the mouse cursor is. In Emacs 29, if +'mouse-yank-at-point' is non-nil, the text will be added to the +isearch instead. + +++ *** New user option 'char-fold-override'. Non-nil means that the default definitions of equivalent characters diff --git a/lisp/isearch.el b/lisp/isearch.el index be0227b6e7..750324a9fe 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -2631,9 +2631,10 @@ is bound to outside of Isearch." ;; Key search depends on mode (bug#47755) (isearch-mode nil)) (key-binding (this-command-keys-vector) t)))) - (if (and (window-minibuffer-p w) - (not (minibuffer-window-active-p w))) ; in echo area - (isearch-yank-x-selection) + (if (or mouse-yank-at-point + (and (window-minibuffer-p w) + (not (minibuffer-window-active-p w)))) ; in echo area + (isearch-yank-x-selection) (when (functionp binding) (call-interactively binding))))) diff --git a/lisp/mouse.el b/lisp/mouse.el index b66cfad487..c08ecaf334 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -42,7 +42,9 @@ :group 'editing) (defcustom mouse-yank-at-point nil - "If non-nil, mouse yank commands yank at point instead of at click." + "If non-nil, mouse yank commands yank at point instead of at click. +This also allows yanking text into an isearch without moving the +mouse cursor to the echo area." :type 'boolean) (defcustom mouse-drag-copy-region nil commit 5aef2623a37d9fe452b7072dbd12c7a24dd971e2 Author: Po Lu Date: Wed Apr 27 19:19:01 2022 +0800 Cleanups to PGTK code * src/pgtkfns.c (pgtk_explicitly_set_name, pgtk_set_tab_bar_lines) (pgtk_change_tab_bar_height, pgtk_set_child_frame_border_width) (pgtk_set_internal_border_width, pgtk_set_cursor_type) (pgtk_set_mouse_color, pgtk_set_override_redirect, xg_set_icon) (pgtk_frame_parm_handlers, Fpgtk_set_monitor_scale_factor) (pgtk_set_scroll_bar_default_width, pgtk_get_focus_frame) (pgtk_hide_tip, Fx_show_tip, Fx_hide_tip, frame_geometry) (syms_of_pgtkfns): Clean up coding style and delete incorrect comments that mostly duplicate what is in xfns.c, and fix comment coding style. Also rename functions from `x_' to `pgtk_'. * src/pgtkterm.c (pgtk_setup_relief_colors): Fix relief caching with new flag. (pgtk_draw_relief_rect, flip_cr_context, pgtk_wait_for_map_event) (pgtk_make_frame_visible, pgtk_make_frame_invisible) (pgtk_set_parent_frame, pgtk_draw_glyph_string_foreground) (pgtk_draw_composite_glyph_string_foreground) (pgtk_draw_glyphless_glyph_string_foreground) (pgtk_set_clip_rectangles, pgtk_draw_glyph_string_bg_rect) (pgtk_draw_image_foreground, pgtk_draw_image_glyph_string) (pgtk_draw_stretch_glyph_string, pgtk_draw_glyph_string) (pgtk_copy_bits, pgtk_bitmap_icon, pgtk_define_fringe_bitmap) (pgtk_show_hourglass, pgtk_flash, pgtk_send_scroll_bar_event) (pgtk_free_pixmap, set_opacity_recursively, frame_highlight) (frame_unhighlight, pgtk_toggle_invisible_pointer) (pgtk_create_terminal, pgtk_window_is_of_frame_recursive) (pgtk_window_is_of_frame, pgtk_any_window_to_frame) (pgtk_handle_draw, size_allocate, pgtk_enqueue_string) (key_press_event, motion_notify_event): Fix coding style and some minor bugs. * src/pgtkterm.h (struct pgtk_output): New field for tracking relief color status, update prototypes. diff --git a/src/pgtkfns.c b/src/pgtkfns.c index 1cab954a07..d1a72804cf 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c @@ -360,7 +360,8 @@ pgtk_set_name (struct frame *f, Lisp_Object name, int explicit) specified a name for the frame; the name will override any set by the redisplay code. */ static void -x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) +pgtk_explicitly_set_name (struct frame *f, Lisp_Object arg, + Lisp_Object oldval) { pgtk_set_name (f, arg, true); } @@ -467,13 +468,12 @@ pgtk_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) else nlines = 0; - x_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); + pgtk_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); } - /* Set the pixel height of the tab bar of frame F to HEIGHT. */ void -x_change_tab_bar_height (struct frame *f, int height) +pgtk_change_tab_bar_height (struct frame *f, int height) { int unit = FRAME_LINE_HEIGHT (f); int old_height = FRAME_TAB_BAR_HEIGHT (f); @@ -578,12 +578,11 @@ pgtk_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object pgtk_clear_under_internal_border (f); } } - } static void pgtk_set_internal_border_width (struct frame *f, Lisp_Object arg, - Lisp_Object oldval) + Lisp_Object oldval) { int border = check_int_nonnegative (arg); @@ -661,32 +660,17 @@ pgtk_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) unblock_input (); } -/* This is the same as the xfns.c definition. */ static void pgtk_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { set_frame_cursor_types (f, arg); } -/* called to set mouse pointer color, but all other terms use it to - initialize pointer types (and don't set the color ;) */ static void pgtk_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { } -/** - * pgtk_set_undecorated: - * - * Set frame F's `undecorated' parameter. If non-nil, F's window-system - * window is drawn without decorations, title, minimize/maximize boxes - * and external borders. This usually means that the window cannot be - * dragged, resized, iconified, maximized or deleted with the mouse. If - * nil, draw the frame with all the elements listed above unless these - * have been suspended via window manager settings. - * - * Some window managers may not honor this parameter. - */ static void pgtk_set_undecorated (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) @@ -698,16 +682,6 @@ pgtk_set_undecorated (struct frame *f, Lisp_Object new_value, } } -/** - * pgtk_set_skip_taskbar: - * - * Set frame F's `skip-taskbar' parameter. If non-nil, this should - * remove F's icon from the taskbar associated with the display of F's - * window-system window and inhibit switching to F's window via - * -. If nil, lift these restrictions. - * - * Some window managers may not honor this parameter. - */ static void pgtk_set_skip_taskbar (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) @@ -719,18 +693,9 @@ pgtk_set_skip_taskbar (struct frame *f, Lisp_Object new_value, } } -/** - * pgtk_set_override_redirect: - * - * Set frame F's `override_redirect' parameter which, if non-nil, hints - * that the window manager doesn't want to deal with F. Usually, such - * frames have no decorations and always appear on top of all frames. - * - * Some window managers may not honor this parameter. - */ static void pgtk_set_override_redirect (struct frame *f, Lisp_Object new_value, - Lisp_Object old_value) + Lisp_Object old_value) { if (!EQ (new_value, old_value)) { @@ -745,9 +710,7 @@ pgtk_set_override_redirect (struct frame *f, Lisp_Object new_value, } } -/* Set icon from FILE for frame F. By using GTK functions the icon - may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */ - +/* Set icon from FILE for frame F. */ bool xg_set_icon (struct frame *f, Lisp_Object file) { @@ -969,59 +932,58 @@ unless TYPE is `png'. */) return pgtk_cr_export_frames (frames, surface_type); } - -/* Note: see frame.c for template, also where generic functions are impl */ -frame_parm_handler pgtk_frame_parm_handlers[] = { - gui_set_autoraise, /* generic OK */ - gui_set_autolower, /* generic OK */ - pgtk_set_background_color, - pgtk_set_border_color, - gui_set_border_width, - pgtk_set_cursor_color, - pgtk_set_cursor_type, - gui_set_font, /* generic OK */ - pgtk_set_foreground_color, - pgtk_set_icon_name, - pgtk_set_icon_type, - pgtk_set_child_frame_border_width, - pgtk_set_internal_border_width, /* generic OK */ - gui_set_right_divider_width, - gui_set_bottom_divider_width, - pgtk_set_menu_bar_lines, - pgtk_set_mouse_color, - x_explicitly_set_name, - gui_set_scroll_bar_width, /* generic OK */ - gui_set_scroll_bar_height, /* generic OK */ - pgtk_set_title, - gui_set_unsplittable, /* generic OK */ - gui_set_vertical_scroll_bars, /* generic OK */ - gui_set_horizontal_scroll_bars, /* generic OK */ - gui_set_visibility, /* generic OK */ - pgtk_set_tab_bar_lines, - pgtk_set_tool_bar_lines, - pgtk_set_scroll_bar_foreground, - pgtk_set_scroll_bar_background, - gui_set_screen_gamma, /* generic OK */ - gui_set_line_spacing, /* generic OK, sets f->extra_line_spacing to int */ - gui_set_left_fringe, /* generic OK */ - gui_set_right_fringe, /* generic OK */ - 0, /* x_set_wait_for_wm */ - gui_set_fullscreen, /* generic OK */ - gui_set_font_backend, /* generic OK */ - gui_set_alpha, - pgtk_set_sticky, - pgtk_set_tool_bar_position, - 0, /* x_set_inhibit_double_buffering */ - pgtk_set_undecorated, - pgtk_set_parent_frame, - pgtk_set_skip_taskbar, - pgtk_set_no_focus_on_map, - pgtk_set_no_accept_focus, - pgtk_set_z_group, - pgtk_set_override_redirect, - gui_set_no_special_glyphs, - pgtk_set_alpha_background, -}; +frame_parm_handler pgtk_frame_parm_handlers[] = + { + gui_set_autoraise, /* generic OK */ + gui_set_autolower, /* generic OK */ + pgtk_set_background_color, + pgtk_set_border_color, + gui_set_border_width, + pgtk_set_cursor_color, + pgtk_set_cursor_type, + gui_set_font, /* generic OK */ + pgtk_set_foreground_color, + pgtk_set_icon_name, + pgtk_set_icon_type, + pgtk_set_child_frame_border_width, + pgtk_set_internal_border_width, /* generic OK */ + gui_set_right_divider_width, + gui_set_bottom_divider_width, + pgtk_set_menu_bar_lines, + pgtk_set_mouse_color, + pgtk_explicitly_set_name, + gui_set_scroll_bar_width, /* generic OK */ + gui_set_scroll_bar_height, /* generic OK */ + pgtk_set_title, + gui_set_unsplittable, /* generic OK */ + gui_set_vertical_scroll_bars, /* generic OK */ + gui_set_horizontal_scroll_bars, /* generic OK */ + gui_set_visibility, /* generic OK */ + pgtk_set_tab_bar_lines, + pgtk_set_tool_bar_lines, + pgtk_set_scroll_bar_foreground, + pgtk_set_scroll_bar_background, + gui_set_screen_gamma, /* generic OK */ + gui_set_line_spacing, /* generic OK, sets f->extra_line_spacing to int */ + gui_set_left_fringe, /* generic OK */ + gui_set_right_fringe, /* generic OK */ + 0, + gui_set_fullscreen, /* generic OK */ + gui_set_font_backend, /* generic OK */ + gui_set_alpha, + pgtk_set_sticky, + pgtk_set_tool_bar_position, + 0, + pgtk_set_undecorated, + pgtk_set_parent_frame, + pgtk_set_skip_taskbar, + pgtk_set_no_focus_on_map, + pgtk_set_no_accept_focus, + pgtk_set_z_group, + pgtk_set_override_redirect, + gui_set_no_special_glyphs, + pgtk_set_alpha_background, + }; /* Handler for signals raised during x_create_frame and @@ -1186,7 +1148,7 @@ incorrect when you specify fractional scale factor in compositor. If you set scale factor by this function, it is used instead of Gdk's one. Pass nil as SCALE-FACTOR if you want to reset the specified monitor's -scale factor. */ ) +scale factor. */) (Lisp_Object monitor_model, Lisp_Object scale_factor) { CHECK_STRING (monitor_model); @@ -2255,27 +2217,6 @@ DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0, return result; } - -DEFUN ("pgtk-hide-others", Fpgtk_hide_others, Spgtk_hide_others, 0, 0, 0, - doc: /* Hides all applications other than Emacs. */) - (void) -{ - check_window_system (NULL); - return Qnil; -} - -DEFUN ("pgtk-hide-emacs", Fpgtk_hide_emacs, Spgtk_hide_emacs, 1, 1, 0, - doc: /* If ON is non-nil, the entire Emacs application is hidden. -Otherwise if Emacs is hidden, it is unhidden. -If ON is equal to `activate', Emacs is unhidden and becomes -the active application. */) - (Lisp_Object on) -{ - check_window_system (NULL); - return Qnil; -} - - DEFUN ("pgtk-font-name", Fpgtk_font_name, Spgtk_font_name, 1, 1, 0, doc: /* Determine font PostScript or family name for font NAME. NAME should be a string containing either the font name or an XLFD @@ -2311,7 +2252,6 @@ check_x_display_info (Lisp_Object frame) return check_pgtk_display_info (frame); } - void pgtk_set_scroll_bar_default_width (struct frame *f) { @@ -2359,9 +2299,8 @@ pgtk_get_string_resource (XrmDatabase rdb, const char *name, return res; } - Lisp_Object -x_get_focus_frame (struct frame *frame) +pgtk_get_focus_frame (struct frame *frame) { struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame); Lisp_Object focus; @@ -2404,7 +2343,6 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0, return Qnil; } - DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0, doc: /* Internal function called by `display-color-p', which see. */) (Lisp_Object terminal) @@ -2413,7 +2351,6 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0, return Qt; } - DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p, 0, 1, 0, doc: /* Return t if the display supports shades of gray. Note that color displays do support shades of gray. @@ -2425,7 +2362,6 @@ If omitted or nil, that stands for the selected frame's display. */) return Qnil; } - DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, 0, 1, 0, doc: /* Return the width in pixels of the display TERMINAL. The optional argument TERMINAL specifies which display to ask about. @@ -2471,7 +2407,6 @@ each physical monitor, use `display-monitor-attributes-list'. */) return make_fixnum (width); } - DEFUN ("x-display-pixel-height", Fx_display_pixel_height, Sx_display_pixel_height, 0, 1, 0, doc: /* Return the height in pixels of the display TERMINAL. The optional argument TERMINAL specifies which display to ask about. @@ -3066,7 +3001,7 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, /* Hide tooltip. Delete its frame if DELETE is true. */ static Lisp_Object -x_hide_tip (bool delete) +pgtk_hide_tip (bool delete) { if (!NILP (tip_timer)) { @@ -3306,13 +3241,13 @@ Text larger than the specified size is clipped. */) } } - x_hide_tip (delete); + pgtk_hide_tip (delete); } else - x_hide_tip (true); + pgtk_hide_tip (true); } else - x_hide_tip (true); + pgtk_hide_tip (true); tip_last_frame = frame; tip_last_string = string; @@ -3439,7 +3374,7 @@ DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0, Value is t if tooltip was open, nil otherwise. */) (void) { - return x_hide_tip (!tooltip_reuse_hidden_frame); + return pgtk_hide_tip (!tooltip_reuse_hidden_frame); } /* Return geometric attributes of FRAME. According to the value of @@ -3465,10 +3400,8 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) int left_pos, top_pos; if (FRAME_GTK_OUTER_WIDGET (f)) - { - gtk_window_get_position (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), - &left_pos, &top_pos); - } + gtk_window_get_position (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), + &left_pos, &top_pos); else { GtkAllocation alloc; @@ -3912,7 +3845,6 @@ syms_of_pgtkfns (void) g_free (ver); } - defsubr (&Spgtk_set_resource); defsubr (&Sxw_display_color_p); /* this and next called directly by C code */ defsubr (&Sx_display_grayscale_p); @@ -3942,9 +3874,6 @@ syms_of_pgtkfns (void) defsubr (&Sx_display_list); defsubr (&Sx_gtk_debug); - defsubr (&Spgtk_hide_others); - defsubr (&Spgtk_hide_emacs); - defsubr (&Sx_show_tip); defsubr (&Sx_hide_tip); diff --git a/src/pgtkterm.c b/src/pgtkterm.c index cf8a7c4816..c8c8bd0d85 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -1,4 +1,4 @@ -/* Pure Gtk+-3 communication module. -*- coding: utf-8 -*- +/* Communication module for window systems using GTK. Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2022 Free Software Foundation, Inc. @@ -278,8 +278,9 @@ flip_cr_context (struct frame *f) if (cr != FRAME_CR_CONTEXT (f)) { cairo_destroy (cr); - FRAME_CR_ACTIVE_CONTEXT (f) = cairo_reference (FRAME_CR_CONTEXT (f)); + FRAME_CR_ACTIVE_CONTEXT (f) + = cairo_reference (FRAME_CR_CONTEXT (f)); } unblock_input (); } @@ -738,19 +739,19 @@ pgtk_wait_for_map_event (struct frame *f, bool multiple_times) { if (FLOATP (Vpgtk_wait_for_event_timeout)) { - guint msec = - (guint) (XFLOAT_DATA (Vpgtk_wait_for_event_timeout) * 1000); + guint msec + = (guint) (XFLOAT_DATA (Vpgtk_wait_for_event_timeout) * 1000); int found = 0; int timed_out = 0; - gulong id = - g_signal_connect (FRAME_WIDGET (f), "map-event", - G_CALLBACK - (pgtk_make_frame_visible_wait_for_map_event_cb), - &found); - guint src = - g_timeout_add (msec, - pgtk_make_frame_visible_wait_for_map_event_timeout, - &timed_out); + gulong id + = g_signal_connect (FRAME_WIDGET (f), "map-event", + G_CALLBACK + (pgtk_make_frame_visible_wait_for_map_event_cb), + &found); + guint src + = g_timeout_add (msec, + pgtk_make_frame_visible_wait_for_map_event_timeout, + &timed_out); if (!multiple_times) { @@ -764,6 +765,7 @@ pgtk_wait_for_map_event (struct frame *f, bool multiple_times) } g_signal_handler_disconnect (FRAME_WIDGET (f), id); + if (!timed_out) g_source_remove (src); } @@ -771,9 +773,6 @@ pgtk_wait_for_map_event (struct frame *f, bool multiple_times) void pgtk_make_frame_visible (struct frame *f) -/* -------------------------------------------------------------------------- - External: Show the window (X11 semantics) - -------------------------------------------------------------------------- */ { GtkWidget *win = FRAME_GTK_OUTER_WIDGET (f); @@ -790,17 +789,11 @@ pgtk_make_frame_visible (struct frame *f) void pgtk_make_frame_invisible (struct frame *f) -/* -------------------------------------------------------------------------- - External: Hide the window (X11 semantics) - -------------------------------------------------------------------------- */ { gtk_widget_hide (FRAME_WIDGET (f)); - /* Map events are emitted many times, and - * map_event() do SET_FRAME_VISIBLE(f, 1). - * I expect visible = 0, so process those map events here and - * SET_FRAME_VISIBLE(f, 0) after that. - */ + /* Handle any pending map event(s), then make the frame visible + manually, to avoid race conditions. */ pgtk_wait_for_map_event (f, true); SET_FRAME_VISIBLE (f, 0); @@ -938,7 +931,8 @@ pgtk_set_parent_frame (struct frame *f, Lisp_Object new_value, { GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed); - /* Here, unhighlight can be called and may change border_color_css_provider. */ + /* Here, unhighlight can be called and may change + border_color_css_provider. */ gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed); if (FRAME_GTK_OUTER_WIDGET (f)) @@ -959,7 +953,8 @@ pgtk_set_parent_frame (struct frame *f, Lisp_Object new_value, { xg_create_frame_outer_widgets (f); pgtk_set_event_handler (f); - gtk_box_pack_start (GTK_BOX (f->output_data.pgtk->hbox_widget), fixed, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (f->output_data.pgtk->hbox_widget), + fixed, TRUE, TRUE, 0); f->output_data.pgtk->preferred_width = alloc.width; f->output_data.pgtk->preferred_height = alloc.height; xg_wm_set_size_hint (f, 0, 0); @@ -1216,7 +1211,6 @@ pgtk_set_glyph_string_clipping (struct glyph_string *s, cairo_t * cr) } } - /* Set SRC's clipping for output of glyph string DST. This is called when we are drawing DST's left_overhang or right_overhang only in the area of SRC. */ @@ -1235,7 +1229,6 @@ pgtk_set_glyph_string_clipping_exactly (struct glyph_string *src, cairo_clip (cr); } - /* RIF: Compute left and right overhang of glyph string S. */ @@ -1276,9 +1269,8 @@ pgtk_compute_glyph_string_overhangs (struct glyph_string *s) } } - -/* Fill rectangle X, Y, W, H with background color of glyph string S. */ - +/* Fill rectangle X, Y, W, H with background color of glyph string + S. */ static void pgtk_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h) @@ -1288,7 +1280,6 @@ pgtk_clear_glyph_string_rect (struct glyph_string *s, int x, int y, || s->hl != DRAW_CURSOR)); } - static void fill_background_by_face (struct frame *f, struct face *face, int x, int y, int width, int height) @@ -1330,7 +1321,6 @@ fill_background (struct glyph_string *s, int x, int y, int width, int height) background even if it wouldn't be drawn normally. This is used when a string preceding S draws into the background of S, or S contains the first component of a composition. */ - static void pgtk_draw_glyph_string_background (struct glyph_string *s, bool force_p) { @@ -1383,7 +1373,6 @@ pgtk_draw_rectangle (struct frame *f, unsigned long color, int x, int y, } /* Draw the foreground of glyph string S. */ - static void pgtk_draw_glyph_string_foreground (struct glyph_string *s) { @@ -1430,7 +1419,6 @@ pgtk_draw_glyph_string_foreground (struct glyph_string *s) } /* Draw the foreground of composite glyph string S. */ - static void pgtk_draw_composite_glyph_string_foreground (struct glyph_string *s) { @@ -1521,7 +1509,6 @@ pgtk_draw_composite_glyph_string_foreground (struct glyph_string *s) /* Draw the foreground of glyph string S for glyphless characters. */ - static void pgtk_draw_glyphless_glyph_string_foreground (struct glyph_string *s) { @@ -1783,8 +1770,10 @@ pgtk_setup_relief_colors (struct glyph_string *s) color = s->xgcv.background; } - if (TRUE) + if (!di->relief_background_valid_p + || di->relief_background != color) { + di->relief_background_valid_p = true; di->relief_background = color; pgtk_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000, WHITE_PIX_DEFAULT (s->f)); @@ -1800,12 +1789,8 @@ pgtk_set_clip_rectangles (struct frame *f, cairo_t *cr, if (n > 0) { for (int i = 0; i < n; i++) - { - cairo_rectangle (cr, - rectangles[i].x, - rectangles[i].y, - rectangles[i].width, rectangles[i].height); - } + cairo_rectangle (cr, rectangles[i].x, rectangles[i].y, + rectangles[i].width, rectangles[i].height); cairo_clip (cr); } } @@ -1823,7 +1808,7 @@ pgtk_draw_relief_rect (struct frame *f, int left_x, int top_y, int right_x, int bottom_y, int hwidth, int vwidth, bool raised_p, bool top_p, bool bot_p, bool left_p, bool right_p, - XRectangle * clip_rect) + XRectangle *clip_rect) { unsigned long top_left_color, bottom_right_color; int corners = 0; @@ -2142,11 +2127,7 @@ pgtk_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) { if (s->stippled_p) - { - /* Fill background with a stipple pattern. */ - - fill_background (s, x, y, w, h); - } + fill_background (s, x, y, w, h); else pgtk_clear_glyph_string_rect (s, x, y, w, h); } @@ -2227,9 +2208,9 @@ pgtk_draw_image_foreground (struct glyph_string *s) if (s->hl == DRAW_CURSOR) { int relief = eabs (s->img->relief); - pgtk_draw_rectangle (s->f, s->xgcv.foreground, x - relief, y - relief, - s->slice.width + relief*2 - 1, - s->slice.height + relief*2 - 1, false); + pgtk_draw_rectangle (s->f, s->xgcv.foreground, x - relief, + y - relief, s->slice.width + relief * 2 - 1, + s->slice.height + relief * 2 - 1, false); } } pgtk_end_cr_clip (s->f); @@ -2278,23 +2259,21 @@ pgtk_draw_image_glyph_string (struct glyph_string *s) || s->img->pixmap == 0 || s->width != s->background_width) { - { - int x = s->x; - int y = s->y; - int width = s->background_width; + int x = s->x; + int y = s->y; + int width = s->background_width; - if (s->first_glyph->left_box_line_p - && s->slice.x == 0) - { - x += box_line_hwidth; - width -= box_line_hwidth; - } + if (s->first_glyph->left_box_line_p + && s->slice.x == 0) + { + x += box_line_hwidth; + width -= box_line_hwidth; + } - if (s->slice.y == 0) - y += box_line_vwidth; + if (s->slice.y == 0) + y += box_line_vwidth; - pgtk_draw_glyph_string_bg_rect (s, x, y, width, height); - } + pgtk_draw_glyph_string_bg_rect (s, x, y, width, height); s->background_filled_p = true; } @@ -2376,15 +2355,10 @@ pgtk_draw_stretch_glyph_string (struct glyph_string *s) pgtk_set_clip_rectangles (s->f, cr, &r, 1); if (s->face->stipple) - { - /* Fill background with a stipple pattern. */ - fill_background (s, x, y, w, h); - } + fill_background (s, x, y, w, h); else - { - pgtk_fill_rectangle (s->f, color, x, y, w, h, - true); - } + pgtk_fill_rectangle (s->f, color, x, y, w, h, + true); pgtk_end_cr_clip (s->f); } @@ -2402,6 +2376,7 @@ pgtk_draw_stretch_glyph_string (struct glyph_string *s) background_width -= text_left_x - x; x = text_left_x; } + if (background_width > 0) pgtk_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height); } @@ -2465,9 +2440,9 @@ pgtk_draw_glyph_string (struct glyph_string *s) /* We must clip just this glyph. left_overhang part has already drawn when s->prev was drawn, and right_overhang part will be drawn later when s->next is drawn. */ - pgtk_set_glyph_string_clipping_exactly (s, s, cr); + pgtk_set_glyph_string_clipping_exactly (s, s, cr); else - pgtk_set_glyph_string_clipping (s, cr); + pgtk_set_glyph_string_clipping (s, cr); switch (s->first_glyph->type) { @@ -2614,10 +2589,8 @@ pgtk_draw_glyph_string (struct glyph_string *s) pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, s->y + dy, s->width, h, false); else - { - pgtk_fill_rectangle (s->f, s->face->overline_color, s->x, - s->y + dy, s->width, h, false); - } + pgtk_fill_rectangle (s->f, s->face->overline_color, s->x, + s->y + dy, s->width, h, false); } /* Draw strike-through. */ @@ -2639,10 +2612,8 @@ pgtk_draw_glyph_string (struct glyph_string *s) pgtk_fill_rectangle (s->f, s->xgcv.foreground, s->x, glyph_y + dy, s->width, h, false); else - { - pgtk_fill_rectangle (s->f, s->face->strike_through_color, s->x, - glyph_y + dy, s->width, h, false); - } + pgtk_fill_rectangle (s->f, s->face->strike_through_color, s->x, + glyph_y + dy, s->width, h, false); } if (s->prev) @@ -2962,11 +2933,11 @@ pgtk_copy_bits (struct frame *f, cairo_rectangle_t *src_rect, cairo_t *cr; cairo_surface_t *surface; /* temporary surface */ - surface = - cairo_surface_create_similar (FRAME_CR_SURFACE (f), - CAIRO_CONTENT_COLOR_ALPHA, - (int) src_rect->width, - (int) src_rect->height); + surface + = cairo_surface_create_similar (FRAME_CR_SURFACE (f), + CAIRO_CONTENT_COLOR_ALPHA, + (int) src_rect->width, + (int) src_rect->height); cr = cairo_create (surface); cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), -src_rect->x, @@ -3186,10 +3157,9 @@ pgtk_bitmap_icon (struct frame *f, Lisp_Object file) } if (FRAME_DISPLAY_INFO (f)->bitmaps[bitmap_id - 1].img != NULL) - { - gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), - FRAME_DISPLAY_INFO (f)->bitmaps[bitmap_id - 1].img); - } + gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), + FRAME_DISPLAY_INFO (f)->bitmaps[bitmap_id - 1].img); + f->output_data.pgtk->icon_bitmap = bitmap_id; return false; @@ -3453,10 +3423,10 @@ pgtk_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd) { i = max_fringe_bmp; max_fringe_bmp = which + 20; - fringe_bmp = - (cairo_pattern_t **) xrealloc (fringe_bmp, - max_fringe_bmp * - sizeof (cairo_pattern_t *)); + fringe_bmp + = (cairo_pattern_t **) xrealloc (fringe_bmp, + max_fringe_bmp * + sizeof (cairo_pattern_t *)); while (i < max_fringe_bmp) fringe_bmp[i++] = 0; } @@ -3608,11 +3578,9 @@ pgtk_show_hourglass (struct frame *f) struct timespec ts = make_timespec (0, 50 * 1000 * 1000); if (hourglass_atimer != NULL) cancel_atimer (hourglass_atimer); - hourglass_atimer = - start_atimer (ATIMER_CONTINUOUS, ts, hourglass_cb, NULL); + hourglass_atimer + = start_atimer (ATIMER_CONTINUOUS, ts, hourglass_cb, NULL); } - - /* Cursor frequently stops animation. gtk's bug? */ } static void @@ -3706,83 +3674,85 @@ recover_from_visible_bell (struct atimer *timer) static void pgtk_flash (struct frame *f) { - { - if (!FRAME_CR_CONTEXT (f)) - return; + cairo_surface_t *surface_orig, *surface; + cairo_t *cr; + int width, height, flash_height, flash_left, flash_right; + struct timespec delay; - block_input (); + if (!FRAME_CR_CONTEXT (f)) + return; - cairo_surface_t *surface_orig = FRAME_CR_SURFACE (f); + block_input (); - int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f); - int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f); - cairo_surface_t *surface - = cairo_surface_create_similar (surface_orig, CAIRO_CONTENT_COLOR_ALPHA, - width, height); + surface_orig = FRAME_CR_SURFACE (f); - cairo_t *cr = cairo_create (surface); - cairo_set_source_surface (cr, surface_orig, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - cairo_clip (cr); - cairo_paint (cr); + width = FRAME_CR_SURFACE_DESIRED_WIDTH (f); + height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f); + surface = cairo_surface_create_similar (surface_orig, + CAIRO_CONTENT_COLOR_ALPHA, + width, height); - cairo_set_source_rgb (cr, 1, 1, 1); - cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE); + cr = cairo_create (surface); + cairo_set_source_surface (cr, surface_orig, 0, 0); + cairo_rectangle (cr, 0, 0, width, height); + cairo_clip (cr); + cairo_paint (cr); + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE); + + /* Get the height not including a menu bar widget. */ + height = FRAME_PIXEL_HEIGHT (f); + /* Height of each line to flash. */ + flash_height = FRAME_LINE_HEIGHT (f); + /* These will be the left and right margins of the rectangles. */ + flash_left = FRAME_INTERNAL_BORDER_WIDTH (f); + flash_right = (FRAME_PIXEL_WIDTH (f) + - FRAME_INTERNAL_BORDER_WIDTH (f)); + width = flash_right - flash_left; + + /* If window is tall, flash top and bottom line. */ + if (height > 3 * FRAME_LINE_HEIGHT (f)) + { + cairo_rectangle (cr, + flash_left, + (FRAME_INTERNAL_BORDER_WIDTH (f) + + FRAME_TOP_MARGIN_HEIGHT (f)), + width, flash_height); + cairo_fill (cr); + + cairo_rectangle (cr, + flash_left, + (height - flash_height + - FRAME_INTERNAL_BORDER_WIDTH (f)), + width, flash_height); + cairo_fill (cr); + } + else { - /* Get the height not including a menu bar widget. */ - int height = FRAME_PIXEL_HEIGHT (f); - /* Height of each line to flash. */ - int flash_height = FRAME_LINE_HEIGHT (f); - /* These will be the left and right margins of the rectangles. */ - int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f); - int flash_right = - FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f); - int width = flash_right - flash_left; - - /* If window is tall, flash top and bottom line. */ - if (height > 3 * FRAME_LINE_HEIGHT (f)) - { - cairo_rectangle (cr, - flash_left, - (FRAME_INTERNAL_BORDER_WIDTH (f) - + FRAME_TOP_MARGIN_HEIGHT (f)), - width, flash_height); - cairo_fill (cr); + /* If it is short, flash it all. */ + cairo_rectangle (cr, + flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), + width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); + cairo_fill (cr); + } - cairo_rectangle (cr, - flash_left, - (height - flash_height - - FRAME_INTERNAL_BORDER_WIDTH (f)), - width, flash_height); - cairo_fill (cr); - } - else - { - /* If it is short, flash it all. */ - cairo_rectangle (cr, - flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), - width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); - cairo_fill (cr); - } + FRAME_X_OUTPUT (f)->cr_surface_visible_bell = surface; - FRAME_X_OUTPUT (f)->cr_surface_visible_bell = surface; - { - struct timespec delay = make_timespec (0, 50 * 1000 * 1000); - if (FRAME_X_OUTPUT (f)->atimer_visible_bell != NULL) - { - cancel_atimer (FRAME_X_OUTPUT (f)->atimer_visible_bell); - FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL; - } - FRAME_X_OUTPUT (f)->atimer_visible_bell = - start_atimer (ATIMER_RELATIVE, delay, recover_from_visible_bell, f); - } + delay = make_timespec (0, 50 * 1000 * 1000); + if (FRAME_X_OUTPUT (f)->atimer_visible_bell != NULL) + { + cancel_atimer (FRAME_X_OUTPUT (f)->atimer_visible_bell); + FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL; } - cairo_destroy (cr); - unblock_input (); - } + FRAME_X_OUTPUT (f)->atimer_visible_bell + = start_atimer (ATIMER_RELATIVE, delay, recover_from_visible_bell, f); + + + cairo_destroy (cr); + unblock_input (); } /* Make audible bell. */ @@ -3863,8 +3833,9 @@ pgtk_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part, EVENT_INIT (inev.ie); - inev.ie.kind = - horizontal ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT : SCROLL_BAR_CLICK_EVENT; + inev.ie.kind = (horizontal + ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT + : SCROLL_BAR_CLICK_EVENT); inev.ie.frame_or_window = window; inev.ie.arg = Qnil; inev.ie.timestamp = 0; @@ -4013,8 +3984,6 @@ pgtk_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, xg_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole); } - - /* Create a scroll bar and return the scroll bar vector for it. W is the Emacs window on which to create the scroll bar. TOP, LEFT, WIDTH and HEIGHT are the pixel coordinates and dimensions of the @@ -4166,7 +4135,6 @@ pgtk_set_vertical_scroll_bar (struct window *w, int portion, int whole, wset_vertical_scroll_bar (w, barobj); } - static void pgtk_set_horizontal_scroll_bar (struct window *w, int portion, int whole, int position) @@ -4281,7 +4249,6 @@ pgtk_condemn_scroll_bars (struct frame *frame) } } - /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle. Note that WINDOW isn't necessarily condemned at all. */ @@ -4505,7 +4472,7 @@ pgtk_query_frame_background_color (struct frame *f, Emacs_Color * bgcolor) } static void -pgtk_free_pixmap (struct frame *_f, Emacs_Pixmap pixmap) +pgtk_free_pixmap (struct frame *f, Emacs_Pixmap pixmap) { if (pixmap) { @@ -4529,13 +4496,14 @@ pgtk_focus_frame (struct frame *f, bool noactivate) } } - static void -set_opacity_recursively (GtkWidget * w, gpointer data) +set_opacity_recursively (GtkWidget *w, gpointer data) { gtk_widget_set_opacity (w, *(double *) data); + if (GTK_IS_CONTAINER (w)) - gtk_container_foreach (GTK_CONTAINER (w), set_opacity_recursively, data); + gtk_container_foreach (GTK_CONTAINER (w), + set_opacity_recursively, data); } static void @@ -4571,22 +4539,13 @@ pgtk_set_frame_alpha (struct frame *f) static void frame_highlight (struct frame *f) { - /* We used to only do this if Vx_no_window_manager was non-nil, but - the ICCCM (section 4.1.6) says that the window's border pixmap - and border pixel are window attributes which are "private to the - client", so we can always change it to whatever we want. */ block_input (); - /* I recently started to get errors in this XSetWindowBorder, depending on - the window-manager in use, tho something more is at play since I've been - using that same window-manager binary for ever. Let's not crash just - because of this (bug#9310). */ - GtkWidget *w = FRAME_WIDGET (f); - char *css = - g_strdup_printf ("decoration { border: solid %dpx #%06x; }", - f->border_width, - (unsigned int) FRAME_X_OUTPUT (f)->border_pixel & 0x00ffffff); + char *css = g_strdup_printf ("decoration { border: solid %dpx #%06x; }", + f->border_width, + ((unsigned int) FRAME_X_OUTPUT (f)->border_pixel + & 0x00ffffff)); GtkStyleContext *ctxt = gtk_widget_get_style_context (w); GtkCssProvider *css_provider = gtk_css_provider_new (); @@ -4611,27 +4570,26 @@ frame_highlight (struct frame *f) static void frame_unhighlight (struct frame *f) { - /* We used to only do this if Vx_no_window_manager was non-nil, but - the ICCCM (section 4.1.6) says that the window's border pixmap - and border pixel are window attributes which are "private to the - client", so we can always change it to whatever we want. */ + GtkWidget *w; + char *css; + GtkStyleContext *ctxt; + GtkCssProvider *css_provider, *old; + block_input (); - /* Same as above for XSetWindowBorder (bug#9310). */ - GtkWidget *w = FRAME_WIDGET (f); + w = FRAME_WIDGET (f); - char *css = - g_strdup_printf ("decoration { border: dotted %dpx #ffffff; }", - f->border_width); + css = g_strdup_printf ("decoration { border: dotted %dpx #ffffff; }", + f->border_width); - GtkStyleContext *ctxt = gtk_widget_get_style_context (w); - GtkCssProvider *css_provider = gtk_css_provider_new (); + ctxt = gtk_widget_get_style_context (w); + css_provider = gtk_css_provider_new (); gtk_css_provider_load_from_data (css_provider, css, -1, NULL); gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); g_free (css); - GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider; + old = FRAME_X_OUTPUT (f)->border_color_css_provider; FRAME_X_OUTPUT (f)->border_color_css_provider = css_provider; if (old != NULL) { @@ -4685,10 +4643,8 @@ pgtk_frame_rehighlight_hook (struct frame *frame) pgtk_frame_rehighlight (FRAME_DISPLAY_INFO (frame)); } - /* Set whether or not the mouse pointer should be visible on frame F. */ - static void pgtk_toggle_invisible_pointer (struct frame *f, bool invisible) { @@ -4700,6 +4656,10 @@ pgtk_toggle_invisible_pointer (struct frame *f, bool invisible) gdk_window_set_cursor (gtk_widget_get_window (FRAME_GTK_WIDGET (f)), cursor); f->pointer_invisible = invisible; + + /* This is needed to make the pointer visible upon receiving a + motion notify event. */ + gdk_display_flush (FRAME_X_DISPLAY (f)); } /* The focus has changed. Update the frames as necessary to reflect @@ -4745,9 +4705,6 @@ pgtk_buffer_flipping_unblocked_hook (struct frame *f) static struct terminal * pgtk_create_terminal (struct pgtk_display_info *dpyinfo) -/* -------------------------------------------------------------------------- - Set up use of Gtk before we make the first connection. - -------------------------------------------------------------------------- */ { struct terminal *terminal; @@ -4772,7 +4729,7 @@ pgtk_create_terminal (struct pgtk_display_info *dpyinfo) terminal->menu_show_hook = pgtk_menu_show; terminal->activate_menubar_hook = pgtk_activate_menubar; terminal->popup_dialog_hook = pgtk_popup_dialog; - terminal->change_tab_bar_height_hook = x_change_tab_bar_height; + terminal->change_tab_bar_height_hook = pgtk_change_tab_bar_height; terminal->set_vertical_scroll_bar_hook = pgtk_set_vertical_scroll_bar; terminal->set_horizontal_scroll_bar_hook = pgtk_set_horizontal_scroll_bar; terminal->condemn_scroll_bars_hook = pgtk_condemn_scroll_bars; @@ -4793,7 +4750,7 @@ pgtk_create_terminal (struct pgtk_display_info *dpyinfo) = pgtk_set_scroll_bar_default_height; terminal->set_window_size_hook = pgtk_set_window_size; terminal->query_colors = pgtk_query_colors; - terminal->get_focus_frame = x_get_focus_frame; + terminal->get_focus_frame = pgtk_get_focus_frame; terminal->focus_frame_hook = pgtk_focus_frame; terminal->set_frame_offset_hook = pgtk_set_offset; terminal->free_pixmap = pgtk_free_pixmap; @@ -4812,7 +4769,7 @@ struct pgtk_window_is_of_frame_recursive_t }; static void -pgtk_window_is_of_frame_recursive (GtkWidget * widget, gpointer data) +pgtk_window_is_of_frame_recursive (GtkWidget *widget, gpointer data) { struct pgtk_window_is_of_frame_recursive_t *datap = data; @@ -4828,14 +4785,13 @@ pgtk_window_is_of_frame_recursive (GtkWidget * widget, gpointer data) return; } - if (GTK_IS_CONTAINER (widget)) { + if (GTK_IS_CONTAINER (widget)) gtk_container_foreach (GTK_CONTAINER (widget), pgtk_window_is_of_frame_recursive, datap); - } } static bool -pgtk_window_is_of_frame (struct frame *f, GdkWindow * window) +pgtk_window_is_of_frame (struct frame *f, GdkWindow *window) { struct pgtk_window_is_of_frame_recursive_t data; data.window = window; @@ -4848,7 +4804,7 @@ pgtk_window_is_of_frame (struct frame *f, GdkWindow * window) /* Like x_window_to_frame but also compares the window with the widget's windows. */ static struct frame * -pgtk_any_window_to_frame (GdkWindow * window) +pgtk_any_window_to_frame (GdkWindow *window) { Lisp_Object tail, frame; struct frame *f, *found = NULL; @@ -4973,7 +4929,7 @@ pgtk_clear_under_internal_border (struct frame *f) } static gboolean -pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data) +pgtk_handle_draw (GtkWidget *widget, cairo_t *cr, gpointer *data) { struct frame *f; @@ -4999,19 +4955,11 @@ pgtk_handle_draw (GtkWidget * widget, cairo_t * cr, gpointer * data) } static void -size_allocate (GtkWidget * widget, GtkAllocation * alloc, +size_allocate (GtkWidget *widget, GtkAllocation *alloc, gpointer user_data) { struct frame *f = pgtk_any_window_to_frame (gtk_widget_get_window (widget)); - /* Between a frame is created and not shown, size is allocated and - * this handler is called. When that, since the widget's window is - * NULL, we can't get f, pgtk_cr_update_surface_desired_size is not - * called, and its size is 0x0. That causes empty frame. - * - * Fortunately since we know f in pgtk_set_event_handler, we can get - * it through user_data; - */ if (!f) f = user_data; @@ -5118,7 +5066,7 @@ pgtk_emacs_to_gtk_modifiers (struct pgtk_display_info *dpyinfo, int state) void -pgtk_enqueue_string (struct frame *f, gchar * str) +pgtk_enqueue_string (struct frame *f, gchar *str) { gunichar *ustr, *uptr; @@ -5210,9 +5158,8 @@ key_press_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data) return TRUE; } - state |= - pgtk_emacs_to_gtk_modifiers (FRAME_DISPLAY_INFO (f), - extra_keyboard_modifiers); + state |= pgtk_emacs_to_gtk_modifiers (FRAME_DISPLAY_INFO (f), + extra_keyboard_modifiers); modifiers = state; /* This will have to go some day... */ @@ -5339,9 +5286,6 @@ key_press_event (GtkWidget *widget, GdkEvent *event, gpointer *user_data) || (orig_keysym & (1 << 28)) || (keysym != GDK_KEY_VoidSymbol && nbytes == 0)) && !(event->key.is_modifier - /* Gtk's modifier keys are different from Xlib's ones. - * I need to exclude them. - */ || IsModifierKey (orig_keysym) /* The symbols from GDK_KEY_ISO_Lock to GDK_KEY_ISO_Last_Group_Lock @@ -5795,17 +5739,14 @@ note_mouse_movement (struct frame *frame, } static gboolean -motion_notify_event (GtkWidget * widget, GdkEvent * event, - gpointer * user_data) +motion_notify_event (GtkWidget *widget, GdkEvent *event, + gpointer *user_data) { union buffered_input_event inev; struct frame *f, *frame; struct pgtk_display_info *dpyinfo; Mouse_HLInfo *hlinfo; - /* This is needed to make pointer visible when motion_notify event */ - pending_signals = true; - EVENT_INIT (inev.ie); inev.ie.kind = NO_EVENT; inev.ie.arg = Qnil; @@ -5827,6 +5768,7 @@ motion_notify_event (GtkWidget * widget, GdkEvent * event, if (f && xg_event_is_for_scrollbar (f, event, false)) f = 0; + if (f) { /* Maybe generate a SELECT_WINDOW_EVENT for @@ -5871,11 +5813,9 @@ motion_notify_event (GtkWidget * widget, GdkEvent * event, help_echo_string = previous_help_echo_string; } else - { - /* If we move outside the frame, then we're - certainly no longer on any text in the frame. */ - clear_mouse_face (hlinfo); - } + /* If we move outside the frame, then we're + certainly no longer on any text in the frame. */ + clear_mouse_face (hlinfo); /* If the contents of the global variable help_echo_string has changed, generate a HELP_EVENT. */ diff --git a/src/pgtkterm.h b/src/pgtkterm.h index 16fd688288..20c161e63b 100644 --- a/src/pgtkterm.h +++ b/src/pgtkterm.h @@ -392,6 +392,10 @@ struct pgtk_output They are changed only when a different background is involved. */ unsigned long relief_background; + /* Whether or not a relief background has been computed for this + frame. */ + bool_bf relief_background_valid_p : 1; + /* Keep track of focus. May be EXPLICIT if we received a FocusIn for this frame, or IMPLICIT if we received an EnterNotify. FocusOut and LeaveNotify clears EXPLICIT/IMPLICIT. */ @@ -566,11 +570,11 @@ extern void pgtk_iconify_frame (struct frame *f); extern void pgtk_focus_frame (struct frame *f, bool noactivate); extern void pgtk_set_scroll_bar_default_width (struct frame *f); extern void pgtk_set_scroll_bar_default_height (struct frame *f); -extern Lisp_Object x_get_focus_frame (struct frame *frame); +extern Lisp_Object pgtk_get_focus_frame (struct frame *frame); extern void pgtk_frame_rehighlight (struct pgtk_display_info *dpyinfo); -extern void x_change_tab_bar_height (struct frame *, int); +extern void pgtk_change_tab_bar_height (struct frame *, int); extern struct pgtk_display_info *check_pgtk_display_info (Lisp_Object object); commit d4e3e548f5519e98c2fc842daf73a6acac7faa70 Author: Po Lu Date: Wed Apr 27 08:07:39 2022 +0000 Remove some unnecessary code * src/haiku_support.cc (class EmacsView, AfterResize) (SetUpDoubleBuffering): Remove `cspace' field since it's always RGBA32. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index b2edcd3099..6dea2d3620 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1410,8 +1410,6 @@ class EmacsView : public BView BPoint tt_absl_pos; BMessage *wait_for_release_message = NULL; - color_space cspace; - EmacsView () : BView (BRect (0, 0, 0, 0), "Emacs", B_FOLLOW_NONE, B_WILL_DRAW) { @@ -1434,12 +1432,6 @@ class EmacsView : public BView grab_view_locker.Unlock (); } - void - AttachedToWindow (void) - { - cspace = B_RGBA32; - } - void MessageReceived (BMessage *msg) { @@ -1551,7 +1543,7 @@ class EmacsView : public BView #endif offscreen_draw_view->RemoveSelf (); delete offscreen_draw_bitmap_1; - offscreen_draw_bitmap_1 = new BBitmap (Frame (), cspace, 1); + offscreen_draw_bitmap_1 = new BBitmap (Frame (), B_RGBA32, 1); if (offscreen_draw_bitmap_1->InitCheck () != B_OK) gui_abort ("Offscreen draw bitmap initialization failed"); @@ -1659,7 +1651,7 @@ class EmacsView : public BView if (offscreen_draw_view) gui_abort ("Failed to lock offscreen view setting up double buffering"); - offscreen_draw_bitmap_1 = new BBitmap (Frame (), cspace, 1); + offscreen_draw_bitmap_1 = new BBitmap (Frame (), B_RGBA32, 1); if (offscreen_draw_bitmap_1->InitCheck () != B_OK) gui_abort ("Failed to init offscreen bitmap"); #ifdef USE_BE_CAIRO commit 1e0c4883b7e26f93c0e5b8e745a055b7682c653a Author: Juri Linkov Date: Wed Apr 27 10:36:41 2022 +0300 * lisp/help-fns.el (help-fns--insert-menu-bindings): Don't highlight heading. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 67045bb4d6..9a6225d858 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -595,7 +595,7 @@ the C sources, too." (when-let ((elem (assq entry (cdr map)))) (when heading (insert heading) - (setq heading nil)) + (setq heading nil start (point))) (when (> level 0) (insert (if (char-displayable-p ?→) commit 3abb3681b57d7c8ca7fa808addb0a10b6b109cab Author: Paul Eggert Date: Wed Apr 27 00:29:26 2022 -0700 Use org-time-convert-to-integer instead of by hand * lisp/org/org-macs.el (org-file-newer-than-p): Don’t assume list-format timestamps, by using org-time-convert-to-integer instead of doing it by hand. diff --git a/lisp/org/org-macs.el b/lisp/org/org-macs.el index b10725bd52..92591b5bb7 100644 --- a/lisp/org/org-macs.el +++ b/lisp/org/org-macs.el @@ -257,15 +257,16 @@ ignored in this case." (defun org-file-newer-than-p (file time) "Non-nil if FILE is newer than TIME. -FILE is a filename, as a string, TIME is a list of integers, as +FILE is a filename, as a string, TIME is a Lisp time value, as returned by, e.g., `current-time'." (and (file-exists-p file) ;; Only compare times up to whole seconds as some file-systems ;; (e.g. HFS+) do not retain any finer granularity. As ;; a consequence, make sure we return non-nil when the two ;; times are equal. - (not (time-less-p (cl-subseq (nth 5 (file-attributes file)) 0 2) - (cl-subseq time 0 2))))) + (not (time-less-p (org-time-convert-to-integer + (nth 5 (file-attributes file))) + (org-time-convert-to-integer time))))) (defun org-compile-file (source process ext &optional err-msg log-buf spec) "Compile a SOURCE file using PROCESS.