fudgets-0.18.3: hsrc/containers/SelectionF.hs
module SelectionF where
import FudUTF8(decodeUTF8,encodeUTF8)
import Command
import CompOps((>=^<), (>^=<))
import Cont(conts,cmdContK')
import Shells(unmappedShellF)
import Event
import Fudget
import FRequest
import Xcommand
import GetWindowProperty
import InternAtom
--import Message(Message(..))
import NullF
import LayoutF(nullLF)
import Spops(putSP,getSP)
import Loops(loopThroughRightF)
import EitherUtils(stripEither)
import SerCompF(absF)
import Xtypes
{-
Supports cut/paste of UTF-8 encoded Unicode Strings.
Cut/paste of Unicode strings between two fudgets program works.
Cut/paste between a fudget program and xterm -u8 from XFree86 4.0 works.
/TH 2000-04-02
-}
data SelCmd a = Sel a | ClearSel | PasteSel deriving (Eq, Ord)
data SelEvt a = LostSel | SelNotify a deriving (Eq, Ord)
data ESelCmd a = OwnSel | SelCmd (SelCmd a) deriving (Eq, Ord)
data ESelEvt a = WantSel | SelEvt (SelEvt a) deriving (Eq, Ord)
eselectionF :: F (ESelCmd String) (ESelEvt String)
eselectionF =
(stripEither >^=< unmappedShellF [] selK nullLF) >=^<
Left where
selK =
conts (flip internAtomK True)
["PRIMARY", "STRING", "NONE", "ATOM"] $
\ [primaryA, stringA, noneA, atomA] ->
conts (flip internAtomK False) ["FUDGETS_UTF8","UTF8_STRING"] $
\ [fudgetsA, utf8A] -> let
sevt = High. SelEvt
l =
getK $ \ev ->
case ev of
High esc -> case esc of
SelCmd sc -> case sc of
Sel t -> l -- select t
ClearSel -> deselect
PasteSel -> paste_utf8string -- try UTF-8 first...
OwnSel -> select
Low (XEvt ev) -> case ev of
SelectionClear s | s == primaryA -> putK (sevt LostSel) l
SelectionRequest t w s -> selectionrequest t w s
SelectionNotify t s -> selectionnotify s
_ -> l
Low _ -> l
selectionrequest time w sel@(Selection s t p) =
if t `notElem` [stringA,utf8A]
then notify time w (Selection s noneA p) l
else
let p' = if p == noneA then t else p
wait (High (SelCmd (Sel t))) = Just t
wait _ = Nothing
in cmdContK' (High WantSel) wait $ \rawtext ->
let text = if t==utf8A
then encodeUTF8 rawtext
else rawtext in
xcommandK (ChangeProperty w p' t 8 propModeReplace text) $
notify time w (Selection s t p') l
notify t w sel = xcommandK (SendEvent w False [] (SelectionNotify t sel))
paste_string = paste' stringA
paste_utf8string = paste' utf8A
paste' typ =
xcommandK (ConvertSelection (Selection primaryA typ fudgetsA)) l
paste_failed = putK (sevt (SelNotify "")) l
selectionnotify sel@(Selection s t p) =
if p==noneA
then if t==utf8A -- UTF8_STRING wasn't supported, try STRING
then paste_string
else paste_failed
else if t `notElem` [stringA,utf8A]
then paste_failed
else getWindowPropertyK 0 p True t $
\(typ, format, nitems, after,seltext) ->
let s' = if t==utf8A then decodeUTF8 seltext else seltext in
putK (sevt (SelNotify s')) l
select = select' True
deselect = select' False
-- should check that setselectionowner succeeded.
select' b = xcommandK (SetSelectionOwner b primaryA) l
in l
selectionF :: F (SelCmd String) (SelEvt String)
selectionF = loopThroughRightF (absF (selSP "")) (eselectionF) where
selSP text =
let same = selSP text
toesel = Left
toout = Right in
getSP $ \msg -> case msg of
Right ocmd -> case ocmd of
Sel t -> putSP (toesel OwnSel) $ selSP t
_ -> putSP (toesel (SelCmd ocmd)) same
Left esevt -> case esevt of
WantSel -> putSP (toesel (SelCmd (Sel text))) same
SelEvt se -> putSP (toout se) same