Discussion:
[xmonad] Catching exceptions from getWindowAttributes
Adam Sjøgren
2016-06-12 17:24:17 UTC
Permalink
I am trying to modify xmonad to handle exceptions thrown in
getWindowAttributes.

Since I am still copy/paste-coding, I need some help.

Take a function like this, which I have seen crashes in (especially when
using Gimp):

floatLocation :: Window -> X (ScreenId, W.RationalRect)
floatLocation w = withDisplay $ \d -> do
ws <- gets windowset
wa <- io $ getWindowAttributes d w
let bw = (fromIntegral . wa_border_width) wa
sc <- fromMaybe (W.current ws) <$> pointScreen (fi $ wa_x wa) (fi $ wa_y wa)

let sr = screenRect . W.screenDetail $ sc
rr = W.RationalRect ((fi (wa_x wa) - fi (rect_x sr)) % fi (rect_width sr))
((fi (wa_y wa) - fi (rect_y sr)) % fi (rect_height sr))
(fi (wa_width wa + bw*2) % fi (rect_width sr))
(fi (wa_height wa + bw*2) % fi (rect_height sr))

return (W.screen sc, rr)
where fi x = fromIntegral x

I somehow need to wrap the code from getWindowAttributes and on, in
something that "does the right thing" if gWA throws an exception.

In other places, I have done something like this:

sendConfigureEvent :: Display -> XEventPtr -> Window -> Event -> IO ()
sendConfigureEvent dpy ev w e = C.handle (\(C.SomeException _) -> putStrLn "sendConfigureEvent failed") $ do
wa <- io $ getWindowAttributes dpy w
setEventType ev configureNotify
setConfigureEvent ev w w
(wa_x wa) (wa_y wa) (wa_width wa)
(wa_height wa) (ev_border_width e) none (wa_override_redirect wa)
sendEvent dpy w False 0 ev

which works, but in floatLocation the type is X and not IO, and ...
well, what's a boy to do?


Best regards,

Adam
--
"It's part of our policy not to be taken seriously" Adam Sjøgren
***@koldfront.dk
Daniel Wagner
2016-06-22 19:55:38 UTC
Permalink
The simplest thing will be to wrap just the call to `getWindowAttributes`,
if that's the one you expect to fail. It is not conveniently possible to
wrap `X` actions; so instead, something like

withDisplay $ \d -> do
ws <- gets windowset
ewa <- io $ try (getWindowAttributes d w)
case ewa of
Left e -> io (putStrLn "HELP! do something!")
Right wa -> do
let bw = (fromIntegral . wa_border_width) wa
{- ... etc. -}

~d
Post by Adam Sjøgren
I am trying to modify xmonad to handle exceptions thrown in
getWindowAttributes.
Since I am still copy/paste-coding, I need some help.
Take a function like this, which I have seen crashes in (especially when
floatLocation :: Window -> X (ScreenId, W.RationalRect)
floatLocation w = withDisplay $ \d -> do
ws <- gets windowset
wa <- io $ getWindowAttributes d w
let bw = (fromIntegral . wa_border_width) wa
sc <- fromMaybe (W.current ws) <$> pointScreen (fi $ wa_x wa) (fi $ wa_y wa)
let sr = screenRect . W.screenDetail $ sc
rr = W.RationalRect ((fi (wa_x wa) - fi (rect_x sr)) % fi (rect_width sr))
((fi (wa_y wa) - fi (rect_y sr)) % fi (rect_height sr))
(fi (wa_width wa + bw*2) % fi (rect_width sr))
(fi (wa_height wa + bw*2) % fi (rect_height sr))
return (W.screen sc, rr)
where fi x = fromIntegral x
I somehow need to wrap the code from getWindowAttributes and on, in
something that "does the right thing" if gWA throws an exception.
sendConfigureEvent :: Display -> XEventPtr -> Window -> Event -> IO ()
sendConfigureEvent dpy ev w e = C.handle (\(C.SomeException _) ->
putStrLn "sendConfigureEvent failed") $ do
wa <- io $ getWindowAttributes dpy w
setEventType ev configureNotify
setConfigureEvent ev w w
(wa_x wa) (wa_y wa) (wa_width wa)
(wa_height wa) (ev_border_width e) none
(wa_override_redirect wa)
sendEvent dpy w False 0 ev
which works, but in floatLocation the type is X and not IO, and ...
well, what's a boy to do?
Best regards,
Adam
--
"It's part of our policy not to be taken seriously" Adam SjÞgren
_______________________________________________
xmonad mailing list
http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad
Brandon Allbery
2016-06-22 20:00:23 UTC
Permalink
It is not conveniently possible to wrap `X` actions
userCode and userCodeDef, in XMonad.Core.
--
brandon s allbery kf8nh sine nomine associates
***@gmail.com ***@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
Adam Sjøgren
2016-09-10 22:09:17 UTC
Permalink
Post by Daniel Wagner
The simplest thing will be to wrap just the call to `getWindowAttributes`,
if that's the one you expect to fail.
It is one I observe failing, yes.
Post by Daniel Wagner
It is not conveniently possible to wrap `X` actions; so instead,
something like
withDisplay $ \d -> do
ws <- gets windowset
ewa <- io $ try (getWindowAttributes d w)
case ewa of
Left e -> io (putStrLn "HELP! do something!")
Right wa -> do
let bw = (fromIntegral . wa_border_width) wa
{- ... etc. -}
I can't make this construction compile, when I try to change
floatLocation to use it, I get errors about a return value being of type
X () instead of X (ScreenId, W.RationalRect).


Best regards,

Adam
--
"Alla för alla, en för en Adam Sjøgren
Alla för alla, en för en ***@koldfront.dk
Så börjar vi om igen"
Daniel Wagner
2016-09-11 23:11:01 UTC
Permalink
I suppose the question that this error is asking you is: when
`getWindowAttributes` throws an error, how should `floatLocation` respond?

Perhaps returning some default -- like `(0, RationalRect 0 0 1 1)` or
something -- will be sufficient? I don't know how `floatLocation` gets
used, so I don't know how dangerous a default that would be.

Do we need to change the type of `floatLocation` to admit that it may not
know the right answer?

~d
Post by Daniel Wagner
Post by Daniel Wagner
The simplest thing will be to wrap just the call to
`getWindowAttributes`,
Post by Daniel Wagner
if that's the one you expect to fail.
It is one I observe failing, yes.
Post by Daniel Wagner
It is not conveniently possible to wrap `X` actions; so instead,
something like
withDisplay $ \d -> do
ws <- gets windowset
ewa <- io $ try (getWindowAttributes d w)
case ewa of
Left e -> io (putStrLn "HELP! do something!")
Right wa -> do
let bw = (fromIntegral . wa_border_width) wa
{- ... etc. -}
I can't make this construction compile, when I try to change
floatLocation to use it, I get errors about a return value being of type
X () instead of X (ScreenId, W.RationalRect).
Best regards,
Adam
--
"Alla för alla, en för en Adam SjÞgren
Så börjar vi om igen"
_______________________________________________
xmonad mailing list
http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad
Brandon Allbery
2016-09-12 04:15:25 UTC
Permalink
Post by Daniel Wagner
I suppose the question that this error is asking you is: when
`getWindowAttributes` throws an error, how should `floatLocation` respond?
I am not sure I understand wjy getWindowAttributes would throw an exception
except for "window removed", and for most of those you probably want to be
aborting the hook in question. So, make sure it's always under control of
userCode; this would include moving the one in X.O.manage into a userCode,
but that would probably be smart anyway since I think we crash currently if
the new window we want to manage goes away before we can. Or both its uses
(one to manage initial windows at startup and one in response to
MapRequestEvent).
--
brandon s allbery kf8nh sine nomine associates
***@gmail.com ***@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
Adam Sjøgren
2016-09-13 05:00:51 UTC
Permalink
Post by Brandon Allbery
Post by Daniel Wagner
I suppose the question that this error is asking you is: when
`getWindowAttributes` throws an error, how should `floatLocation` respond?
Yeah, and I don't really know enough to answer that question either. I
guess something is really wrong with the window, and XMonad should give
up?
Post by Brandon Allbery
I am not sure I understand wjy getWindowAttributes would throw an
exception except for "window removed",
That could very well be it, I usually see the exceptions from
getWindowAttributes in floatLocation when Gimp opens windows that
display some kind of progress and quickly closes them again.
Post by Brandon Allbery
and for most of those you probably want to be aborting the hook in
question. So, make sure it's always under control of userCode; this
would include moving the one in X.O.manage into a userCode, but that
would probably be smart anyway since I think we crash currently if the
new window we want to manage goes away before we can. Or both its uses
(one to manage initial windows at startup and one in response to
MapRequestEvent).
Yes. Uhm. Ah. I haven't got the foggiest of how to do any of that.


Best regards,

Adam
--
"Good evening. Today is Good Friday. There is no news." Adam Sjøgren
***@koldfront.dk
Loading...