Hmm, I think I now know how to work with XEventPtr's with allocaXEvent event, what I have now is this:

raiseWin :: Win -> IO ();
  raiseWin w = let {
      d         = disp w;
      r         = root w;
      xID       = xid w;
    } in 
      do {
        ctime   <- Monad.liftM (\(Time.TOD t _) -> fromIntegral t) Time.getClockTime;
        atom    <- Xlib.Atom.internAtom d "_NET_ACTIVE_WINDOW" True;
        Xlib.Event.allocaXEvent $ \ePtr -> do {
          Xlib.Extras.setEventType            ePtr XTypes.clientMessage;
          Xlib.Extras.setClientMessageEvent   ePtr xID atom 32 2 ctime;
          
          Xlib.Event.sendEvent d r False 
            (Xlib.substructureNotifyMask .|. Xlib.substructureRedirectMask) ePtr;
        };
      };

where root in the Win record is derived from:

 (root, parent, _) 
      <- Xlib.Extras.queryTree d xid;

The code compiles and type checks, it just doesn't... work, it does nothing. Replacing the code with:

  raiseWin w = 
    System.Process.rawSystem "xdotool" ["windowactivate", show x] >> return () where {
      x = xid w;
    } 

Makes it work without errors, inspecting the code of xdotool makes it reveal to use the "_NET_ACTIVE_WINDOW" client message to the root hole? Any idea what I could be doing wrongly, is this the correct root window?




On 10 December 2013 06:22, Brandon Allbery <allbery.b@gmail.com> wrote:
On Mon, Dec 9, 2013 at 10:57 PM, EatsKittens <temporalabstraction@gmail.com> wrote:
Xlib.Event seems to define the interestingly recursive type data XEvent = XEvent (Ptr XEvent) and otherwise give no information about that type.

Anything on the far side of a Ptr is defined by C and accessed via the FFI. In this case, you're looking for the XEvent structure defined by the C Xlib and described in X11/X.h (constants) and X11/Xlib.h (structs; note that there is a separate struct for each event type although they all have a common preamble).

You may be better served by the event definitions in http://xmonad.org/xmonad-docs/X11/Graphics-X11-Xlib-Extras.html which is a Haskell, instead of FFI, interface. (I pointed to the xmonad copy of the docs because that's what I already have loaded in a tab, but it's part of the same X11 binding as Graphics.X11.Xlib.Event.)

I need this type to send an XEvent message to a window, is this a mistake or am I overlooking something in how to use it, or is the idea that the only way to make XEvent data is to make it in C and import it from there?

allocaXEvent is defined in Graphics.X11.Xlib.Event, but you need to refer to the C Xlib definitions and use FFI marshaling to work with it (and may need to know C type sizes and how the C compiler packs structs on your system). There's some code in xmonad-contrib which uses that interface to send custom events.

--
brandon s allbery kf8nh                               sine nomine associates
allbery.b@gmail.com                                  ballbery@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net