After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 94535 - slow over remote connection
slow over remote connection
Status: RESOLVED WONTFIX
Product: gtk+
Classification: Platform
Component: Widget: Other
2.0.x
Other Linux
: Normal enhancement
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2002-09-30 17:05 UTC by Stephane Chauveau
Modified: 2004-12-22 21:47 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Stephane Chauveau 2002-09-30 17:05:23 UTC
At work, I am able to connect to my linux box at home
where I can start remote gtk/gnome applications. I noticed 
that gtk is clearly not optimized for slow connections.

For example, if I open a menu and move the mouse to the
last item then the menu items will be slowly enabled and
disabled ones by ones potentially showing each submenu. 
If each item takes 2 to 3 seconds to be processed then 
I may have to wait 30 seconds or more before the final 
item is finally selected. 

I suspect that events are processed by sequentially. 
A more optimal way would be to queue events and to 
group them to reduce the number of actions effectively  
processed. For example, a 'leave widget' event would 
cancel a previous 'enter widget' event. 

PS: does anyone know a way to simulate a slow connection
on a local system (maybe with Xnest)?
Comment 1 Soren Sandmann Pedersen 2002-09-30 18:11:54 UTC
I have been meaning to file this for a long time. Can I commit?

--- gtkmenuitem.c	23 Sep 2002 22:46:28 -0000	1.85
+++ gtkmenuitem.c	30 Sep 2002 18:09:32 -0000
@@ -724,7 +724,7 @@ gtk_real_menu_item_select (GtkItem *item
     }
   
   gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_PRELIGHT);
-  gtk_widget_draw (GTK_WIDGET (menu_item), NULL);
+  gtk_widget_queue_draw (GTK_WIDGET (menu_item));
 }
 
 static void
@@ -757,7 +757,7 @@ gtk_real_menu_item_deselect (GtkItem *it
     }
 
   gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_NORMAL);
-  gtk_widget_draw (GTK_WIDGET (menu_item), NULL);
+  gtk_widget_queue_draw (GTK_WIDGET (menu_item));
 }
 
 static gboolean
Comment 2 Owen Taylor 2002-09-30 18:43:26 UTC
Sure, but:

 - Are you sure this will help that much? I don't see any
   round  trips, so it won't have an effect on high latency
   circumstances and it reduces the total amount drawn by only 50%.

   Fixing latency problems is almost totally a question of looking
   for the round trips.

 - Maybe you want to clean up the other couple of gtk_widget_draw()
   calls in gtk+ while you are at it?
Comment 3 Stephane Chauveau 2002-09-30 18:49:22 UTC
That was a fast reply.

If I understand the patch then 2 consecutive draws are 
replaced by a single draw. This is clearly more efficient 
than the current behavior but the remaining draw should
also be cancelled. 

Also, I do not think that this patch can prevent submenus
to be displayed. Submenus are the killer cases.


 
Comment 4 Havoc Pennington 2002-09-30 19:04:44 UTC
Aren't there round trips if the menu has alpha-blended icons next to
the items?
Comment 5 Soren Sandmann Pedersen 2002-09-30 19:25:57 UTC
I thought gtk_widget_draw() called gdk_flush(), but I see it doesn't.

I'll look at the other few calls to gtk_widget_draw().


An idea I just got (it's probably bad, but I'll post it anyway):

Maintain a new region in GdkWindow with these properties:

      - Disjoint with the invalid region
      - The pixels it covers are valid (ie, they are the same
        as was previously drawn)

It would be used like this:

       - When idle-exposing, use the union of the invalid 
         region and this new region.
        
       - widgets should be able to add and remove stuff from it.
         Gdk would preserve the invariants.

       - Expose events would remove the area from this region and
         add to the invalid region

This would allow a widget to "cancel" a draw.
Comment 6 Owen Taylor 2002-10-02 14:21:09 UTC
Yeah, that's a bad idea :-). It adds a whole lot of complexity
and it would be really hard for a widget to know when it
could safely cancel a draw; what if there intervening
changes to the font or something?

The nice thing about the draw logic in GTK+-2 is it is 
really simple and straightforward. 

(Note that gtkmain.c compresses adjacent enter/leave events. 
But it doesn't actually do any good for menu items 
since we get motion events betweeenthe enter and the 
leave.)

Comment 7 Soren Sandmann Pedersen 2002-10-06 08:42:37 UTC
The gtk_widget_draw() fixes are in cvs now. 

Wrt. the submenus, note that current behavior is to pop out if there
has been at least 75 ms since last pop-out. This means the first
submenu is _always_ popped out immediately (since for the first
submenu, there will always have been 75 ms since last submenu pop-out.)

The patch in bug 74950 removes this behavior and makes pop-outs much
less frequent.
Comment 8 Owen Taylor 2002-10-16 19:17:24 UTC
I don't think there is really anything concrete here to work
on, so I'm going to close the bug. It will probably help
a lot to have the RENDER extension on the target X server
if you don't.
Comment 9 Stephane Chauveau 2002-10-16 20:02:53 UTC
The problem is not caused by the performance of the X server
but by the latency between the server and the client.

Basically, gtk is processing obsolete old X11 events while 
newer X11 events are already received but are waiting in the
queue. 

I can use an example: You come back from a long trip abroad 
and you notice that during this period, a friend or yours 
send you 20 emails asking you to send him a document using 
the email of different hotels (he is also traveling a lot).
So what you do is to read the OLDEST email and send the 
document to the specified address. A few hours latter, you
receive a reply from this hotel telling you that your friend
is not anymore in this hotel. So you try the 2nd OLDEST email
address and so on. 

Of course, acting like that is plain stupid. You should have 
used immediately the email address in the LATEST email. 

Now if you replace "hotel" by "menu entry", "friend" by "mouse
pointer", and "friend email" by "motion event"  then you are 
back to my initial problem. GTK is process obsolete motion 
events while newer ones are already received (in the event 
stack).












Comment 10 Owen Taylor 2002-10-16 20:21:54 UTC
The reason I recommend RENDER is that if the extension is
present, the number of round-trips GTK+ does for particular
drawing is much reduced. And round-trips are what kills
performance on slow connections.

It's very hard for GTK+ to (in general) say that events it
receives should be ignored because there is something newer
in the queue ... there are all sorts of tricky bugs you
can trigger if you start saying that some events don't
matter.

In some cases, a protocol like VNC can work better than X
for remote display because VNC knows that some change had
no effect because the bits didn't change in in the end. 
From GTK+'s point of view, the bits just coincidentally
ended up the same.

Soeren's fix will probably improve things a bit because
it will be doing less drawing, so you won't _see_ the
intermediate menu items being drawn, then undrawn. The
the draw/undraw will be compressed into a single draw
in the unselected state. 

Getting rid of this single draw is really hard within 
the GTK+/X model.

(On the other hand, performance may appear worse GTK+
will just sit their churning but apparently doing nothing.)