Re: Input event reduction
On 30 March 2017 at 11:21, Gabriele Grecowrote: >> >> Thanks. While I can remember have read your explanations somewhere >> already, I really missed that g_main_context_invoke() function. > > > There is some difference/advantage on calling: > > g_main_context_invoke(NULL, func, data)? > > instead of > > g_idle_add(func, data); Calling g_main_context_invoke() will ensure that the main context is owned and acquired during the invocation. As I said, it will do the right thing depending on the type of context you are using. > As far as I can see from the function documentations g_main_context_invoke > seems useful when having multiple contexts on different threads, I'm wrong? Correct, but remember that different libraries may have different contexts in different threads already by the time you call your code. It's also a good rule of thumb to start using this function, as it will be more efficient once you start using API like GTask, with its own main context. Ciao, Emmanuele. -- https://www.bassi.io [@] ebassi [@gmail.com] ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
> > > Thanks. While I can remember have read your explanations somewhere > already, I really missed that g_main_context_invoke() function. There is some difference/advantage on calling: g_main_context_invoke(NULL, func, data)? instead of g_idle_add(func, data); As far as I can see from the function documentations g_main_context_invoke seems useful when having multiple contexts on different threads, I'm wrong? -- *Bye,* * Gabry* ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
On Thu, 2017-03-30 at 10:21 +0100, Emmanuele Bassi wrote: > g_idle_add() or, better yet, g_main_context_invoke(). Thanks. While I can remember have read your explanations somewhere already, I really missed that g_main_context_invoke() function. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
On Thu, 2017-03-30 at 11:10 +0200, Nicola Fontana wrote: > > > As said you can leverage the main loop and unroll yours, e.g.: > > gboolean my_idle_callback() > { > gint n; > for (n = 0; n < 100; ++n) { > ... > } > return FALSE; > } > > should become: > > gboolean my_unrolled_idle_callback() > { > static gint n = 0; > ... > ++n; > return n < 100; > } > > Depending on your use case, the above could or could not be > possible. > Ah yes, that is an interesting idea. > > > > So I have to go back to my initial idea -- create a thread which > > gets a > > message for each "changed" signal, and then calls an idle function > > only > > for the last message in the queue each. I have to use > > gdk_threads_add_idle() then. > > This is probably the cleanest solution, although I don't > understand why you would have to use gdk_threads_add_idle(). I think gdk_threads_add_idle() is the recommended way to update the GTK GUI from inside a second thread. I am doing it in the current version of the editor already for querying and displaying extended symbol information, see https://github.com/ngtk3/NEd Here is where gdk_threads_add_idle() was suggested: https://developer.gnome.org/gdk3/stable/gdk3-Threads.html "You can schedule work in the main thread safely from other threads by using gdk_threads_add_idle() and gdk_threads_add_timeout()" > > > > > The task of that idle function in my current use case would be to > > get > > highlight syntax information from the IDE process called nimsuggest > > and > > then to apply the corresponding tags to gtksource textbuffer. > > IMO it is essential to split your code in two parts: (1) gathering > the highlight information and (2) applying it to the textbuffer. Yes, that was my thoughts too. It would imply some additional code, but may be the best solution. > > (1) can be run entirely in the working thread (hence non-blocking) > while (2) must be implemented as a callback to be run in the GTK+ > thread. I cannot believe (2) takes tenths of second. > > When you are ready from (1) you can spawn the idle callback with > g_source_attach()... no needs for gdk_threads_add_idle(). In the > following StackOverflow answer I provided an example in C: > > http://stackoverflow.com/questions/27950493/safety-of-using-pthreads- > in-gtk2-0-application#27990662 > Thanks for that suggestion, I will look at the stackoverflow example. And indeed, applying the text tags to the gtksource buffer is finally the only critical part. I dont know how fast that really is, I would assume that it takes less than 50 ms, what would be fine. If it really is slow, I may split it in multiple parts/calls. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
On 30 March 2017 at 10:10, Nicola Fontanawrote: > When you are ready from (1) you can spawn the idle callback with > g_source_attach()... no needs for gdk_threads_add_idle(). In the > following StackOverflow answer I provided an example in C: A small correction: use g_main_context_invoke() instead, as it will always do the right thing. The only reason to prefer gdk_threads_add_idle() to g_idle_add() (or g_main_context_invoke()) is that your own code may depend on additional libraries that still attempt at acquiring the GDK thread lock — i.e. they use gdk_threads_enter()/gdk_threads_leave() inside a separate thread to mark a critical section. No newly written, maintained, or portable code should do that, so you can safely use g_idle_add() or, better yet, g_main_context_invoke(). Ciao, Emmanuele. -- https://www.bassi.io [@] ebassi [@gmail.com] ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
Il Thu, 30 Mar 2017 09:38:41 +0200 Stefan Salewskiscrisse: > On Wed, 2017-03-29 at 23:26 +0200, Nicola Fontana wrote: > > > > > > idle functions do *not* run in the background so if you don't > > release the CPU you will experience what you described. > > > > AFAIK all the GMainLoop code is single-threaded hence, as a > > consequence, you will block the UI whenever the CPU is busy > > running your code, being it inside a signal handler, a timeout > > function or (as in your case) an idle function. > > > > Just avoid loops when you know they are expensive. Instead > > leverage the cyclic nature of GMainLoop for iterating over your > > code, i.e. by respawning your idle function as much as needed. > > > > In that case it is really a bad idea to have a outer loop in that idle > function :-( As said you can leverage the main loop and unroll yours, e.g.: gboolean my_idle_callback() { gint n; for (n = 0; n < 100; ++n) { ... } return FALSE; } should become: gboolean my_unrolled_idle_callback() { static gint n = 0; ... ++n; return n < 100; } Depending on your use case, the above could or could not be possible. > So I have to go back to my initial idea -- create a thread which gets a > message for each "changed" signal, and then calls an idle function only > for the last message in the queue each. I have to use > gdk_threads_add_idle() then. This is probably the cleanest solution, although I don't understand why you would have to use gdk_threads_add_idle(). > The task of that idle function in my current use case would be to get > highlight syntax information from the IDE process called nimsuggest and > then to apply the corresponding tags to gtksource textbuffer. IMO it is essential to split your code in two parts: (1) gathering the highlight information and (2) applying it to the textbuffer. (1) can be run entirely in the working thread (hence non-blocking) while (2) must be implemented as a callback to be run in the GTK+ thread. I cannot believe (2) takes tenths of second. When you are ready from (1) you can spawn the idle callback with g_source_attach()... no needs for gdk_threads_add_idle(). In the following StackOverflow answer I provided an example in C: http://stackoverflow.com/questions/27950493/safety-of-using-pthreads-in-gtk2-0-application#27990662 Ciao. -- Nicola ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
On Thu, 2017-03-30 at 09:38 +0200, Stefan Salewski wrote: > Currently I wonder if the call of gtk3.mainIteration() inside the > idle > function is possible and if it would help updating the display. In my > first draft of the Nim toy chess I used something like this > > while gtk3.eventsPending(): discard gtk3.mainIteration() Yes, that has an effect, it seems to allow GUI redraw, but keyboard input remains sluggish. If I add additional a sleep() function call keyboard seems to react better. But of course that is no real solution, so I have to test the thread idea next. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
On Wed, 2017-03-29 at 23:26 +0200, Nicola Fontana wrote: > > > idle functions do *not* run in the background so if you don't > release the CPU you will experience what you described. > > AFAIK all the GMainLoop code is single-threaded hence, as a > consequence, you will block the UI whenever the CPU is busy > running your code, being it inside a signal handler, a timeout > function or (as in your case) an idle function. > > Just avoid loops when you know they are expensive. Instead > leverage the cyclic nature of GMainLoop for iterating over your > code, i.e. by respawning your idle function as much as needed. > In that case it is really a bad idea to have a outer loop in that idle function :-( So I have to go back to my initial idea -- create a thread which gets a message for each "changed" signal, and then calls an idle function only for the last message in the queue each. I have to use gdk_threads_add_idle() then. The task of that idle function in my current use case would be to get highlight syntax information from the IDE process called nimsuggest and then to apply the corresponding tags to gtksource textbuffer. Unfortunately that may take a few hundred milliseconds for each full update. Currently I wonder if the call of gtk3.mainIteration() inside the idle function is possible and if it would help updating the display. In my first draft of the Nim toy chess I used something like this while gtk3.eventsPending(): discard gtk3.mainIteration() to avoid display freeze. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
Il Wed, 29 Mar 2017 21:27:48 +0200 Stefan Salewskiscrisse: > ... > > Problem is the idle function added with > > https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-idle-add > > I have the strong feeling, that the provided function is not running > silently in the background, ... Hi Stefan, idle functions do *not* run in the background so if you don't release the CPU you will experience what you described. AFAIK all the GMainLoop code is single-threaded hence, as a consequence, you will block the UI whenever the CPU is busy running your code, being it inside a signal handler, a timeout function or (as in your case) an idle function. Just avoid loops when you know they are expensive. Instead leverage the cyclic nature of GMainLoop for iterating over your code, i.e. by respawning your idle function as much as needed. Ciao. -- Nicola ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
On Wed, 2017-03-29 at 16:47 +0200, Stefan Salewski wrote: > On Wed, 2017-03-29 at 09:42 +0200, Stefan Salewski wrote: > > > > It is still the old problem: > > Well, after some thinking I have the feeling that it may work with > only > an idle function, so no separate thread and message passing is > necessary: The callback set a flag indicating that there is work to > do, > and calls the idle function unless the idle function is still > working. > That idle functions has an outer loop, which tests the flag and > returns > if unset. Otherwise it clears the flag and does the work. Will test > soon... > Yes, basically that works fine. Problem is the idle function added with https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-idle-add I have the strong feeling, that the provided function is not running silently in the background, but it is just called at some point and then blocks user input until the function terminates. At least, when that function is added with g-idle-add on GtkTextBuffer changed signal and that functions does only a delay of 2000 ms, then for that time user input into text buffer is blocked. That was not what I expected. And it is bad, user input becomes a bit sluggish. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Input event reduction
On Wed, 2017-03-29 at 09:42 +0200, Stefan Salewski wrote: > It is still the old problem: Well, after some thinking I have the feeling that it may work with only an idle function, so no separate thread and message passing is necessary: The callback set a flag indicating that there is work to do, and calls the idle function unless the idle function is still working. That idle functions has an outer loop, which tests the flag and returns if unset. Otherwise it clears the flag and does the work. Will test soon... ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list