emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/pgtk 42d4ffa 1/3: Fix SEGV crash by unref css provider too much


From: Yuuki Harano
Subject: feature/pgtk 42d4ffa 1/3: Fix SEGV crash by unref css provider too much
Date: Mon, 6 Dec 2021 10:47:42 -0500 (EST)

branch: feature/pgtk
commit 42d4ffad5ad3c381a5495c7ce059ff1526a22a28
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Yuuki Harano <masm+github@masm11.me>

    Fix SEGV crash by unref css provider too much
    
    I Got css provider from F, and was going to remove it from style
    context.  But between them, unhighlight was called when
    gtk_container_remove was called, and the css provider was already
    freed, so I can't use the css provider to remove it from style
    context.
    
    As a fix, I call gtk_container_remove after remove it.
    Also, I free a css provider set by unhighlight.
    
    * src/pgtkterm.c (x_set_parent_frame):
---
 src/pgtkterm.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index bf863c8..ed7a4a4 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -798,15 +798,19 @@ x_set_parent_frame (struct frame *f, Lisp_Object 
new_value,
       gtk_widget_get_allocation (fixed, &alloc);
       g_object_ref (fixed);
 
+      /* Remember the css provider, and restore it later. */
       GtkCssProvider *provider = FRAME_X_OUTPUT (f)->border_color_css_provider;
+      FRAME_X_OUTPUT (f)->border_color_css_provider = NULL;
+      {
+       GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
+       gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (provider));
+      }
 
       {
        GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed);
+       /* Here, unhighlight can be called and may change 
border_color_css_provider. */
        gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed);
 
-       GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
-       gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (provider));
-
        if (FRAME_GTK_OUTER_WIDGET (f))
          {
            gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
@@ -842,9 +846,17 @@ x_set_parent_frame (struct frame *f, Lisp_Object new_value,
          gtk_widget_show_all (fixed);
        }
 
+      /* Restore css provider. */
       GtkStyleContext *ctxt = gtk_widget_get_style_context (FRAME_WIDGET (f));
+      GtkCssProvider *old = FRAME_X_OUTPUT (f)->border_color_css_provider;
+      FRAME_X_OUTPUT (f)->border_color_css_provider = provider;
       gtk_style_context_add_provider (ctxt, GTK_STYLE_PROVIDER (provider),
                                      GTK_STYLE_PROVIDER_PRIORITY_USER);
+      if (old != NULL)
+       {
+         gtk_style_context_remove_provider (ctxt, GTK_STYLE_PROVIDER (old));
+         g_object_unref(old);
+       }
 
       g_object_unref (fixed);
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]