do-sch / gnome-shell-touchpad-window-move

GNOME Extension that allows moving windows with three finger trackpad gestures
GNU General Public License v3.0
24 stars 6 forks source link

Is it possible to have three finger do drag and drop? #3

Closed pofl closed 4 years ago

pofl commented 5 years ago

Hi I don't know how to contact you other than via an issue. What I would love to have in GNOME is three fingers to drag and drop. Like with a mouse when I would move the pointer onto something and then click and hold the button and then move the thing. Can you tell me how feasible that is?

do-sch commented 5 years ago

It was in fact my first intention to make three finger gestures to do a drag and drop while pressing super key to move windows around. But unfortunately it did never work that well. In some cases the mouse stayed clicked or super key stayed pressed, even when the gesture was over. I could not figure out if it was my mistake or a bug in clutter. But maybe you have more luck. It should not be that complicated either.

The steps to implement such an extension are the following: 1) You will need to listen to touchpad gestures. Just take a look at my extension.js or at the extension.js of the extendedgestures-extension: https://github.com/mpiannucci/gnome-shell-extended-gestures/blob/master/extendedgestures%40mpiannucci.github.com/extension.js Here an example; It would be better to create an own class for this and do it an an object oriented way:

function handleEvent(actor, event) {
    if (event.type() != Clutter.EventType.TOUCHPAD_SWIPE) // only handle touchpad swipes
        return Clutter.EVENT_PROPAGATE;

    if (event.get_touchpad_gesture_finger_count() != 3) // only handle three finger gestures
        return Clutter.EVENT_PROPAGATE;

    // handle your drag and drop here
    let [dx, dy] = event.get_gesture_motion_delta(); // dx and dy are the relative values of your gesture move
}

// connect to touchpad events here
gestureCallbackID = global.stage.connect('captured-event', Lang.bind(this, handleEvent));

2) Get a DeviceManager and create a virtual pointer

const deviceManager = Clutter.DeviceManager.get_default();
const virtualPointer = deviceManager.create_virtual_device(Clutter.InputDeviceType. POINTER_DEVICE);

3) You can manipulate the pointer then. It will behave as if a secound mouse is connected to your computer

virtualPointer.notify_relative_motion(global.get_current_time(), dx, dy); //move pointer
virtualPointer.notify_button(global.get_current_time(), Clutter.BUTTON_PRIMARY, Clutter.ButtonState.PRESSED); //begin to click
virtualPointer.notify_button(global.get_current_time(), Clutter.BUTTON_PRIMARY, Clutter.ButtonState.RELEASED); // stop click

The API for this is not really commented anywhere, at least I did not find anything. I figured it out through this Header-File: https://gitlab.gnome.org/GNOME/mutter/blob/master/clutter/clutter/clutter-virtual-input-device.h Reading source code of other, similar extensions will also help you.