From reikdas at gmail.com Sat Dec 1 06:39:54 2018 From: reikdas at gmail.com (Pratyush Das) Date: Sat, 1 Dec 2018 12:09:54 +0530 Subject: [xmonad] Xmonad on Ubuntu 18.04 (GNOME) Message-ID: Hi, The wiki is not updated to include information about how to install Xmonad on Ubuntu Bionic Beaver - https://wiki.haskell.org/Xmonad/Using_xmonad_in_Gnome#Ubuntu Could you tell me how to make xmonad work with Ubuntu 18.04(Gnome3)? Regards, -- Pratyush Das(Reik) -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Sat Dec 1 15:23:57 2018 From: allbery.b at gmail.com (Brandon Allbery) Date: Sat, 1 Dec 2018 10:23:57 -0500 Subject: [xmonad] Xmonad on Ubuntu 18.04 (GNOME) In-Reply-To: References: Message-ID: The reason there are no updates is that the situation has not changed: there is no way to use a different window manager with Gnome > 3.6. Either you are using gnome-shell with its window manager plugin, or you are not running Gnome 3. On Sat, Dec 1, 2018 at 1:40 AM Pratyush Das wrote: > Hi, > > The wiki is not updated to include information about how to install Xmonad > on Ubuntu Bionic Beaver - > https://wiki.haskell.org/Xmonad/Using_xmonad_in_Gnome#Ubuntu > > Could you tell me how to make xmonad work with Ubuntu 18.04(Gnome3)? > > Regards, > > -- > Pratyush Das(Reik) > _______________________________________________ > xmonad mailing list > xmonad at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From sgf.dma at gmail.com Mon Dec 3 14:38:37 2018 From: sgf.dma at gmail.com (Dmitriy Matrosov) Date: Mon, 03 Dec 2018 17:38:37 +0300 Subject: [xmonad] Suspend Keybinding Temporarily In-Reply-To: References: <5ED9B6B4-6E9C-4045-BE93-CB98D9EE4E0C@gmail.com> <0d1ef995-1664-029d-8f53-bdacd74f7e48@gmail.com> <59885eaa-ebc7-c0c7-0d4c-96accd12aa38@gmail.com> Message-ID: <0FA5013E-04E8-4932-982C-60FDA0D421AB@gmail.com> On November 30, 2018 11:18:51 PM GMT+03:00, Brandon Allbery wrote: >Er. What version of ghc? That sounds like either a ghc runtime bug, or >a >system configuration issue. In particular, xmonad creates no threads >itself, so that would be the ghc runtime's IO manager thread. That reminds me, that i've compiled my xmonad build with `-threaded - with-rtsopts=-N`. I've tried without these options and for now it seems stable. May that be the case? Ghc versions are different: this error happens to me with different stack snapshots from time to time more than year already. >On Fri, Nov 30, 2018 at 3:07 PM Dmitriy Matrosov >wrote: > >> On 11/30/2018 12:11 AM, Brandon Allbery wrote: >> > Yes. More specifically, it's ultimately using the execve() >syscall, via >> > one of the wrappers which propagates the environment (which one >depends >> > on whether it's asked to do $PATH search or not). >> >> So.. here is version using environment: >> >> import XMonad >> import XMonad.Operations >> import XMonad.Util.EZConfig >> >> import System.Environment >> import Control.Exception >> >> main :: IO () >> main = do >> let xcf = def >> { modMask = mod4Mask >> , handleExtraArgs = disableKeysE >> } >> `additionalKeys` >> [ ((mod4Mask, xK_d), disableKeysOn) ] >> xmonad xcf >> >> disableKeysOn :: X () >> disableKeysOn = do >> trace "Preparing to disable keys and restarting.." >> io $ setEnv "XMONAD_DISABLE_KEYS" "1" >> restart "xmonad" True >> >> disableKeysE :: [String] -> XConfig Layout -> IO (XConfig >Layout) >> disableKeysE _ xcf = do >> me <- lookupEnv "XMONAD_DISABLE_KEYS" >> case me of >> Just _ -> do >> trace "Disabling all keys." >> unsetEnv "XMONAD_DISABLE_KEYS" >> return (xcf {keys = \_ -> mempty}) >> Nothing -> return xcf >> >> It also restarts xmonad on key press (when disabling keys) and all >> works fine, but.. xmonad frequently crashes with >> >> xmonad: failed to create OS thread: Resource temporarily >> unavailable >> >> I don't think this crash relates somehow to using environment, and it >> happened from time to time before too, but still.. Can you advise, >> how to fix it? >> >> > On Thu, Nov 29, 2018 at 4:07 PM Dmitriy Matrosov >> > > wrote: >> > >> > On 11/29/2018 09:50 PM, Brandon Allbery wrote: >> > > You were talking about restart, between the running xmonad >and >> its >> > > replacement via executeFile. There, you can use the >environment. >> > There >> > > is no way to pass information between an invoked "xmonad >> > --restart" and >> > > the running xmonad. >> > >> > You mean, `executeFile` preserves environment? So, i may >change >> it from >> > running xmonad (by e.g. keybinding) and then restart it? >> > >> > > On Thu, Nov 29, 2018 at 6:01 AM Dmitriy Matrosov >> > >> > > >> >wrote: >> > > >> > > >> > > >> > > On November 28, 2018 9:25:00 PM GMT+03:00, Brandon >Allbery >> > > >> > >> >wrote: >> > > >Not by default; there's already a bug ( >> > > >https://github.com/xmonad/xmonad/issues/78) about our >not >> > obeying the >> > > >ICCCM >> > > >replace protocol unless started by replacing some >other WM. >> > > > >> > > >There's a few other places you can hide extra >parameters; >> > starting >> > > that >> > > >early, the environment is probably the easiest to >use, >> provided >> > > they're >> > > >not >> > > >too large (see why there's a state file now). >> > > >> > > Hm, i don't understand how to use environment. I need >to pass >> > > something to running xmonad process (to which i send >> > > XMONAD_RESTART). As far as i know, i can't change >> environment of >> > > another process.. >> > > >> > > >> > > >On Wed, Nov 28, 2018 at 1:20 PM Dmitriy Matrosov >> > > >> > >> >> > > >wrote: >> > > > >> > > >> Hi. >> > > >> >> > > >> On 11/21/2018 09:49 PM, Eyal Erez wrote: >> > > >> > Hi, >> > > >> > >> > > >> > I'm getting some collisions between my xmonad >> > keybindings and an >> > > >> > application I'm running (it's a game that is >suppose to >> > run full >> > > >screen >> > > >> > but in reality just uses a large window). I was >> > wondering if I >> > > >could >> > > >> > suspend or change some keybindings from a script >that I >> > can run >> > > >before >> > > >> > the app launches and then restore later. >> > > >> > >> > > >> > Is this at all possible? Happy to entertain >other >> options. >> > > >> >> > > >> Here is proof of concept: >> > > >> >> > > >> >> > > >> import XMonad >> > > >> import XMonad.Hooks.EwmhDesktops >> > > >> >> > > >> import System.Directory >> > > >> import System.FilePath >> > > >> >> > > >> >> > > >> main :: IO () >> > > >> main = do >> > > >> let xcf = ewmh $ def >> > > >> { modMask = mod4Mask >> > > >> , handleExtraArgs = >> disableKeys >> > > >> } >> > > >> xmonad xcf >> > > >> >> > > >> disableKeys :: [String] -> XConfig Layout >-> IO >> > (XConfig >> > > >Layout) >> > > >> disableKeys _ xcf = do >> > > >> xd <- getXMonadDir >> > > >> let disableFn = xd "disable_keys" >> > > >> b <- doesFileExist disableFn >> > > >> if b >> > > >> then do >> > > >> trace "Disabling all keys." >> > > >> removeFile disableFn >> > > >> return (xcf {keys = \_ -> mempty}) >> > > >> else return xcf >> > > >> >> > > >> >> > > >> To disable all keys create file >`~/.xmonad/disable_keys` >> > and then >> > > >> restart xmonad with `xmonad --restart`. All keys >will be >> > disabled >> > > >> _and_ file deleted (to avoid locking yourself), >thus next >> > restart >> > > >will >> > > >> restore all keys back. >> > > >> >> > > >> As far as i understand, xmonad grabs keys in >> > `X.Main.launch` before >> > > >> entering main loop. Thus, the one way to change key >grab >> > is to >> > > >restart >> > > >> xmonad. I need to modify `XConfig` before calling >> > > X.Main.launch`, and >> > > >> this may be done by `handleExtraArgs` (called in >> `launch'` in >> > > >> `X.Main.xmonad`). Unfortunately, it seems, that >xmonad >> > does not >> > > allow >> > > >> to pass extra cmd arguments during restart >> > (`X.Operations.restart` >> > > >> always starts xmonad with name `xmonad` and no >> > arguments). Also, i >> > > >> can't use extensible state in `handleExtraArgs`, >because >> > it runs in >> > > >> `IO` (`X` context is not yet built at that time). >Thus, >> > to pass >> > > >> something to it, i may use either file or >(probably) >> > > `--replace`. The >> > > >> above version uses file. And i have no luck with >> > `--replace`: it >> > > >> seems, `xmonad` can't replace itself?.. >> > > >> _______________________________________________ >> > > >> xmonad mailing list >> > > >> xmonad at haskell.org >> > > >> > > >> >http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad >> > > >> >> > > _______________________________________________ >> > > xmonad mailing list >> > > xmonad at haskell.org >> > > >> > > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad >> > > >> > > >> > > >> > > -- >> > > brandon s allbery kf8nh >> > > allbery.b at gmail.com >> > > >> > >> > _______________________________________________ >> > xmonad mailing list >> > xmonad at haskell.org >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad >> > >> > >> > >> > -- >> > brandon s allbery kf8nh >> > allbery.b at gmail.com >> >> From allbery.b at gmail.com Mon Dec 3 18:55:33 2018 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 3 Dec 2018 13:55:33 -0500 Subject: [xmonad] Suspend Keybinding Temporarily In-Reply-To: <0FA5013E-04E8-4932-982C-60FDA0D421AB@gmail.com> References: <5ED9B6B4-6E9C-4045-BE93-CB98D9EE4E0C@gmail.com> <0d1ef995-1664-029d-8f53-bdacd74f7e48@gmail.com> <59885eaa-ebc7-c0c7-0d4c-96accd12aa38@gmail.com> <0FA5013E-04E8-4932-982C-60FDA0D421AB@gmail.com> Message-ID: Threaded builds would run a certain risk of confusing X11 under some circumstances (specifically, if you tried to use the existing server connection in a thread, you could see X11 protocol errors). They shouldn't produce that error. On Mon, Dec 3, 2018 at 9:38 AM Dmitriy Matrosov wrote: > > > On November 30, 2018 11:18:51 PM GMT+03:00, Brandon Allbery < > allbery.b at gmail.com> wrote: > >Er. What version of ghc? That sounds like either a ghc runtime bug, or > >a > >system configuration issue. In particular, xmonad creates no threads > >itself, so that would be the ghc runtime's IO manager thread. > > That reminds me, that i've compiled my xmonad build with `-threaded - > with-rtsopts=-N`. I've tried without these options and for now it seems > stable. May that be the case? > > Ghc versions are different: this error happens to me with different stack > snapshots from time to time more than year already. > > >On Fri, Nov 30, 2018 at 3:07 PM Dmitriy Matrosov > >wrote: > > > >> On 11/30/2018 12:11 AM, Brandon Allbery wrote: > >> > Yes. More specifically, it's ultimately using the execve() > >syscall, via > >> > one of the wrappers which propagates the environment (which one > >depends > >> > on whether it's asked to do $PATH search or not). > >> > >> So.. here is version using environment: > >> > >> import XMonad > >> import XMonad.Operations > >> import XMonad.Util.EZConfig > >> > >> import System.Environment > >> import Control.Exception > >> > >> main :: IO () > >> main = do > >> let xcf = def > >> { modMask = mod4Mask > >> , handleExtraArgs = disableKeysE > >> } > >> `additionalKeys` > >> [ ((mod4Mask, xK_d), disableKeysOn) ] > >> xmonad xcf > >> > >> disableKeysOn :: X () > >> disableKeysOn = do > >> trace "Preparing to disable keys and restarting.." > >> io $ setEnv "XMONAD_DISABLE_KEYS" "1" > >> restart "xmonad" True > >> > >> disableKeysE :: [String] -> XConfig Layout -> IO (XConfig > >Layout) > >> disableKeysE _ xcf = do > >> me <- lookupEnv "XMONAD_DISABLE_KEYS" > >> case me of > >> Just _ -> do > >> trace "Disabling all keys." > >> unsetEnv "XMONAD_DISABLE_KEYS" > >> return (xcf {keys = \_ -> mempty}) > >> Nothing -> return xcf > >> > >> It also restarts xmonad on key press (when disabling keys) and all > >> works fine, but.. xmonad frequently crashes with > >> > >> xmonad: failed to create OS thread: Resource temporarily > >> unavailable > >> > >> I don't think this crash relates somehow to using environment, and it > >> happened from time to time before too, but still.. Can you advise, > >> how to fix it? > >> > >> > On Thu, Nov 29, 2018 at 4:07 PM Dmitriy Matrosov > > >> > > wrote: > >> > > >> > On 11/29/2018 09:50 PM, Brandon Allbery wrote: > >> > > You were talking about restart, between the running xmonad > >and > >> its > >> > > replacement via executeFile. There, you can use the > >environment. > >> > There > >> > > is no way to pass information between an invoked "xmonad > >> > --restart" and > >> > > the running xmonad. > >> > > >> > You mean, `executeFile` preserves environment? So, i may > >change > >> it from > >> > running xmonad (by e.g. keybinding) and then restart it? > >> > > >> > > On Thu, Nov 29, 2018 at 6:01 AM Dmitriy Matrosov > >> > > >> > > >> > >wrote: > >> > > > >> > > > >> > > > >> > > On November 28, 2018 9:25:00 PM GMT+03:00, Brandon > >Allbery > >> > > > >> > >> > >wrote: > >> > > >Not by default; there's already a bug ( > >> > > >https://github.com/xmonad/xmonad/issues/78) about our > >not > >> > obeying the > >> > > >ICCCM > >> > > >replace protocol unless started by replacing some > >other WM. > >> > > > > >> > > >There's a few other places you can hide extra > >parameters; > >> > starting > >> > > that > >> > > >early, the environment is probably the easiest to > >use, > >> provided > >> > > they're > >> > > >not > >> > > >too large (see why there's a state file now). > >> > > > >> > > Hm, i don't understand how to use environment. I need > >to pass > >> > > something to running xmonad process (to which i send > >> > > XMONAD_RESTART). As far as i know, i can't change > >> environment of > >> > > another process.. > >> > > > >> > > > >> > > >On Wed, Nov 28, 2018 at 1:20 PM Dmitriy Matrosov > >> > > > >> > >> > >> > > >wrote: > >> > > > > >> > > >> Hi. > >> > > >> > >> > > >> On 11/21/2018 09:49 PM, Eyal Erez wrote: > >> > > >> > Hi, > >> > > >> > > >> > > >> > I'm getting some collisions between my xmonad > >> > keybindings and an > >> > > >> > application I'm running (it's a game that is > >suppose to > >> > run full > >> > > >screen > >> > > >> > but in reality just uses a large window). I was > >> > wondering if I > >> > > >could > >> > > >> > suspend or change some keybindings from a script > >that I > >> > can run > >> > > >before > >> > > >> > the app launches and then restore later. > >> > > >> > > >> > > >> > Is this at all possible? Happy to entertain > >other > >> options. > >> > > >> > >> > > >> Here is proof of concept: > >> > > >> > >> > > >> > >> > > >> import XMonad > >> > > >> import XMonad.Hooks.EwmhDesktops > >> > > >> > >> > > >> import System.Directory > >> > > >> import System.FilePath > >> > > >> > >> > > >> > >> > > >> main :: IO () > >> > > >> main = do > >> > > >> let xcf = ewmh $ def > >> > > >> { modMask = mod4Mask > >> > > >> , handleExtraArgs = > >> disableKeys > >> > > >> } > >> > > >> xmonad xcf > >> > > >> > >> > > >> disableKeys :: [String] -> XConfig Layout > >-> IO > >> > (XConfig > >> > > >Layout) > >> > > >> disableKeys _ xcf = do > >> > > >> xd <- getXMonadDir > >> > > >> let disableFn = xd "disable_keys" > >> > > >> b <- doesFileExist disableFn > >> > > >> if b > >> > > >> then do > >> > > >> trace "Disabling all keys." > >> > > >> removeFile disableFn > >> > > >> return (xcf {keys = \_ -> mempty}) > >> > > >> else return xcf > >> > > >> > >> > > >> > >> > > >> To disable all keys create file > >`~/.xmonad/disable_keys` > >> > and then > >> > > >> restart xmonad with `xmonad --restart`. All keys > >will be > >> > disabled > >> > > >> _and_ file deleted (to avoid locking yourself), > >thus next > >> > restart > >> > > >will > >> > > >> restore all keys back. > >> > > >> > >> > > >> As far as i understand, xmonad grabs keys in > >> > `X.Main.launch` before > >> > > >> entering main loop. Thus, the one way to change key > >grab > >> > is to > >> > > >restart > >> > > >> xmonad. I need to modify `XConfig` before calling > >> > > X.Main.launch`, and > >> > > >> this may be done by `handleExtraArgs` (called in > >> `launch'` in > >> > > >> `X.Main.xmonad`). Unfortunately, it seems, that > >xmonad > >> > does not > >> > > allow > >> > > >> to pass extra cmd arguments during restart > >> > (`X.Operations.restart` > >> > > >> always starts xmonad with name `xmonad` and no > >> > arguments). Also, i > >> > > >> can't use extensible state in `handleExtraArgs`, > >because > >> > it runs in > >> > > >> `IO` (`X` context is not yet built at that time). > >Thus, > >> > to pass > >> > > >> something to it, i may use either file or > >(probably) > >> > > `--replace`. The > >> > > >> above version uses file. And i have no luck with > >> > `--replace`: it > >> > > >> seems, `xmonad` can't replace itself?.. > >> > > >> _______________________________________________ > >> > > >> xmonad mailing list > >> > > >> xmonad at haskell.org > >> > > > >> > > >> > >http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > >> > > >> > >> > > _______________________________________________ > >> > > xmonad mailing list > >> > > xmonad at haskell.org > >> > > > >> > > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > >> > > > >> > > > >> > > > >> > > -- > >> > > brandon s allbery kf8nh > >> > > allbery.b at gmail.com > >> > > > >> > > >> > _______________________________________________ > >> > xmonad mailing list > >> > xmonad at haskell.org > >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > >> > > >> > > >> > > >> > -- > >> > brandon s allbery kf8nh > >> > allbery.b at gmail.com > >> > >> > _______________________________________________ > xmonad mailing list > xmonad at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From tofgarion+xmonad at runbox.com Thu Dec 13 11:17:24 2018 From: tofgarion+xmonad at runbox.com (Christophe Garion) Date: Thu, 13 Dec 2018 12:17:24 +0100 Subject: [xmonad] Changing workspaces on both physical screens Message-ID: <87y38tptff.fsf@port-garion.isae.fr> Hello, I am using xmonad on my Linux laptop and pdfpc (https://pdfpc.github.io/) for presentation. pdfpc uses two windows, one with current slide, next slides, notes etc. and the other one with the presentation only. I usually use workspace 8 on my laptop with the window with notes and workspace 9 on the projector with the presentation window. I sometimes switch workspaces to show code snippets in emacs etc. and I want to be able to quickly restore the "pdfpc" workspaces. I use the following binding: ((modMask .|. shiftMask , xK_p), (do windows (W.view "9"); swapNextScreen; windows (W.view "8"))) which may not be the most elegant solution :) Is there a more "haskell" way to do the same thing? Best, Christophe -- Christophe Garion GPG: 1982 15B2 64AC 3C34 532D BF19 6CD6 246C 62DA 5A7F From byorgey at gmail.com Sat Dec 15 20:22:27 2018 From: byorgey at gmail.com (Brent Yorgey) Date: Sat, 15 Dec 2018 14:22:27 -0600 Subject: [xmonad] Changing workspaces on both physical screens In-Reply-To: <87y38tptff.fsf@port-garion.isae.fr> References: <87y38tptff.fsf@port-garion.isae.fr> Message-ID: This looks fine to me. If you want something a bit more general you could try using http://hackage.haskell.org/package/xmonad-contrib-0.15/docs/XMonad-Actions-DynamicWorkspaceGroups.html which lets you set up named groups of workspaces so you can quickly switch to them. It is designed to let you do this *dynamically* but there's no reason you couldn't create a "static" group in your startupHook. -Brent On Thu, Dec 13, 2018 at 5:17 AM Christophe Garion < tofgarion+xmonad at runbox.com> wrote: > Hello, > > I am using xmonad on my Linux laptop and pdfpc > (https://pdfpc.github.io/) for presentation. pdfpc uses two windows, one > with current slide, next slides, notes etc. and the other one with the > presentation only. I usually use workspace 8 on my laptop with the > window with notes and workspace 9 on the projector with the presentation > window. > > I sometimes switch workspaces to show code snippets in emacs etc. and I > want to be able to quickly restore the "pdfpc" workspaces. I use the > following binding: > > ((modMask .|. shiftMask , xK_p), (do windows (W.view "9"); > swapNextScreen; > windows (W.view "8"))) > > which may not be the most elegant solution :) > > Is there a more "haskell" way to do the same thing? > > Best, > > Christophe > > -- > Christophe Garion > GPG: 1982 15B2 64AC 3C34 532D BF19 6CD6 246C 62DA 5A7F > _______________________________________________ > xmonad mailing list > xmonad at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/xmonad > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tofgarion+xmonad at runbox.com Sun Dec 16 15:24:10 2018 From: tofgarion+xmonad at runbox.com (Christophe Garion) Date: Sun, 16 Dec 2018 16:24:10 +0100 Subject: [xmonad] Changing workspaces on both physical screens In-Reply-To: References: <87y38tptff.fsf@port-garion.isae.fr> Message-ID: <87k1k9336t.fsf@port-garion.isae.fr> On Sat, Dec 15 2018 at 09:22:27 PM, Brent Yorgey wrote: > This looks fine to me. If you want something a bit more general you could > try using > > http://hackage.haskell.org/package/xmonad-contrib-0.15/docs/XMonad-Actions-DynamicWorkspaceGroups.html > > > which lets you set up named groups of workspaces so you can quickly switch > to them. It is designed to let you do this *dynamically* but there's no > reason you couldn't create a "static" group in your startupHook. Yes, that's a good idea! Thanks, Christophe -- Christophe Garion GPG: 1982 15B2 64AC 3C34 532D BF19 6CD6 246C 62DA 5A7F From blak3mill3r at gmail.com Mon Dec 31 03:07:35 2018 From: blak3mill3r at gmail.com (Blake Miller) Date: Mon, 31 Dec 2018 03:07:35 +0000 Subject: [xmonad] New virtual X mouse tool Message-ID: This is only indirectly related to XMonad... For a while I've been using keynav to avoid reaching for the mouse for those few annoying circumstances which seemingly require a mouse. I did find that keynav sometimes saved me some energy, but I only found it useful for simple clicks. It does not seem useful if you want to click and drag a region, for example. Repeatedly bisecting the screen to narrow in on a point for the cursor is a fine approach and has some advantages, but I found myself wanting something more visceral: a little physics simulation to let me move the mouse around using the keyboard, like a video game. So I put this little utility together, in C++, and I have a keybinding spawn it from xmonad. It was an interesting challenge to make it single-threaded and still simultaneously run the physics loop, poll for X events, and send fake mouse events with XTest. I ended up designing it around channels (as in CSP) using boost::fiber. I hope someone finds it useful or entertaining! I had fun writing it. https://github.com/blak3mill3r/mouser -------------- next part -------------- An HTML attachment was scrubbed... URL: