mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 03:20:21 -07:00
Essentially, whenever the tutorial actually has decent material on the subject matter. The replacement is roughly done as follows: - logHook → tutorial - keybindings → tutorial, as this is thoroughly covered - manageHook → tutorial + X.D.Extending, as the manageHook stuff the tutorial talks about is a little bit of an afterthought. - X.D.Extending (on its own) → tutorial + X.D.Extending - layoutHook → tutorial + X.D.Extending, as the tutorial, while talking about layouts, doesn't necessarily have a huge focus there. - mouse bindings → leave this alone, as the tutorial does not at all talk about them.
117 lines
4.9 KiB
Haskell
117 lines
4.9 KiB
Haskell
-----------------------------------------------------------------------------
|
|
-- |
|
|
-- Module : XMonad.Hooks.SetWMName
|
|
-- Description : Set the WM name to a given string.
|
|
-- Copyright : © 2007 Ivan Tarasov <Ivan.Tarasov@gmail.com>
|
|
-- License : BSD
|
|
--
|
|
-- Maintainer : Ivan.Tarasov@gmail.com
|
|
-- Stability : experimental
|
|
-- Portability : unportable
|
|
--
|
|
-- Sets the WM name to a given string, so that it could be detected using
|
|
-- _NET_SUPPORTING_WM_CHECK protocol.
|
|
--
|
|
-- May be useful for making Java GUI programs work, just set WM name to "LG3D"
|
|
-- and use Java 1.6u1 (1.6.0_01-ea-b03 works for me) or later.
|
|
--
|
|
-- To your @~\/.xmonad\/xmonad.hs@ file, add the following line:
|
|
--
|
|
-- > import XMonad.Hooks.SetWMName
|
|
--
|
|
-- Then edit your @startupHook@:
|
|
--
|
|
-- > startupHook = setWMName "LG3D"
|
|
--
|
|
-- For details on the problems with running Java GUI programs in non-reparenting
|
|
-- WMs, see <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6429775> and
|
|
-- related bugs.
|
|
--
|
|
-- Setting WM name to "compiz" does not solve the problem, because of yet
|
|
-- another bug in AWT code (related to insets). For LG3D insets are explicitly
|
|
-- set to 0, while for other WMs the insets are \"guessed\" and the algorithm
|
|
-- fails miserably by guessing absolutely bogus values.
|
|
--
|
|
-- For detailed instructions on editing your hooks, see
|
|
-- <https://xmonad.org/TUTORIAL.html the tutorial> and "XMonad.Doc.Extending".
|
|
-----------------------------------------------------------------------------
|
|
|
|
module XMonad.Hooks.SetWMName (
|
|
setWMName
|
|
, getWMName
|
|
)
|
|
where
|
|
|
|
import Foreign.C.Types (CChar)
|
|
import Foreign.Marshal.Alloc (alloca)
|
|
|
|
import XMonad
|
|
import XMonad.Prelude (fromJust, join, listToMaybe, maybeToList, nub, ord)
|
|
|
|
-- | sets WM name
|
|
setWMName :: String -> X ()
|
|
setWMName name = do
|
|
atom_NET_SUPPORTING_WM_CHECK <- netSupportingWMCheckAtom
|
|
atom_NET_WM_NAME <- getAtom "_NET_WM_NAME"
|
|
atom_NET_SUPPORTED_ATOM <- getAtom "_NET_SUPPORTED"
|
|
atom_UTF8_STRING <- getAtom "UTF8_STRING"
|
|
|
|
root <- asks theRoot
|
|
supportWindow <- getSupportWindow
|
|
dpy <- asks display
|
|
io $ do
|
|
-- _NET_SUPPORTING_WM_CHECK atom of root and support windows refers to the support window
|
|
mapM_ (\w -> changeProperty32 dpy w atom_NET_SUPPORTING_WM_CHECK wINDOW propModeReplace [fromIntegral supportWindow]) [root, supportWindow]
|
|
-- set WM_NAME in supportWindow (now only accepts latin1 names to eliminate dependency on utf8 encoder)
|
|
changeProperty8 dpy supportWindow atom_NET_WM_NAME atom_UTF8_STRING propModeReplace (latin1StringToCCharList name)
|
|
-- declare which _NET protocols are supported (append to the list if it exists)
|
|
supportedList <- join . maybeToList <$> getWindowProperty32 dpy atom_NET_SUPPORTED_ATOM root
|
|
changeProperty32 dpy root atom_NET_SUPPORTED_ATOM aTOM propModeReplace (nub $ fromIntegral atom_NET_SUPPORTING_WM_CHECK : fromIntegral atom_NET_WM_NAME : supportedList)
|
|
where
|
|
latin1StringToCCharList :: String -> [CChar]
|
|
latin1StringToCCharList = map (fromIntegral . ord)
|
|
|
|
netSupportingWMCheckAtom :: X Atom
|
|
netSupportingWMCheckAtom = getAtom "_NET_SUPPORTING_WM_CHECK"
|
|
|
|
getSupportWindow :: X Window
|
|
getSupportWindow = withDisplay $ \dpy -> do
|
|
atom_NET_SUPPORTING_WM_CHECK <- netSupportingWMCheckAtom
|
|
root <- asks theRoot
|
|
supportWindow <- (listToMaybe =<<) <$> io (getWindowProperty32 dpy atom_NET_SUPPORTING_WM_CHECK root)
|
|
validateWindow (fmap fromIntegral supportWindow)
|
|
where
|
|
validateWindow :: Maybe Window -> X Window
|
|
validateWindow w = do
|
|
valid <- maybe (return False) isValidWindow w
|
|
if valid then
|
|
return $ fromJust w
|
|
else
|
|
createSupportWindow
|
|
|
|
-- is there a better way to check the validity of the window?
|
|
isValidWindow :: Window -> X Bool
|
|
isValidWindow w = withDisplay $ \dpy -> io $ alloca $ \p -> do
|
|
status <- xGetWindowAttributes dpy w p
|
|
return (status /= 0)
|
|
|
|
-- this code was translated from C (see OpenBox WM, screen.c)
|
|
createSupportWindow :: X Window
|
|
createSupportWindow = withDisplay $ \dpy -> do
|
|
root <- asks theRoot
|
|
let visual = defaultVisual dpy (defaultScreen dpy) -- should be CopyFromParent (=0), but the constructor is hidden in X11.XLib
|
|
window <- io $ allocaSetWindowAttributes $ \winAttrs -> do
|
|
set_override_redirect winAttrs True -- WM cannot decorate/move/close this window
|
|
set_event_mask winAttrs propertyChangeMask -- not sure if this is needed
|
|
let bogusX = -100
|
|
bogusY = -100
|
|
in
|
|
createWindow dpy root bogusX bogusY 1 1 0 0 inputOutput visual (cWEventMask .|. cWOverrideRedirect) winAttrs
|
|
io $ mapWindow dpy window -- not sure if this is needed
|
|
io $ lowerWindow dpy window -- not sure if this is needed
|
|
return window
|
|
|
|
-- | Get WM name.
|
|
getWMName :: X String
|
|
getWMName = getSupportWindow >>= runQuery title
|