Custom Cursor in gtkmm

I have to build a functionality very much similar to erase or pencil using (Square or Circle Tool) where the size of the Square(SIDES) and Circle(RADIUS) can be changed by the user so sides of square and the radius of the circle need to be changed. As the cursor moves around in the Drawing area.

Here is the image for your reference and better understanding

  1. I would like to draw a square or circle with the size selected by the user using dotted lines keeping cursor x,y as their(square) center points.
  2. I would like to add a small Icon similar to eraser in the image

PS: I have used GIMP erase tool to demonstrate the requirement. If I am not wrong even GIMP has been written using GTK


Have a look at gtk4-demo (or gtk3-demo, depending on the version you use).

There is a “Cursors” demo showing how to use custom pointers, and a “Paint” demo showing how to draw a square at cursor position.

Since it is for Gimp: can’t you use a regular brush, that can be circle or square (or any other shape) and can already be changed on-the-fly (pressure if using a stylus, keyboard shortcuts, or secondary mouse buttons or mouse wheel)?.

Hey @gwillems I am using gtkmm-3,24, on some search I found this but unable to find the cursor and the paint demo that you mentioned. Can you guide me where exactly I can find those examples?

I came across this Programming with gtkmm 3 can’t seem to find the examples you mentioned

I want to build a functionality similar to what GIMP has like erase and pencil into a custom application I am building. I am not actually using gimp anywhere in the custom application.

The source code of the demos is here:

It’s not gtkmm/C++ but gtk/C, but I hope you’ll get the idea.

If you use Linux, the gtk3-demo tool should be installable (on Ubuntu it’s provided by the package “gtk-3-examples”), so you can play with it to see the actual result.

Found this seems code looks much easy
Cairo-Tutorial: 6-mouse-position


#include "canvas.h"
#include <gtkmm/application.h>
#include <gtkmm/window.h>

int main(int argc, char** argv)
    auto app = Gtk::Application::create(argc, argv, "org.gtkmm.cairo.tut");

    Gtk::Window window;
    window.set_title("Cairo tutorial C++");

    CCanvas area;

    return app->run(window);


#include "canvas.h"

bool CCanvas::on_motion_notify_event(GdkEventMotion *event)
    m_tMousePos = SPoint{*event};
    return true;

bool CCanvas::on_draw(Cairo::RefPtr<Cairo::Context> const & cr)
    Gtk::Allocation allocation{ get_allocation() };
    auto const width { (double)allocation.get_width() };
    auto const height{ (double)allocation.get_height() };


    // line crossing the whole window
    cr->move_to(    0,      0);
    cr->line_to(width, height);

    // circle gray
    cr->arc(width/2, height/2, 100, 0, 2*M_PI);

    // picture png quadratic
    // - load picture
    static Glib::RefPtr<Gdk::Pixbuf> const image  = Gdk::Pixbuf::create_from_file("../CairoTut.svg");
    // - scale picture to destination size
    static Glib::RefPtr<Gdk::Pixbuf>       imageS = image->scale_simple( 180, 180, Gdk::INTERP_BILINEAR);
    // - place scaled pictures to specified position in render context
    Gdk::Cairo::set_source_pixbuf(cr, imageS, width/2-90, height/2-90 );
    // - open a hole for the pixels
    cr->rectangle( width/2-90, height/2-90, 180, 180 );
    // - show the hole

    // draw a blue circle at last mouse position
    cr->arc(m_tMousePos.x, m_tMousePos.y, 3, 0, 2*M_PI);

    return true;


#include <gtkmm.h>
#include <gtkmm/drawingarea.h>

struct SPoint
    SPoint() = default;
    SPoint(double const & x, double const & y) : x(x), y(y) {}
    template<typename T>
        SPoint(T const & t) : x(t.x), y(t.y) {}
    double x{0}, y{0};

class CCanvas : public Gtk::DrawingArea

        virtual ~CCanvas() { };

        // Override default signal handler:
        bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr) override;
        bool on_motion_notify_event(GdkEventMotion *event) override;
        SPoint   m_tMousePos;

    }; // CCanvas

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