open-browser 0.3.0.1 → 0.5.1.0
raw patch · 11 files changed
Files
- CHANGELOG.md +27/−6
- example/Main.hs +22/−4
- lib/Web/Browser.hs +30/−9
- lib/unix-like/common/Utils.hs +0/−20
- lib/unix-like/open/Web/Browser/OS.hs +11/−4
- lib/unix-like/xdg-open/Web/Browser/OS.hs +12/−20
- lib/unsupported-os/Web/Browser/OS.hs +5/−3
- lib/windows/Web/Browser/OS.hs +14/−9
- open-browser.cabal +79/−85
- stack.yaml +0/−1
- stack.yaml.lock +0/−12
CHANGELOG.md view
@@ -6,6 +6,23 @@ and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/). +## 0.5.1.0 - 2026-07-02 + +* Fix a regression on unsupported operating systems. + +## 0.5.0.0 - 2026-06-22 + +* Fix a regression on Linux operating systems, whereby `xdg-open` would not + return until the browser was closed. +* Replace utility `openBrowserWithExitCode` with `openBrowserWithException`. + +## 0.4.0.0 - 2025-04-02 + +* On Unix-like operating systems, use Haskell to silence the opening + application or script, rather than the `sh` shell on Linux and BSD. +* Add utility `openBrowserWithExitCode`, to help with debugging failure. +* Improve Haddock documentation. + ## 0.3.0.1 - 2025-03-17 * On Windows, remove unnecessary dependency on `process`. @@ -31,8 +48,9 @@ * As released by rightfold on Hackage. This entry and prior change log is reconstructed. -* Support GHC versions before GHC 8.0. -* Add support for 32-bit Windows. +* Support GHC versions before GHC 8.0, by removing the Byte Order Mark from + source files. +* Add support for 32-bit Windows, by using the `stdcall` calling convention. ## 0.2.0.0 - 2015-07-31 @@ -40,11 +58,13 @@ ## 0.1.4.0 - 2015-07-30 -* On Linux, silence `xdg-open`. +* On Linux and BSD, silence the `xdg-open` script using the `sh` shell. ## 0.1.3.0 - 2015-07-27 -* Add support for BSD and Windows. +* Add support for BSD, using the `xdg-open` script. +* Add support for Windows, using the Win32 API and the `ccall` calling + convention. ## 0.1.2.0 - 2015-07-27 @@ -52,8 +72,9 @@ ## 0.1.1.0 - 2015-07-27 -* Add support for Linux. +* Add support for Linux, using the `xdg-open` script. +* On OS X, use the `open` application. ## 0.1.0.0 - 2015-07-25 -* Initial version. Only OS X supported. +* Initial version. Only OS X supported, using `open location` in an AppleScript.
example/Main.hs view
@@ -4,9 +4,27 @@ ( main ) where -import Web.Browser ( openBrowser ) +import Control.Exception ( Exception (..), SomeException ) +import Web.Browser ( openBrowser, openBrowserWithException ) main :: IO () -main = openBrowser "https://haskell.org/" >>= \case - True -> putStrLn "The operation succeeded!" - False -> putStrLn "The operation failed!" +main = do + openBrowser "https://haskell.org/" >>= \case + True -> putStrLn "The operation succeeded!" + False -> putStrLn "The operation failed!" + blankLine + putStrLn "Help with debugging:" + putStrLn "Try a good URL:" + tryOpenGoodUrl >>= reportResult + blankLine + putStrLn "Try a bad URL:" + tryOpenBadUrl >>= reportResult + where + tryOpenGoodUrl :: IO (Maybe SomeException) + tryOpenGoodUrl = openBrowserWithException "https://haskell.org/" + tryOpenBadUrl :: IO (Maybe SomeException) + tryOpenBadUrl = openBrowserWithException "example-bad-url" + reportResult = \case + Just e -> putStrLn $ "Exception: " <> displayException e + Nothing -> putStrLn "Nothing to report" + blankLine = putStrLn ""
lib/Web/Browser.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE LambdaCase #-} + {-| Module : Web.Browser Description : Open a web browser from Haskell @@ -11,14 +13,18 @@ module Web.Browser ( openBrowser + -- * Utilities + , openBrowserWithException ) where +import Control.Exception ( Exception (..), SomeException, try) +import Data.Maybe ( isNothing ) import qualified Web.Browser.OS as OS --- | Seeks to open the given item. If the item is a URL or another item --- associated with a web browser (for example, it represents a local @.html@ --- file), seeks to open it in the user's preferred web browser. Returns whether --- or not the operation succeeded. +-- | Seeks to open the given item, silently. If the item is a URL or another +-- item associated with a web browser (for example, it represents a local +-- @.html@ file), seeks to open it in the user's preferred web browser. Returns +-- whether or not the operation succeeded. -- -- No checks are performed on the nature or validity of the given item. -- @@ -31,13 +37,28 @@ -- item that represents a file, equivalent to double-clicking on the file's -- icon; and -- --- * on Linux, FreeBSD, OpenBSD or NetBSD, the \'xdg-open\' application, if it --- is on the user's PATH, via \'sh\' to allow the application's output to be --- silenced. +-- * on Linux, FreeBSD, OpenBSD or NetBSD, the \'xdg-open\' script, if it +-- is on the user's PATH. -- -- On other operating systems, the operation always fails. +-- +-- @since 0.1.0.0 openBrowser :: String - -- ^ URL or other item to try to open + -- ^ URL or other item to try to open. -> IO Bool -openBrowser = OS.openBrowser +openBrowser url = + isNothing <$> (openBrowserWithException url :: IO (Maybe SomeException)) + +-- | Exported to help with debugging. As for 'openBrowser' but returns 'Nothing' +-- or 'Just' an exception. +-- +-- @since 0.5.0.0 +openBrowserWithException :: + Exception e + => String + -- ^ URL or other item to try to open. + -> IO (Maybe e) +openBrowserWithException url = try (OS.openBrowser url) >>= \case + Left e -> pure $ Just e + Right () -> pure Nothing
− lib/unix-like/common/Utils.hs
@@ -1,20 +0,0 @@--------------------------------------------------------------------------------- --- For operating systems that use an application on the PATH to open the URL. --------------------------------------------------------------------------------- - -module Utils - ( openBrowserWith - ) where - -import System.Exit ( ExitCode (..) ) -import System.Process ( proc, waitForProcess, withCreateProcess ) - -openBrowserWith :: - String - -- ^ Name of relevant executable on the PATH. - -> [String] - -- ^ Arguments for executable. - -> IO Bool -openBrowserWith cmd args = - withCreateProcess (proc cmd args) $ \_ _ _ p -> - (== ExitSuccess) <$> waitForProcess p
lib/unix-like/open/Web/Browser/OS.hs view
@@ -7,11 +7,18 @@ ( openBrowser ) where -import Utils ( openBrowserWith ) +import Control.Monad ( void ) +import System.Process + ( CreateProcess (..), StdStream (..), createProcess, proc ) -- https://ss64.com/mac/open.html openBrowser :: String - -- ^ URL - -> IO Bool -openBrowser url = openBrowserWith "open" [url] + -- ^ URL or other item to try to open. + -> IO () +openBrowser url = void $ createProcess (proc "open" [url]) + { std_in = NoStream + , std_out = NoStream + , std_err = NoStream + , close_fds = True + }
lib/unix-like/xdg-open/Web/Browser/OS.hs view
@@ -1,31 +1,23 @@ -------------------------------------------------------------------------------- --- For Unix-like operating systems that provide the xdg-open application on the --- PATH. +-- For Unix-like operating systems that provide the xdg-open script on the PATH. -------------------------------------------------------------------------------- module Web.Browser.OS ( openBrowser ) where -import Utils ( openBrowserWith ) +import Control.Monad ( void ) +import System.Process + ( CreateProcess (..), StdStream (..), createProcess, proc ) -- https://ss64.com/bash/xdg-open.html openBrowser :: String - -- ^ URL - -> IO Bool -openBrowser url = - -- sh -c '...' - -- - -- tells the shell (sh) to execute the given string as a command, and - -- the following argument (url) is passed as a positional argument $0. - -- - -- xdg-open "$0" 2>&1 > /dev/null - -- - -- The $0 is expanded and the double quotes ensures it is treated as a single - -- argument to xdg-open. - -- - -- 2>&1 redirects standard error to standard output. - -- - -- > /dev/null discards standard output. - openBrowserWith "sh" ["-c", "xdg-open \"$0\" 2>&1 > /dev/null", url] + -- ^ URL or other item to try to open. + -> IO () +openBrowser url = void $ createProcess (proc "xdg-open" [url]) + { std_in = NoStream + , std_out = NoStream + , std_err = NoStream + , close_fds = True + }
lib/unsupported-os/Web/Browser/OS.hs view
@@ -8,6 +8,8 @@ openBrowser :: String - -- ^ URL - -> IO Bool -openBrowser = const (pure False) -- Operation never succeeds + -- ^ URL or other item to try to open. + -> IO () +openBrowser _ = + -- Operation never succeeds + error "openBrowser: Unsupported operating system."
lib/windows/Web/Browser/OS.hs view
@@ -11,8 +11,11 @@ ( openBrowser ) where -import System.Win32.Types - ( HANDLE, HINSTANCE, INT, LPCWSTR, handleToWord, nullPtr, withTString ) +import Control.Monad ( unless ) +import System.Win32.Types + ( HANDLE, HINSTANCE, INT, LPCWSTR, handleToWord, nullPtr + , withTString + ) type HWND = HANDLE @@ -26,14 +29,16 @@ openBrowser :: String - -- ^ URL - -> IO Bool -openBrowser url = - withTString "open" $ \openStr -> - withTString url $ \urlStr -> exitCodeToBool <$> + -- ^ URL or other item to try to open. + -> IO () +openBrowser url = do + hinst <- withTString "open" $ \openStr -> + withTString url $ \urlStr -> c_ShellExecute nullPtr openStr urlStr nullPtr nullPtr sW_SHOWNORMAL - where - exitCodeToBool hinst = handleToWord hinst > 32 + let exitcode = fromIntegral (handleToWord hinst) :: Int + unless (exitcode > 32) $ error $ + "openBrowser: ShellExecuteW \"open\" failed with exit code: " + <> show exitcode -- https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew foreign import ccall unsafe "windows.h ShellExecuteW"
open-browser.cabal view
@@ -1,86 +1,80 @@ cabal-version: 1.12 ---- This file has been generated from package.yaml by hpack version 0.38.0.------ see: https://github.com/sol/hpack--name: open-browser-version: 0.3.0.1-synopsis: Open a web browser from Haskell-description: Open a web browser from Haskell. Windows, macOS, Linux and BSD are supported.-category: Web-homepage: https://github.com/mpilgrem/open-browser-bug-reports: https://github.com/mpilgrem/open-browser/issues-author: rightfold-maintainer: public@pilgrem.com-license: BSD3-license-file: LICENSE-build-type: Simple-tested-with:- GHC >= 8.4-extra-source-files:- CHANGELOG.md- README.md- stack.yaml- stack.yaml.lock--source-repository head- type: git- location: https://github.com/mpilgrem/open-browser--flag example- description: Build the example application- manual: True- default: False--library- hs-source-dirs:- lib- exposed-modules:- Web.Browser- build-depends:- base ==4.*- default-language: Haskell2010- if os(windows)- other-modules:- Web.Browser.OS- hs-source-dirs:- lib/windows- build-depends:- Win32 <3- else- if os(darwin)- other-modules:- Utils- Web.Browser.OS- hs-source-dirs:- lib/unix-like/common- lib/unix-like/open- build-depends:- process >=1.4.3.0 && <2- else- if os(linux) || os(freebsd) || os(openbsd) || os(netbsd)- other-modules:- Utils- Web.Browser.OS- hs-source-dirs:- lib/unix-like/common- lib/unix-like/xdg-open- build-depends:- process >=1.4.3.0 && <2- else- other-modules:- Web.Browser.OS- hs-source-dirs:- lib/unsupported-os--executable open-browser-example- main-is: Main.hs- hs-source-dirs:- example- build-depends:- base ==4.*- , open-browser- default-language: Haskell2010- if !flag(example)- buildable: False+ +-- This file has been generated from package.yaml by hpack version 0.39.6. +-- +-- see: https://github.com/sol/hpack + +name: open-browser +version: 0.5.1.0 +synopsis: Open a web browser from Haskell +description: Open a web browser from Haskell. Windows, macOS, Linux and BSD are supported. +category: Web +homepage: https://github.com/mpilgrem/open-browser +bug-reports: https://github.com/mpilgrem/open-browser/issues +author: rightfold +maintainer: public@pilgrem.com +license: BSD3 +license-file: LICENSE +build-type: Simple +tested-with: + GHC >= 8.4 +extra-source-files: + CHANGELOG.md + README.md + +source-repository head + type: git + location: https://github.com/mpilgrem/open-browser + +flag example + description: Build the example application + manual: True + default: False + +library + hs-source-dirs: + lib + exposed-modules: + Web.Browser + build-depends: + base ==4.* + default-language: Haskell2010 + if os(windows) + other-modules: + Web.Browser.OS + hs-source-dirs: + lib/windows + build-depends: + Win32 <3 + else + if os(darwin) + other-modules: + Web.Browser.OS + hs-source-dirs: + lib/unix-like/open + build-depends: + process >=1.2.0.0 && <2 + else + if os(linux) || os(freebsd) || os(openbsd) || os(netbsd) + other-modules: + Web.Browser.OS + hs-source-dirs: + lib/unix-like/xdg-open + build-depends: + process >=1.2.0.0 && <2 + else + other-modules: + Web.Browser.OS + hs-source-dirs: + lib/unsupported-os + +executable open-browser-example + main-is: Main.hs + hs-source-dirs: + example + build-depends: + base ==4.* + , open-browser + default-language: Haskell2010 + if !flag(example) + buildable: False
− stack.yaml
@@ -1,1 +0,0 @@-snapshot: lts-23.14 # GHC 9.8.4
− stack.yaml.lock
@@ -1,12 +0,0 @@-# This file was autogenerated by Stack. -# You should not edit this file by hand. -# For more information, please see the documentation at: -# https://docs.haskellstack.org/en/stable/topics/lock_files - -packages: [] -snapshots: -- completed: - sha256: 1964d439d2a152be4238053f3f997a09fb348391984daab86d724975ef9a423f - size: 683814 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/14.yaml - original: lts-23.14