From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Po Lu Newsgroups: gmane.emacs.devel Subject: Fix flickering on X11 xwidgets (was: Re: SVG widget in GNU Emacs) Date: Thu, 28 Oct 2021 21:50:56 +0800 Message-ID: <87bl39mf5r.fsf_-_@yahoo.com> References: <87bl3kcrpl.fsf@yahoo.com> <83ilxrc2ys.fsf@gnu.org> <875ytrc168.fsf@yahoo.com> <83a6j3c092.fsf@gnu.org> <87wnm7al92.fsf@yahoo.com> <835ytrbx8s.fsf@gnu.org> <874k92sstk.fsf@yahoo.com> <83mtmuwtv7.fsf@gnu.org> <87pmrqr6xh.fsf@yahoo.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="36721"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: Eli Zaretskii , Emacs developers To: Akira Kyle Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Thu Oct 28 15:52:24 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mg5pP-0009Lq-8J for ged-emacs-devel@m.gmane-mx.org; Thu, 28 Oct 2021 15:52:23 +0200 Original-Received: from localhost ([::1]:40346 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mg5pN-0004JU-CW for ged-emacs-devel@m.gmane-mx.org; Thu, 28 Oct 2021 09:52:21 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:48222) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mg5oN-0003aB-AU for emacs-devel@gnu.org; Thu, 28 Oct 2021 09:51:19 -0400 Original-Received: from sonic312-23.consmr.mail.ne1.yahoo.com ([66.163.191.204]:36779) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mg5oI-0003eV-0W for emacs-devel@gnu.org; Thu, 28 Oct 2021 09:51:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1635429071; bh=4bOT7ToC2hLB863qFiTzWE5LUe2zzLZN5nIDGZgwLTY=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=S4f77ilvL7U4KewV1qdldjF3PkFoSxLBrsPDp2LCOmJZ42+GiJIL5kggEwmn40EDtYs6bYZojBAhs39XsjPrjM70TIrq2ey3krPPHI8rei/gqDKPFhc47cd/GLrVJrqKWlZgM9/IOiA4M3edp3h67Bbtize1rp/9/3MdZXuEyg4I+zzczqOnkdovtaovxfDyyp60kcCCBq/qzrYCFwT6b6D+3KZJUyUBzJqHFx3PWl2C5IQ4SlsAQT/BVwIUJhNGrLy7w7YlAtoHZJSdrXqX1EDS9GT28eRGJtOcbl1qSz1EOOgYpVTtEZd1wkCC/c1UTDGiQNOTQmdtRUh+T09MYA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1635429071; bh=GlTEW1++MR4UiqmbRj076QSwfLMoUec2vG8V0mOr4sA=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=t7+Ra1NsFdfxV5pqLjtlEC73CX0cmb9r2LotCTw2sOFX7WlVIWf+KTxmg6vmpfsRj/SckWiG4mGRnNNVthnUwZeafqTPY0LC1fAp8nMAFruVVZ3HunKpuaIUgLGfZt0TSxIsqPUym2rVptxugvtXdJkabhyIevbZF698G45OAUpAJtWC0aL1QR0Dt1WOofA6xLL9va/9b4kpAmzQYpQFQcUdB1P33TERMw0nB2S8BzRJOtMjYpgrbdhtkTqzxugT4hPkZRdZ1MzYl6LdhAKSljJcERN+N8CAWGW+4Qt03k1PiUt0h5vKCr1r3n2YijiIdLy5pScF3mTfClghFnGtZg== X-YMail-OSG: eLU39N8VM1kwjht.us6u8UeA42aOaTDvCffvM4SoN2_aRb2fiB5lhLde8HDqz7f WVFAbNKCn8Z2i0py5K8.BKFNwSKgkRmvZZx8gUyoON05g4joUWYAqhnVtlAe62xw4XRvNX6w9Nrl .jxpbXtB1SGUVUOo6O7uL3e66PsiTBY..HJQJF2K_biIL67U0BUo8FxL8MibeAs22AwB2Iih7xYw U8QTEmO4nEzXaqD2LgOLcaEGbSPxnp0ssK0mBD78zKESc9TVHJnmSZcCX0ObbCjSK7bqi6qJOuSA 5mnxT6ScwHoHpPqLzQ6le2V89sFsdeMT089.TvpBB_PM2fDsDlp2aAxmpQXWrtYhqv25DQhSg9Iy 5Gu_1GxfaViTtSzv8j.P7RprOl5sGwGoJoDyvDeZTMJuLqlh5xb.oqMGeGxq80MFCITav4rzQaxa iwGcmG4MBcFfLi8K8pLvXeWtZId1bTN_eanlbN9L4ie4tbSYL0ld5aCs.Hecbt6en.eU08Dk9MB. alUM78DIicePPlEI8kVruMsRE02vo4v1RZ3EDgq3oKHa_NFky8vVvyTZQM9DB9iWpRd44t0q712i c7QRunYqHR5d.xlgJ.A72zfs.Uu2V6PeQcUNRq5AOyK7st52z11sU_odITYr6UxtLQGkFYRB8SIJ 3RsTd27N5iElEm1LJsogFDY1hb2Ld14jCfj27SLpMcwDEmdx9o5B4SpXkGnHqqgbF9HbIb46qKNM ZChi27KJGB0fpzMLACqss7t64PAlADVEAfI9RQ4qAu4gz_ipLpsqJl6lAml4XxWKHX2e5_sRuw25 D09vR2vRkcWP5YE4P6Z8QvAL6Afo_ddugjm.sSgTaL X-Sonic-MF: Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.ne1.yahoo.com with HTTP; Thu, 28 Oct 2021 13:51:11 +0000 Original-Received: by kubenode512.mail-prod1.omega.sg3.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 803afaf11ef4728873391530b78dec06; Thu, 28 Oct 2021 13:51:02 +0000 (UTC) In-Reply-To: (Akira Kyle's message of "Wed, 27 Oct 2021 14:01:38 -0600") X-Mailer: WebService/1.1.19198 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Received-SPF: pass client-ip=66.163.191.204; envelope-from=luangruo@yahoo.com; helo=sonic312-23.consmr.mail.ne1.yahoo.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:278103 Archived-At: --=-=-= Content-Type: text/plain And to confirm my suspicions, moving xwidget rendering to an X window does indeed fix the flicker. Please test the attached patch. (Unfortunately, I haven't been able to enable the scrolling optimization yet, as it will now involve moving X windows around on-screen, but I think I know how to do it and will let you know ASAP if I complete that.) --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Use-an-X-window-to-display-xwidgets-on-X11.patch >From 131416ea626309d34585301727a4311d25e3fd10 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 28 Oct 2021 21:46:01 +0800 Subject: [PATCH] Use an X window to display xwidgets on X11 Since Emacs draws using X11 primitives, Emacs drawing operations can erase the GtkDrawingArea used to draw the offscreen widget, which leads to unpleasant flickering effects, all of which can be prevented by creating a native X window and drawing to that instead. * src/xterm.c (x_window_to_frame): Return xwidget window if appropriate. (handle_one_xevent): Handle xwidget expose events. * src/xwidget.c (x_window_to_xvw_map): New variable. (xwidget_view_from_window): New function. (xwidget_show_view, xwidget_hide_view) (offscreen_damage_event): Move to drawing xwidgets with X windows. (xv_do_draw) (xwidget_expose): New function. (xwidget_osr_draw_cb, xwidget_osr_event_forward) (xwidget_osr_event_set_embedder): Removed. (xwidget_init_view): Replace use of GtkDrawingArea with that of an X window. (x_draw_xwidget_glyph_string): Prevent xwidget views from constantly generating expose events, and use an X window instead of a GtkDrawingArea. (syms_of_xwidget): Initialize x_window_to_xwv_map. src/xwidget.h (struct xwidget_view): Replace GTK widgets with X-related fields. (xwidget_view_from_window, xwidget_expose): New functions. --- src/xterm.c | 24 ++++- src/xwidget.c | 277 ++++++++++++++++++++++++++------------------------ src/xwidget.h | 12 ++- 3 files changed, 175 insertions(+), 138 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index aa1a1a5eed..54bfb65bd0 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -4563,8 +4563,9 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra } } -/* Return the Emacs frame-object corresponding to an X window. - It could be the frame's main window or an icon window. */ +/* Return the Emacs frame-object corresponding to an X window. It + could be the frame's main window, an icon window, or an xwidget + window. */ static struct frame * x_window_to_frame (struct x_display_info *dpyinfo, int wdesc) @@ -4575,6 +4576,13 @@ x_window_to_frame (struct x_display_info *dpyinfo, int wdesc) if (wdesc == None) return NULL; +#ifdef HAVE_XWIDGETS + struct xwidget_view *xvw = xwidget_view_from_window (wdesc); + + if (xvw && xvw->frame) + return xvw->frame; +#endif + FOR_EACH_FRAME (tail, frame) { f = XFRAME (frame); @@ -8211,6 +8219,18 @@ handle_one_xevent (struct x_display_info *dpyinfo, case Expose: f = x_window_to_frame (dpyinfo, event->xexpose.window); +#ifdef HAVE_XWIDGETS + { + struct xwidget_view *xv = + xwidget_view_from_window (event->xexpose.window); + + if (xv) + { + xwidget_expose (xv); + goto OTHER; + } + } +#endif if (f) { if (!FRAME_VISIBLE_P (f)) diff --git a/src/xwidget.c b/src/xwidget.c index e4b42e6e0c..1bd27091d0 100644 --- a/src/xwidget.c +++ b/src/xwidget.c @@ -35,10 +35,16 @@ Copyright (C) 2011-2021 Free Software Foundation, Inc. #ifdef USE_GTK #include #include +#include +#include #elif defined NS_IMPL_COCOA #include "nsxwidget.h" #endif +#ifdef USE_GTK +static Lisp_Object x_window_to_xwv_map; +#endif + static struct xwidget * allocate_xwidget (void) { @@ -222,15 +228,28 @@ xwidget_hidden (struct xwidget_view *xv) } #ifdef USE_GTK + +struct xwidget_view * +xwidget_view_from_window (Window wdesc) +{ + Lisp_Object key = make_fixnum (wdesc); + Lisp_Object xwv = Fgethash (key, x_window_to_xwv_map, Qnil); + + if (NILP (xwv)) + return NULL; + + return XXWIDGET_VIEW (xwv); +} + static void xwidget_show_view (struct xwidget_view *xv) { xv->hidden = false; - gtk_widget_show (xv->widgetwindow); - gtk_fixed_move (GTK_FIXED (xv->emacswindow), - xv->widgetwindow, - xv->x + xv->clip_left, - xv->y + xv->clip_top); + XMoveWindow (xv->dpy, xv->wdesc, + xv->x + xv->clip_left, + xv->y + xv->clip_top); + XMapWindow (xv->dpy, xv->wdesc); + XFlush (xv->dpy); } /* Hide an xwidget view. */ @@ -238,28 +257,48 @@ xwidget_show_view (struct xwidget_view *xv) xwidget_hide_view (struct xwidget_view *xv) { xv->hidden = true; - gtk_fixed_move (GTK_FIXED (xv->emacswindow), xv->widgetwindow, - 10000, 10000); + XUnmapWindow (xv->dpy, xv->wdesc); + XFlush (xv->dpy); +} + +static void +xv_do_draw (struct xwidget_view *xw, struct xwidget *w) +{ + block_input (); + + cairo_save (xw->cr_context); + cairo_translate (xw->cr_context, -xw->clip_left, + -xw->clip_top); + gtk_widget_draw (w->widget_osr, xw->cr_context); + cairo_restore (xw->cr_context); + + unblock_input (); } /* When the off-screen webkit master view changes this signal is called. It copies the bitmap from the off-screen instance. */ static gboolean offscreen_damage_event (GtkWidget *widget, GdkEvent *event, - gpointer xv_widget) + gpointer xwidget_view) { - /* Queue a redraw of onscreen widget. - There is a guard against receiving an invalid widget, - which should only happen if we failed to remove the - specific signal handler for the damage event. */ - if (GTK_IS_WIDGET (xv_widget)) - gtk_widget_queue_draw (GTK_WIDGET (xv_widget)); - else - message ("Warning, offscreen_damage_event received invalid xv pointer:%p\n", - xv_widget); + struct xwidget_view *xw = xwidget_view; + struct xwidget *w = XXWIDGET (xw->model); + + if (xw->wdesc == None) + return FALSE; + + xv_do_draw (xw, w); return FALSE; } + +void +xwidget_expose (struct xwidget_view *xv) +{ + struct xwidget *xw = XXWIDGET (xv->model); + + xv_do_draw (xv, xw); +} #endif /* USE_GTK */ void @@ -498,51 +537,6 @@ webkit_decide_policy_cb (WebKitWebView *webView, return FALSE; } } - - -/* For gtk3 offscreen rendered widgets. */ -static gboolean -xwidget_osr_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) -{ - struct xwidget *xw = g_object_get_data (G_OBJECT (widget), XG_XWIDGET); - struct xwidget_view *xv = g_object_get_data (G_OBJECT (widget), - XG_XWIDGET_VIEW); - - cairo_rectangle (cr, 0, 0, xv->clip_right, xv->clip_bottom); - cairo_clip (cr); - - gtk_widget_draw (xw->widget_osr, cr); - return FALSE; -} - -static gboolean -xwidget_osr_event_forward (GtkWidget *widget, GdkEvent *event, - gpointer user_data) -{ - /* Copy events that arrive at the outer widget to the offscreen widget. */ - struct xwidget *xw = g_object_get_data (G_OBJECT (widget), XG_XWIDGET); - GdkEvent *eventcopy = gdk_event_copy (event); - eventcopy->any.window = gtk_widget_get_window (xw->widget_osr); - - /* TODO: This might leak events. They should be deallocated later, - perhaps in xwgir_event_cb. */ - gtk_main_do_event (eventcopy); - - /* Don't propagate this event further. */ - return TRUE; -} - -static gboolean -xwidget_osr_event_set_embedder (GtkWidget *widget, GdkEvent *event, - gpointer data) -{ - struct xwidget_view *xv = data; - struct xwidget *xww = XXWIDGET (xv->model); - gdk_offscreen_window_set_embedder (gtk_widget_get_window - (xww->widgetwindow_osr), - gtk_widget_get_window (xv->widget)); - return FALSE; -} #endif /* USE_GTK */ @@ -568,63 +562,21 @@ xwidget_init_view (struct xwidget *xww, XSETXWIDGET (xv->model, xww); #ifdef USE_GTK - if (EQ (xww->type, Qwebkit)) - { - xv->widget = gtk_drawing_area_new (); - /* Expose event handling. */ - gtk_widget_set_app_paintable (xv->widget, TRUE); - gtk_widget_add_events (xv->widget, GDK_ALL_EVENTS_MASK); - - /* Draw the view on damage-event. */ - g_signal_connect (G_OBJECT (xww->widgetwindow_osr), "damage-event", - G_CALLBACK (offscreen_damage_event), xv->widget); - - if (EQ (xww->type, Qwebkit)) - { - g_signal_connect (G_OBJECT (xv->widget), "button-press-event", - G_CALLBACK (xwidget_osr_event_forward), NULL); - g_signal_connect (G_OBJECT (xv->widget), "button-release-event", - G_CALLBACK (xwidget_osr_event_forward), NULL); - g_signal_connect (G_OBJECT (xv->widget), "motion-notify-event", - G_CALLBACK (xwidget_osr_event_forward), NULL); - } - else - { - /* xwgir debug, orthogonal to forwarding. */ - g_signal_connect (G_OBJECT (xv->widget), "enter-notify-event", - G_CALLBACK (xwidget_osr_event_set_embedder), xv); - } - g_signal_connect (G_OBJECT (xv->widget), "draw", - G_CALLBACK (xwidget_osr_draw_cb), NULL); - } + xv->dpy = FRAME_X_DISPLAY (s->f); - /* Widget realization. - - Make container widget first, and put the actual widget inside the - container later. Drawing should crop container window if necessary - to handle case where xwidget is partially obscured by other Emacs - windows. Other containers than gtk_fixed where explored, but - gtk_fixed had the most predictable behavior so far. */ - - xv->emacswindow = FRAME_GTK_WIDGET (s->f); - xv->widgetwindow = gtk_fixed_new (); - gtk_widget_set_has_window (xv->widgetwindow, TRUE); - gtk_container_add (GTK_CONTAINER (xv->widgetwindow), xv->widget); - - /* Store some xwidget data in the gtk widgets. */ - g_object_set_data (G_OBJECT (xv->widget), XG_FRAME_DATA, s->f); - g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET, xww); - g_object_set_data (G_OBJECT (xv->widget), XG_XWIDGET_VIEW, xv); - g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET, xww); - g_object_set_data (G_OBJECT (xv->widgetwindow), XG_XWIDGET_VIEW, xv); - - gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xww->width, - xww->height); - gtk_widget_set_size_request (xv->widgetwindow, xww->width, xww->height); - gtk_fixed_put (GTK_FIXED (FRAME_GTK_WIDGET (s->f)), xv->widgetwindow, x, y); xv->x = x; xv->y = y; - gtk_widget_show_all (xv->widgetwindow); + + xv->clip_left = 0; + xv->clip_right = xww->width; + xv->clip_top = 0; + xv->clip_bottom = xww->height; + + 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); @@ -681,6 +633,8 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) window_box (s->w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width, &text_area_height); + /* On X11, this keeps generating expose events. */ +#ifndef USE_GTK /* Resize xwidget webkit if its container window size is changed in some ways, for example, a buffer became hidden in small split window, then it can appear front in merged whole window. */ @@ -693,6 +647,7 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) make_int (text_area_width), make_int (text_area_height)); } +#endif clip_left = max (0, text_area_x - x); clip_right = max (clip_left, @@ -711,15 +666,45 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) later. */ bool moved = (xv->x + xv->clip_left != x + clip_left || xv->y + xv->clip_top != y + clip_top); + +#ifdef USE_GTK + bool wdesc_was_none = xv->wdesc == None; +#endif xv->x = x; xv->y = y; +#ifdef USE_GTK + block_input (); + if (xv->wdesc == None) + { + Lisp_Object xvw; + XSETXWIDGET_VIEW (xvw, xv); + XSetWindowAttributes a; + a.event_mask = ExposureMask; + + xv->wdesc = XCreateWindow (xv->dpy, FRAME_X_WINDOW (s->f), + x + clip_left, y + clip_top, + clip_right - clip_left, + clip_bottom - clip_top, 0, + CopyFromParent, CopyFromParent, + CopyFromParent, CWEventMask, &a); + xv->cr_surface = cairo_xlib_surface_create (xv->dpy, + xv->wdesc, + FRAME_DISPLAY_INFO (s->f)->visual, + clip_right - clip_left, + clip_bottom - clip_top); + xv->cr_context = cairo_create (xv->cr_surface); + Fputhash (make_fixnum (xv->wdesc), xvw, x_window_to_xwv_map); + + moved = false; + } +#endif + /* Has it moved? */ if (moved) { #ifdef USE_GTK - gtk_fixed_move (GTK_FIXED (FRAME_GTK_WIDGET (s->f)), - xv->widgetwindow, x + clip_left, y + clip_top); + XMoveWindow (xv->dpy, xv->wdesc, x + clip_left, y + clip_top); #elif defined NS_IMPL_COCOA nsxwidget_move_view (xv, x + clip_left, y + clip_top); #endif @@ -735,10 +720,14 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) || xv->clip_top != clip_top || xv->clip_left != clip_left) { #ifdef USE_GTK - gtk_widget_set_size_request (xv->widgetwindow, clip_right - clip_left, - clip_bottom - clip_top); - gtk_fixed_move (GTK_FIXED (xv->widgetwindow), xv->widget, -clip_left, - -clip_top); + if (!wdesc_was_none) + { + XResizeWindow (xv->dpy, xv->wdesc, clip_right - clip_left, + clip_bottom - clip_top); + XFlush (xv->dpy); + cairo_xlib_surface_set_size (xv->cr_surface, clip_right - clip_left, + clip_bottom - clip_top); + } #elif defined NS_IMPL_COCOA nsxwidget_resize_view (xv, clip_right - clip_left, clip_bottom - clip_top); @@ -758,12 +747,15 @@ x_draw_xwidget_glyph_string (struct glyph_string *s) if (!xwidget_hidden (xv)) { #ifdef USE_GTK - gtk_widget_queue_draw (xv->widgetwindow); - gtk_widget_queue_draw (xv->widget); + xv_do_draw (xv, xww); #elif defined NS_IMPL_COCOA nsxwidget_set_needsdisplay (xv); #endif } + +#ifdef USE_GTK + unblock_input (); +#endif } static bool @@ -976,8 +968,13 @@ DEFUN ("xwidget-resize", Fxwidget_resize, Sxwidget_resize, 3, 3, 0, if (XXWIDGET (xv->model) == xw) { #ifdef USE_GTK - gtk_widget_set_size_request (GTK_WIDGET (xv->widget), xw->width, - xw->height); + if (xv->wdesc != None) + { + XResizeWindow (xv->dpy, xv->wdesc, xw->width, xw->height); + XFlush (xv->dpy); + cairo_xlib_surface_set_size (xv->cr_surface, + xw->width, xw->height); + } #elif defined NS_IMPL_COCOA nsxwidget_resize_view(xv, xw->width, xw->height); #endif @@ -1084,13 +1081,21 @@ DEFUN ("delete-xwidget-view", CHECK_XWIDGET_VIEW (xwidget_view); struct xwidget_view *xv = XXWIDGET_VIEW (xwidget_view); #ifdef USE_GTK - gtk_widget_destroy (xv->widgetwindow); - /* 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->widget); + 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); + Fputhash (make_fixnum (xv->wdesc), Qnil, x_window_to_xwv_map); + unblock_input (); + } #elif defined NS_IMPL_COCOA nsxwidget_delete_view (xv); #endif @@ -1236,6 +1241,12 @@ syms_of_xwidget (void) Vxwidget_view_list = Qnil; Fprovide (intern ("xwidget-internal"), Qnil); + +#ifdef USE_GTK + x_window_to_xwv_map = CALLN (Fmake_hash_table, QCtest, Qequal); + + staticpro (&x_window_to_xwv_map); +#endif } diff --git a/src/xwidget.h b/src/xwidget.h index 591f23489d..fc68b52cdb 100644 --- a/src/xwidget.h +++ b/src/xwidget.h @@ -32,6 +32,7 @@ #define XWIDGET_H_INCLUDED #if defined (USE_GTK) #include +#include #elif defined (NS_IMPL_COCOA) && defined (__OBJC__) #import #import "nsxwidget.h" @@ -98,9 +99,12 @@ #define XWIDGET_H_INCLUDED bool hidden; #if defined (USE_GTK) - GtkWidget *widget; - GtkWidget *widgetwindow; - GtkWidget *emacswindow; + Display *dpy; + Window wdesc; + struct frame *frame; + + cairo_surface_t *cr_surface; + cairo_t *cr_context; #elif defined (NS_IMPL_COCOA) # ifdef __OBJC__ XvWindow *xvWindow; @@ -162,6 +166,8 @@ #define XG_XWIDGET_VIEW "emacs_xwidget_view" void store_xwidget_js_callback_event (struct xwidget *xw, Lisp_Object proc, Lisp_Object argument); +struct xwidget_view *xwidget_view_from_window (Window wdesc); +void xwidget_expose (struct xwidget_view *xv); #else INLINE_HEADER_BEGIN INLINE void syms_of_xwidget (void) {} -- 2.31.1 --=-=-=--