some fixes!
Isaac Dupree
ml at isaac.cedarswampstudios.org
Mon Dec 31 00:05:26 CET 2012
Funny story: I found arbtt because I was writing exactly the same idea
in Haskell, searched for Haskell bindings to the XScreenSaver extension,
and the arbtt repository was the only one that had those bindings.
(Off-topic: Those bindings should probably be in the X11 package.)
I attached the darcs patches I needed to get arbtt working well enough
for me on GHC 7.6.1 and XMonad (on Arch Linux). Did I do 'darcs send'
right? Do the patches need improvement?
-Isaac
-------------- next part --------------
3 patches for repository http://darcs.nomeata.de/arbtt:
Sun Dec 30 16:22:54 EST 2012 Isaac Dupree <id at isaac.cedarswampstudios.org>
* Fix build with base 4.6 (GHC 7.6)
(Someone who knows this code / these exceptions better could
probably use Control.Exception.catch to only catch the specific
IO exceptions we're interested in. This patch, however,
does not change which exceptions are caught.)
Sun Dec 30 17:16:23 EST 2012 Isaac Dupree <id at isaac.cedarswampstudios.org>
* restore smarter & non-crashy followTreeUntil
Following along from
http://lists.nomeata.de/archive/arbtt/2012/000144.html
I tried hacking on followTreeUntil in various ways and
found that on my system, calling queryTree with 0 as the window
argument seems to cause a segfault after the 12th or 13th call.
(A way to test for a segfault: replace 'w' in the queryTree call
with '0'; rebuild; call arbtt-capture with -r 0 or -r 1 depending
on patience.)
(XQueryTree() returns 0 as the parent window when it's called on the
root window [and maybe at other times? Its man page didn't say anything
about when it returns 0].)
The root-window-avoiding behavior from before is useful for XMonad.
So I restore that, while retaining the /= 0 checks.
For paranoia's sake I make extra sure that followTreeUntil can never
call queryTree with 0 as the window param.
Sun Dec 30 17:27:39 EST 2012 Isaac Dupree <id at isaac.cedarswampstudios.org>
* Semi-fix arbtt for xmonad (a non-_NET_CLIENT_LIST-setting WM)
This now captures (only) the currently focused window;
I'm not personally interested in other windows so I'm not
trying harder to fix that part.
XMonad is a non-reparenting wm, so all interesting windows have
a root window as their parent, so this method works fine.
As JOKer notes[1], the i3 window manager would need a bit more work:
it does not provide _NET_CLIENT_LIST but it does reparent managed
windows to inside its own container windows. We'd need to detect
those container windows in the arbtt code. I don't currently have
an i3 wm set up to look for a good method; JOKer posts a method
that worked for them[1].
[1] http://lists.nomeata.de/archive/arbtt/2012/000145.html
(The "filter (/= 0)" is just paranoia in case the _NET_CLIENT_LIST
contains 0 or the focused window is 0 somehow due to odd WMs or focuses.
This check wasn't necessary for my quick tests in the particular WM setup
I have.)
New patches:
[Fix build with base 4.6 (GHC 7.6)
Isaac Dupree <id at isaac.cedarswampstudios.org>**20121230212254
Ignore-this: a91f4ab1f7b285e54c7c4aea94762c5b
(Someone who knows this code / these exceptions better could
probably use Control.Exception.catch to only catch the specific
IO exceptions we're interested in. This patch, however,
does not change which exceptions are caught.)
] hunk ./arbtt.cabal 33
main-is: capture-main.hs
hs-source-dirs: src
build-depends:
- base == 4.5.*, filepath, directory, transformers, time >= 1.4, utf8-string,
+ base == 4.5.* || == 4.6.*,
+ filepath, directory, transformers, time >= 1.4, utf8-string,
bytestring, binary, deepseq, strict,
terminal-progress-bar, bytestring-progress
other-modules:
hunk ./src/Capture/X11.hs 8
import Graphics.X11.Xlib.Extras
import Control.Monad
import Control.Exception (bracket)
+import System.IO.Error (catchIOError)
import Control.Applicative
import Data.Maybe
import Data.Time.Clock
hunk ./src/Capture/X11.hs 81
myFetchName d w = do
let getProp =
(internAtom d "_NET_WM_NAME" False >>= getTextProperty d w)
- `catch`
+ `catchIOError`
(\_ -> getTextProperty d w wM_NAME)
extract prop = do l <- wcTextPropertyToTextList d prop
hunk ./src/Capture/X11.hs 87
return $ if null l then "" else head l
- bracket getProp (xFree . tp_value) extract `catch` \_ -> return ""
+ bracket getProp (xFree . tp_value) extract
+ `catchIOError` \_ -> return ""
hunk ./src/capture-main.hs 73
hPutStrLn stderr ("arbtt [Error]: Could not aquire lock for " ++ filename ++"!")
exitFailure
#else
- flip catch (\e -> hPutStrLn stderr ("arbtt [Error]: Could not aquire lock for " ++ filename ++"!") >> exitFailure) $ do
+ flip catchIOError (\e -> hPutStrLn stderr ("arbtt [Error]: Could not aquire lock for " ++ filename ++"!") >> exitFailure) $ do
fd <- openFd (filename ++ ".lck") WriteOnly (Just 0o644) defaultFileFlags
setLock fd (WriteLock, AbsoluteSeek, 0, 0)
#endif
[restore smarter & non-crashy followTreeUntil
Isaac Dupree <id at isaac.cedarswampstudios.org>**20121230221623
Ignore-this: 6410333233854d7b5048d8b08ab1b1ca
Following along from
http://lists.nomeata.de/archive/arbtt/2012/000144.html
I tried hacking on followTreeUntil in various ways and
found that on my system, calling queryTree with 0 as the window
argument seems to cause a segfault after the 12th or 13th call.
(A way to test for a segfault: replace 'w' in the queryTree call
with '0'; rebuild; call arbtt-capture with -r 0 or -r 1 depending
on patience.)
(XQueryTree() returns 0 as the parent window when it's called on the
root window [and maybe at other times? Its man page didn't say anything
about when it returns 0].)
The root-window-avoiding behavior from before is useful for XMonad.
So I restore that, while retaining the /= 0 checks.
For paranoia's sake I make extra sure that followTreeUntil can never
call queryTree with 0 as the window param.
] hunk ./src/Capture/X11.hs 65
getProgramName :: Display -> Window -> IO String
getProgramName dpy = fmap resName . getClassHint dpy
--- | Follows the tree of windows up until the condition is met or the root
--- window is reached.
+-- | Follows the tree of windows up until the condition is met or the window is
+-- a direct child of the root.
followTreeUntil :: Display -> (Window -> Bool) -> Window -> IO Window
followTreeUntil dpy cond = go
hunk ./src/Capture/X11.hs 69
- where go w | cond w = return w
- | otherwise = do (r,p,_) <- queryTree dpy w
- if p == 0 then return w
- else go p
+ where go w | 0 == w || cond w = return w
+ | otherwise = do
+ (r,p,_) <- queryTree dpy w
+ if p == 0 || p == r then return w
+ else go p
-- | better than fetchName from X11, as it supports _NET_WM_NAME and unicode
--
[Semi-fix arbtt for xmonad (a non-_NET_CLIENT_LIST-setting WM)
Isaac Dupree <id at isaac.cedarswampstudios.org>**20121230222739
Ignore-this: b98d8743723a5d5b1a88adaae6225f6c
This now captures (only) the currently focused window;
I'm not personally interested in other windows so I'm not
trying harder to fix that part.
XMonad is a non-reparenting wm, so all interesting windows have
a root window as their parent, so this method works fine.
As JOKer notes[1], the i3 window manager would need a bit more work:
it does not provide _NET_CLIENT_LIST but it does reparent managed
windows to inside its own container windows. We'd need to detect
those container windows in the arbtt code. I don't currently have
an i3 wm set up to look for a good method; JOKer posts a method
that worked for them[1].
[1] http://lists.nomeata.de/archive/arbtt/2012/000145.html
(The "filter (/= 0)" is just paranoia in case the _NET_CLIENT_LIST
contains 0 or the focused window is 0 somehow due to odd WMs or focuses.
This check wasn't necessary for my quick tests in the particular WM setup
I have.)
] hunk ./src/Capture/X11.hs 14
import Data.Time.Clock
import System.IO
import qualified Data.MyText as T
+import qualified Data.List as List
import System.Locale.SetLocale
import Graphics.X11.XScreenSaver (getXIdleTime, compiledWithXScreenSaver)
hunk ./src/Capture/X11.hs 31
a <- internAtom dpy "_NET_CLIENT_LIST" False
p <- getWindowProperty32 dpy a rwin
when (isNothing p) $ do
- hPutStrLn stderr "arbtt: ERROR: No _NET_CLIENT_LIST set for the root window"
+ hPutStrLn stderr "arbtt: WARNING: No _NET_CLIENT_LIST set for the root window,"
+ hPutStrLn stderr " so arbtt can only capture focused windows"
closeDisplay dpy
captureData :: IO CaptureData
hunk ./src/Capture/X11.hs 51
(fsubwin,_) <- getInputFocus dpy
fwin <- followTreeUntil dpy (`elem` wins) fsubwin
- winData <- forM wins $ \w -> (,,)
+ let loggedWins = filter (/= 0)
+ (List.union wins [fwin])
+
+ winData <- forM loggedWins $ \w -> (,,)
(w == fwin) <$>
(T.pack <$> getWindowTitle dpy w) <*>
(T.pack <$> getProgramName dpy w)
Context:
[Merge bugfix release
Joachim Breitner <mail at joachim-breitner.de>**20121115110410
Ignore-this: aca7d7e2f1376105cd8f865049068960
]
[TAG 0.6.4.1
Joachim Breitner <mail at joachim-breitner.de>**20121115110310
Ignore-this: 9a2581849bffdee4ee468adffaaebf3
]
[Forgot to add LeftFold to .cabal file
Joachim Breitner <mail at joachim-breitner.de>**20121115110213
Ignore-this: c469890ff016ad194e345d23ec5069f6
]
[Try to parse UTF8 Bytestrings more efficiently
Joachim Breitner <mail at joachim-breitner.de>**20121003095614
Ignore-this: 9d82d7b96af5bf3b1e2f6f33e4b5b59c
]
[Future code to speed up Data.MyText.get
Joachim Breitner <mail at joachim-breitner.de>**20121003091856
Ignore-this: ef97e016680c036d8e750bf1205a85b6
]
[SCC diffTimeFromRational
Joachim Breitner <mail at joachim-breitner.de>**20121003091851
Ignore-this: a2f995b5c4b5d7e79b1789b2f3723b95
]
[Avoid mixup of title and progress bar
Joachim Breitner <mail at joachim-breitner.de>**20121003084150
Ignore-this: 49df6319d0c73629248469d0f1554c4f
]
[Share currentWindow, small speedup
Joachim Breitner <mail at joachim-breitner.de>**20121003083744
Ignore-this: 1512364075d3cccca5ec2af405a36481
]
[docbook fix
Joachim Breitner <mail at joachim-breitner.de>**20121002235616
Ignore-this: 3f00021820f6e86b9c2dfd48360c5eee
]
[Use TimeZone at parse time, considerable speedup
Joachim Breitner <mail at joachim-breitner.de>**20121002234716
Ignore-this: 733f51e288783dee0e073be4f84009c
]
[Pass TimeZone already at parse time
Joachim Breitner <mail at joachim-breitner.de>**20121002234641
Ignore-this: 7c3f6c8a7db085dd31afa2bb97de2e08
]
[Add failing operators to Text.Parsec.ExprFail
Joachim Breitner <mail at joachim-breitner.de>**20121002234628
Ignore-this: 7fd5aac79328f3da47cf0cf53313172d
]
[Import Text.Parsec.Expr from parsec-3.1.3
Joachim Breitner <mail at joachim-breitner.de>**20121002233445
Ignore-this: 48dcfdc43ead4cfcfa68f9d5b9dca8fe
]
[More strictness in the advanced MapFold operations
Joachim Breitner <mail at joachim-breitner.de>**20121002225115
Ignore-this: 7577ac985102b1d8fab76714eef728b9
]
[Support for date literals
Joachim Breitner <mail at joachim-breitner.de>**20121002203246
Ignore-this: ef831b034449bf5b554a0d974daa4c12
]
[Warn about format speed
Joachim Breitner <mail at joachim-breitner.de>**20121002195422
Ignore-this: a0f8092a2a6638566bc2ea32c90571db
]
[Ensure logfile is not world-readable
Joachim Breitner <mail at joachim-breitner.de>**20120929210618
Ignore-this: 4ada859e37ed264fa0651f902d5d22c
]
[Show a progress bar in arbtt-stats
Joachim Breitner <mail at joachim-breitner.de>**20120928203659
Ignore-this: 257a2895d8ef8ecedd2521a5f104968c
]
[TAG 0.6.4
Joachim Breitner <mail at joachim-breitner.de>**20120928165721
Ignore-this: 49acb948bbc371d27c99887b7698a498
]
Patch bundle hash:
8f94ecfb9f037c5d24460075bfe8b57758681740
More information about the arbtt
mailing list