commit 763ec05cc17973134c440f2d0afb6eb5d095d0d4 (HEAD, refs/remotes/origin/master) Author: Justin Timmons Date: Fri Apr 17 06:00:19 2020 +0200 Bind 'n' and 'p' to move between symbols in apropos * lisp/apropos.el (apropos-next-symbol) (apropos-previous-symbol): New commands. (apropos-mode-map): Bind above commands to 'n' and 'p'. (Bug#20694) * etc/NEWS: Announce the new commands. diff --git a/etc/NEWS b/etc/NEWS index 396c757e70..025d5c14a7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -282,6 +282,12 @@ This is used when invoking 'texi2dvi' from 'texinfo-tex-buffer'. Its default value matches localized abbreviations of the "reply" prefix on the Subject line in various languages. +** Apropos + +*** New commands 'apropos-next-symbol' and 'apropos-previous-symbol'. +These new navigation commands are bound to 'n' and 'p' in +'apropos-mode'. + * New Modes and Packages in Emacs 28.1 diff --git a/lisp/apropos.el b/lisp/apropos.el index 23f70d10fd..7277319cd8 100644 --- a/lisp/apropos.el +++ b/lisp/apropos.el @@ -160,6 +160,10 @@ If value is `verbose', the computed score is shown for each match." ;; definition of RET, so that users can use it anywhere in an ;; apropos item, not just on top of a button. (define-key map "\C-m" 'apropos-follow) + + ;; Movement keys + (define-key map "n" 'apropos-next-symbol) + (define-key map "p" 'apropos-previous-symbol) map) "Keymap used in Apropos mode.") @@ -1270,6 +1274,21 @@ as a heading." (or (apropos-next-label-button (line-beginning-position)) (error "There is nothing to follow here")))) +(defun apropos-next-symbol () + "Move cursor down to the next symbol in an apropos-mode buffer." + (interactive) + (forward-line) + (while (and (not (eq (face-at-point) 'apropos-symbol)) + (< (point) (point-max))) + (forward-line))) + +(defun apropos-previous-symbol () + "Move cursor back to the last symbol in an apropos-mode buffer." + (interactive) + (forward-line -1) + (while (and (not (eq (face-at-point) 'apropos-symbol)) + (> (point) (point-min))) + (forward-line -1))) (defun apropos-describe-plist (symbol) "Display a pretty listing of SYMBOL's plist." commit be77a68d527223f7f276e94e16fe05b49846c7a3 Author: Masahiro Nakamura Date: Tue Apr 14 22:37:17 2020 +0900 Fix comparing command names in strokes.el (bug#40600) * lisp/strokes.el (strokes-alphabetic-lessp): Simply call string-lessp because the cdr of the argument may be a string. diff --git a/lisp/strokes.el b/lisp/strokes.el index 7c00305835..08a381801d 100644 --- a/lisp/strokes.el +++ b/lisp/strokes.el @@ -1375,9 +1375,7 @@ If STROKES-MAP is not given, `strokes-global-map' will be used instead." (defun strokes-alphabetic-lessp (stroke1 stroke2) "Return t if STROKE1's command name precedes STROKE2's in lexicographic order." - (let ((command-name-1 (symbol-name (cdr stroke1))) - (command-name-2 (symbol-name (cdr stroke2)))) - (string-lessp command-name-1 command-name-2))) + (string-lessp (cdr stroke1) (cdr stroke2))) (defvar strokes-mode-map (let ((map (make-sparse-keymap))) commit e105d01c952aab93de1607ebcfed7860837288fb Author: Alan Third Date: Tue Apr 14 22:56:06 2020 +0100 Use native image API for NS * configure.ac (NATIVE_IMAGE_API): Move above NS definitions. (HAVE_NATIVE_IMAGE_API): Set for NS. (HAVE_PNG, HAVE_JPEG, HAVE_GIF, HAVE_TIFF): Enable on NS builds. * src/image.c (HAVE_NS): Fix a number of #if's so they no longer rely on HAVE_NS. (PIX_MASK_DRAW): Add for HAVE_NS so libpng support will compile. (image_can_use_native_api): (native_image_load): Add NS support. (png_load): (jpeg_load): (tiff_load): (gif_load): Remove NS specific definitions. * src/nsimage.m (ns_can_use_native_image_api): New function. * src/nsterm.h: (ns_can_use_native_image_api): New function. diff --git a/configure.ac b/configure.ac index 8cd754bd56..719eb747ae 100644 --- a/configure.ac +++ b/configure.ac @@ -1910,6 +1910,8 @@ else bitmapdir=${bmd_acc#:} fi +NATIVE_IMAGE_API=no + test "${with_ns}" = maybe && test "${opsys}" != darwin && with_ns=no HAVE_NS=no NS_GNUSTEP_CONFIG=no @@ -2021,6 +2023,11 @@ Either fix this, or re-configure with the option '--without-ns'.])]) AC_MSG_ERROR([Mac OS X 10.6 or newer is required]); fi fi + + if test "${with_native_image_api}" = yes; then + AC_DEFINE(HAVE_NATIVE_IMAGE_API, 1, [Define to use native OS APIs for images.]) + NATIVE_IMAGE_API="yes (ns)" + fi fi AC_SUBST(LIBS_GNUSTEP) @@ -2127,7 +2134,6 @@ LIB_WSOCK32= NTLIB= CM_OBJ="cm.o" XARGS_LIMIT= -NATIVE_IMAGE_API=no if test "${HAVE_W32}" = "yes"; then AC_DEFINE(HAVE_NTGUI, 1, [Define to use native MS Windows GUI.]) if test "$with_toolkit_scroll_bars" = "no"; then @@ -3575,9 +3581,8 @@ AC_SUBST(LIBXPM) ### Use -ljpeg if available, unless '--with-jpeg=no'. HAVE_JPEG=no LIBJPEG= -if test "${NS_IMPL_COCOA}" = yes; then - : # Cocoa provides its own jpeg support, so do nothing. -elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes"; then +if test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \ + || test "${HAVE_NS}" = "yes"; then if test "${with_jpeg}" != "no"; then AC_CACHE_CHECK([for jpeglib 6b or later], [emacs_cv_jpeglib], @@ -3726,13 +3731,12 @@ AC_SUBST(emacs_major_version) HAVE_PNG=no LIBPNG= PNG_CFLAGS= -if test "${NS_IMPL_COCOA}" = yes; then - : # Cocoa provides its own png support, so do nothing. -elif test "${with_png}" != no; then +if test "${with_png}" != no; then # mingw32 loads the library dynamically. if test "$opsys" = mingw32; then AC_CHECK_HEADER([png.h], [HAVE_PNG=yes]) - elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes"; then + elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \ + || test "${HAVE_NS}" = "yes"; then EMACS_CHECK_MODULES([PNG], [libpng >= 1.0.0]) if test $HAVE_PNG = yes; then LIBPNG=$PNG_LIBS @@ -3806,7 +3810,8 @@ if test "${opsys}" = "mingw32"; then if test "${HAVE_TIFF}" = "yes"; then AC_DEFINE(HAVE_TIFF, 1, [Define to 1 if you have the tiff library (-ltiff).]) fi -elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes"; then +elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \ + || test "${HAVE_NS}" = "yes"; then if test "${with_tiff}" != "no"; then AC_CHECK_HEADER(tiffio.h, [tifflibs="-lz -lm" @@ -3835,7 +3840,7 @@ if test "${opsys}" = "mingw32"; then AC_DEFINE(HAVE_GIF, 1, [Define to 1 if you have a gif (or ungif) library.]) fi elif test "${HAVE_X11}" = "yes" && test "${with_gif}" != "no" \ - || test "${HAVE_W32}" = "yes"; then + || test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes"; then AC_CHECK_HEADER(gif_lib.h, # EGifPutExtensionLast only exists from version libungif-4.1.0b1. # Earlier versions can crash Emacs, but version 5.0 removes EGifPutExtensionLast. diff --git a/src/image.c b/src/image.c index acb1e9d23d..ffe2f607e5 100644 --- a/src/image.c +++ b/src/image.c @@ -24,7 +24,7 @@ along with GNU Emacs. If not, see . */ /* Include this before including to work around bugs with older libpng; see Bug#17429. */ -#if defined HAVE_PNG && !defined HAVE_NS +#if defined HAVE_PNG # include #endif @@ -125,6 +125,7 @@ typedef struct ns_bitmap_record Bitmap_Record; #define NO_PIXMAP 0 #define PIX_MASK_RETAIN 0 +#define PIX_MASK_DRAW 1 #endif /* HAVE_NS */ @@ -6242,6 +6243,8 @@ image_can_use_native_api (Lisp_Object type) { # ifdef HAVE_NTGUI return w32_can_use_native_image_api (type); +# elif defined HAVE_NS + return ns_can_use_native_image_api (type); # else return false; # endif @@ -6310,6 +6313,10 @@ native_image_load (struct frame *f, struct image *img) return w32_load_image (f, img, image_spec_value (img->spec, QCfile, NULL), image_spec_value (img->spec, QCdata, NULL)); +# elif defined HAVE_NS + return ns_load_image (f, img, + image_spec_value (img->spec, QCfile, NULL), + image_spec_value (img->spec, QCdata, NULL)); # else return 0; # endif @@ -6322,7 +6329,7 @@ native_image_load (struct frame *f, struct image *img) PNG ***********************************************************************/ -#if defined (HAVE_PNG) || defined (HAVE_NS) +#if defined (HAVE_PNG) /* Indices of image specification fields in png_format, below. */ @@ -6373,10 +6380,10 @@ png_image_p (Lisp_Object object) return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1; } -#endif /* HAVE_PNG || HAVE_NS */ +#endif /* HAVE_PNG */ -#if defined HAVE_PNG && !defined HAVE_NS +#ifdef HAVE_PNG # ifdef WINDOWSNT /* PNG library details. */ @@ -6966,17 +6973,7 @@ png_load (struct frame *f, struct image *img) return png_load_body (f, img, &c); } -#elif defined HAVE_NS - -static bool -png_load (struct frame *f, struct image *img) -{ - return ns_load_image (f, img, - image_spec_value (img->spec, QCfile, NULL), - image_spec_value (img->spec, QCdata, NULL)); -} - -#endif /* HAVE_NS */ +#endif /* HAVE_PNG */ @@ -6984,7 +6981,7 @@ png_load (struct frame *f, struct image *img) JPEG ***********************************************************************/ -#if defined (HAVE_JPEG) || defined (HAVE_NS) +#if defined (HAVE_JPEG) /* Indices of image specification fields in gs_format, below. */ @@ -7036,7 +7033,7 @@ jpeg_image_p (Lisp_Object object) return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1; } -#endif /* HAVE_JPEG || HAVE_NS */ +#endif /* HAVE_JPEG */ #ifdef HAVE_JPEG @@ -7538,18 +7535,6 @@ jpeg_load (struct frame *f, struct image *img) return jpeg_load_body (f, img, &mgr); } -#else /* HAVE_JPEG */ - -#ifdef HAVE_NS -static bool -jpeg_load (struct frame *f, struct image *img) -{ - return ns_load_image (f, img, - image_spec_value (img->spec, QCfile, NULL), - image_spec_value (img->spec, QCdata, NULL)); -} -#endif /* HAVE_NS */ - #endif /* !HAVE_JPEG */ @@ -7558,7 +7543,7 @@ jpeg_load (struct frame *f, struct image *img) TIFF ***********************************************************************/ -#if defined (HAVE_TIFF) || defined (HAVE_NS) +#if defined (HAVE_TIFF) /* Indices of image specification fields in tiff_format, below. */ @@ -7611,7 +7596,7 @@ tiff_image_p (Lisp_Object object) return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1; } -#endif /* HAVE_TIFF || HAVE_NS */ +#endif /* HAVE_TIFF */ #ifdef HAVE_TIFF @@ -7979,16 +7964,6 @@ tiff_load (struct frame *f, struct image *img) return 1; } -#elif defined HAVE_NS - -static bool -tiff_load (struct frame *f, struct image *img) -{ - return ns_load_image (f, img, - image_spec_value (img->spec, QCfile, NULL), - image_spec_value (img->spec, QCdata, NULL)); -} - #endif @@ -7997,7 +7972,7 @@ tiff_load (struct frame *f, struct image *img) GIF ***********************************************************************/ -#if defined (HAVE_GIF) || defined (HAVE_NS) +#if defined (HAVE_GIF) /* Indices of image specification fields in gif_format, below. */ @@ -8059,7 +8034,7 @@ gif_image_p (Lisp_Object object) return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1; } -#endif /* HAVE_GIF || HAVE_NS */ +#endif /* HAVE_GIF */ #ifdef HAVE_GIF @@ -8576,18 +8551,6 @@ gif_load (struct frame *f, struct image *img) return 1; } -#else /* !HAVE_GIF */ - -#ifdef HAVE_NS -static bool -gif_load (struct frame *f, struct image *img) -{ - return ns_load_image (f, img, - image_spec_value (img->spec, QCfile, NULL), - image_spec_value (img->spec, QCdata, NULL)); -} -#endif /* HAVE_NS */ - #endif /* HAVE_GIF */ @@ -10256,19 +10219,19 @@ static struct image_type const image_types[] = { SYMBOL_INDEX (Qsvg), svg_image_p, svg_load, image_clear_image, IMAGE_TYPE_INIT (init_svg_functions) }, #endif -#if defined HAVE_PNG || defined HAVE_NS +#if defined HAVE_PNG { SYMBOL_INDEX (Qpng), png_image_p, png_load, image_clear_image, IMAGE_TYPE_INIT (init_png_functions) }, #endif -#if defined HAVE_GIF || defined HAVE_NS +#if defined HAVE_GIF { SYMBOL_INDEX (Qgif), gif_image_p, gif_load, gif_clear_image, IMAGE_TYPE_INIT (init_gif_functions) }, #endif -#if defined HAVE_TIFF || defined HAVE_NS +#if defined HAVE_TIFF { SYMBOL_INDEX (Qtiff), tiff_image_p, tiff_load, image_clear_image, IMAGE_TYPE_INIT (init_tiff_functions) }, #endif -#if defined HAVE_JPEG || defined HAVE_NS +#if defined HAVE_JPEG { SYMBOL_INDEX (Qjpeg), jpeg_image_p, jpeg_load, image_clear_image, IMAGE_TYPE_INIT (init_jpeg_functions) }, #endif @@ -10418,22 +10381,22 @@ non-numeric, there is no explicit limit on the size of images. */); add_image_type (Qxpm); #endif -#if defined (HAVE_JPEG) || defined (HAVE_NS) || defined (HAVE_NATIVE_IMAGE_API) +#if defined (HAVE_JPEG) || defined (HAVE_NATIVE_IMAGE_API) DEFSYM (Qjpeg, "jpeg"); add_image_type (Qjpeg); #endif -#if defined (HAVE_TIFF) || defined (HAVE_NS) || defined (HAVE_NATIVE_IMAGE_API) +#if defined (HAVE_TIFF) || defined (HAVE_NATIVE_IMAGE_API) DEFSYM (Qtiff, "tiff"); add_image_type (Qtiff); #endif -#if defined (HAVE_GIF) || defined (HAVE_NS) || defined (HAVE_NATIVE_IMAGE_API) +#if defined (HAVE_GIF) || defined (HAVE_NATIVE_IMAGE_API) DEFSYM (Qgif, "gif"); add_image_type (Qgif); #endif -#if defined (HAVE_PNG) || defined (HAVE_NS) || defined(HAVE_NATIVE_IMAGE_API) +#if defined (HAVE_PNG) || defined (HAVE_NATIVE_IMAGE_API) DEFSYM (Qpng, "png"); add_image_type (Qpng); #endif diff --git a/src/nsimage.m b/src/nsimage.m index 3cccc984ca..07750de95f 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -45,6 +45,55 @@ Updated by Christian Limpach (chris@nice.ch) ========================================================================== */ +bool +ns_can_use_native_image_api (Lisp_Object type) +{ + NSString *imageType = @"unknown"; + NSArray *types; + + NSTRACE ("ns_can_use_native_image_api"); + + if (EQ (type, Qnative_image)) + return YES; + +#ifdef NS_IMPL_COCOA + /* Work out the UTI of the image type. */ + if (EQ (type, Qjpeg)) + imageType = @"public.jpeg"; + else if (EQ (type, Qpng)) + imageType = @"public.png"; + else if (EQ (type, Qgif)) + imageType = @"com.compuserve.gif"; + else if (EQ (type, Qtiff)) + imageType = @"public.tiff"; + else if (EQ (type, Qsvg)) + imageType = @"public.svg-image"; + + /* NSImage also supports a host of other types such as PDF and BMP, + but we don't yet support these in image.c. */ + + types = [NSImage imageTypes]; +#else + /* Work out the image type. */ + if (EQ (type, Qjpeg)) + imageType = @"jpeg"; + else if (EQ (type, Qpng)) + imageType = @"png"; + else if (EQ (type, Qgif)) + imageType = @"gif"; + else if (EQ (type, Qtiff)) + imageType = @"tiff"; + + types = [NSImage imageFileTypes]; +#endif + + /* Check if the type is supported on this system. */ + if ([types indexOfObject:imageType] != NSNotFound) + return YES; + else + return NO; +} + void * ns_image_from_XBM (char *bits, int width, int height, unsigned long fg, unsigned long bg) diff --git a/src/nsterm.h b/src/nsterm.h index f5d3c32b8b..8d5371c8f2 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -1189,6 +1189,7 @@ extern void syms_of_nsselect (void); /* From nsimage.m, needed in image.c */ struct image; +extern bool ns_can_use_native_image_api (Lisp_Object type); extern void *ns_image_from_XBM (char *bits, int width, int height, unsigned long fg, unsigned long bg); extern void *ns_image_for_XPM (int width, int height, int depth); commit c019f03e38850b3ba3a2bcbcc84960d5b8d9663f Author: Alan Third Date: Sat Apr 11 14:18:39 2020 +0100 Allow dynamic choice of drawing path on NS (bug#39883) * src/nsterm.h (NS_DRAW_TO_BUFFER): Let this be enabled on versions older than 10.14. * src/nsterm.m (ns_update_begin): (ns_update_end): (ns_focus): (ns_unfocus): ([EmacsView viewDidResize:]): ([EmacsView createDrawingBuffer]): ([EmacsView windowDidChangeBackingProperties:]): ([EmacsView copyRect:to:]): ([EmacsView wantsUpdateLayer]): Dynamically switch between drawing to a buffer and drawing to the screen, depending on the version of AppKit in use. ([EmacsView dealloc]): We can't release the context unless NS_DRAW_TO_BUFFER is defined. diff --git a/src/nsterm.h b/src/nsterm.h index e142dbd4f0..f5d3c32b8b 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -343,14 +343,8 @@ typedef id instancetype; therefore we draw to an offscreen buffer and swap it in when the toolkit wants to draw the frame. GNUstep and macOS 10.7 and below do not support this method, so we revert to drawing directly to the - glass. - - FIXME: Should we make this macOS 10.8+, or macOS 10.14+? I'm - inclined to go with 10.14+ as there have been some reports of funny - behaviour on 10.13 and below. It may be worth adding a variable to - allow people in the overlapping region to switch between drawing - paths. */ -#if defined (NS_IMPL_COCOA) && defined (MAC_OS_X_VERSION_10_14) + glass. */ +#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101400 #define NS_DRAW_TO_BUFFER 1 #endif diff --git a/src/nsterm.m b/src/nsterm.m index a75c3ef4db..9cd1c9d860 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1144,10 +1144,25 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen) ns_updating_frame = f; #ifdef NS_DRAW_TO_BUFFER - [view focusOnDrawingBuffer]; -#else - [view lockFocus]; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) + { #endif + [view focusOnDrawingBuffer]; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } + else + { +#endif +#endif /* NS_DRAW_TO_BUFFER */ + +#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + [view lockFocus]; +#endif +#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } +#endif + } @@ -1166,15 +1181,29 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen) MOUSE_HL_INFO (f)->mouse_face_defer = 0; #ifdef NS_DRAW_TO_BUFFER - [NSGraphicsContext setCurrentContext:nil]; - [view setNeedsDisplay:YES]; -#else - block_input (); +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) + { +#endif + [NSGraphicsContext setCurrentContext:nil]; + [view setNeedsDisplay:YES]; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } + else + { +#endif +#endif /* NS_DRAW_TO_BUFFER */ - [view unlockFocus]; - [[view window] flushWindow]; +#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + block_input (); - unblock_input (); + [view unlockFocus]; + [[view window] flushWindow]; + + unblock_input (); +#endif +#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } #endif ns_updating_frame = NULL; } @@ -1199,24 +1228,39 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen) } if (f != ns_updating_frame) -#ifdef NS_DRAW_TO_BUFFER - [view focusOnDrawingBuffer]; -#else { - if (view != focus_view) +#ifdef NS_DRAW_TO_BUFFER +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) { - if (focus_view != NULL) +#endif + [view focusOnDrawingBuffer]; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } + else + { +#endif +#endif /* NS_DRAW_TO_BUFFER */ + +#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + if (view != focus_view) { - [focus_view unlockFocus]; - [[focus_view window] flushWindow]; - } + if (focus_view != NULL) + { + [focus_view unlockFocus]; + [[focus_view window] flushWindow]; + } - if (view) - [view lockFocus]; - focus_view = view; + if (view) + [view lockFocus]; + focus_view = view; + } +#endif +#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 } - } #endif + } + /* clipping */ if (r) @@ -1246,16 +1290,30 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen) } #ifdef NS_DRAW_TO_BUFFER - [FRAME_NS_VIEW (f) setNeedsDisplay:YES]; -#else - if (f != ns_updating_frame) + #if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + if ([FRAME_NS_VIEW (f) wantsUpdateLayer]) + { +#endif + [FRAME_NS_VIEW (f) setNeedsDisplay:YES]; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } + else { - if (focus_view != NULL) +#endif +#endif /* NS_DRAW_TO_BUFFER */ + +#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + if (f != ns_updating_frame) { - [focus_view unlockFocus]; - [[focus_view window] flushWindow]; - focus_view = NULL; + if (focus_view != NULL) + { + [focus_view unlockFocus]; + [[focus_view window] flushWindow]; + focus_view = NULL; + } } +#endif +#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 } #endif } @@ -6254,7 +6312,9 @@ - (void)dealloc name:NSViewFrameDidChangeNotification object:nil]; +#ifdef NS_DRAW_TO_BUFFER CGContextRelease (drawingBuffer); +#endif [toolbar release]; if (fs_state == FULLSCREEN_BOTH) @@ -7268,13 +7328,27 @@ - (void)viewDidResize:(NSNotification *)notification return; #ifdef NS_DRAW_TO_BUFFER - CGFloat scale = [[self window] backingScaleFactor]; - oldw = (CGFloat)CGBitmapContextGetWidth (drawingBuffer) / scale; - oldh = (CGFloat)CGBitmapContextGetHeight (drawingBuffer) / scale; -#else - oldw = FRAME_PIXEL_WIDTH (emacsframe); - oldh = FRAME_PIXEL_HEIGHT (emacsframe); +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + if ([self wantsUpdateLayer]) + { +#endif + CGFloat scale = [[self window] backingScaleFactor]; + oldw = (CGFloat)CGBitmapContextGetWidth (drawingBuffer) / scale; + oldh = (CGFloat)CGBitmapContextGetHeight (drawingBuffer) / scale; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } + else + { #endif +#endif /* NS_DRAW_TO_BUFFER */ +#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + oldw = FRAME_PIXEL_WIDTH (emacsframe); + oldh = FRAME_PIXEL_HEIGHT (emacsframe); +#endif +#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } +#endif + neww = (int)NSWidth (frame); newh = (int)NSHeight (frame); @@ -8304,6 +8378,9 @@ - (void)createDrawingBuffer { NSTRACE ("EmacsView createDrawingBuffer]"); + if (! [self wantsUpdateLayer]) + return; + NSGraphicsContext *screen; CGColorSpaceRef colorSpace = [[[self window] colorSpace] CGColorSpace]; CGFloat scale = [[self window] backingScaleFactor]; @@ -8339,6 +8416,9 @@ - (void)windowDidChangeBackingProperties:(NSNotification *)notification { NSTRACE ("EmacsView windowDidChangeBackingProperties:]"); + if (! [self wantsUpdateLayer]) + return; + CGFloat old = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; @@ -8362,41 +8442,56 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect NSTRACE_RECT ("Destination", dstRect); #ifdef NS_DRAW_TO_BUFFER - CGImageRef copy; - NSRect frame = [self frame]; - NSAffineTransform *setOrigin = [NSAffineTransform transform]; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + if ([self wantsUpdateLayer]) + { +#endif + CGImageRef copy; + NSRect frame = [self frame]; + NSAffineTransform *setOrigin = [NSAffineTransform transform]; - [[NSGraphicsContext currentContext] saveGraphicsState]; + [[NSGraphicsContext currentContext] saveGraphicsState]; - /* Set the clipping before messing with the buffer's - orientation. */ - NSRectClip (dstRect); + /* Set the clipping before messing with the buffer's + orientation. */ + NSRectClip (dstRect); - /* Unflip the buffer as the copied image will be unflipped, and - offset the top left so when we draw back into the buffer the - correct part of the image is drawn. */ - CGContextScaleCTM(drawingBuffer, 1, -1); - CGContextTranslateCTM(drawingBuffer, - NSMinX (dstRect) - NSMinX (srcRect), - -NSHeight (frame) - (NSMinY (dstRect) - NSMinY (srcRect))); + /* Unflip the buffer as the copied image will be unflipped, and + offset the top left so when we draw back into the buffer the + correct part of the image is drawn. */ + CGContextScaleCTM(drawingBuffer, 1, -1); + CGContextTranslateCTM(drawingBuffer, + NSMinX (dstRect) - NSMinX (srcRect), + -NSHeight (frame) - (NSMinY (dstRect) - NSMinY (srcRect))); - /* Take a copy of the buffer and then draw it back to the buffer, - limited by the clipping rectangle. */ - copy = CGBitmapContextCreateImage (drawingBuffer); - CGContextDrawImage (drawingBuffer, frame, copy); + /* Take a copy of the buffer and then draw it back to the buffer, + limited by the clipping rectangle. */ + copy = CGBitmapContextCreateImage (drawingBuffer); + CGContextDrawImage (drawingBuffer, frame, copy); - CGImageRelease (copy); + CGImageRelease (copy); - [[NSGraphicsContext currentContext] restoreGraphicsState]; - [self setNeedsDisplayInRect:dstRect]; -#else - hide_bell(); // Ensure the bell image isn't scrolled. + [[NSGraphicsContext currentContext] restoreGraphicsState]; + [self setNeedsDisplayInRect:dstRect]; - ns_focus (emacsframe, &dstRect, 1); - [self scrollRect: srcRect - by: NSMakeSize (dstRect.origin.x - srcRect.origin.x, - dstRect.origin.y - srcRect.origin.y)]; - ns_unfocus (emacsframe); +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } + else + { +#endif +#endif /* NS_DRAW_TO_BUFFER */ + +#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + hide_bell(); // Ensure the bell image isn't scrolled. + + ns_focus (emacsframe, &dstRect, 1); + [self scrollRect: srcRect + by: NSMakeSize (dstRect.origin.x - srcRect.origin.x, + dstRect.origin.y - srcRect.origin.y)]; + ns_unfocus (emacsframe); +#endif +#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + } #endif } @@ -8404,7 +8499,13 @@ - (void)copyRect:(NSRect)srcRect to:(NSRect)dstRect #ifdef NS_DRAW_TO_BUFFER - (BOOL)wantsUpdateLayer { - return YES; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400 + if (NSAppKitVersionNumber < 1671) + return NO; +#endif + + /* Running on macOS 10.14 or above. */ + return YES; } commit 24cb6908d70c14792c686679cb08091447b9c3b1 Author: Alan Third Date: Sat Apr 4 15:13:58 2020 +0100 Fix NS frame resizing issues (bug#40200, bug#28872) * src/nsmenu.m (update_frame_tool_bar): Remove reference to updateFrameSize. * src/nsterm.h: ([EmacsView updateFrameSize]): ([EmacsView setRows:andColumns:]): Remove unused method definitions. (NS_PARENT_WINDOW_LEFT_POS): (NS_PARENT_WINDOW_TOP_POS): Move to nsterm.m. * src/nsterm.m (ns_parent_window_rect): New function. (NS_PARENT_WINDOW_LEFT_POS): (NS_PARENT_WINDOW_TOP_POS): Move to nsterm.m and simplify. (ns_set_offset): Fix strange behaviours when using negative values. (ns_set_window_size): (ns_set_undecorated): ([EmacsView windowDidResize:]): ([EmacsView windowDidExitFullScreen]): (ns_judge_scroll_bars): Remove references to updateFrameSize. ([EmacsView dealloc]): Unset resize notification and release buffer. ([EmacsView updateFrameSize:]): Remove function. ([EmacsView windowWillResize:toSize:]): Move some code to viewDidResize. ([EmacsView viewDidResize]): New function. ([EmacsView initFrameFromEmacs:]): Set up resize notification and move buffer creation until after the prerequisite objects are created. ([EmacsView toggleFullScreen:]): Set frame to the size of the contentview, not the whole window, and remove reference to updateFrameSize. ([EmacsView setRows:andColumns:]): Remove unused method. ([EmacsView windowDidMove:]): Tidy up. diff --git a/src/nsmenu.m b/src/nsmenu.m index 67f9a45a40..b7e4cbd565 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -1141,8 +1141,6 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f } #endif - if (oldh != FRAME_TOOLBAR_HEIGHT (f)) - [view updateFrameSize:YES]; if (view->wait_for_tool_bar && FRAME_TOOLBAR_HEIGHT (f) > 0) { view->wait_for_tool_bar = NO; diff --git a/src/nsterm.h b/src/nsterm.h index 8396a542f7..e142dbd4f0 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -439,7 +439,6 @@ typedef id instancetype; #endif @public struct frame *emacsframe; - int rows, cols; int scrollbarsNeedingUpdate; EmacsToolbar *toolbar; NSRect ns_userRect; @@ -458,11 +457,9 @@ typedef id instancetype; /* Emacs-side interface */ - (instancetype) initFrameFromEmacs: (struct frame *) f; - (void) createToolbar: (struct frame *)f; -- (void) setRows: (int) r andColumns: (int) c; - (void) setWindowClosing: (BOOL)closing; - (EmacsToolbar *) toolbar; - (void) deleteWorkingText; -- (void) updateFrameSize: (BOOL) delay; - (void) handleFS; - (void) setFSValue: (int)value; - (void) toggleFullScreen: (id) sender; @@ -1084,18 +1081,6 @@ struct x_output (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f) \ - NS_SCROLL_BAR_HEIGHT (f)) : 0) -/* Calculate system coordinates of the left and top of the parent - window or, if there is no parent window, the screen. */ -#define NS_PARENT_WINDOW_LEFT_POS(f) \ - (FRAME_PARENT_FRAME (f) != NULL \ - ? [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window].frame.origin.x : 0) -#define NS_PARENT_WINDOW_TOP_POS(f) \ - (FRAME_PARENT_FRAME (f) != NULL \ - ? ([FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window].frame.origin.y \ - + [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window].frame.size.height \ - - FRAME_NS_TITLEBAR_HEIGHT (FRAME_PARENT_FRAME (f))) \ - : [[[NSScreen screens] objectAtIndex: 0] frame].size.height) - #define FRAME_NS_FONT_TABLE(f) (FRAME_DISPLAY_INFO (f)->font_table) #define FRAME_FONTSET(f) ((f)->output_data.ns->fontset) diff --git a/src/nsterm.m b/src/nsterm.m index 2f181eafd0..a75c3ef4db 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -843,6 +843,32 @@ Free a pool and temporary objects it refers to (callable from C) } +/* Get the frame rect, in system coordinates, of the parent window or, + if there is no parent window, the main screen. */ +static inline NSRect +ns_parent_window_rect (struct frame *f) +{ + NSRect parentRect; + + if (FRAME_PARENT_FRAME (f) != NULL) + { + EmacsView *parentView = FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)); + parentRect = [parentView convertRect:[parentView frame] + toView:nil]; + parentRect = [[parentView window] convertRectToScreen:parentRect]; + } + else + parentRect = [[[NSScreen screens] objectAtIndex:0] frame]; + + return parentRect; +} + +/* Calculate system coordinates of the left and top of the parent + window or, if there is no parent window, the main screen. */ +#define NS_PARENT_WINDOW_LEFT_POS(f) NSMinX (ns_parent_window_rect (f)) +#define NS_PARENT_WINDOW_TOP_POS(f) NSMaxY (ns_parent_window_rect (f)) + + static NSRect ns_row_rect (struct window *w, struct glyph_row *row, enum glyph_row_area area) @@ -1741,61 +1767,64 @@ Hide the window (X11 semantics) -------------------------------------------------------------------------- */ { NSView *view = FRAME_NS_VIEW (f); - NSScreen *screen = [[view window] screen]; + NSRect windowFrame = [[view window] frame]; + NSPoint topLeft; NSTRACE ("ns_set_offset"); block_input (); - f->left_pos = xoff; - f->top_pos = yoff; + if (FRAME_PARENT_FRAME (f)) + { + /* Convert the parent frame's view rectangle into screen + coords. */ + EmacsView *parentView = FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)); + NSRect parentRect = [parentView convertRect:[parentView frame] + toView:nil]; + parentRect = [[parentView window] convertRectToScreen:parentRect]; + + if (f->size_hint_flags & XNegative) + topLeft.x = NSMaxX (parentRect) - NSWidth (windowFrame) + xoff; + else + topLeft.x = NSMinX (parentRect) + xoff; - if (view != nil) + if (f->size_hint_flags & YNegative) + topLeft.y = NSMinY (parentRect) + NSHeight (windowFrame) - yoff; + else + topLeft.y = NSMaxY (parentRect) - yoff; + } + else { - if (FRAME_PARENT_FRAME (f) == NULL && screen) - { - f->left_pos = f->size_hint_flags & XNegative - ? [screen visibleFrame].size.width + f->left_pos - FRAME_PIXEL_WIDTH (f) - : f->left_pos; - /* We use visibleFrame here to take menu bar into account. - Ideally we should also adjust left/top with visibleFrame.origin. */ - - f->top_pos = f->size_hint_flags & YNegative - ? ([screen visibleFrame].size.height + f->top_pos - - FRAME_PIXEL_HEIGHT (f) - FRAME_NS_TITLEBAR_HEIGHT (f) - - FRAME_TOOLBAR_HEIGHT (f)) - : f->top_pos; -#ifdef NS_IMPL_GNUSTEP - if (f->left_pos < 100) - f->left_pos = 100; /* don't overlap menu */ -#endif - } - else if (FRAME_PARENT_FRAME (f) != NULL) - { - struct frame *parent = FRAME_PARENT_FRAME (f); + /* If there is no parent frame then just convert to screen + coordinates, UNLESS we have negative values, in which case I + think it's best to position from the bottom and right of the + current screen rather than the main screen or whole + display. */ + NSRect screenFrame = [[[view window] screen] frame]; - /* On X negative values for child frames always result in - positioning relative to the bottom right corner of the - parent frame. */ - if (f->left_pos < 0) - f->left_pos = FRAME_PIXEL_WIDTH (parent) - FRAME_PIXEL_WIDTH (f) + f->left_pos; + if (f->size_hint_flags & XNegative) + topLeft.x = NSMaxX (screenFrame) - NSWidth (windowFrame) + xoff; + else + topLeft.x = xoff; - if (f->top_pos < 0) - f->top_pos = FRAME_PIXEL_HEIGHT (parent) + FRAME_TOOLBAR_HEIGHT (parent) - - FRAME_PIXEL_HEIGHT (f) + f->top_pos; - } + if (f->size_hint_flags & YNegative) + topLeft.y = NSMinY (screenFrame) + NSHeight (windowFrame) - yoff; + else + topLeft.y = NSMaxY ([[[NSScreen screens] objectAtIndex:0] frame]) - yoff; + +#ifdef NS_IMPL_GNUSTEP + /* Don't overlap the menu. - /* Constrain the setFrameTopLeftPoint so we don't move behind the - menu bar. */ - NSPoint pt = NSMakePoint (SCREENMAXBOUND (f->left_pos - + NS_PARENT_WINDOW_LEFT_POS (f)), - SCREENMAXBOUND (NS_PARENT_WINDOW_TOP_POS (f) - - f->top_pos)); - NSTRACE_POINT ("setFrameTopLeftPoint", pt); - [[view window] setFrameTopLeftPoint: pt]; - f->size_hint_flags &= ~(XNegative|YNegative); + FIXME: Surely there's a better way than just hardcoding 100 + in here? */ + boundsRect.origin.x = 100; +#endif } + NSTRACE_POINT ("setFrameTopLeftPoint", topLeft); + [[view window] setFrameTopLeftPoint:topLeft]; + f->size_hint_flags &= ~(XNegative|YNegative); + unblock_input (); } @@ -1862,9 +1891,16 @@ Hide the window (X11 semantics) make_fixnum (FRAME_NS_TITLEBAR_HEIGHT (f)), make_fixnum (FRAME_TOOLBAR_HEIGHT (f)))); - [window setFrame: wr display: YES]; + /* Usually it seems safe to delay changing the frame size, but when a + series of actions are taken with no redisplay between them then we + can end up using old values so don't delay here. */ + change_frame_size (f, + FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth), + FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight), + 0, NO, 0, 1); + + [window setFrame:wr display:NO]; - [view updateFrameSize: NO]; unblock_input (); } @@ -1913,7 +1949,6 @@ Hide the window (X11 semantics) so some key presses (TAB) are swallowed by the system. */ [window makeFirstResponder: view]; - [view updateFrameSize: NO]; unblock_input (); } } @@ -5026,9 +5061,6 @@ in certain situations (rapid incoming events). if ([view judge]) removed = YES; } - - if (removed) - [eview updateFrameSize: NO]; } /* ========================================================================== @@ -6215,6 +6247,15 @@ - (void) setWindowClosing: (BOOL)closing - (void)dealloc { NSTRACE ("[EmacsView dealloc]"); + + /* Clear the view resize notification. */ + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:NSViewFrameDidChangeNotification + object:nil]; + + CGContextRelease (drawingBuffer); + [toolbar release]; if (fs_state == FULLSCREEN_BOTH) [nonfs_window release]; @@ -7056,108 +7097,12 @@ - (BOOL)windowShouldClose: (id)sender return NO; } -- (void) updateFrameSize: (BOOL) delay -{ - NSWindow *window = [self window]; - NSRect wr = [window frame]; - int extra = 0; - int oldc = cols, oldr = rows; - int oldw = FRAME_PIXEL_WIDTH (emacsframe); - int oldh = FRAME_PIXEL_HEIGHT (emacsframe); - int neww, newh; - - NSTRACE ("[EmacsView updateFrameSize:]"); - NSTRACE_SIZE ("Original size", NSMakeSize (oldw, oldh)); - NSTRACE_RECT ("Original frame", wr); - NSTRACE_MSG ("Original columns: %d", cols); - NSTRACE_MSG ("Original rows: %d", rows); - - if (! [self isFullscreen]) - { - int toolbar_height; -#ifdef NS_IMPL_GNUSTEP - // GNUstep does not always update the tool bar height. Force it. - if (toolbar && [toolbar isVisible]) - update_frame_tool_bar (emacsframe); -#endif - - toolbar_height = FRAME_TOOLBAR_HEIGHT (emacsframe); - if (toolbar_height < 0) - toolbar_height = 35; - - extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) - + toolbar_height; - } - - if (wait_for_tool_bar) - { - /* The toolbar height is always 0 in fullscreen and undecorated - frames, so don't wait for it to become available. */ - if (FRAME_TOOLBAR_HEIGHT (emacsframe) == 0 - && FRAME_UNDECORATED (emacsframe) == false - && ! [self isFullscreen]) - { - NSTRACE_MSG ("Waiting for toolbar"); - return; - } - wait_for_tool_bar = NO; - } - - neww = (int)wr.size.width - emacsframe->border_width; - newh = (int)wr.size.height - extra; - - NSTRACE_SIZE ("New size", NSMakeSize (neww, newh)); - NSTRACE_MSG ("FRAME_TOOLBAR_HEIGHT: %d", FRAME_TOOLBAR_HEIGHT (emacsframe)); - NSTRACE_MSG ("FRAME_NS_TITLEBAR_HEIGHT: %d", FRAME_NS_TITLEBAR_HEIGHT (emacsframe)); - - cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, neww); - rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, newh); - - if (cols < MINWIDTH) - cols = MINWIDTH; - - if (rows < MINHEIGHT) - rows = MINHEIGHT; - - NSTRACE_MSG ("New columns: %d", cols); - NSTRACE_MSG ("New rows: %d", rows); - - if (oldr != rows || oldc != cols || neww != oldw || newh != oldh) - { - NSView *view = FRAME_NS_VIEW (emacsframe); - - change_frame_size (emacsframe, - FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww), - FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh), - 0, delay, 0, 1); - SET_FRAME_GARBAGED (emacsframe); - cancel_mouse_face (emacsframe); - - /* The next two lines set the frame to the same size as we've - already set above. We need to do this when we switch back - from non-native fullscreen, in other circumstances it appears - to be a noop. (bug#28872) */ - wr = NSMakeRect (0, 0, neww, newh); - [view setFrame: wr]; -#ifdef NS_DRAW_TO_BUFFER - [self createDrawingBuffer]; -#endif - - // To do: consider using [NSNotificationCenter postNotificationName:]. - [self windowDidMove: // Update top/left. - [NSNotification notificationWithName:NSWindowDidMoveNotification - object:[view window]]]; - } - else - { - NSTRACE_MSG ("No change"); - } -} - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize /* Normalize frame to gridded text size. */ { int extra = 0; + int cols, rows; NSTRACE ("[EmacsView windowWillResize:toSize: " NSTRACE_FMT_SIZE "]", NSTRACE_ARG_SIZE (frameSize)); @@ -7294,11 +7239,6 @@ - (void)windowDidResize: (NSNotification *)notification sz = [self windowWillResize: theWindow toSize: sz]; #endif /* NS_IMPL_GNUSTEP */ - if (cols > 0 && rows > 0) - { - [self updateFrameSize: YES]; - } - ns_send_appdefined (-1); } @@ -7319,6 +7259,50 @@ - (void)viewDidEndLiveResize #endif /* NS_IMPL_COCOA */ +- (void)viewDidResize:(NSNotification *)notification +{ + NSRect frame = [self frame]; + int oldw, oldh, neww, newh; + + if (! FRAME_LIVE_P (emacsframe)) + return; + +#ifdef NS_DRAW_TO_BUFFER + CGFloat scale = [[self window] backingScaleFactor]; + oldw = (CGFloat)CGBitmapContextGetWidth (drawingBuffer) / scale; + oldh = (CGFloat)CGBitmapContextGetHeight (drawingBuffer) / scale; +#else + oldw = FRAME_PIXEL_WIDTH (emacsframe); + oldh = FRAME_PIXEL_HEIGHT (emacsframe); +#endif + neww = (int)NSWidth (frame); + newh = (int)NSHeight (frame); + + NSTRACE ("[EmacsView viewDidResize]"); + + /* Don't want to do anything when the view size hasn't changed. */ + if ((oldh == newh && oldw == neww)) + { + NSTRACE_MSG ("No change"); + return; + } + + NSTRACE_SIZE ("Original size", NSMakeSize (oldw, oldh)); + NSTRACE_SIZE ("New size", NSMakeSize (neww, newh)); + + change_frame_size (emacsframe, + FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww), + FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh), + 0, YES, 0, 1); + +#ifdef NS_DRAW_TO_BUFFER + [self createDrawingBuffer]; +#endif + SET_FRAME_GARBAGED (emacsframe); + cancel_mouse_face (emacsframe); +} + + - (void)windowDidBecomeKey: (NSNotification *)notification /* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */ { @@ -7480,10 +7464,6 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f maximizing_resize = NO; #endif -#ifdef NS_DRAW_TO_BUFFER - [self createDrawingBuffer]; -#endif - win = [[EmacsWindow alloc] initWithContentRect: r styleMask: (FRAME_UNDECORATED (f) @@ -7589,6 +7569,17 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f [NSApp registerServicesMenuSendTypes: ns_send_types returnTypes: [NSArray array]]; +#ifdef NS_DRAW_TO_BUFFER + [self createDrawingBuffer]; +#endif + + /* Set up view resize notifications. */ + [self setPostsFrameChangedNotifications:YES]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector (viewDidResize:) + name:NSViewFrameDidChangeNotification object:nil]; + /* macOS Sierra automatically enables tabbed windows. We can't allow this to be enabled until it's available on a Free system. Currently it only happens by accident and is buggy anyway. */ @@ -7618,9 +7609,8 @@ - (void)windowDidMove: sender return; if (screen != nil) { - emacsframe->left_pos = r.origin.x - NS_PARENT_WINDOW_LEFT_POS (emacsframe); - emacsframe->top_pos = - NS_PARENT_WINDOW_TOP_POS (emacsframe) - (r.origin.y + r.size.height); + emacsframe->left_pos = NSMinX (r) - NS_PARENT_WINDOW_LEFT_POS (emacsframe); + emacsframe->top_pos = NS_PARENT_WINDOW_TOP_POS (emacsframe) - NSMaxY (r); // FIXME: after event part below didExitFullScreen is not received // if (emacs_event) @@ -7919,7 +7909,6 @@ - (void)windowDidExitFullScreen /* provided for direct calls */ { [toolbar setVisible:YES]; update_frame_tool_bar (emacsframe); - [self updateFrameSize:YES]; [[self window] display]; } else @@ -8132,11 +8121,11 @@ - (void)toggleFullScreen: (id)sender // send notifications. [self windowWillExitFullScreen]; - [fw setFrame: [w frame] display:YES animate:ns_use_fullscreen_animation]; + [fw setFrame:[[w contentView] frame] + display:YES animate:ns_use_fullscreen_animation]; [fw close]; [w makeKeyAndOrderFront:NSApp]; [self windowDidExitFullScreen]; - [self updateFrameSize:YES]; } } @@ -8645,13 +8634,6 @@ - (instancetype)setMiniwindowImage: (BOOL) setMini } -- (void) setRows: (int) r andColumns: (int) c -{ - NSTRACE ("[EmacsView setRows:%d andColumns:%d]", r, c); - rows = r; - cols = c; -} - - (int) fullscreenState { return fs_state; commit 6a60701bba3d87f5d9a1730e18b6da827f41a062 Author: Mattias Engdegård Date: Thu Apr 16 19:40:26 2020 +0200 Improve regexp in org-table-finish-edit-field * lisp/org/org-table.el (org-table-finish-edit-field): Further improvement of regexp, as suggested by Paul Eggert. diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index 8927b1c2ed..abba29952e 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -2005,7 +2005,7 @@ the table and kill the editing buffer." text) (goto-char (point-min)) (while (re-search-forward "^#.*\n?" nil t) (replace-match "")) - (while (re-search-forward "[ \t]*\\(?:\n[ \t]*\\)+" nil t) + (while (re-search-forward "[ \t]*\n[ \t\n]*" nil t) (replace-match " ")) (setq text (org-trim (buffer-string))) (set-window-configuration cw) commit 0bb3aec2675779d0e0aba12a60274aedea49086a Author: Michael Albinus Date: Thu Apr 16 19:51:23 2020 +0200 Ignore D-Bus errors in tramp-gvfs.el (Bug#40655) * lisp/net/tramp-gvfs.el (with-tramp-dbus-call-method): Ignore D-Bus errors. (Bug#40655) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 526c564ee3..f19e510eb6 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -912,7 +912,9 @@ or `dbus-call-method-asynchronously'." #'dbus-call-method #'dbus-call-method-asynchronously)) (args (append (list ,bus ,service ,path ,interface ,method) (if ,synchronous (list ,@args) (list 'ignore ,@args))))) - (tramp-dbus-function ,vec func args))) + ;; We use `dbus-ignore-errors', because this macro is also called + ;; when loading. + (dbus-ignore-errors (tramp-dbus-function ,vec func args)))) (font-lock-add-keywords 'emacs-lisp-mode '("\\")) commit 22ba04742072098be60ec223ed2e97fa9a09b045 Author: Alan Mackenzie Date: Thu Apr 16 17:01:14 2020 +0000 (forward-comment -n): escaped newline is sometimes NOT end of comment * src/syntax.c (Fforward_comment) When comment-end-can-be-escaped is non-nil, don't attempt back_comment when point is just after an escaped newline, etc. diff --git a/src/syntax.c b/src/syntax.c index e24b98da32..ff125b137c 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -2572,8 +2572,9 @@ between them, return t; otherwise return nil. */) } else if (code == Sendcomment) { - found = back_comment (from, from_byte, stop, comnested, comstyle, - &out_charpos, &out_bytepos); + found = (!quoted || !Vcomment_end_can_be_escaped) + && back_comment (from, from_byte, stop, comnested, comstyle, + &out_charpos, &out_bytepos); if (!found) { if (c == '\n') commit 0127118c2592ee5103cc36be5aaed0c9443ae82f Author: Paul Eggert Date: Thu Apr 16 09:22:42 2020 -0700 Fix type-checking bug in vertical-motion * src/indent.c (Fvertical_motion): Fix bug where the type of lcols was checked too late. diff --git a/src/indent.c b/src/indent.c index dd81b983d4..06f11a251e 100644 --- a/src/indent.c +++ b/src/indent.c @@ -2091,19 +2091,17 @@ whether or not it is currently displayed in some window. */) struct it it; struct text_pos pt; struct window *w; - Lisp_Object lcols; + Lisp_Object lcols = Qnil; void *itdata = NULL; ptrdiff_t count = SPECPDL_INDEX (); /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */ - bool lcols_given = CONSP (lines); - if (lcols_given) + if (CONSP (lines)) { lcols = XCAR (lines); + CHECK_NUMBER (lcols); lines = XCDR (lines); } - else - lcols = make_fixnum (0); /* shut up stupid GCC warning */ CHECK_FIXNUM (lines); w = decode_live_window (window); @@ -2281,9 +2279,9 @@ whether or not it is currently displayed in some window. */) overshoot_handled = 1; } - if (lcols_given) + if (!NILP (lcols)) to_x = - window_column_x (w, window, extract_float (lcols), lcols) + window_column_x (w, window, XFLOATINT (lcols), lcols) + lnum_pixel_width; if (nlines <= 0) { @@ -2334,7 +2332,7 @@ whether or not it is currently displayed in some window. */) /* Move to the goal column, if one was specified. If the window was originally hscrolled, the goal column is interpreted as an addition to the hscroll amount. */ - if (lcols_given) + if (!NILP (lcols)) { move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X); /* If we find ourselves in the middle of an overlay string commit cead6f0ad18206401b5180fd44f848a76fed8e43 Author: Glenn Morris Date: Thu Apr 16 09:05:52 2020 -0700 * src/indent.c (Fvertical_motion): Fix int/Lisp_Object mix up. diff --git a/src/indent.c b/src/indent.c index 2d07791606..dd81b983d4 100644 --- a/src/indent.c +++ b/src/indent.c @@ -2103,7 +2103,7 @@ whether or not it is currently displayed in some window. */) lines = XCDR (lines); } else - lcols = 0; /* shut up stupid GCC warning */ + lcols = make_fixnum (0); /* shut up stupid GCC warning */ CHECK_FIXNUM (lines); w = decode_live_window (window); commit b5e9beda8d80345ec4c2d2ecec9c03cc31c1eb29 Author: Mattias Engdegård Date: Thu Apr 16 17:33:02 2020 +0200 ; * lisp/files.el (directory-files-no-dot-files-regexp): Arg name. diff --git a/lisp/files.el b/lisp/files.el index b2b14e1b90..fa72e51c49 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -5756,7 +5756,7 @@ If called interactively, then PARENTS is non-nil." "[^.]\\|\\.\\.\\." "Regexp matching any file name except \".\" and \"..\". More precisely, it matches parts of any nonempty string except those two. -It is useful as the PATTERN argument to `directory-files' and +It is useful as the regexp argument to `directory-files' and `directory-files-and-attributes'.") (defun files--force (no-such fn &rest args) commit d5a7df8c02f04102d50a5cd2290262f59f2b1415 Author: Mattias Engdegård Date: Thu Apr 16 12:05:02 2020 +0200 Use directory-files-no-dot-files-regexp wherever possible Suggested by Paul Eggert. * lisp/files.el (directory-files-no-dot-files-regexp): Clarify semantics and purpose. * lisp/dired.el (dired-re-no-dot): Define as obsolete alias of directory-files-no-dot-files-regexp. (dired-delete-file): * lisp/gnus/gnus-util.el (gnus-delete-directory): * lisp/net/ange-ftp.el (ange-ftp-delete-directory): * lisp/obsolete/vc-arch.el (vc-arch-trim-revlib): * lisp/org/ob-core.el (org-babel-remove-temporary-directory): * lisp/vc/vc-rcs.el (vc-rcs-unregister): Use directory-files-no-dot-files-regexp. diff --git a/lisp/dired.el b/lisp/dired.el index 9583d5d809..14bbb28db5 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -3235,8 +3235,8 @@ Any other value means to ask for each directory." (const :tag "Confirm for each top directory only" top)) :group 'dired) -;; Match anything but `.' and `..'. -(defvar dired-re-no-dot (rx (or (not ".") "..."))) +(define-obsolete-variable-alias 'dired-re-no-dot + 'directory-files-no-dot-files-regexp "28.1") ;; Delete file, possibly delete a directory and all its files. ;; This function is useful outside of dired. One could change its name @@ -3258,7 +3258,9 @@ TRASH non-nil means to trash the file instead of deleting, provided ;; but more efficient (if (not (eq t (car (file-attributes file)))) (delete-file file trash) - (let* ((empty-dir-p (null (directory-files file t dired-re-no-dot)))) + (let* ((empty-dir-p (null (directory-files + file t + directory-files-no-dot-files-regexp)))) (if (and recursive (not empty-dir-p)) (unless (eq recursive 'always) (let ((prompt diff --git a/lisp/files.el b/lisp/files.el index 04c271d796..b2b14e1b90 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -5754,7 +5754,10 @@ If called interactively, then PARENTS is non-nil." (defconst directory-files-no-dot-files-regexp "[^.]\\|\\.\\.\\." - "Regexp matching any file name except \".\" and \"..\".") + "Regexp matching any file name except \".\" and \"..\". +More precisely, it matches parts of any nonempty string except those two. +It is useful as the PATTERN argument to `directory-files' and +`directory-files-and-attributes'.") (defun files--force (no-such fn &rest args) "Use NO-SUCH to affect behavior of function FN applied to list ARGS. diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index f0d328d334..8d8956f1fb 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -768,7 +768,7 @@ nil. See also `gnus-bind-print-variables'." If there's no subdirectory, delete DIRECTORY as well." (when (file-directory-p directory) (let ((files (directory-files - directory t (rx (or (not ".") "...")))) + directory t directory-files-no-dot-files-regexp)) file dir) (while files (setq file (pop files)) diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el index af37df07f9..70aeac00d7 100644 --- a/lisp/gnus/gnus-uu.el +++ b/lisp/gnus/gnus-uu.el @@ -1674,7 +1674,7 @@ Gnus might fail to display all of it.") did-unpack)) (defun gnus-uu-dir-files (dir) - (let ((dirs (directory-files dir t (rx (or (not ".") "...")))) + (let ((dirs (directory-files dir t directory-files-no-dot-files-regexp)) files file) (while dirs (if (file-directory-p (setq file (car dirs))) diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index bf20128b61..0cb8d7cb83 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -4169,8 +4169,7 @@ directory, so that Emacs will know its current contents." (if (file-directory-p file) (ange-ftp-delete-directory file recursive trash) (delete-file file trash))) - ;; We do not want to delete "." and "..". - (directory-files dir 'full (rx (or (not ".") "..."))))) + (directory-files dir 'full directory-files-no-dot-files-regexp))) (if parsed (let* ((host (nth 0 parsed)) (user (nth 1 parsed)) diff --git a/lisp/obsolete/vc-arch.el b/lisp/obsolete/vc-arch.el index bcdefac518..93bd991eb3 100644 --- a/lisp/obsolete/vc-arch.el +++ b/lisp/obsolete/vc-arch.el @@ -597,20 +597,21 @@ CALLBACK expects (ENTRIES &optional MORE-TO-COME); see (unless (file-writable-p rl-dir) (error "No writable revlib directory found")) (message "Revlib at %s" rl-dir) - (let* ((archives (directory-files rl-dir 'full (rx (or (not ".") "...")))) + (let* ((archives (directory-files rl-dir 'full + directory-files-no-dot-files-regexp)) (categories (apply 'append (mapcar (lambda (dir) (when (file-directory-p dir) - (directory-files dir 'full - (rx (or (not ".") "..."))))) + (directory-files + dir 'full directory-files-no-dot-files-regexp))) archives))) (branches (apply 'append (mapcar (lambda (dir) (when (file-directory-p dir) - (directory-files dir 'full - (rx (or (not ".") "..."))))) + (directory-files + dir 'full directory-files-no-dot-files-regexp))) categories))) (versions (apply 'append diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el index debc27cfbf..fe9af1ce60 100644 --- a/lisp/org/ob-core.el +++ b/lisp/org/ob-core.el @@ -3053,9 +3053,8 @@ of `org-babel-temporary-directory'." (if (eq t (car (file-attributes file))) (delete-directory file) (delete-file file))) - ;; We do not want to delete "." and "..". (directory-files org-babel-temporary-directory 'full - (rx (or (not ".") "...")))) + directory-files-no-dot-files-regexp)) (delete-directory org-babel-temporary-directory)) (error (message "Failed to remove temporary Org-babel directory %s" diff --git a/lisp/vc/vc-rcs.el b/lisp/vc/vc-rcs.el index 273f37c10d..23f088b0cf 100644 --- a/lisp/vc/vc-rcs.el +++ b/lisp/vc/vc-rcs.el @@ -312,7 +312,7 @@ whether to remove it." (and (string= (file-name-nondirectory (directory-file-name dir)) "RCS") ;; check whether RCS dir is empty, i.e. it does not ;; contain any files except "." and ".." - (not (directory-files dir nil (rx (or (not ".") "...")))) + (not (directory-files dir nil directory-files-no-dot-files-regexp)) (yes-or-no-p (format "Directory %s is empty; remove it? " dir)) (delete-directory dir))))) commit 7839390f271211882414f167e8e680b3154ee929 Author: Mattias Engdegård Date: Thu Apr 16 11:27:43 2020 +0200 Quote semanticdb-ebrowse-default-file-name in regexp Noticed by Andreas Schwab. * lisp/cedet/semantic/db-ebrowse.el (semanticdb-load-ebrowse-caches): Quote file name in regexp. diff --git a/lisp/cedet/semantic/db-ebrowse.el b/lisp/cedet/semantic/db-ebrowse.el index 6262efb5b8..d63e5bc486 100644 --- a/lisp/cedet/semantic/db-ebrowse.el +++ b/lisp/cedet/semantic/db-ebrowse.el @@ -181,7 +181,8 @@ is specified by `semanticdb-default-save-directory'." "Load all semanticdb controlled EBROWSE caches." (interactive) (let ((f (directory-files semanticdb-default-save-directory - t (concat semanticdb-ebrowse-default-file-name + t (concat (regexp-quote + semanticdb-ebrowse-default-file-name) "-load\\.el\\'") t))) (while f commit 905c0a13f7929298cb36151f46dbef03f7bdcbe4 Author: Mattias Engdegård Date: Thu Apr 16 11:04:24 2020 +0200 Fix bugs, inefficiencies and bad style in regexps Found by relint. See discussion at https://lists.gnu.org/archive/html/emacs-devel/2020-04/msg00265.html * lisp/org/org-table.el (org-table-finish-edit-field): * lisp/arc-mode.el (archive-rar-summarize): Avoid wrapped subsumption in repeated sequences. * lisp/erc/erc-dcc.el (erc-dcc-ctcp-query-send-regexp): Replace inefficient repeated empty-matching expression with a plain greedy form. (erc-dcc-handle-ctcp-send): Adjust group numbers. * lisp/net/puny.el (puny-encode-domain): Fix fast-path shortcut pattern so that it actually works as intended. * lisp/progmodes/gdb-mi.el (gdb-control-commands-regexp): * lisp/vc/diff-mode.el (diff-imenu-generic-expression): Remove superfluous backslashes. * lisp/progmodes/scheme.el (scheme-imenu-generic-expression): Correct confused definition-matching pattern which would match more than intended. * lisp/textmodes/sgml-mode.el (sgml-tag-name-re): Avoid inefficient matching by using the fact that the first character cannot match the last char of sgml-name-re. diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index 4d36667969..c918f06c80 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el @@ -2032,7 +2032,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." (call-process "lsar" nil t nil "-l" (or file copy)) (if copy (delete-file copy))) (goto-char (point-min)) - (re-search-forward "^\\(\s+=+\s*\\)+\n") + (re-search-forward "^\\(?:\s+=+\\)+\s*\n") (while (looking-at (concat "^\s+[0-9.]+\s+D?-+\s+" ; Flags "\\([0-9-]+\\)\s+" ; Size "\\([-0-9.]+\\)%?\s+" ; Ratio diff --git a/lisp/erc/erc-dcc.el b/lisp/erc/erc-dcc.el index 26701cec1e..8ccceec459 100644 --- a/lisp/erc/erc-dcc.el +++ b/lisp/erc/erc-dcc.el @@ -627,11 +627,11 @@ that subcommand." ?q query ?n nick ?u login ?h host)))) (defconst erc-dcc-ctcp-query-send-regexp - (concat "^DCC SEND \\(" + (concat "^DCC SEND \\(?:" ;; Following part matches either filename without spaces ;; or filename enclosed in double quotes with any number ;; of escaped double quotes inside. - "\"\\(\\(.*?\\(\\\\\"\\)?\\)+?\\)\"\\|\\([^ ]+\\)" + "\"\\(\\(?:\\\\\"\\|[^\"\\]\\)+\\)\"\\|\\([^ ]+\\)" "\\) \\([0-9]+\\) \\([0-9]+\\) *\\([0-9]*\\)")) (define-inline erc-dcc-unquote-filename (filename) @@ -653,11 +653,11 @@ It extracts the information about the dcc request and adds it to ?r "SEND" ?n nick ?u login ?h host)) ((string-match erc-dcc-ctcp-query-send-regexp query) (let ((filename - (or (match-string 5 query) - (erc-dcc-unquote-filename (match-string 2 query)))) - (ip (erc-decimal-to-ip (match-string 6 query))) - (port (match-string 7 query)) - (size (match-string 8 query))) + (or (match-string 2 query) + (erc-dcc-unquote-filename (match-string 1 query)))) + (ip (erc-decimal-to-ip (match-string 3 query))) + (port (match-string 4 query)) + (size (match-string 5 query))) ;; FIXME: a warning really should also be sent ;; if the ip address != the host the dcc sender is on. (erc-display-message diff --git a/lisp/net/puny.el b/lisp/net/puny.el index 60a6c12e6c..6987d25324 100644 --- a/lisp/net/puny.el +++ b/lisp/net/puny.el @@ -35,7 +35,7 @@ For instance, \"fśf.org\" => \"xn--ff-2sa.org\"." ;; The vast majority of domain names are not IDNA domain names, so ;; add a check first to avoid doing unnecessary work. - (if (string-match "\\'[[:ascii:]]+\\'" domain) + (if (string-match "\\`[[:ascii:]]+\\'" domain) domain (mapconcat 'puny-encode-string (split-string domain "[.]") "."))) diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index 98702feb37..8927b1c2ed 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -2005,7 +2005,7 @@ the table and kill the editing buffer." text) (goto-char (point-min)) (while (re-search-forward "^#.*\n?" nil t) (replace-match "")) - (while (re-search-forward "\\([ \t]*\n[ \t]*\\)+" nil t) + (while (re-search-forward "[ \t]*\\(?:\n[ \t]*\\)+" nil t) (replace-match " ")) (setq text (org-trim (buffer-string))) (set-window-configuration cw) diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index ba586981de..c1184211d0 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -1867,7 +1867,7 @@ static char *magick[] = { "\\|def\\(i\\(ne?\\)?\\)?\\|doc\\(u\\(m\\(e\\(nt?\\)?\\)?\\)?\\)?\\|" gdb-python-guile-commands-regexp "\\|while-stepping\\|stepp\\(i\\(ng?\\)?\\)?\\|ws\\|actions" - "\\|expl\\(o\\(r\\e?\\)?\\)?" + "\\|expl\\(o\\(re?\\)?\\)?" "\\)\\([[:blank:]]+\\([^[:blank:]]*\\)\\)*$") "Regexp matching GDB commands that enter a recursive reading loop. As long as GDB is in the recursive reading loop, it does not expect diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el index 751d7da542..33ba0d11d8 100644 --- a/lisp/progmodes/scheme.el +++ b/lisp/progmodes/scheme.el @@ -116,7 +116,7 @@ (defvar scheme-imenu-generic-expression '((nil - "^(define\\(\\|-\\(generic\\(\\|-procedure\\)\\|method\\)\\)*\\s-+(?\\(\\sw+\\)" 4) + "^(define\\(?:-\\(?:generic\\(?:-procedure\\)?\\|method\\)\\)?\\s-+(?\\(\\sw+\\)" 1) ("Types" "^(define-class\\s-+(?\\(\\sw+\\)" 1) ("Macros" diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 6152a8ad0a..9b29b844d0 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -286,7 +286,10 @@ separated by a space." (defconst sgml-namespace-re "[_[:alpha:]][-_.[:alnum:]]*") (defconst sgml-name-re "[_:[:alpha:]][-_.:[:alnum:]]*") (defconst sgml-tag-name-re (concat "<\\([!/?]?" sgml-name-re "\\)")) -(defconst sgml-attrs-re "\\(?:[^\"'/><]\\|\"[^\"]*\"\\|'[^']*'\\)*") +(defconst sgml-attrs-re + ;; This pattern cannot begin with a character matched by the end of + ;; `sgml-name-re' above. + "\\(?:[^_.:\"'/><[:alnum:]-]\\(?:[^\"'/><]\\|\"[^\"]*\"\\|'[^']*'\\)*\\)?") (defconst sgml-start-tag-regex (concat "<" sgml-name-re sgml-attrs-re) "Regular expression that matches a non-empty start tag. Any terminating `>' or `/' is not matched.") diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index da2d5ed50e..d194d6c0a0 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -484,7 +484,7 @@ and the face `diff-added' for added lines.") ;; Prefer second name as first is most likely to be a backup or ;; version-control name. The [\t\n] at the end of the unidiff pattern ;; catches Debian source diff files (which lack the trailing date). - '((nil "\\+\\+\\+\\ \\([^\t\n]+\\)[\t\n]" 1) ; unidiffs + '((nil "\\+\\+\\+ \\([^\t\n]+\\)[\t\n]" 1) ; unidiffs (nil "^--- \\([^\t\n]+\\)\t.*\n\\*" 1))) ; context diffs ;;;; commit 01436fddfb2587271391e72b7eaa6c5c541b46d8 Author: Mattias Engdegård Date: Thu Apr 16 09:06:37 2020 +0200 Regularise some file-matching regexps * admin/authors.el (authors-obsolete-files-regexps) (authors-renamed-files-regexps): Replace ^ and $ with \` and \'. diff --git a/admin/authors.el b/admin/authors.el index fd17a3394d..13b203b9bc 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -283,9 +283,9 @@ If REALNAME is nil, ignore that author.") (defvar authors-obsolete-files-regexps - '(".*loaddefs\\.el$" ; not obsolete, but auto-generated - "\\.\\(bzr\\|cvs\\|git\\)ignore$" ; obsolete or uninteresting - "\\.arch-inventory$" + '(".*loaddefs\\.el\\'" ; not obsolete, but auto-generated + "\\.\\(bzr\\|cvs\\|git\\)ignore\\'" ; obsolete or uninteresting + "\\.arch-inventory\\'" "ChangeLog\\(\\.[0-9]+\\)?\\'" "\\(automated\\|test\\)/data/" ; not interesting "cedet/tests/" @@ -1140,7 +1140,7 @@ Elements are (OLDNAME . NEWNAME).") \\(\\(cs\\|fr\\|sk\\)-\\)?survival\\)\\.tex\\'" "refcards/\\&") ("\\`refcard-\\(de\\|pl\\)\\.tex\\'" "refcards/\\1-refcard.tex") ("\\`\\(refcards/\\)?fr-drdref\\.tex\\'" "refcards/fr-dired-ref.tex") - ("^\\(TUTORIAL[^/]*\\)" "tutorials/\\1") + ("\\`\\(TUTORIAL[^/]*\\)" "tutorials/\\1") ("\\`themes/dev-\\(tsdh-\\(?:light\\|dark\\)-theme\\.el\\)\\'" "themes/\\1") ;; Moved from lisp/toolbar to etc/images. @@ -1165,9 +1165,9 @@ remove\\|run\\|until\\|up\\|watch\\)\\(\\.\\(?:pb\\|xp\\)m\\)\\'" ("\\`\\(toolbar/gud-\\|images/gud/\\)s\\(i\\)?\\(\\.\\(?:pb\\|xp\\)m\\)\\'" "images/gud/step\\2\\3") ("\\`toolbar/lc-\\([-a-z]+\\.xpm\\)\\'" "images/low-color/\\1") - ("^\\(tree-widget/\\(?:default\\|folder\\)/[-a-z]+\\.\\(png\\|xpm\\)\\)$" + ("\\`\\(tree-widget/\\(?:default\\|folder\\)/[-a-z]+\\.\\(png\\|xpm\\)\\)\\'" "images/\\1") - ("^\\(images/icons/\\)mac\\(emacs\\)_\\([0-9]+\\)\\(\\.png\\)" + ("\\`\\(images/icons/\\)mac\\(emacs\\)_\\([0-9]+\\)\\(\\.png\\)" "\\1\\2\\3_mac\\4") ("\\(images/icons/\\)emacs_\\([0-9][0-9]\\)\\.png" "\\1hicolor/\\2x\\2/apps/emacs.png") @@ -1198,10 +1198,10 @@ ediff\\|emerge\\|log-edit\\|log-view\\|pcvs\\|smerge-mode\\|vc\\)\\.el\\'" ;; Maybe not the exact new name, but disambiguates from lisp/. ("automated/\\([^/]*\\)\\.el\\'" "\\1-tests.el") ;; NB lax rules should come last. - ("^m/m-\\(.*\\.h\\)$" "m/\\1" t) - ("^m-\\(.*\\.h\\)$" "\\1" t) - ("^s/s-\\(.*\\.h\\)$" "s/\\1" t) - ("^s-\\(.*\\.h\\)$" "\\1" t) + ("\\`m/m-\\(.*\\.h\\)\\'" "m/\\1" t) + ("\\`m-\\(.*\\.h\\)\\'" "\\1" t) + ("\\`s/s-\\(.*\\.h\\)\\'" "s/\\1" t) + ("\\`s-\\(.*\\.h\\)\\'" "\\1" t) ("\\.\\(el\\|[ch]\\|x[pb]m\\|pbm\\)\\'" t t) ) "List of regexps and rewriting rules for renamed files. commit c77d6af1ddb4cc2a515397e955b8389fa9025d8c Author: Eli Zaretskii Date: Thu Apr 16 13:08:01 2020 +0300 Avoid compiler warning in indent.c * src/indent.c (Fvertical_motion): Avoid compilation warning. Reported by Juanma Barranquero . diff --git a/src/indent.c b/src/indent.c index f7db42783c..2d07791606 100644 --- a/src/indent.c +++ b/src/indent.c @@ -2102,6 +2102,8 @@ whether or not it is currently displayed in some window. */) lcols = XCAR (lines); lines = XCDR (lines); } + else + lcols = 0; /* shut up stupid GCC warning */ CHECK_FIXNUM (lines); w = decode_live_window (window); commit 82c1d150938b38435c0ae9aa921d7c2739ed200c Author: Eli Zaretskii Date: Thu Apr 16 12:52:35 2020 +0300 ; * src/w32image.c (w32_select_active_frame): Comment about GUID values. diff --git a/src/w32image.c b/src/w32image.c index 80c3247e97..0a2a55d3f6 100644 --- a/src/w32image.c +++ b/src/w32image.c @@ -283,6 +283,11 @@ w32_select_active_frame (GpBitmap *pBitmap, int frame, int *nframes, *delay = 0.0; if (count) { + /* The following call will fill pDimensionIDs[0] with the + FrameDimensionTime GUID for GIF images, and + FrameDimensionPage GUID for other image types. Multi-page + GIF and TIFF images expect these values in the + GdipImageSelectActiveFrame call below. */ status = GdipImageGetFrameDimensionsList (pBitmap, pDimensionIDs, 1); status = GdipImageGetFrameCount (pBitmap, &pDimensionIDs[0], &frameCount); if (status == Ok && frameCount > 1)