Re: Emitting signals from threads

Thanks for the reply.

When calling g_main_context_invoke_full(), I am using NULL as the
context pointer. According to the documentation of

        "If context is NULL then the global default main context — as
returned by g_main_context_default() — is used."

So, the code should be using the correct context.

One of the main reasons why I am not using g_idle_add() is the timing
of the callback. I don't want to defer the processing of the callback
to the "idle" time since this is signal handling related. Another
advantage of g_main_context_invoke[_full]() is that it will check the
"context" of the caller and, if possible, will call the callback

       "If context is owned by the current thread, function is called
directly. Otherwise, if context is the thread-default main context of
the current thread and g_main_context_acquire()
       succeeds, then function is called and g_main_context_release()
is called afterwards.
       In any other case, an idle source is created to call function
and that source is attached to context (presumably to be run in
another thread). The idle source is attached with
       G_PRIORITY_DEFAULT priority. If you want a different priority,
use g_main_context_invoke_full()."

Your suggested implementation is basically the GLib's async queues.
Or, may be, a custom event source. However, it seems that
g_main_context_invoke_full() should be doing exactly that. With all
due respect, I also don't see how it would solve the issue. If the
current implementation has an problem with locking/race conditions,
would your suggested implementation suffer from the same issue since
it's using the same or similar mechanism for calling the callback?

Thank you,


On Mon, Jan 7, 2019 at 3:54 PM ente <ente ck76 de> wrote:


I am not sure with my answer. Treat it as unreliable.

There seems to be a difference between g_idle_add
and g_main_context_invoke_full. While the documentation of idle_add
"Adds a function to be called [...] to the default main loop." (i.e.
main thread / the only gtk-thread) g_main_context_invoke_full does not
mention the main loop - although it mentions a "context" which I have
no experience with and which may be related to the main loop. So maybe
you must retrieve the correct context using g_main_context_default or
g_main_context_acquire. Keep in mind: glib is thread safe, gtk is not.
g_main_context_invoke_full may support glib multi threading while
g_idle_add clearly sends your function call to the gtk thread.

The effect you are describing makes sense to me. The effects you
observe sound very much like race conditions in the treeview event

Why aren't you using g_idle_add in the first place? In my experience
this works like a charm. Be careful with one thing tho: The main loop
has a "todo-list". Each time you call "g_idle_add" it adds an item to
that todo-list and schedules a call to your function. If your function
doesn't return false, it won't even be taken down from the todo-list.
Each click event ends on that todo-list. Each column resize adds
multiple items to that todo-list (depending on your column resize
policy and the number of rows). As soon as you add more items to that
list, your UI becomes unresponsive. It seems advisable to build your
own shadow todo-list for the update process, i.e.:
* setup a function "update_progress"
* on the first threaded update event, call idle_add for the function
and put the new progress and the row number in your own data structure
* while the function is still "planned in for idle_add", just add new
events to your own data structure
* process 1 to 10 (maybe some more) events on each of the calls
* the function returns true as long as there is still some events in
your own list; it returns false otherwise
* apply mutex checks on your data structure (not sure if i should
mention, I am sure you had this in your mind already)

Each time you update a progress bar in your treeview, several (at least
one) events are added to the gtk-todo list (repaint!, re-order? and
maybe some more). Doing multiple progress events at once may lower the
amount of events, gtk has to process (a re-order affects all rows -
doing an update on multiple rows does not change anything here).

That's my 5 cents. I hope it helped a bit.



On Mon, 2019-01-07 at 08:28 -0800, Mitko Haralanov via gtk-list wrote:
Anyone have any ideas? I still can't figure out why the column sizes
go to

Thank you.

On Tue, Dec 18, 2018, 13:40 Mitko Haralanov <
voidtrance gmail com

This is Gtk3:

On Tue, Dec 18, 2018 at 1:14 PM Luca Bacci via gtk-list <
gtk-list gnome org

Is it Gtk2 or Gtk3, which version exactly?

Il giorno mar 18 dic 2018 alle ore 18:47 Mitko Haralanov via gtk-
list <
gtk-list gnome org
ha scritto:

I mistakenly replied only to Luca!! Forwarding to the list.

(Sorry, Luca, my bad)
- Mitko

---------- Forwarded message ---------
From: Mitko Haralanov <
voidtrance gmail com

Date: Tue, Dec 18, 2018 at 9:37 AM
Subject: Re: Emitting signals from threads
To: Luca Bacci <
luca bacci982 gmail com

I found something that is different between the two cases -
button click
with signals and without.

Using the code from the link that Luca posted, I decided to
print the
size of each column when a button press is received. As it
turns out, the
width of the columns is different in the two cases:

Without thread signals:
column[0](193) = 0 -> 193
cell[0] = min->109, natural->109
column[1](66) = 193 -> 259
cell[0] = min->20, natural->20
cell[1] = min->16, natural->16
cell[2] = min->35, natural->35
column[2](36) = 259 -> 295
cell[0] = min->16, natural->16
x = 105.872116, y = 259.547516

(x and y are the coordinates of the button press event)

With thread signals:
column[0](0) = 0 -> 0
cell[0] = min->135, natural->135
column[1](66) = 0 -> 66
cell[0] = min->20, natural->20
cell[1] = min->16, natural->16
cell[2] = min->35, natural->35
column[2](36) = 66 -> 102
cell[0] = min->16, natural->16
x = 113.528488, y = 158.563782

As you can see, the width of the first column is 0 when the
signals are
being emitted. As expected, if I were to click very close to
the left
border of the widget, the edit dialog does not get triggered as
the x
coordinate falls within column 1:

column[0](0) = 0 -> 0
cell[0] = min->135, natural->135
column[1](66) = 0 -> 66
cell[0] = min->20, natural->20
cell[1] = min->16, natural->16
cell[2] = min->35, natural->35
column[2](36) = 66 -> 102
cell[0] = min->16, natural->16
x = 21.247330, y = 181.310333

I could use the cell renderer width if the column width is 0
but that
seems unreliable since the cell renderer width is not the same
as the
column and it's also not static.

On Tue, Dec 18, 2018 at 8:23 AM Mitko Haralanov <
voidtrance gmail com


I am not posting the complete function because there is a lot
irrelevant code. I am also not interested in the specific
cell renderer but
rather the row on which the click occurred.

tatic gboolean on_button_press_event(GtkWidget *widget,
      GdkEvent *event,
      gpointer data)
GtkTreeView *treeview = GTK_TREE_VIEW(widget);
GdkEventButton *button = (GdkEventButton *)event;
GtkTreeModel *model;
GtkTreePath *path;
GtkTreeIter iter;
GtkTreeViewColumn *column;
GtkScopeProjectEditDialog *dialog;
GtkScopeProjectEditData *pdata, fill;
GtkScopeProject *project;
guint response, index;
gboolean ret = FALSE;

if (button->type != GDK_BUTTON_PRESS ||
    !gtk_tree_view_get_path_at_pos(treeview, button->x,
   &path, &column, NULL, NULL))
return FALSE;

index = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(column),
goto done;
model = gtk_tree_view_get_model(treeview);
if (!gtk_tree_model_get_iter(model, &iter, path))
goto done;
gtk_tree_model_get(model, &iter, PROJECT_COLUMN_OBJ,
&project, -1);

The issue is that the column which is returned by
gtk_tree_view_get_path_at_pos() is different depending on
whether thread
signals are being emitted vs not. I have verified that the
button press
coordinates are the same (button->x and button->y have the
same values in
both cases).

On Tue, Dec 18, 2018 at 5:24 AM Luca Bacci <
luca bacci982 gmail com


Hi Mitko! Can you post here the code for the button-press
It should more or less follow the code here:


Il giorno lun 17 dic 2018 alle ore 20:28 Mitko Haralanov
via gtk-list <
gtk-list gnome org
ha scritto:


In my application, I want to be able to update a treeview
from a
separate thread. Each treeview row was a column that is a
progress bar. The
progress to be displayed is generated by a separate
thread as to not block
the UI.

Since GTK is not thread-safe, the way the application is
written is
that the thread, when it needs to emit a signal, will
prepare the signal
data and then call g_main_context_invoke_full(NULL, cb,
data, ...) in order
to be able to call g_singal_emit() in the global default
context thread.
The signal handler updates the tree model, which in turn
updates the tree

For the most part this works with one big, ugly exception
- the same
treeview has a column, which is supposed to open the
item's Edit dialog
when clicked. So, naturally, I have a button-press
handler connected to the
treeview, which launches the Edit dialog when the button
press occurs in
the correct column.

However, when an update is running and the thread is
emitting signals, clicking on *any* column of *any* of
the other items
opens the Edit dialog. The treeview behaves as if the
items in it have only
one column.

Every example or document that I have seen in relation to
from threads says to emit the signal from a g_idle_add()
handler. However,
g_main_context_invoke_full(NULL, ...) should be the same
as calling

Can someone shed some light into what might be happening?

Thank you.

gtk-list mailing list
gtk-list gnome org


gtk-list mailing list
gtk-list gnome org

gtk-list mailing list
gtk-list gnome org

gtk-list mailing list
gtk-list gnome org

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