From 7fae558c198d53e5c0ba3a0050a659c7da8cd3b7 Mon Sep 17 00:00:00 2001 From: Ilya Portnov Date: Sun, 15 May 2011 13:29:07 +0600 Subject: [PATCH] Updates... --- lib/AppGroups.hs | 82 +++++++++++++++++++++++++++++------------------ lib/CommonFunctions.hs | 32 +++++++++++++++--- lib/GroupsSetup.hs | 38 ++++++++++++---------- lib/KeyBindings.hs | 19 +++++------ lib/Themes.hs | 2 +- xmonad.hs | 3 +- 6 files changed, 107 insertions(+), 69 deletions(-) diff --git a/lib/AppGroups.hs b/lib/AppGroups.hs index 7040f95..3ad3086 100644 --- a/lib/AppGroups.hs +++ b/lib/AppGroups.hs @@ -1,9 +1,9 @@ {-# LANGUAGE ExistentialQuantification, TypeSynonymInstances, FlexibleInstances #-} module AppGroups - (Key, App (..), Apps, Condition (..), Cond (..), Regex (..), + (Key, App (..), Apps, Condition (..), Cond (..), query, oneOf, apps2hooks, apps2keys, - selectAppGroup, + selectAppGroup, runNewApp, switchToApp, doFullscreen) where @@ -18,7 +18,7 @@ import qualified XMonad.StackSet as W import XMonad.Actions.GridSelect import XMonad.Actions.DynamicWorkspaces import XMonad.Util.WindowProperties --- import XMonad.Hooks.ManageHelpers hiding (C) +import XMonad.Util.WindowPropertiesRE import CommonFunctions ((~?), selectOneWindow) @@ -65,30 +65,13 @@ instance Condition String where instance Condition Property where toQuery p = propertyToQuery p --- | Regular expression over condition -data (Condition a) => Regex a = Regex a - -instance (Show a, Condition a) => Show (Regex a) where - show (Regex a) = show a - -instance Condition (Regex String) where - toQuery (Regex s) = className ~? s +instance Condition PropertyRE where + toQuery (RE p) = propertyToQueryRE p -- | Query WM_WINDOW_ROLE atom role :: Query String role = stringProperty "WM_WINDOW_ROLE" -instance Condition (Regex Property) where - toQuery (Regex (Title s)) = title ~? s - toQuery (Regex (Resource s)) = resource ~? s - toQuery (Regex (ClassName s)) = className ~? s - toQuery (Regex (Role s)) = role ~? s - toQuery (Regex (Machine s)) = stringProperty "WM_CLIENT_MACHINE" ~? s - toQuery (Regex (And p1 p2)) = toQuery p1 <&&> toQuery p2 - toQuery (Regex (Or p1 p2)) = toQuery p1 <||> toQuery p2 - toQuery (Regex (Not p)) = not `fmap` toQuery p - toQuery (Regex (Const b)) = return b - -- | Turn any X () operation on window into ManageHook fromWindowOp :: (Window -> X()) -> ManageHook fromWindowOp fn = ask >>= \w -> liftX (fn w) >> doF id @@ -176,14 +159,35 @@ groupName (_ :-> wksp) = wksp groupName (Float app) = groupName app groupName (Named _ name) = name +appWorkspace :: App -> Maybe WorkspaceId +appWorkspace (On app _) = appWorkspace app +appWorkspace (_ ::: _) = Nothing +appWorkspace (_ :>> _) = Nothing +appWorkspace (Group _) = Nothing +appWorkspace (_ :-> wksp) = Just wksp +appWorkspace (Float app) = appWorkspace app +appWorkspace (Fullscreen app) = appWorkspace app +appWorkspace (Named app _) = appWorkspace app + +appAction :: App -> Maybe (X ()) +appAction (On app _) = appAction app +appAction (command ::: app) = Just $ spawn command +appAction (action :>> _) = Just action +appAction (Group _) = Nothing +appAction (Fullscreen app) = appAction app +appAction (Named app _) = appAction app +appAction (Float app) = appAction app +appAction (app :-> _) = appAction app + runApp :: App -> X () -runApp (On app _) = runApp app -runApp (command ::: _) = spawn command -runApp (action :>> _) = action -runApp (Group _) = return () -runApp (Fullscreen app) = runApp app -runApp (app :-> _) = runApp app -runApp (Named app _) = runApp app +runApp (command ::: _) = spawn command +runApp (app :-> wksp) = runApp app +runApp (action :>> _) = action +runApp (On app _) = runApp app +runApp (Group _) = return () +runApp (Fullscreen ap) = runApp ap +runApp (Float app) = runApp app +runApp (Named app _) = runApp app apps2hooks :: Apps -> [ManageHook] apps2hooks lst = map appHook lst @@ -230,7 +234,21 @@ selectAppGroup gscA gscW apps = do group <- gridselect gscA $ zip names nonempty whenJust group $ \app -> selectWithQuery gscW (query app) (runApp app) - where - isNotEmpty :: App -> X Bool - isNotEmpty group = (not . null) `fmap` matchingWindows (query group) + +isNotEmpty :: App -> X Bool +isNotEmpty group = (not . null) `fmap` matchingWindows (query group) + +shouldRun :: App -> X Bool +shouldRun group = do + ws <- matchingWindows (query group) + if null ws + then return $ isJust $ appAction group + else return False + +runNewApp :: GSConfig App -> Apps -> X () +runNewApp gsconfig apps = do + empty <- filterM shouldRun apps + let names = map groupName empty + selected <- gridselect gsconfig $ zip names empty + whenJust selected runApp diff --git a/lib/CommonFunctions.hs b/lib/CommonFunctions.hs index d0cde73..a437306 100644 --- a/lib/CommonFunctions.hs +++ b/lib/CommonFunctions.hs @@ -7,7 +7,8 @@ module CommonFunctions gotoWorkspace, selectOneWindow, searchInWorkspace, specialMove, - vimsessions, textEditors, + vimsession, vimsessions, textEditors, + edit_config, recent, (~?), isFloat, @@ -36,6 +37,7 @@ import XMonad.Util.NamedWindows import XMonad.Actions.DynamicWorkspaces import XMonad.Actions.GridSelect +import XMonad.Actions.SpawnOn import Themes @@ -144,6 +146,9 @@ returnToCurrent c s = W.view curtag s curstack :: W.StackSet i l a sid sd -> Maybe (W.Stack a) curstack s = W.stack $ W.workspace $ W.current s +getCurrentWorkspace :: X WorkspaceId +getCurrentWorkspace = withWindowSet (\ws -> return $ W.tag $ W.workspace $ W.current ws) + emptyCurrentWorkspace :: (Eq s) => W.StackSet String l a s sd -> W.StackSet String l a s sd emptyCurrentWorkspace s = returnToCurrent s (addStackToTarget "trash" (curstack s) $ emptyCurrentWs s) @@ -202,15 +207,21 @@ recent types = "recently-used.py " ++ unwords (map mime types) ("doc", "application/msword application/vnd.oasis.opendocument.text"), ("png", "image/png")] +-- | Open specified GVim session +vimsession :: String -> X () +vimsession name = do + home <- io $ getEnv "HOME" + let path = home ".vim/sessions" (name ++ ".vimsession") + spawn ("gvim -S " ++ path) + -- | Open selected GVim session vimsessions :: X () vimsessions = do home <- io $ getEnv "HOME" paths <- io $ (concat . fst) `fmap` globDir [compile "*.vimsession"] (home ".vim/sessions") - let actions = map ("gvim -S " ++) paths - sessions = map (dropExtension . takeFileName) paths - selected <- gridselect myGSConfig $ zip sessions actions - whenJust selected spawn + let sessions = map (dropExtension . takeFileName) paths + selected <- gridselect myGSConfig $ zip sessions sessions + whenJust selected vimsession -- | Run the selected text editor textEditors :: X () @@ -246,10 +257,19 @@ trashWindow = do -- | On window unmap, remove current workspace if it's empty. unmapEventHook :: Event -> X All -unmapEventHook (UnmapEvent {}) = removeEmptyWorkspace >> return (All True) +unmapEventHook (UnmapEvent {}) = do + current <- getCurrentWorkspace + when (current /= "dashboard") removeEmptyWorkspace + return (All True) unmapEventHook _ = return (All True) -- | Regular expressions matching for ManageHooks (~?) :: (Functor f) => f String -> String -> f Bool q ~? x = fmap (=~ x) q +edit_config :: X () +edit_config = do + vimsession "xmonad" + spawnOn "text" =<< asks (terminal . config) + + diff --git a/lib/GroupsSetup.hs b/lib/GroupsSetup.hs index 54f7163..d8d54e4 100644 --- a/lib/GroupsSetup.hs +++ b/lib/GroupsSetup.hs @@ -1,35 +1,37 @@ {-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts #-} module GroupsSetup where +import XMonad.Util.WindowProperties +import XMonad.Util.WindowPropertiesRE + import AppGroups -import CommonFunctions (textEditors, recent) +import CommonFunctions (textEditors, recent, edit_config) -regex :: (Condition (Regex a), Condition a) => a -> Cond -regex = C . Regex +regex = C . RE . ClassName defaultFM :: String defaultFM = "konqueror --profile filemanagement" myApps = [ "iceweasel" ::: [C "Epiphany-browser", C "Kontact", C "Iceweasel", - C "Firefox", C "Opera", C "Arora" ] :-> "inet" `On` "M1-x w" `Named` "internet", - "icedove" ::: [C "Icedove", C "Kontact" ] :-> "inet" `On` "M1-x y" `Named` "mail", - "rssowl" ::: [C "Liferea", C "RSSOwl"] :-> "inet" `Named` "rss", - "transmission-gtk" ::: [regex "Transmission"] :-> "torrents" `On` "M1-x r", + C "Firefox", C "Opera", C "Arora" ] :-> "inet" `On` "M1-x w" `Named` "internet", + "icedove" ::: [C "Icedove", C "Kontact" ] :-> "inet" `On` "M1-x y" `Named` "mail", + "rssowl" ::: [C "Liferea", C "RSSOwl"] :-> "inet" `Named` "rss", + "transmission-gtk" ::: [regex "Transmission"] :-> "torrents" `On` "M1-x r", Group [C "Inkscape", C "Eog", C "Gwenview", C "Dia", C "MyPaint"] :-> "graphics" `On` "M1-x d", - Group [regex "Gimp"] :-> "gimp" `On` "M1-x g", - Group [C "F-spot",C "Digikam"] :-> "photo" `On` "M1-x p", - "gnome-terminal" ::: [C "Gnome-terminal", C "Konsole"] :-> "term" `On` "M1-x t", + Group [regex "Gimp"] :-> "gimp" `On` "M1-x g", + Group [C "F-spot",C "Digikam"] :-> "photo" `On` "M1-x p", + "gnome-terminal" ::: [C "Gnome-terminal", C "Konsole"] :-> "term" `On` "M1-x t", textEditors :>> [C "Gedit", C "Leafpad", - C "Gvim", C "Kate", C "KWrite", C "Emacs"] :-> "text" `On` "M1-x e", - recent ["doc"] ::: [regex "libreoffice", C "TeXmacs"] :-> "office" `On` "M1-x o", - recent ["pdf","djvu"] ::: [C "Evince", C "Okular"] :-> "docs" `On` "M1-x k", + C "Gvim", C "Kate", C "Kwrite", C "Emacs"] :-> "text" `On` "M1-x e", + recent ["doc"] ::: [regex "libreoffice", C "TeXmacs"] :-> "office" `On` "M1-x o", + recent ["pdf","djvu"] ::: [C "Evince", C "Okular"] :-> "docs" `On` "M1-x k", defaultFM ::: [C "Nautilus", C "Dolphin", C "Konqueror", - C "Krusader"] :-> "files" `On` "M1-x f", + C "Krusader"] :-> "files" `On` "M1-x f", Group [C "Amarok", C "Rhythmbox", - regex "Audacious" ] :-> "music" `On` "M1-x a", - Group [C "MPlayer", C "Totem"] :-> "video" `On` "M1-x v", - Group [C "Wxmaxima"] :-> "math" `On` "M1-x m", - "pidgin" ::: [C "Pidgin", C "Kopete"] :-> "im" `On` "M1-x i" ] + regex "Audacious" ] :-> "music" `On` "M1-x a", + Group [C "MPlayer", C "Totem"] :-> "video" `On` "M1-x v", + Group [C "Wxmaxima"] :-> "math" `On` "M1-x m", + "pidgin" ::: [C "Pidgin", C "Kopete"] :-> "im" `On` "M1-x i"] diff --git a/lib/KeyBindings.hs b/lib/KeyBindings.hs index 9889250..6fa0cfd 100644 --- a/lib/KeyBindings.hs +++ b/lib/KeyBindings.hs @@ -32,7 +32,7 @@ import XMonad.Prompt.Window import CommonFunctions import Mouse import Themes (myXPConfig, myGSConfig, searchGS) -import AppGroups (switchToApp) +import AppGroups (switchToApp, runNewApp) import GroupsSetup (myApps) workspaceOrder = ["inet","text","files","im","term"] @@ -68,6 +68,7 @@ addKeys = [-- ("M1-", gnomeRun), ("M1-", spawn "gmrun"), ("", spawn "qwerty.py -a -f -g 640x400"), ("M-v", vimsessions), + ("M-a", runNewApp searchGS myApps), -- close focused window ("M1-", killIfNot (Role "buddy_list")), @@ -83,14 +84,13 @@ addKeys = [-- ("M1-", gnomeRun), ("M-b", sendMessage $ ToggleStruts), - -- Focus urgent window - ("M-", focusUrgent), + ("M1-e", windows (W.greedyView "dashboard")), -- Bring any window to current workspace - ("M1-w", windowPromptBring myXPConfig), - ("M1-x x", searchInWorkspace searchGS), - ("M1-z", goToSelected searchGS), - ("M-z", gridselectWorkspace searchGS W.greedyView), + ("M1-w", bringSelected searchGS), + ("M1-", searchInWorkspace searchGS), + ("M-", gridselectWorkspace searchGS W.greedyView), + ("M1-/", goToSelected searchGS), ("M-", nextMatch History (return True)), @@ -99,7 +99,6 @@ addKeys = [-- ("M1-", gnomeRun), -- Move focus to the next window -- ("M1-", windows W.focusDown), - ("M1-", searchInWorkspace searchGS), ("M-j", windows W.focusDown), ("M-k", windows W.focusUp ), @@ -125,8 +124,6 @@ addKeys = [-- ("M1-", gnomeRun), ("M-M1-u", withFocused (sendMessage . UnMerge)), - ("M-M1-u", withFocused (sendMessage . UnMergeAll)), - -- Shrink/expand the master area ("M-e", sendMessage Shrink), ("M-r", sendMessage Expand), @@ -134,7 +131,7 @@ addKeys = [-- ("M1-", gnomeRun), -- Push window back into tiling ("M-S-f", withFocused $ windows . W.sink), - ("M-", spawn "gvim ~/.xmonad/xmonad.hs"), + ("M-", edit_config), ("M-l", spawn "xscreensaver-command -lock"), diff --git a/lib/Themes.hs b/lib/Themes.hs index 003d740..47c50f1 100644 --- a/lib/Themes.hs +++ b/lib/Themes.hs @@ -28,7 +28,7 @@ searchGS = defaultGSConfig { ----------------------------------------------------------------------- -- Some general settings myWorkspaces :: [WorkspaceId] -myWorkspaces = ["main"] +myWorkspaces = ["dashboard"] myFocusedBorderColor :: String myFocusedBorderColor = "#E3A775" diff --git a/xmonad.hs b/xmonad.hs index c7cdb0c..d56e8ac 100644 --- a/xmonad.hs +++ b/xmonad.hs @@ -6,6 +6,7 @@ import XMonad.Config.Kde (kde4Config) import XMonad.Actions.GroupNavigation (historyHook) import XMonad.Actions.UpdatePointer +import XMonad.Actions.SpawnOn -- Import hooks to support EWMH and other compatibility hooks import XMonad.Hooks.EwmhDesktops (ewmh) @@ -45,7 +46,7 @@ main = do -- hooks, layouts layoutHook = myLayout, handleEventHook = unmapEventHook <+> minimizeEventHook, - manageHook = baseManageHook <+> myManageHook, + manageHook = manageSpawn <+> baseManageHook <+> myManageHook, logHook = do baseLogHook updatePointer (TowardsCentre 0.5 0.5) -- 1.7.2.3