commit 9a56b4e6864c4e0815bb67805cfa67910ab3eeb5 (HEAD, refs/remotes/origin/master) Author: Stefan Kangas Date: Mon Jan 31 07:42:50 2022 +0100 Factor out function to check for clang in tests This also stops a flymake test from failing on my machine. * lisp/emacs-lisp/ert-x.el (ert-gcc-is-clang-p): New function factored out from ... * test/lisp/progmodes/flymake-tests.el (flymake-tests--gcc-is-clang): * test/lisp/cedet/semantic/bovine/gcc-tests.el (semantic-gcc-test-output-parser-this-machine): ... here. * test/lisp/progmodes/flymake-tests.el (different-diagnostic-types) (included-c-header-files): * test/lisp/cedet/semantic/bovine/gcc-tests.el (semantic-gcc-test-output-parser-this-machine): Use above new function. diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el index 2818d4b6cc..0e412a8d34 100644 --- a/lisp/emacs-lisp/ert-x.el +++ b/lisp/emacs-lisp/ert-x.el @@ -475,6 +475,14 @@ The same keyword arguments are supported as in :directory t ,@body)) +(defun ert-gcc-is-clang-p () + "Return non-nil if the `gcc' command actually runs the Clang compiler." + ;; Some macOS machines run llvm when you type gcc. (!) + ;; We can't even check if it's a symlink; it's a binary placed in + ;; "/usr/bin/gcc". So we need to check the output. + (string-match "Apple \\(LLVM\\|[Cc]lang\\)\\|Xcode\\.app" + (shell-command-to-string "gcc --version"))) + (provide 'ert-x) ;;; ert-x.el ends here diff --git a/test/lisp/cedet/semantic/bovine/gcc-tests.el b/test/lisp/cedet/semantic/bovine/gcc-tests.el index 2e61f91e58..525843d996 100644 --- a/test/lisp/cedet/semantic/bovine/gcc-tests.el +++ b/test/lisp/cedet/semantic/bovine/gcc-tests.el @@ -122,14 +122,9 @@ gcc version 2.95.2 19991024 (release)" (ert-deftest semantic-gcc-test-output-parser-this-machine () "Test the output parser against the machine currently running Emacs." - (skip-unless (executable-find "gcc")) + (skip-unless (and (executable-find "gcc") + (not (ert-gcc-is-clang-p)))) (let ((semantic-gcc-test-strings (list (semantic-gcc-query "gcc" "-v")))) - ;; Some macOS machines run llvm when you type gcc. (!) - ;; We can't even check if it's a symlink; it's a binary placed in - ;; "/usr/bin/gcc". So check the output and just skip this test if - ;; it looks like that's the case. - (unless (string-match "Apple \\(LLVM\\|clang\\)\\|Xcode\\.app" - (car semantic-gcc-test-strings)) - (semantic-gcc-test-output-parser)))) + (semantic-gcc-test-output-parser))) ;;; gcc-tests.el ends here diff --git a/test/lisp/progmodes/flymake-tests.el b/test/lisp/progmodes/flymake-tests.el index ced7b5aace..71b03b21e5 100644 --- a/test/lisp/progmodes/flymake-tests.el +++ b/test/lisp/progmodes/flymake-tests.el @@ -140,15 +140,10 @@ SEVERITY-PREDICATE is used to setup (flymake-goto-next-error) (should (eq 'flymake-error (face-at-point))))))) -(defun flymake-tests--gcc-is-clang () - "Whether the `gcc' command actually runs the Clang compiler." - (string-match "[Cc]lang version " - (shell-command-to-string "gcc --version"))) - (ert-deftest different-diagnostic-types () "Test GCC warning via function predicate." (skip-unless (and (executable-find "gcc") - (not (flymake-tests--gcc-is-clang)) + (not (ert-gcc-is-clang-p)) (version<= "5" (string-trim (shell-command-to-string "gcc -dumpversion"))) @@ -173,7 +168,7 @@ SEVERITY-PREDICATE is used to setup (ert-deftest included-c-header-files () "Test inclusion of .h header files." (skip-unless (and (executable-find "gcc") - (not (flymake-tests--gcc-is-clang)) + (not (ert-gcc-is-clang-p)) (executable-find "make"))) (let ((flymake-wrap-around nil)) (flymake-tests--with-flymake commit d464454f4502e337d4114e7b818aad11c9506497 Author: Stefan Kangas Date: Mon Jan 31 00:10:58 2022 +0100 * lisp/image.el (image-map): Use defvar-keymap. diff --git a/lisp/image.el b/lisp/image.el index 80815a8a66..ec4ee06eb1 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -171,18 +171,16 @@ or \"ffmpeg\") is installed." (define-error 'unknown-image-type "Unknown image type") -;; Map put into text properties on images. -(defvar image-map - (let ((map (make-sparse-keymap))) - (define-key map "-" 'image-decrease-size) - (define-key map "+" 'image-increase-size) - (define-key map [C-wheel-down] 'image-mouse-decrease-size) - (define-key map [C-mouse-5] 'image-mouse-decrease-size) - (define-key map [C-wheel-up] 'image-mouse-increase-size) - (define-key map [C-mouse-4] 'image-mouse-increase-size) - (define-key map "r" 'image-rotate) - (define-key map "o" 'image-save) - map)) +(defvar-keymap image-map + :doc "Map put into text properties on images." + "-" #'image-decrease-size + "+" #'image-increase-size + "r" #'image-rotate + "o" #'image-save + "C-" #'image-mouse-decrease-size + "C-" #'image-mouse-decrease-size + "C-" #'image-mouse-increase-size + "C-" #'image-mouse-increase-size) (defun image-load-path-for-library (library image &optional path no-error) "Return a suitable search path for images used by LIBRARY. commit 3652170d7dd3a0aa3cf59d7ccffbf13d6fa0118e Merge: cb91643c97 6f282b31ad Author: Stefan Kangas Date: Mon Jan 31 06:58:23 2022 +0100 Merge from origin/emacs-28 6f282b31ad Update to Org 9.5.2-13-gdd6486 6636231b2c ; * lisp/international/latin1-disp.el: Update commentary. f22e9ba9ac Fix regression in Occur Edit mode commit cb91643c976540fc8c9d46e12a8edcb73be53467 Author: Po Lu Date: Mon Jan 31 13:45:48 2022 +0800 Fix motion not being reported on GTK when mouse moves over toolbar * src/gtkutil.c (xg_event_is_for_scrollbar): Make code consistent between XI2 and Core Input. diff --git a/src/gtkutil.c b/src/gtkutil.c index c46a2b3a6a..ea9c91d316 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -4853,9 +4853,8 @@ xg_event_is_for_scrollbar (struct frame *f, const EVENT *event) && event->type == GenericEvent && (event->xgeneric.extension == FRAME_DISPLAY_INFO (f)->xi2_opcode) - && ((event->xgeneric.evtype == XI_ButtonPress - && xev->detail < 4) - || (event->xgeneric.evtype == XI_Motion))) + && (event->xgeneric.evtype == XI_ButtonPress + && xev->detail < 4)) || (event->type == ButtonPress && event->xbutton.button < 4))) #else @@ -4887,19 +4886,7 @@ xg_event_is_for_scrollbar (struct frame *f, const EVENT *event) #else gwin = gdk_display_get_window_at_pointer (gdpy, NULL, NULL); #endif -#ifndef HAVE_XINPUT2 retval = gwin != gtk_widget_get_window (f->output_data.xp->edit_widget); -#else - retval = (gwin - && (gwin - != gtk_widget_get_window (f->output_data.xp->edit_widget))); -#endif -#ifdef HAVE_XINPUT2 - GtkWidget *grab = gtk_grab_get_current (); - if (event->type == GenericEvent - && event->xgeneric.evtype == XI_Motion) - retval = retval || (grab && GTK_IS_SCROLLBAR (grab)); -#endif } #ifdef HAVE_XINPUT2 else if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2 commit eb9dd321309d08708d65ad0c002238275c35c651 Author: Po Lu Date: Mon Jan 31 13:06:14 2022 +0800 Make cursor alpha consistent with a transparent background * src/xfont.c (xfont_draw): * src/xftfont.c (xftfont_shape): * src/xterm.c (x_clear_glyph_string_rect): Don't respect background alpha when drawing the cursor. diff --git a/src/xfont.c b/src/xfont.c index 7a50378a00..78f5f19bc8 100644 --- a/src/xfont.c +++ b/src/xfont.c @@ -1016,7 +1016,8 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font); x_xr_apply_ext_clip (s->f, gc); - x_xrender_color_from_gc_background (s->f, gc, &xc, true); + x_xrender_color_from_gc_background (s->f, gc, &xc, + s->hl != DRAW_CURSOR); XRenderFillRectangle (FRAME_X_DISPLAY (s->f), PictOpSrc, FRAME_X_PICTURE (s->f), &xc, x, y - ascent, s->width, height); diff --git a/src/xftfont.c b/src/xftfont.c index 1fcc0f4528..cfbf7cdc7a 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -519,7 +519,7 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y, 0, 0, s->clip, s->num_clips); else x_xr_reset_ext_clip (f); - x_xrender_color_from_gc_background (s->f, s->gc, &xc, true); + x_xrender_color_from_gc_background (s->f, s->gc, &xc, s->hl != DRAW_CURSOR); XRenderFillRectangle (FRAME_X_DISPLAY (s->f), PictOpSrc, FRAME_X_PICTURE (s->f), &xc, x, y - ascent, s->width, height); diff --git a/src/xterm.c b/src/xterm.c index e7019a3a74..edafd88211 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -2357,7 +2357,9 @@ x_compute_glyph_string_overhangs (struct glyph_string *s) static void x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h) { - x_clear_rectangle (s->f, s->gc, x, y, w, h, true); + x_clear_rectangle (s->f, s->gc, x, y, w, h, + (s->first_glyph->type != STRETCH_GLYPH + || s->hl != DRAW_CURSOR)); } commit ae8332b83093d7a3f879d87599e207d3dc215f88 Author: Po Lu Date: Mon Jan 31 12:58:11 2022 +0800 * src/xterm.c (x_xrender_color_from_gc_foreground): Fix omission error. diff --git a/src/xterm.c b/src/xterm.c index 80c0654e24..e7019a3a74 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -16365,6 +16365,10 @@ x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color, xc.pixel = xgcv.foreground; x_query_colors (f, &xc, 1); + color->alpha = (apply_alpha_background + ? 65535 * f->alpha_background + : 65535); + if (color->alpha == 65535) { color->red = xc.red; commit 04f9c3b8df6afaf1e9de9f2a4478f63fd959bf09 Author: Po Lu Date: Mon Jan 31 11:59:52 2022 +0800 Fix the X toolkit build * src/xterm.c (x_after_update_window_line): Update calls to `x_fill_rectangle'. diff --git a/src/xterm.c b/src/xterm.c index 08b00f8051..80c0654e24 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1974,9 +1974,9 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row) GC gc = f->output_data.x->normal_gc; XSetForeground (display, gc, color); - x_fill_rectangle (f, gc, 0, y, width, height); + x_fill_rectangle (f, gc, 0, y, width, height, true); x_fill_rectangle (f, gc, FRAME_PIXEL_WIDTH (f) - width, y, - width, height); + width, height, true); XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f)); } else commit a31914dda58ba9090abab21a4a66dead9c7a5bfd Author: Po Lu Date: Mon Jan 31 11:53:10 2022 +0800 Fix tooltip frame creation with 32-bit visuals * src/xfns.c (x_create_tip_frame): Define CWColormap and CWBorderPixel to use a 32-bit visual if available. diff --git a/src/xfns.c b/src/xfns.c index 6716acc25b..8887b92241 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -7191,7 +7191,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip; block_input (); - mask = CWBackPixel | CWOverrideRedirect | CWEventMask | CWCursor; + mask = (CWBackPixel | CWOverrideRedirect | CWEventMask + | CWCursor | CWColormap | CWBorderPixel); if (DoesSaveUnders (dpyinfo->screen)) mask |= CWSaveUnder; @@ -7201,9 +7202,11 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) attrs.override_redirect = True; attrs.save_under = True; attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f); + attrs.colormap = FRAME_X_COLORMAP (f); attrs.cursor = f->output_data.x->current_cursor = f->output_data.x->text_cursor; + attrs.border_pixel = f->output_data.x->border_pixel; /* Arrange for getting MapNotify and UnmapNotify events. */ attrs.event_mask = StructureNotifyMask; tip_window @@ -7214,7 +7217,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) 0, 0, 1, 1, /* Border. */ f->border_width, - CopyFromParent, InputOutput, CopyFromParent, + dpyinfo->n_planes, InputOutput, + FRAME_X_VISUAL (f), mask, &attrs); initial_set_up_x_back_buffer (f); XChangeProperty (FRAME_X_DISPLAY (f), tip_window, @@ -7223,17 +7227,21 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) (unsigned char *)&type, 1); unblock_input (); #else - uint32_t value_list[4]; + uint32_t value_list[6]; xcb_atom_t net_wm_window_type_tooltip = (xcb_atom_t) dpyinfo->Xatom_net_window_type_tooltip; + xcb_visualid_t visual_id + = (xcb_visualid_t) XVisualIDFromVisual (FRAME_X_VISUAL (f)); f->output_data.x->current_cursor = f->output_data.x->text_cursor; /* Values are set in the order of their enumeration in `enum xcb_cw_t'. */ value_list[0] = FRAME_BACKGROUND_PIXEL (f); - value_list[1] = true; - value_list[2] = XCB_EVENT_MASK_STRUCTURE_NOTIFY; - value_list[3] = (xcb_cursor_t) f->output_data.x->text_cursor; + value_list[1] = f->output_data.x->border_pixel; + value_list[2] = true; + value_list[3] = XCB_EVENT_MASK_STRUCTURE_NOTIFY; + value_list[4] = (xcb_colormap_t) FRAME_X_COLORMAP (f); + value_list[5] = (xcb_cursor_t) f->output_data.x->text_cursor; block_input (); tip_window @@ -7241,15 +7249,17 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) = (Window) xcb_generate_id (dpyinfo->xcb_connection); xcb_create_window (dpyinfo->xcb_connection, - XCB_COPY_FROM_PARENT, + dpyinfo->n_planes, (xcb_window_t) tip_window, (xcb_window_t) dpyinfo->root_window, 0, 0, 1, 1, f->border_width, XCB_WINDOW_CLASS_INPUT_OUTPUT, - XCB_COPY_FROM_PARENT, + visual_id, (XCB_CW_BACK_PIXEL + | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK + | XCB_CW_COLORMAP | XCB_CW_CURSOR), &value_list); commit 5c87d826201a5cae242ce5887a0aa7e24ad6f5ee Author: Po Lu Date: Mon Jan 31 10:39:12 2022 +0800 * etc/NEWS: Announce the 'alpha-background' frame parameter. diff --git a/etc/NEWS b/etc/NEWS index 184046c9ec..4583cfb095 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -174,6 +174,11 @@ and pop-up menus. This controls the style of the pre-edit and status areas of X input methods. ++++ +** New frame parameter 'alpha-background' and X resource "alphaBackground". +This controls the opacity of the text background when running on a +composited display. + --- ** New user option 'x-gtk-use-native-input'. This controls whether or not GTK input methods are used by Emacs, commit 2f32333cff29b8ffe8bf0034af4a0d4b17fc32f0 Author: Po Lu Date: Mon Jan 31 10:34:50 2022 +0800 Fix the no toolkit build. * src/xfns.c (x_window): Use n_planes instead of CopyFromParent for depth. diff --git a/src/xfns.c b/src/xfns.c index ed56b07214..6716acc25b 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -3780,7 +3780,7 @@ x_window (struct frame *f) f->top_pos, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), f->border_width, - CopyFromParent, /* depth */ + FRAME_DISPLAY_INFO (f)->n_planes, /* depth */ InputOutput, /* class */ FRAME_X_VISUAL (f), attribute_mask, &attributes); commit 7b137370558e8924a8282880bdffe84ff8324d28 Author: Lars Ingebrigtsen Date: Mon Jan 31 03:31:01 2022 +0100 Fix with-suppressed-warnings edebug spec * lisp/emacs-lisp/byte-run.el (with-suppressed-warnings): Fix edebug spec. diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index fedc10cea4..110f7e4abf 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -656,7 +656,7 @@ For the `mapcar' case, only the `mapcar' function can be used in the symbol list. For `suspicious', only `set-buffer' can be used." ;; Note: during compilation, this definition is overridden by the one in ;; byte-compile-initial-macro-environment. - (declare (debug (sexp &optional body)) (indent 1)) + (declare (debug (sexp body)) (indent 1)) (if (not (and (featurep 'macroexp) (boundp 'byte-compile--suppressed-warnings))) ;; If `macroexp' is not yet loaded, we're in the middle of commit 0a34aeee7e0fbc30a40ecd4191aba0b70e13cf8a Author: Po Lu Date: Mon Jan 31 10:30:24 2022 +0800 Fix builds without GTK * src/xfns.c (x_set_alpha_background): Don't call gtk_widget_set_app_paintable without GTK. diff --git a/src/xfns.c b/src/xfns.c index c0198fdc9d..ed56b07214 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -732,10 +732,12 @@ x_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { gui_set_alpha_background (f, arg, oldval); +#ifdef USE_GTK /* This prevents GTK from painting the window's background, which interferes with transparent background in some environments */ gtk_widget_set_app_paintable (FRAME_GTK_OUTER_WIDGET (f), f->alpha_background != 1.0); +#endif if (f->alpha_background != 1.0) { commit 1555453694d9c2861c447b2f030b125f60e48297 Author: Po Lu Date: Mon Jan 31 10:15:47 2022 +0800 Implement `alpha-background' on non-Cairo builds * src/frame.c (gui_set_alpha_background): Recompute basic faces so xft face ext info gets reset. * src/gtkutil.c (xg_create_frame_widgets): Attach to style updated signal. (xg_update_frame_menubar): Set menu bar visual correctly. (xg_widget_style_updated): New function. * src/xfns.c (x_set_alpha_background): New function. (x_frame_parm_handlers): Use x_set_alpha_background instead. * src/xfont.c (xfont_draw): * src/xftfont.c (xftfont_draw): Handle `alpha-background' parameter. * src/xterm.c (x_xr_ensure_picture): Export function. (x_update_opaque_region): New function. (x_fill_rectangle): New parameter `respect_alpha_background'. All callers changed. (handle_one_xevent): Set opaque region on ConfigureNotify. (x_drop_xrender_surfaces): Set opaque region. (x_xrender_color_from_gc_foreground): (x_xrender_color_from_gc_background): Premultiply alpha with components if asked for. * src/xterm.h (struct x_display_info): New atom `Xatom_net_wm_opaque_region'. diff --git a/src/frame.c b/src/frame.c index f94dff0a60..8750fe4889 100644 --- a/src/frame.c +++ b/src/frame.c @@ -5050,6 +5050,7 @@ gui_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval) f->alpha_background = alpha; + recompute_basic_faces (f); SET_FRAME_GARBAGED (f); } diff --git a/src/gtkutil.c b/src/gtkutil.c index ef6270dbcf..c46a2b3a6a 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -81,6 +81,10 @@ static void xg_im_context_commit (GtkIMContext *, gchar *, gpointer); static void xg_im_context_preedit_changed (GtkIMContext *, gpointer); static void xg_im_context_preedit_end (GtkIMContext *, gpointer); static bool xg_widget_key_press_event_cb (GtkWidget *, GdkEvent *, gpointer); + +#if GTK_CHECK_VERSION (3, 10, 0) +static void xg_widget_style_updated (GtkWidget *, gpointer); +#endif #endif #ifndef HAVE_GTK3 @@ -1460,6 +1464,13 @@ xg_create_frame_widgets (struct frame *f) } else wtop = gtk_window_new (type); + +#if GTK_CHECK_VERSION (3, 10, 0) + g_signal_connect (G_OBJECT (wtop), "style-updated", + G_CALLBACK (xg_widget_style_updated), f); +#endif + + gtk_widget_set_app_paintable (wtop, f->alpha_background != 1.0); #else if (f->tooltip) { @@ -1467,10 +1478,6 @@ xg_create_frame_widgets (struct frame *f) } wtop = gtk_window_new (type); gtk_widget_add_events (wtop, GDK_ALL_EVENTS_MASK); - - /* This prevents GTK from painting the window's background, which - would interfere with transparent background in some environments */ - gtk_widget_set_app_paintable (wtop, TRUE); #endif /* gtk_window_set_has_resize_grip is a Gtk+ 3.0 function but Ubuntu @@ -4044,6 +4051,18 @@ xg_update_frame_menubar (struct frame *f) gtk_widget_show_all (x->menubar_widget); gtk_widget_get_preferred_size (x->menubar_widget, NULL, &req); req.height *= xg_get_scale (f); + +#ifndef HAVE_PGTK + if (FRAME_DISPLAY_INFO (f)->n_planes == 32) + { + GdkScreen *screen = gtk_widget_get_screen (x->menubar_widget); + GdkVisual *visual = gdk_screen_get_system_visual (screen); + + gtk_widget_realize (x->menubar_widget); + gtk_widget_set_visual (x->menubar_widget, visual); + } +#endif + if (FRAME_MENUBAR_HEIGHT (f) != (req.height * scale)) { FRAME_MENUBAR_HEIGHT (f) = req.height * scale; @@ -6390,5 +6409,20 @@ xg_filter_key (struct frame *frame, XEvent *xkey) return result; } + +#if GTK_CHECK_VERSION (3, 10, 0) +static void +xg_widget_style_updated (GtkWidget *widget, gpointer user_data) +{ + struct frame *f = user_data; + + if (f->alpha_background < 1.0) + XChangeProperty (FRAME_X_DISPLAY (f), + FRAME_X_WINDOW (f), + FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region, + XA_CARDINAL, 32, PropModeReplace, + NULL, 0); +} +#endif #endif #endif /* USE_GTK */ diff --git a/src/xfns.c b/src/xfns.c index 7fe181fa3f..c0198fdc9d 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -727,6 +727,26 @@ x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value f->output_data.x->wait_for_wm = !NILP (new_value); } +static void +x_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval) +{ + gui_set_alpha_background (f, arg, oldval); + + /* This prevents GTK from painting the window's background, which + interferes with transparent background in some environments */ + gtk_widget_set_app_paintable (FRAME_GTK_OUTER_WIDGET (f), + f->alpha_background != 1.0); + + if (f->alpha_background != 1.0) + { + XChangeProperty (FRAME_X_DISPLAY (f), + FRAME_X_WINDOW (f), + FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region, + XA_CARDINAL, 32, PropModeReplace, + NULL, 0); + } +} + static void x_set_tool_bar_position (struct frame *f, Lisp_Object new_value, @@ -8583,7 +8603,7 @@ frame_parm_handler x_frame_parm_handlers[] = x_set_z_group, x_set_override_redirect, gui_set_no_special_glyphs, - gui_set_alpha_background, + x_set_alpha_background, }; void diff --git a/src/xfont.c b/src/xfont.c index b5765cfa7b..7a50378a00 100644 --- a/src/xfont.c +++ b/src/xfont.c @@ -1003,6 +1003,31 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y, unblock_input (); } +#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2)) + if (with_background + && FRAME_DISPLAY_INFO (s->f)->n_planes == 32 + && FRAME_CHECK_XR_VERSION (s->f, 0, 2)) + { + x_xr_ensure_picture (s->f); + + if (FRAME_X_PICTURE (s->f) != None) + { + XRenderColor xc; + int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font); + + x_xr_apply_ext_clip (s->f, gc); + x_xrender_color_from_gc_background (s->f, gc, &xc, true); + XRenderFillRectangle (FRAME_X_DISPLAY (s->f), + PictOpSrc, FRAME_X_PICTURE (s->f), + &xc, x, y - ascent, s->width, height); + x_xr_reset_ext_clip (s->f); + x_mark_frame_dirty (s->f); + + with_background = false; + } + } +#endif + if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0) { USE_SAFE_ALLOCA; diff --git a/src/xftfont.c b/src/xftfont.c index c2175d9614..1fcc0f4528 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -33,6 +33,10 @@ along with GNU Emacs. If not, see . */ #include "ftfont.h" #include "pdumper.h" +#ifdef HAVE_XRENDER +#include +#endif + #ifndef FC_LCD_FILTER /* Older fontconfig versions don't have FC_LCD_FILTER. */ # define FC_LCD_FILTER "lcdfilter" @@ -496,7 +500,40 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y, height = ascent = s->first_glyph->slice.glyphless.lower_yoff - s->first_glyph->slice.glyphless.upper_yoff; - XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height); + +#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2)) + if (with_background + && FRAME_DISPLAY_INFO (s->f)->n_planes == 32 + && FRAME_CHECK_XR_VERSION (s->f, 0, 2)) + { + x_xr_ensure_picture (s->f); + + if (FRAME_X_PICTURE (s->f) != None) + { + XRenderColor xc; + int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font); + + if (s->num_clips > 0) + XRenderSetPictureClipRectangles (FRAME_X_DISPLAY (s->f), + FRAME_X_PICTURE (s->f), + 0, 0, s->clip, s->num_clips); + else + x_xr_reset_ext_clip (f); + x_xrender_color_from_gc_background (s->f, s->gc, &xc, true); + XRenderFillRectangle (FRAME_X_DISPLAY (s->f), + PictOpSrc, FRAME_X_PICTURE (s->f), + &xc, x, y - ascent, s->width, height); + x_xr_reset_ext_clip (f); + x_mark_frame_dirty (s->f); + + with_background = false; + } + else + XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height); + } + else +#endif + XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height); } code = alloca (sizeof (FT_UInt) * len); for (i = 0; i < len; i++) diff --git a/src/xterm.c b/src/xterm.c index e41319e95e..08b00f8051 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -341,6 +341,7 @@ static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t); static void x_initialize (void); static bool x_get_current_wm_state (struct frame *, Window, int *, bool *); +static void x_update_opaque_region (struct frame *); /* Flush display of frame F. */ @@ -361,6 +362,7 @@ x_flush (struct frame *f) static void x_drop_xrender_surfaces (struct frame *f) { + x_update_opaque_region (f); font_drop_xrender_surfaces (f); #ifdef HAVE_XRENDER @@ -375,7 +377,7 @@ x_drop_xrender_surfaces (struct frame *f) } #ifdef HAVE_XRENDER -MAYBE_UNUSED static void +void x_xr_ensure_picture (struct frame *f) { if (FRAME_X_PICTURE (f) == None && FRAME_X_PICTURE_FORMAT (f)) @@ -444,6 +446,18 @@ record_event (char *locus, int type) #endif +static void +x_update_opaque_region (struct frame *f) +{ + if (f->alpha_background < 1.0) + XChangeProperty (FRAME_X_DISPLAY (f), + FRAME_X_WINDOW (f), + FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region, + XA_CARDINAL, 32, PropModeReplace, + NULL, 0); +} + + #if defined USE_CAIRO || defined HAVE_XRENDER static struct x_gc_ext_data * x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p) @@ -1244,8 +1258,8 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type) #endif /* USE_CAIRO */ -#if defined HAVE_XRENDER && !defined USE_CAIRO -MAYBE_UNUSED static void +#if defined HAVE_XRENDER +void x_xr_apply_ext_clip (struct frame *f, GC gc) { eassert (FRAME_X_PICTURE (f) != None); @@ -1259,7 +1273,7 @@ x_xr_apply_ext_clip (struct frame *f, GC gc) data->n_clip_rects); } -MAYBE_UNUSED static void +void x_xr_reset_ext_clip (struct frame *f) { XRenderPictureAttributes attrs = { .clip_mask = None }; @@ -1301,7 +1315,8 @@ x_reset_clip_rectangles (struct frame *f, GC gc) } static void -x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height) +x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height, + bool respect_alpha_background) { #ifdef USE_CAIRO Display *dpy = FRAME_X_DISPLAY (f); @@ -1339,6 +1354,29 @@ x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height) } x_end_cr_clip (f); #else +#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2)) + if (respect_alpha_background + && FRAME_DISPLAY_INFO (f)->n_planes == 32 + && FRAME_CHECK_XR_VERSION (f, 0, 2)) + { + x_xr_ensure_picture (f); + + if (FRAME_X_PICTURE (f) != None) + { + XRenderColor xc; + + x_xr_apply_ext_clip (f, gc); + x_xrender_color_from_gc_foreground (f, gc, &xc, true); + XRenderFillRectangle (FRAME_X_DISPLAY (f), + PictOpSrc, FRAME_X_PICTURE (f), + &xc, x, y, width, height); + x_xr_reset_ext_clip (f); + x_mark_frame_dirty (f); + + return; + } + } +#endif XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), gc, x, y, width, height); #endif @@ -1346,7 +1384,8 @@ x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height) static void -x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height) +x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height, + bool respect_alpha_background) { #ifdef USE_CAIRO cairo_t *cr; @@ -1357,6 +1396,30 @@ x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height) cairo_fill (cr); x_end_cr_clip (f); #else +#if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2)) + if (respect_alpha_background + && FRAME_DISPLAY_INFO (f)->n_planes == 32 + && FRAME_CHECK_XR_VERSION (f, 0, 2)) + { + x_xr_ensure_picture (f); + + if (FRAME_X_PICTURE (f) != None) + { + XRenderColor xc; + + x_xr_apply_ext_clip (f, gc); + x_xrender_color_from_gc_background (f, gc, &xc, true); + XRenderFillRectangle (FRAME_X_DISPLAY (f), + PictOpSrc, FRAME_X_PICTURE (f), + &xc, x, y, width, height); + x_xr_reset_ext_clip (f); + x_mark_frame_dirty (f); + + return; + } + } +#endif + XGCValues xgcv; Display *dpy = FRAME_X_DISPLAY (f); XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv); @@ -1397,7 +1460,7 @@ x_clear_window (struct frame *f) x_end_cr_clip (f); #else #ifndef USE_GTK - if (FRAME_X_DOUBLE_BUFFERED_P (f)) + if (FRAME_X_DOUBLE_BUFFERED_P (f) || (f->alpha_background != 1.0)) #endif x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); #ifndef USE_GTK @@ -1655,7 +1718,7 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1) face->foreground); #ifdef USE_CAIRO - x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0); + x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0, false); #else XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), f->output_data.x->normal_gc, x, y0, x, y1); @@ -1688,13 +1751,13 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1) { XSetForeground (display, f->output_data.x->normal_gc, color_first); x_fill_rectangle (f, f->output_data.x->normal_gc, - x0, y0, 1, y1 - y0); + x0, y0, 1, y1 - y0, false); XSetForeground (display, f->output_data.x->normal_gc, color); x_fill_rectangle (f, f->output_data.x->normal_gc, - x0 + 1, y0, x1 - x0 - 2, y1 - y0); + x0 + 1, y0, x1 - x0 - 2, y1 - y0, false); XSetForeground (display, f->output_data.x->normal_gc, color_last); x_fill_rectangle (f, f->output_data.x->normal_gc, - x1 - 1, y0, 1, y1 - y0); + x1 - 1, y0, 1, y1 - y0, false); } else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3)) /* A horizontal divider, at least three pixels high: Draw first and @@ -1702,13 +1765,13 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1) { XSetForeground (display, f->output_data.x->normal_gc, color_first); x_fill_rectangle (f, f->output_data.x->normal_gc, - x0, y0, x1 - x0, 1); + x0, y0, x1 - x0, 1, false); XSetForeground (display, f->output_data.x->normal_gc, color); x_fill_rectangle (f, f->output_data.x->normal_gc, - x0, y0 + 1, x1 - x0, y1 - y0 - 2); + x0, y0 + 1, x1 - x0, y1 - y0 - 2, false); XSetForeground (display, f->output_data.x->normal_gc, color_last); x_fill_rectangle (f, f->output_data.x->normal_gc, - x0, y1 - 1, x1 - x0, 1); + x0, y1 - 1, x1 - x0, 1, false); } else { @@ -1716,7 +1779,7 @@ x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1) differently. */ XSetForeground (display, f->output_data.x->normal_gc, color); x_fill_rectangle (f, f->output_data.x->normal_gc, - x0, y0, x1 - x0, y1 - y0); + x0, y0, x1 - x0, y1 - y0, false); } } @@ -1841,10 +1904,10 @@ x_clear_under_internal_border (struct frame *f) GC gc = f->output_data.x->normal_gc; XSetForeground (display, gc, color); - x_fill_rectangle (f, gc, 0, margin, width, border); - x_fill_rectangle (f, gc, 0, 0, border, height); - x_fill_rectangle (f, gc, width - border, 0, border, height); - x_fill_rectangle (f, gc, 0, height - border, width, border); + x_fill_rectangle (f, gc, 0, margin, width, border, false); + x_fill_rectangle (f, gc, 0, 0, border, height, false); + x_fill_rectangle (f, gc, width - border, 0, border, height, false); + x_fill_rectangle (f, gc, 0, height - border, width, border, false); XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f)); } else @@ -1949,7 +2012,8 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring else XSetBackground (display, face->gc, face->background); - x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny); + x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny, + true); if (!face->stipple) XSetForeground (display, face->gc, face->foreground); @@ -2293,7 +2357,7 @@ x_compute_glyph_string_overhangs (struct glyph_string *s) static void x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h) { - x_clear_rectangle (s->f, s->gc, x, y, w, h); + x_clear_rectangle (s->f, s->gc, x, y, w, h, true); } @@ -2319,9 +2383,10 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p) /* Fill background with a stipple pattern. */ XSetFillStyle (display, s->gc, FillOpaqueStippled); x_fill_rectangle (s->f, s->gc, s->x, - s->y + box_line_width, - s->background_width, - s->height - 2 * box_line_width); + s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width, + false); XSetFillStyle (display, s->gc, FillSolid); s->background_filled_p = true; } @@ -2416,7 +2481,8 @@ x_draw_glyph_string_foreground (struct glyph_string *s) x_fill_rectangle (s->f, s->gc, s->x, s->y + box_line_width, s->background_width, - s->height - 2 * box_line_width); + s->height - 2 * box_line_width, + false); XSetFillStyle (display, s->gc, FillSolid); } else @@ -3344,7 +3410,7 @@ x_draw_relief_rect (struct frame *f, if (left_p) { x_fill_rectangle (f, top_left_gc, left_x, top_y, - vwidth, bottom_y + 1 - top_y); + vwidth, bottom_y + 1 - top_y, false); if (top_p) corners |= 1 << CORNER_TOP_LEFT; if (bot_p) @@ -3353,7 +3419,7 @@ x_draw_relief_rect (struct frame *f, if (right_p) { x_fill_rectangle (f, bottom_right_gc, right_x + 1 - vwidth, top_y, - vwidth, bottom_y + 1 - top_y); + vwidth, bottom_y + 1 - top_y, false); if (top_p) corners |= 1 << CORNER_TOP_RIGHT; if (bot_p) @@ -3363,7 +3429,7 @@ x_draw_relief_rect (struct frame *f, { if (!right_p) x_fill_rectangle (f, top_left_gc, left_x, top_y, - right_x + 1 - left_x, hwidth); + right_x + 1 - left_x, hwidth, false); else x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y, right_x + 1 - left_x, hwidth, 1); @@ -3372,7 +3438,7 @@ x_draw_relief_rect (struct frame *f, { if (!left_p) x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth, - right_x + 1 - left_x, hwidth); + right_x + 1 - left_x, hwidth, false); else x_fill_trapezoid_for_relief (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth, @@ -3380,10 +3446,10 @@ x_draw_relief_rect (struct frame *f, } if (left_p && vwidth > 1) x_fill_rectangle (f, bottom_right_gc, left_x, top_y, - 1, bottom_y + 1 - top_y); + 1, bottom_y + 1 - top_y, false); if (top_p && hwidth > 1) x_fill_rectangle (f, bottom_right_gc, left_x, top_y, - right_x + 1 - left_x, 1); + right_x + 1 - left_x, 1, false); if (corners) { XSetBackground (FRAME_X_DISPLAY (f), top_left_gc, @@ -3505,21 +3571,25 @@ x_draw_box_rect (struct glyph_string *s, /* Top. */ x_fill_rectangle (s->f, s->gc, - left_x, top_y, right_x - left_x + 1, hwidth); + left_x, top_y, right_x - left_x + 1, hwidth, + false); /* Left. */ if (left_p) x_fill_rectangle (s->f, s->gc, - left_x, top_y, vwidth, bottom_y - top_y + 1); + left_x, top_y, vwidth, bottom_y - top_y + 1, + false); /* Bottom. */ x_fill_rectangle (s->f, s->gc, - left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth); + left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth, + false); /* Right. */ if (right_p) x_fill_rectangle (s->f, s->gc, - right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1); + right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1, + false); XSetForeground (display, s->gc, xgcv.foreground); x_reset_clip_rectangles (s->f, s->gc); @@ -3934,7 +4004,7 @@ x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) /* Fill background with a stipple pattern. */ XSetFillStyle (display, s->gc, FillOpaqueStippled); - x_fill_rectangle (s->f, s->gc, x, y, w, h); + x_fill_rectangle (s->f, s->gc, x, y, w, h, false); XSetFillStyle (display, s->gc, FillSolid); } else @@ -4139,7 +4209,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s) { /* Fill background with a stipple pattern. */ XSetFillStyle (display, gc, FillOpaqueStippled); - x_fill_rectangle (s->f, gc, x, y, w, h); + x_fill_rectangle (s->f, gc, x, y, w, h, true); XSetFillStyle (display, gc, FillSolid); } else @@ -4147,7 +4217,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s) XGCValues xgcv; XGetGCValues (display, gc, GCForeground | GCBackground, &xgcv); XSetForeground (display, gc, xgcv.background); - x_fill_rectangle (s->f, gc, x, y, w, h); + x_fill_rectangle (s->f, gc, x, y, w, h, true); XSetForeground (display, gc, xgcv.foreground); } @@ -4497,7 +4567,8 @@ x_draw_glyph_string (struct glyph_string *s) y = s->ybase + position; if (s->face->underline_defaulted_p) x_fill_rectangle (s->f, s->gc, - s->x, y, decoration_width, thickness); + s->x, y, decoration_width, thickness, + false); else { Display *display = FRAME_X_DISPLAY (s->f); @@ -4505,7 +4576,8 @@ x_draw_glyph_string (struct glyph_string *s) XGetGCValues (display, s->gc, GCForeground, &xgcv); XSetForeground (display, s->gc, s->face->underline_color); x_fill_rectangle (s->f, s->gc, - s->x, y, decoration_width, thickness); + s->x, y, decoration_width, thickness, + false); XSetForeground (display, s->gc, xgcv.foreground); } } @@ -4517,7 +4589,7 @@ x_draw_glyph_string (struct glyph_string *s) if (s->face->overline_color_defaulted_p) x_fill_rectangle (s->f, s->gc, s->x, s->y + dy, - decoration_width, h); + decoration_width, h, false); else { Display *display = FRAME_X_DISPLAY (s->f); @@ -4525,7 +4597,7 @@ x_draw_glyph_string (struct glyph_string *s) XGetGCValues (display, s->gc, GCForeground, &xgcv); XSetForeground (display, s->gc, s->face->overline_color); x_fill_rectangle (s->f, s->gc, s->x, s->y + dy, - decoration_width, h); + decoration_width, h, false); XSetForeground (display, s->gc, xgcv.foreground); } } @@ -4547,7 +4619,7 @@ x_draw_glyph_string (struct glyph_string *s) if (s->face->strike_through_color_defaulted_p) x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy, - s->width, h); + s->width, h, false); else { Display *display = FRAME_X_DISPLAY (s->f); @@ -4555,7 +4627,7 @@ x_draw_glyph_string (struct glyph_string *s) XGetGCValues (display, s->gc, GCForeground, &xgcv); XSetForeground (display, s->gc, s->face->strike_through_color); x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy, - decoration_width, h); + decoration_width, h, false); XSetForeground (display, s->gc, xgcv.foreground); } } @@ -4667,7 +4739,8 @@ x_clear_area (struct frame *f, int x, int y, int width, int height) x_end_cr_clip (f); #else #ifndef USE_GTK - if (FRAME_X_DOUBLE_BUFFERED_P (f)) + if (FRAME_X_DOUBLE_BUFFERED_P (f) + || f->alpha_background != 1.0) #endif { #if defined HAVE_XRENDER && \ @@ -4677,10 +4750,10 @@ x_clear_area (struct frame *f, int x, int y, int width, int height) && FRAME_CHECK_XR_VERSION (f, 0, 2)) { XRenderColor xc; - GC gc = f->output_data.x->reverse_gc; + GC gc = f->output_data.x->normal_gc; x_xr_apply_ext_clip (f, gc); - x_xrender_color_from_gc_foreground (f, gc, &xc); + x_xrender_color_from_gc_background (f, gc, &xc, true); XRenderFillRectangle (FRAME_X_DISPLAY (f), PictOpSrc, FRAME_X_PICTURE (f), &xc, x, y, width, height); @@ -9392,6 +9465,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, f->output_data.x->has_been_visible = true; } + x_update_opaque_region (f); + if (not_hidden && iconified) { inev.ie.kind = DEICONIFY_EVENT; @@ -12134,8 +12209,8 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text x += cursor_glyph->pixel_width - width; x_fill_rectangle (f, gc, x, - WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), - width, row->height); + WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), + width, row->height, false); } else /* HBAR_CURSOR */ { @@ -12156,7 +12231,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text x_fill_rectangle (f, gc, x, WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y + row->height - width), - w->phys_cursor_width - 1, width); + w->phys_cursor_width - 1, width, false); } x_reset_clip_rectangles (f, gc); @@ -15743,6 +15818,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar) ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above) ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below) + ATOM_REFS_INIT ("_NET_WM_OPAQUE_REGION", Xatom_net_wm_opaque_region) #ifdef HAVE_XKB ATOM_REFS_INIT ("Meta", Xatom_Meta) ATOM_REFS_INIT ("Super", Xatom_Super) @@ -16279,7 +16355,8 @@ init_xterm (void) #ifdef HAVE_XRENDER void -x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color) +x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color, + bool apply_alpha_background) { XGCValues xgcv; XColor xc; @@ -16288,26 +16365,47 @@ x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color) xc.pixel = xgcv.foreground; x_query_colors (f, &xc, 1); - color->alpha = 65535; - color->red = xc.red; - color->blue = xc.blue; - color->green = xc.green; + if (color->alpha == 65535) + { + color->red = xc.red; + color->blue = xc.blue; + color->green = xc.green; + } + else + { + color->red = (xc.red * color->alpha) / 65535; + color->blue = (xc.blue * color->alpha) / 65535; + color->green = (xc.green * color->alpha) / 65535; + } } void -x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor *color) +x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor *color, + bool apply_alpha_background) { XGCValues xgcv; XColor xc; XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv); - xc.pixel = xgcv.foreground; + xc.pixel = xgcv.background; x_query_colors (f, &xc, 1); - color->alpha = 65535; - color->red = xc.red; - color->blue = xc.blue; - color->green = xc.green; + color->alpha = (apply_alpha_background + ? 65535 * f->alpha_background + : 65535); + + if (color->alpha == 65535) + { + color->red = xc.red; + color->blue = xc.blue; + color->green = xc.green; + } + else + { + color->red = (xc.red * color->alpha) / 65535; + color->blue = (xc.blue * color->alpha) / 65535; + color->green = (xc.green * color->alpha) / 65535; + } } #endif diff --git a/src/xterm.h b/src/xterm.h index aa5bd2caa1..5e17d5b721 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -496,7 +496,8 @@ struct x_display_info Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert, Xatom_net_wm_state_sticky, Xatom_net_wm_state_above, Xatom_net_wm_state_below, Xatom_net_wm_state_hidden, Xatom_net_wm_state_skip_taskbar, - Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea; + Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea, + Xatom_net_wm_opaque_region; /* XSettings atoms and windows. */ Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr; @@ -1242,8 +1243,13 @@ extern Lisp_Object x_cr_export_frames (Lisp_Object, cairo_surface_type_t); #endif #ifdef HAVE_XRENDER -extern void x_xrender_color_from_gc_foreground (struct frame *, GC, XRenderColor *); -extern void x_xrender_color_from_gc_background (struct frame *, GC, XRenderColor *); +extern void x_xrender_color_from_gc_foreground (struct frame *, GC, + XRenderColor *, bool); +extern void x_xrender_color_from_gc_background (struct frame *, GC, + XRenderColor *, bool); +extern void x_xr_ensure_picture (struct frame *f); +extern void x_xr_apply_ext_clip (struct frame *f, GC gc); +extern void x_xr_reset_ext_clip (struct frame *f); #endif INLINE int commit 6f282b31ad7548ab744565144e0d30dd56774210 (refs/remotes/origin/emacs-28) Author: Kyle Meyer Date: Sun Jan 30 20:38:01 2022 -0500 Update to Org 9.5.2-13-gdd6486 diff --git a/lisp/org/ob-tangle.el b/lisp/org/ob-tangle.el index cf307aa0cb..566258eba4 100644 --- a/lisp/org/ob-tangle.el +++ b/lisp/org/ob-tangle.el @@ -43,7 +43,7 @@ (declare-function org-in-commented-heading-p "org" (&optional no-inheritance)) (declare-function org-in-archived-heading-p "org" (&optional no-inheritance)) (declare-function outline-previous-heading "outline" ()) -(defvar org-id-link-to-org-use-id nil) ; Dynamically scoped +(defvar org-id-link-to-org-use-id) ; Dynamically scoped (defcustom org-babel-tangle-lang-exts '(("emacs-lisp" . "el") diff --git a/lisp/org/ol-bibtex.el b/lisp/org/ol-bibtex.el index 41443d7959..218f8f17ed 100644 --- a/lisp/org/ol-bibtex.el +++ b/lisp/org/ol-bibtex.el @@ -115,7 +115,7 @@ (defvar org-agenda-overriding-header) (defvar org-agenda-search-view-always-boolean) -(defvar org-bibtex-description nil) ; dynamically scoped from org.el +(defvar org-bibtex-description nil) (defvar org-id-locations) (defvar org-property-end-re) (defvar org-special-properties) diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el index 94aea1b0a3..ae0058e037 100644 --- a/lisp/org/org-agenda.el +++ b/lisp/org/org-agenda.el @@ -99,8 +99,8 @@ ;; Defined somewhere in this file, but used before definition. (defvar org-agenda-buffer-name "*Org Agenda*") -(defvar org-agenda-overriding-header nil) (defvar org-agenda-title-append nil) +(defvar org-agenda-overriding-header) ;; (with-no-warnings (defvar entry)) ;; unprefixed, from calendar.el ;; (with-no-warnings (defvar date)) ;; unprefixed, from calendar.el (defvar original-date) ; dynamically scoped, calendar.el does scope this @@ -2158,7 +2158,7 @@ string that it returns." (org-remap org-agenda-mode-map 'move-end-of-line 'org-agenda-end-of-line) (defvar org-agenda-menu) ; defined later in this file. -(defvar org-agenda-restrict nil) ; defined later in this file. +(defvar org-agenda-restrict nil) (defvar org-agenda-follow-mode nil) (defvar org-agenda-entry-text-mode nil) (defvar org-agenda-clockreport-mode nil) @@ -7288,7 +7288,7 @@ When TYPE is \"scheduled\", \"deadline\", \"timestamp\" or \"timestamp_ia\", compare within each of these type. When TYPE is the empty string, compare all timestamps without respect of their type." - (let* ((def (and (not org-agenda-sort-notime-is-late) -1)) + (let* ((def (if org-agenda-sort-notime-is-late 99999999 -1)) (ta (or (and (string-match type (or (get-text-property 1 'type a) "")) (get-text-property 1 'ts-date a)) def)) diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el index be368e1c42..895d124e14 100644 --- a/lisp/org/org-clock.el +++ b/lisp/org/org-clock.el @@ -2506,7 +2506,7 @@ the currently selected interval size." (when step ;; Write many tables, in steps (unless (or block (and ts te)) - (user-error "Clocktable `:step' can only be used with `:block' or `:tstart, :end'")) + (user-error "Clocktable `:step' can only be used with `:block' or `:tstart', `:tend'")) (org-clocktable-steps params) (throw 'exit nil)) diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el index db23553a8b..4ad87c84d0 100644 --- a/lisp/org/org-compat.el +++ b/lisp/org/org-compat.el @@ -1049,9 +1049,9 @@ ELEMENT is the element at point." (cl-case (org-element-type object) ;; Prevent checks in links due to keybinding conflict with ;; Flyspell. - ((code entity export-snippet inline-babel-call - inline-src-block line-break latex-fragment link macro - statistics-cookie target timestamp verbatim) + ((citation citation-reference code entity export-snippet inline-babel-call + inline-src-block line-break latex-fragment link macro + statistics-cookie target timestamp verbatim) nil) (footnote-reference ;; Only in inline footnotes, within the definition. diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el index 5337d9df74..572203711c 100644 --- a/lisp/org/org-version.el +++ b/lisp/org/org-version.el @@ -11,7 +11,7 @@ Inserted by installing Org mode or when a release is made." (defun org-git-version () "The Git version of Org mode. Inserted by installing Org or when a release is made." - (let ((org-git-version "release_9.5.2-9-g7ba24c")) + (let ((org-git-version "release_9.5.2-13-gdd6486")) org-git-version)) (provide 'org-version) commit 58bb9eb4005599155a8fce8d5c5beb531a72c534 Author: Juri Linkov Date: Sun Jan 30 18:38:24 2022 +0200 * lisp/frame.el (undelete-frame--save-deleted-frame): Handle initial frame. The function undelete-frame--save-deleted-frame is renamed from undelete-frame--handle-delete-frame (bug#51883). diff --git a/lisp/frame.el b/lisp/frame.el index 56295a56e3..d39597d0af 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -2531,12 +2531,12 @@ deleting them." (setq this next)))) (defvar undelete-frame--deleted-frames nil - "Internal variable used by `undelete-frame--handle-delete-frame'.") + "Internal variable used by `undelete-frame--save-deleted-frame'.") -(defun undelete-frame--handle-delete-frame (frame) +(defun undelete-frame--save-deleted-frame (frame) "Save the configuration of frames deleted with `delete-frame'. Only the 16 most recently deleted frames are saved." - (when (frame-live-p frame) + (when (and after-init-time (frame-live-p frame)) (setq undelete-frame--deleted-frames (cons (list @@ -2564,9 +2564,9 @@ Only the 16 most recently deleted frames are saved." :global t (if undelete-frame-mode (add-hook 'delete-frame-functions - #'undelete-frame--handle-delete-frame -75) + #'undelete-frame--save-deleted-frame -75) (remove-hook 'delete-frame-functions - #'undelete-frame--handle-delete-frame) + #'undelete-frame--save-deleted-frame) (setq undelete-frame--deleted-frames nil))) (defun undelete-frame (&optional arg) commit 1b83e58adb46c2ab89320ffba868eb2025138b51 Author: Juri Linkov Date: Sun Jan 30 18:35:33 2022 +0200 * lisp/frame.el: Don't require 'frameset.el' (bug#51883). (clone-frame): Use frame-internal-parameters. (undelete-frame--handle-delete-frame): Instead of using frameset-save, save frame-parameters except frame-internal-parameters and 'display' on non-graphic display. Also save window-state from window-state-get. (undelete-frame): Instead of using frameset-restore, set default-frame-alist for make-frame (like in clone-frame), and restore window-state with window-state-put. * lisp/frameset.el (frameset-session-filter-alist): Append parameters from frame-internal-parameters with the filter :never. Remove :name that is now in frame-internal-parameters. (frameset-persistent-filter-alist): Remove outer-window-id, parent-id, window-id that are now in frame-internal-parameters, included here via frameset-session-filter-alist. * src/frame.c (frame-internal-parameters): New variable. diff --git a/lisp/frame.el b/lisp/frame.el index 13f82ea4c7..56295a56e3 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -799,7 +799,7 @@ also select the new frame." (window-state-get (frame-root-window frame)))) (default-frame-alist (seq-remove (lambda (elem) - (memq (car elem) '(name parent-id))) + (memq (car elem) frame-internal-parameters)) (frame-parameters frame))) (new-frame (make-frame))) (when windows @@ -2530,8 +2530,6 @@ deleting them." (if iconify (iconify-frame this) (delete-frame this))) (setq this next)))) -(eval-when-compile (require 'frameset)) - (defvar undelete-frame--deleted-frames nil "Internal variable used by `undelete-frame--handle-delete-frame'.") @@ -2541,20 +2539,20 @@ Only the 16 most recently deleted frames are saved." (when (frame-live-p frame) (setq undelete-frame--deleted-frames (cons - (cons + (list (display-graphic-p) - (frameset-save - (list frame) - ;; When the daemon is started from a graphical - ;; environment, TTY frames have a 'display' parameter set - ;; to the value of $DISPLAY (see the note in - ;; `server--on-display-p'). Do not store that parameter - ;; in the frameset, otherwise `frameset-restore' attempts - ;; to restore a graphical frame. - :filters (if (display-graphic-p) - frameset-filter-alist - (cons '(display . :never) - frameset-filter-alist)))) + (seq-remove + (lambda (elem) + (or (memq (car elem) frame-internal-parameters) + ;; When the daemon is started from a graphical + ;; environment, TTY frames have a 'display' parameter set + ;; to the value of $DISPLAY (see the note in + ;; `server--on-display-p'). Do not store that parameter + ;; in the frame data, otherwise `undelete-frame' attempts + ;; to restore a graphical frame. + (and (eq (car elem) 'display) (not (display-graphic-p))))) + (frame-parameters frame)) + (window-state-get (frame-root-window frame))) undelete-frame--deleted-frames)) (if (> (length undelete-frame--deleted-frames) 16) (setq undelete-frame--deleted-frames @@ -2584,26 +2582,25 @@ When called from Lisp, returns the new frame." (if (consp arg) (user-error "Missing deleted frame number argument") (let* ((number (pcase arg ('nil 1) ('- -1) (_ arg))) - (frames (frame-list)) - (frameset (nth (1- number) undelete-frame--deleted-frames)) + (frame-data (nth (1- number) undelete-frame--deleted-frames)) (graphic (display-graphic-p))) (if (not (<= 1 number 16)) (user-error "%d is not a valid deleted frame number argument" number) - (if (not frameset) + (if (not frame-data) (user-error "No deleted frame with number %d" number) - (if (not (eq graphic (car frameset))) + (if (not (eq graphic (nth 0 frame-data))) (user-error "Cannot undelete a %s display frame on a %s display" (if graphic "non-graphic" "graphic") (if graphic "graphic" "non-graphic")) (setq undelete-frame--deleted-frames - (delq frameset undelete-frame--deleted-frames)) - (frameset-restore (cdr frameset)) - (let ((frame (car (seq-difference (frame-list) frames)))) - (when frame - (select-frame-set-input-focus frame) - frame))))))))) + (delq frame-data undelete-frame--deleted-frames)) + (let* ((default-frame-alist (nth 1 frame-data)) + (frame (make-frame))) + (window-state-put (nth 2 frame-data) (frame-root-window frame) 'safe) + (select-frame-set-input-focus frame) + frame)))))))) ;;; Window dividers. (defgroup window-divider nil diff --git a/lisp/frameset.el b/lisp/frameset.el index 10714af1fa..05884eed3a 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -436,10 +436,11 @@ Properties can be set with ;;;###autoload (defvar frameset-session-filter-alist - '((name . :never) - (left . frameset-filter-iconified) - (minibuffer . frameset-filter-minibuffer) - (top . frameset-filter-iconified)) + (append + '((left . frameset-filter-iconified) + (minibuffer . frameset-filter-minibuffer) + (top . frameset-filter-iconified)) + (mapcar (lambda (p) (cons p :never)) frame-internal-parameters)) "Minimum set of parameters to filter for live (on-session) framesets. DO NOT MODIFY. See `frameset-filter-alist' for a full description.") @@ -468,14 +469,11 @@ DO NOT MODIFY. See `frameset-filter-alist' for a full description.") (GUI:height . frameset-filter-unshelve-param) (GUI:width . frameset-filter-unshelve-param) (height . frameset-filter-shelve-param) - (outer-window-id . :never) (parent-frame . :never) - (parent-id . :never) (mouse-wheel-frame . :never) (tty . frameset-filter-tty-to-GUI) (tty-type . frameset-filter-tty-to-GUI) (width . frameset-filter-shelve-param) - (window-id . :never) (window-system . :never)) frameset-session-filter-alist) "Parameters to filter for persistent framesets. diff --git a/src/frame.c b/src/frame.c index c331cff32b..f94dff0a60 100644 --- a/src/frame.c +++ b/src/frame.c @@ -6524,6 +6524,14 @@ making the child frame unresponsive to user actions, the default is to iconify the top level frame instead. */); iconify_child_frame = Qiconify_top_level; + DEFVAR_LISP ("frame-internal-parameters", frame_internal_parameters, + doc: /* Frame parameters specific to every frame. */); +#ifdef HAVE_X_WINDOWS + frame_internal_parameters = list4 (Qname, Qparent_id, Qwindow_id, Qouter_window_id); +#else + frame_internal_parameters = list3 (Qname, Qparent_id, Qwindow_id); +#endif + defsubr (&Sframep); defsubr (&Sframe_live_p); defsubr (&Swindow_system); commit 46611aa46838c234584678c0e8befc3adf4a9fe4 Author: Alan Mackenzie Date: Sun Jan 30 16:32:21 2022 +0000 Enlarge max-specpdl-size for generation of leim-list.el in bootstrap * leim/Makefile.in (${leimdir}/leim-list.el): Add a --eval clause to set max-specpdl-size to 5000 (previously 2500) for this target. diff --git a/leim/Makefile.in b/leim/Makefile.in index 2a477d868b..6cf0abb40c 100644 --- a/leim/Makefile.in +++ b/leim/Makefile.in @@ -122,6 +122,7 @@ leim-list.el: ${leimdir}/leim-list.el ${leimdir}/leim-list.el: ${srcdir}/leim-ext.el ${TIT_MISC} $(AM_V_GEN)rm -f $@ $(AM_V_at)${RUN_EMACS} -l international/quail \ + --eval "(setq max-specpdl-size 5000)" \ --eval "(update-leim-list-file (unmsys--file-name \"${leimdir}\"))" $(AM_V_at)sed -n -e '/^[^;]/p' -e 's/^;\(;*\)inc /;\1 /p' < $< >> $@ commit 71174a16da43260a5a7c773719d2baffcd939597 Author: Po Lu Date: Sun Jan 30 13:23:52 2022 +0000 Handle correctly errors during frame creation on Haiku * src/haikufns.c (haiku_create_frame): Only block input where required. * src/haiku_support.cc (BCursor_delete): Accept NULL values of `cursor'. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 794023c98e..8ab8217091 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -2028,7 +2028,8 @@ BCursor_create_grab (void) void BCursor_delete (void *cursor) { - delete (BCursor *) cursor; + if (cursor) + delete (BCursor *) cursor; } void diff --git a/src/haikufns.c b/src/haikufns.c index 0e0cffea72..3b22f7bb37 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -592,8 +592,6 @@ haiku_create_frame (Lisp_Object parms) if (STRINGP (name)) Vx_resource_name = name; - block_input (); - /* make_frame_without_minibuffer can run Lisp code and garbage collect. */ /* No need to protect DISPLAY because that's not used after passing it to make_frame_without_minibuffer. */ @@ -668,8 +666,6 @@ haiku_create_frame (Lisp_Object parms) FRAME_RIF (f)->default_font_parameter (f, parms); - unblock_input (); - gui_default_parameter (f, parms, Qborder_width, make_fixnum (0), "borderwidth", "BorderWidth", RES_TYPE_NUMBER); gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (2), @@ -749,6 +745,7 @@ haiku_create_frame (Lisp_Object parms) RES_TYPE_BOOLEAN); f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !NILP (tem)); + block_input (); #define ASSIGN_CURSOR(cursor, be_cursor) \ (FRAME_OUTPUT_DATA (f)->cursor = be_cursor) @@ -786,11 +783,15 @@ haiku_create_frame (Lisp_Object parms) f->terminal->reference_count++; FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view); + unblock_input (); + if (!FRAME_OUTPUT_DATA (f)->window) xsignal1 (Qerror, build_unibyte_string ("Could not create window")); + block_input (); if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f)) initialize_frame_menubar (f); + unblock_input (); FRAME_OUTPUT_DATA (f)->window_desc = FRAME_OUTPUT_DATA (f)->window; @@ -871,10 +872,12 @@ haiku_create_frame (Lisp_Object parms) if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem)))) fset_param_alist (f, Fcons (XCAR (tem), f->param_alist)); + block_input (); if (window_prompting & (USPosition | PPosition)) haiku_set_offset (f, f->left_pos, f->top_pos, 1); else BWindow_center_on_screen (FRAME_HAIKU_WINDOW (f)); + unblock_input (); /* Make sure windows on this frame appear in calls to next-window and similar functions. */ commit 6636231b2ce554b88379da06ca6cd2de62dfaa3a Author: Eli Zaretskii Date: Sun Jan 30 09:40:12 2022 +0200 ; * lisp/international/latin1-disp.el: Update commentary. diff --git a/lisp/international/latin1-disp.el b/lisp/international/latin1-disp.el index c8ff93aeb2..96a54cc212 100644 --- a/lisp/international/latin1-disp.el +++ b/lisp/international/latin1-disp.el @@ -1,4 +1,4 @@ -;;; latin1-disp.el --- display tables for other ISO 8859 on Latin-1 terminals -*- lexical-binding: t; -*- +;;; latin1-disp.el --- display tables for non-ASCII on Latin-1 terminals -*- lexical-binding: t; -*- ;; Copyright (C) 2000-2022 Free Software Foundation, Inc. @@ -22,18 +22,23 @@ ;;; Commentary: -;; This package sets up display of ISO 8859-n for n>1 by substituting -;; Latin-1 characters and sequences of them for characters which can't -;; be displayed, either because we're on a tty or because we don't -;; have the relevant window system fonts available. For instance, -;; Latin-9 is very similar to Latin-1, so we can display most Latin-9 -;; characters using the Latin-1 characters at the same code point and -;; fall back on more-or-less mnemonic ASCII sequences for the rest. +;; This package sets up display of many non-ASCII characters by +;; substituting ASCII and Latin-1 characters and sequences of them for +;; characters which can't be displayed, either because we're on a tty +;; or because we don't have the relevant window system fonts +;; available. For instance, Latin-9 is very similar to Latin-1, so we +;; can display most Latin-9 characters using the Latin-1 characters at +;; the same code point and fall back on more-or-less mnemonic ASCII +;; sequences for the rest. ;; For the Latin charsets the ASCII sequences are mostly consistent ;; with the Quail prefix input sequences. Latin-4 uses the Quail ;; postfix sequences since a prefix method isn't defined for Latin-4. +;; Non-Latin non-ASCII characters are generally displayed as ASCII +;; strings remotely reminiscent of the original characters, as best as +;; possible. See `latin1-display-ucs-per-lynx'. + ;; [A different approach is taken in the DOS display tables in ;; term/internal.el, and the relevant ASCII sequences from there are ;; available as an alternative; see `latin1-display-mnemonic'. Only commit f22e9ba9ac64c30d6532a508494b5149c27596e7 Author: Eli Zaretskii Date: Sun Jan 30 08:49:34 2022 +0200 Fix regression in Occur Edit mode * lisp/replace.el (occur-after-change-function): Fix the algorithm to find the smallest change in some corner cases. (Bug#53598) diff --git a/lisp/replace.el b/lisp/replace.el index 45bd05d41d..b1cfd7e3f4 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -1413,10 +1413,15 @@ To return to ordinary Occur mode, use \\[occur-cease-edit]." (length s1))))) (prefix-len (funcall common-prefix buf-str text)) (suffix-len (funcall common-prefix - (reverse buf-str) (reverse text)))) + (reverse (substring + buf-str prefix-len)) + (reverse (substring + text prefix-len))))) (setq beg-pos (+ beg-pos prefix-len)) (setq end-pos (- end-pos suffix-len)) - (setq text (substring text prefix-len (- suffix-len))) + (setq text (substring text prefix-len + (and (not (zerop suffix-len)) + (- suffix-len)))) (delete-region beg-pos end-pos) (goto-char beg-pos) (insert text)))