Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gtkmm scroll_event do not work when a button is pressed

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;
}
like image 776
Pioz Avatar asked Jan 25 '26 20:01

Pioz


2 Answers

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.

like image 69
pdw Avatar answered Jan 27 '26 08:01

pdw


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.
like image 28
Random Citizen Avatar answered Jan 27 '26 10:01

Random Citizen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!