gtk3 motionNotifyEvent doesn't work when button is depressed

492 views Asked by At
module Main where

import Control.Monad.IO.Class
import Graphics.UI.Gtk

main :: IO ()
main = do
    initGUI
    window <- windowNew
    canvas <- drawingAreaNew

    widgetAddEvents canvas [Button1MotionMask]

    canvas `on` motionNotifyEvent $ do
        c <- eventCoordinates
        liftIO $ print c
        return False

    containerAdd window canvas
    widgetShowAll window
    mainGUI

In the code above, I am trying to handle a 'mouse drag' on a GtkDrawingArea, where the left mouse button is depressed. However, nothing is printed, indicating that the event is never firing. Even stranger, when I change Button1MotionMask to PointerMotionMask, the event fires when I move my mouse normally (as expected), but not when I move the mouse while depressing the left mouse button. What is going on here? I am using the gtk3-0.14.8 package on Windows 10.

EDIT: I should probably be a bit clearer about my problem. When I hold the left mouse button down while moving the mouse, motionNotifyEventdoes not fire. This does not depend on whether I have added PointerMotionMask or Button1MotionMask.

2

There are 2 answers

0
bradrn On BEST ANSWER

It doesn't seem to be mentioned in the documentation, but it turns out that you also need to enable ButtonPressMask to recieve any event with the mouse button pressed - including motion events which occur when the button is pressed down. This results in the paradoxical behaviour where enabling only Button1MotionMask results in no events being received unless you also enable ButtonPressMask. I finally figured this out after discovering the gtk-demo sample application - it's very useful for learning GTK!

0
Alexander Dmitriev On

Interesting, C documentation on motion-notify-event says

To receive this signal, the GdkWindow associated to the widget needs to enable the GDK_POINTER_MOTION_MASK mask

Enabling only GDK_BUTTON1_MOTION_MASK doesn't work for me too. Fortunately, GdkEventMotion has field state, where you can check whether button1 is pressed or not.