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