{-# LANGUAGE CPP #-}
module XMonad.Util.XSelection (
getSelection,
promptSelection,
safePromptSelection,
transformPromptSelection,
transformSafePromptSelection) where
import Control.Exception as E (catch,SomeException(..))
import XMonad
import XMonad.Util.Run (safeSpawn, unsafeSpawn)
import Codec.Binary.UTF8.String (decode)
getSelection :: MonadIO m => m String
getSelection :: forall (m :: * -> *). MonadIO m => m String
getSelection = forall (m :: * -> *) a. MonadIO m => IO a -> m a
io forall a b. (a -> b) -> a -> b
$ do
Display
dpy <- String -> IO Display
openDisplay String
""
let dflt :: Dimension
dflt = Display -> Dimension
defaultScreen Display
dpy
Pixel
rootw <- Display -> Dimension -> IO Pixel
rootWindow Display
dpy Dimension
dflt
Pixel
win <- Display
-> Pixel
-> Position
-> Position
-> Dimension
-> Dimension
-> CInt
-> Pixel
-> Pixel
-> IO Pixel
createSimpleWindow Display
dpy Pixel
rootw Position
0 Position
0 Dimension
1 Dimension
1 CInt
0 Pixel
0 Pixel
0
Pixel
p <- Display -> String -> Bool -> IO Pixel
internAtom Display
dpy String
"PRIMARY" Bool
True
Pixel
ty <- forall e a. Exception e => IO a -> (e -> IO a) -> IO a
E.catch
(forall e a. Exception e => IO a -> (e -> IO a) -> IO a
E.catch
(Display -> String -> Bool -> IO Pixel
internAtom Display
dpy String
"UTF8_STRING" Bool
False)
(\(E.SomeException e
_) -> Display -> String -> Bool -> IO Pixel
internAtom Display
dpy String
"COMPOUND_TEXT" Bool
False))
(\(E.SomeException e
_) -> Display -> String -> Bool -> IO Pixel
internAtom Display
dpy String
"sTring" Bool
False)
Pixel
clp <- Display -> String -> Bool -> IO Pixel
internAtom Display
dpy String
"BLITZ_SEL_STRING" Bool
False
Display -> Pixel -> Pixel -> Pixel -> Pixel -> Pixel -> IO ()
xConvertSelection Display
dpy Pixel
p Pixel
ty Pixel
clp Pixel
win Pixel
currentTime
forall a. (XEventPtr -> IO a) -> IO a
allocaXEvent forall a b. (a -> b) -> a -> b
$ \XEventPtr
e -> do
Display -> XEventPtr -> IO ()
nextEvent Display
dpy XEventPtr
e
Event
ev <- XEventPtr -> IO Event
getEvent XEventPtr
e
String
result <- if Event -> Dimension
ev_event_type Event
ev forall a. Eq a => a -> a -> Bool
== Dimension
selectionNotify
then do Maybe [CChar]
res <- Display -> Pixel -> Pixel -> IO (Maybe [CChar])
getWindowProperty8 Display
dpy Pixel
clp Pixel
win
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Word8] -> String
decode forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (Integral a, Num b) => a -> b
fromIntegral) forall a b. (a -> b) -> a -> b
$ Maybe [CChar]
res
else Display -> Pixel -> IO ()
destroyWindow Display
dpy Pixel
win forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return String
""
Display -> IO ()
closeDisplay Display
dpy
forall (m :: * -> *) a. Monad m => a -> m a
return String
result
promptSelection, safePromptSelection, unsafePromptSelection :: String -> X ()
promptSelection :: String -> X ()
promptSelection = String -> X ()
unsafePromptSelection
safePromptSelection :: String -> X ()
safePromptSelection String
app = forall (m :: * -> *). MonadIO m => String -> [String] -> m ()
safeSpawn String
app forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Monad m => a -> m a
return forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *). MonadIO m => m String
getSelection
unsafePromptSelection :: String -> X ()
unsafePromptSelection String
app = forall (m :: * -> *). MonadIO m => String -> m ()
unsafeSpawn forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\String
x -> String
app forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ String
x) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *). MonadIO m => m String
getSelection
transformPromptSelection, transformSafePromptSelection :: (String -> String) -> String -> X ()
transformPromptSelection :: (String -> String) -> String -> X ()
transformPromptSelection String -> String
f String
app = (forall (m :: * -> *). MonadIO m => String -> [String] -> m ()
safeSpawn String
app forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
f) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *). MonadIO m => m String
getSelection
transformSafePromptSelection :: (String -> String) -> String -> X ()
transformSafePromptSelection String -> String
f String
app = forall (m :: * -> *). MonadIO m => String -> m ()
unsafeSpawn forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\String
x -> String
app forall a. [a] -> [a] -> [a]
++ String
" " forall a. [a] -> [a] -> [a]
++ String
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
f forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *). MonadIO m => m String
getSelection