Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Crash when setting the content of a GtkTextBuffer #428

Closed
pixel27 opened this issue Jul 18, 2019 · 2 comments
Closed

Crash when setting the content of a GtkTextBuffer #428

pixel27 opened this issue Jul 18, 2019 · 2 comments

Comments

@pixel27
Copy link
Contributor

pixel27 commented Jul 18, 2019

This only seems to happen if you also looking for a changed signal on the buffer.

using Gtk

function test(glade)
    builder = GtkBuilder(buffer=glade)
    showall(builder["main"])

    signal_connect(builder["buffer"], "changed") do widget
        println("Changed!")
    end

    signal_connect(builder["populate"], "clicked") do widget
        GAccessor.text(builder["buffer"], "", -1)
        # @sigatom GAccessor.text(builder["buffer"], "", -1)

        @sigatom @async begin
            sleep(1)
            @sigatom GAccessor.text(builder["buffer"], "abcde", -1)
        end
    end
end

test("""<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkTextBuffer" id="buffer"/>
  <object class="GtkApplicationWindow" id="main">
    <property name="can_focus">False</property>
    <property name="default_width">440</property>
    <property name="default_height">250</property>
    <child>
      <placeholder/>
    </child>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkButton" id="populate">
            <property name="label" translatable="yes">Populate</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkScrolledWindow">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="shadow_type">in</property>
            <child>
              <object class="GtkTextView">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="buffer">buffer</property>
              </object>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
""")

The quickest way to reproduce the issue, is enter some text into the buffer like "a", then click the Populate button and drag the window. The julia process will Segmentation fault. I didn't put the wait code so this needs to be entered or included in an interactive session.

If line 12 is commented out and line 13 is commented in, everything works fine. Not sure if this means developers should always do a @sigatom when setting the text if they are receiving the changed event or if the text call should just do it by default?

@jonathanBieler
Copy link
Collaborator

I'm not sure what the issue is but this works on my computer:

using Gtk

function update_cb!(user_data)
    buffer = user_data::GtkTextBuffer
    GAccessor.text(buffer, "abcde", -1)
    Cint(true)#keep running
end

@guarded nothing function buffer_changed_cb(ptr::Ptr, user_data)
    println("Changed!")
    nothing
end

function test(glade)
    builder = GtkBuilder(buffer=glade)
    showall(builder["main"])

    signal_connect(buffer_changed_cb, builder["buffer"] , "changed", Nothing, (), false)

    signal_connect(builder["populate"], "clicked") do widget
        GAccessor.text(builder["buffer"], "", -1)
        
        @sigatom @async begin
            sleep(1)
            @sigatom GAccessor.text(builder["buffer"], "abcde", -1)
        end

        #g_timeout_add(1000,update_cb!,builder["buffer"]) #do every 1000ms
    end
end

I'm just using an explicit signal_connect instead of the simplified do syntax (it seems it often creates issues in non-trivial cases).

You can also use g_timeout_add, it adds a function to be called from Gtk's main loop. It might be safer that using Julia's Tasks.

@pixel27
Copy link
Contributor Author

pixel27 commented Jul 19, 2019

That's interesting, yes that works for me as well. Thanks I'll look into this method.

@pixel27 pixel27 closed this as completed Jul 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants