0

I'm trying to modify the popular waybar program (which can be found here). Waybar is a highly customizable status bar that organizes various visual elements into "modules", which can respond to certain form of interaction like mouseover events and clicks (or button presses, as gtk apparently refers to them). I want to extend functionality to allow modules to react to key presses as well.

My intended use case for this functionality is having another way to trigger drawers. Waybar allows for groups of modules called "drawers", which only displays the first module in the drawer on the bar until moused over. This allows you to hide modules that you don't need / want constantly displayed to the bar. I'd like it if I could expand drawers on a keypress instead of having to mouseover them to see their contents. This isn't particular vital to my question, but I add it here anyways for additional context.

Perusing the codebase lead me to AModule.cpp, which is where the logic for letting modules react to mouse over events is implemented. In particular, I believe it is these two lines in specific.

event_box_.signal_enter_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseEnter));

event_box_.signal_leave_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseLeave));

From the naming scheme of these signal methods, I found signal_key_press_event() and signal_key_release_event() which seemed to do exactly what I wanted, so I wrote my own rudimentary key press handlers (that just print to the console upon being triggered) and tried adding these lines

event_box_.signal_key_press_event().connect(sigc::mem_fun(*this, &AModule::handleKeyPress),false);

event_box_.signal_key_release_event().connect(sigc::mem_fun(*this, &AModule::handleKeyRelease),false);

And nothing happens. My language sever claims that the Gdk::Window associated with the widget needs to enable Gdk::KEY_PRESS_MASK to receive the event, and in some other places in the file I see event_box_.add_events(Gdk::SOME_MASK_HERE) so I try adding event_box_.add_events(Gdk::KEY_PRESS_MASK)before my two lines, and I still get nothing.

I do some more googling and I come across this forum thread, which implies that widgets need to be "focused" to receive key press events, but making the box focusable and then calling grab_focus() still does nothing. Then I see that apparently focused widgets need to be mapped (which I don't really understand what that is), and when I try to map the event_box it just spits out a lot of errors upon running the executable.

This was when I concluded that I don't know enough about gtk programming to implement this myself. I've read a little bit about the event interception model of gtk 4 and seen some recommendations to use an "EventController", but I still don't quite understand enough to know what exactly needs to be done. I fear this is a very general question, but does anybody have any advice on how exactly an event_box can receive a key press event?

5
  • Only one window at a time sees each particular key event. If your window does, then other windows don't. Do you really want that? Commented Aug 21 at 4:17
  • @n.m.couldbeanAI I mean kind of? I wouldn't mind having key press events consumed by my status bar for the small time I want it to react to specific key presses. I'm envisioning essentially allowing various modules to be able to be configured to react to specific key presses (like my volume adjustment keys for example), not all keys on the keyboard all the time. Are you saying that this is not really possible though? Commented Aug 21 at 20:16
  • If you want your window to always react to specific keys, as opposed to all keys only when it has focus, you need to register those specific keys as global hotkeys. Not all windowing systems permit applications to do that. Normally global hotkeys are managed by a dedicated desktop component such as GNOME Shell, and not by the applications themselves. Commented Aug 22 at 5:41
  • 1
    If your GTK application needs to be controlled by a global hotkey, consider exposing its functionality through a D-Bus interface or a command-line interface. You can then configure a global hotkey in your desktop environment to execute a command that interacts with your application via D-Bus or its CLI. (This is what google AI says about the matter, I personally confirm that it's the right thing to do). Commented Aug 22 at 5:44
  • OTOH if you only want your app to react to key presses when it has focus, you need to make sure its window has focus in the first place. Normally the window manager gives windows focus. Look at window decorations: there should be at most active window and your desktop should somehow highlight its decorations. Specific windows like toolbars might be designed to never get focus from the window manager, which could be your case. Commented Aug 22 at 5:48

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.