Hi Mitko, last time I tried creating a simple C application for testing but I did get always correct values. (Btw I used g_idle_add) Can you try to write a minimal test application that still exhibits the problem? That would be very helpful!
Il giorno mer 9 gen 2019, 18:32 Mitko Haralanov via gtk-list < gtk-list@gnome.org> ha scritto: > After some offline discussion, I decided to experiment with > g_idle_add_full() since that function seems to work for other people. > > Unfortunately, it doesn't in my case. The width of the first column is > still 0 and bad behavior is reproducible: > > column[0](0) = 0 -> 0 > cell[0] = min->102, natural->102, text->98 > column[1](66) = 98 -> 164 > cell[0] = min->20, natural->20 > cell[1] = min->16, natural->16 > cell[2] = min->35, natural->35 > column[2](36) = 164 -> 200 > cell[0] = min->16, natural->16 > x = 138.000000, y = 274.000000 > > Looking at the code for g_main_context_invoke_full() and > g_idle_add_full(), as expected, the portion of > g_main_context_invoke_full() that deals with the idle source is > virtually identical to g_idle_add_full(). So, the issue is somewhere > deeper. > > Are there any GLib or Gtk+ developers on this list that can offer any help? > > On Tue, Jan 8, 2019 at 4:35 PM Lex Trotman <ele...@gmail.com> wrote: > > > > "calling gtk functions from a thread would be possible only through > > g_idle_add()." thats my understanding from > > https://developer.gnome.org/gdk3/stable/gdk3-Threads.html and thats > > what our app does. It never seems to be a performance problem, the > > main thread continuously chews its way through the idle queue. > > > > Cheers > > Lex > > > > On Wed, 9 Jan 2019 at 10:17, Mitko Haralanov <voidtra...@gmail.com> > wrote: > > > > > > I havent looked at the actual code but I am willing to bet that the > "idle source" is just using g_idle_add(). If so, > g_main_context_invoke_full() is essentially the same. > > > > > > If not the case, calling gtk functions from a thread would be possible > only through g_idle_add(). I would think that if that were the case, it > would have been mentioned in the docs. > > > > > > Thank you, > > > Mitko > > > > > > On Tue, Jan 8, 2019, 16:11 Lex Trotman <ele...@gmail.com wrote: > > >> > > >> Hi Mitko, > > >> > > >> Same problem, from g_main_context_invoke() "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)." > > >> > > >> Cheers > > >> Lex > > >> > > >> On Wed, 9 Jan 2019 at 09:55, Mitko Haralanov <voidtra...@gmail.com> > wrote: > > >> > > > >> > Hi Lex, > > >> > > > >> > That is for the "notify" callback, which only deals with > free/release > > >> > of the "data" pointer. The "function" callback is different and > should > > >> > be called from the context default thread (as the documentation > > >> > describes.) > > >> > > > >> > Thank you, > > >> > Mitko > > >> > > > >> > On Tue, Jan 8, 2019 at 3:44 PM Lex Trotman <ele...@gmail.com> > wrote: > > >> > > > > >> > > Mito, > > >> > > > > >> > > It seems to me that since the g_main_context_invoke_full() docs > say > > >> > > "notify should not assume that it is called from any particular > > >> > > thread" that notify cannot call GTK functions since GTK is not > thread > > >> > > safe. > > >> > > > > >> > > Cheers > > >> > > Lex > > >> > > > > >> > > PS I'm not on gtk-list and am not gonna join for one line, feel > free to forward > > >> > > > > >> > > On Wed, 9 Jan 2019 at 04:03, Mitko Haralanov via gtk-list > > >> > > <gtk-list@gnome.org> wrote: > > >> > > > > > >> > > > Thanks for the reply. > > >> > > > > > >> > > > When calling g_main_context_invoke_full(), I am using NULL as > the > > >> > > > context pointer. According to the documentation of > > >> > > > g_main_context_invoke(): > > >> > > > > > >> > > > "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 > > >> > > > directly: > > >> > > > > > >> > > > "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, > > >> > > > > > >> > > > Mitko > > >> > > > > > >> > > > > > >> > > > On Mon, Jan 7, 2019 at 3:54 PM ente <e...@ck76.de> wrote: > > >> > > > > > > >> > > > > Hi, > > >> > > > > > > >> > > > > > > >> > > > > 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 > > >> > > > > says: > > >> > > > > "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 > > >> > > > > handler. > > >> > > > > > > >> > > > > 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. > > >> > > > > > > >> > > > > > > >> > > > > regards, > > >> > > > > > > >> > > > > > > >> > > > > ente > > >> > > > > > > >> > > > > > > >> > > > > 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 > > >> > > > > > 0. > > >> > > > > > > > >> > > > > > Thank you. > > >> > > > > > > > >> > > > > > On Tue, Dec 18, 2018, 13:40 Mitko Haralanov < > > >> > > > > > voidtra...@gmail.com > > >> > > > > > wrote: > > >> > > > > > > > >> > > > > > > This is Gtk3: > > >> > > > > > > gtk3-3.22.26-2.fc27.x86_64 > > >> > > > > > > > > >> > > > > > > On Tue, Dec 18, 2018 at 1:14 PM Luca Bacci via gtk-list < > > >> > > > > > > gtk-list@gnome.org > > >> > > > > > > > wrote: > > >> > > > > > > > > >> > > > > > > > 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 < > > >> > > > > > > > > voidtra...@gmail.com > > >> > > > > > > > > > > > >> > > > > > > > > Date: Tue, Dec 18, 2018 at 9:37 AM > > >> > > > > > > > > Subject: Re: Emitting signals from threads > > >> > > > > > > > > To: Luca Bacci < > > >> > > > > > > > > luca.bacci...@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 < > > >> > > > > > > > > voidtra...@gmail.com > > >> > > > > > > > > > > > >> > > > > > > > > wrote: > > >> > > > > > > > > > > >> > > > > > > > > > I am not posting the complete function because > there is a lot > > >> > > > > > > > > > of > > >> > > > > > > > > > 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, > > >> > > > > > > > > > button->y, > > >> > > > > > > > > > &path, &column, NULL, NULL)) > > >> > > > > > > > > > return FALSE; > > >> > > > > > > > > > > > >> > > > > > > > > > index = > GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(column), > > >> > > > > > > > > > "index")); > > >> > > > > > > > > > if (index != TREEVIEW_COLUMN_EDIT) > > >> > > > > > > > > > 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.bacci...@gmail.com > > >> > > > > > > > > > > > > >> > > > > > > > > > wrote: > > >> > > > > > > > > > > > >> > > > > > > > > > > Hi Mitko! Can you post here the code for the > button-press > > >> > > > > > > > > > > event > > >> > > > > > > > > > > handler? > > >> > > > > > > > > > > It should more or less follow the code here: > > >> > > > > > > > > > > > http://scentric.net/tutorial/sec-misc-get-renderer-from-click.html > > >> > > > > > > > > > > > > >> > > > > > > > > > > > > >> > > > > > > > > > > Luca > > >> > > > > > > > > > > > > >> > > > > > > > > > > Il giorno lun 17 dic 2018 alle ore 20:28 Mitko > Haralanov > > >> > > > > > > > > > > via gtk-list < > > >> > > > > > > > > > > gtk-list@gnome.org > > >> > > > > > > > > > > > ha scritto: > > >> > > > > > > > > > > > > >> > > > > > > > > > > > Hi, > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > 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 > > >> > > > > > > > > > > > view. > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > 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 > > >> > > > > > > > > > > > continuously > > >> > > > > > > > > > > > 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 > > >> > > > > > > > > > > > signals > > >> > > > > > > > > > > > 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 > > >> > > > > > > > > > > > g_idle_add(). > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Can someone shed some light into what might be > happening? > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > Thank you. > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > _______________________________________________ > > >> > > > > > > > > > > > gtk-list mailing list > > >> > > > > > > > > > > > gtk-list@gnome.org > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > > https://mail.gnome.org/mailman/listinfo/gtk-list > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > > > >> > > > > > > > > > > > > >> > > > > > > > > > > _______________________________________________ > > >> > > > > > > > > > > >> > > > > > > > > gtk-list mailing list > > >> > > > > > > > > gtk-list@gnome.org > > >> > > > > > > > > > > >> > > > > > > > > https://mail.gnome.org/mailman/listinfo/gtk-list > > >> > > > > > > > > > > >> > > > > > > > > > > >> > > > > > > > > > >> > > > > > > > _______________________________________________ > > >> > > > > > > > gtk-list mailing list > > >> > > > > > > > gtk-list@gnome.org > > >> > > > > > > > > > >> > > > > > > > https://mail.gnome.org/mailman/listinfo/gtk-list > > >> > > > > > > > > > >> > > > > > > > > > >> > > > > > > > >> > > > > > _______________________________________________ > > >> > > > > > gtk-list mailing list > > >> > > > > > gtk-list@gnome.org > > >> > > > > > > > >> > > > > > https://mail.gnome.org/mailman/listinfo/gtk-list > > >> > > > > > > > >> > > > > > > >> > > > > > > >> > > > > > > >> > > > _______________________________________________ > > >> > > > gtk-list mailing list > > >> > > > gtk-list@gnome.org > > >> > > > https://mail.gnome.org/mailman/listinfo/gtk-list > _______________________________________________ > gtk-list mailing list > gtk-list@gnome.org > https://mail.gnome.org/mailman/listinfo/gtk-list >
_______________________________________________ gtk-list mailing list gtk-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-list