>From b490315aad58c704589fbb753de3238ce0d08819 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 29 Oct 2021 19:26:49 +0800 Subject: [PATCH 3/3] Destroy xwidgets when destroying frames * src/xterm.c (x_free_frame_resources): Make sure to kill xwidget views. * src/xwidget.c (Fmake_xwidget): Attach damage event signal. (offscreen_damage_event): Operate on xwidgets and not individual views. (xwidget_init_view): Don't attach damage event signal here. (Fdelete_xwidget_view): Destroy window correctly and stop removing damage event signal. (kill_frame_xwidget_views): New function. * src/xwidget.c (kill_frame_xwidget_views): New function. --- src/xterm.c | 4 ++++ src/xwidget.c | 52 +++++++++++++++++++++++++++++++++++---------------- src/xwidget.h | 1 + 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index b12c15cb7a..3e8cfb8b29 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -12210,6 +12210,10 @@ x_free_frame_resources (struct frame *f) xfree (f->shell_position); #else /* !USE_X_TOOLKIT */ +#ifdef HAVE_XWIDGETS + kill_frame_xwidget_views (f); +#endif + #ifdef USE_GTK xg_free_frame_widgets (f); #endif /* USE_GTK */ diff --git a/src/xwidget.c b/src/xwidget.c index 68188eba08..fe6640171c 100644 --- a/src/xwidget.c +++ b/src/xwidget.c @@ -46,6 +46,7 @@ Copyright (C) 2011-2021 Free Software Foundation, Inc. #ifdef USE_GTK static Lisp_Object x_window_to_xwv_map; +static gboolean offscreen_damage_event (GtkWidget *, GdkEvent *, gpointer); #endif static struct xwidget * @@ -193,6 +194,9 @@ DEFUN ("make-xwidget", xw); } + g_signal_connect (G_OBJECT (xw->widgetwindow_osr), "damage-event", + G_CALLBACK (offscreen_damage_event), xw); + unblock_input (); } #elif defined NS_IMPL_COCOA @@ -297,15 +301,20 @@ xv_do_draw (struct xwidget_view *xw, struct xwidget *w) It copies the bitmap from the off-screen instance. */ static gboolean offscreen_damage_event (GtkWidget *widget, GdkEvent *event, - gpointer xwidget_view) + gpointer xwidget) { - struct xwidget_view *xw = xwidget_view; - struct xwidget *w = XXWIDGET (xw->model); + block_input (); - if (xw->wdesc == None) - return FALSE; + for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail); + tail = XCDR (tail)) + { + struct xwidget_view *view = XXWIDGET_VIEW (XCAR (tail)); + + if (view->wdesc && XXWIDGET (view->model) == xwidget) + xv_do_draw (view, XXWIDGET (view->model)); + } - xv_do_draw (xw, w); + unblock_input (); return FALSE; } @@ -592,9 +601,6 @@ xwidget_init_view (struct xwidget *xww, xv->wdesc = None; xv->frame = s->f; - - g_signal_connect (G_OBJECT (xww->widgetwindow_osr), "damage-event", - G_CALLBACK (offscreen_damage_event), xv); #elif defined NS_IMPL_COCOA nsxwidget_init_view (xv, xww, s, x, y); nsxwidget_resize_view(xv, xww->width, xww->height); @@ -1102,15 +1108,9 @@ DEFUN ("delete-xwidget-view", if (xv->wdesc != None) { block_input (); - XDestroyWindow (xv->dpy, xv->wdesc); - /* xv->model still has signals pointing to the view. There can be - several views. Find the matching signals and delete them all. */ - g_signal_handlers_disconnect_matched (XXWIDGET (xv->model)->widgetwindow_osr, - G_SIGNAL_MATCH_DATA, - 0, 0, 0, 0, xv); - cairo_destroy (xv->cr_context); cairo_surface_destroy (xv->cr_surface); + XDestroyWindow (xv->dpy, xv->wdesc); Fremhash (make_fixnum (xv->wdesc), x_window_to_xwv_map); unblock_input (); } @@ -1456,6 +1456,26 @@ xwidget_end_redisplay (struct window *w, struct glyph_matrix *matrix) } } +#ifdef USE_GTK +void +kill_frame_xwidget_views (struct frame *f) +{ + Lisp_Object rem = Qnil; + + for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail); + tail = XCDR (tail)) + { + if (XXWIDGET_VIEW (XCAR (tail))->frame == f) + rem = Fcons (XCAR (tail), rem); + } + + for (; CONSP (rem); rem = XCDR (rem)) + { + Fdelete_xwidget_view (XCAR (rem)); + } +} +#endif + /* Kill all xwidget in BUFFER. */ void kill_buffer_xwidgets (Lisp_Object buffer) diff --git a/src/xwidget.h b/src/xwidget.h index 28098c0b09..f51921dbef 100644 --- a/src/xwidget.h +++ b/src/xwidget.h @@ -171,6 +171,7 @@ #define XG_XWIDGET_VIEW "emacs_xwidget_view" void xwidget_expose (struct xwidget_view *xv); extern struct xwidget *xwidget_from_id (uint32_t id); +extern void kill_frame_xwidget_views (struct frame *f); #else INLINE_HEADER_BEGIN INLINE void syms_of_xwidget (void) {} -- 2.31.1