diff options
| author | Po Lu | 2021-11-12 08:17:41 +0800 |
|---|---|---|
| committer | Po Lu | 2021-11-12 08:17:41 +0800 |
| commit | 554a875493680f8b52821267ee88e191d462ea36 (patch) | |
| tree | 22bd120a4d1cfc3c8cc99bf17a6361437e140399 /src | |
| parent | a8fc08085110de00ebcbd67b5273a755a5cb8ea1 (diff) | |
| download | emacs-554a875493680f8b52821267ee88e191d462ea36.tar.gz emacs-554a875493680f8b52821267ee88e191d462ea36.zip | |
Prevent crashes in xwidgets whose buffers have been killed
* doc/lispref/display.texi (Xwidgets): Explain meaning of killed
xwidgets.
* src/xwidget.c (Fxwidget_live_p): New function.
(Fxwidget_perform_lispy_event, WEBKIT_FN_INIT)
(Fxwidget_resize, Fxwidget_size_request)
(Fxwidget_info, Fxwidget_plist)
(Fset_xwidget_buffer, Fset_xwidget_plist)
(Fset_xwidget_query_on_exit_flag)
(Fxwidget_query_on_exit_flag)
(Fxwidget_webkit_search)
(Fxwidget_webkit_next_result)
(Fxwidget_webkit_previous_result)
(Fxwidget_webkit_finish_search)
(Fxwidget_webkit_load_html): Check for live xwidgets instead of
just xwidgets.
(xwidget_button, xwidget_motion_or_crossing)
(xv_do_draw, x_draw_xwidget_glyph_string)
(Fdelete_xwidget_view): Ignore killed xwidgets.
(syms_of_xwidget): Define new symbols and subrs and define
appropriate weakness of id_to_xwidget map.
(kill_buffer_xwidgets): Check live xwidgets instead of
killed xwidgets, set xwidget buffer to nil, and rely on GC to
free the hash table for us instead.
* src/xwidget.h (XWIDGET_LIVE_P, CHECK_LIVE_XWIDGET): New
macros.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xwidget.c | 116 | ||||
| -rw-r--r-- | src/xwidget.h | 7 |
2 files changed, 88 insertions, 35 deletions
diff --git a/src/xwidget.c b/src/xwidget.c index fc05f4f5709..d0cc3b987c9 100644 --- a/src/xwidget.c +++ b/src/xwidget.c | |||
| @@ -272,6 +272,16 @@ fails. */) | |||
| 272 | return val; | 272 | return val; |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | DEFUN ("xwidget-live-p", Fxwidget_live_p, Sxwidget_live_p, | ||
| 276 | 1, 1, 0, doc: /* Return t if OBJECT is an xwidget that has not been killed. | ||
| 277 | Value is nil if OBJECT is not an xwidget or if it has been killed. */) | ||
| 278 | (Lisp_Object object) | ||
| 279 | { | ||
| 280 | return ((XWIDGETP (object) | ||
| 281 | && !NILP (XXWIDGET (object)->buffer)) | ||
| 282 | ? Qt : Qnil); | ||
| 283 | } | ||
| 284 | |||
| 275 | #ifdef USE_GTK | 285 | #ifdef USE_GTK |
| 276 | static void | 286 | static void |
| 277 | set_widget_if_text_view (GtkWidget *widget, void *data) | 287 | set_widget_if_text_view (GtkWidget *widget, void *data) |
| @@ -304,7 +314,7 @@ selected frame is not an X-Windows frame. */) | |||
| 304 | GtkWidget *temp = NULL; | 314 | GtkWidget *temp = NULL; |
| 305 | #endif | 315 | #endif |
| 306 | 316 | ||
| 307 | CHECK_XWIDGET (xwidget); | 317 | CHECK_LIVE_XWIDGET (xwidget); |
| 308 | xw = XXWIDGET (xwidget); | 318 | xw = XXWIDGET (xwidget); |
| 309 | 319 | ||
| 310 | if (!NILP (frame)) | 320 | if (!NILP (frame)) |
| @@ -806,6 +816,9 @@ xwidget_button (struct xwidget_view *view, | |||
| 806 | bool down_p, int x, int y, int button, | 816 | bool down_p, int x, int y, int button, |
| 807 | int modifier_state, Time time) | 817 | int modifier_state, Time time) |
| 808 | { | 818 | { |
| 819 | if (NILP (XXWIDGET (view->model)->buffer)) | ||
| 820 | return; | ||
| 821 | |||
| 809 | record_osr_embedder (view); | 822 | record_osr_embedder (view); |
| 810 | 823 | ||
| 811 | if (button < 4 || button > 8) | 824 | if (button < 4 || button > 8) |
| @@ -856,22 +869,29 @@ xwidget_button (struct xwidget_view *view, | |||
| 856 | void | 869 | void |
| 857 | xwidget_motion_or_crossing (struct xwidget_view *view, const XEvent *event) | 870 | xwidget_motion_or_crossing (struct xwidget_view *view, const XEvent *event) |
| 858 | { | 871 | { |
| 859 | GdkEvent *xg_event = gdk_event_new (event->type == MotionNotify | 872 | GdkEvent *xg_event; |
| 860 | ? GDK_MOTION_NOTIFY | ||
| 861 | : (event->type == LeaveNotify | ||
| 862 | ? GDK_LEAVE_NOTIFY | ||
| 863 | : GDK_ENTER_NOTIFY)); | ||
| 864 | struct xwidget *model = XXWIDGET (view->model); | 873 | struct xwidget *model = XXWIDGET (view->model); |
| 865 | int x; | 874 | int x; |
| 866 | int y; | 875 | int y; |
| 867 | GtkWidget *target = find_widget_at_pos (model->widgetwindow_osr, | 876 | GtkWidget *target; |
| 868 | (event->type == MotionNotify | 877 | |
| 869 | ? event->xmotion.x + view->clip_left | 878 | if (NILP (model->buffer)) |
| 870 | : event->xcrossing.x + view->clip_left), | 879 | return; |
| 871 | (event->type == MotionNotify | 880 | |
| 872 | ? event->xmotion.y + view->clip_top | 881 | xg_event = gdk_event_new (event->type == MotionNotify |
| 873 | : event->xcrossing.y + view->clip_top), | 882 | ? GDK_MOTION_NOTIFY |
| 874 | &x, &y); | 883 | : (event->type == LeaveNotify |
| 884 | ? GDK_LEAVE_NOTIFY | ||
| 885 | : GDK_ENTER_NOTIFY)); | ||
| 886 | |||
| 887 | target = find_widget_at_pos (model->widgetwindow_osr, | ||
| 888 | (event->type == MotionNotify | ||
| 889 | ? event->xmotion.x + view->clip_left | ||
| 890 | : event->xcrossing.x + view->clip_left), | ||
| 891 | (event->type == MotionNotify | ||
| 892 | ? event->xmotion.y + view->clip_top | ||
| 893 | : event->xcrossing.y + view->clip_top), | ||
| 894 | &x, &y); | ||
| 875 | 895 | ||
| 876 | if (!target) | 896 | if (!target) |
| 877 | target = model->widget_osr; | 897 | target = model->widget_osr; |
| @@ -968,6 +988,13 @@ xv_do_draw (struct xwidget_view *xw, struct xwidget *w) | |||
| 968 | { | 988 | { |
| 969 | GtkOffscreenWindow *wnd; | 989 | GtkOffscreenWindow *wnd; |
| 970 | cairo_surface_t *surface; | 990 | cairo_surface_t *surface; |
| 991 | |||
| 992 | if (NILP (w->buffer)) | ||
| 993 | { | ||
| 994 | XClearWindow (xw->dpy, xw->wdesc); | ||
| 995 | return; | ||
| 996 | } | ||
| 997 | |||
| 971 | block_input (); | 998 | block_input (); |
| 972 | wnd = GTK_OFFSCREEN_WINDOW (w->widgetwindow_osr); | 999 | wnd = GTK_OFFSCREEN_WINDOW (w->widgetwindow_osr); |
| 973 | surface = gtk_offscreen_window_get_surface (wnd); | 1000 | surface = gtk_offscreen_window_get_surface (wnd); |
| @@ -1650,14 +1677,25 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) | |||
| 1650 | a redraw. It seems its possible to get out of sync with emacs | 1677 | a redraw. It seems its possible to get out of sync with emacs |
| 1651 | redraws so emacs background sometimes shows up instead of the | 1678 | redraws so emacs background sometimes shows up instead of the |
| 1652 | xwidgets background. It's just a visual glitch though. */ | 1679 | xwidgets background. It's just a visual glitch though. */ |
| 1653 | if (!xwidget_hidden (xv)) | 1680 | /* When xww->buffer is nil, that means the xwidget has been killed. */ |
| 1681 | if (!NILP (xww->buffer)) | ||
| 1654 | { | 1682 | { |
| 1683 | if (!xwidget_hidden (xv)) | ||
| 1684 | { | ||
| 1655 | #ifdef USE_GTK | 1685 | #ifdef USE_GTK |
| 1656 | gtk_widget_queue_draw (xww->widget_osr); | 1686 | gtk_widget_queue_draw (xww->widget_osr); |
| 1657 | #elif defined NS_IMPL_COCOA | 1687 | #elif defined NS_IMPL_COCOA |
| 1658 | nsxwidget_set_needsdisplay (xv); | 1688 | nsxwidget_set_needsdisplay (xv); |
| 1659 | #endif | 1689 | #endif |
| 1690 | } | ||
| 1691 | } | ||
| 1692 | #ifdef USE_GTK | ||
| 1693 | else | ||
| 1694 | { | ||
| 1695 | XSetWindowBackground (xv->dpy, xv->wdesc, | ||
| 1696 | FRAME_BACKGROUND_PIXEL (s->f)); | ||
| 1660 | } | 1697 | } |
| 1698 | #endif | ||
| 1661 | 1699 | ||
| 1662 | #ifdef USE_GTK | 1700 | #ifdef USE_GTK |
| 1663 | unblock_input (); | 1701 | unblock_input (); |
| @@ -1676,7 +1714,7 @@ xwidget_is_web_view (struct xwidget *xw) | |||
| 1676 | 1714 | ||
| 1677 | /* Macro that checks xwidget hold webkit web view first. */ | 1715 | /* Macro that checks xwidget hold webkit web view first. */ |
| 1678 | #define WEBKIT_FN_INIT() \ | 1716 | #define WEBKIT_FN_INIT() \ |
| 1679 | CHECK_XWIDGET (xwidget); \ | 1717 | CHECK_LIVE_XWIDGET (xwidget); \ |
| 1680 | struct xwidget *xw = XXWIDGET (xwidget); \ | 1718 | struct xwidget *xw = XXWIDGET (xwidget); \ |
| 1681 | if (!xwidget_is_web_view (xw)) \ | 1719 | if (!xwidget_is_web_view (xw)) \ |
| 1682 | { \ | 1720 | { \ |
| @@ -1855,7 +1893,7 @@ DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0, | |||
| 1855 | doc: /* Resize XWIDGET to NEW_WIDTH, NEW_HEIGHT. */ ) | 1893 | doc: /* Resize XWIDGET to NEW_WIDTH, NEW_HEIGHT. */ ) |
| 1856 | (Lisp_Object xwidget, Lisp_Object new_width, Lisp_Object new_height) | 1894 | (Lisp_Object xwidget, Lisp_Object new_width, Lisp_Object new_height) |
| 1857 | { | 1895 | { |
| 1858 | CHECK_XWIDGET (xwidget); | 1896 | CHECK_LIVE_XWIDGET (xwidget); |
| 1859 | int w = check_integer_range (new_width, 0, INT_MAX); | 1897 | int w = check_integer_range (new_width, 0, INT_MAX); |
| 1860 | int h = check_integer_range (new_height, 0, INT_MAX); | 1898 | int h = check_integer_range (new_height, 0, INT_MAX); |
| 1861 | struct xwidget *xw = XXWIDGET (xwidget); | 1899 | struct xwidget *xw = XXWIDGET (xwidget); |
| @@ -1906,7 +1944,7 @@ This can be used to read the xwidget desired size, and resizes the | |||
| 1906 | Emacs allocated area accordingly. */) | 1944 | Emacs allocated area accordingly. */) |
| 1907 | (Lisp_Object xwidget) | 1945 | (Lisp_Object xwidget) |
| 1908 | { | 1946 | { |
| 1909 | CHECK_XWIDGET (xwidget); | 1947 | CHECK_LIVE_XWIDGET (xwidget); |
| 1910 | #ifdef USE_GTK | 1948 | #ifdef USE_GTK |
| 1911 | GtkRequisition requisition; | 1949 | GtkRequisition requisition; |
| 1912 | gtk_widget_size_request (XXWIDGET (xwidget)->widget_osr, &requisition); | 1950 | gtk_widget_size_request (XXWIDGET (xwidget)->widget_osr, &requisition); |
| @@ -1941,7 +1979,7 @@ DEFUN ("xwidget-info", | |||
| 1941 | Currently [TYPE TITLE WIDTH HEIGHT]. */) | 1979 | Currently [TYPE TITLE WIDTH HEIGHT]. */) |
| 1942 | (Lisp_Object xwidget) | 1980 | (Lisp_Object xwidget) |
| 1943 | { | 1981 | { |
| 1944 | CHECK_XWIDGET (xwidget); | 1982 | CHECK_LIVE_XWIDGET (xwidget); |
| 1945 | struct xwidget *xw = XXWIDGET (xwidget); | 1983 | struct xwidget *xw = XXWIDGET (xwidget); |
| 1946 | return CALLN (Fvector, xw->type, xw->title, | 1984 | return CALLN (Fvector, xw->type, xw->title, |
| 1947 | make_fixed_natnum (xw->width), make_fixed_natnum (xw->height)); | 1985 | make_fixed_natnum (xw->width), make_fixed_natnum (xw->height)); |
| @@ -2004,7 +2042,7 @@ DEFUN ("delete-xwidget-view", | |||
| 2004 | unblock_input (); | 2042 | unblock_input (); |
| 2005 | } | 2043 | } |
| 2006 | 2044 | ||
| 2007 | if (xw->embedder_view == xv) | 2045 | if (xw->embedder_view == xv && !NILP (xw->buffer)) |
| 2008 | { | 2046 | { |
| 2009 | w = gtk_widget_get_window (xw->widgetwindow_osr); | 2047 | w = gtk_widget_get_window (xw->widgetwindow_osr); |
| 2010 | 2048 | ||
| @@ -2053,7 +2091,7 @@ DEFUN ("xwidget-plist", | |||
| 2053 | doc: /* Return the plist of XWIDGET. */) | 2091 | doc: /* Return the plist of XWIDGET. */) |
| 2054 | (Lisp_Object xwidget) | 2092 | (Lisp_Object xwidget) |
| 2055 | { | 2093 | { |
| 2056 | CHECK_XWIDGET (xwidget); | 2094 | CHECK_LIVE_XWIDGET (xwidget); |
| 2057 | return XXWIDGET (xwidget)->plist; | 2095 | return XXWIDGET (xwidget)->plist; |
| 2058 | } | 2096 | } |
| 2059 | 2097 | ||
| @@ -2073,7 +2111,7 @@ DEFUN ("set-xwidget-buffer", | |||
| 2073 | doc: /* Set XWIDGET's buffer to BUFFER. */) | 2111 | doc: /* Set XWIDGET's buffer to BUFFER. */) |
| 2074 | (Lisp_Object xwidget, Lisp_Object buffer) | 2112 | (Lisp_Object xwidget, Lisp_Object buffer) |
| 2075 | { | 2113 | { |
| 2076 | CHECK_XWIDGET (xwidget); | 2114 | CHECK_LIVE_XWIDGET (xwidget); |
| 2077 | CHECK_BUFFER (buffer); | 2115 | CHECK_BUFFER (buffer); |
| 2078 | 2116 | ||
| 2079 | XXWIDGET (xwidget)->buffer = buffer; | 2117 | XXWIDGET (xwidget)->buffer = buffer; |
| @@ -2087,7 +2125,7 @@ DEFUN ("set-xwidget-plist", | |||
| 2087 | Returns PLIST. */) | 2125 | Returns PLIST. */) |
| 2088 | (Lisp_Object xwidget, Lisp_Object plist) | 2126 | (Lisp_Object xwidget, Lisp_Object plist) |
| 2089 | { | 2127 | { |
| 2090 | CHECK_XWIDGET (xwidget); | 2128 | CHECK_LIVE_XWIDGET (xwidget); |
| 2091 | CHECK_LIST (plist); | 2129 | CHECK_LIST (plist); |
| 2092 | 2130 | ||
| 2093 | XXWIDGET (xwidget)->plist = plist; | 2131 | XXWIDGET (xwidget)->plist = plist; |
| @@ -2103,7 +2141,7 @@ exiting or killing a buffer if XWIDGET is running. | |||
| 2103 | This function returns FLAG. */) | 2141 | This function returns FLAG. */) |
| 2104 | (Lisp_Object xwidget, Lisp_Object flag) | 2142 | (Lisp_Object xwidget, Lisp_Object flag) |
| 2105 | { | 2143 | { |
| 2106 | CHECK_XWIDGET (xwidget); | 2144 | CHECK_LIVE_XWIDGET (xwidget); |
| 2107 | XXWIDGET (xwidget)->kill_without_query = NILP (flag); | 2145 | XXWIDGET (xwidget)->kill_without_query = NILP (flag); |
| 2108 | return flag; | 2146 | return flag; |
| 2109 | } | 2147 | } |
| @@ -2114,7 +2152,7 @@ DEFUN ("xwidget-query-on-exit-flag", | |||
| 2114 | doc: /* Return the current value of the query-on-exit flag for XWIDGET. */) | 2152 | doc: /* Return the current value of the query-on-exit flag for XWIDGET. */) |
| 2115 | (Lisp_Object xwidget) | 2153 | (Lisp_Object xwidget) |
| 2116 | { | 2154 | { |
| 2117 | CHECK_XWIDGET (xwidget); | 2155 | CHECK_LIVE_XWIDGET (xwidget); |
| 2118 | return (XXWIDGET (xwidget)->kill_without_query ? Qnil : Qt); | 2156 | return (XXWIDGET (xwidget)->kill_without_query ? Qnil : Qt); |
| 2119 | } | 2157 | } |
| 2120 | 2158 | ||
| @@ -2147,7 +2185,7 @@ with QUERY. */) | |||
| 2147 | #endif | 2185 | #endif |
| 2148 | 2186 | ||
| 2149 | CHECK_STRING (query); | 2187 | CHECK_STRING (query); |
| 2150 | CHECK_XWIDGET (xwidget); | 2188 | CHECK_LIVE_XWIDGET (xwidget); |
| 2151 | 2189 | ||
| 2152 | #ifdef USE_GTK | 2190 | #ifdef USE_GTK |
| 2153 | xw = XXWIDGET (xwidget); | 2191 | xw = XXWIDGET (xwidget); |
| @@ -2191,7 +2229,7 @@ using `xwidget-webkit-search'. */) | |||
| 2191 | WebKitFindController *controller; | 2229 | WebKitFindController *controller; |
| 2192 | #endif | 2230 | #endif |
| 2193 | 2231 | ||
| 2194 | CHECK_XWIDGET (xwidget); | 2232 | CHECK_LIVE_XWIDGET (xwidget); |
| 2195 | xw = XXWIDGET (xwidget); | 2233 | xw = XXWIDGET (xwidget); |
| 2196 | 2234 | ||
| 2197 | if (!xw->find_text) | 2235 | if (!xw->find_text) |
| @@ -2223,7 +2261,7 @@ using `xwidget-webkit-search'. */) | |||
| 2223 | WebKitFindController *controller; | 2261 | WebKitFindController *controller; |
| 2224 | #endif | 2262 | #endif |
| 2225 | 2263 | ||
| 2226 | CHECK_XWIDGET (xwidget); | 2264 | CHECK_LIVE_XWIDGET (xwidget); |
| 2227 | xw = XXWIDGET (xwidget); | 2265 | xw = XXWIDGET (xwidget); |
| 2228 | 2266 | ||
| 2229 | if (!xw->find_text) | 2267 | if (!xw->find_text) |
| @@ -2255,7 +2293,7 @@ using `xwidget-webkit-search'. */) | |||
| 2255 | WebKitFindController *controller; | 2293 | WebKitFindController *controller; |
| 2256 | #endif | 2294 | #endif |
| 2257 | 2295 | ||
| 2258 | CHECK_XWIDGET (xwidget); | 2296 | CHECK_LIVE_XWIDGET (xwidget); |
| 2259 | xw = XXWIDGET (xwidget); | 2297 | xw = XXWIDGET (xwidget); |
| 2260 | 2298 | ||
| 2261 | if (!xw->find_text) | 2299 | if (!xw->find_text) |
| @@ -2293,7 +2331,7 @@ to "about:blank". */) | |||
| 2293 | WebKitWebView *webview; | 2331 | WebKitWebView *webview; |
| 2294 | char *data, *uri; | 2332 | char *data, *uri; |
| 2295 | 2333 | ||
| 2296 | CHECK_XWIDGET (xwidget); | 2334 | CHECK_LIVE_XWIDGET (xwidget); |
| 2297 | CHECK_STRING (text); | 2335 | CHECK_STRING (text); |
| 2298 | if (NILP (base_uri)) | 2336 | if (NILP (base_uri)) |
| 2299 | base_uri = build_string ("about:blank"); | 2337 | base_uri = build_string ("about:blank"); |
| @@ -2321,7 +2359,9 @@ syms_of_xwidget (void) | |||
| 2321 | { | 2359 | { |
| 2322 | defsubr (&Smake_xwidget); | 2360 | defsubr (&Smake_xwidget); |
| 2323 | defsubr (&Sxwidgetp); | 2361 | defsubr (&Sxwidgetp); |
| 2362 | defsubr (&Sxwidget_live_p); | ||
| 2324 | DEFSYM (Qxwidgetp, "xwidgetp"); | 2363 | DEFSYM (Qxwidgetp, "xwidgetp"); |
| 2364 | DEFSYM (Qxwidget_live_p, "xwidget-live-p"); | ||
| 2325 | defsubr (&Sxwidget_view_p); | 2365 | defsubr (&Sxwidget_view_p); |
| 2326 | DEFSYM (Qxwidget_view_p, "xwidget-view-p"); | 2366 | DEFSYM (Qxwidget_view_p, "xwidget-view-p"); |
| 2327 | defsubr (&Sxwidget_info); | 2367 | defsubr (&Sxwidget_info); |
| @@ -2379,7 +2419,8 @@ syms_of_xwidget (void) | |||
| 2379 | 2419 | ||
| 2380 | Fprovide (intern ("xwidget-internal"), Qnil); | 2420 | Fprovide (intern ("xwidget-internal"), Qnil); |
| 2381 | 2421 | ||
| 2382 | id_to_xwidget_map = CALLN (Fmake_hash_table, QCtest, Qeq); | 2422 | id_to_xwidget_map = CALLN (Fmake_hash_table, QCtest, Qeq, |
| 2423 | QCweakness, Qvalue); | ||
| 2383 | staticpro (&id_to_xwidget_map); | 2424 | staticpro (&id_to_xwidget_map); |
| 2384 | 2425 | ||
| 2385 | #ifdef USE_GTK | 2426 | #ifdef USE_GTK |
| @@ -2605,9 +2646,10 @@ kill_buffer_xwidgets (Lisp_Object buffer) | |||
| 2605 | Vxwidget_list = Fdelq (xwidget, Vxwidget_list); | 2646 | Vxwidget_list = Fdelq (xwidget, Vxwidget_list); |
| 2606 | /* TODO free the GTK things in xw. */ | 2647 | /* TODO free the GTK things in xw. */ |
| 2607 | { | 2648 | { |
| 2608 | CHECK_XWIDGET (xwidget); | 2649 | CHECK_LIVE_XWIDGET (xwidget); |
| 2609 | struct xwidget *xw = XXWIDGET (xwidget); | 2650 | struct xwidget *xw = XXWIDGET (xwidget); |
| 2610 | Fremhash (make_fixnum (xw->xwidget_id), id_to_xwidget_map); | 2651 | xw->buffer = Qnil; |
| 2652 | |||
| 2611 | #ifdef USE_GTK | 2653 | #ifdef USE_GTK |
| 2612 | if (xw->widget_osr && xw->widgetwindow_osr) | 2654 | if (xw->widget_osr && xw->widgetwindow_osr) |
| 2613 | { | 2655 | { |
| @@ -2624,6 +2666,10 @@ kill_buffer_xwidgets (Lisp_Object buffer) | |||
| 2624 | xfree (xmint_pointer (XCAR (cb))); | 2666 | xfree (xmint_pointer (XCAR (cb))); |
| 2625 | ASET (xw->script_callbacks, idx, Qnil); | 2667 | ASET (xw->script_callbacks, idx, Qnil); |
| 2626 | } | 2668 | } |
| 2669 | |||
| 2670 | xw->widget_osr = NULL; | ||
| 2671 | xw->widgetwindow_osr = NULL; | ||
| 2672 | xw->find_text = NULL; | ||
| 2627 | #elif defined NS_IMPL_COCOA | 2673 | #elif defined NS_IMPL_COCOA |
| 2628 | nsxwidget_kill (xw); | 2674 | nsxwidget_kill (xw); |
| 2629 | #endif | 2675 | #endif |
diff --git a/src/xwidget.h b/src/xwidget.h index 6e6b39c8b4f..4377b50e840 100644 --- a/src/xwidget.h +++ b/src/xwidget.h | |||
| @@ -138,9 +138,16 @@ struct xwidget_view | |||
| 138 | #define XXWIDGET(a) (eassert (XWIDGETP (a)), \ | 138 | #define XXWIDGET(a) (eassert (XWIDGETP (a)), \ |
| 139 | XUNTAG (a, Lisp_Vectorlike, struct xwidget)) | 139 | XUNTAG (a, Lisp_Vectorlike, struct xwidget)) |
| 140 | 140 | ||
| 141 | #define XWIDGET_LIVE_P(w) (!NILP ((w)->buffer)) | ||
| 142 | |||
| 141 | #define CHECK_XWIDGET(x) \ | 143 | #define CHECK_XWIDGET(x) \ |
| 142 | CHECK_TYPE (XWIDGETP (x), Qxwidgetp, x) | 144 | CHECK_TYPE (XWIDGETP (x), Qxwidgetp, x) |
| 143 | 145 | ||
| 146 | #define CHECK_LIVE_XWIDGET(x) \ | ||
| 147 | CHECK_TYPE ((XWIDGETP (x) \ | ||
| 148 | && XWIDGET_LIVE_P (XXWIDGET (x))), \ | ||
| 149 | Qxwidget_live_p, x) | ||
| 150 | |||
| 144 | /* Test for xwidget_view pseudovector. */ | 151 | /* Test for xwidget_view pseudovector. */ |
| 145 | #define XWIDGET_VIEW_P(x) PSEUDOVECTORP (x, PVEC_XWIDGET_VIEW) | 152 | #define XWIDGET_VIEW_P(x) PSEUDOVECTORP (x, PVEC_XWIDGET_VIEW) |
| 146 | #define XXWIDGET_VIEW(a) (eassert (XWIDGET_VIEW_P (a)), \ | 153 | #define XXWIDGET_VIEW(a) (eassert (XWIDGET_VIEW_P (a)), \ |