packages feed

hbro 0.9.0.0 → 0.9.1.0

raw patch · 12 files changed

+170/−144 lines, 12 filesdep ~gtkPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: gtk

API changes (from Hackage documentation)

- Hbro.Hbro: launchHbro :: Config -> IO ()
- Hbro.Keys: manageSequentialKeys :: (String -> K (String, Bool)) -> String -> K (String, Bool)
+ Hbro.Boot: getOptions :: IO CliOptions
+ Hbro.Boot: hbro :: Config -> IO ()
+ Hbro.Boot: printDyrePaths :: IO ()
+ Hbro.Boot: recompile :: IO (Maybe String)
+ Hbro.Hbro: main :: (Config', CliOptions) -> IO ()
+ Hbro.Hbro: main' :: Environment -> IO ()
+ Hbro.Hbro: onDownload :: Environment -> Download -> IO Bool
+ Hbro.Hbro: onKeyPressed :: Environment -> EventM EKey Bool
+ Hbro.Hbro: onMIMEDisposition :: Environment -> WebFrame -> NetworkRequest -> String -> WebPolicyDecision -> IO Bool
+ Hbro.Hbro: onNavigationRequest :: Environment -> WebFrame -> NetworkRequest -> WebNavigationAction -> WebPolicyDecision -> IO Bool
+ Hbro.Hbro: onNewWebView :: Environment -> WebFrame -> IO WebView
+ Hbro.Hbro: onNewWindow :: Environment -> WebFrame -> NetworkRequest -> WebNavigationAction -> WebPolicyDecision -> IO Bool
+ Hbro.Hbro: onPromptChanged :: Environment -> IO ()
+ Hbro.Hbro: onPromptKeyPress :: Environment -> EventM EKey Bool
+ Hbro.Hbro: onTitleChanged :: Environment -> WebFrame -> String -> IO ()
+ Hbro.Keys: defaultKeyHandler :: KeysList -> String -> K (String, Bool)
+ Hbro.Keys: emacsKeyHandler :: KeysList -> [String] -> String -> K (String, Bool)
+ Hbro.Util: logNormal, logVerbose :: MonadIO m => String -> m ()

Files

+ Hbro/Boot.hs view
@@ -0,0 +1,106 @@+module Hbro.Boot (+-- * Commandline options+    getOptions,+-- * Dynamic reconfiguration+    printDyrePaths,+    recompile,+-- * Boot+    hbro    +) where++import qualified Hbro.Hbro as Hbro+import Hbro.Types+import Hbro.Util++import qualified Config.Dyre as D+import Config.Dyre.Compile+import Config.Dyre.Paths++import Control.Monad++import Graphics.UI.Gtk.General.General hiding(initGUI)++import System.Console.CmdArgs+import System.Exit+import System.IO+import System.Posix.Signals+++++-- {{{ Commandline options+cliOptions :: CliOptions+cliOptions = CliOptions {+    mURI           = def &= name "u" &= name "uri" &= typ "URI" &= help "URI to open at start-up" &= explicit,+    mVanilla       = def &= name "1" &= name "vanilla"&= help "Do not read custom configuration file." &= explicit,+    mRecompile     = def &= name "r" &= name "recompile" &= help "Force recompilation and do not launch browser." &= explicit,+    mDenyReconf    = def             &= name "deny-reconf" &= help "Deny recompilation even if the configuration file has changed." &= explicit,+    mForceReconf   = def             &= name "force-reconf" &= help "Force recompilation even if the configuration file hasn't changed." &= explicit,+    mDyreDebug     = def             &= name "dyre-debug" &= help "Force the application to use './cache/' as the cache directory, and ./ as the configuration directory. Useful to debug the program without installation." &= explicit,+    mMasterBinary  = def             &= name "dyre-master-binary" &= explicit+}++getOptions :: IO CliOptions+getOptions = cmdArgs $ cliOptions+    &= verbosityArgs [explicit, name "verbose", name "v"] []+    &= versionArg [ignore]+    &= help "A minimal KISS-compliant browser."+    &= helpArg [explicit, name "help", name "h"]+    &= program "hbro"+-- }}}++-- {{{ Dynamic reconfiguration+printDyrePaths :: IO ()+printDyrePaths = getPaths dyreParameters >>= \(a,b,c,d,e) -> (putStrLn . unlines) [+    "Current binary:  " ++ a,+    "Custom binary:   " ++ b,+    "Config file:     " ++ c,+    "Cache directory: " ++ d,+    "Lib directory:   " ++ e, []]++-- | Launch a recompilation of the configuration file+recompile :: IO (Maybe String)+recompile = do+    customCompile  dyreParameters +    getErrorString dyreParameters ++showError :: (Config', a) -> String -> (Config', a)+showError (_, x) message = (Left message, x)++dyreParameters :: D.Params (Config', CliOptions)+dyreParameters = D.defaultParams {+    D.projectName  = "hbro",+    D.showError    = showError,+    D.realMain     = realMain,+    D.ghcOpts      = ["-threaded"],+    D.statusOut    = hPutStrLn stderr+}+-- }}}++-- | Browser's main function.+-- To be called in main function with a proper configuration.+-- See Hbro.Main for an example.+hbro :: Config -> IO ()+hbro config = do+    options <- getOptions+    +    when (mRecompile options) $+        recompile+        >>= maybe exitSuccess (\e -> putStrLn e >> exitFailure)+    +    case mVanilla options of+        True -> D.wrapMain dyreParameters{ D.configCheck = False } (Right config, options)+        _    -> D.wrapMain dyreParameters                          (Right config, options)+++realMain :: (Config', CliOptions) -> IO ()+realMain (Left e, _)             = putStrLn e+realMain config = do+    void $ installHandler sigINT (Catch interruptHandler) Nothing+    whenLoud printDyrePaths+    Hbro.main config+++interruptHandler :: IO ()+interruptHandler = logVerbose "Received SIGINT." >> mainQuit+
Hbro/Config.hs view
@@ -13,7 +13,7 @@  -- {{{ Import import Hbro.Core---import Hbro.Keys+import Hbro.Keys import Hbro.Gui import qualified Hbro.Prompt as Prompt import Hbro.Types@@ -23,7 +23,6 @@  import Data.Foldable import Data.Functor-import qualified Data.Map as M  import Graphics.UI.Gtk.Abstract.Widget import Graphics.UI.Gtk.General.General@@ -36,7 +35,6 @@  import Network.URI -import System.Console.CmdArgs (whenLoud) import System.FilePath import System.Glib.Attributes -- }}}@@ -76,16 +74,6 @@ -- | Warn user about missing download hook. defaultDownloadHook :: URI -> String -> Int -> K () defaultDownloadHook _ _ _ = notify 5000 "No download hook defined."---- | Look for a callback associated to the given keystrokes and trigger it, if any.-defaultKeyHandler :: KeysList -> String -> K (String, Bool)-defaultKeyHandler keysList keystrokes = do-    io . whenLoud . putStr $ "Key pressed: " ++ keystrokes-    (log', isMapped) <- case M.lookup keystrokes (M.fromList keysList) of-        Just callback -> callback >> return (" (mapped)",   True) -        _             ->             return (" (unmapped)", False)-    io . whenLoud . putStrLn $ log'-    return (keystrokes, isMapped)  -- | Default key bindings. defaultKeyBindings :: KeysList
Hbro/Core.hs view
@@ -130,7 +130,7 @@  loadURI :: URI -> K () loadURI uri = do-    io . whenLoud . putStrLn . ("Loading URI: " ++) . show $ uri'+    logVerbose $ "Loading URI: " ++ (show uri')     with (mWebView . mGUI) (`webViewLoadUri` uri')   where     uri' = case uriScheme uri of
Hbro/Hbro.hs view
@@ -1,9 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DoRec #-}-module Hbro.Hbro (--- * Main-    launchHbro-) where+module Hbro.Hbro where  -- {{{ Imports --import Hbro.Config@@ -15,15 +12,12 @@ import Hbro.Types import Hbro.Util -import qualified Config.Dyre as D-import Config.Dyre.Compile-import Config.Dyre.Paths- --import Control.Concurrent import Control.Monad.Reader hiding(forM_, mapM_)  import Data.Dynamic import Data.Foldable+import Data.Functor import Data.IORef import qualified Data.Map as M @@ -45,97 +39,26 @@  import System.Console.CmdArgs import System.Directory-import System.Exit import System.FilePath import System.Glib.Signals-import System.IO --import System.Posix.Process-import System.Posix.Signals import qualified System.ZMQ as ZMQ -- }}} --- {{{ Commandline options-cliOptions :: CliOptions-cliOptions = CliOptions {-    mURI           = def &= help "URI to open at start-up" &= explicit &= name "u" &= name "uri" &= typ "URI",-    mVanilla       = def &= help "Do not read custom configuration file." &= explicit &= name "1" &= name "vanilla",-    mRecompile     = def &= help "Force recompilation and do not launch browser." &= explicit &= name "r" &= name "recompile",-    mDenyReconf    = def &= help "Deny recompilation even if the configuration file has changed." &= explicit &= name "deny-reconf",-    mForceReconf   = def &= help "Force recompilation even if the configuration file hasn't changed." &= explicit &= name "force-reconf",-    mDyreDebug     = def &= help "Force the application to use './cache/' as the cache directory, and ./ as the configuration directory. Useful to debug the program without installation." &= explicit &= name "dyre-debug",-    mMasterBinary  = def &= explicit &= name "dyre-master-binary"-} -getOptions :: IO CliOptions-getOptions = cmdArgs $ cliOptions-    &= verbosityArgs [explicit, name "verbose", name "v"] []-    &= versionArg [ignore]-    &= help "A minimal KISS-compliant browser."-    &= helpArg [explicit, name "help", name "h"]-    &= program "hbro"--- }}}---- {{{ Util-printDyrePaths :: IO ()-printDyrePaths = getPaths dyreParameters >>= \(a,b,c,d,e) -> (putStrLn . unlines) [-    "Current binary:  " ++ a,-    "Custom binary:   " ++ b,-    "Config file:     " ++ c,-    "Cache directory: " ++ d,-    "Lib directory:   " ++ e, []]---- | Launch a recompilation of the configuration file-recompile :: IO (Maybe String)-recompile = do-    customCompile dyreParameters -    getErrorString dyreParameters --showError :: (Config', a) -> String -> (Config', a)-showError (_, x) message = (Left message, x)--- }}}---- {{{ Entry point      -dyreParameters :: D.Params (Config', CliOptions)-dyreParameters = D.defaultParams {-    D.projectName  = "hbro",-    D.showError    = showError,-    D.realMain     = realMain,-    D.ghcOpts      = ["-threaded"],-    D.statusOut    = hPutStrLn stderr-}---- | Browser's main function.--- To be called in main function with a proper configuration.--- See Hbro.Main for an example.-launchHbro :: Config -> IO ()-launchHbro config = do-    options <- getOptions--- Handle recompilation-    when (mRecompile options) $-        recompile-        >>= maybe exitSuccess (\e -> putStrLn e >> exitFailure)--- Handle vanilla mode-    case mVanilla options of-        True -> D.wrapMain dyreParameters{ D.configCheck = False } (Right config, options)-        _    -> D.wrapMain dyreParameters                          (Right config, options)- -- At this point, the reconfiguration process is done-realMain :: (Config', CliOptions) -> IO ()-realMain (Left e, _)             = putStrLn e-realMain (Right config, options) = do--- Handle SIGINT-    void $ installHandler sigINT (Catch interruptHandler) Nothing--- Print configuration state-    whenLoud printDyrePaths+main :: (Config', CliOptions) -> IO ()+main (Left e, _)             = putStrLn e+main (Right config, options) = do -- Initialize GUI, state and IPC socket     gui   <- initGUI (mUIFile config) (mWebSettings config)     state <- newIORef (M.empty :: M.Map String Dynamic)     -    ZMQ.withContext 1 $ \context -> realMain' (Environment state options config gui context)+    ZMQ.withContext 1 $ \context -> main' (Environment state options config gui context)     whenNormal . putStrLn $ "Exiting..." -realMain' :: Environment -> IO ()-realMain' environment@Environment{ mOptions = options, mConfig = config, mGUI = gui} = let+main' :: Environment -> IO ()+main' environment@Environment{ mOptions = options, mConfig = config, mGUI = gui} = let     entry   = (mEntry . mPromptBar) gui     webView = mWebView gui     hooks   = mHooks config@@ -173,21 +96,18 @@         io mainGUI                  Socket.close--interruptHandler :: IO ()-interruptHandler = whenLoud (putStrLn "Received SIGINT.") >> mainQuit -- }}}  -- {{{ Hooks onDownload :: Environment -> Download -> IO Bool onDownload environment download = do-    uri      <- (>>= parseURI) `fmap` downloadGetUri download+    uri      <- fmap (>>= parseURI) . downloadGetUri $ download     filename <- downloadGetSuggestedFilename download     size     <- downloadGetTotalSize download          case (uri, filename) of         (Just uri', Just filename') -> do-            whenLoud . putStrLn . ("Requested download: " ++) . show $ uri'+            logVerbose . ("Requested download: " ++) . show $ uri'             runK environment $ do                 notify 5000 $ "Requested download: " ++ filename' ++ " (" ++ show size ++ ")"                 callback uri' filename' size@@ -199,10 +119,11 @@ onKeyPressed :: Environment -> EventM EKey Bool onKeyPressed env = do     modifiers <- eventModifier-    key'      <- keyToString `fmap` eventKeyVal+    key'      <- keyToString <$> eventKeyVal      io . forM_ key' $ \key -> do          let keystrokes = (++ key) . concat . map stringify $ modifiers+        logVerbose $ "Key pressed: " ++ keystrokes         runK env $ (mKeyPressed hooks) keystrokes     return False   where@@ -255,7 +176,6 @@     return True            - -- Triggered in 2 cases: --  1/ Javascript window.open() --  2/ Context menu  "Open in new window"@@ -304,8 +224,6 @@ --  onTitleChanged :: Environment -> WebFrame -> String -> IO () onTitleChanged env _frame title = do-    whenLoud . putStrLn . ("Title changed: " ++) $ title-    runK env $ hook title-  where-    hook = mTitleChanged . mHooks . mConfig $ env+    logVerbose $ "Title changed: " ++ title+    runK env $ (mTitleChanged . mHooks . mConfig $ env) title -- }}}  
Hbro/Keys.hs view
@@ -1,10 +1,11 @@ {-# LANGUAGE DoRec #-} module Hbro.Keys ( -- * Other+    defaultKeyHandler,+    emacsKeyHandler, -- * Util     stringify,     keyToString,-    manageSequentialKeys ) where  -- {{{ Imports@@ -17,7 +18,7 @@  --import Data.Foldable import Data.IORef---import qualified Data.Map as M+import qualified Data.Map as M --import qualified Data.Set as S  import Graphics.UI.Gtk.Abstract.Widget@@ -30,24 +31,31 @@ --import System.Glib.Signals -- }}} +-- | Look for a callback associated to the given keystrokes and trigger it, if any.+defaultKeyHandler :: KeysList -> String -> K (String, Bool)+defaultKeyHandler keysList keystrokes = case M.lookup keystrokes (M.fromList keysList) of+    Just callback -> callback >> return (keystrokes, True) +    _             ->             return (keystrokes, False) -manageSequentialKeys :: (String -> K (String, Bool)) -> String -> K (String, Bool)-manageSequentialKeys handler keystroke = do-    keysRef         <- getState "Hbro.Keys.manageSequentialKeys" "" -    keys            <- io $ manageSequentialKeys' keysRef keystroke-    (keys', result) <- handler keys-    case result of-        True -> (io . modifyIORef keysRef $ const []) >> return ([], result)-        _    -> return (keys', result)+-- | Emacs-like key handler.+emacsKeyHandler :: KeysList     -- ^ Key bindings+                -> [String]     -- ^ List of prefix keys+                -> String       +                -> K (String, Bool)+emacsKeyHandler keysList prefixes keystrokes = do+    keysRef <- getState "Hbro.Keys.manageSequentialKeys" "" +    io $ modifyIORef keysRef (++ keystrokes)+    chainedKeys <- io $ readIORef keysRef -manageSequentialKeys' :: IORef String -> String -> IO String-manageSequentialKeys' previousKeys "<Escape>" = do-    writeIORef previousKeys []-    return []-manageSequentialKeys' previousKeys keystroke = do-    modifyIORef previousKeys (++ keystroke)-    return =<< readIORef previousKeys- +    case elem chainedKeys prefixes of+        True -> do+            io $ modifyIORef keysRef (++ " ")+            return (chainedKeys ++ " ", False)+        _    -> do+            io $ writeIORef keysRef []+            defaultKeyHandler keysList chainedKeys++ -- | Convert a KeyVal to a String. -- For printable characters, the corresponding String is returned, except for the space character for which "<Space>" is returned. -- For non-printable characters, the corresponding keyName wrapped into "< >" is returned.
Hbro/Main.hs view
@@ -1,8 +1,8 @@ module Main where  -- {{{ Imports+import Hbro.Boot import Hbro.Config-import Hbro.Hbro import Hbro.Types  import Paths_hbro@@ -13,6 +13,6 @@ main = do     uiFile <- getDataFileName "examples/ui.xml"     -    launchHbro $ defaultConfig {+    hbro $ defaultConfig {         mUIFile = const uiFile     }
Hbro/Prompt.hs view
@@ -22,8 +22,6 @@ import Network.URI  import Prelude hiding(mapM_)--import System.Console.CmdArgs (whenLoud) -- }}}  init :: Builder -> IO PromptBar@@ -40,7 +38,7 @@  open :: String -> String -> K () open newDescription defaultText = with (mPromptBar . mGUI) $ \(PromptBar promptBox description entry _ _) -> do-    whenLoud . putStrLn $ "Opening prompt."+    logVerbose "Opening prompt."     labelSetText description newDescription     entrySetText entry defaultText     
Hbro/Socket.hs view
@@ -12,9 +12,8 @@ --import Data.Foldable import qualified Data.Map as M -import Prelude hiding(mapM_)+import Prelude hiding(log, mapM_) -import System.Console.CmdArgs (whenNormal, whenLoud) import System.FilePath import System.Posix.Process import System.Posix.Types@@ -29,7 +28,7 @@     socketURI <- with (mSocketDir . mConfig) $ resolve >=> (return . (socketFile pid)) -- Open socket and listen to commands     mapK (void . forkIO) $ withK mContext $ \context -> do-        io . whenNormal . putStrLn . ("Opening socket at " ++) $ socketURI+        logNormal $ "Opening socket at " ++ socketURI         mapK2 (withSocket context Rep) $ \sock -> do             io $ bind sock socketURI             readCommands sock@@ -39,8 +38,8 @@ -- Typically called when exiting application.             close :: K () close = getURI >>= \uri -> do -    (io . whenLoud . putStrLn . ("Closing socket " ++) . (++ " ...")) uri-    (void . (`sendCommand` "QUIT")) uri+    logVerbose . ("Closing socket " ++) . (++ " ...") $ uri+    void . (`sendCommand` "QUIT") $ uri   -- | Listen for incoming requests from response socket.@@ -54,11 +53,11 @@         [] -> io $ send sock (pack "ERROR Unknown command") []     -- Exit command         ["QUIT"] -> io $ do-            whenLoud . putStrLn $ "Receiving QUIT command"+            logVerbose "Receiving QUIT command"             send sock (pack "OK") []     -- Valid command         command:arguments -> withK (M.fromList . mCommands . mConfig) $ \commands -> do-            io . whenLoud . putStrLn . ("Receiving command: " ++) $ message+            logVerbose . ("Receiving command: " ++) $ message             case M.lookup command commands of                 Just callback -> callback arguments >>= io . (send'' sock) . pack                 _             -> io $ send sock (pack "ERROR Unknown command") []
Hbro/Types.hs view
@@ -26,7 +26,7 @@ import Network.URI  import System.Console.CmdArgs-import System.Glib.Attributes+import System.Glib.Attributes hiding(get) --import System.Glib.Signals import System.ZMQ  -- }}}
Hbro/Util.hs view
@@ -1,6 +1,8 @@ module Hbro.Util ( -- * General purpose     io,+    logNormal,+    logVerbose,     resolve, -- * Process management     spawn,@@ -35,6 +37,8 @@ import Graphics.UI.Gtk.Display.Label import Graphics.UI.Gtk.General.General +import Prelude hiding(log)+ import System.Console.CmdArgs import System.Directory import System.Environment.XDG.BaseDir@@ -53,6 +57,10 @@  send'' :: Socket a -> ByteString -> IO () send'' x y = send x y []++logNormal, logVerbose :: (MonadIO m) => String -> m ()+logNormal  = io . whenNormal . putStrLn+logVerbose = io . whenLoud   . putStrLn  -- | resolve :: (RefDirs -> a) -> IO a
README.rst view
@@ -26,7 +26,7 @@ Extensibility and programmable interface   Targets are advanced users who have various expectations ; to be sure everyone is happy, configuration should use a programming language, and an interprocess interface should be available. As he who can do the most can do the least, the default configuration should be suitable for users that cannot afford/don't want to spend (waste ?) their time in tweaks. -Keyboard-friendly+Keyboard driven   Special attention should be given to allow keyboard control of the browser whenever possible ; however, this should not become an obsession in cases where mouse use is obviously a more convenient solution (yes, such cases do exist).  Free software
hbro.cabal view
@@ -1,5 +1,5 @@ Name:                hbro-Version:             0.9.0.0+Version:             0.9.1.0 Synopsis:            Minimal KISS compliant browser -- Description:          Homepage:            http://projects.haskell.org/hbro/@@ -33,7 +33,7 @@         dyre,         filepath,         glib,-        gtk,+        gtk >= 0.12.3,         mtl,         network,         pango,@@ -44,6 +44,7 @@         xdg-basedir,         zeromq-haskell     Exposed-modules:+        Hbro.Boot,         Hbro.Config,         Hbro.Core,         Hbro.Gui,