[gnome-shell-ext] Bind Modifier+Mouse Button



Hi there!

I am totally new to this list - I hope that it's a good place to ask my question; if not feel free to point me to a better place!

Question: Is it somehow possible to globally bind a callback to mouse events? I am interested in mouse click events while other modifiers are pressed. Like key-bindings, but with mouse buttons instead.

Background: I am currently developing a successor to Gnome-Pie (https://github.com/Schneegans/Gnome-Pie) in form of a Gnome-Shell Extension. This allows me to do things which are normally not possible with standard Wayland clients (such as grabbing the complete input, listing running applications, ...). This works very well and I am quite happy with GJS and Clutter. However, one incredibly useful feature of Gnome-Pie was to bind pie menus to mouse buttons. You could either:

  1. Open pie menus when a specific modifier is hold down and you press a button or
  2. Open pie menus when pressing a mouse button only (this is useful if you have one of these mice featuring many buttons) or
  3. Open a pie menu when a mouse button was pressed for some time (e.g. 500 milliseconds). If you clicked faster, it would just act as a normal click event.
This was all implemented with X11 specific code, obviously. But from the things I tried, I still have the hope that at least 1. and 2. could be possible for Gnome-Shell extensions under Wayland. Here is what I tried:

1. Bind to events of global.stage. This event is only emitted when some ui elements of Gnome-Shell are clicked on, not client windows (why?).

global.stage.connect('button-release-event', (actor, event) => {
  // do something
  return Clutter.EVENT_STOP;
});

2. Polling. It is possible to get pointer information at any time with global.get_pointer(); So this works somehow, but the original click event is not captured. While this could open a pie menu, there would still be a click on whatever is currently under the pointer.

GLib.timeout_add(GLib.PRIORITY_DEFAULT, 10, () => {
  const [x, y, mods] = global.get_pointer();
  if (mods & Clutter.ModifierType.BUTTON1_MASK &&
      mods & Clutter.ModifierType.CONTROL_MASK) {

    // do something
  }

  return true;
});

3. Weird combination of Main.pushModal() and Seat.create_virtual_device(). It might be possible to capture the input globally and forward the events I am not interested in with virtual devices. While this could work - I did not try this yet - it sounds veeery hacky.

Has somebody an idea whether this could be achieved?

Thank you very much!

Simon



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]