Question

I have an Gtk::EventBox with two events connected: button_press_event and scroll_event. All the two events work fine, but when I hold down a mouse button, the scroll event is not emitted.

I have implement in my class the two functions bool on_button_press_event (GdkEventButton *e) and bool on_scroll_event (GdkEventScroll *e). This two functions return false to propagate the event further.

Im using gtkmm3.

How can I solve this problem?

An example of code to reproduce the problem:

#include <gtkmm.h>
#include <iostream>

class MyWindow : public Gtk::Window
{
  Gtk::EventBox event_box;
  Gtk::ScrolledWindow scrolled;
public:
  bool on_button_press_event(GdkEventButton *b)
  {
    std::cout << "button press" << std::endl;
    return false;
  }

  bool on_scroll_event(GdkEventScroll *e)
  {
    std::cout << "scrollEvent" << std::endl;
    return false;
  }

  MyWindow ()
  {
    add(scrolled);
    scrolled.add(event_box);
    set_default_size(640, 480);
    show_all();
  }
};

int main(int argc, char** argv)
{
  Gtk::Main kit(argc, argv);
  MyWindow window;
  kit.run(window);
  return 0;
}
Was it helpful?

Solution

The example code you show has two problems.

  • First, you say "I have an Gtk::EventBox with two events connected." But in your example you connect to MyWindow's events, and leave the EventBox's events unconnected.

  • An EventBox allows you to receive events, but you still have to explicitly say which events you want to receive.

This is the corrected code:

#include <gtkmm.h>
#include <iostream>

class MyWindow : public Gtk::Window
{
  Gtk::EventBox event_box;

  bool event_box_button_press(GdkEventButton *b)
  {
    std::cout << "button press" << std::endl;
    return false;
  }

  bool event_box_scroll(GdkEventScroll *e)
  {
    std::cout << "scrollEvent" << std::endl;
    return false;
  }

public:
  MyWindow ()
  {
    event_box.add_events(Gdk::BUTTON_MOTION_MASK);
    event_box.add_events(Gdk::SCROLL_MASK);

    event_box.signal_button_press_event().connect(
        sigc::mem_fun(*this, &MyWindow::event_box_button_press));
    event_box.signal_scroll_event().connect(
        sigc::mem_fun(*this, &MyWindow::event_box_scroll));

    add(event_box);

    set_default_size(640, 480);
    show_all();
  }
};

int main(int argc, char** argv)
{
  Gtk::Main kit(argc, argv);
  MyWindow window;
  kit.run(window);
  return 0;
}

Some notes on this code:

  • I've omitted the ScrolledWindow, as that is irrelevant to the example. You don't need it to catch scroll events. You can add it back if you actually need a scrolled window for your application.

  • The code would probably be neater if you derive a custom EventBox with the behavior you need. I didn't do this to stay closer to your original code.

  • See this documentation for information on connecting signals and the sigc::mem_fun stuff.

OTHER TIPS

It looks like on windows, the scrolledWindow was the right place to watch for scroll events instead of the main window.

Using the following modification, I was able to handle scroll events on windows 7.

#include <gtkmm.h>
#include <iostream>

class MyScrolledWindow : public Gtk::ScrolledWindow
{
public:
  bool on_scroll_event(GdkEventScroll *e)
  {
    std::cout << "scrollEvent" << std::endl;
    return false;
  }

  MyScrolledWindow()
  {
  }
};

class MyWindow : public Gtk::Window
{
  Gtk::EventBox event_box;
  MyScrolledWindow scrolled;
public:
  bool on_button_press_event(GdkEventButton *b)
  {
    std::cout << "button press" << std::endl;
    return false;
  }

  MyWindow ()
  {
    add(scrolled);
    scrolled.add(event_box);
    set_default_size(640, 480);
    show_all();
  }
};

int main(int argc, char** argv)
{
  Gtk::Main kit(argc, argv);
  MyWindow window;
  kit.run(window);
  return 0;
}

====== Old Answer: ================

I am not able to reproduce your isse. This is the code I used to try to reproduce your issue:

#include <gtkmm.h>
#include <iostream>

class MyEventBox : public Gtk::EventBox
{
  bool on_button_press_event(GdkEventButton *b)
  {
    std::cout << "button press" << std::endl;

    return false;
  }

  bool on_scroll_event(GdkEventScroll *e)
  {
    std::cout << "scrollEvent" << std::endl;

    return false;
  }
};


int main(int argc, char** argv)
{
  Gtk::Main kit(argc, argv);
  Gtk::Window window;
  MyEventBox eventBox;

  eventBox.show();
  window.add(eventBox);

  kit.run(window);

  return 0;
}

For compiling, I used the folowing command line (using Linux):

g++ main.cpp $(pkg-config --cflags --libs gtkmm-3.0)

  • If you can reproduce your issue using this minimum example, the problem might be platform specific and a workaround using the window's/event box' Gdk::Window might be necessary.
  • If you can't reproduce your issue using this code, the issue is caused somewhere else in your code and you'll need to post more information.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top