Very simple interpolated drawing code

Pray tell what harm does disabling event compression do ? If it is benign why disable it ? Too late to ask that question, I guess.

If one wants a simple disk drawn one has to use the Cairo primitive cairo_arc. Including starting and ending angles and then has to fill the dot as a separate call. There has to be a lot of stuff going on in cairo_arc to do that. This is what I mean by fancy – I’m used to whamo, blamo pixel pushing.

The “tl;dr” answer is: the more events GTK needs to dispatch to client code, the less time is available in the frame budget.

Dispatching signals can be slow, and since everything in GTK happens inside the same thread and main loop, it means that too many signals being dispatched will reduce the amount of time available for client code—i.e. your application’s code—to perform its own operations. Since the average display runs at 60 Hz, this means that each frame has 16.67 milliseconds at its disposal to do:

  • event dispatching
  • layout
  • drawing

If any of these operations take too long, frames will be skipped, and that may be displeasing. Additionally, input will be skipped as well, since the toolkit’s main loop won’t be able to “catch up” to the windowing system.

This is why compression on motion events is typically paired with storing the history of the coordinates of each motion event that happens in sequence during the same frame.

That’s not how GTK works, sorry.

You may want to use something simpler, for instance an immediate mode toolkit like imgui if you want to merely draw pixels and some UI controls around them. SDL2 is another option, though it’ll require you write your own UI elements.

GTK lets you draw things that UI elements require: boxes, shadows, gradients, text, texture data. For primitive drawing we have vector-based API in the form of Cairo. That means you’ll have to keep some form of state in your own widget, that you can then draw.

I have a quick reply here to show that event compression does do something.

Well, I can remember a discussion maybe 8 years ago, in early GTK3 days, when disabling compression made no difference for some people, including me. If you should depend on disabling compression, you may ensure that it works really reliable for all of your users, including Mac and Windows. I will do a test myself later. But I think for new software we should use GTK4 instead of GTK3 now.

And I actually wonder how the event rate is on 144 or 200 Hz displays, I really hope it is not hard coded to 60 Hz max?

4 posts were split to a new topic: Rendering backend for GTK

Users ? I write for myself ! :wink: What I’m currently writing has one user and is on one platform.

I started using GTK a while back when I wanted to make it possible for an artist collaborator to be able to use some software I had written that had NO user interface – not even a command line. To change the operation of the code I would change the source, recompile and run ! The source code was the UI – it’s the best UI there is :wink:

Most of my work is with OpenGL and GLSL. Vulkan isn’t for me. I’ve written just a very few GTK applications.

My original question was to find a small GTK application example that uses: gdk_event_get_history and integrates it, with interpolation, for freehand drawing.

It still seems odd that GTK would drop disabling compression when it is already off by default. Those that might find it useful can then choose to disable compression. My single case shows it is useful. My 4K 30Hz screen with a Wacom tablet draws much better without the event compression.

Still, gdk_event_get_history should do things in the best way and thus I have been looking for a demo example.

That’s the opposite of what is happening: GTK3 enables event compression by default, but allows you to disable it for legacy reasons. GTK4 always performs compression for motion and scroll events, and does not have any way of disabling it.

Yes, I understand that. It just doesn’t make sense to take a facility away that is off by default and isn’t getting in anyone’s way. Consequently weirdos, like me, that find it useful, now cannot choose to override it. More choices are usually better, if they don’t get in anybody’s way and don’t slow things down.

The event compression is obviously some piece of buried code that chooses what to throw away, meanwhile stashing all the events in a history table.

Oh, and when I go look for the history stuff I find:
https://gitlab.gnome.org/GNOME/gtk/-/issues/4809
not very encouraging.

1 Like

It makes sense to the people that maintain the toolkit to remove code that is legacy. That’s why it happened in GTK4.

I wouldn’t call people writing drawing applications “weirdos”: after all, that’s what GIMP does.

Event compression was introduced in GTK3 because every application that is not drawing directly from input events is not going to benefit from more events than necessary; since existing applications being ported from GTK2 to GTK3 did not want to refactor their code to the extent of making use of the event history, a toggle was introduced to ease their porting process. That toggle has now been removed in GTK4, as applications have had 9 years to port their internals to the new API.

If you expect GTK to not have bugs, you’ll be sorely disappointed. :wink:

That particular issue has been fixed 3 months ago.

6 posts were split to a new topic: Deprecations in GTK

A post was split to a new topic: Creating and destroying Cairo contexts

Now that I understand that Cairo is somewhat orphaned, what is to replace it ?

gtk_window_create_similar_surface() returns a Cairo surface is there some other kind of drawing surface available ?

I can only vaguely imagine that there might be a gtk_window_create_similar_OpenGL_window() but that seems close to impossible.

I’m guessing I need to use X11 via gdk_x11_window_foreign_new_for_diaplay() to get to more direct drawing ?

If you need high quality rendering, you are still going to use Cairo. If you want to render things like widgets—i.e. things that get styled with CSS—then you want the GtkSnapshot API.

No, if you want to draw with OpenGL, then you need GtkGLArea.

Nope, you never, ever draw on windowing system surfaces directly.

I’ll investigate GtkGLArea. If I can get to an OpenGL session then all kinds of things open up such as GLSL shaders . Is this true ?

Yes, you can also use GLSL shaders.

There are quite a few demos in gtk4-demo for GTK4.

For GTK3, there’s a demo in gtk3-demo, and an explanation in this glarea example.

I just found this:

thank you for writing it !

We can also try Blend2d. I think he is using plain C, so using the Blend2D C API should be easy. The only additional step is copying from a Blend2D surface to a GtkDrawingArea. For that step we had a forum discussion maybe one year ago, it is not that difficult. Unfortunately, when using other languages than C or C++, then we have to create the bindings to Blend2D first.

The GitHub - jpbruyere/vkvg: Vulkan 2D graphics library may be also an option, seems the author is still working on it.

@MCarthy: I hope you have answered your question at the cairo mailing list from some days ago now yourself? As you seems to have solved the issue. The reason that no one other answered is not only that cairo is orphaned as you said, but more that you gave not enough context – it was impossible to guess your real issue from your message. And I think you send your mail as HTML, which may be not really welcome. One remark to your tool: For me it is a bit strange that you draw single points with your scribble app. Cairo is a vector lib, so joining the points with lines would make more sense for me. Or, you may use just a raster/bitmap surface.

My code was missing a crucial gtk_widget_queue_draw() so the re-initialization and clearing of the drawing area didn’t happen. The drawing area was initialized correctly when things were first set up. However, my “clear” button simply didn’t work. All is now good. :smile:

I just want to draw a basic filled circle (dot), and Cairo seemed to be the simplest way forward despite it being a vector library. Now I can gain yet more facility using GtkGLArea though it’s a bit of overkill. It is possible that Cairo is fast enough but that the speed of the main Gtk event loop “misses” stylus moves. Consequently interpolating/joining sequential stylus positions is necessary. The results vary depending on the speed of the machine that I test things on. A cheap x86 tablet with a Celeron N4120 doesn’t work as well as an i7-1165G7 – no surprise there.

1 Like

My scribble_email code now uses cairo_draw_to() which works well enough by linearly interpolating between drawn points: https://github.com/CliveMcCarthy/scribble_email

Thank you guys for your help.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.