commit 2ab73286b7a58eb983da21bca8b781ec884eb996 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Thu Jan 6 15:50:52 2022 +0800 Add group to xkey state before filtering it on XI_KeyRelease * src/xterm.c (handle_one_xevent): Add group to xkey.state before filtering an XI2 key release event. This fixes fcitx on some systems. diff --git a/src/xterm.c b/src/xterm.c index ad6652fb33..ff6c71283e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -10998,7 +10998,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, xkey.root = xev->root; xkey.subwindow = xev->child; xkey.time = xev->time; - xkey.state = xev->mods.effective; + xkey.state = ((xev->mods.effective & ~(1 << 13 | 1 << 14)) + | (xev->group.effective << 13)); xkey.keycode = xev->detail; xkey.same_screen = True; commit 3b1164de0ed126686977e8688f2e09268cb74e4d Author: Po Lu Date: Thu Jan 6 14:10:52 2022 +0800 Fix GNUstep compilation warnings * src/Makefile.in (NON_OBJC_CFLAGS): Add `-Wnested-externs'. * src/emacs.c (load_pdump): Only define exec_bufsize if !NS_SELF_CONTAINED. * src/image.c (ARGB_TO_ULONG): Don't define if HAVE_NS. * src/nsterm.m (ns_destroy_window): Pacify incorrect GCC warning. (ns_query_color): Make static. (ns_run_loop_break): Fix old-style definition. ([EmacsView toggleFullScreen:]): Remove unused variable. diff --git a/src/Makefile.in b/src/Makefile.in index 83210b1317..04fabd5f42 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -379,7 +379,7 @@ pdmp := endif # Flags that might be in WARN_CFLAGS but are not valid for Objective C. -NON_OBJC_CFLAGS = -Wignored-attributes -Wignored-qualifiers -Wopenmp-simd +NON_OBJC_CFLAGS = -Wignored-attributes -Wignored-qualifiers -Wopenmp-simd -Wnested-externs # Ditto, but for C++. NON_CXX_CFLAGS = -Wmissing-prototypes -Wnested-externs -Wold-style-definition \ -Wstrict-prototypes -Wno-override-init diff --git a/src/emacs.c b/src/emacs.c index 3b708db779..f6e2c01ee7 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -875,9 +875,14 @@ load_pdump (int argc, char **argv) } /* Where's our executable? */ - ptrdiff_t bufsize, exec_bufsize; + ptrdiff_t bufsize; +#ifndef NS_SELF_CONTAINED + ptrdiff_t exec_bufsize; +#endif emacs_executable = load_pdump_find_executable (argv[0], &bufsize); +#ifndef NS_SELF_CONTAINED exec_bufsize = bufsize; +#endif /* If we couldn't find our executable, go straight to looking for the dump in the hardcoded location. */ diff --git a/src/image.c b/src/image.c index 439348759f..e7d347b782 100644 --- a/src/image.c +++ b/src/image.c @@ -82,7 +82,9 @@ typedef struct x_bitmap_record Bitmap_Record; #if defined(USE_CAIRO) || defined(HAVE_NS) #define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) +#ifndef HAVE_NS #define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) +#endif #define RED_FROM_ULONG(color) (((color) >> 16) & 0xff) #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff) #define BLUE_FROM_ULONG(color) ((color) & 0xff) diff --git a/src/nsterm.m b/src/nsterm.m index 382aa57a12..428d1a2fe2 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1617,10 +1617,17 @@ Hide the window (X11 semantics) /* If this frame has a parent window, detach it as not doing so can cause a crash in GNUStep. */ - if (FRAME_PARENT_FRAME (f) != NULL) + if (FRAME_PARENT_FRAME (f)) { NSWindow *child = [FRAME_NS_VIEW (f) window]; - NSWindow *parent = [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window]; + NSWindow *parent; + + /* Pacify a incorrect GCC warning about FRAME_PARENT_FRAME (f) + being NULL. */ + if (FRAME_PARENT_FRAME (f)) + parent = [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window]; + else + emacs_abort (); [parent removeChildWindow: child]; } @@ -2086,8 +2093,8 @@ Hide the window (X11 semantics) return 1; } -void -ns_query_color(void *col, Emacs_Color *color_def) +static void +ns_query_color (void *col, Emacs_Color *color_def) /* -------------------------------------------------------------------------- Get ARGB values out of NSColor col and put them into color_def and set color_def pixel to the ARGB color. @@ -4481,7 +4488,7 @@ in certain situations (rapid incoming events). #ifdef HAVE_PTHREAD void -ns_run_loop_break () +ns_run_loop_break (void) /* Break out of the NS run loop in ns_select or ns_read_socket. */ { NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_run_loop_break"); @@ -7565,7 +7572,7 @@ - (void)toggleFullScreen: (id)sender EmacsWindow *w, *fw; BOOL onFirstScreen; struct frame *f; - NSRect r, wr; + NSRect r; NSColor *col; NSTRACE ("[EmacsView toggleFullScreen:]"); @@ -7584,7 +7591,6 @@ - (void)toggleFullScreen: (id)sender w = (EmacsWindow *)[self window]; onFirstScreen = [[w screen] isEqual:[[NSScreen screens] objectAtIndex:0]]; f = emacsframe; - wr = [w frame]; col = [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (FACE_FROM_ID (f, DEFAULT_FACE_ID))]; commit e882dd48e3c3d6aa443383016c36f53683cd3048 Author: Po Lu Date: Thu Jan 6 14:02:43 2022 +0800 Fix duplicate overhang display on GNUstep * src/nsfont.m (nsfont_draw): Stop saving DPS clip and remove workaround for bad clipping. * src/nsterm.m (ns_draw_glyph_string): Clip to glyph string rect when displaying overhangs. diff --git a/src/nsfont.m b/src/nsfont.m index d4ea4fa504..f3c8a82930 100644 --- a/src/nsfont.m +++ b/src/nsfont.m @@ -1222,22 +1222,10 @@ is false when (FROM > 0 || TO < S->nchars). */ /* render under GNUstep using DPS */ { NSGraphicsContext *context = [NSGraphicsContext currentContext]; - DPSgsave (context); - if (s->clip_head) - { - DPSrectclip (context, s->clip_head->x, 0, - FRAME_PIXEL_WIDTH (s->f), - FRAME_PIXEL_HEIGHT (s->f)); - } [font->nsfont set]; - [col set]; - DPSmoveto (context, r.origin.x, r.origin.y); GSShowGlyphs (context, c, len); - DPSstroke (context); - - DPSgrestore (context); } unblock_input (); diff --git a/src/nsterm.m b/src/nsterm.m index 41c311e04d..382aa57a12 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -4063,19 +4063,22 @@ Function modeled after x_draw_glyph_string_box (). /* As prev was drawn while clipped to its own area, we must draw the right_overhang part using s->hl now. */ enum draw_glyphs_face save = prev->hl; - struct face *save_face = prev->face; - prev->face = s->face; + prev->hl = s->hl; NSRect r = NSMakeRect (s->x, s->y, s->width, s->height); + NSRect rc; + get_glyph_string_clip_rect (s, &rc); [[NSGraphicsContext currentContext] saveGraphicsState]; NSRectClip (r); + if (n) + NSRectClip (rc); #ifdef NS_IMPL_GNUSTEP DPSgsave ([NSGraphicsContext currentContext]); DPSrectclip ([NSGraphicsContext currentContext], s->x, s->y, s->width, s->height); + DPSrectclip ([NSGraphicsContext currentContext], NSMinX (rc), + NSMinY (rc), NSWidth (rc), NSHeight (rc)); #endif - prev->num_clips = 1; - prev->hl = s->hl; if (prev->first_glyph->type == CHAR_GLYPH) ns_draw_glyph_string_foreground (prev); else @@ -4085,8 +4088,6 @@ Function modeled after x_draw_glyph_string_box (). #endif [[NSGraphicsContext currentContext] restoreGraphicsState]; prev->hl = save; - prev->face = save_face; - prev->num_clips = 0; } ns_unfocus (s->f); } @@ -4103,19 +4104,21 @@ Function modeled after x_draw_glyph_string_box (). /* As next will be drawn while clipped to its own area, we must draw the left_overhang part using s->hl now. */ enum draw_glyphs_face save = next->hl; - struct face *save_face = next->face; next->hl = s->hl; - next->face = s->face; NSRect r = NSMakeRect (s->x, s->y, s->width, s->height); + NSRect rc; + get_glyph_string_clip_rect (s, &rc); [[NSGraphicsContext currentContext] saveGraphicsState]; NSRectClip (r); + NSRectClip (rc); #ifdef NS_IMPL_GNUSTEP DPSgsave ([NSGraphicsContext currentContext]); DPSrectclip ([NSGraphicsContext currentContext], s->x, s->y, s->width, s->height); + DPSrectclip ([NSGraphicsContext currentContext], NSMinX (rc), + NSMinY (rc), NSWidth (rc), NSHeight (rc)); #endif - next->num_clips = 1; if (next->first_glyph->type == CHAR_GLYPH) ns_draw_glyph_string_foreground (next); else @@ -4125,10 +4128,7 @@ Function modeled after x_draw_glyph_string_box (). #endif [[NSGraphicsContext currentContext] restoreGraphicsState]; next->hl = save; - next->num_clips = 0; - next->face = save_face; - next->clip_head = next; - next->background_filled_p = 0; + next->clip_head = s->next; } ns_unfocus (s->f); } commit 5749c57e473808b589a615ac4e4e7f7eef8da949 Author: Po Lu Date: Thu Jan 6 09:45:20 2022 +0800 * src/xterm.c (handle_one_xevent): Check for errors when kbd map. diff --git a/src/xterm.c b/src/xterm.c index 8202e8fb00..ad6652fb33 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -11253,15 +11253,22 @@ handle_one_xevent (struct x_display_info *dpyinfo, { if (dpyinfo->xkb_desc) { - XkbGetUpdatedMap (dpyinfo->display, - (XkbKeySymsMask - | XkbKeyTypesMask - | XkbModifierMapMask - | XkbVirtualModsMask), - dpyinfo->xkb_desc); - XkbGetNames (dpyinfo->display, - XkbGroupNamesMask | XkbVirtualModNamesMask, - dpyinfo->xkb_desc); + if (XkbGetUpdatedMap (dpyinfo->display, + (XkbKeySymsMask + | XkbKeyTypesMask + | XkbModifierMapMask + | XkbVirtualModsMask), + dpyinfo->xkb_desc) == Success) + { + XkbGetNames (dpyinfo->display, + XkbGroupNamesMask | XkbVirtualModNamesMask, + dpyinfo->xkb_desc); + } + else + { + XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True); + dpyinfo->xkb_desc = NULL; + } x_find_modifier_meanings (dpyinfo); } commit 61f8f7f68f3bac5dc7ab41532902c480417552d8 Author: Stefan Monnier Date: Wed Jan 5 14:28:08 2022 -0500 cl-generic.el: Fix bug#46722 Fix longstanding bug due to unexpected interference via side-effect. * lisp/emacs-lisp/cl-generic.el (cl--generic-get-dispatcher): Copy the `dispatch` arg before storing it into the hash-table. diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 983694204d..5090e06037 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -604,7 +604,9 @@ The set of acceptable TYPEs (also called \"specializers\") is defined (defun cl--generic-get-dispatcher (dispatch) (with-memoization - (gethash dispatch cl--generic-dispatchers) + ;; We need `copy-sequence` here because this `dispatch' object might be + ;; modified by side-effect in `cl-generic-define-method' (bug#46722). + (gethash (copy-sequence dispatch) cl--generic-dispatchers) ;; (message "cl--generic-get-dispatcher (%S)" dispatch) (let* ((dispatch-arg (car dispatch)) (generalizers (cdr dispatch)) commit 2b59a425832f6f89bb6b1267812711bfcc7a16cd Author: Juri Linkov Date: Wed Jan 5 20:47:20 2022 +0200 * lisp/textmodes/paragraphs.el (repunctuate-sentences): Use filter variable. (repunctuate-sentences-filter): Reimplement without using match data. (repunctuate-sentences-filter): New variable. (repunctuate-sentences): Use new variable. Remove regexp group from spaces as was before. https://lists.gnu.org/archive/html/emacs-devel/2022-01/msg00395.html diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el index fc10a0dd1b..7daf71e990 100644 --- a/lisp/textmodes/paragraphs.el +++ b/lisp/textmodes/paragraphs.el @@ -481,23 +481,27 @@ sentences. Also, every paragraph boundary terminates sentences as well." (defun repunctuate-sentences-filter (_start _end) "Search filter used by `repunctuate-sentences' to skip unneeded spaces. -By default, it skips occurrences that already have two spaces. -It is advised to put `advice-add' on this function to add more filters, +By default, it skips occurrences that already have two spaces." + (/= 2 (- (point) (save-excursion (skip-chars-backward " ") (point))))) + +(defvar repunctuate-sentences-filter #'repunctuate-sentences-filter + "The default filter used by `repunctuate-sentences'. +It is advised to use `add-function' on this to add more filters, for example, `(looking-back (rx (or \"e.g.\" \"i.e.\") \" \") 5)' -with a set of predefined abbreviations to skip from adding two spaces." - (not (length= (match-string 4) 2))) +with a set of predefined abbreviations to skip from adding two spaces.") (defun repunctuate-sentences (&optional no-query start end) "Put two spaces at the end of sentences from point to the end of buffer. It works using `query-replace-regexp'. In Transient Mark mode, if the mark is active, operate on the contents of the region. Second and third arg START and END specify the region to operate on. -If optional argument NO-QUERY is non-nil, make changes without -asking for confirmation." +If optional argument NO-QUERY is non-nil, make changes without asking +for confirmation. You can use `repunctuate-sentences-filter' to add +filters to skip occurrences of spaces that don't need to be replaced." (interactive (list nil (if (use-region-p) (region-beginning)) (if (use-region-p) (region-end)))) - (let ((regexp "\\([]\"')]?\\)\\([.?!]\\)\\([]\"')]?\\)\\( +\\)") + (let ((regexp "\\([]\"')]?\\)\\([.?!]\\)\\([]\"')]?\\) +") (to-string "\\1\\2\\3 ")) (if no-query (progn @@ -507,10 +511,10 @@ asking for confirmation." (unwind-protect (progn (add-function :after-while isearch-filter-predicate - #'repunctuate-sentences-filter) + repunctuate-sentences-filter) (query-replace-regexp regexp to-string nil start end)) (remove-function isearch-filter-predicate - #'repunctuate-sentences-filter))))) + repunctuate-sentences-filter))))) (defun backward-sentence (&optional arg) commit 0a51652f6dcf62c598bde9bece5639e09966dbb5 Author: Lars Ingebrigtsen Date: Wed Jan 5 17:07:07 2022 +0100 Fix typo in cvs-status-mode-map keymap * lisp/vc/cvs-status.el (cvs-status-mode-map): Fix typo in keymap definition. diff --git a/lisp/vc/cvs-status.el b/lisp/vc/cvs-status.el index e0168f1e6d..7f921a7339 100644 --- a/lisp/vc/cvs-status.el +++ b/lisp/vc/cvs-status.el @@ -30,12 +30,11 @@ (require 'cl-lib) (require 'pcvs) -(require 'easy-mmode) ;;; (defvar-keymap cvs-status-mode-map - :parent 'cvs-mode-map + :parent cvs-mode-map "n" #'next-line "p" #'previous-line "N" #'cvs-status-next commit fab840e381db8b5fd226f59d976abd3e4f16bec4 Author: Stefan Kangas Date: Wed Jan 5 14:54:24 2022 +0100 ; * lisp/buff-menu.el (Buffer-menu-mode-map): Fix warning. diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index ee503846d0..50c2c155ca 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -150,7 +150,7 @@ commands.") "M-s a C-o" #'Buffer-menu-multi-occur "" #'Buffer-menu-mouse-select - "" #'mouse-face) + "" 'mouse-face) (easy-menu-define Buffer-menu-mode-menu Buffer-menu-mode-map "Menu for `Buffer-menu-mode' buffers." commit bb0c197b77e04258ebba7bb989a2357740bfa28d Author: Eli Zaretskii Date: Wed Jan 5 15:14:54 2022 +0200 ; Fix typo in last change. diff --git a/lisp/info-look.el b/lisp/info-look.el index 00c06003c2..64f16df4dc 100644 --- a/lisp/info-look.el +++ b/lisp/info-look.el @@ -397,7 +397,7 @@ ITEM is the item whose documentation to search: file name if TOPIC is `file', a symbol if TOPIC is `symbol', etc. MODE is the `major-mode' whose Info manuals to search for documentation of ITEM; if it's nil, the function uses `info-lookup-file-name-alist' -andthe current buffer's file name to guess the mode.." +and the current buffer's file name to guess the mode.." (or mode (setq mode (info-lookup-select-mode))) (setq mode (info-lookup--item-to-mode item mode)) (if-let ((info (info-lookup->mode-value topic mode))) commit 82959661e5816d27c9650c61768d98b0bd248d3a Author: Eli Zaretskii Date: Wed Jan 5 15:11:24 2022 +0200 Fix info-lookup docs and "C-h S" in major-modes with no manuals * lisp/info-look.el (info-lookup-alist, info-lookup-add-help) (info-lookup-symbol, info-lookup-file, info-lookup) (info-lookup-interactive-arguments): Clarify and expand the doc strings. (info-lookup-change-mode): Topic values can have their `:mode' as a cons cell, not just a mode's symbol; support that. diff --git a/lisp/info-look.el b/lisp/info-look.el index e6f267d4ed..00c06003c2 100644 --- a/lisp/info-look.el +++ b/lisp/info-look.el @@ -94,7 +94,10 @@ HELP-DATA is a HELP-TOPIC's public data set. (HELP-MODE REGEXP IGNORE-CASE DOC-SPEC PARSE-RULE OTHER-MODES) -HELP-MODE is a mode's symbol. +HELP-MODE is either a mode's symbol, or a cons cell of the +form (HELP-MODE . SYMBOL-PREFIX), where SYMBOL-PREFIX is the +prefix (the part up to the first dash) of names of symbols whose +documentation is specified by DOC-SPEC. REGEXP is a regular expression matching those help items whose documentation can be looked up via DOC-SPEC. IGNORE-CASE is non-nil if help items are case insensitive. @@ -159,8 +162,10 @@ KEYWORD is either `:topic', `:mode', `:regexp', `:ignore-case', doing so at load time, this is done when the user asks for info on the mode in question. -ARGUMENT has a value as explained in the documentation of the - variable `info-lookup-alist'. +ARGUMENT is the value corresponding to KEYWORD. The meaning of the values +is explained in the documentation of the variable `info-lookup-alist': for +example, the value corresponding to `:topic' is documented as HELP-TOPIC, +the value of `:mode' as HELP-MODE, etc.. If no topic or mode option has been specified, then the help topic defaults to `symbol', and the help mode defaults to the current major mode." @@ -276,14 +281,19 @@ system." ;;;###autoload (put 'info-lookup-symbol 'info-file "emacs") ;;;###autoload (defun info-lookup-symbol (symbol &optional mode) - "Display the definition of SYMBOL, as found in the relevant manual. -When this command is called interactively, it reads SYMBOL from the -minibuffer. In the minibuffer, use \\\ -\\[next-history-element] to yank the default argument -value into the minibuffer so you can edit it. The default symbol is the -one found at point. - -With prefix arg MODE a query for the symbol help mode is offered." + "Look up and display documentation of SYMBOL in the relevant Info manual. +SYMBOL should be an identifier: a function or method, a macro, a variable, +a data type, a class, etc. + +Interactively, prompt for SYMBOL; you can use \\\\[next-history-element] in the minibuffer +to yank the default argument value into the minibuffer so you can edit it. +The default symbol is the one found at point. + +MODE is the major mode whose Info manuals to search for the documentation +of SYMBOL. It defaults to the current buffer's `major-mode'; if that +mode doesn't have any Info manuals known to Emacs, the command will +prompt for MODE to use, with completion. With prefix arg, the command +always prompts for MODE." (interactive (info-lookup-interactive-arguments 'symbol current-prefix-arg)) (info-lookup 'symbol symbol mode)) @@ -291,20 +301,28 @@ With prefix arg MODE a query for the symbol help mode is offered." ;;;###autoload (put 'info-lookup-file 'info-file "emacs") ;;;###autoload (defun info-lookup-file (file &optional mode) - "Display the documentation of a file. -When this command is called interactively, it reads FILE from the minibuffer. -In the minibuffer, use \\\ -\\[next-history-element] to yank the default file name -into the minibuffer so you can edit it. + "Look up and display documentation of FILE in the relevant Info manual. +FILE should be the name of a file; a notable example is a standard header +file that is part of the C or C++ standard library. + +Interactively, prompt for FILE; you can use \\\\[next-history-element] in the minibuffer +to yank the default argument value into the minibuffer so you can edit it. The default file name is the one found at point. -With prefix arg MODE a query for the file help mode is offered." +MODE is the major mode whose Info manuals to search for the documentation +of FILE. It defaults to the current buffer's `major-mode'; if that +mode doesn't have any Info manuals known to Emacs, the command will +prompt for MODE to use, with completion. With prefix arg, the command +always prompts for MODE." (interactive (info-lookup-interactive-arguments 'file current-prefix-arg)) (info-lookup 'file file mode)) (defun info-lookup-interactive-arguments (topic &optional query) - "Read and return argument value (and help mode) for help topic TOPIC. + "Read and return argument value (and help mode) for help TOPIC. +TOPIC should be any known symbol of a help topic, such as `file' +or `symbol'. See the documentation of HELP-TOPIC in the doc +string of `info-lookup-alist'. If optional argument QUERY is non-nil, query for the help mode." (let* ((mode (cond (query (info-lookup-change-mode topic)) @@ -347,7 +365,10 @@ If optional argument QUERY is non-nil, query for the help mode." (defun info-lookup-change-mode (topic) (let* ((completions (mapcar (lambda (arg) - (cons (symbol-name (car arg)) (car arg))) + (let ((mode-spec (car arg))) + (and (consp mode-spec) + (setq mode-spec (car mode-spec))) + (cons (symbol-name mode-spec) mode-spec))) (info-lookup->topic-value topic))) (mode (completing-read (format "Use %s help mode: " topic) @@ -368,7 +389,15 @@ If optional argument QUERY is non-nil, query for the help mode." mode))) (defun info-lookup (topic item mode) - "Display the documentation of a help item." + "Display the documentation of TOPIC whose name is ITEM, using MODE's manuals. +TOPIC should be any known symbol of a help topic type, such as `file' +or `symbol'. See the documentation of HELP-TOPIC in the doc +string of `info-lookup-alist'. +ITEM is the item whose documentation to search: file name if +TOPIC is `file', a symbol if TOPIC is `symbol', etc. +MODE is the `major-mode' whose Info manuals to search for documentation +of ITEM; if it's nil, the function uses `info-lookup-file-name-alist' +andthe current buffer's file name to guess the mode.." (or mode (setq mode (info-lookup-select-mode))) (setq mode (info-lookup--item-to-mode item mode)) (if-let ((info (info-lookup->mode-value topic mode))) commit ed7c6d687306a69cb31154e9251c6b1d8af62de5 Author: Po Lu Date: Wed Jan 5 12:02:32 2022 +0000 Enable subpixel antialiasing on the Cairo font driver on Haiku * src/ftcrfont.c (ftcrfont_open): Manually enable subpixel antialiasing on Haiku. * src/haiku_support.cc (get_subpixel_antialiasing): New function declaration. (be_use_subpixel_antialising): * src/haiku_support.h (be_use_subpixel_antialising): New functions. diff --git a/src/ftcrfont.c b/src/ftcrfont.c index 337e804b89..558e44d5b9 100644 --- a/src/ftcrfont.c +++ b/src/ftcrfont.c @@ -169,6 +169,10 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size) cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size); cairo_matrix_init_identity (&ctm); cairo_font_options_t *options = cairo_font_options_create (); +#ifdef USE_BE_CAIRO + if (be_use_subpixel_antialiasing ()) + cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_SUBPIXEL); +#endif cairo_scaled_font_t *scaled_font = cairo_scaled_font_create (font_face, &font_matrix, &ctm, options); cairo_font_face_destroy (font_face); diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 40f37d577e..2e9eff4067 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -112,6 +112,10 @@ static BLocker child_frame_lock; static BLocker movement_locker; +/* This could be a private API, but it's used by (at least) the Qt + port, so it's probably here to stay. */ +extern status_t get_subpixel_antialiasing (bool *); + extern "C" { extern _Noreturn void emacs_abort (void); @@ -3043,3 +3047,14 @@ BWindow_is_active (void *window) BWindow *w = (BWindow *) window; return w->IsActive (); } + +bool +be_use_subpixel_antialiasing (void) +{ + bool current_subpixel_antialiasing; + + if (get_subpixel_antialiasing (¤t_subpixel_antialiasing) != B_OK) + return false; + + return current_subpixel_antialiasing; +} diff --git a/src/haiku_support.h b/src/haiku_support.h index 550ebd0050..6a99eb245d 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -853,6 +853,9 @@ extern "C" extern bool BWindow_is_active (void *window); + extern bool + be_use_subpixel_antialiasing (void); + #ifdef __cplusplus extern void * find_appropriate_view_for_draw (void *vw); commit 83e346b70a47091ecd6eb526935abfd0db6c7cf3 Author: Stefan Kangas Date: Wed Jan 5 12:07:10 2022 +0100 * lisp/buff-menu.el (Buffer-menu-mode-map): Use defvar-keymap. diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index 59040371c9..ee503846d0 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -116,43 +116,41 @@ as it is by default." This is set by the prefix argument to `buffer-menu' and related commands.") -(defvar Buffer-menu-mode-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map tabulated-list-mode-map) - (define-key map "v" 'Buffer-menu-select) - (define-key map "2" 'Buffer-menu-2-window) - (define-key map "1" 'Buffer-menu-1-window) - (define-key map "f" 'Buffer-menu-this-window) - (define-key map "e" 'Buffer-menu-this-window) - (define-key map "\C-m" 'Buffer-menu-this-window) - (define-key map "o" 'Buffer-menu-other-window) - (define-key map "\C-o" 'Buffer-menu-switch-other-window) - (define-key map "s" 'Buffer-menu-save) - (define-key map "d" 'Buffer-menu-delete) - (define-key map "k" 'Buffer-menu-delete) - (define-key map "\C-k" 'Buffer-menu-delete) - (define-key map "\C-d" 'Buffer-menu-delete-backwards) - (define-key map "x" 'Buffer-menu-execute) - (define-key map " " 'next-line) - (define-key map "\177" 'Buffer-menu-backup-unmark) - (define-key map "~" 'Buffer-menu-not-modified) - (define-key map "u" 'Buffer-menu-unmark) - (define-key map "\M-\177" 'Buffer-menu-unmark-all-buffers) - (define-key map "U" 'Buffer-menu-unmark-all) - (define-key map "m" 'Buffer-menu-mark) - (define-key map "t" 'Buffer-menu-visit-tags-table) - (define-key map "%" 'Buffer-menu-toggle-read-only) - (define-key map "b" 'Buffer-menu-bury) - (define-key map "V" 'Buffer-menu-view) - (define-key map "T" 'Buffer-menu-toggle-files-only) - (define-key map (kbd "M-s a C-s") 'Buffer-menu-isearch-buffers) - (define-key map (kbd "M-s a M-C-s") 'Buffer-menu-isearch-buffers-regexp) - (define-key map (kbd "M-s a C-o") 'Buffer-menu-multi-occur) - - (define-key map [mouse-2] 'Buffer-menu-mouse-select) - (define-key map [follow-link] 'mouse-face) - map) - "Local keymap for `Buffer-menu-mode' buffers.") +(defvar-keymap Buffer-menu-mode-map + :doc "Local keymap for `Buffer-menu-mode' buffers." + :parent tabulated-list-mode-map + "v" #'Buffer-menu-select + "2" #'Buffer-menu-2-window + "1" #'Buffer-menu-1-window + "f" #'Buffer-menu-this-window + "e" #'Buffer-menu-this-window + "C-m" #'Buffer-menu-this-window + "o" #'Buffer-menu-other-window + "C-o" #'Buffer-menu-switch-other-window + "s" #'Buffer-menu-save + "d" #'Buffer-menu-delete + "k" #'Buffer-menu-delete + "C-k" #'Buffer-menu-delete + "C-d" #'Buffer-menu-delete-backwards + "x" #'Buffer-menu-execute + "SPC" #'next-line + "DEL" #'Buffer-menu-backup-unmark + "~" #'Buffer-menu-not-modified + "u" #'Buffer-menu-unmark + "M-DEL" #'Buffer-menu-unmark-all-buffers + "U" #'Buffer-menu-unmark-all + "m" #'Buffer-menu-mark + "t" #'Buffer-menu-visit-tags-table + "%" #'Buffer-menu-toggle-read-only + "b" #'Buffer-menu-bury + "V" #'Buffer-menu-view + "T" #'Buffer-menu-toggle-files-only + "M-s a C-s" #'Buffer-menu-isearch-buffers + "M-s a C-M-s" #'Buffer-menu-isearch-buffers-regexp + "M-s a C-o" #'Buffer-menu-multi-occur + + "" #'Buffer-menu-mouse-select + "" #'mouse-face) (easy-menu-define Buffer-menu-mode-menu Buffer-menu-mode-map "Menu for `Buffer-menu-mode' buffers." commit ed62de0d39fc5f4e459a49444af2cda3e0426607 Author: Po Lu Date: Wed Jan 5 10:34:43 2022 +0000 Resolve clipping related mysteries on Haiku * src/ftcrfont.c (ftcrfont_draw): * src/haikufont.c (haikufont_draw): Remove workarounds for previously broken clipping code. * src/haikuterm.c (haiku_clip_to_string): Handle empty clipping rectangles correctly. (haiku_clip_to_string_exactly): Stop setting num_clips. (haiku_draw_glyph_string): Stop saving face when drawing overhangs. diff --git a/src/ftcrfont.c b/src/ftcrfont.c index e8159d11b1..337e804b89 100644 --- a/src/ftcrfont.c +++ b/src/ftcrfont.c @@ -545,13 +545,6 @@ ftcrfont_draw (struct glyph_string *s, return 0; } BView_cr_dump_clipping (FRAME_HAIKU_VIEW (f), cr); - - if (s->left_overhang && s->clip_head && !s->for_overlaps) - { - cairo_rectangle (cr, s->clip_head->x, 0, - FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); - cairo_clip (cr); - } #endif if (with_background) diff --git a/src/haikufont.c b/src/haikufont.c index e1a09f407c..e08792be4b 100644 --- a/src/haikufont.c +++ b/src/haikufont.c @@ -983,13 +983,6 @@ haikufont_draw (struct glyph_string *s, int from, int to, s->background_filled_p = 1; } - if (s->left_overhang && s->clip_head && !s->for_overlaps) - { - /* XXX: Why is this neccessary? */ - BView_ClipToRect (view, s->clip_head->x, 0, - FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); - } - if (s->hl == DRAW_CURSOR) BView_SetHighColor (view, FRAME_OUTPUT_DATA (s->f)->cursor_fg); else diff --git a/src/haikuterm.c b/src/haikuterm.c index b8cb57a8fb..928b571855 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -145,15 +145,32 @@ haiku_clip_to_string (struct glyph_string *s) int n = get_glyph_string_clip_rects (s, (struct haiku_rect *) &r, 2); if (n) - BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[0].x, r[0].y, - r[0].width, r[0].height); - if (n > 1) { - BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[1].x, r[1].y, - r[1].width, r[1].height); + /* If n[FOO].width is 0, it means to not draw at all, so set the + clipping to some impossible value. */ + if (r[0].width <= 0) + BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), + FRAME_PIXEL_WIDTH (s->f), + FRAME_PIXEL_HEIGHT (s->f), + 10, 10); + else + BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[0].x, + r[0].y, r[0].width, r[0].height); } - s->num_clips = n; + if (n > 1) + { + /* If n[FOO].width is 0, it means to not draw at all, so set the + clipping to some impossible value. */ + if (r[1].width <= 0) + BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), + FRAME_PIXEL_WIDTH (s->f), + FRAME_PIXEL_HEIGHT (s->f), + 10, 10); + else + BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), r[1].x, r[1].y, + r[1].width, r[1].height); + } } static void @@ -161,7 +178,6 @@ haiku_clip_to_string_exactly (struct glyph_string *s, struct glyph_string *dst) { BView_ClipToRect (FRAME_HAIKU_VIEW (s->f), s->x, s->y, s->width, s->height); - dst->num_clips = 1; } static void @@ -1468,7 +1484,6 @@ haiku_draw_glyph_string (struct glyph_string *s) haiku_maybe_draw_background (s->next, 1); else haiku_draw_stretch_glyph_string (s->next); - next->num_clips = 0; haiku_end_clip (s); } } @@ -1486,9 +1501,13 @@ haiku_draw_glyph_string (struct glyph_string *s) box_filled_p = 1; haiku_draw_string_box (s, 0); } - else if (!s->clip_head && !s->clip_tail && - ((s->prev && s->left_overhang && s->prev->hl != s->hl) || - (s->next && s->right_overhang && s->next->hl != s->hl))) + else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */ + && !s->clip_tail + && ((s->prev && s->prev->hl != s->hl && s->left_overhang) + || (s->next && s->next->hl != s->hl && s->right_overhang))) + /* 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. */ haiku_clip_to_string_exactly (s, s); else haiku_clip_to_string (s); @@ -1526,15 +1545,18 @@ haiku_draw_glyph_string (struct glyph_string *s) haiku_maybe_draw_background (s, 1); haiku_draw_glyphless_glyph_string_foreground (s); break; + default: + emacs_abort (); } - if (!box_filled_p && face->box != FACE_NO_BOX) - haiku_draw_string_box (s, 1); - else - haiku_draw_text_decoration (s, face, face->foreground, s->width, s->x); - if (!s->for_overlaps) { + if (!box_filled_p && face->box != FACE_NO_BOX) + haiku_draw_string_box (s, 1); + else + haiku_draw_text_decoration (s, face, face->foreground, + s->width, s->x); + if (s->prev) { struct glyph_string *prev; @@ -1546,11 +1568,10 @@ haiku_draw_glyph_string (struct glyph_string *s) /* As prev was drawn while clipped to its own area, we must draw the right_overhang part using s->hl now. */ enum draw_glyphs_face save = prev->hl; - struct face *save_face = prev->face; prev->hl = s->hl; - prev->face = s->face; haiku_start_clip (s); + haiku_clip_to_string (s); haiku_clip_to_string_exactly (s, prev); if (prev->first_glyph->type == CHAR_GLYPH) haiku_draw_glyph_string_foreground (prev); @@ -1558,8 +1579,6 @@ haiku_draw_glyph_string (struct glyph_string *s) haiku_draw_composite_glyph_string_foreground (prev); haiku_end_clip (s); prev->hl = save; - prev->face = save_face; - prev->num_clips = 0; } } @@ -1574,11 +1593,10 @@ haiku_draw_glyph_string (struct glyph_string *s) /* As next will be drawn while clipped to its own area, we must draw the left_overhang part using s->hl now. */ enum draw_glyphs_face save = next->hl; - struct face *save_face = next->face; next->hl = s->hl; - next->face = s->face; haiku_start_clip (s); + haiku_clip_to_string (s); haiku_clip_to_string_exactly (s, next); if (next->first_glyph->type == CHAR_GLYPH) haiku_draw_glyph_string_foreground (next); @@ -1586,15 +1604,11 @@ haiku_draw_glyph_string (struct glyph_string *s) haiku_draw_composite_glyph_string_foreground (next); haiku_end_clip (s); - next->background_filled_p = 0; next->hl = save; - next->face = save_face; - next->clip_head = next; - next->num_clips = 0; + next->clip_head = s->next; } } } - s->num_clips = 0; haiku_end_clip (s); unblock_input (); }