Emmanuele Bassi twisted the bytes to say: Hi Emmanuele,
Emmanuele> On 30 March 2015 at 18:56, dmg <d...@uvic.ca> wrote: >> On Mon, Mar 30, 2015 at 5:22 AM, Emmanuele Bassi <eba...@gmail.com> wrote: >>> Motion events are compressed in GTK+; they get collected and pushed to >>> the application code once per frame, because you cannot obviously >>> paint any faster than what your display can show, and because the vast >>> majority of applications do not draw content in response to fine event >>> delivery. >> >> Please see this: https://github.com/xournalpp/xournalpp/issues/109 >> it exemplifies the problem we have from gtk2 to gtk3. >> >> I did a small test. I tried to draw a curve during 1 second. And the >> results seem to support this as the reason. >> >> in the motion notify event our logic is the following: >> >> 1- We gather the coordinates of the new point >> 2- Using cairo we draw the new line segment directly onto the canvas Emmanuele> What does drawing "directly onto the canvas" mean, in this context? I have modified the example program to draw on the screen using cairo. It mimics what we do in Xournal regarding drawing (except that we don't use a callback). https://github.com/dmgerman/testDrawing/blob/master/drawing.c I have made it such that it uses both gtk_widget_queue_draw and it does not. Compile and run. If you press the middle button it will switch from not using gtk_widget_queue_draw to using gtk_widget_queue_draw. I use different colors for different segments. See http://turingmachine.org/~dmg/temp/test_Drawing.png I am using two methods to refresh the screen: 1. gtk_widget_queue_draw (see line 132) 2. a timer callback. See line 69. There are things i don't quite understand. 1. Why can the timer handler refresh the screen without a call to gtk_widget_queue_draw 2. How can I achieve the same result inside draw_line to avoid the timer callback without using gtk_widget_queue_draw? 3. What is the proper way to use gdk_window_set_event_compression: gdk_window_set_event_compression (gtk_widget_get_parent_window (window), FALSE); I get: (drawing:22296): Gdk-CRITICAL **: gdk_window_set_event_compression: assertion 'GDK_IS_WINDOW (window)' failed I have tried different widgets and I get the same error. Let me answer the rest of your questions: >> 3- We then compute the area that the new segment occupies >> 4- We call gtk_widget_queue_draw_area synchronously Emmanuele> What does "call gtk_widget_queue_draw_area" synchronously mean, in this context? We call it inside the even handler for motion notify. Every time we draw a line segment, we call it to refresh the screen (the person writing needs to have the screen refreshed every 50ms or so to not feel a lag). >> When 4 is removed, sampling increases significantly and we no longer >> have the problem but now the screen is not refreshed immediately. It >> is random when the refresh is. Emmanuele> That sounds… impressively wrong. :) See my test. Emmanuele> Are you getting a cairo_t* from the GdkWindow used by the widget and Emmanuele> just drawing on it? Yes. Emmanuele> Are you drawing on an image surface and then using the image surface Emmanuele> as the source for the cairo_t* in the GtkWidget::draw signal handler? No. This will sound like a hack, but this is what we need to do: 1. We keep a data structure for the polygons drawn by the user. In the draw callback we redraw the surface from the data structures. 2. When the user is drawing a line we directly draw in the surface as the user is adding segments, one segment at a time. These segments are then overwritten by the draw callback. When the user lifts the pen we invalidate the region of the polygon being drawn, and issue a gtk_widget_queue_draw_area. This is ok, because the user does not need as immediate feedback as when drawing from the line. The way I test this is by drawing the segments in grey. And then when responding to "draw" I draw them in black. This way I can see that the segments are drawn as expected, and then replaced with the proper polygon once the stroke finishes. Emmanuele> Are you using a thread to avoid blocking the UI from the event handler Emmanuele> while you draw on an offscreen surface? no. >> It seems to me that the problem is the that we call >> gtk_widget_queue_draw_area every time we have a segment. Emmanuele> No, that's definitely not the problem. Please run the test. I am very grateful you are helping us. -- Daniel M. German "If all mankind minus one, were of one opinion, and only one person were of the contrary opinion, mankind would be no more justified in silencing that one person, than he, if he had the power, John Stuart Mill -> would be justified in silencing mankind." http://turingmachine.org/ http://silvernegative.com/ dmg (at) uvic (dot) ca replace (at) with @ and (dot) with . _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list