bluetile-0.6/0000755000000000000000000000000011664267105011362 5ustar0000000000000000bluetile-0.6/LICENSE0000644000000000000000000000266111664267105012374 0ustar0000000000000000Copyright (c) 2009 Jan Vornberger All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. bluetile-0.6/README0000644000000000000000000000071211664267105012242 0ustar0000000000000000Quickstart: After installing Bluetile (use 'cabal install') just open a terminal under your current window manager/desktop environment (preferably GNOME) and enter 'bluetile' or '/path/to/bluetile' if it's not in your PATH. Bluetile will replace the currently running window manager (if the window manager supports this) and start up. See the man page of Bluetile for further information - including how to set up Bluetile as your permanent window manager. bluetile-0.6/Setup.lhs0000644000000000000000000000445111664267105013176 0ustar0000000000000000#!/usr/bin/env runhaskell > import Distribution.PackageDescription > import Distribution.Simple > import Distribution.Simple.LocalBuildInfo > import Distribution.Simple.Setup > import System.FilePath > import System.Directory > import System.IO > import Control.Monad > import Data.List > > main = defaultMainWithHooks (simpleUserHooks { postCopy = myPostCopy, postInst = myPostInst } ) > > myPostCopy :: Args -> CopyFlags -> PackageDescription -> LocalBuildInfo -> IO () > myPostCopy _ copyflags pkgdesc lbi = do > let copyDirs = absoluteInstallDirs pkgdesc lbi (fromFlag $ copyDest copyflags) > libExecHook copyDirs > let installDirs = absoluteInstallDirs pkgdesc lbi NoCopyDest > insertPath copyDirs installDirs > > myPostInst :: Args -> InstallFlags -> PackageDescription -> LocalBuildInfo -> IO () > myPostInst _ _ pkgdesc lbi = do > let dirs = absoluteInstallDirs pkgdesc lbi NoCopyDest > libExecHook dirs > insertPath dirs dirs > > -- hook to move helper binaries to the libexec directory > libExecHook :: InstallDirs String -> IO () > libExecHook dirs = do > let bdir = bindir dirs > let lexecdir = libexecdir dirs > createDirectoryIfMissing True lexecdir > forM_ ["bluetiledock", "bluetilemockwin", "bluetilegreet"] $ \binary -> > renameFile (bdir binary) (lexecdir binary) > > -- hook to insert path to system wide configuration > insertPath :: InstallDirs String -> InstallDirs String -> IO () > insertPath copyDirs installDirs = do > let userConfigTemplate = datadir copyDirs "etc" "bluetilerc_user_template" > let pathToSystemConfig = datadir installDirs "etc" "bluetilerc" > contents <- readFileStrict userConfigTemplate > let contentsPatched = replaceStr "__PATH_TO_BLUETILERC__" pathToSystemConfig contents > writeFile userConfigTemplate contentsPatched > > replaceStr :: (Eq a) => [a] -> [a] -> [a] -> [a] > replaceStr _ _ [] = [] > replaceStr old new xs@(y:ys) = > case stripPrefix old xs of > Nothing -> y : replaceStr old new ys > Just ys' -> new ++ replaceStr old new ys' > > -- taken from System.IO.Strict on Hackage > readFileStrict :: FilePath -> IO String > readFileStrict name = openFile name ReadMode >>= hGetContentsStrict > > hGetContentsStrict :: Handle -> IO String > hGetContentsStrict h = hGetContents h >>= \s -> length s `seq` return s bluetile-0.6/NEWS0000644000000000000000000000263311664267105012065 0ustar0000000000000000Bluetile 0.6 (on 2011/11/26) Jan Vornberger Now that XMonad 0.10 is out, it was possible to clean up Bluetile's code base and reference modules from xmonad-contrib 0.10 instead. Furthermore, the modules XMonad.Hooks.ICCCMFocus (workaround for some problems with Java-based applications) and XMonad.Actions.PhysicalScreens (enumerating multiple monitors in a sensible manner) have been incorporated into the standard configuration. Bluetile 0.5.3 (on 2010/08/10) Jan Vornberger Bluetile's theme is now configurable, including the font that is used. I also switched back to the old, grey-ish theme. For reference, below is the blue-ish theme, which was used for a few releases in an attempt to make the focused window stand out more. However, it was not very well received, apparently. Everyone is welcome to choose their own color combinations now. :-) decoration_focused_color = #7ca3d3 decoration_focused_text_color = white decoration_focused_border_color = white decoration_normal_color = #e3e2e1 decoration_normal_text_color = black decoration_normal_border_color = black decoration_font = xft: Sans Bold:size=9 window_border_focused_color = black window_border_normal_color = gray Bluetile should also now build on Ubuntu Maverick Meerkat thanks to a patch by Iain Lane. bluetile-0.6/bluetile.cabal0000644000000000000000000000717711664267105014167 0ustar0000000000000000Name: bluetile Version: 0.6 homepage: http://www.bluetile.org/ synopsis: full-featured tiling for the GNOME desktop environment description: Bluetile is a tiling window manager for Linux, designed to integrate with the GNOME desktop environment. It provides both a traditional, stacking layout mode as well as tiling layouts where windows are arranged to use the entire screen without overlapping. Bluetile tries to make the tiling paradigm easily accessible to users coming from traditional window managers by drawing on known conventions and providing both mouse and keyboard access for all features. category: System License: BSD3 License-file: LICENSE Author: Jan Vornberger Maintainer: jan.vornberger@informatik.uni-oldenburg.de extra-source-files: src/Config.hs, src/ConfigParser.hs, src/BluetileDock.hs, bluetiledock/Utils.hs, bluetilegreet/Utils.hs, man/bluetile.1, man/gnome-bluetile-session.1, misc/bluetile.desktop, misc/bluetile-session.desktop, misc/gnome-bluetile-session.desktop, README, NEWS data-files: bluetiledock/bluetiledock.glade, bluetiledock/floating.svg, bluetiledock/tiled1.svg, bluetiledock/tiled2.svg, bluetiledock/fullscreen.svg, bluetilegreet/bluetilegreet.glade, logo/bluetile-icon-48x48.png, logo/bluetile-icon.svg, etc/bluetilerc, etc/bluetilerc_user_template Build-Type: Custom Cabal-Version: >=1.6 Source-Repository head type: darcs location: http://code.haskell.org/~jav/bluetile/ Executable bluetile Main-is: Main.hs Hs-Source-Dirs: src Build-Depends: base>=3, base<5, containers, process, filepath, random, utf8-string, unix, regex-compat, mtl, ConfigFile, directory, X11-xft, xmonad>=0.10, xmonad-contrib>=0.10 if true Ghc-Options: -Wall if impl(ghc >= 6.12.1) Ghc-Options: -fno-warn-unused-do-bind Executable gnome-bluetile-session Buildable: True Hs-Source-Dirs: gnome-bluetile-session Main-is: GnomeBluetileSession.hs Build-Depends: base>=3, base<5, filepath, unix if true Ghc-Options: -Wall if impl(ghc >= 6.12.1) Ghc-Options: -fno-warn-unused-do-bind Executable bluetiledock Buildable: True Hs-Source-Dirs: bluetiledock Main-is: BluetileDock.hs Build-Depends: base>=3, base<5, unix, glade, gtk, X11>=1.4 pkgconfig-depends: gtk+-2.0 C-sources: bluetiledock/gdk_property_change_wrapper.c if true Ghc-Options: -Wall if impl(ghc >= 6.12.1) Ghc-Options: -fno-warn-unused-do-bind Executable bluetilemockwin Buildable: True Hs-Source-Dirs: bluetilemockwin Main-is: BluetileMockWin.hs Build-Depends: base>=3, base<5, gtk if true Ghc-Options: -Wall if impl(ghc >= 6.12.1) Ghc-Options: -fno-warn-unused-do-bind Executable bluetilegreet Buildable: True Hs-Source-Dirs: bluetilegreet Main-is: BluetileGreet.hs Build-Depends: base>=3, base<5, directory, filepath, glade, gtk if true Ghc-Options: -Wall if impl(ghc >= 6.12.1) Ghc-Options: -fno-warn-unused-do-bind bluetile-0.6/bluetiledock/0000755000000000000000000000000011664267105014030 5ustar0000000000000000bluetile-0.6/bluetiledock/Utils.hs0000644000000000000000000000177111664267105015472 0ustar0000000000000000---------------------------------------------------------------------------- -- | -- Module : Utils -- Copyright : (c) Jan Vornberger 2009 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- ----------------------------------------------------------------------------- module Utils where import System.Posix import System.IO -- | Launch an external application through the system shell and return a @Handle@ to its standard input. spawnPipe :: String -> IO Handle spawnPipe x = do (rd, wr) <- createPipe setFdOption wr CloseOnExec True h <- fdToHandle wr hSetBuffering h LineBuffering forkProcess $ do createSession uninstallSignalHandlers dupTo rd stdInput executeFile "/bin/sh" False ["-c", x] Nothing return h uninstallSignalHandlers :: IO () uninstallSignalHandlers = do installHandler sigCHLD Default Nothing return () bluetile-0.6/bluetiledock/tiled2.svg0000644000000000000000000001003111664267105015727 0ustar0000000000000000 image/svg+xml bluetile-0.6/bluetiledock/fullscreen.svg0000644000000000000000000000516511664267105016722 0ustar0000000000000000 image/svg+xml bluetile-0.6/bluetiledock/tiled1.svg0000644000000000000000000001003411664267105015731 0ustar0000000000000000 image/svg+xml bluetile-0.6/bluetiledock/BluetileDock.hs0000644000000000000000000002340311664267105016734 0ustar0000000000000000{-# LANGUAGE ForeignFunctionInterface #-} ---------------------------------------------------------------------------- -- | -- Module : Main -- Copyright : (c) Jan Vornberger 2009 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- ----------------------------------------------------------------------------- module Main where import Graphics.UI.Gtk import Graphics.UI.Gtk.Glade import Control.Concurrent import Control.Monad(when, forM_) import qualified Graphics.X11.Xlib as X import qualified Graphics.X11.Xlib.Extras as XE import System.Environment import System.IO import System.FilePath import Paths_bluetile import Utils import Data.IORef import Data.Maybe import Foreign import Foreign.C.Types import Unsafe.Coerce(unsafeCoerce) foreign import ccall "set_strut_properties" c_set_strut_properties :: Ptr Window -> CLong -> CLong -> CLong -> CLong -> CLong -> CLong -> CLong -> CLong -> CLong -> CLong -> CLong -> CLong -> () setStrutProperties :: Window -> (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) -> IO () setStrutProperties gtkWindow (left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x) = do let ptrWin = unsafeCoerce gtkWindow :: ForeignPtr Window let fi = fromIntegral withForeignPtr ptrWin $ \realPointer -> do return $ c_set_strut_properties realPointer (fi left) (fi right) (fi top) (fi bottom) (fi left_start_y) (fi left_end_y) (fi right_start_y) (fi right_end_y) (fi top_start_x) (fi top_end_x) (fi bottom_start_x) (fi bottom_end_x) data DockOutput = DO Int String String | InternalQuitCmd deriving (Show, Read) nextScreenCmdOffset :: Int nextScreenCmdOffset = 18 incMasterCmd :: Int incMasterCmd = 16 decMasterCmd :: Int decMasterCmd = 17 quitBluetileCmd :: Int quitBluetileCmd = 18 quitBluetileStartMetacityCmd :: Int quitBluetileStartMetacityCmd = 19 -- name of widget caption identifier group command to execute tbData :: [(String, String, String, String, ToggleButton -> Int -> IORef Bool -> IO ())] tbData = [ ("togglebutton1" , "1", "1" , "workspace", sendCommandIfToggled 2) , ("togglebutton2" , "2", "2" , "workspace", sendCommandIfToggled 3) , ("togglebutton3" , "3", "3" , "workspace", sendCommandIfToggled 4) , ("togglebutton4" , "4", "4" , "workspace", sendCommandIfToggled 5) , ("togglebutton5" , "5", "5" , "workspace", sendCommandIfToggled 6) , ("togglebutton6" , "6", "6" , "workspace", sendCommandIfToggled 7) , ("togglebutton7" , "7", "7" , "workspace", sendCommandIfToggled 8) , ("togglebutton8" , "8", "8" , "workspace", sendCommandIfToggled 9) , ("togglebutton9" , "9", "9" , "workspace", sendCommandIfToggled 10) , ("togglebutton0" , "0", "0" , "workspace", sendCommandIfToggled 11) , ("togglebuttonlayouta", "A", "Floating" , "layout" , sendCommandIfToggled 12) , ("togglebuttonlayoutb", "S", "Tiled1" , "layout" , sendCommandIfToggled 13) , ("togglebuttonlayoutc", "D", "Tiled2" , "layout" , sendCommandIfToggled 14) , ("togglebuttonlayoutd", "F", "Fullscreen", "layout" , sendCommandIfToggled 15) ] main :: IO () main = do args <- getArgs let myScreenId = if (length args > 0 && head args == "--otherscreen") then 1 else 0 lockSendCommand <- newIORef False otherDockProcess <- newIORef Nothing -- prepare GUI initGUI dataDir <- getDataDir Just xml <- xmlNew $ dataDir "bluetiledock" "bluetiledock.glade" Just dfltScreen <- screenGetDefault dfltWh <- screenGetWidth dfltScreen -- monitor0 dock monitor0Dock <- xmlGetWidget xml castToWindow "monitor0Dock" windowSetTypeHint monitor0Dock WindowTypeHintDock onDestroy monitor0Dock mainQuit (m0DockWh, m0DockHt) <- windowGetSize monitor0Dock configBtn <- xmlGetWidget xml castToButton "configbutton" quitBtn <- xmlGetWidget xml castToButton "quitbutton" let m0DockY = 35 if myScreenId == 0 then do windowMove monitor0Dock 0 m0DockY onRealize monitor0Dock $ setStrutProperties monitor0Dock (m0DockWh + 1, 0, 0, 0, m0DockY, m0DockY + m0DockHt, 0, 0, 0, 0, 0, 0) return () else do windowMove monitor0Dock (dfltWh - m0DockWh) m0DockY onRealize monitor0Dock $ setStrutProperties monitor0Dock (0, m0DockWh + 1, 0, 0, 0, 0, m0DockY, m0DockY + m0DockHt, 0, 0, 0, 0) widgetSetSensitivity quitBtn False return () widgetShowAll monitor0Dock -- toggle buttons forM_ tbData $ \(tbName, tbCaption, _, _, f) -> do widget <- getTogglebutton xml tbName buttonSetLabel widget tbCaption onToggled widget (f widget myScreenId lockSendCommand) -- master area buttons incMasterBtn <- xmlGetWidget xml castToButton "incmasterbutton" decMasterBtn <- xmlGetWidget xml castToButton "decmasterbutton" onClicked incMasterBtn $ sendCommand incMasterCmd myScreenId onClicked decMasterBtn $ sendCommand decMasterCmd myScreenId -- config button onClicked configBtn $ do home <- getEnv "HOME" let userConfig = home ".bluetilerc" spawnPipe $ "gnome-open " ++ userConfig return () -- quit button onClicked quitBtn $ do dialog <- messageDialogNew (Just monitor0Dock) [DialogModal] MessageQuestion ButtonsNone "Really quit Bluetile?" dialogAddButton dialog "Quit" (ResponseUser quitBluetileCmd) dialogAddButton dialog "Quit and start Metacity" (ResponseUser quitBluetileStartMetacityCmd) dialogAddButton dialog "Cancel" ResponseCancel resp <- dialogRun dialog widgetDestroy dialog case resp of ResponseUser cmd -> do sendCommand cmd myScreenId hndlM <- readIORef otherDockProcess when (isJust hndlM) $ do hPutStrLn (fromJust hndlM) $ show InternalQuitCmd mainQuit _ -> return () -- prepare stdin reader updates <- getContents forkIO $ processUpdate (lines updates) xml myScreenId lockSendCommand otherDockProcess -- enter main GUI loop timeoutAddFull (yield >> return True) priorityDefaultIdle 50 mainGUI getTogglebutton :: GladeXML -> String -> IO (ToggleButton) getTogglebutton xml tbName = xmlGetWidget xml castToToggleButton tbName processUpdate :: [String] -> GladeXML -> Int -> IORef Bool -> IORef (Maybe Handle) -> IO () processUpdate updates xml myScreenId lockSendCommand otherDockProcess = mapM_ (pU . read) updates where pU :: DockOutput -> IO () pU update@(DO sid longLayoutDesc cws) = do let layoutDesc = last $ words longLayoutDesc hndlM <- readIORef otherDockProcess when (sid == myScreenId) $ do writeIORef lockSendCommand True activateToggleButtons xml cws "workspace" activateToggleButtons xml layoutDesc "layout" writeIORef lockSendCommand False when (sid /= myScreenId && isNothing hndlM) $ do libexecDir <- getLibexecDir hndl <- spawnPipe $ libexecDir "bluetiledock --otherscreen" writeIORef otherDockProcess (Just hndl) hPutStrLn hndl $ show update when (sid /= myScreenId && isJust hndlM) $ do hPutStrLn (fromJust hndlM) $ show update pU InternalQuitCmd = mainQuit activateToggleButtons :: GladeXML -> String -> String -> IO () activateToggleButtons xml cws group = do let relevantTbData = filter (\(_, _, _, group', _) -> group' == group) tbData forM_ relevantTbData $ \(tbName, _, tag, _, _) -> do widget <- getTogglebutton xml tbName toggleButtonSetActive widget (tag == cws) sendCommandIfToggled :: (ToggleButtonClass self) => Int -> self -> Int -> IORef Bool -> IO () sendCommandIfToggled cmd widget myScreenId lockSendCommand = do isToggled <- toggleButtonGetActive widget isLocked <- readIORef lockSendCommand when (isToggled && not isLocked) $ sendCommand cmd myScreenId sendCommand :: Int -> Int -> IO () sendCommand cmd myScreenId = sendCommandX (cmd + myScreenId * nextScreenCmdOffset) sendCommandX :: Int -> IO () sendCommandX com = do d <- X.openDisplay "" rw <- X.rootWindow d $ X.defaultScreen d a <- X.internAtom d "XMONAD_COMMAND" False X.allocaXEvent $ \e -> do XE.setEventType e X.clientMessage XE.setClientMessageEvent e rw a 32 (fromIntegral com) XE.currentTime X.sendEvent d rw False X.structureNotifyMask e X.sync d False bluetile-0.6/bluetiledock/gdk_property_change_wrapper.c0000644000000000000000000000211711664267105021753 0ustar0000000000000000//////////////////////////////////////////////////////////////////////////// // Copyright : (c) Jan Vornberger 2009 // License : BSD3-style (see LICENSE) // // Maintainer : jan.vornberger@informatik.uni-oldenburg.de ////////////////////////////////////////////////////////////////////////////- #include #include void set_strut_properties(GtkWindow *window, long left, long right, long top, long bottom, long left_start_y, long left_end_y, long right_start_y, long right_end_y, long top_start_x, long top_end_x, long bottom_start_x, long bottom_end_x) { gulong data[12] = {0}; data[0] = left; data[1] = right; data[2] = top; data[3] = bottom; data[4] = left_start_y; data[5] = left_end_y; data[6] = right_start_y; data[7] = right_end_y; data[8] = top_start_x; data[9] = top_end_x; data[10] = bottom_start_x; data[11] = bottom_end_x; gdk_property_change(GTK_WIDGET(window)->window, gdk_atom_intern("_NET_WM_STRUT_PARTIAL", FALSE), gdk_atom_intern ("CARDINAL", FALSE), 32, GDK_PROP_MODE_REPLACE, (unsigned char *)data, 12); } bluetile-0.6/bluetiledock/floating.svg0000644000000000000000000000705411664267105016362 0ustar0000000000000000 image/svg+xml bluetile-0.6/bluetiledock/bluetiledock.glade0000644000000000000000000003774111664267105017510 0ustar0000000000000000 30 700 BluetileDock - Workspace True vertical True vertical True Wrk- spc 0 togglebutton True True True Switch to workspace 1 1 togglebutton True True True Switch to workspace 2 2 togglebutton True True True Switch to workspace 3 3 togglebutton True True True Switch to workspace 4 4 togglebutton True True True Switch to workspace 5 5 togglebutton True True True Switch to workspace 6 6 togglebutton True True True Switch to workspace 7 7 togglebutton True True True Switch to workspace 8 8 togglebutton True True True Switch to workspace 9 9 togglebutton True True True Switch to workspace 0 10 0 True vertical True Lay- out 0 True vertical True floating.svg 0 ... True True True Switch to stacking window layout half 1 2 1 True vertical True tiled1.svg 0 ... True True True Switch to tiled horizontal layout 1 2 2 True vertical True tiled2.svg 0 ... True True True Switch to tiled vertical layout 1 2 3 True vertical True fullscreen.svg 0 ... True True True Switch to fullscreen layout 1 2 4 1 True vertical +1 True True True Increase number of windows in the master area 0 -1 True True True Decrease number of windows in the master area 1 C True True True True Configure Bluetile 2 Q True True True True Quit Bluetile 3 2 bluetile-0.6/man/0000755000000000000000000000000011664267105012135 5ustar0000000000000000bluetile-0.6/man/bluetile.10000644000000000000000000001726011664267105014032 0ustar0000000000000000.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "BLUETILE 1" .TH BLUETILE 1 "2010-11-07" "perl v5.10.1" "" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" bluetile \- full\-featured tiling for the GNOME desktop environment .SH "SYNOPSIS" .IX Header "SYNOPSIS" bluetile [\-\-help] [\-\-version] [\-\-restart] .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBBluetile\fR is a tiling window manager designed to integrate with the \&\s-1GNOME\s0 desktop environment. It provides both a traditional, stacking layout mode as well as tiling layouts where windows are arranged to use the entire screen without overlapping. \fBBluetile\fR tries to make the tiling paradigm easily accessible to users coming from traditional window managers by drawing on known conventions and providing both mouse and keyboard access for all features. .IP "\(bu" 4 Designed to integrate with the \s-1GNOME\s0 desktop environment .IP "\(bu" 4 Hybrid approach: Stacking window layout & tiling layouts available .IP "\(bu" 4 All features accessible from mouse, as well as keyboard .IP "\(bu" 4 Maximizing & minimizing windows in all layouts .IP "\(bu" 4 Good multihead support .IP "\(bu" 4 Proper handling of fullscreen applications .SH "OVERVIEW" .IX Header "OVERVIEW" To quickly get up and running just start \fBBluetile\fR from your current window manager/desktop environment (preferably \s-1GNOME\s0). \fBBluetile\fR will replace the currently running window manager (if the window manager supports this) and start up. .PP One way to set up \fBBluetile\fR as your default window manager under \s-1GNOME\s0 is to make sure that the environment variable \s-1WINDOW_MANAGER\s0 contains the path to the \fBBluetile\fR binary before \s-1GNOME\s0 starts. This can be achieved by putting something like the following line into ~/.gnomerc: .PP .Vb 1 \& export WINDOW_MANAGER=bluetile .Ve .PP If you use a packaged version of \fBBluetile\fR, your distribution might already provide you with a preconfigured xsession. .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-\-help\fR print help message .PP \&\fB\-\-version\fR print the version number .PP \&\fB\-\-restart\fR request a running \fBBluetile\fR process to restart .SH "KEYBOARD SHORTCUTS" .IX Header "KEYBOARD SHORTCUTS" This is a list of most keyboard shortcuts for \fBBluetile\fR: .PP .Vb 2 \& Win+Return Launch terminal \& Win+p Launch GNOME "Run application" dialog \& \& Win+a Switch to stacking window layout \& Win+s Switch to tiled horizontal layout \& Win+d Switch to tiled vertical layout \& Win+f Switch to fullscreen layout \& \& Win+j Move focus to the next window \& Win+k Move focus to the previous window \& Win+Space Move focus to the master window \& Win+Shift+j Swap the focused window with the next window \& Win+Shift+k Swap the focused window with the previous window \& Win+Shift+Space Swap the focused window with the master window \& \& Win+h Shrink the master area \& Win+l Expand the master area \& Win+u Shrink a slave area \& Win+i Expand a slave area \& Win+, Increment the number of windows in the master area \& Win+. Decrement the number of windows in the master area \& \& Win+Shift+c Close the focused window \& Win+z Maximize/zoom focused window \& Win+m Minimize focused window \& Win+Shift+m Restore next minimized window \& Win+o Show window menu for focused window \& Win+t Push dialog window back into tiling \& Win+b Toggle to previously displayed workspace \& \& Win+1 .. Win+9, Win+0 \& Switch to workspace N \& \& Win+Shift+1 .. Win+Shift+9, Win+Shift+0 \& Move client to workspace N \& \& Win+w, Win+e, Win+r \& Switch to physical/Xinerama screens 1, 2 or 3 \& \& Win+Shift+w, Win+Shift+e, Win+Shift+r \& Move client to physical/Xinerama screen 1, 2 or 3 \& \& Win+F5 Refresh layout \& Win+Shift+q Quit Bluetile .Ve .SH "CONFIGURATION" .IX Header "CONFIGURATION" Edit the file ~/.bluetilerc to configure \fBBluetile\fR. .SH "AUTHOR" .IX Header "AUTHOR" Jan Vornberger bluetile-0.6/man/gnome-bluetile-session.10000644000000000000000000001031111664267105016604 0ustar0000000000000000.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "GNOME-BLUETILE-SESSION 1" .TH GNOME-BLUETILE-SESSION 1 "2010-06-24" "perl v5.10.1" "" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" gnome\-bluetile\-session \- Invoke gnome\-session with Bluetile as window manager .SH "SYNOPSIS" .IX Header "SYNOPSIS" gnome-bluetile-session .SH "DESCRIPTION" .IX Header "DESCRIPTION" Invokes gnome-session after setting the environment variable \&\s-1WINDOW_MANAGER\s0 to the path of the \fBBluetile\fR binary. This will start up the \s-1GNOME\s0 desktop environment with Bluetile as the window manager. .SH "AUTHOR" .IX Header "AUTHOR" Jan Vornberger bluetile-0.6/logo/0000755000000000000000000000000011664267105012322 5ustar0000000000000000bluetile-0.6/logo/bluetile-icon-48x48.png0000644000000000000000000000044711664267105016365 0ustar0000000000000000‰PNG  IHDR00Wù‡sBIT|dˆ pHYs©© 0¡tEXtSoftwarewww.inkscape.org›î<¤IDAThíÚ1… EÑë;±ö¿ JVƒÅßS˜7$ï$t‚ÞX`ˆ°8Ø ÐZãyž­ cŒÔ ""u}v}€kÿ7¶=²²ëÿÒ¹Å8@ÍjPs@יּ±+"¼—à5¨9@ÍjÇ€O%´ æ5¨9@Í”ú¶Ùås¡* æ5¨pg'ôÞ¿xŽôúsN.ÿÝæ}^às ´%IEND®B`‚bluetile-0.6/logo/bluetile-icon.svg0000644000000000000000000001202411664267105015575 0ustar0000000000000000 image/svg+xml bluetile-0.6/gnome-bluetile-session/0000755000000000000000000000000011664267105015753 5ustar0000000000000000bluetile-0.6/gnome-bluetile-session/GnomeBluetileSession.hs0000644000000000000000000000123711664267105022411 0ustar0000000000000000---------------------------------------------------------------------------- -- | -- Module : Main -- Copyright : (c) Jan Vornberger 2009 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- ----------------------------------------------------------------------------- module Main (main) where import System.Posix.Env import System.Posix.Process import System.FilePath import Paths_bluetile main :: IO () main = do binDir <- getBinDir setEnv "WINDOW_MANAGER" (binDir "bluetile") True executeFile "gnome-session" True [] Nothing bluetile-0.6/bluetilemockwin/0000755000000000000000000000000011664267105014557 5ustar0000000000000000bluetile-0.6/bluetilemockwin/BluetileMockWin.hs0000644000000000000000000000173711664267105020160 0ustar0000000000000000---------------------------------------------------------------------------- -- | -- Module : Main -- Copyright : (c) Jan Vornberger 2009 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- ----------------------------------------------------------------------------- module Main where import Graphics.UI.Gtk import System.Environment(getArgs,getProgName) main :: IO () main = do args <- getArgs progName <- getProgName if length args /= 3 then putStrLn $ "Usage: " ++ progName ++ " 0 0 65535" else let r = read $ args !! 0 g = read $ args !! 1 b = read $ args !! 2 in showMockWin (Color r g b) showMockWin :: Color -> IO () showMockWin c = do initGUI window <- windowNew onDestroy window mainQuit widgetModifyBg window StateNormal c widgetShowAll window mainGUI bluetile-0.6/misc/0000755000000000000000000000000011664267105012315 5ustar0000000000000000bluetile-0.6/misc/bluetile-session.desktop0000644000000000000000000000017111664267105017175 0ustar0000000000000000[Desktop Entry] Encoding=UTF-8 Name=Bluetile Comment=Tiling window manager Exec=bluetile Icon=bluetile.png Type=XSession bluetile-0.6/misc/gnome-bluetile-session.desktop0000644000000000000000000000025611664267105020304 0ustar0000000000000000[Desktop Entry] Encoding=UTF-8 Name=GNOME + Bluetile Comment=Tiling window manager TryExec=/usr/bin/gnome-session Exec=gnome-bluetile-session Icon=bluetile.png Type=XSession bluetile-0.6/misc/bluetile.desktop0000644000000000000000000000032611664267105015516 0ustar0000000000000000[Desktop Entry] Type=Application Encoding=UTF-8 Name=Bluetile Exec=bluetile NoDisplay=true X-GNOME-WMName=bluetile X-GNOME-Autostart-Phase=WindowManager X-GNOME-Provides=windowmanager X-GNOME-Autostart-Notify=true bluetile-0.6/bluetilegreet/0000755000000000000000000000000011664267105014216 5ustar0000000000000000bluetile-0.6/bluetilegreet/Utils.hs0000644000000000000000000000177111664267105015660 0ustar0000000000000000---------------------------------------------------------------------------- -- | -- Module : Utils -- Copyright : (c) Jan Vornberger 2009 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- ----------------------------------------------------------------------------- module Utils where import System.Posix import System.IO -- | Launch an external application through the system shell and return a @Handle@ to its standard input. spawnPipe :: String -> IO Handle spawnPipe x = do (rd, wr) <- createPipe setFdOption wr CloseOnExec True h <- fdToHandle wr hSetBuffering h LineBuffering forkProcess $ do createSession uninstallSignalHandlers dupTo rd stdInput executeFile "/bin/sh" False ["-c", x] Nothing return h uninstallSignalHandlers :: IO () uninstallSignalHandlers = do installHandler sigCHLD Default Nothing return () bluetile-0.6/bluetilegreet/bluetilegreet.glade0000644000000000000000000002026311664267105020053 0ustar0000000000000000 450 450 Welcome to Bluetile! True 10 10 10 10 True GTK_ORIENTATION_VERTICAL 5 GTK_ORIENTATION_VERTICAL True <span size="large" font_weight="bold">Welcome to Bluetile!</span> full-featured tiling for the GNOME desktop environment True GTK_JUSTIFY_CENTER True 3 2 3 3 True Quickstart: Open a few windows and notice that you are currently in the traditional layout mode, known from most other window managers. To start tiling, switch to another layout in one of these ways: True True * Using the dock on the left (buttons A, S, D or F), * pressing the middle mouse button while holding down the Windows key or * using the keyboard shortcuts Win+A, Win+S, Win+D or Win+F . 1 2 True You should be fine exploring the tiling paradigm with your mouse alone, but to get the most out of it you might want to look at the keyboard shortcuts at some point. They are documented on Bluetile's website. True 2 3 True 3 3 3 3 True True True 0 True <span size="x-small">Open a few windows</span> True 1 2 1 2 1 2 1 True GTK_ORIENTATION_VERTICAL GTK_ORIENTATION_VERTICAL True True Do not show this window on future startups. 0 True True True True Let's start tiling! 0 1 2 bluetile-0.6/bluetilegreet/BluetileGreet.hs0000644000000000000000000000364511664267105017316 0ustar0000000000000000---------------------------------------------------------------------------- -- | -- Module : Main -- Copyright : (c) Jan Vornberger 2009 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- ----------------------------------------------------------------------------- module Main where import Graphics.UI.Gtk import Graphics.UI.Gtk.Glade import Paths_bluetile import Utils import Control.Monad(when) import System.Environment(getEnv) import System.FilePath(pathSeparator) import System.Directory(doesFileExist) main :: IO () main = do home <- getEnv "HOME" let configFile = home ++ [pathSeparator] ++ ".bluetilegreet" exists <- doesFileExist configFile when (not exists) $ greetingScreen configFile greetingScreen :: String -> IO () greetingScreen configFile = do initGUI dataDir <- getDataDir Just xml <- xmlNew $ dataDir ++ [pathSeparator] ++ "bluetilegreet" ++ [pathSeparator] ++ "bluetilegreet.glade" window <- xmlGetWidget xml castToWindow "bluetilegreetwindow" onDestroy window mainQuit windowSetPosition window WinPosCenter openWindowsBtn <- xmlGetWidget xml castToButton "openwindowsbutton" onClicked openWindowsBtn $ do libexecDir <- getLibexecDir spawnPipe $ libexecDir ++ [pathSeparator] ++ "bluetilemockwin 0 0 65535" spawnPipe $ libexecDir ++ [pathSeparator] ++ "bluetilemockwin 65535 0 0" return () startBtn <- xmlGetWidget xml castToButton "startbutton" startupAgainChkBtn <- xmlGetWidget xml castToCheckButton "startupagaincheckbutton" onClicked startBtn $ do noFutureStartups <- toggleButtonGetActive startupAgainChkBtn when noFutureStartups $ do writeFile configFile "Delete this file to show the Bluetile greeting screen again.\n" mainQuit widgetShowAll window mainGUI bluetile-0.6/etc/0000755000000000000000000000000011664267105012135 5ustar0000000000000000bluetile-0.6/etc/bluetilerc_user_template0000644000000000000000000000152211664267105017143 0ustar0000000000000000# This is your Bluetile configuration file. # Use this file to make changes to the default configuration. # You can see all the defaults in the file # __PATH_TO_BLUETILERC__ # # Below are a few examples - note: Mod1 is usually the Alt key. # Run 'bluetile --list-identifiers' to see a complete list of all # possibile modifier and key names. #start_dock: false #terminal: xterm #default_modifier: Mod1 #key_launch_terminal: DefaultMod+Shift+Return # blue-ish theme where the focused window stands out more #decoration_focused_color = #7ca3d3 #decoration_focused_text_color = white #decoration_focused_border_color = white #decoration_normal_color = #e3e2e1 #decoration_normal_text_color = black #decoration_normal_border_color = black #decoration_font = xft: Sans Bold:size=9 #window_border_focused_color = black #window_border_normal_color = gray bluetile-0.6/etc/bluetilerc0000644000000000000000000000775011664267105014223 0ustar0000000000000000# This is the default configuration of Bluetile. # It is recommended to not change this file and instead # make your changes in ~/.bluetilerc # # Note: You can ignore the key bindings that end # in '_alternative'. These only exist because a few # actions can be invoked in two different ways. # global options (Mod4 is usually the logo key) default_modifier: Mod4 terminal: gnome-terminal start_dock: true # theme decoration_focused_color = #999999 decoration_focused_text_color = #FFFFFF decoration_focused_border_color = #FFFFFF decoration_normal_color = #666666 decoration_normal_text_color = #BFBFBF decoration_normal_border_color = #BBBBBB decoration_font = xft: Sans Bold:size=9 window_border_focused_color = black window_border_normal_color = gray # launching and killing programs key_launch_terminal: DefaultMod+Return key_gnome_run: DefaultMod+p key_close_window: DefaultMod+Shift+c key_refresh: DefaultMod+F5 key_window_menu: DefaultMod+o # move focus key_focus_next_window: DefaultMod+j key_focus_prev_window: DefaultMod+k key_focus_master_window: DefaultMod+Space key_focus_next_window_alternative: DefaultMod+Tab key_focus_prev_window_alternative: DefaultMod+Shift+Tab # modifying the window order key_swap_with_master_window: DefaultMod+Shift+Space key_swap_with_next_window: DefaultMod+Shift+j key_swap_with_prev_window: DefaultMod+Shift+k # resizing the master/slave ratio key_shrink_master_area: DefaultMod+h key_expand_master_area: DefaultMod+l key_shrink_slave_area: DefaultMod+u key_expand_slave_area: DefaultMod+i # dialog windows key_treat_as_regular_window: DefaultMod+t key_treat_as_dialog_window: DefaultMod+Shift+t # increase or decrease number of windows in the master area key_inc_windows_in_master_area: DefaultMod+comma key_dec_windows_in_master_area: DefaultMod+period # Metacity-like workspace switching key_prev_workspace: Mod1+Ctrl+Left key_next_workspace: Mod1+Ctrl+Right key_shift_window_to_prev_workspace: Mod1+Ctrl+Shift+Left key_shift_window_to_next_workspace: Mod1+Ctrl+Shift+Right # more Metacity keys key_gnome_run_alternative: Mod1+F2 key_close_window_alternative: Mod1+F4 # switching to layouts key_switch_to_layout_stacked: DefaultMod+a key_switch_to_layout_tiled1: DefaultMod+s key_switch_to_layout_tiled2: DefaultMod+d key_switch_to_layout_fullscreen: DefaultMod+f # maximizing and minimizing key_maximize_window: DefaultMod+z key_minimize_window: DefaultMod+m key_restore_minimized_window: DefaultMod+Shift+m # switching workspaces key_toggle_workspace: DefaultMod+b key_switch_to_workspace_0: DefaultMod+0 key_switch_to_workspace_1: DefaultMod+1 key_switch_to_workspace_2: DefaultMod+2 key_switch_to_workspace_3: DefaultMod+3 key_switch_to_workspace_4: DefaultMod+4 key_switch_to_workspace_5: DefaultMod+5 key_switch_to_workspace_6: DefaultMod+6 key_switch_to_workspace_7: DefaultMod+7 key_switch_to_workspace_8: DefaultMod+8 key_switch_to_workspace_9: DefaultMod+9 # moving clients to workspaces key_shift_window_to_workspace_0: DefaultMod+Shift+0 key_shift_window_to_workspace_1: DefaultMod+Shift+1 key_shift_window_to_workspace_2: DefaultMod+Shift+2 key_shift_window_to_workspace_3: DefaultMod+Shift+3 key_shift_window_to_workspace_4: DefaultMod+Shift+4 key_shift_window_to_workspace_5: DefaultMod+Shift+5 key_shift_window_to_workspace_6: DefaultMod+Shift+6 key_shift_window_to_workspace_7: DefaultMod+Shift+7 key_shift_window_to_workspace_8: DefaultMod+Shift+8 key_shift_window_to_workspace_9: DefaultMod+Shift+9 # multi head: switching and moving clients key_switch_to_screen_0: DefaultMod+w key_switch_to_screen_1: DefaultMod+e key_switch_to_screen_2: DefaultMod+r key_shift_window_to_screen_0: DefaultMod+Shift+w key_shift_window_to_screen_1: DefaultMod+Shift+e key_shift_window_to_screen_2: DefaultMod+Shift+r # misc keybindings - note: these are only listed # for the sake of completeness, some might not work # correctly and are only used during development focus_follows_mouse: false key_quit_bluetile: DefaultMod+Shift+q key_restart_bluetile: DefaultMod+q key_reset_layouts: DefaultMod+Shift+F5 bluetile-0.6/src/0000755000000000000000000000000011664267105012151 5ustar0000000000000000bluetile-0.6/src/Config.hs0000644000000000000000000002643511664267105013724 0ustar0000000000000000{-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS -fno-warn-missing-signatures #-} ---------------------------------------------------------------------------- -- | -- Module : Config -- Copyright : (c) Jan Vornberger 2009 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- -- This module builds an XMonad configuration from Bluetile's configuration -- ----------------------------------------------------------------------------- module Config ( createXMonadConfig ) where import XMonad hiding ( (|||) ) import XMonad.Layout.BorderResize import XMonad.Layout.BoringWindows import XMonad.Layout.ButtonDecoration import XMonad.Layout.Decoration import XMonad.Layout.DecorationAddons import XMonad.Layout.DraggingVisualizer import XMonad.Layout.LayoutCombinators import XMonad.Layout.Maximize import XMonad.Layout.Minimize import XMonad.Layout.MouseResizableTile import XMonad.Layout.Named import XMonad.Layout.NoBorders import XMonad.Layout.PositionStoreFloat import XMonad.Layout.WindowSwitcherDecoration import XMonad.Actions.BluetileCommands import XMonad.Actions.CycleWS import XMonad.Actions.PhysicalScreens import XMonad.Actions.WindowMenu import XMonad.Hooks.CurrentWorkspaceOnTop import XMonad.Hooks.EwmhDesktops import XMonad.Hooks.ICCCMFocus import XMonad.Hooks.ManageDocks import XMonad.Hooks.ManageHelpers import XMonad.Hooks.Minimize import XMonad.Hooks.PositionStoreHooks import XMonad.Hooks.ServerMode import XMonad.Hooks.WorkspaceByPos import XMonad.Config.Gnome import qualified XMonad.StackSet as W import qualified Data.Map as M import System.Exit import Data.Monoid import Control.Monad(when) import ConfigParser bluetileWorkspaces :: [String] bluetileWorkspaces = ["1","2","3","4","5","6","7","8","9","0"] bluetileKeys :: BluetileRC -> XConfig Layout -> M.Map (KeyMask, KeySym) (X ()) bluetileKeys bluetilerc conf = M.fromList $ map (\(desc, action) -> (getKeyBinding desc bluetilerc, action)) $ -- launching and killing programs [ ("key_launch_terminal" , spawn $ XMonad.terminal conf) -- %! Launch terminal , ("key_gnome_run" , gnomeRun) -- %! Launch Gnome "Run application" dialog , ("key_close_window" , kill) -- %! Close the focused window , ("key_refresh" , refresh) -- %! Resize viewed windows to the correct size , ("key_reset_layouts" , setLayout $ XMonad.layoutHook conf) -- %! Reset the layouts on the current workspace to default , ("key_window_menu" , windowMenu) -- move focus up or down the window stack , ("key_focus_next_window" , focusDown) -- %! Move focus to the next window , ("key_focus_prev_window" , focusUp) -- %! Move focus to the previous window , ("key_focus_next_window_alternative" , focusDown) -- %! Move focus to the next window , ("key_focus_prev_window_alternative" , focusUp) -- %! Move focus to the previous window , ("key_focus_master_window" , focusMaster) -- %! Move focus to the master window -- modifying the window order , ("key_swap_with_master_window" , windows W.swapMaster) -- %! Swap the focused window and the master window , ("key_swap_with_next_window" , windows W.swapDown ) -- %! Swap the focused window with the next window , ("key_swap_with_prev_window" , windows W.swapUp ) -- %! Swap the focused window with the previous window -- resizing the master/slave ratio , ("key_shrink_master_area" , sendMessage Shrink) -- %! Shrink the master area , ("key_expand_master_area" , sendMessage Expand) -- %! Expand the master area , ("key_shrink_slave_area" , sendMessage ShrinkSlave) -- %! Shrink a slave area , ("key_expand_slave_area" , sendMessage ExpandSlave) -- %! Expand a slave area -- floating layer support , ("key_treat_as_regular_window" , withFocused $ windows . W.sink) -- %! Push window back into tiling , ("key_treat_as_dialog_window" , withFocused $ float ) -- %! Float window -- increase or decrease number of windows in the master area , ("key_inc_windows_in_master_area" , sendMessage (IncMasterN 1)) -- %! Increment the number of windows in the master area , ("key_dec_windows_in_master_area" , sendMessage (IncMasterN (-1))) -- %! Deincrement the number of windows in the master area -- quit, or restart , ("key_quit_bluetile" , io (exitWith ExitSuccess)) -- %! Quit bluetile , ("key_restart_bluetile" , spawn "bluetile --restart") -- %! Restart bluetile -- Metacity-like workspace switching , ("key_prev_workspace" , prevWS) , ("key_next_workspace" , nextWS) , ("key_shift_window_to_prev_workspace" , shiftToPrev >> prevWS) , ("key_shift_window_to_next_workspace" , shiftToNext >> nextWS) -- more Metacity keys , ("key_gnome_run_alternative" , gnomeRun) , ("key_close_window_alternative" , kill) -- switching to layouts , ("key_switch_to_layout_stacked" , sendMessage $ JumpToLayout "Floating") , ("key_switch_to_layout_tiled1" , sendMessage $ JumpToLayout "Tiled1") , ("key_switch_to_layout_tiled2" , sendMessage $ JumpToLayout "Tiled2") , ("key_switch_to_layout_fullscreen" , sendMessage $ JumpToLayout "Fullscreen") -- maximizing and minimizing , ("key_maximize_window" , withFocused (sendMessage . maximizeRestore)) , ("key_minimize_window" , withFocused minimizeWindow) , ("key_restore_minimized_window" , sendMessage RestoreNextMinimizedWin) -- toggle to previously displayed workspace , ("key_toggle_workspace" , toggleWS) ] ++ -- mod-[1..9] ++ [0] %! Switch to workspace N [("key_switch_to_workspace_" ++ (show wkspNr), windows $ W.greedyView i) | (wkspNr :: Integer, i) <- zip ([1 .. 9] ++ [0]) (XMonad.workspaces conf)] ++ -- mod-shift-[1..9] ++ [0] %! Move client to workspace N [("key_shift_window_to_workspace_" ++ (show wkspNr), windows $ W.shift i) | (wkspNr :: Integer, i) <- zip ([1 .. 9] ++ [0]) (XMonad.workspaces conf)] ++ -- mod-{w,e,r} %! Switch to physical/Xinerama screens 1, 2, or 3 [("key_switch_to_screen_" ++ (show screenNr), viewScreen sc) | (screenNr :: Integer, sc) <- zip [0 .. 2] [0 ..]] -- mod-shift-{w,e,r} %! Move client to screen 1, 2, or 3 ++ [("key_shift_window_to_screen_" ++ (show screenNr), sendToScreen sc) | (screenNr :: Integer, sc) <- zip [0 .. 2] [0 ..]] bluetileMouseBindings :: XConfig Layout -> M.Map (KeyMask, Button) (Window -> X ()) bluetileMouseBindings (XConfig {XMonad.modMask = modMask'}) = M.fromList $ -- mod-button1 %! Move a floated window by dragging [ ((modMask', button1), (\w -> isFloating w >>= \isF -> when (isF) $ focus w >> mouseMoveWindow w >> windows W.shiftMaster)) -- mod-button2 %! Switch to next and first layout , ((modMask', button2), (\_ -> sendMessage NextLayout)) , ((modMask' .|. shiftMask, button2), (\_ -> sendMessage $ JumpToLayout "Floating")) -- mod-button3 %! Resize a floated window by dragging , ((modMask', button3), (\w -> isFloating w >>= \isF -> when (isF) $ focus w >> mouseResizeWindow w >> windows W.shiftMaster)) ] isFloating :: Window -> X (Bool) isFloating w = do ws <- gets windowset return $ M.member w (W.floating ws) bluetileManageHook :: ManageHook bluetileManageHook = composeAll [ workspaceByPos, positionStoreManageHook (Just defaultThemeWithButtons) , className =? "MPlayer" --> doFloat , isFullscreen --> doFullFloat , manageDocks] bluetileLayoutHook bluetileTheme = avoidStruts $ minimize $ boringWindows $ ( named "Floating" floating ||| named "Tiled1" tiled1 ||| named "Tiled2" tiled2 ||| named "Fullscreen" fullscreen ) where floating = floatingDeco $ maximize $ borderResize $ positionStoreFloat tiled1 = tilingDeco $ maximize $ mouseResizableTile { isMirrored = True } tiled2 = tilingDeco $ maximize $ mouseResizableTile fullscreen = tilingDeco $ maximize $ smartBorders Full tilingDeco l = windowSwitcherDecorationWithButtons shrinkText bluetileTheme (draggingVisualizer l) floatingDeco l = buttonDeco shrinkText bluetileTheme l createXMonadConfig bluetilerc = defaultConfig { modMask = defaultModifierBRC bluetilerc, startupHook = ewmhDesktopsStartup, manageHook = bluetileManageHook, layoutHook = bluetileLayoutHook bluetileTheme, logHook = currentWorkspaceOnTop >> ewmhDesktopsLogHook >> takeTopFocus, handleEventHook = ewmhDesktopsEventHook `mappend` fullscreenEventHook `mappend` minimizeEventHook `mappend` serverModeEventHook' bluetileCommands `mappend` positionStoreEventHook, workspaces = bluetileWorkspaces, keys = bluetileKeys bluetilerc, mouseBindings = bluetileMouseBindings, focusFollowsMouse = focusFollowsMouseBRC bluetilerc, normalBorderColor = getDecoConfig "window_border_normal_color" bluetilerc, focusedBorderColor = getDecoConfig "window_border_focused_color" bluetilerc, terminal = terminalBRC bluetilerc } where bluetileTheme = defaultThemeWithButtons { activeColor = getDecoConfig "decoration_focused_color" bluetilerc , activeTextColor = getDecoConfig "decoration_focused_text_color" bluetilerc , activeBorderColor = getDecoConfig "decoration_focused_border_color" bluetilerc , inactiveColor = getDecoConfig "decoration_normal_color" bluetilerc , inactiveTextColor = getDecoConfig "decoration_normal_text_color" bluetilerc , inactiveBorderColor = getDecoConfig "decoration_normal_border_color" bluetilerc , fontName = getDecoConfig "decoration_font" bluetilerc } getDecoConfig :: String -> BluetileRC -> String getDecoConfig desc bluetilerc = case (lookup desc (decorationBRC bluetilerc)) of (Just decoConfig) -> decoConfig (Nothing) -> error $ "Configuration does not include decoration config value for '" ++ desc ++ "'" getKeyBinding :: String -> BluetileRC -> (KeyMask, KeySym) getKeyBinding desc bluetilerc = case (lookup desc (keysBRC bluetilerc)) of (Just keybinding) -> keybinding (Nothing) -> error $ "Configuration does not include key binding for key '" ++ desc ++ "'" bluetile-0.6/src/ConfigParser.hs0000644000000000000000000004352411664267105015077 0ustar0000000000000000{-# LANGUAGE FlexibleContexts #-} ---------------------------------------------------------------------------- -- | -- Module : ConfigParser -- Copyright : (c) Jan Vornberger 2010 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- -- This module helps to parse Bluetile's configuration file -- ----------------------------------------------------------------------------- module ConfigParser ( parseConfigFile, BluetileRC(..), displayIdentifiers ) where import XMonad import qualified Data.ConfigFile as CF import Control.Monad.Error import Data.Char import Data.List import Text.Regex import System.Exit data BluetileRC = BluetileRC { defaultModifierBRC :: KeyMask , focusFollowsMouseBRC :: Bool , terminalBRC :: String , startDockBRC :: Bool , keysBRC :: [(String, (KeyMask, KeySym))] , decorationBRC :: [(String, String)] } deriving (Show) maskKeywordsBRC :: [(String, KeyMask)] maskKeywordsBRC = [ ("Shift", shiftMask) , ("Lock", lockMask) , ("Ctrl", controlMask) , ("Mod1", mod1Mask) , ("Mod2", mod2Mask) , ("Mod3", mod3Mask) , ("Mod4", mod4Mask) , ("Mod5", mod5Mask) ] keysKeywordsBRC :: [(String, KeySym)] keysKeywordsBRC = [ ("BackSpace", xK_BackSpace) , ("Tab", xK_Tab) , ("Linefeed", xK_Linefeed) , ("Clear", xK_Clear) , ("Return", xK_Return) , ("Pause", xK_Pause) , ("Scroll_Lock", xK_Scroll_Lock) , ("Sys_Req", xK_Sys_Req) , ("Escape", xK_Escape) , ("Delete", xK_Delete) , ("Home", xK_Home) , ("Left", xK_Left) , ("Up", xK_Up) , ("Right", xK_Right) , ("Down", xK_Down) , ("Prior", xK_Prior) , ("Page_Up", xK_Page_Up) , ("Next", xK_Next) , ("Page_Down", xK_Page_Down) , ("End", xK_End) , ("Begin", xK_Begin) , ("Select", xK_Select) , ("Print", xK_Print) , ("Execute", xK_Execute) , ("Insert", xK_Insert) , ("Undo", xK_Undo) , ("Redo", xK_Redo) , ("Menu", xK_Menu) , ("Find", xK_Find) , ("Cancel", xK_Cancel) , ("Help", xK_Help) , ("Break", xK_Break) , ("Num_Lock", xK_Num_Lock) , ("KP_Space", xK_KP_Space) , ("KP_Tab", xK_KP_Tab) , ("KP_Enter", xK_KP_Enter) , ("KP_F1", xK_KP_F1) , ("KP_F2", xK_KP_F2) , ("KP_F3", xK_KP_F3) , ("KP_F4", xK_KP_F4) , ("KP_Home", xK_KP_Home) , ("KP_Left", xK_KP_Left) , ("KP_Up", xK_KP_Up) , ("KP_Right", xK_KP_Right) , ("KP_Down", xK_KP_Down) , ("KP_Prior", xK_KP_Prior) , ("KP_Page_Up", xK_KP_Page_Up) , ("KP_Next", xK_KP_Next) , ("KP_Page_Down", xK_KP_Page_Down) , ("KP_End", xK_KP_End) , ("KP_Begin", xK_KP_Begin) , ("KP_Insert", xK_KP_Insert) , ("KP_Delete", xK_KP_Delete) , ("KP_Equal", xK_KP_Equal) , ("KP_Multiply", xK_KP_Multiply) , ("KP_Add", xK_KP_Add) , ("KP_Separator", xK_KP_Separator) , ("KP_Subtract", xK_KP_Subtract) , ("KP_Decimal", xK_KP_Decimal) , ("KP_Divide", xK_KP_Divide) , ("KP_0", xK_KP_0) , ("KP_1", xK_KP_1) , ("KP_2", xK_KP_2) , ("KP_3", xK_KP_3) , ("KP_4", xK_KP_4) , ("KP_5", xK_KP_5) , ("KP_6", xK_KP_6) , ("KP_7", xK_KP_7) , ("KP_8", xK_KP_8) , ("KP_9", xK_KP_9) , ("F1", xK_F1) , ("F2", xK_F2) , ("F3", xK_F3) , ("F4", xK_F4) , ("F5", xK_F5) , ("F6", xK_F6) , ("F7", xK_F7) , ("F8", xK_F8) , ("F9", xK_F9) , ("F10", xK_F10) , ("F11", xK_F11) , ("L1", xK_L1) , ("F12", xK_F12) , ("L2", xK_L2) , ("F13", xK_F13) , ("L3", xK_L3) , ("F14", xK_F14) , ("L4", xK_L4) , ("F15", xK_F15) , ("L5", xK_L5) , ("F16", xK_F16) , ("L6", xK_L6) , ("F17", xK_F17) , ("L7", xK_L7) , ("F18", xK_F18) , ("L8", xK_L8) , ("F19", xK_F19) , ("L9", xK_L9) , ("F20", xK_F20) , ("L10", xK_L10) , ("F21", xK_F21) , ("R1", xK_R1) , ("F22", xK_F22) , ("R2", xK_R2) , ("F23", xK_F23) , ("R3", xK_R3) , ("F24", xK_F24) , ("R4", xK_R4) , ("F25", xK_F25) , ("R5", xK_R5) , ("F26", xK_F26) , ("R6", xK_R6) , ("F27", xK_F27) , ("R7", xK_R7) , ("F28", xK_F28) , ("R8", xK_R8) , ("F29", xK_F29) , ("R9", xK_R9) , ("F30", xK_F30) , ("R10", xK_R10) , ("F31", xK_F31) , ("R11", xK_R11) , ("F32", xK_F32) , ("R12", xK_R12) , ("F33", xK_F33) , ("R13", xK_R13) , ("F34", xK_F34) , ("R14", xK_R14) , ("F35", xK_F35) , ("R15", xK_R15) , ("space", xK_space) , ("exclam", xK_exclam) , ("quotedbl", xK_quotedbl) , ("numbersign", xK_numbersign) , ("dollar", xK_dollar) , ("percent", xK_percent) , ("ampersand", xK_ampersand) , ("apostrophe", xK_apostrophe) , ("quoteright", xK_quoteright) , ("parenleft", xK_parenleft) , ("parenright", xK_parenright) , ("asterisk", xK_asterisk) , ("plus", xK_plus) , ("comma", xK_comma) , ("minus", xK_minus) , ("period", xK_period) , ("slash", xK_slash) , ("0", xK_0) , ("1", xK_1) , ("2", xK_2) , ("3", xK_3) , ("4", xK_4) , ("5", xK_5) , ("6", xK_6) , ("7", xK_7) , ("8", xK_8) , ("9", xK_9) , ("colon", xK_colon) , ("semicolon", xK_semicolon) , ("less", xK_less) , ("equal", xK_equal) , ("greater", xK_greater) , ("question", xK_question) , ("at", xK_at) , ("bracketleft", xK_bracketleft) , ("backslash", xK_backslash) , ("bracketright", xK_bracketright) , ("asciicircum", xK_asciicircum) , ("underscore", xK_underscore) , ("grave", xK_grave) , ("quoteleft", xK_quoteleft) , ("a", xK_a) , ("b", xK_b) , ("c", xK_c) , ("d", xK_d) , ("e", xK_e) , ("f", xK_f) , ("g", xK_g) , ("h", xK_h) , ("i", xK_i) , ("j", xK_j) , ("k", xK_k) , ("l", xK_l) , ("m", xK_m) , ("n", xK_n) , ("o", xK_o) , ("p", xK_p) , ("q", xK_q) , ("r", xK_r) , ("s", xK_s) , ("t", xK_t) , ("u", xK_u) , ("v", xK_v) , ("w", xK_w) , ("x", xK_x) , ("y", xK_y) , ("z", xK_z) , ("braceleft", xK_braceleft) , ("bar", xK_bar) , ("braceright", xK_braceright) , ("asciitilde", xK_asciitilde) , ("nobreakspace", xK_nobreakspace) , ("exclamdown", xK_exclamdown) , ("cent", xK_cent) , ("sterling", xK_sterling) , ("currency", xK_currency) , ("yen", xK_yen) , ("brokenbar", xK_brokenbar) , ("section", xK_section) , ("diaeresis", xK_diaeresis) , ("copyright", xK_copyright) , ("ordfeminine", xK_ordfeminine) , ("guillemotleft", xK_guillemotleft) , ("notsign", xK_notsign) , ("hyphen", xK_hyphen) , ("registered", xK_registered) , ("macron", xK_macron) , ("degree", xK_degree) , ("plusminus", xK_plusminus) , ("twosuperior", xK_twosuperior) , ("threesuperior", xK_threesuperior) , ("acute", xK_acute) , ("mu", xK_mu) , ("paragraph", xK_paragraph) , ("periodcentered", xK_periodcentered) , ("cedilla", xK_cedilla) , ("onesuperior", xK_onesuperior) , ("masculine", xK_masculine) , ("guillemotright", xK_guillemotright) , ("onequarter", xK_onequarter) , ("onehalf", xK_onehalf) , ("threequarters", xK_threequarters) , ("questiondown", xK_questiondown) , ("Agrave", xK_Agrave) , ("Aacute", xK_Aacute) , ("Acircumflex", xK_Acircumflex) , ("Atilde", xK_Atilde) , ("Adiaeresis", xK_Adiaeresis) , ("Aring", xK_Aring) , ("AE", xK_AE) , ("Ccedilla", xK_Ccedilla) , ("Egrave", xK_Egrave) , ("Eacute", xK_Eacute) , ("Ecircumflex", xK_Ecircumflex) , ("Ediaeresis", xK_Ediaeresis) , ("Igrave", xK_Igrave) , ("Iacute", xK_Iacute) , ("Icircumflex", xK_Icircumflex) , ("Idiaeresis", xK_Idiaeresis) , ("ETH", xK_ETH) , ("Eth", xK_Eth) , ("Ntilde", xK_Ntilde) , ("Ograve", xK_Ograve) , ("Oacute", xK_Oacute) , ("Ocircumflex", xK_Ocircumflex) , ("Otilde", xK_Otilde) , ("Odiaeresis", xK_Odiaeresis) , ("multiply", xK_multiply) , ("Ooblique", xK_Ooblique) , ("Ugrave", xK_Ugrave) , ("Uacute", xK_Uacute) , ("Ucircumflex", xK_Ucircumflex) , ("Udiaeresis", xK_Udiaeresis) , ("Yacute", xK_Yacute) , ("THORN", xK_THORN) , ("Thorn", xK_Thorn) , ("ssharp", xK_ssharp) , ("agrave", xK_agrave) , ("aacute", xK_aacute) , ("acircumflex", xK_acircumflex) , ("atilde", xK_atilde) , ("adiaeresis", xK_adiaeresis) , ("aring", xK_aring) , ("ae", xK_ae) , ("ccedilla", xK_ccedilla) , ("egrave", xK_egrave) , ("eacute", xK_eacute) , ("ecircumflex", xK_ecircumflex) , ("ediaeresis", xK_ediaeresis) , ("igrave", xK_igrave) , ("iacute", xK_iacute) , ("icircumflex", xK_icircumflex) , ("idiaeresis", xK_idiaeresis) , ("eth", xK_eth) , ("ntilde", xK_ntilde) , ("ograve", xK_ograve) , ("oacute", xK_oacute) , ("ocircumflex", xK_ocircumflex) , ("otilde", xK_otilde) , ("odiaeresis", xK_odiaeresis) , ("division", xK_division) , ("oslash", xK_oslash) , ("ugrave", xK_ugrave) , ("uacute", xK_uacute) , ("ucircumflex", xK_ucircumflex) , ("udiaeresis", xK_udiaeresis) , ("yacute", xK_yacute) , ("thorn", xK_thorn) , ("ydiaeresis", xK_ydiaeresis) ] maskKeywordsBRC' :: [(String, KeyMask)] maskKeywordsBRC' = map (\(k, v) -> (map toLower k, v)) maskKeywordsBRC keysKeywordsBRC' :: [(String, KeySym)] keysKeywordsBRC' = map (\(k, v) -> (map toLower k, v)) keysKeywordsBRC lookupMask :: MonadError CF.CPError m => [(String, KeyMask)] -> String -> m KeyMask lookupMask t k = case (lookup (map toLower k) t) of (Just v) -> return v (Nothing) -> throwError (CF.OtherProblem ("Unknown modifier '" ++ k ++ "'"), "other_problem") lookupKey :: MonadError CF.CPError m => String -> m KeySym lookupKey k = case (lookup (map toLower k) keysKeywordsBRC') of (Just v) -> return v (Nothing) -> throwError (CF.OtherProblem ("Unknown key '" ++ k ++ "'"), "other_problem") parseKeyCombo :: MonadError CF.CPError m => [(String, KeyMask)] -> String -> m (KeyMask, KeySym) parseKeyCombo maskKBRC combo = do let parts = splitRegex (mkRegex "\\+") combo if (length parts > 0) then do masks <- mapM (lookupMask maskKBRC) (init parts) key <- lookupKey (last parts) return (foldl (.|.) 0 masks, key) else throwError (CF.OtherProblem ("Empty key binding"), "other_problem") parseKeyBinding :: MonadError CF.CPError m => [(String, KeyMask)] -> (String, String) -> m (String, (KeyMask, KeySym)) parseKeyBinding maskKBRC (desc, keyCombo) = do keyBinding <- parseKeyCombo maskKBRC keyCombo return (desc, keyBinding) parseConfigFile :: FilePath -> FilePath -> IO BluetileRC parseConfigFile systemConfig userConfig = do rv <- runErrorT $ do -- read files cpDefault <- join $ liftIO $ CF.readfile CF.emptyCP systemConfig cp <- join $ liftIO $ CF.readfile cpDefault userConfig -- global options defaultModifierCF <- lookupMask maskKeywordsBRC' =<< CF.get cp "DEFAULT" "default_modifier" terminalCF <- CF.get cp "DEFAULT" "terminal" focusFollowsMouseCF <- CF.get cp "DEFAULT" "focus_follows_mouse" startDockCF <- CF.get cp "DEFAULT" "start_dock" let maskKeywordsBRCwithDefault = maskKeywordsBRC' ++ [("defaultmod", defaultModifierCF)] -- theme itemsCF <- CF.items cp "DEFAULT" let colorsCF = filter (\(k, _) -> isPrefixOf "decoration_" k) itemsCF ++ filter (\(k, _) -> isPrefixOf "window_border_" k) itemsCF -- keys let keyBindingsCFstr = filter (\(k, _) -> isPrefixOf "key_" k) itemsCF keyBindingsCF <- mapM (parseKeyBinding maskKeywordsBRCwithDefault) keyBindingsCFstr let bluetilerc = BluetileRC { defaultModifierBRC = defaultModifierCF , focusFollowsMouseBRC = focusFollowsMouseCF , terminalBRC = terminalCF , startDockBRC = startDockCF , keysBRC = keyBindingsCF , decorationBRC = colorsCF } return bluetilerc case rv of (Left err) -> do putStrLn "There was a problem reading the configuration. This is what the parser told me:" putStrLn (show err) exitFailure (Right bluetilerc) -> do return bluetilerc displayIdentifiers :: IO () displayIdentifiers = do putStrLn "The following modifiers can be used in Bluetile's configuration:" putStrLn $ concat $ intersperse ", " ("DefaultMod" : (map fst maskKeywordsBRC)) putStrLn "" putStrLn "The following keys can be used in Bluetile's configuration:" putStrLn $ concat $ intersperse ", " (map fst keysKeywordsBRC) bluetile-0.6/src/Main.hs0000644000000000000000000000730711664267105013400 0ustar0000000000000000---------------------------------------------------------------------------- -- | -- Module : Main -- Copyright : (c) Jan Vornberger 2009 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- -- Bluetile - full-featured tiling for the GNOME desktop environment -- ----------------------------------------------------------------------------- module Main (main) where import XMonad import XMonad.Util.Run (spawnPipe) import XMonad.Util.Replace import BluetileDock import Config import ConfigParser import System.Environment import System.FilePath import System.Directory import Control.Monad import Paths_bluetile import Data.Version(showVersion) -- | The entry point into bluetile. Just launch with the default -- configuration. Compiling a custom configuration is not supported for now. main :: IO () main = do -- process arguments args <- getArgs case args of [] -> launch ("--resume":_) -> launch ["--help"] -> usage ["--list-identifiers"] -> displayIdentifiers ["--restart"] -> sendRestart >> return () ["--version"] -> putStrLn ("bluetile " ++ showVersion version) _ -> fail "unrecognized flags" launch :: IO () launch = do putStrLn "Welcome to Bluetile! The window manager is now attempting to start up." putStrLn "Information: Two helper applications should appear (Bluetile's dock and" putStrLn "a greeting screen). However, even if you see these applications, the actual" putStrLn "window manager might still have failed to start. Make sure to check the output" putStrLn "below for any errors and have a look at the window decorations, to be sure," putStrLn "that Bluetile started successfully. Happy tiling!" putStrLn "" -- check if configuration present home <- getEnv "HOME" let userConfig = home ".bluetilerc" dataDir <- getDataDir let systemConfig = dataDir "etc" "bluetilerc" let userConfigTemplate = dataDir "etc" "bluetilerc_user_template" userConfigPresent <- doesFileExist userConfig unless (userConfigPresent) $ copyFile userConfigTemplate userConfig -- read configuration bluetilerc <- parseConfigFile systemConfig userConfig let xmonadConfig = createXMonadConfig bluetilerc -- start docks and greeting screen libexecDir <- getLibexecDir xmonadConfig' <- case (startDockBRC bluetilerc) of True -> do dockHandle <- spawnPipe $ libexecDir "bluetiledock" return xmonadConfig { logHook = logHook xmonadConfig >> bluetileDock dockHandle } False -> return xmonadConfig spawnPipe $ libexecDir "bluetilegreet" replace xmonad xmonadConfig' usage :: IO () usage = do self <- getProgName putStr . unlines $ concat ["Usage: ", self, " [OPTION]"] : "Options:" : " --help Print this message" : " --version Print the version number" : " --list-identifiers Print modifiers and keys that can be used in the configuration" : " --restart Request a running Bluetile process to restart" : [] sendRestart :: IO () sendRestart = do dpy <- openDisplay "" rw <- rootWindow dpy $ defaultScreen dpy a <- internAtom dpy "XMONAD_COMMAND" False allocaXEvent $ \e -> do setEventType e clientMessage setClientMessageEvent e rw a 32 1 currentTime sendEvent dpy rw False structureNotifyMask e sync dpy False bluetile-0.6/src/BluetileDock.hs0000644000000000000000000000242711664267105015060 0ustar0000000000000000---------------------------------------------------------------------------- -- | -- Module : BluetileDock -- Copyright : (c) Jan Vornberger 2009 -- License : BSD3-style (see LICENSE) -- -- Maintainer : jan.vornberger@informatik.uni-oldenburg.de -- Stability : unstable -- Portability : not portable -- ----------------------------------------------------------------------------- module BluetileDock (bluetileDock) where import XMonad import qualified XMonad.StackSet as S import System.IO import Control.Monad(forM_) data DockOutput = DO Int String String deriving (Show, Read) bluetileDock :: Handle -> X () bluetileDock outputHandle = do ws <- gets windowset let allscreens = S.screens ws let outputs = for allscreens $ \s -> DO (getScreenId (S.screen s)) (getLayoutDesc s) (getCurrentWorkspace s) forM_ outputs $ \o -> io $ hPutStrLn outputHandle $ show o getScreenId :: ScreenId -> Int getScreenId (S sid) = sid getLayoutDesc :: S.Screen i (Layout Window) a sid sd -> String getLayoutDesc = description . S.layout . S.workspace getCurrentWorkspace :: S.Screen i l a sid sd -> i getCurrentWorkspace = S.tag . S.workspace for :: [a] -> (a -> b) -> [b] for = flip map