Freehand drawing Gtk / set_event_compression(false) does not work

1

I'm developing a graphic software with GTK+ (gtkmm) and want to build a free hand drawing feature.

I connect to the signal_motion_notify_event on a Gtk::EventBox and set set_event_compression to false on the event box. I also set set_event_compression(false) on the window containing the event box, but nothing seems to work. The program is not running so fluently that it would allow drawn trough lines, instead I get multiple single dots or short dashes.

I also tried using Gdk::Window::get_pointer(int,int,Gdk::ModifierType) in an extra thread, but this doesn't work either (no drawn through lines also).

Here is some example code to illustrate (I use Gtk::Image-class to draw the a pixbuf):

Toolbox.cc

// eb means EventBox
Gtk::EventBox& eb = drawingWin->getEventBox();
eb.signal_motion_notify_event().connect(sigc::mem_fun(image, &Image::motionEvent));

DrawingWindow.cc

DrawingWindow::DrawingWindow(int x, int y) : area(x, y), background("/home/tux/Pictures/Arch_Linux_Wallpaper_by_james66.jpg")
{
    // eb means EventBox
    eb.get_window()->set_event_compression(false);
}

Image.cc

bool Image::motionEvent(_GdkEventMotion* event)
{
    if(event)
    {
        mutex.lock();
        //custom set_pixel function on Gdk::Pixbuf using guint8* Gdk::Pixbuf::get_pixels() const
        this->set_pixel(event->x, event->y, 0x000000ff);
        //updates the Gtk::Image by calling Gtk::Image::set(Glib::RefPtr<Gdk::Pixbuf>)
        this->_udpate();
        mutex.unlock();
    }
}
events
gtk
drawing
gtk3
gtkmm
asked on Stack Overflow Feb 1, 2018 by Arch Linux Tux • edited Feb 5, 2018 by Arch Linux Tux

1 Answer

0

In GIMP (the program GTK+ was originally written for) there are gaps between single points too, if the mouse is moved too quickly, which are filled with straight lines between the points.

In GTK+ and gtkmm there are Gdk::EventMasks. These can be set with Gtk::Widget::set_events(Gdk::EventMask). One needs to make sure that POINTER_MOTION_MASK is set (not POINTER_MOTION_HINT_MASK).

One also needs to make sure, that event-compression is disabled. Until including GTK3 this could be done using Gdk::Window::set_event_compression(false)

In GTK4 event-compression is always turned on:

With GTK4 one needs to look at the event history between motion events to reconstruct the ones that where coalesced. In gtk4 event delivery rate is fixed to run by the frame clock (that is, 60hz). get_motion_history() (function name may have changed) will only return the motion coordinates that were accumulated during the handling of that frame.

Here are two examples:

  1. gtk3-demo
  2. PyGtk2 (one needs to have python2, pygtk2 and gtk2 installed to test this.

All of these examples lack coherence (there are gaps between the lines).

It's not possible building choerent free hand drawing using GTK+ without interpolation!

There is also an example using Qt5, which is coherent: Qt5 Scribble

answered on Stack Overflow Feb 6, 2018 by Arch Linux Tux

User contributions licensed under CC BY-SA 3.0