
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
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

On Tue, Dec 10, 2013 at 12:24 PM, EatsKittens wrote: where root in the Win record is derived from: (root, parent, _)
<- Xlib.Extras.queryTree d xid; That looks like it should be the right one, but normally I'd just get the
root window of the default Screen.
For what it's worth, I see one issue: setClientMessageEvent does only the
basic information necessary for a client message, which is insufficient for
the _NET_ACTIVE_WINDOW message. (It's missing the client active window,
which in this case should probably be 0 anyway so it may not be an issue
that it's missing.) 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? You might use something like xtrace/xscope/xmon to make sure that xdotool
and your program are actually sending the same client message.
--
brandon s allbery kf8nh sine nomine associates
allbery.b@gmail.com ballbery@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

xtrace revealed to me that Haskell Xlib was not even sending the event.
After some further inspection of XMonad code they apparently call
Xlib.Event.Sync d False a lot at. I'm not entirely sure why Haskell needs
it as the Xlib pages say it shouldn't be needed but it works when calling
it. xdotool does not seem to use it in it's C code. Is there any reason why
Haskell's Xlib needs it?
On 10 December 2013 19:03, Brandon Allbery
On Tue, Dec 10, 2013 at 12:24 PM, EatsKittens < temporalabstraction@gmail.com> wrote:
where root in the Win record is derived from:
(root, parent, _) <- Xlib.Extras.queryTree d xid;
That looks like it should be the right one, but normally I'd just get the root window of the default Screen.
For what it's worth, I see one issue: setClientMessageEvent does only the basic information necessary for a client message, which is insufficient for the _NET_ACTIVE_WINDOW message. (It's missing the client active window, which in this case should probably be 0 anyway so it may not be an issue that it's missing.)
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?
You might use something like xtrace/xscope/xmon to make sure that xdotool and your program are actually sending the same client message.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
participants (2)
-
Brandon Allbery
-
EatsKittens