packages feed

greenclip 2.0.0 → 2.0.1

raw patch · 4 files changed

+140/−15 lines, 4 filesdep +X11dep +unixdep +utf8-stringdep −Clipboard

Dependencies added: X11, unix, utf8-string

Dependencies removed: Clipboard

Files

README.md view
@@ -7,21 +7,22 @@ Recyle your clipboard selections with greenclip and don't waste your time anymore to reselect things other and other. -**Purpose :**+**Purpose:** Keeps track of your history of selections to quickly switch between them -**Demo :** -<video controls>-  <source src="https://github.com/erebe/greenclip/releases/download/1.1/demo.webm" type="video/webm">- <a href="https://www.youtube.com/watch?v=Utk-9Gy8H3w">Video Link</a>-</video>+**Demo:**  <a href="https://www.youtube.com/watch?v=Utk-9Gy8H3w">Video Link</a> -**Installation :**+**Features:**+  + Integrated with [rofi](https://github.com/DaveDavenport/rofi)+  + Permanently set some selections to added at the end (set `staticHistoryPath = your/file/with/static/entries` in the config file)+  + Merge X Primary selection with clipboard selection (set `usePrimarySelectionAsInput = True` in the config file) -1. It's a static binary so drop it anywhere in your $PATH env +**Installation:** -```wget https://github.com/erebe/greenclip/releases/download/1.3/greenclip```+1. It's a static binary so drop it anywhere in your $PATH env +```wget https://github.com/erebe/greenclip/releases/download/2.0/greenclip```+ Alternatively if you are using Archlinux you can install the package from AUR  ``pacman -S greenclip``@@ -29,7 +30,7 @@ PS: If you want, you can add a permanent list of selections to be added to your current history. Go see the config file  -**Usage :**+**Usage:**  Greenclip is intended to be used with [rofi](https://github.com/DaveDavenport/rofi) @@ -38,7 +39,7 @@ 3. The entry that you have selected will be in your clipboard now 4. Configuration file can be found in ```.config/greenclip.cfg``` -**Compilation :**+**Compilation:**  1. Get [stack](https://docs.haskellstack.org/en/stable/README/) for Haskell 2. stack init && stack install
greenclip.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           greenclip-version:        2.0.0+version:        2.0.1 synopsis:       Simple clipboard manager to be integrated with rofi description:    Please see README.md category:       Linux Desktop@@ -27,11 +27,16 @@   build-depends:       base >= 4.7 && < 5     , classy-prelude-    , Clipboard     , text     , vector     , binary     , microlens     , microlens-mtl     , directory+    , X11 >= 1.6+    , utf8-string+    , unix+    , directory+  other-modules:+      Clipboard   default-language: Haskell2010
+ src/Clipboard.hs view
@@ -0,0 +1,119 @@+{-# LANGUAGE RecordWildCards #-}++module Clipboard+  ( getClipboardString+  , setClipboardString+  , getPrimaryClipboard+  ) where++import Graphics.X11.Xlib+import Graphics.X11.Xlib.Extras+import System.Posix.Process     (forkProcess)++import Codec.Binary.UTF8.String (decode, encode)+import Control.Monad+import Data.Maybe+import Foreign                  (peekByteOff)+import Foreign.C.Types          (CChar, CUChar)+import Foreign.Marshal.Array    (withArrayLen)+import System.Directory         (setCurrentDirectory)+import System.IO                (hClose, stderr, stdin, stdout)+import System.IO.Unsafe (unsafePerformIO)+import Data.IORef+import Control.Concurrent (threadDelay)++getClipboardString :: IO (Maybe String)+getClipboardString = do+    (display, window, clipboards) <- readIORef initialSetup+    inp <- internAtom display "clipboard_get" False+    target <- internAtom display "UTF8_STRING" True+    xConvertSelection display (head clipboards) target inp window currentTime+    Just <$> clipboardInputWait display window inp++getPrimaryClipboard :: IO (Maybe String)+getPrimaryClipboard = do+    (display, window, clipboards) <- readIORef initialSetup+    inp <- internAtom display "clipboard_get" False+    target <- internAtom display "UTF8_STRING" True+    xConvertSelection display (clipboards !! 1) target inp window currentTime+    Just <$> clipboardInputWait display window inp++clipboardInputWait :: Display -> Window -> Atom -> IO String+clipboardInputWait display' window' inp' = allocaXEvent (go display' window' inp')+  where+  go display window inp evPtr = do+    waitForEvent display+    nextEvent display evPtr+    ev <- getEvent evPtr+    if ev_event_type ev == selectionNotify+       then charsToString . fromMaybe mempty <$> getWindowProperty8 display inp window+       else go display window inp evPtr+  waitForEvent display = do+    nbEvs <- pending display+    when (nbEvs == 0) $ threadDelay 100000 >> waitForEvent display++charsToString :: [CChar] -> String+charsToString = decode . map fromIntegral++setClipboardString :: String -> IO ()+setClipboardString str = void $ forkProcess $ do+        mapM_ hClose [stdin, stdout, stderr]+        setCurrentDirectory "/"+        (display, window, clipboards) <- readIORef initialSetup+        mapM_ (\atom -> xSetSelectionOwner display atom window currentTime) clipboards+        advertiseSelection display clipboards (stringToChars str)+        cleanup display window++advertiseSelection :: Display -> [Atom] -> [CUChar] -> IO ()+advertiseSelection display clipboards' str = allocaXEvent (go clipboards')+  where+    go [] _ = return ()+    go clipboards evPtr = do+      nextEvent display evPtr+      ev <- getEvent evPtr+      case ev of+          SelectionRequest {..} -> do+              target' <- getAtomName display ev_target+              res <- handleOutput display ev_requestor ev_property target' str+              sendSelectionNotify display ev_requestor ev_selection ev_target res ev_time+              go clipboards evPtr++          _ | ev_event_type ev == selectionClear -> do+              target <- peekByteOff evPtr 40 :: IO Atom+              go (filter (/= target) clipboards) evPtr++          _ -> go clipboards evPtr++handleOutput :: Display -> Window -> Atom -> Maybe String -> [CUChar] -> IO Atom+handleOutput display req prop (Just "UTF8_STRING") str = do+    prop' <- getAtomName display prop+    if isNothing prop' then handleOutput display req prop Nothing str else do+        target <- internAtom display "UTF8_STRING" True+        void $ withArrayLen str $ \len str' ->+            xChangeProperty display req prop target 8 propModeReplace str'+                            (fromIntegral len)+        return prop+handleOutput _ _ _ _ _ = return none++sendSelectionNotify :: Display -> Window -> Atom -> Atom -> Atom -> Time -> IO ()+sendSelectionNotify display req sel target prop time = allocaXEvent $ \ev -> do+    setEventType ev selectionNotify+    setSelectionNotify ev req sel target prop time+    sendEvent display req False 0 ev++stringToChars :: String -> [CUChar]+stringToChars = map fromIntegral . encode++initialSetup :: IORef (Display, Window, [Atom])+initialSetup = unsafePerformIO $ do+    display <- openDisplay ""+    window <- createSimpleWindow display (defaultRootWindow display)+                                 0 0 1 1 0 0 0+    clipboards <- internAtom display "CLIPBOARD" False+    newIORef (display, window, [clipboards, pRIMARY])+{-# NOINLINE initialSetup #-}++cleanup :: Display -> Window -> IO ()+cleanup display window = do+    destroyWindow display window+    closeDisplay display
src/Main.hs view
@@ -14,7 +14,7 @@ import qualified Data.Vector        as V import           Lens.Micro import           Lens.Micro.Mtl-import qualified System.Clipboard   as Clip+import qualified Clipboard   as Clip import qualified System.Directory   as Dir import           System.Environment (lookupEnv) import           System.IO          (IOMode (..), openFile)@@ -153,7 +153,7 @@     -- Should rename COPY into ADVERTISE but as greenclip is already used I don't want to break configs     -- of other people     COPY sel -> advertiseSelection sel-    HELP     -> putStrLn $ "greenclip v1.3 -- Recyle your clipboard selections\n\n" <>+    HELP     -> putStrLn $ "greenclip v2.0 -- Recyle your clipboard selections\n\n" <>                            "Available commands\n" <>                            "daemon: Spawn the daemon that will listen to selections\n" <>                            "print:  Display all selections history\n" <>