Wait cursor animation does not work properly

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Wait cursor animation does not work properly

Stefan Salewski-2
Since a few months I have observed that for my chess game the mouse
pointer/cursor animation stopped working properly.

Yesterday I tried cleaning up the code for moving the game GUI to the
new high level Nim GTK GUI, but I was unable to get it working.

When I moved the busy-cursor out of the application window and back
again, animation stops. Same if I used g_idle_add() call -- animation
stops as long as idle function (computer chess engine) is active.

I was not able to find recent bug reports about this, so I am not sure
if I am doing something wrong (do not really think so.)

So I just grabbed a C demo application from the gnome side and added
set cursor stuff. There is no idle function currently, but the problem
occurs already when I move the animated cursor out of the window and
back again. Animation stops.

This is for gtk+-3.22.16:3::gentoo GDM display manager logged in under
WAYLAND.

// gcc t.c `pkg-config --libs --cflags gtk+-3.0`

#include <gtk/gtk.h>

static void
button_clicked (GtkButton *button,
                gpointer   user_data)
{
  const char *old_label;
  char *new_label;
  old_label = gtk_button_get_label (button);
  new_label = g_utf8_strreverse (old_label, -1);
  gtk_button_set_label (button, new_label);
  g_free (new_label);
}
static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget *window;
  GtkWidget *button;
  GdkDisplay *display;
  GdkCursor *cursor;
  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "GNOME Button");
  gtk_window_set_default_size (GTK_WINDOW (window), 250, 50);
  button = gtk_button_new_with_label ("Click Me");
  gtk_container_add (GTK_CONTAINER (window), button);
  g_signal_connect (GTK_BUTTON (button),
                    "clicked", 
                    G_CALLBACK (button_clicked), 
                    G_OBJECT (window));
  gtk_widget_show_all (window);
  display = gdk_display_get_default();
  cursor = gdk_cursor_new_from_name(display, "wait");
  gdk_window_set_cursor(gtk_widget_get_window(window), cursor);
}

int
main (int argc, char **argv)
{
  GtkApplication *app;
  int status;
  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);
  return status;
}
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Stefan Salewski-2
On Sun, 2017-09-03 at 16:43 +0200, Stefan Salewski wrote:
> Since a few months I have observed that for my chess game the mouse
> pointer/cursor animation stopped working properly.

Well, I have added the g_idle_add() problem also.

When I move the mouse pointer the first time into the button widget,
animation works fine. But when I click on the button, animation stops
while idle function is active, which is 5 seconds. After that period
animation works fine again.

But when I move the pointer out of the window and back again, animation
is stopped and will not start again.

May that be a Wayland problem? I do not really think so, but I am not
really sure.

// gcc t.c `pkg-config --libs --cflags gtk+-3.0`

#include <gtk/gtk.h>
//include <glib/glib.h>
#include <glib/gprintf.h>
static gboolean
idle_func(gpointer data)
{
  int i;
  i = 0;
  while (i < 9)
  {
    g_usleep(1000000);
    i++;
    g_printf("busy\n");
  }
  return G_SOURCE_REMOVE;
}

static void
button_clicked (GtkButton *button,
                gpointer   user_data)
{
  const char *old_label;
  char *new_label;
  old_label = gtk_button_get_label (button);
  new_label = g_utf8_strreverse (old_label, -1);
  gtk_button_set_label (button, new_label);
  g_free (new_label);
  g_idle_add(idle_func, NULL);
}
static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget *window;
  GtkWidget *button;
  GdkDisplay *display;
  GdkCursor *cursor;
  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "GNOME Button");
  gtk_window_set_default_size (GTK_WINDOW (window), 250, 50);
  button = gtk_button_new_with_label ("Click Me");
  gtk_container_add (GTK_CONTAINER (window), button);
  g_signal_connect (GTK_BUTTON (button),
                    "clicked", 
                    G_CALLBACK (button_clicked), 
                    G_OBJECT (window));
  gtk_widget_show_all (window);
  display = gdk_display_get_default();
  cursor = gdk_cursor_new_from_name(display, "wait");
  gdk_window_set_cursor(gtk_widget_get_window(window), cursor);

}

int
main (int argc, char **argv)
{
  GtkApplication *app;
  int status;
  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);
  return status;
}
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Emmanuele Bassi
On 3 September 2017 at 16:32, Stefan Salewski <[hidden email]> wrote:

> On Sun, 2017-09-03 at 16:43 +0200, Stefan Salewski wrote:
>> Since a few months I have observed that for my chess game the mouse
>> pointer/cursor animation stopped working properly.
>
> Well, I have added the g_idle_add() problem also.
>
> When I move the mouse pointer the first time into the button widget,
> animation works fine. But when I click on the button, animation stops
> while idle function is active, which is 5 seconds. After that period
> animation works fine again.
>
> But when I move the pointer out of the window and back again, animation
> is stopped and will not start again.
>
> May that be a Wayland problem? I do not really think so, but I am not
> really sure.
>
> // gcc t.c `pkg-config --libs --cflags gtk+-3.0`
>
> #include <gtk/gtk.h>
> //include <glib/glib.h>
> #include <glib/gprintf.h>
> static gboolean
> idle_func(gpointer data)
> {
>   int i;
>   i = 0;
>   while (i < 9)
>   {
>     g_usleep(1000000);
>     i++;
>     g_printf("busy\n");
>   }
>   return G_SOURCE_REMOVE;
> }

I don't understand what you're trying to achieve.

You're blocking the toolkit's main loop, here. If your application
does this, it's broken and needs to be fixed - regardless of what the
cursor looks like.

The cursor is rendered by the Wayland compositor, but the animation is
performed by the toolkit, i.e. it's the toolkit that uploads the
cursor's data to the compositor.

Ciao,
 Emmanuele.

--
https://www.bassi.io
[@] ebassi [@gmail.com]
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Stefan Salewski-2
On Sun, 2017-09-03 at 16:54 +0100, Emmanuele Bassi wrote:
> You're blocking the toolkit's main loop,

When I add a background function with g_idle_add() I am blocking the
GTK main loop? Well I just wanted to avoid that.

But even without use of g_idle_add() the animation stops, when I move
the cursor out of the window and back, see my first example. So there
is a GTK bug.

My initial chess GUI was this:

https://github.com/StefanSalewski/nim-chess3/blob/master/board.nim

I know that it was really ugly, I was told that

while gtk3.eventsPending(): discard gtk3.mainIteration()

is really bad design. But that first draft was basically only a test of
the low level Nim GTK wrapper, and it was working six months ago. It is
still working, but mouse cursor is not animated any longer.

For user input, I was going to use a basic state maschiene -- state
advances by each user mouse click. Response of computer is more
difficult, I was going to use g_idle_add() to run computer chess engine
in the background. But maybe I should use a own task/process? (Which
may be a problem again, as GTK is single threaded?)

Unfortunately, for such use cases there are nearly no GTK example
available. Have done some Goggle search already...
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Gtk+ - General mailing list
In reply to this post by Stefan Salewski-2


Hi Stefan,

When I test your original post code, with GTK3.18 I get the animated "wait" cursor. With a jhbuild of GTK3.22 I get a wrist watch type clock cursor for "wait" that doesn't have any animation. The theme is broken there and I haven't got around to fixing it yet so that might be a factor. This is Ubuntu16.04 with x windows. Moving the cursor back and forth over the window works fine with the 3.18 cursor. It remains animated over the window. I don't see anything moving with the GTK3.22 cursor. It just stays the same. So... I don't know.

Eric



_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Stefan Salewski-2
On Sun, 2017-09-03 at 17:23 -0400, [hidden email] wrote:
> With a jhbuild of GTK3.22 I get a wrist watch type clock cursor for
> "wait" that doesn't have any animation.

Thanks for testing. So problem is not my local Gentoo box, but GTK
3.22.
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Stefan Salewski-2
In reply to this post by Emmanuele Bassi
On Sun, 2017-09-03 at 16:54 +0100, Emmanuele Bassi wrote:
> You're blocking the toolkit's main loop, here. If your application
> does this, it's broken and needs to be fixed - regardless of what the
> cursor looks like.
>
> The cursor is rendered by the Wayland compositor, but the animation
> is
> performed by the toolkit, i.e. it's the toolkit that uploads the
> cursor's data to the compositor.

Of course you are right that using g_idle_add() is still blocking the
GUI. But I think that having an animated Busy cursor makes only sense
at all when it is animated while a program is doing some heavy
calculation. So the animated cursor is indeed an indication for a short
blocked period. My chess engine takes only a few seconds to calculate
the next move, so creating an own thread is some overkill. What I need:
User has done his move, so update display, indicate that computer is
"thinking" for a few seconds, and then update display again. I think
that should be possible with g_idle_add(). Instead of the busy pointer
I may set a message to the window title.

Later I may consider indeed using a separate thread -- I did that
already one year ago for my Ned Nim editor for communicating with the
nimsuggest process, but I can not remember details currently. Doing it
really properly may be not easy for a chess engine, as the human player
should be able to interrupt the computer thinking at arbitrary times.
Unfortunately there exist very few examples, and some are more Python
related like

https://stackoverflow.com/questions/16934087/how-to-do-background-task-in-gtk3-python
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Chris Vine-3
On Mon, 04 Sep 2017 09:17:10 +0200
Stefan Salewski <[hidden email]> wrote:

> On Sun, 2017-09-03 at 16:54 +0100, Emmanuele Bassi wrote:
> > You're blocking the toolkit's main loop, here. If your application
> > does this, it's broken and needs to be fixed - regardless of what
> > the cursor looks like.
> >
> > The cursor is rendered by the Wayland compositor, but the animation
> > is
> > performed by the toolkit, i.e. it's the toolkit that uploads the
> > cursor's data to the compositor.  
>
> Of course you are right that using g_idle_add() is still blocking the
> GUI. But I think that having an animated Busy cursor makes only sense
> at all when it is animated while a program is doing some heavy
> calculation. So the animated cursor is indeed an indication for a
> short blocked period. My chess engine takes only a few seconds to
> calculate the next move, so creating an own thread is some overkill.
> What I need: User has done his move, so update display, indicate that
> computer is "thinking" for a few seconds, and then update display
> again. I think that should be possible with g_idle_add(). Instead of
> the busy pointer I may set a message to the window title.
>
> Later I may consider indeed using a separate thread -- I did that
> already one year ago for my Ned Nim editor for communicating with the
> nimsuggest process, but I can not remember details currently. Doing it
> really properly may be not easy for a chess engine, as the human
> player should be able to interrupt the computer thinking at arbitrary
> times. Unfortunately there exist very few examples, and some are more
> Python related like

I think you are partly thinking out loud, because you began with "of
course you are right that using g_idle_add() is still blocking the
GUI", but in so far as you were wanting an answer the point is that any
GTK+ program runs a glib event loop in its main (starting) thread.  That
event loop must not be blocked by your "some heavy calculation", whether
in an idle callback or in some GTK+ signal callback or in whatever
other way you may be thinking of doing it in that thread.

The conventional way of dealing with this is for the blocking "heavy
calculation" to be run in a separate worker thread or in a thread pool,
and for that worker thread to post its result back to GTK+ using
g_idle_add().  g_idle_add() is thread safe.  You might also want to look
at GTask (and g_task_run_in_thread()), which follows this approach but
with some additional syntactic sugar.

As to your test case, that works fine in GTK+-3.22 with the X11
backend and the Adwaita theme.  I do not have wayland installed.
Possibly you have found a bug in the wayland backend, depending on
whether anyone else can reproduce your issue.

Chris
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Paul Davis
In reply to this post by Stefan Salewski-2


On Mon, Sep 4, 2017 at 3:17 AM, Stefan Salewski <[hidden email]> wrote:
​My chess engine takes only a few seconds to calculate
the next move, so creating an own thread is some overkill.

​Incorrect thinking. ​
 
What I need:
User has done his move, so update display, indicate that computer is
"thinking" for a few seconds, and then update display again. I think
that should be possible with g_idle_add(). Instead of the busy pointer
I may set a message to the window title.

Later I may consider indeed using a separate thread

​Do it now.

Chris explained the rest.


_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Emmanuele Bassi
In reply to this post by Chris Vine-3
On 4 September 2017 at 11:58, Chris Vine <[hidden email]> wrote:

> As to your test case, that works fine in GTK+-3.22 with the X11
> backend and the Adwaita theme.  I do not have wayland installed.
> Possibly you have found a bug in the wayland backend, depending on
> whether anyone else can reproduce your issue.

It's not a bug of the Wayland backend, per se; it's a different
behaviour inherent as to how cursors work in Wayland and in X11.

Cursor themes in X11 are loaded by the X server, and the toolkit just
tells the server to load the named cursor from the theme. Under
Wayland, the toolkit is responsible for presenting the cursor frame to
the display server, and updating the buffer for every frame. The
display server is a privileged component, and it should only deal with
buffers coming from clients, not with loading image data from random
places. If you block the toolkit's main loop, the toolkit cannot
update the animation, and thus you get a stuck cursor animation — just
like you get a stuck UI.

Ciao,
 Emmanuele.

--
https://www.bassi.io
[@] ebassi [@gmail.com]
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Chris Vine-3
On Mon, 4 Sep 2017 14:05:08 +0100
Emmanuele Bassi <[hidden email]> wrote:

> On 4 September 2017 at 11:58, Chris Vine <[hidden email]>
> wrote:
>
> > As to your test case, that works fine in GTK+-3.22 with the X11
> > backend and the Adwaita theme.  I do not have wayland installed.
> > Possibly you have found a bug in the wayland backend, depending on
> > whether anyone else can reproduce your issue.  
>
> It's not a bug of the Wayland backend, per se; it's a different
> behaviour inherent as to how cursors work in Wayland and in X11.
>
> Cursor themes in X11 are loaded by the X server, and the toolkit just
> tells the server to load the named cursor from the theme. Under
> Wayland, the toolkit is responsible for presenting the cursor frame to
> the display server, and updating the buffer for every frame. The
> display server is a privileged component, and it should only deal with
> buffers coming from clients, not with loading image data from random
> places. If you block the toolkit's main loop, the toolkit cannot
> update the animation, and thus you get a stuck cursor animation — just
> like you get a stuck UI.

Rereading Stefan's successive postings I am now quite confused about
what bug he thinks he has found.  The code I tested was the code he
first posted, without the idle callback, which he said exhibited a
problem with cursor animation which I have been unable to reproduce.  I
didn't bother testing his second posting with a blocking idle callback
because it was obviously wrong, as I thought he now recognises.

If Stefan needs any further assistance I think he needs to explain what
his issue actually is.

Chris
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Stefan Salewski-2
On Mon, 2017-09-04 at 22:39 +0100, Chris Vine wrote:
> If Stefan needs any further assistance I think he needs to explain
> what
> his issue actually is.

Well, my first posting in this thread seems to indicate a real issue,
as Mr [hidden email] confirmed. Animation does not continue when
mouse pointer is moved out of the widget and back again. Maybe that is
a Wayland problem -- when it is I assume that it will be fixed some
day. Maybe it is restricted to my dev-libs/wayland-1.13.0::gentoo

For the g_idle_add(): As Mr E. Bassi explained, there is a different
behaviour in Wayland, cursor animation does only work when main thread
is idle.

I will follow all your advice and start a new thread for the chess
engine to return the reply move.
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Gtk+ - General mailing list
In reply to this post by Stefan Salewski-2

Hi Stephan,

I don't have wayland to test with so I can't confirm what you are seeing. My jhbuild of GTK3.22 also has a broken theme so I can't test cursors properly with 3.22 and x windows right now. If I had a setup I could test wayland on gentoo I might suspect the theme at first and check there since there was some changes to themes not long ago. This is guessing on my part though.

Eric



_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Wait cursor animation does not work properly

Stefan Salewski-2
In reply to this post by Stefan Salewski-2
On Tue, 2017-09-05 at 08:50 +0200, Stefan Salewski wrote:
> I will follow all your advice and start a new thread for the chess
> engine to return the reply move.

Well yes, but not now...

For now I have pushed a still blocking release to github:

https://github.com/StefanSalewski/nim-chess4

I think the GTK code looks not too bad now:

https://github.com/StefanSalewski/nim-chess4/blob/master/board.nim

Creating a thread for the chess engine would be some work, and
currently I am more interesting in testing the high level Nim bindings
and providing some example code.

I have also added a cairo animated drawing example to the tutorial, see
bottom of

https://github.com/StefanSalewski/gintro

It is based of a C example someone recently posted at cairo mailing
list.
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list