1138 Commits
v0.4 ... v0.8.1

Author SHA1 Message Date
Spencer Janssen
b456b87e0e TAG 0.8.1 2009-01-18 22:06:47 +00:00
Spencer Janssen
da2a08ec7e Use spawnOn in my config 2009-01-17 04:10:26 +00:00
Spencer Janssen
c51f64476a Add XMonad.Actions.SpawnOn 2009-01-17 04:04:32 +00:00
Spencer Janssen
d1b2eb4bbb Bump version to 0.8.1 2009-01-16 22:36:07 +00:00
Spencer Janssen
03513bb9b4 Compile without optimizations on x86_64 and GHC 6.10
This is a workaround for http://xmonad.org/bugs/226
2009-01-08 23:16:50 +00:00
Spencer Janssen
0272b8e468 Update all uses of doubleFork/waitForProcess 2009-01-16 21:03:15 +00:00
Spencer Janssen
b1984eef30 Update to my config 2009-01-16 20:45:53 +00:00
Daniel Schoepe
deacde29a0 Adjustments to new userCode function 2009-01-10 22:13:10 +00:00
Brent Yorgey
22ea09d747 X.U.EZConfig: expand documentation 2009-01-16 15:31:43 +00:00
Brent Yorgey
2786791ff5 add a bit of documentation to HintedTile 2009-01-14 06:51:26 +00:00
johanngiwer
021298cb34 ManageHelpers: add isDialog 2009-01-08 23:25:05 +00:00
portnov84
f885e942e9 CenteredMaster
centerMaster layout modifier places master window at top of other, at center of screen. Other windows are managed by base layout.
topRightMaster is similar, but places master window at top right corner.
2009-01-11 13:45:13 +00:00
gwern0
b5d77062b9 XMonad.Util.XSelection: update maintainer information 2009-01-10 21:30:00 +00:00
Brent Yorgey
bcec549103 X.U.XSelection: get rid of warning about missing newline, add Haddock link 2009-01-02 19:43:57 +00:00
loupgaroublond
d889c531d0 adds haddock documentation for transformPromptSelection
also renames the function per mailing list recommendation
2009-01-02 19:09:54 +00:00
loupgaroublond
44b9610906 adds a weird function to XSelection
This enables you to pass a function of (String -> String) to a selection function to modify the string before executing it.  This way, you can input your own escape routines to make it shell command line safe, and/or do other fancier things.
2008-12-22 02:07:30 +00:00
xmonad
f3617e75c5 ThreeColumnsMiddle 2009-01-02 09:10:19 +00:00
rupa
56850074df fix-fromJust-errors
bogner wrote all this stuff and i just tested it.

I had:

myLogHook = ewmhDesktopLogHookCustom ScratchpadFilterOutWorkspace >> updatePointer Nearest

Everytime I invoked or hid Scratchpad, it would leave a 'Maybe.fromJust: Nothing' line in .xsession-errors, and updatePointer would stop working.
2008-12-24 04:55:09 +00:00
Dominik Bruhn
3ac1205411 Prompt: Change Filemode to 600 for history-file (fixes bug 244) 2008-12-18 00:16:01 +00:00
Roman Cheplyaka
ed240c6972 X.L.Monitor: changes in message passing
- transform mbName (Maybe String) to name (String)
- slghtly change semantics of messages, document it
2008-12-26 22:08:51 +00:00
Roman Cheplyaka
d44ca42551 X.L.Monitor: change interface
- remove add*Monitor
- add manageMonitor, monitor template
2008-12-26 21:31:18 +00:00
Roman Cheplyaka
fc581c9e4a X.U.WindowProperties: propertyToQuery+docs 2008-12-25 08:07:02 +00:00
Roman Cheplyaka
c5af703cb8 X.L.Monitor: docs 2008-12-25 07:39:04 +00:00
gwern0
42692986e6 hlintify XUtils, XSelection, Search, WindowGo 2008-12-20 15:33:02 +00:00
Norbert Zeh
88e524f480 fix focus issue for XMonad.Actions.Warp.banishScreen
This patch ensures that the focus (or in fact the whose windowset)
does not change as a result of a banishScreen.  The way this is implemented
will become problematic if xmonad ever goes multithreaded.
2008-12-12 20:35:32 +00:00
Norbert Zeh
4c7ebafcfe addition of XMonad.Actions.Warp.banishScreen
This works on top of warpToScreen and, thus, suffers from the same issue:
focus change.
2008-12-12 19:26:21 +00:00
Norbert Zeh
fe253a602c fixed documentation for banish
banish actually warps to the specified corner of the current window, not
the screen.
2008-12-12 19:18:19 +00:00
Norbert Zeh
52379a3736 addition of combined TallGrid layout
Added a module XMonad.Layouts.GridVariants, which defines layouts
Grid and TallGrid.  The former is a customizable version of Grid.  The latter
is a combination of Grid and Tall (see doc of the module).
2008-12-12 18:48:36 +00:00
Justin Bogner
a11a42b2a5 Add FixedColumn, a layout like Tall but based on the resize hints of windows 2008-12-13 07:30:54 +00:00
gwern0
afa80ad2a2 XMonad.Actions.WindowGo: fix a floating-related focus bug
If a floating window was focused, a cross-workspace 'raise' would cause a loop of
shifting windows. Apparently the problem was 'focus' and its mouse-handling. Spencer
suggested that the calls to focus be replaced with 'focusWindow', which resolved it.
2008-12-05 15:07:55 +00:00
gwern0
ef310e1792 Prompt.hs: +greenXPConfig and amberXPConfig 2008-11-19 21:31:22 +00:00
gwern0
8afb72a48e Prompt.hs: increase font size to 12 from niggardly 10 2008-11-19 21:25:23 +00:00
gwern0
a521838fac Prompt.hs: replace magic numbers with understandable names 2008-11-19 21:25:02 +00:00
Roman Cheplyaka
8698e58f12 X.L.Monitor: recommend doHideIgnore (docs) 2008-12-15 19:07:10 +00:00
Roman Cheplyaka
99f04b7504 X.L.Monitor: docs 2008-12-15 18:44:23 +00:00
Roman Cheplyaka
f365c082ba X.L.Monitor: export Monitor datatype 2008-12-15 18:43:18 +00:00
Roman Cheplyaka
601c3c06db X.H.ManageHelpers: add doHideIgnore 2008-12-15 18:27:58 +00:00
Spencer Janssen
9d0f34852c Add KDE 4 config, thanks to Shirakawasuna on IRC 2008-12-11 07:11:41 +00:00
Spencer Janssen
293b8152aa I use the deleteConsecutive history filter 2008-10-25 07:04:38 +00:00
Braden Shepherdson
1d78c1fd60 Remove XMonad.Config.PlainConfig, it has been turned into the separate xmonad-light project. 2008-12-03 16:15:34 +00:00
gwern0
96786e0abd XMonad.Prompt: swap up and down per bug #243 2008-12-03 01:33:23 +00:00
Aleksandar Dimitrov
78a9495c03 Fix boolean operator precedence in GridSelect keybindings
The vim-like hjkl keys were ORed to the key event AND arrow keys.
2008-12-01 12:09:28 +00:00
sean.escriva
0462f00f42 GridSelect.hs: navigate grid with h,j,k,l as well as arrow keys 2008-11-22 08:47:25 +00:00
Roman Cheplyaka
3b4473f121 Export setOpacity from FadeInactive. Document how to make monitor transparent (X.L.Monitor) 2008-11-17 15:30:27 +00:00
Roman Cheplyaka
6962d8f216 Monitor: use broadcastMessage instead of sendMessage; this solves several issues 2008-11-17 13:39:57 +00:00
Roman Cheplyaka
0a935aff63 FadeInactive: fade all inactive windows (including focused windows on visible screens) 2008-11-17 13:01:15 +00:00
Roman Cheplyaka
642cbdcad6 Monitor: documented one more issue 2008-11-17 11:38:07 +00:00
Roman Cheplyaka
1a6c11e8e6 Monitor: improved the docs 2008-11-17 07:37:09 +00:00
Roman Cheplyaka
8cc3556448 added XMonad.Layout.Monitor 2008-11-15 10:47:35 +00:00
Roman Cheplyaka
d043dfbaf9 WindowProperties: added allWithProperty 2008-11-15 10:45:25 +00:00
Roman Cheplyaka
565dd89ebe ManageHelpers: added doSideFloat (generalization of doCenterFloat) 2008-11-14 11:30:15 +00:00
Dominik Bruhn
20119ffa7a GridSelect: Export default_colorizer 2008-11-12 14:00:05 +00:00
Dominik Bruhn
7337ce50c2 Simplify code for restriction-calculation and remove compiletime warnings 2008-11-12 13:46:30 +00:00
Clemens Fruhwirth
cbc978936e Simplify handle/eventLoop, introduce findInWindowMap, partial updates for key movements (less flickering)
* handle/eventLoop carried the display and the drawing window as
  parameters. The display is available from the embedded X monad, the
  drawing windows was added.

* updateWindows now takes a list of windows to
  update. updateAllWindows updates all windows.

* only the windows that are modified by key movements are redrawn
  now. This means less flickering.
2008-11-11 10:04:05 +00:00
Roman Cheplyaka
80618c53c1 GridSelect: force cursor stay in visible area 2008-11-11 06:33:48 +00:00
Roman Cheplyaka
4908cc5efb GridSelect: fix infiniteness problem with diamondRestrict 2008-11-11 05:53:50 +00:00
Roman Cheplyaka
a5ffb70fc6 GridSelect: remove tabs 2008-11-11 05:36:47 +00:00
Roman Cheplyaka
dcde384f1a Exported shrinkWhile from Decoration to use in GridSelect 2008-11-10 19:15:34 +00:00
Roman Cheplyaka
e3503bc3f2 GridSelect: added link to a screenshot 2008-11-10 19:06:17 +00:00
Roman Cheplyaka
1415787fa3 GridSelect: various improvements
Added documentation
Restricted export list for the sake of haddock
Added functions:
  withSelectedWindow
  bringSelected (by Clemens Fruhwirth)
  goToSelected (by Dominik Bruhn)
2008-11-10 18:46:44 +00:00
Clemens Fruhwirth
de64bf60b4 Initial version of GridSelect.hs with a lot room for improvement/cleanups 2008-11-07 11:51:14 +00:00
sean.escriva
7749dc92d5 documentation: XMonad.Util.Search.hs, add EZConfig keybindings example 2008-11-06 17:17:07 +00:00
Don Stewart
9d2a5d4acc typo 2008-11-04 04:30:44 +00:00
Don Stewart
b6164c6ddc place an upper bound on the version of base we support 2008-11-04 03:58:57 +00:00
Don Stewart
c40d8c2f3d explicit import list for things in the process library 2008-11-04 03:53:19 +00:00
Don Stewart
b6c951a30c Work around ghc 6.10 bug #2738 2008-11-04 03:48:19 +00:00
deadguysfrom
2520104b1e windowPromptBringCopy 2008-10-23 17:30:19 +00:00
Travis B. Hartwell
b849ccb29e generic menu and window bringer 2008-10-27 00:55:23 +00:00
gwern0
1e30ffe2c6 Search.hs: +hackage search, courtesy of byorgey 2008-10-31 21:49:37 +00:00
gwern0
f0259987b1 Prompt.hs rename deleteConsecutiveDuplicates
That name is really unwieldy and long.
2008-10-08 20:51:31 +00:00
gwern0
c27eb22b39 Prompt.hs: have historyCompletion filter dupes
Specifically, it calls deleteConsecutiveDuplicates on the end product. uniqSort reverses order in an unfortunate way, so we don't use that.
The use-case is when a user has added the same input many times - as it stands, if the history records 30 'top's or whatever, the completion will show 30 'top' entries! This fixes that.
2008-10-08 20:47:10 +00:00
gwern0
a0ac6331df Prompt.hs: tweak haddocks 2008-10-08 20:46:49 +00:00
gwern0
806c1f4b5f Prompt.hs: mv uniqSort to next to its confreres, and mention the trade-off 2008-10-08 19:26:45 +00:00
Joachim Breitner
a4cbf496e7 Do not consider XMONAD_TIMER unknown 2008-10-08 19:56:43 +00:00
Joachim Breitner
6d17e66bb3 Kill window without focusing it first
This patch requires the patch "add killWindow function" in xmonad.
Before this patch, people would experience “workspace flicker” when closing
a window via EWMH that is not on the current workspace, for example when
quitting pidgin via the panel icon.
2008-10-05 00:25:33 +00:00
daniel
a2cf9d4d97 let MagnifyLess actually magnify less 2008-10-15 15:39:11 +00:00
intrigeri
9d409b6b3d Actions.Search: add a few search engines
Add Debian {package, bug, tracking system} search engines, as well as Google
Images and isohunt.
2008-10-08 10:40:33 +00:00
Joachim Breitner
5f361b02af Implement HiddenNonEmptyWS with HiddenWS and NonEmptyWS
(Just to reduce code duplication)
2008-10-06 21:10:27 +00:00
Joachim Breitner
5514c2ddca Add straightforward HiddenWS to WSType
With NonEmptyWS and HiddenNonEmptyWS present, HiddenWS is obviously missing.
2008-10-06 21:05:48 +00:00
Joachim Breitner
2480ba1f02 Merge emptyLayoutMod into redoLayout
This removes the emptyLayoutMod method from the LayoutModifier class, and
change the Stack parameter to redoLayout to a Maybe Stack one. It also changes
all affected code. This should should be a refactoring without any change in
program behaviour.
2008-10-05 19:02:20 +00:00
Joachim Breitner
2102a565fd SmartBorders even for empty layouts
Fixes: http://code.google.com/p/xmonad/issues/detail?id=223
2008-10-05 18:44:26 +00:00
gwern0
2051b80b25 Paste.hs: improve haddocks 2008-09-27 15:01:58 +00:00
gwern0
e8edf860f7 Paste.hs: fix haddock 2008-09-27 14:52:38 +00:00
daniel
95c8fa2d1d minor explanatory comment 2008-10-03 01:59:19 +00:00
Lukas Mai
a667fa5720 XMonad.Layout.HintedGrid: add GridRatio (--no-test because of haddock breakage) 2008-09-30 14:17:15 +00:00
Lukas Mai
31fd3135cf XMonad.Util.Font: UTF8 -> USE_UTF8 2008-09-30 14:00:56 +00:00
gwern0
300d9cf2b7 Paste.hs: implement noModMask suggestion 2008-09-26 23:20:56 +00:00
daniel
b663075990 fix a divide by zero error in Grid 2008-09-26 20:41:48 +00:00
gwern0
b0c3dcc192 -DUTF8 flag with -DUSE_UTF8 2008-09-21 15:40:14 +00:00
gwern0
07e9192f6f XSelection.hs: use CPP to compile against utf8-string 2008-09-20 15:16:15 +00:00
Devin Mullins
205032840b add XMonad.Config.Azerty 2008-09-24 04:49:46 +00:00
Devin Mullins
ae57d452be flip GridRatio to match convention (x/y) 2008-09-22 03:33:54 +00:00
daniel
bf51c0f64c let Grid have a configurable aspect ratio goal 2008-09-22 01:09:50 +00:00
gwern0
8971328f06 Paste.hs: +warning about ASCII limitations 2008-09-21 15:50:38 +00:00
gwern0
38a21daefe Paste.hs: shorten comment lines to under 80 columns per sjanssen 2008-09-21 15:49:50 +00:00
Spencer Janssen
9476610ee0 Forgot to enable historyFilter :( 2008-09-21 09:42:54 +00:00
Spencer Janssen
2d5b9475b9 Prompt: add configurable history filters 2008-09-21 09:34:53 +00:00
Spencer Janssen
005f4ef7fb Update my config to use 'statusBar' 2008-09-21 06:35:13 +00:00
Spencer Janssen
1c1205daed Rename pasteKey functions to sendKey 2008-09-21 06:20:16 +00:00
Spencer Janssen
505cbb2430 DynamicLog: doc fixes 2008-09-21 06:13:14 +00:00
Spencer Janssen
2477985387 Move XMonad.Util.XPaste to XMonad.Util.Paste 2008-09-21 06:09:47 +00:00
Spencer Janssen
8d670902e5 Depend on X11 >= 1.4.3 2008-09-21 05:54:56 +00:00
Spencer Janssen
c75b058c5b statusBar now supplies the action to toggle struts 2008-09-18 01:38:58 +00:00
Devin Mullins
f3b6b2707a cleanup - use currentTag 2008-09-21 01:11:59 +00:00
gwern0
bd2b5379ab XPaste.hs: improve author info 2008-09-20 15:23:42 +00:00
gwern0
4ae4a7ec07 +XMonad.Util.XPaste: a module for pasting strings to windows 2008-09-20 15:21:06 +00:00
Devin Mullins
9dd5fff540 UrgencyHook bug fix: cleanupUrgents should clean up reminders, too 2008-09-20 06:21:17 +00:00
Spencer Janssen
026fdf71be Sketch of XMonad.Config.Monad 2008-09-17 08:18:38 +00:00
seanmce33
10be813bd7 raiseMaster 2008-09-12 18:48:30 +00:00
Daniel Neri
63a0177187 Add missing space between dzen command and flags 2008-09-15 13:10:09 +00:00
Spencer Janssen
2d1ccbe643 Big DynamicLog refactor. Added statusBar, improved compositionality for dzen and xmobar
Compatibility notes:
    - dzen type change
    - xmobar type change
    - dynamicLogDzen removed
    - dynamicLogXmobar removed
2008-09-13 20:59:31 +00:00
Spencer Janssen
03caedc589 Take maintainership of XMonad.Prompt 2008-09-11 23:04:42 +00:00
Spencer Janssen
e677bb3cc1 Overhaul Prompt to use a zipper for history navigation. Fixes issue #216 2008-09-11 22:59:40 +00:00
Spencer Janssen
644b85ab36 Use the new completion on tab setting 2008-09-11 08:59:40 +00:00
Joachim Breitner
587078d456 Only start to show the completion window with more than one match 2008-09-08 11:01:29 +00:00
Joachim Breitner
25033caf6e XPrompt: Add showCompletionOnTab option
This patch partially implements
http://code.google.com/p/xmonad/issues/detail?id=215
It adds a XPConfig option that, if enabled, hides the completion window
until the user presses Tab once. Default behaviour is preserved.
TODO: If Tab causes a unique completion, continue to hide the completion
window.
2008-09-08 10:57:58 +00:00
Marco Túlio Gontijo e Silva
a908ff760b XMonad.Actions.Plane.planeKeys: function to make easier to configure 2008-07-14 15:36:01 +00:00
Marco Túlio Gontijo e Silva
07a5355edc XMonad.Actions.Plane: removed unneeded hiding 2008-07-14 15:26:31 +00:00
Marco Túlio Gontijo e Silva
289b994646 Improvements in documentation 2008-07-09 00:24:25 +00:00
Spencer Janssen
297e626fc7 Fix haddock typos in XMonad.Config.{Desktop,Gnome,Kde} 2008-09-11 04:08:08 +00:00
Devin Mullins
c3d5c09e84 add clearUrgents for your keys 2008-09-09 05:54:25 +00:00
Devin Mullins
27efc7a626 add reminder functionality to UrgencyHook
I'm considering rewriting remindWhen and suppressWhen as UrgencyHookModifiers, so to speak. Bleh.
2008-08-24 20:05:48 +00:00
Spencer Janssen
25896cd43d Bump version to 0.8 2008-09-05 19:44:15 +00:00
Devin Mullins
7325062ccf Take maintainership of X.L.WindowNavigation
Since I've been working on a rewrite, it seems only fair that I be forced to
better understand the existing code / issues.
2008-09-02 07:02:47 +00:00
Spencer Janssen
df58a90077 Take maintainership of NoBorders 2008-08-29 20:13:25 +00:00
Joachim Breitner
9dae24bfd8 Only move pointers over managed windows 2008-06-10 19:59:16 +00:00
robreim
9515818409 Fix window region checking in UpdatePointer 2008-05-11 09:40:56 +00:00
David Roundy
1f2162781f remove myself as maintainer from modules I don't maintain or use. 2008-08-28 15:18:30 +00:00
Devin Mullins
4d2365734d change withUrgencyHookC api
Now it takes an UrgencyConfig record type.
2008-08-21 05:20:46 +00:00
Spencer Janssen
1df08883b8 Accept a range of xmonad versions 2008-08-20 21:40:56 +00:00
acura
79b0c3401a StackTile_fix 2008-08-20 06:19:18 +00:00
Devin Mullins
bfc265d663 X.H.UrgencyHook: haddock fixes 2008-08-16 19:52:20 +00:00
Spencer Janssen
26e40e555e Improve documentation for XMonad.Hooks.EwmhDesktops 2008-08-13 19:18:57 +00:00
Devin Mullins
e58933b9c1 simplify WindowBringer code, and change greedyView to focusWindow 2008-08-11 03:31:37 +00:00
Spencer Janssen
1c03ecc596 Updates to my config 2008-08-12 05:01:24 +00:00
Braden Shepherdson
1a9af96070 Added XMonad.Hooks.DynamicHooks
Allows runtime creation and modification of ManageHooks. Also allows one-shot
ManageHooks that are removed after the fire. Note that if several transient
hooks fire at once, only the most recently defined is executed, and all
are removed.
2008-07-24 22:20:54 +00:00
gwern0
8aa2076a45 XMonad.Hooks.UrgencyHook: +FocusHook
This is a hook for simply traveling to whatever window has just set an urgent flag, instead of doing something more involved like printing to a status bar and letting the user do something manually.
2008-07-16 22:47:45 +00:00
Lukas Mai
e9980e2052 Grid/HintedGrid: prefer wider windows 2008-07-17 20:51:38 +00:00
Spencer Janssen
94101637c9 I prefer the spencerjanssen@gmail.com address 2008-07-14 20:40:05 +00:00
Devin Mullins
cfaadb644e callUrgencyHook after adjustUrgents
So folks can readUrgents inside their urgencyHook, should they so desire.
2008-07-14 04:30:20 +00:00
gwern0
ed49f823d0 XMonad/Doc/Developing.hs: update haddock ln, cpedit 2008-07-08 20:50:58 +00:00
gwern0
f29f38fbeb XMonad/Doc.hs: why link to a specific version instead of the latest? 2008-07-08 20:22:36 +00:00
leoserra
f06a147057 XMonad.Actions.Plane.Linear 2008-07-06 17:53:03 +00:00
Marco Túlio Gontijo e Silva
e0ebbc1ea8 XMonad.Actions.Plane: Improvements in code quality 2008-07-06 17:28:29 +00:00
Marco Túlio Gontijo e Silva
52192efe56 XMonad.Actions.Plane: Treat error in read 2008-07-10 13:53:42 +00:00
Marco Túlio Gontijo e Silva
18ae6a3e2c XMonad.Actions.Plane: GConf support
Thanks to Johan Dahlin.
2008-07-09 00:19:00 +00:00
Devin Mullins
b775d682ca X.A.WindowNavigation: comments 2008-07-10 04:10:28 +00:00
Devin Mullins
99f9c8acc3 add autoComplete option to XMonad.Prompt
Maybe this will get Gwern one step closer to a complete Ratpoison binding.
2008-07-04 07:34:15 +00:00
Marco Túlio Gontijo e Silva
95b26ac219 XMonad.Actions.Plane: Copyright update 2008-07-09 00:15:48 +00:00
Marco Túlio Gontijo e Silva
374c034628 XMonad.Actions.Plane: removed missing haddock chunck 2008-07-09 01:05:30 +00:00
Braden Shepherdson
ae1010882a Added function to filter out scratchpad workspace for use with ewmhLogHookCustom. 2008-07-06 16:10:27 +00:00
Braden Shepherdson
afb54c64b0 Added ewmhLogHookCustom, which allows arbitrary transformation of the workspace list. 2008-07-06 16:08:47 +00:00
brian
23588c09ae adding thesaurus.reference.com and Google Labs Code Search searches 2008-07-01 09:01:42 +00:00
gwern0
60e02bb08a fillout banish example in Warp.hs
We also include a nice little type to avoid specifying 0 0 stuff.
2008-06-29 20:20:47 +00:00
gwern0
ddb522d0cb fix Actions.Wap doc
warp 1 1 has a comment claiming that this moves the cursor to the lower *left*, but if you look at the warpToWindow haddock, it says that 1 1 is actually lower *right* - as indeed it proved to do. This was annoying as it led me astray for a minute or so.
2008-06-29 11:55:04 +00:00
brian
2dc1b0c5f7 allow function keys up to F24 2008-06-26 04:05:16 +00:00
Braden Shepherdson
7cc6859496 Now using -name instead of -title as the term app argument, and correspondingly resource for the ManageHook. 2008-06-08 18:07:48 +00:00
Brent Yorgey
6530f28720 Actions/Search.hs: export SearchEngine constructor 2008-06-20 21:20:16 +00:00
Malebria
ddc49ade7b Export PerWorkspace to allow type signatures 2008-06-20 01:50:46 +00:00
Lukas Mai
1c18687ec4 XMonad.Util.EZConfig: add keypad bindings 2008-06-15 14:37:02 +00:00
Lukas Mai
4dc9baca48 XMonad.Util.EZConfig: minor cleanups 2008-05-28 16:54:50 +00:00
David Roundy
389e23b979 make default highlighting a bit dimmer for neighbors in WindowNavigation. 2008-06-10 17:42:00 +00:00
David Roundy
d988bda23f keep drag panes on the bottom of the window stack. 2008-06-10 17:40:44 +00:00
David Roundy
78f934255b add support to Magnifier for vertical zooming. 2008-06-10 17:37:47 +00:00
Malebria
f6e166c5ea XMonad.Hooks.EwmhDesktops export EwmHDesktopsHook
Any function that a user may write in his configuration file that is related to ewmhDesktopsLayout cannot have it's type signature if this type is not exported.
2008-06-10 13:06:14 +00:00
Malebria
a8c84232f3 XMonad.Config.Desktop type problem (monomorphism?)
With main = xmonad defaultConfig {layoutHook = desktopLayoutModifiers Full} I got a type error, that's not present with the patch.
2008-06-10 18:28:56 +00:00
Justin Bogner
f736a57bf0 Make prompt keybindings work when numLock or capsLock are active 2008-06-08 17:20:57 +00:00
Braden Shepherdson
244c75bee7 Replaced old "spawn on mod+s" semantics with "spawn/summon or banish on mod+s".
Originally the key binding just spawned a new floating terminal on every keypress.
Now it spawns if it doesn't exist, summons from another workspace if it does but
isn't visible, or banishes it to a dynamically created workspace if it is on the
current workspace.
2008-06-08 04:54:57 +00:00
Braden Shepherdson
303107fbae Exporting addHiddenWorkspace, it's needed by the new Scratchpad 2008-06-08 04:53:18 +00:00
Braden Shepherdson
aa9e7ca663 Added scratchpadSpawnActionTerminal to specify the terminal program directly as a String. 2008-06-08 03:26:19 +00:00
Braden Shepherdson
744b8197ee Removed odd scratchpadSpawnDefault, improved documentation. 2008-06-08 03:24:39 +00:00
gwern0
7b81a45619 Actions.Search.hs: switch inappropriate use of getShellCompl for a historyCompletion
It's inappropriate because if I am searching Wikipedia, say, why on earth do I want completion of files and executables on my PC? A previous search query is much more likely to be what I want.
2008-06-07 07:13:31 +00:00
gwern0
da64090416 Prompt.hs: +a historyCompletion function for use in XPrompts 2008-06-07 07:12:25 +00:00
Trevor Elliott
aa8275e491 Add C-w to XMonad.Prompt
* Bind C-w to kill the previous word
2008-06-05 22:06:56 +00:00
Don Stewart
955a4bd24f Add missing xfce module to .cabal 2008-06-02 17:42:19 +00:00
Malebria
5c908f986a Use lines instead of columns in configuration (similar to GNOME and KDE) 2008-05-26 22:53:37 +00:00
Malebria
f95fa1f551 Bug correction when areasColumn > 1 2008-05-26 22:32:20 +00:00
Devin Mullins
3436683f88 more documentation for WindowNavigation and UrgencyHook 2008-05-25 05:02:31 +00:00
Devin Mullins
8bec9a32e1 X.A.WindowNavigation: add logHook for better state tracking 2008-05-25 03:23:25 +00:00
Devin Mullins
f13c352bff doco tweaks 2008-05-24 21:18:49 +00:00
Justin Bogner
5895a401be made fadeInactiveLogHook take an argument amount to fade 2008-05-23 21:39:37 +00:00
Justin Bogner
5fc69c1ae7 add FadeInactive to fade out inactive windows using xcompmgr 2008-05-23 20:58:38 +00:00
Justin Bogner
0cbb8b83af add close window functionality to EwmhDesktops 2008-05-23 18:59:08 +00:00
Malebria
65109b90c6 Add XMonad.Actions.Plane 2008-05-23 00:43:57 +00:00
Ivan.Miljenovic
25de482d5f Default Xfce config, this time with me holding the copyright, maintainership, etc. 2008-05-22 10:53:16 +00:00
Joachim Fasting
7ef87af128 StackTile: minor documentation fix
That '[]' in the example seems incorrect
2008-05-21 18:26:37 +00:00
acura
8a4ffb3e57 StackTile
A simple patch to get a dishes like stacking, but with the ability to resize master pane.
2008-05-20 19:55:59 +00:00
gwern0
12e54671a5 revamp Search.hs to export a replacement for simpleEngine
It's called searchEngine now, and is a wrapper around the SearchEngine type. Different type as well
2008-05-19 19:09:12 +00:00
gwern0
e3974a91b3 sp ShowWName.hs 2008-05-19 19:05:20 +00:00
David Roundy
8c65d469db remove ScratchWorkspace.
It's ugly code, and I'd be surprised if anyone actually uses it.  I see no
reason to continue to maintain it.
2008-05-16 18:57:29 +00:00
Roman Cheplyaka
3cbccce5e8 Fixed location of xmonad.conf 2008-05-18 20:46:02 +00:00
zhen.sydow
7a3ff21b89 add site name in search prompt dialog 2008-05-18 10:13:57 +00:00
zhen.sydow
0140d63947 add youtube to search engines 2008-05-13 21:25:08 +00:00
Devin Mullins
8a646c9983 SwapWorkspaces: swapTo Next|Prev 2008-05-18 02:41:21 +00:00
Devin Mullins
e355598321 UrgencyHook: removeVisiblesFromUrgents -> cleanupUrgents
Now only removes windows based on SuppressWhen setting.
2008-05-15 16:44:36 +00:00
Braden Shepherdson
dd0ad36b22 Added XMonad.Config.PlainConfig: proof-of-concept GHC-less plain text configuration file parser
An example of the config file format can be found in the Haddock.
Notably missing features are docks and more layouts than just the standard three.
2008-05-17 22:29:16 +00:00
lithis
826512a460 XMonad.Hooks.SetWMName: Update documentation to reflect the addition of startupHook. 2008-05-16 22:10:11 +00:00
David Roundy
f4b537a06e I no longer use ScratchWorkspace. 2008-05-16 18:57:15 +00:00
David Roundy
6c2489e4a5 fix bug in smartBorders when combined with decorated windows. 2008-05-16 18:48:55 +00:00
Devin Mullins
52d2a731c9 decent documentation for UrgencyHook
Blame it on lack of sleep. Or perhaps the causation is the reverse.
2008-05-15 08:22:22 +00:00
Devin Mullins
21dd3fed8f X.A.WindowNavigation: currentPosition and setPosition share the same inside logic, now
Aside from documentation, this is pretty much usable, now.
2008-05-15 06:22:11 +00:00
Devin Mullins
7852e704fa X.A.WindowNavigation: have currentPosition handle axes independently
This improves some subtle interactions between mod-j/k and mod-w/a/s/d, though
that might not become very apparent until I fix setPosition.
2008-05-15 05:33:30 +00:00
Devin Mullins
1d93dfba51 fix compile warnings in BoringWindows 2008-05-15 05:17:28 +00:00
David Roundy
60f269f0b3 add BoringWindows module to make certain windows skipped when rotating focus. 2008-05-14 16:28:46 +00:00
Devin Mullins
4d520a4f20 UrgencyHook: some documentation (more is needed) 2008-05-14 08:01:04 +00:00
Devin Mullins
7d34680a9c UrgencyHook: got rid of the need for instances to know about suppressWhen
This changes the API a little bit, but that's what you get for using a day-old feature from darcs.
2008-05-14 07:22:17 +00:00
zhen.sydow
ac6f1a66fe move AppLauncher from Actions module to Prompt module 2008-05-13 20:12:52 +00:00
Devin Mullins
921097c9b5 X.A.WindowNavigation: comment cleanup 2008-05-13 09:13:13 +00:00
Devin Mullins
2d60591715 windowRect now compensates for border width
Odd that I have to do (Rectangle x y (w + 2 * bw) (h + 2 * bw)) -- you'd think
the window would be centered within the bordered area.
2008-05-13 09:01:51 +00:00
Devin Mullins
4d1bc6eecb X.A.WindowNavigation: update TODO 2008-05-13 04:42:29 +00:00
Devin Mullins
bb5fd00967 X.A.WindowNavigation: minor cleanup 2008-05-12 17:04:10 +00:00
Devin Mullins
864f3382ce X.A.WindowNavigation: simplify inr somewhat 2008-05-12 09:06:47 +00:00
Devin Mullins
95e5210d95 X.A.WindowNavigation: clarity 2008-05-12 08:53:38 +00:00
Devin Mullins
6eb5074bd1 X.A.WindowNavigation: ugh, typo 2008-05-12 08:22:28 +00:00
Devin Mullins
70caa5a67b X.A.WindowNavigation: implement swap, extract withTargetWindow commonality
Why doesn't mapWindows exist already?
2008-05-12 06:47:15 +00:00
Devin Mullins
cdeb842834 add more flexible withWindowNavigationKeys
Names aren't permanent yet, so don't cry if they change.
2008-05-12 05:06:37 +00:00
Devin Mullins
255a04753e X.A.WindowNavigation: TODO 2008-05-11 22:21:16 +00:00
Devin Mullins
8f0b9fa066 X.A.WindowNavigation: add withWindowNavigation, for easy setup
This should be more flexible than it is -- I've got an idea, but am interested to hear others.
2008-05-11 22:04:58 +00:00
Devin Mullins
98c70dd264 X.A.WindowNavigation: fix currentPosition
Now properly deals with an unitialized state (e.g. from a restart) or an
inconsistent state (e.g. from using mod-j/k). Deserves cleanup.
2008-05-11 21:21:28 +00:00
Devin Mullins
5338391ae9 X.A.WindowNavigation: add TODOs 2008-05-11 21:13:26 +00:00
Devin Mullins
ad787b2d5f X.A.WindowNavigation state is now workspace-specific
racking up some code debt, here...
2008-05-11 07:16:56 +00:00
Devin Mullins
50420922eb X.A.WindowNavigation: minor doco changes 2008-05-06 07:42:35 +00:00
Devin Mullins
b45722cf82 add draft XMonad.Actions.WindowNavigation
This is an experiment with replacing the WindowNavigation LayoutModifier with
one that simply adds keybindings and stores state in an IORef. Credit to
droundy for the original code -- hopefully I'm not butchering it. The end
intent is to add Xinerama support, but it'll be a little while before I get
there.
2008-05-04 05:00:22 +00:00
zhen.sydow
07b2f424b1 new contrib module to launch apps with command line parameters 2008-05-13 13:47:54 +00:00
Devin Mullins
090d77236d pull suppressWhen logic into main WithUrgencyHook handler
In order for this to work, I added a new UrgencyHook method to communicate the
SuppressWhen value. I'm not sure if this is actually better than just providing
a convenience function, but it's an easy switch.
2008-05-13 07:52:47 +00:00
Devin Mullins
4b8575f3ae add suppressWhen option to dzenUrgencyHook 2008-05-13 05:46:15 +00:00
Devin Mullins
5e045d018b WindowNavigation: extract navigable function 2008-04-22 04:52:48 +00:00
Devin Mullins
e8b19b8b33 UrgencyHook: doc typo 2008-05-12 05:21:37 +00:00
Devin Mullins
0350117f47 UrgencyHook: extract whenNotVisible 2008-05-12 04:18:52 +00:00
Devin Mullins
26b1a747c6 SpawnUrgencyHook, FWIW 2008-05-12 04:04:49 +00:00
Devin Mullins
33b0a1b760 make UrgencyHook an EventHook
This gets rid of the stupid bug that led to a need for the clearBit hack, and
allowed me to simplify the types (since EventHooks aren't required to
parameterize on the window type). Config files need not change, unless they
declare instances of UrgencyHook, in which case, they should remove "Window" as
is seen in this patch.
2008-05-12 02:48:22 +00:00
Ivan N. Veselov
82a6bea527 'xmobar' function added to DynamicLog for running xmobar with some defaults 2008-05-08 19:49:18 +00:00
lithis
7c9948f9ee HintedTile: Fix mistake in documentation. 2008-05-08 00:35:52 +00:00
Spencer Janssen
58610f1c15 Use gnome-session-save for the mod-shift-q binding 2008-05-07 08:22:05 +00:00
Spencer Janssen
e3eb2151da Use the named constant 'none' rather than 0 2008-05-07 08:18:54 +00:00
lithis
52932bcd03 HintedTile: Improve documentation. 2008-05-08 00:02:45 +00:00
Spencer Janssen
d38b2b4f72 Whitespace only 2008-05-07 03:13:06 +00:00
Spencer Janssen
72c42e6b0a Add a binding for Gnome's "Run Application" dialog 2008-05-07 03:11:27 +00:00
Spencer Janssen
2a2c33b37f Add some keybindings to the Kde config 2008-05-07 02:26:58 +00:00
Spencer Janssen
c66c634cf0 Indentation 2008-05-07 02:25:53 +00:00
Spencer Janssen
90d5b56d45 Add ToggleStruts to the desktop config 2008-05-07 02:25:16 +00:00
Spencer Janssen
8677090476 Refactor my config 2008-05-07 02:15:04 +00:00
Spencer Janssen
1e6c4e485a Add XMonad.Config.Kde 2008-05-07 02:08:33 +00:00
Klaus Weidner
476fb301d4 Don't move the pointer if the user is moving the mouse
This patch depends on the following xmonad core patch:

  Remember if focus changes were caused by mouse actions or by key commands

If the user was moving the mouse, it's not appropriate to move the pointer
around in resonse to focus changes. Do that only in response to keyboard
commands.
2008-04-17 02:22:34 +00:00
Don Stewart
570f6c9cf1 Missing pragmas 2008-05-06 05:34:02 +00:00
Don Stewart
0a118f1179 Add full documentation 2008-05-05 21:05:46 +00:00
Devin Mullins
99d0c45074 minor cleanup on getName 2008-05-04 05:49:23 +00:00
Devin Mullins
5e7462d9b2 bug doco for UrgencyHook 2008-04-26 20:36:38 +00:00
Spencer Janssen
b15fd831fe NamedWindows: when converting the text property, handle the empty list.
This fixes a "Prelude.head" exception observed with windows that have no title.
Reproduce by placing several windows in the tabbed layout, then starting
'xterm -name ""'.  Thanks to Andrea for pointing out the issue.
2008-05-02 10:42:49 +00:00
Andrea Rossato
82975240b7 Fix issue #179 by handling events correctly 2008-05-01 06:23:57 +00:00
Spencer Janssen
e35e0a001c My monitor is larger now :) 2008-04-30 08:30:26 +00:00
Spencer Janssen
4fff234f3b manageHooks for my config 2008-04-30 08:25:36 +00:00
Spencer Janssen
a46e04fef7 Remove redundant type signature 2008-04-30 08:24:47 +00:00
Spencer Janssen
034eee34e3 Add XMonad.Config.Desktop and XMonad.Config.Gnome 2008-04-30 08:22:53 +00:00
Spencer Janssen
49b705906b Alphabetize exposed-modules 2008-04-30 03:54:53 +00:00
joamaki
0df598fa5d new contrib layout: XMonad.Layout.SimplestFloat - A floating layout like SimpleFloat, but without decoration 2008-04-24 22:09:57 +00:00
Don Stewart
b2c1e077b2 stricitfy some gap fields 2008-04-27 19:12:47 +00:00
Lukas Mai
2418d4b374 XMonad.Hooks.ManageHelpers: quick&dirty support for _NET_WM_STATE_FULLSCREEN 2008-04-26 13:27:45 +00:00
Lukas Mai
aca6fd8058 XMonad.Hooks.Script: haddock fixes 2008-04-26 13:26:29 +00:00
Ivan.Miljenovic
8e5df4b950 Error fix for Tabbed when tabbar always shown 2008-04-24 06:31:35 +00:00
Don Stewart
336c617cbe remove my config file -- the wiki is where its at. 2008-04-19 19:56:50 +00:00
Don Stewart
bcc4295d3d tweaks to docs for SimpleDecoration 2008-04-18 21:51:55 +00:00
Ivan.Miljenovic
2e050d29d9 Allow tabbar to always be shown.
Patch take 4, hopefully the final version.  Includes droundy's suggestions.
2008-04-15 04:37:28 +00:00
Don Stewart
19156cb3ff polish 2008-04-18 03:31:33 +00:00
Trevor Elliott
5344db6c90 Script-based hooks 2008-04-16 21:30:24 +00:00
Spencer Janssen
b1d4d97c1a Don't strictify the Display component, this triggers a bug in GHC 6.6 2008-04-16 18:57:33 +00:00
Roman Cheplyaka
adbee1ce2c Fix to IM modifier.
Avoid differentiating integrated stack by using StackSet.filter.
2008-04-14 23:24:37 +00:00
Ivan N. Veselov
adde0fc668 IM layout converted to LayoutModifier, which can be applied to any layout 2008-04-13 20:58:24 +00:00
Don Stewart
c98059db64 stictify some fields 2008-04-13 07:01:17 +00:00
Don Stewart
58f10da612 strictify some fields 2008-04-13 06:59:58 +00:00
Joachim Breitner
ab782c936a Fix window order in EWMH
For pagers to draw the stacking order correctly, the focused window has to
be the last in the list. Thus put an appropriate implementation of allWindows
into the Module.
This does not work perfectly with floating windows.
2008-04-11 13:44:11 +00:00
David Roundy
117c3bd6b1 remove myself as maintainer of CopyWindow.
I'm not sure who's maintaining this, but it's not me.
2008-04-09 14:43:33 +00:00
Roman Cheplyaka
9e6dca0fa1 XMonad.Util.WindowProperties: add WM_WINDOW_ROLE as Role 2008-04-09 17:49:35 +00:00
Spencer Janssen
1071d0a4e1 Generalize copyWindow, minor style change 2008-04-08 21:00:50 +00:00
Ivan N. Veselov
56031b1f63 XMonad.Actions.CopyWindow: added copyToAll and killAllOtherCopies functions 2008-04-08 19:51:11 +00:00
Lukas Mai
59fc99504f XMonad.Actions.UpdatePointer: doc fix 2008-04-07 15:27:41 +00:00
Lukas Mai
413023b5d0 XMonad.Util.Font: minor reformatting 2008-04-06 02:09:35 +00:00
Lukas Mai
b2b1671630 DynamicLog: resolve merge conflict 2008-04-06 02:05:27 +00:00
lithis
999029d95f Encode the entire DynamicLog output, instead of just window title. 2008-03-29 03:15:37 +00:00
Andrea Rossato
4277d11def DynamicLog: add support for UTF-8 locales when compiled with XFT or UFT-8 support 2008-03-13 10:26:43 +00:00
Lukas Mai
cdfbf3ebce XMonad.Util.Font: don't call setlocale; core does it for us 2008-04-06 01:31:23 +00:00
Lukas Mai
c86409624f XMonad.Util.NamedWindows: fix imports 2008-03-26 17:27:45 +00:00
Mats Jansborg
e28702c57b Changed getName to use locale-aware functions
Rewrote getName using getTextProperty and wcTextPropertyToTextList.
2007-08-19 13:21:04 +00:00
Ian Zerny
ef25a538bf Added next-window versions of the raise* functions. 2008-04-05 18:29:00 +00:00
Lukas Mai
b495c7f725 XMonad.Layout.Master: initial import 2008-04-04 22:07:34 +00:00
Lukas Mai
1950a4e2cc update contrib for applySizeHints changes 2008-04-04 22:05:58 +00:00
Lukas Mai
c15eea99c9 XMonad.Hooks.ManageDocks: haddock fix 2008-04-04 22:05:32 +00:00
Brent Yorgey
8783bc727c MultiToggle/Instances: ghc 6.6 can't parse LANGUAGE pragma 2008-04-04 20:01:57 +00:00
Joachim Breitner
8d2f363729 Document _NET_ACTIVE_WINDOW behaviour more exactly 2008-04-04 07:29:44 +00:00
Joachim Breitner
2747f802df _NET_ACTIVE_WINDOW moves windows if necessary
This makes EWMH behave a bit more like metacity: If _NET_ACTIVE_WINDOW is
received and the window is not on the current worspace, it is brought here 
(instead of the workspace switched to the other one). So for example, if you
click on the pidgin icon in the panel and the buddy list is already open some
where it is moved here.
2008-04-02 14:38:11 +00:00
Don Stewart
0971238cf6 onstart=lower, solves floating dzen issue 2008-04-03 20:34:25 +00:00
Don Stewart
6c324cbfed some bang patterns 2008-04-03 17:22:46 +00:00
Don Stewart
f1d91209a4 have 'dzen' use autoStruts to detect the gaps 2008-04-03 00:31:30 +00:00
Brent Yorgey
5d352c8bf4 Actions/Search.hs: add dictionary.com search 2008-04-02 15:05:21 +00:00
Joachim Breitner
63bac5b539 _NET_ACTIVE_WINDOW moves windows if necessary
This makes EWMH behave a bit more like metacity: If _NET_ACTIVE_WINDOW is
received and the window is not on the current worspace, it is brought here 
(instead of the workspace switched to the other one). So for example, if you
click on the pidgin icon in the panel and the buddy list is already open some
where it is moved here.
2008-04-02 14:38:11 +00:00
Lukas Mai
7e3cb59c23 HintedGrid: guesstimate window flexibility and layout rigid windows first 2008-04-02 04:28:46 +00:00
Lukas Mai
adbf9032ca HintedGrid: try both bottom-up/top-down window placement to minimize unused space 2008-04-02 01:25:38 +00:00
Lukas Mai
d2df9b329e Grid/HintedGrid: use an ncolumns formula inspired by dwm's "optimal" mode 2008-04-02 01:21:26 +00:00
Brent Yorgey
25c23eb79d XMonad.Layout.Gaps: new contrib module for manual gap support, in the few cases where ManageDocks is not appropriate (dock apps that don't set STRUTS properly, adjusting for a display that is cut off on one edge, etc.) 2008-04-02 00:37:42 +00:00
gwern0
e170cfc611 improve WindowGo.hs Haddock formatting 2008-04-01 02:31:30 +00:00
gwern0
7382e616a9 forgot a haddock for getEditor in Shell.hs 2008-04-01 02:20:12 +00:00
gwern0
64396d85ab WindowGo.hs: +raiseBrowser, raiseEditor
Specialize runOrRaise in the same way as with Actions.Search, for one's browser and one's editors.
2008-04-01 02:17:40 +00:00
gwern0
acd13fd324 RunOrRaise.hs: FF 3 doesn't use the "Firefox-bin" classname 2008-04-01 01:50:49 +00:00
gwern0
a4fb5d127f Search.hs: remove an argument from selectSearch and promptSearch
The new getBrowser function allows us to mv the old selectSearch and promptSearch aside as too-general functions, and replace them with new versions, which employ getBrowser to supply one more argument. This allows us to replace the tedious 'selectSearch google "firefox"; selectSearch yahoo "firefox"...' with shorter 'selectSearch google' and so on. One less argument.

Also, update the docs.
2008-04-01 01:39:47 +00:00
gwern0
494823eb82 Shell.hs: +getBrowser, getEditor, helper function
The helper function asks the shell for the value of a variable, else returns the second argument.
getBrowser and getEditor obviously specialize it for two particular possibly queries
2008-04-01 01:34:47 +00:00
Lukas Mai
dcd1aea5d6 XMonad.Layout.HintedGrid: initial import 2008-04-01 23:17:22 +00:00
Roman Cheplyaka
6c19138d55 Documentation improvement. 2008-04-01 13:43:05 +00:00
Roman Cheplyaka
8816dc5c3f Remove broken link to screenshot. 2008-03-31 21:08:54 +00:00
Brent Yorgey
110c3863e8 MultiToggle: add new XMonad.Layout.MultiToggle.Instances module for common instances of Transformer, update MultiToggle docs accordingly 2008-03-31 20:17:39 +00:00
Michal Janeczek
f77f71512b XMonad.Actions.CycleRecentWS: initial import 2008-03-31 11:19:06 +00:00
Lukas Mai
7abbbd4568 XMonad.Hooks.ManageDocks: export checkDoc 2008-03-31 01:29:11 +00:00
Lukas Mai
5bbf9700f3 XMonad.Layout.Grid: fix indentation 2008-03-30 00:48:59 +00:00
Brent Yorgey
c857ebe29c move Direction type from WindowNavigation to ManageDocks (ManageDocks will move into the core, taking Direction with it) 2008-03-31 01:01:27 +00:00
Brent Yorgey
da5452b009 ManageDocks: clean up + add more documentation 2008-03-31 00:29:29 +00:00
Brent Yorgey
a09ed70091 Util.Run, Hooks.DynamicLog: re-export hPutStrLn and hPutStr from Util.Run for convenience, and update DynamicLog documentation to show proper imports 2008-03-28 20:54:46 +00:00
Brent Yorgey
bc0851f52a ManageDocks: add avoidStrutsOn, for covering some docks and not others by default. 2008-03-27 20:39:40 +00:00
Brent Yorgey
4e66e0ad1b ManageDocks: add ability to toggle individual gaps independently 2008-03-27 11:17:22 +00:00
Brent Yorgey
8efc32759a PerWorkspace: add modWorkspace(s) combinators, for selectively applying layout modifiers to certain workspaces but not others 2008-03-26 21:43:51 +00:00
Roman Cheplyaka
c86dd6f097 Haddock fix 2008-03-30 13:44:35 +00:00
Spencer Janssen
0d310df103 Remove stale status gaps code 2008-03-29 23:07:37 +00:00
Spencer Janssen
071081f38e Bump version to 0.7 2008-03-29 19:24:00 +00:00
Spencer Janssen
64f04628b9 Fix haddock error 2008-03-29 19:17:52 +00:00
Lukas Mai
f15334d02d XMonad.Layout.MultiToggle: let runLayout modify the base layout if no transformer is active 2008-03-28 19:09:03 +00:00
Brent Yorgey
920336e1ac Spiral: add documentation 2008-03-28 19:22:31 +00:00
David Roundy
c2d0a209eb corrected version of make workspaceDir work even in workspaces with no windows. 2008-03-27 14:22:57 +00:00
David Roundy
143e68f664 cleanup in Tabbed (make 'loc' be actual location). 2008-03-26 15:10:04 +00:00
David Roundy
296b0b2513 make workspaceDir work even in workspaces with no windows.
This also fixes a (minor) bug when the focussed window is present on
multiple visible workspaces.
2008-03-26 15:27:08 +00:00
David Roundy
e17d039c3a clean up Config.Droundy. 2008-03-27 00:21:59 +00:00
David Roundy
e3d455ded4 make workspaceDir work even in workspaces with no windows.
This also fixes a (minor) bug when the focussed window is present on
multiple visible workspaces.
2008-03-26 15:27:08 +00:00
Brent Yorgey
a787d4badf ManageDocks: add warning about making sure gaps are set to zero before switching to avoidStruts, since ToggleStruts won't work otherwise 2008-03-26 23:19:28 +00:00
Brent Yorgey
f0e7b48bda update documentation in XMonad/Doc in preparation for 0.7 release 2008-03-26 19:57:41 +00:00
Lukas Mai
6ada04c415 XMonad.Hooks.ManageHelpers: reformatting 2008-03-26 18:27:07 +00:00
Lukas Mai
6761a61cad XMonad.Layout.NoBorders: fix floating fullscreen logic 2008-03-26 17:28:44 +00:00
xmonad
1c6798a639 UpdatePointer: Make pointer position configurable. 2008-03-26 07:57:59 +00:00
Spencer Janssen
b85ce7522f Fix bugs in Tabbed and TabBarDecoration -- please remember multi-head! 2008-03-26 03:45:41 +00:00
Don Stewart
7de2ed2152 my current config 2008-03-26 02:33:03 +00:00
Spencer Janssen
31d303508e I don't use DwmStyle 2008-03-25 21:38:18 +00:00
David Roundy
ca2d0ca406 fix bug in TabBarDecoration leading to gaps in corner. 2008-03-25 21:03:27 +00:00
David Roundy
6850c0fed7 fix bug leading to gaps in tabs at the corner of the screen.
Besides being ugly, this had the effect of making me fail to click on the
tab I aimed for, if it was in the corner.
2008-03-25 21:02:11 +00:00
Brent Yorgey
1f53383e2e XMonad.Layout.LayoutModifier: add a metric crapload of documentation 2008-03-25 20:50:06 +00:00
Brent Yorgey
ec2cd8d8b1 XMonad.Layout.Reflect: update documentation to reflect (haha) recent updates to MultiToggle 2008-03-25 18:56:30 +00:00
Lukas Mai
529797ae8e XMonad.Layout.HintedTile: make alignment of shrunk windows configurable 2008-03-25 20:29:58 +00:00
Brent Yorgey
687c898c55 XMonad.Actions.Commands: documentation fix 2008-03-25 16:57:07 +00:00
redbeard0531
492b1e27c2 focusedHasProperty 2008-03-25 04:04:12 +00:00
Brent Yorgey
0900dbf0be XMonad.Util.Themes: improve documentation to make it clear that themes only apply to decorated layouts 2008-03-24 18:59:46 +00:00
Brent Yorgey
883b803794 Doc/Extending: remove references to "XMonad.Layouts" -- it's now called "XMonad.Layout", and in any case, importing it explicitly is not needed anyway. 2008-03-24 14:35:03 +00:00
Brent Yorgey
6fd03c107c XMonad.Actions.Search: add Google Maps search 2008-03-24 14:33:48 +00:00
Brent Yorgey
16fc0f231d XMonad.Layout.Magnifier: add documentation 2008-03-24 14:32:14 +00:00
wcfarrington
cfb3f6575e wfarrTheme
Add a new color theme using blue and black.
2008-03-24 01:16:25 +00:00
Justin Bogner
f0cb1b3bf2 added RunOrRaisePrompt, exported getCommands from Shell 2008-03-23 22:26:32 +00:00
Lukas Mai
180298def6 XMonad.Actions.MouseGestures: reexport Direction from WindowNavigation, avoid type duplication 2008-03-22 19:34:57 +00:00
David Roundy
b378857a8e use ewmhDesktopsLayout in Droundy. 2008-03-22 15:36:10 +00:00
David Roundy
c0519e4375 cut Anneal and Mosaic. 2008-03-22 15:35:46 +00:00
David Roundy
f86648cf7c fix WorkspaceDir to work when there are multiple screens.
In particlar, ScratchWorkspace broke this.
2008-03-11 22:12:01 +00:00
Lukas Mai
4b7167c6e5 fix various compilation errors 2008-03-22 07:41:13 +00:00
Lukas Mai
a9a8e488ef XMonad.Layout.NoBorders: first attempt at documenting smartBorders 2008-03-21 22:13:15 +00:00
daniel
7d0b8fd72f allow magnifier to toggle whether it's active 2008-03-21 10:46:05 +00:00
daniel
d0260ddbff a magnifier that defaults to not magnifying any windows 2008-03-21 10:44:41 +00:00
Lukas Mai
f34258af22 XMonad.Layout.Magnifier: remove references to Data.Ratio.% from documentation 2008-03-20 22:38:16 +00:00
Don Stewart
426a9e4795 mark Mosaic as broken. use MosaicAlt 2008-03-20 22:37:17 +00:00
Joachim Breitner
ce2b39be1a add ewmhDesktopsLayout for EWMH interaction
This is based on Andrea’s EventHook thingy. Note that I could not merge
this with some of my earlier EWHM interaction patches (darcs was failing on me),
so I copied some code. Do not try to merge it with those patches either.

Note that the docs are saying what should work. There are still some bugs
to be resolved, but it works sometimes and should work similar to what we have.
2008-03-19 19:57:36 +00:00
Joachim Breitner
098f11e1c0 Export HandleEvent type to be able to use it in type annotations 2008-03-19 19:56:03 +00:00
Andrea Rossato
f1c5f11c2e I now use ServerMode 2008-02-26 11:53:47 +00:00
Andrea Rossato
12ca9dbfa6 EventHook: handle events after the underlying layout and more
- check the first time the Bool is True
- coding and naming style
2008-02-24 23:08:54 +00:00
Andrea Rossato
6cac436d47 Add Hooks.ServerMode: an event hook to execute commands sent by an external client 2008-02-24 13:37:06 +00:00
Andrea Rossato
ce6241b6b3 Add EventHook: a layout modifier to handle X events 2008-02-24 11:24:32 +00:00
Don Stewart
c60522bfef tabs 2008-03-17 22:47:58 +00:00
Brent Yorgey
1c7e519126 WindowProperties: fix documentation 2008-03-18 20:45:40 +00:00
Roman Cheplyaka
4015eb2c6f Move window properties to a separate Util module
Add XMonad.Util.WindowProperties
Modify XMonad.Layout.IM.hs to use WindowProperties.
2008-03-18 16:56:58 +00:00
Lukas Mai
7a341fa790 XMonad.Layout.NoBorders: always unborder fullscreen floating windows, even when there are multiple screens 2008-03-17 18:30:43 +00:00
Brent Yorgey
a1fce4af5a MagicFocus: reimplement as a LayoutModifier, fix bug (MagicFocus didn't pass on messages to underlying layouts) 2008-03-17 19:30:08 +00:00
gwern0
929c9a1b56 WindowGo.hs: improve description
I'm still not sure whether the description makes sense if you don't already understand the idea.
2008-03-16 22:39:46 +00:00
gwern0
7d5235e942 Run.hs: improve haddock
This module too was causing horizontal scrolling because of the shell command. I managed to discover that you only need to specify 'png:' *or* "foo.png", not both, which trimmed off enough characters.
Also, I improved the docs for my functions.
2008-03-16 22:32:19 +00:00
gwern0
3b09878000 XSelection.hs: improved haddockf formatting, more links, & cpedit 2008-03-16 22:20:50 +00:00
gwern0
a97c325b8b Search.hs: try to add a more descriptive type 2008-03-16 21:57:28 +00:00
gwern0
aca42e5ddb improve the formatting for WindowGo.hs 2008-03-16 21:56:42 +00:00
gwern0
87bb590217 Search.hs: haddock fmt
This removes whitespace in source code snippets. Because Haddock renders quoted source code as monospaced unwrappable text, the excess whitespace meant you would have to scroll horizontally, unpleasantly.
2008-03-16 21:39:14 +00:00
xmonad
e216c95beb Add XMonad.Actions.Promote 2008-03-16 20:57:22 +00:00
Brent Yorgey
2526a5ddaa LayoutCombinators: improve documentation (closes ticket #136) 2008-03-16 19:58:26 +00:00
Lukas Mai
2000ddb82e Xmonad.Layout.NoBorders: make smartBorders unborder fullscreen floating windows (bug 157) 2008-03-16 04:29:41 +00:00
Lukas Mai
9ccc684f3d Xmonad.Prompt.DirExec: fix haddock error 2008-03-16 04:28:40 +00:00
Alec Berryman
f38f27420b EwmhDesktops: advertise support for _NET_CLIENT_LIST_STACKING 2008-03-15 21:26:31 +00:00
Brent Yorgey
245fd850e3 ScratchWorkspace: update to work with runLayout changes 2008-03-11 21:29:08 +00:00
Brent Yorgey
bf8268c003 Scratchpad: update to work with runLayout changes 2008-03-11 18:17:15 +00:00
Brent Yorgey
eb18de22c8 MagicFocus: update to work with runLayout changes 2008-03-11 18:16:25 +00:00
Brent Yorgey
8b27f8e0aa LayoutScreens: update to work with runLayout changes 2008-03-11 18:15:37 +00:00
Brent Yorgey
a0daaf1e47 Combo: update to work with runLayout changes 2008-03-11 18:14:00 +00:00
Brent Yorgey
5769b3343b MultiToggle: fix to work with runLayout changes to core 2008-03-11 17:20:46 +00:00
Andrea Rossato
32941d49b4 PerWorksapce: use a safer False as default 2008-02-23 07:55:31 +00:00
Andrea Rossato
c9e4f2dc10 PerWorkspace: reimplemented using runLayout
This way we have a Xinerama safe PerWorkspace and the emptyLayout
method for free.
2008-02-22 17:59:54 +00:00
Andrea Rossato
c2dcd6ede8 ToggleLayouts: reimplemented with runLayout 2008-02-23 08:15:53 +00:00
Andrea Rossato
e0987d1330 LayoutCombinators: NewSelect reimplemented with runLayout 2008-02-23 08:09:58 +00:00
Andrea Rossato
3ca4966b06 LayoutModifier: reimplement ModifiedLayout using runLayout and more
- change modifyLayout type to get the Workspace
- updated ResizeScreen and ManageDocks accordingly.
2008-02-23 07:56:10 +00:00
Andrea Rossato
9ac91e3a15 Combo: updated to latest runLayout changes 2008-02-22 17:59:24 +00:00
Brent Yorgey
5acc881930 EZConfig: add documentation and a warning, so no one repeats my silly hard-to-track-down mistake. 2008-03-11 17:26:10 +00:00
robreim
c4b0af9adf Fix to work with "floats always use current screen" patch 2008-03-08 02:49:28 +00:00
David Roundy
8950dced20 make smartBorders ignore screens with no dimensions. 2008-03-08 22:42:44 +00:00
David Roundy
c754adc48b rewrite ScratchWorkspace to make scratch always visible, but not always on screen. 2008-03-08 22:38:30 +00:00
David Roundy
6da9d73f0d add HiddenNonEmptyWS to CycleWS to avoid workspaces already visible. 2008-03-08 22:37:17 +00:00
Roman Cheplyaka
0db06db23e Fix ThreeColumns doc. 2008-03-07 20:30:22 +00:00
Andrea Rossato
83f5512909 Shell: add support for UTF-8 locales 2008-03-02 09:59:24 +00:00
Andrea Rossato
5a9781ee48 Font and XUtils: add UTF-8 support and various fixes related to XFT
- printStringXMF: use the background color for XFT fonts too
- textWidthXMF now returns the text width even with xft fonts
- textExtentsXMF will now return only the ascend and the descent of a
  string.
- stringPosition now takes the display too
- add support for UTF-8 locales: if the contrib library is compiled
  with the 'with_xft' or the 'with_utf8' option the prompt and the
  decoration system will support UTF-8 locales - this requires
  utf8-strings.
2008-03-02 09:57:12 +00:00
Andrea Rossato
7f14dbb5dd Ssh: coding style 2008-02-29 10:03:46 +00:00
Andrea Rossato
639558798f Ssh: complete known hosts with non standard ports too 2008-02-29 09:50:14 +00:00
nicolas.pouillard
579a3feb1c Fix xmonadPromptC and use it. 2008-03-06 16:39:28 +00:00
nicolas.pouillard
7f8882faf2 Documentation typo about UpdatePointer. 2008-03-06 16:35:16 +00:00
Braden Shepherdson
3a6e2d8b8e Fix ToggleOff: It was adding 0.1 to the magnification. 2008-03-05 22:23:02 +00:00
Juraj Hercek
4f2e1927b0 Removed WmiiActions module. 2008-03-05 08:23:36 +00:00
Juraj Hercek
91da412bf1 Adjusted signature of DirExec module functions.
- added parameter for function which executes the selected program
  - renamed dirExecPromptWithName to dirExecPromptNamed
2008-03-01 17:19:05 +00:00
Juraj Hercek
34f9ad7d1f Import of new DirExec module.
- allows execution of executable files from specific directory
2008-02-29 21:22:57 +00:00
Dmitry Kurochkin
9b6b495e06 Hooks.DynamicLog: export xmobarPP 2008-03-03 21:56:37 +00:00
Brent Yorgey
413296ca8a Magnifier: fix behavior for windows on the bottom + right of the screen. Now all magnified windows will be the same size, possibly shifted in order to fit completely on the screen. 2008-03-03 20:46:19 +00:00
robreim
d44253f17f Changed semantics of UpdatePointer to move to nearest point 2008-03-01 14:31:26 +00:00
robreim
26de20d294 UpdatePointer XMonadContrib module 2008-03-01 13:44:01 +00:00
gwern0
ef50ecda71 Util.Run: minor clarification in comment 2008-03-03 05:15:13 +00:00
Roman Cheplyaka
11e57ce367 Add XMonad.Actions.PerWorkspaceKeys 2008-03-02 20:23:46 +00:00
Dominik Bruhn
2d7ceeb75e Haddock fix: Changed URL-Markup 2008-03-02 18:54:35 +00:00
David Roundy
372f1e14fe switch Droundy to smartBorders (which works better with ScratchWorkspace). 2008-03-01 19:11:03 +00:00
Lukas Mai
68a05495e5 XMonad.Layout.Simplest: add FlexibleInstances pragma 2008-03-01 06:17:14 +00:00
Lukas Mai
6b72b94994 XMonad.Layout.ScratchWorkspace: avoid warnings, make tests compile again 2008-03-01 06:16:25 +00:00
David Roundy
4e6f032d64 implement ScratchWorkspace. 2008-02-29 22:43:16 +00:00
David Roundy
93cf069aab in Prompt.Workspace sort by official workspace order. 2008-02-29 22:30:47 +00:00
David Roundy
dca8b60cd5 simplify Simplest--allow it to apply to non-Windows. 2008-02-29 22:13:26 +00:00
Lukas Mai
77476932c4 XMonad.Actions.MouseGestures.mkCollect: generalize type 2008-02-29 21:17:32 +00:00
Roman Cheplyaka
b3a9ed8dcd Add bottom-tabbed layout. 2008-02-29 15:51:20 +00:00
Lukas Mai
2fb79e1d70 XMonad.Actions.MouseGestures: refactoring, code simplification
It is now possible to get "live" status updates while the gesture handler
is running. I use this in my xmonad.hs to print the current gesture to my
status bar. Because collecting movements is now the callback's job, the
implementation of mouseGestureH got quite a bit simpler. The interface is
incompatible with the previous mouseGestureH but the old mouseGesture
function works as before.
2008-02-29 00:21:36 +00:00
Brent Yorgey
40b636aea5 EZConfig: additional documentation 2008-02-27 16:46:02 +00:00
Brent Yorgey
9eeca8057b XMonad.Util.Scratchpad: change 'XConfig Layout' to 'XConfig l', to avoid type mismatches; the exact layout type doesn't actually matter 2008-02-27 01:42:01 +00:00
Brent Yorgey
3cbddabe3d EZConfig: add an emacs-style keybinding parser!
Now, instead of writing out incredibly dull things like

  ((modMask conf .|. controlMask .|. shiftMask, xK_F2), ...)

you can just write

  ("M-C-S-<F2>", ...)

Hooray!
2008-02-26 22:27:23 +00:00
Lukas Mai
cdab5ae1c3 Xmonad.Actions.MouseGestures: generalize interface, allow hooks 2008-02-26 20:26:39 +00:00
Lukas Mai
09a12b46f6 update inactive debugging code in MouseGestures; no visible changes 2007-11-09 02:07:55 +00:00
Braden Shepherdson
04a8c51f95 Scratchpad terminal
Key binding and ManageHook to pop up a small, floating terminal window for a few quick commands.

Combined with a utility like detach[1], makes a great X application launcher.

Requires my two new ManageHooks (doRectFloat, specifically).

[1] http://detach.sourceforge.net
2008-02-25 18:36:33 +00:00
Braden Shepherdson
da14e60ded Two new floating window ManageHooks.
Adds doRectFloat, which floats the new window in the given rectangle; and doCenterFloat, which floats the 
new window with its original size, but centered.
2008-02-25 18:33:37 +00:00
Roman Cheplyaka
e185d12b78 Fix usage doc. 2008-02-25 06:23:30 +00:00
Roman Cheplyaka
aa4a928d36 Fix haddock hyperlink. 2008-02-24 20:54:16 +00:00
Roman Cheplyaka
37b2051c04 Add XMonad.Layout.IM 2008-02-21 08:57:52 +00:00
Roman Cheplyaka
4e828e85e3 Export XMonad.Layout.Grid.arrange (for use in XMonad.Layout.IM) 2008-02-21 06:22:04 +00:00
Andrea Rossato
d9e8311d52 Decoration: some haddock updates 2008-02-20 21:49:34 +00:00
Nils Anders Danielsson
10862fe143 Small refactoring. 2008-02-10 22:47:56 +00:00
Nils Anders Danielsson
83df2b4415 Fixed off-by-one error which broke strut handling for some panels. 2008-02-10 22:26:00 +00:00
Andrea Rossato
e093874211 Decoration: fix an issue with decoration window creation and more
- fix a bug reported by Roman Cheplyaka: when decorate returned
  Nothing the window was never going to be created, even if decorate
  was reporting a Just Rectangle in the next run. Quite a deep issue,
  still visible only with TabbedDecoration at the present time.
- remove decorateFirst (decorate has enough information to decide
  whether a window is the first one or not, am I right, David?)
- some point free.
2008-02-20 20:43:55 +00:00
Andrea Rossato
cbeae0b86c DynamicLog.hs: haddock fix
Someone forgot to check if her patch was going to break haddock docs
generation or not. So, while I was recording a patch with quite a long
description I had to manually write - sound strange? -, I found out
that my patch did not pass the tests, because of this haddock problem
left behind.

And so I fixed it, recorded this patch, with the hope the my next
description of the next patch I'm going to record will survive the
test suite we created to avoid this kind of problems for.
2008-02-20 20:40:33 +00:00
Brent Yorgey
2a8cb7d84c improvements to XMonad.Hooks.DynamicLog, and new contrib module XMonad.Util.Loggers
Improvements to DynamicLog include:
  * Greatly expanded and improved documentation and examples
  * remove seemingly useless makeSimpleDzenConfig function
  * factor out xmobarPP
  * add new ppExtras field to PP record, for specifying 'extra'
    loggers which can supply information other than window title,
    layout, and workspace status to a status bar (for example, time and date,
    battery status, mail status, etc.)

The new XMonad.Util.Loggers module provides some example loggers that 
can be used in the new ppExtras field of the PP record.  Create your own,
add them to this module, go crazy! =)
2008-02-19 21:01:28 +00:00
Andrea Rossato
172d422efb LayoutHints: fix a wrong fix
The case analisys of my fix should be the other way around... this is
the real fix.
2008-02-19 16:51:27 +00:00
Andrea Rossato
9cd93a043a Arossato: updated to latest changes 2008-02-19 16:30:58 +00:00
Andrea Rossato
ce95a5c93a Decoration: comment only
This is a detailed commentary of all the code.
2008-02-19 16:13:39 +00:00
Andrea Rossato
3f40309087 Decoratione: generate rectangles first, and create windows accordingly
With this patch Decoration will first generate a rectangle and only if
there is a rectangle available a window will be created.

This makes the Decoration state a bit more difficult to process, but
should reduce resource consumption.
2008-02-19 12:21:15 +00:00
Roman Cheplyaka
ad5b862c5a Fix doc for Tabbed 2008-02-19 05:56:50 +00:00
Andrea Rossato
a6ce16d2e7 Tabbed and TabBarDecoration: no need to implement decorateFirst (the default is used) 2008-02-18 18:49:50 +00:00
Andrea Rossato
fd250226bc TabBarDecoration: simpleTabBar automatically applies resizeVertical
Added some comments too.
2008-02-18 18:09:22 +00:00
Andrea Rossato
a0067681f3 DwmStyle: comment fix only 2008-02-18 18:07:27 +00:00
Andrea Rossato
4136c4eb22 ResizeScreen: add resizeHorizontalRight and resizeVerticalBottom 2008-02-18 18:05:04 +00:00
Andrea Rossato
1e85802e2f Add TabBarDecoration, a layout modifier to add a bar of tabs to any layout
... and port DecorationMadness to the new system.
2008-02-18 16:11:21 +00:00
Andrea Rossato
cf4bd0a225 add Eq superclass to DecorationStyle and change styles in order not to decorate non managed windows 2008-02-18 13:13:20 +00:00
Andrea Rossato
651acdbc3e Refactor MouseResize, remove isDecoration and introduce isInStack, isVisible, isInvisible
This patch includes several changes, which are strictly related and
cannot be recorded separately:
- remove Decoraion.isDecoartion and introduce Decoration.isInStack
  (with the related change to LayoutHints)
- in Decoration introduce useful utilities: isVisible, isInvisible,
  isWithin and lookFor'
- MouseResize: - invisible inputOnly windows will not be created;
	       - fix a bug in the read instance which caused a failure
                 in the state deserialization.
2008-02-18 10:57:26 +00:00
Andrea Rossato
cb3f424823 Prompt: regenerate completion list if there's just one completion 2008-02-17 13:27:34 +00:00
Andrea Rossato
977349d911 Prompt.Theme: use mkComplFunFromList' to generate completions 2008-02-17 12:44:53 +00:00
Andrea Rossato
72806ee75c some code formatting 2008-02-17 12:44:34 +00:00
Andrea Rossato
6a026cf692 Prompt: comment only (clafiry completionToCommand uses) 2008-02-16 18:16:20 +00:00
Andrea Rossato
11d3eff158 Prompt: comment only (remove confusing remarks about commandToComplete) 2008-02-16 18:04:12 +00:00
Andrea Rossato
2871ea6662 Prompt: haddock fixes only 2008-02-16 17:23:31 +00:00
Andrea Rossato
62637b0325 Prompt.XMonad: use mkComplFunFromList' to get all the completions with an empty command line 2008-02-16 13:39:49 +00:00
Andrea Rossato
4def39f610 Prompt.Window: remove unneeded and ugly escaping/unescaping 2008-02-16 13:38:42 +00:00
Andrea Rossato
f611982205 Theme: move theme's nextCompletion implementation to Prompt.getNextCompletion 2008-02-16 13:37:38 +00:00
Andrea Rossato
b06e4a50fb Shell: escape the string in the command line only 2008-02-16 13:36:51 +00:00
Andrea Rossato
a7da5dd460 Prompt: add some methods to make completions more flexible
- now it is possible to decide if the prompt will complete the last
  word of the command line or the whole line (default is the last
  word);
- completing the last word can be fine tuned by implementing
  'commandToComplete' and 'completionToCommand': see comments for
  details;
- move mkComplFunFromList' from TagWindows to Prompt.
2008-02-16 13:34:54 +00:00
Andrea Rossato
1dd33dc560 Prompt.Theme: display all theme information and handle completion accordingly 2008-02-16 11:41:59 +00:00
Andrea Rossato
e753278080 Prompt.Shell: if there's just one completion and it is a directory add a trailing slash 2008-02-16 11:40:05 +00:00
Andrea Rossato
99f6944c3d Prompt: added nextCompletion and commandToComplete methods to fine tune prompts' completion functions 2008-02-16 11:37:23 +00:00
Andrea Rossato
8a793ce064 Util.Themes: add ppThemeInfor to render the theme info 2008-02-16 11:36:35 +00:00
Andrea Rossato
f4fc09b00d DecorationMadness: resizable layouts now use MouseResize too 2008-02-12 17:36:45 +00:00
Andrea Rossato
94b2529999 SimpleFloat now uses MouseResize 2008-02-12 17:36:15 +00:00
Andrea Rossato
c948559c53 Add Actions.MouseResize: a layout modifier to resize windows with the mouse 2008-02-12 17:34:55 +00:00
Andrea Rossato
c5a57f337e Decoration: remove mouse resize and more
- since mouse resize is not related to decoration, I removed the code
  from here. Mouse resize will be handled by a separated layout
  modifier (in a separated module)
- now also stacked decoration will be removed (I separated insert_dwr
  from remove_stacked)
2008-02-12 16:53:06 +00:00
Andrea Rossato
0d69127db5 Decoration.hs: variable names consistency only 2008-02-11 12:30:56 +00:00
Andrea Rossato
7e8276d0b7 Tabbed and SimpleTabbed (in DecorationMadness) define their own decorationMouseDragHook method
... to disable mouse drag in tabbed layouts
2008-02-11 11:40:43 +00:00
Andrea Rossato
7ffe391d6c Decoration: DecorationStyle class cleanup and focus/drag unification
- moved decoEventHook to decorationEventHook
- added decorationMouseFocusHook, decorationMouseDragHook,
  decorationMouseResizeHook methods
- added a handleMouseFocusDrag to focus and drag a window (which makes
  it possible to focus *and* drag unfocused windows too
2008-02-11 11:36:50 +00:00
Roman Cheplyaka
364ba77cdc Refactor XMonad.Hooks.DynamicLog
This allows using DynamicLog not only for statusbar.
2008-02-10 22:24:06 +00:00
Andrea Rossato
f764fea592 DecorationMadness: comment only 2008-02-10 13:14:27 +00:00
Andrea Rossato
e57a9f011d DecorationMadness: added a few floating layouts 2008-02-10 12:25:23 +00:00
Andrea Rossato
ab38525b72 SimpleFloat: export SimpleFloat and add documentation 2008-02-10 11:31:59 +00:00
Andrea Rossato
041f12f21d Move DefaultDecoration from DecorationMadness to Decoration 2008-02-10 10:43:04 +00:00
Andrea Rossato
c1090dfcaf Themes: added robertTheme and donaldTheme 2008-02-10 08:30:16 +00:00
Andrea Rossato
97371565fa DecorationMadness: make tunable tabbed layouts respect the Theme decoHeight field 2008-02-10 07:53:22 +00:00
Andrea Rossato
f2a268c14e ScreenResize: vertical and horizontal now respond to SetTheme
And so they will change the screen dimension accordingly.
2008-02-10 07:45:44 +00:00
Brent Yorgey
8f71c70d37 WindowGo.hs: fix syntax in example 2008-02-09 22:51:35 +00:00
gwern0
37748e0b26 +doc for WindowGo.hs: I've discovered a common usecase for me for raiseMaybe 2008-02-05 03:21:55 +00:00
gwern0
14792eb6cc Run.hs: add an option to runinterms
It turns out that for urxvt, and most terminal, apparently, once you give a '-e' option, that's it.
They will not interpret anything after that as anything but input for /bin/sh, so if you wanted to go 'runInTerm "'screen -r session' -title IRC"',
you were SOL - the -title would not be seen by urxvt. This, needless to say, is bad, since then you can't do stuff like set the title which means
various hooks and extensions are helpless. This patch adds an extra options argument which is inserted *before* the -e. If you want the old behaivour,
you can just go 'runInTerm "" "executable"', but now if you need to do something extra, 'runInTerm "-title mutt" "mutt"' works fine.

This patch also updates callers.
2008-02-05 03:18:24 +00:00
Andrea Rossato
84d5962dbe Add DecorationMadness: a repository of weirdnesses 2008-02-09 18:25:15 +00:00
Andrea Rossato
29093c6493 Decoration: change mouseEventHook to decoEventHook and more
Fix also the problem with window's movement when the grabbing starts
2008-02-09 16:51:01 +00:00
Andrea Rossato
4ee7aafd1c Tabbed: add simpleTabbed and fx documentation
simpleTabbed is just a version of tabbed with default theme and
default srhinker.
2008-02-09 16:39:17 +00:00
Andrea Rossato
42f78498f1 Arossato: update to latest changes 2008-02-08 14:06:04 +00:00
Andrea Rossato
b8cf0d0694 Decoration: enable mouse dragging of windows 2008-02-08 08:36:02 +00:00
Andrea Rossato
954981e2e3 WindowArranger: add a SetGeometry message - needed to enable mouseDrag 2008-02-08 08:34:13 +00:00
Andrea Rossato
7f5d86009d Decoration: add a mouseEventHook methohd and move mouse button event there 2008-02-08 07:35:14 +00:00
Andrea Rossato
1a99a75bf3 Util.Thems: some more typos in comments 2008-02-07 23:33:41 +00:00
Andrea Rossato
3df63c7376 Util.Themes: documentation and export list (added themes that have been left out) 2008-02-07 23:22:51 +00:00
Andrea Rossato
0e9b9d7263 Prompt.Theme: comments and some point-free 2008-02-07 23:21:55 +00:00
its.sec
44730f59b3 oxymor00nTheme 2008-02-07 21:31:00 +00:00
its.sec
3e5b16da3d add swapScreen to CycleWS
* add support for swapping the workspaces on screens to CycleWS
2008-02-06 19:10:32 +00:00
Andrea Rossato
8578cf419a Decoration: consistency of variable names
Since the configuration is now called Theme, the variable 'c' is now a
't'
2008-02-07 19:14:42 +00:00
Andrea Rossato
7493f8fb04 Add Prompt.Theme: a prompt for dynamically applying a theme to the current workspace 2008-02-07 18:43:21 +00:00
Andrea Rossato
2170415689 Decoration: add a SetTheme message and releaseResources
...which should make it harder to forget to release the font structure.
2008-02-07 18:40:48 +00:00
Andrea Rossato
b690154b97 cabal file: respect alphabetic order for modules 2008-02-07 18:31:53 +00:00
Andrea Rossato
89fa996786 Add Util.Themes to collect user contributed themes 2008-02-07 18:28:43 +00:00
Andrea Rossato
4621e66837 SimpleFloat: comment only 2008-02-07 18:24:38 +00:00
Don Stewart
0675af2b53 Update to safer initColor api 2008-02-06 19:22:32 +00:00
David Roundy
7b022b9981 use Util.WorkspaceCompare in Prompt.Workspace. 2008-02-06 00:40:57 +00:00
David Roundy
ed6b36b289 roll back to previous version of Droundy.hs.
A cleaner WindowNavigation fix made the separation of tabbed and addTabs
not strictly necessary (but still a desireable possibility in my opinion,
as it allows pretty decoration of non-composite layouts that might want to
have some of their windows tabbed.
2008-02-05 20:40:43 +00:00
David Roundy
026400e7ef make WindowNavigation ignore decorations. 2008-02-05 20:35:56 +00:00
David Roundy
5df47fcfc5 make tabbed work nicely with LayoutCombinators and WindowNavigation.
The problem is that WindowNavigation assumes all windows are navigable, and
it was getting confused by decorations.  With a bit of work, we can
decorate windows *after* combining layouts just fine.
2008-02-05 20:23:43 +00:00
David Roundy
f804991d22 make WindowNavigation work when windows are stacked. 2008-02-05 20:20:27 +00:00
gwern0
4c7a536465 XMonad.Actions.WindowGo: add a runOrRaise module for Joseph Garvin with the help of Spencer Janssen 2008-02-04 17:34:02 +00:00
David Roundy
10f24bccaf enable proper handling of panels in droundy config. 2008-02-04 03:08:43 +00:00
David Roundy
a19af8a4f0 enable button click for focus in tabbed.
Note that this patch doesn't work with

Thu Dec 27 03:03:56 EST 2007  Spencer Janssen <sjanssen@cse.unl.edu>
  * Broadcast button events to all layouts, fix for issue #111

but this isn't a regression, since button events have never worked with
tabbed and this change.
2008-02-04 01:05:36 +00:00
David Roundy
dc81032fa8 in Decoration, remove windows that are precisely hidden underneath other windows.
This is needed for WindowNavigation to work properly with the new
Decorations framework.
2008-02-04 00:54:13 +00:00
David Roundy
8034498f91 switch tabbed back to using Simplest (so tabs will be shown). 2008-02-04 00:53:50 +00:00
Brent Yorgey
e6d229e8e1 CycleWS: change example binding for toggleWS from mod-t to mod-z. example bindings shouldn't conflict with default key bindings. 2008-02-01 20:21:26 +00:00
Brent Yorgey
5492a1265e REMOVE RotView: use CycleWS instead.
See CycleWS docs for info on switching, or just look at the changes to
XMonad.Config.Droundy.
2008-02-01 18:06:18 +00:00
Brent Yorgey
1cfbd20de1 CycleWS: add more general functionality that now subsumes the functionality of RotView. Now with parameterized workspace sorting and predicates! 2008-02-01 12:15:24 +00:00
Brent Yorgey
902240b5e0 WorkspaceCompare: some refactoring.
* Export WorkspaceCompare and WorkspaceSort types.
  * Extract commonality in sort methods into mkWsSort, which creates
    a workspace sort from a workspace comparison function.
  * Rename getSortByTag to getSortByIndex, since it did not actually sort
    by tag at all; it sorts by index of workspace tags in the user's config.
  * Create a new getSortByTag function which actually does sort
    lexicographically by tag.
  * Enhance documentation.
2008-02-01 12:04:30 +00:00
Brent Yorgey
e685c5d0ff Search.hs: haddock cleanup 2008-01-31 16:19:48 +00:00
v.dijk.bas
f2877c4f20 Added a handy tip to the documentation of XMonad.Actions.Search
The tip explains how to use the submap action to create a handy submap of keybindings for searching.
2008-01-31 12:26:20 +00:00
Andrea Rossato
3b04fd4235 Make LayoutHints a decoration aware layout modifier 2008-01-31 08:23:14 +00:00
Andrea Rossato
de1d0432b2 Remove LayoutCombinator class and revert PerWorkspace to its Maybe Bool state
As I said in order to have a CombinedLayout type instace of
LayoutClass and a class for easily writing pure and impure combinators
to be feeded to the CombinedLayout together with the layouts to be
conbined, there's seems to be the need to change the type of the
LayoutClass.description method from l a -> String to l a -> X String.

Without that "ugly" change - loosing the purity of the description
(please note the *every* methods of that class unless description
operates in the X monad) - I'm plainly unable to write something
really useful and maintainable. If someone can point me in the right
direction I would really really appreciate.

Since, in the meantime, PerWorkspace, which has its users, is broken
and I broke it, I'm reverting it to it supposedly more beautiful
PerWorkspac [WorkspaceId] (Maybe Bool) (l1 a) (l2 a) type.
2008-01-31 06:39:29 +00:00
Brent Yorgey
adf747b666 Extending.hs: documentation update 2008-01-31 01:27:28 +00:00
Brent Yorgey
1826f43e85 DynamicLog: lots of additional documentation; add byorgeyPP as an example dzen config 2008-01-30 20:52:19 +00:00
Juraj Hercek
f5a867c3a9 Extended PP with sorting algorithm specification and added xinerama sorting
algorithm
  - idea is to specify sorting algorithm from user's xmonad.hs
  - xinerama sorting algorithm produces same ordering as
    pprWindowSetXinerama
  - default ppSort is set to getSortByTag, so the default functionality
    is the same as it was before
2008-01-09 15:49:23 +00:00
Andrea Rossato
9222210f22 SimpleDecoration: export defaultTheme 2008-01-30 12:46:09 +00:00
Spencer Janssen
dfa3a4ee01 Various decorations related updates
* remove deprecated TConf stuff
 * Remove 'style' from DeConf
 * Change DeConf to Theme
 * share defaultTheme across all decorations
2008-01-30 06:46:24 +00:00
Joachim Fasting
c050c3efa9 TwoPane: add description string 2008-01-26 14:13:32 +00:00
Roman Cheplyaka
bb1fce547f add XMonad.Actions.CycleSelectedLayouts 2008-01-16 20:50:20 +00:00
Brent Yorgey
63a63b3bd0 Search.hs: add documentation and two more search engines (MathWorld and Google Scholar) 2008-01-28 19:04:43 +00:00
Brent Yorgey
fd3751ea61 xmonad-contrib.cabal: add build-type field to get rid of Cabal warning 2008-01-28 19:01:37 +00:00
Andrea Rossato
2797c0d71b LayoutCombinator class: code clean up
- ComboType becomes CombboChooser
- removed the stupid doFirst
- better comboDescription default implemenation
2008-01-29 22:49:52 +00:00
Andrea Rossato
055a6b1232 Add a LayoutCombinator class and a CombinedLayout and port PerWorkspace to the new system 2008-01-29 19:29:03 +00:00
Andrea Rossato
f23a87f4e6 Named: reimplemented as a LayoutModifier and updated Config.Droundy accordingly 2008-01-28 16:13:43 +00:00
Andrea Rossato
6912227914 LayoutModifier: add modifyDescription for completely override the modified layout description 2008-01-28 16:06:14 +00:00
Andrea Rossato
5dab294a2d Make ToggleLayouts and Named implement emptyLayout 2008-01-28 15:15:35 +00:00
Andrea Rossato
97acd14ed5 Decoration: the fontset must be released even when we don't decorate the first window
This is quite an old bug! It affected Tabbed since the very beginning..;)
2008-01-28 00:44:11 +00:00
Andrea Rossato
beea8ab5d8 Decoration: I forgot we need to release the fontset too! 2008-01-27 23:35:21 +00:00
Andrea Rossato
700944720b Decoration: after deleting the windows we must update the layout modifier
Thanks to Feuerbach for reporting this.
2008-01-27 23:18:15 +00:00
Andrea Rossato
c281e20e0a Reflect: reimplemented as a layout modifier (which makes it compatible with windowArranger and decoration) 2008-01-27 16:58:54 +00:00
Andrea Rossato
ddbbc56285 SimpleFLoat: change the description to Float (Simple is the decoration description) 2008-01-27 14:45:56 +00:00
Andrea Rossato
14d7231dd0 ManageDocks: implement AvoidStruts as a layout modifier 2008-01-27 14:43:01 +00:00
Andrea Rossato
18921e16c9 ResizeScreen has been rewritten as a layout modifier 2008-01-27 14:08:37 +00:00
Andrea Rossato
0f0a99e355 LayoutModifier add a modifyLayout
Many layouts are written as layout modifiers because they need to
change the stack of the rectangle before executing doLayout.

This is a major source of bugs. all layout modifiers should be using the
LayoutModifier class. This method (modifyLayout) can be used to
manipulate the rectangle and the stack before running doLayout by the
layout modifier.
2008-01-27 14:02:19 +00:00
Andrea Rossato
099d1c689f Make LayoutCombinators deal with emptyLayout 2008-01-27 09:24:15 +00:00
Andrea Rossato
ee0b0d59cb Add ResizeScreen, a layout modifier for modifing the screen geometry 2008-01-27 01:07:55 +00:00
Andrea Rossato
8f65eecf92 WindowArranger can now arrange all windows
This is useful for SimpleFloat, whose state can now persists across
layout switches.
2008-01-26 23:30:53 +00:00
Andrea Rossato
bb4c97ede0 Arossato: updated my config to recent changes 2008-01-26 20:56:38 +00:00
Andrea Rossato
de40bee12f Add SimpleFloat a very basic floating layout that will place windows according to their size hints 2008-01-26 20:54:10 +00:00
Andrea Rossato
c84a26022d WindoWrranger: export the WindowArranger type (see the upcoming SimpleFloat) 2008-01-26 20:46:05 +00:00
Andrea Rossato
d32fa5ae21 ShowWName: show the name of empty layouts too 2008-01-26 19:02:14 +00:00
Andrea Rossato
07c2c3e7f9 ManageDocks: add emptyLayout definition for supporting the new decoration framework 2008-01-26 18:59:36 +00:00
Andrea Rossato
a7bc2bf88e Decoration: code formatting only 2008-01-26 10:13:54 +00:00
Andrea Rossato
6d21eb841e export DeConfig to avoid importing Decoration 2008-01-26 10:10:49 +00:00
Andrea Rossato
ababfeca6f Prompt: code formatting only 2008-01-26 09:32:34 +00:00
Andrea Rossato
041eb5dc18 Don't export TConf anymore and export DeConfig instead
WARNING: this patch may be breaking your configuration. While it is
still possible to use:

tabbed shrinkText defaultTConf

updating the fields of the defaultTConf record is not possible
anymore, since the type TConf is now hidden.

WARNING: "tabSize" has been substituted by "decoHeight"

You can change your configuration this way:
myTConf :: TConf
myTConf = defaultTConf
       { tabSize = 15
       , etc....

becomes:
myTConf :: DeConfig TabbedDecoration Window
myTConf = defaultTabbedConfig
       { decoHeight = 15
       , etc....

and
tabbed shrinkText myTConf

becomes:
tabDeco shrinkText myTConf
2008-01-26 09:21:41 +00:00
Andrea Rossato
baca0e98d1 Tabbed now uses Decoration 2008-01-25 15:23:11 +00:00
Andrea Rossato
18e5a2658f Add DwmStyle, a layout modifier to add dwm-style decorations to windows in any layout 2008-01-25 15:21:52 +00:00
Andrea Rossato
8c3d08544a Adde SimpleDecoration, a layout modifier to add simple decorations to windows in any layout 2008-01-25 15:21:06 +00:00
Andrea Rossato
82a62c856f Add Layout.Simplest, the simplest layout 2008-01-25 15:20:15 +00:00
Andrea Rossato
6a6a09a991 Add Decoration, a layout modifier and a class for easily writing decorated layouts 2008-01-25 15:17:26 +00:00
Andrea Rossato
c749fbc399 Add WindowArranger, a layout modifier to move and resize windows with the keyboard 2008-01-25 15:16:33 +00:00
Andrea Rossato
968868a359 ShowWName: moved fi to XUtils 2008-01-24 13:47:25 +00:00
Andrea Rossato
8120af677b XUtils: add functions for operating on lists of windows and export fi 2008-01-24 13:46:38 +00:00
Andrea Rossato
e9f0f05217 LayoutModifier: add emptyLayoutMod for dealing with empty workspaces 2008-01-24 01:56:05 +00:00
Andrea Rossato
efc4ad95b8 LayoutModifier: add pureMess and pureModifier to the LayoutModifier class 2008-01-22 11:13:19 +00:00
Andrea Rossato
a07b207023 Layout.ShowWName: generalize the instance 2008-01-15 04:51:39 +00:00
Lukas Mai
d1dc49575b add emptyLayout to MultiToggle 2008-01-28 17:53:13 +00:00
Lukas Mai
ced1792bfa grammar fix 2008-01-28 17:50:59 +00:00
Spencer Janssen
2659a12049 depend on xmonad-0.6 2008-01-27 22:11:01 +00:00
Spencer Janssen
3533a5d3f3 Bump version to 0.6 2008-01-27 21:15:04 +00:00
Spencer Janssen
d8baf188db I use urxvtc now 2008-01-27 21:14:52 +00:00
Spencer Janssen
8dcb699db3 Update the test hook 2008-01-27 20:51:48 +00:00
Lukas Mai
4440974718 add 'single' helper function 2008-01-17 23:45:50 +00:00
Lukas Mai
7629022c72 documentation fix 2008-01-17 23:44:01 +00:00
Lukas Mai
9a209f6d55 style assimilation 2008-01-17 23:40:59 +00:00
xmonad-contrib
9a6494fae2 cleared up transience to better highlight how to use ManageHooks properly
The initial patch that extended the EDSL for writing ManageHook rules did not come with a good example on how to use it.  This patch ammends that. 'move' is an example of how to write a rule to resolve a Query (Maybe a) into something tangible.  'move'' is an example of how to write a rule isolating window managing code from the rest ofthe mess the EDSL creates.
2008-01-02 07:48:10 +00:00
xmonad-contrib
f7c34eef31 expands the EDSL for performing actions on windows
This patch adds a few types of relationships and operators for managing windows with rules.  It provides grouping operators so the X action can access the quantifier that was matched or not matched.  It provides a formalism for predicates that work in both grouping and non grouping rules.  It could do with some classes, so that there are fewer operators that always do the Right Thing (TM), but the Haskell Type system currently has some problems resolving types.  Since I don't know enough about these high level things, it would be hard to create a GHC patch just to make it all work.
2008-01-01 17:44:46 +00:00
Spencer Janssen
dec7167bc8 -Werror when flag(testing) only 2008-01-18 01:52:07 +00:00
Andrea Rossato
80f70d284d Timer: some code cleanup 2008-01-14 21:11:14 +00:00
nicolas.pouillard
c7a64a99ce Use doubleFork instead of manual double fork, or buggy single fork.
This fixes showWName because Timer was leaking zombie processes.
You should update xmonad, since doubleFork was not exported.
2008-01-14 20:28:33 +00:00
Brent Yorgey
73502fbbdf Reflect.hs: minor haddock fix 2008-01-16 20:35:46 +00:00
Brent Yorgey
10fbf85a2a Reflect.hs: use -fglasgow-exts for now instead of LANGUAGE pragmas, for compatibility with ghc 6.6 2008-01-15 19:48:11 +00:00
Brent Yorgey
e0024ec9c8 Reflect.hs: add MultiToggle support 2008-01-15 19:35:19 +00:00
Brent Yorgey
670d3160c4 MultiToggle.hs: improve 'description' implementation in LayoutClass instance to display the current transformed layout rather than just 'MultiToggle' 2008-01-15 19:33:11 +00:00
Brent Yorgey
4026d40730 Layout.Reflect: new contrib module for reflecting layouts horizontally/vertically 2008-01-15 03:09:47 +00:00
Brent Yorgey
e76c654211 ShowWName.hs: switch color/bgcolor in call to paintAndWrite 2008-01-14 15:38:21 +00:00
Andrea Rossato
1e7cd73544 Prompt: clean up and optimize moveWord a bit 2008-01-13 16:47:45 +00:00
Andrea Rossato
06b3767cae Prompt: added moveWord to move the cursor to the word boundaries
The actions have been bound to ctrl+Left and Right
2008-01-13 12:35:29 +00:00
Andrea Rossato
1125e9102e Doc.Extending: added links and description of recent module addition 2008-01-13 09:32:11 +00:00
Andrea Rossato
396ae4e77c Action.Search: small haddock fixes 2008-01-13 09:26:46 +00:00
Andrea Rossato
7124346ebe ShowWName now uses Timer and XUtils to display the workspace name 2008-01-13 09:11:07 +00:00
Andrea Rossato
6283298a85 Add XMonad.Util.Timer, a module to set up timers and to handle them 2008-01-13 09:01:40 +00:00
Andrea Rossato
c1a711dba0 de-obfuscate the initState and set the init offset to the length of the default text 2008-01-10 14:09:51 +00:00
nicolas.pouillard
9a4559d2fa prompt: Allow to provide a default text in the prompt config. 2008-01-09 21:39:16 +00:00
Joachim Fasting
9b0a2649b6 Correct caps in module header. 2007-12-30 06:19:20 +00:00
Joachim Fasting
8454e5d6b3 Use LANGUAGE pragma. 2007-12-30 06:18:17 +00:00
mail
35c5c1eaf0 shiftPrevScreen and shiftNextScreen, to make CycleWS consistent 2007-12-31 17:16:09 +00:00
Don Stewart
a0dde418ad formatting 2007-12-04 17:49:20 +00:00
Brent Yorgey
4fbd0c5b3f PerWorkspace.hs: add an explanatory note 2007-12-31 13:58:06 +00:00
Andrea Rossato
926c5ec9d2 Add ShowWName a layout modifier to show the workspace name
This module requires dzen
2007-12-31 13:04:41 +00:00
Andrea Rossato
69453d212a ManageDocks: some documentation fixes 2007-12-31 10:18:20 +00:00
Spencer Janssen
0917d4f5d4 -Wall police (again) 2007-12-28 06:18:41 +00:00
Spencer Janssen
0bf616d2fb -Wall police 2007-12-28 06:18:22 +00:00
mail
4f2feafd04 Fulfill the EWMH specification by listing the supported ATOMs, doesnt really make a differene AFAIK 2007-12-27 21:56:07 +00:00
mail
e153c6d406 display all visible windows on the current desktop in the pager
This is my best shot at modeling xmonad’s WM behaviour in a way that
the Extended Window Manager Hints specification allows.

Unfortunately, we can not tell the panel what size and position it should
think the apps are.
2007-12-27 20:43:49 +00:00
mail
0b1beb1d2b Although I do not need the curr variable after all, this is nicer 2007-12-27 19:01:13 +00:00
mail
54c138c4f0 Add support for cycling through screens to CycleWS 2007-12-27 18:26:35 +00:00
mail
35ea95dc88 Clear _NET_ACTIVE_WINDOW when nothing is focused 2007-12-28 15:42:22 +00:00
Andrea Rossato
6bcefb308b textExtentsXMF doesn't require the display 2007-12-28 12:59:13 +00:00
Spencer Janssen
c6e80350e2 Don't bother checking executable bits of items in $PATH, yields a significant speed-up 2007-12-26 03:24:12 +00:00
Brent Yorgey
24b112c452 ResizableTile.hs: fix resizing to work in the presence of floating windows (resolves issue #100) 2007-12-25 13:58:39 +00:00
Andrea Rossato
c698a58fe6 LayoutScreens: haddock fixes 2007-12-25 10:53:16 +00:00
Andrea Rossato
f6723df7d8 XMonad.Actions.Search: haddock fix 2007-12-24 17:11:15 +00:00
Andrea Rossato
0c835744c2 Fix isssue 105
issue 105 was due to the fact that tab windows created when
bootstrapping the windowset after a restart where managed. Setting the
override_redirect attributes to True fixes the issue.

Added the possibility to set the override_redirect attribute with
XMonad.Util.XUtils.creationNewWindow
2007-12-24 17:10:20 +00:00
gwern0
7e0186ef4e Prompt.hs: mv .xmonad_history into .xmonad/
See my email to mailing list. This will slightly break anyone who upgrades while running and expects to see their prompt history, and leave a stray file, I think, but nothing else, and it'll permanently improve tab-completion, and is tidier.
2007-12-24 05:46:10 +00:00
gwern0
9e28c1ce37 Search.hs: +docs, and export simpleEngine so users can define their own 2007-12-24 04:38:28 +00:00
gwern0
7b3466d9a9 Search.hs: mv into Actions/ per IRC suggestion 2007-12-24 04:37:35 +00:00
Lukas Mai
bf55da2bad add XMonad.Actions.NoBorders 2007-12-20 20:39:53 +00:00
Spencer Janssen
53571aad1e AvoidStruts: add support for partial struts 2007-12-22 13:34:25 +00:00
Brent Yorgey
838c878fa2 Search.hs: add hoogle 2007-12-22 18:49:12 +00:00
Spencer Janssen
feae6b11e5 ManageDocks: ignore desktop windows also 2007-12-22 11:38:08 +00:00
Spencer Janssen
0cca07363d Wibble 2007-12-22 11:06:41 +00:00
Spencer Janssen
4c6f940a1d EwmhDesktops: add _NET_ACTIVE_WINDOW support 2007-12-22 11:05:52 +00:00
Spencer Janssen
44cf0f02c3 A few short comments for WorkspaceCompare 2007-12-22 10:50:45 +00:00
Spencer Janssen
64c9db6bab EwmhDesktops: drop 'Workspace' from displayed workspace names 2007-12-22 10:45:59 +00:00
Spencer Janssen
e11534fa56 Factor workspace sorting into a separate module 2007-12-22 10:41:14 +00:00
Spencer Janssen
662eeb7e5f No more tabs 2007-12-22 05:04:39 +00:00
Spencer Janssen
da6155ebac Refactor Search.hs 2007-12-22 04:47:14 +00:00
Spencer Janssen
edb48ee66c Generalize XSelection functions to MonadIO 2007-12-22 04:45:14 +00:00
gwern0
a5431b3f85 Search.hs: +imdb & amazon engines for unk_red 2007-12-22 03:58:37 +00:00
gwern0
cdf37639e4 Search.hs: cleanup and refactor 2007-12-20 17:40:01 +00:00
Spencer Janssen
9997b18970 Update various restart bindings 2007-12-19 22:06:34 +00:00
Roman Cheplyaka
ef14aa07ba Fix typo. 2007-12-19 07:38:57 +00:00
Brent Yorgey
f20b54067c Doc/Developing.hs: add some information about Haddock documentation. 2007-12-19 21:53:00 +00:00
Brent Yorgey
1a4c17e35e require haddock documentation to build successfully in order to record a patch. 2007-12-19 21:52:17 +00:00
Spencer Janssen
71f87d5804 Remove inaccurate comment about 'banish' 2007-12-17 23:15:40 +00:00
Brent Yorgey
0d5de727c3 Warp.hs: haddock fixes 2007-12-17 22:47:12 +00:00
gwern0
697d9e21b7 Warp.hs: +doc
Describe how to emulate Ratpoison's 'banish' functionality on one's config
2007-12-16 03:00:15 +00:00
Brent Yorgey
2949cbeef4 Util/Search.hs: a few updates/fixes
* fix shadowing warning (ghc 6.8.2 complains)
  * export a few more of the functions
  * re-de-obfuscate generated URLs by not escaping alphanumerics or punct.
2007-12-17 22:29:30 +00:00
gwern0
8925732d5f Util.Search: import escapeURIString, and fall back on the ugly const false hack to avoid copy-pasting even more 2007-12-15 21:16:38 +00:00
David Roundy
ecc2f0d5ec update Config.Droundy to use a few nice hooks. 2007-12-16 18:56:53 +00:00
Shachaf Ben-Kiki
0853c1ce21 Add UrgencyHook support to Tabbed 2007-12-15 17:16:17 +00:00
Brent Yorgey
b95f4daab7 DynamicLog.hs: some documentation updates. 2007-12-15 14:37:27 +00:00
Brent Yorgey
e75a72d63f DynamicLog.hs: fix shadowing warning 2007-12-15 14:32:27 +00:00
Shachaf Ben-Kiki
7064ac5ec9 Add UrgencyHook support to DynamicLog
Someone with Xinerama should look at this -- I don't know exactly how that
should behave.
2007-12-14 04:35:28 +00:00
Spencer Janssen
d4798cf7ae Depend on X11-1.4.1, it has crucial bugfixes 2007-12-15 02:21:51 +00:00
Spencer Janssen
5954f61988 Remove network dependency, potentially breaking XMonad.Util.Search 2007-12-14 23:18:59 +00:00
Brent Yorgey
67ab9fb6ad Search.hs: fix shadowing warning and haddock errors 2007-12-14 16:31:19 +00:00
gwern0
38306b1deb +cabal support for XMonad.Util.Search 2007-12-13 20:56:54 +00:00
gwern0
aba20ccf60 +XMonad.Util.Search: new module
This module is intended to provide helpful functions for easily running web searchs; just hit a bound key, enter your query, and up opens a new tab/browser/window with the search results. In theory anyway; the Wikipedia and Google ones work fine for me, but the Internet Archive's docs on how to do don't necessarily seem to be correct. If you were, like me, previously running shell commands to call Surfraw or similar shell scripts to do the same thing, you can now scrap them and replace them.

There aren't too many search engines defined here; new ones would be good, and they're easy to add!
2007-12-13 20:51:59 +00:00
Spencer Janssen
647c7e9b61 Add support for _NET_WM_STRUT_PARTIAL 2007-12-13 02:17:04 +00:00
Spencer Janssen
2033064db1 ManageDocks: when there are struts on opposing edges, the right/bottom strut
was ignored.  TODO: quickchecks
2007-12-10 02:10:30 +00:00
"Valery V. Vorotyntsev"
dd80c23f56 Run.hs: fix documentation, cleanup whitespace 2007-12-12 09:15:16 +00:00
"Valery V. Vorotyntsev"
fb9a8cfef8 Man.hs: input speedup
Descend manpage directories once -- when `manPrompt' is called.
(Previous version used to search directories upon each character
arrival.)
2007-12-12 09:02:56 +00:00
Lukas Mai
02012aeedd new XMonad.Hooks.ManageHelpers module 2007-12-11 18:30:40 +00:00
intrigeri
ef79fa7c10 Magnifier: custom zoom ratio for magnifier' too 2007-12-11 01:55:54 +00:00
Brent Yorgey
2a73b577c2 Magnifier.hs: minor haddock fixes 2007-12-11 01:11:54 +00:00
tim.thelion
0155164015 fix haddock on Magnifier 2007-12-10 23:19:42 +00:00
tim.thelion
5375240f08 Custom zoom levels for magnifier 2007-12-08 23:08:44 +00:00
Spencer Janssen
3cdd04141f Remove references to xmonad 0.4 2007-12-09 23:23:24 +00:00
Spencer Janssen
aca2d6f365 Bump version to 0.5! 2007-12-09 23:16:22 +00:00
Andrea Rossato
88424dc1a8 Extending: updated to the lates config changes - manageHook simplification 2007-12-09 16:47:31 +00:00
Spencer Janssen
71d1c8c23b I use ManageDocks now 2007-12-09 13:44:45 +00:00
Spencer Janssen
bd3e3ed64c Update ManageDocks to the new ManageHook system, remove the gap setting code in favor of AvoidStruts 2007-12-09 13:42:25 +00:00
Andrea Rossato
2d4032665d Extending: some fixes 2007-12-09 12:36:23 +00:00
Andrea Rossato
b2d8bd71c3 Arossato: my teaTime application. 2007-12-09 12:33:27 +00:00
Andrea Rossato
e630b47bc2 XPropManage: haddock fixes 2007-12-09 12:32:46 +00:00
Andrea Rossato
a488b7a54f SetWMName: haddock fixes 2007-12-09 12:32:27 +00:00
Andrea Rossato
7330ee34af EwmhDesktops: haddock fixes 2007-12-09 12:32:04 +00:00
Andrea Rossato
8dc2651a9c DynamicLog: haddock fixes 2007-12-09 12:31:48 +00:00
dominik
0e3d6afc96 Sshprompt: Add explanation for the completion in sshprompt 2007-12-07 00:09:04 +00:00
Spencer Janssen
503cb539af More import pruning 2007-12-08 01:48:46 +00:00
Spencer Janssen
3a522e7e3c Remove XMonad.Operations imports 2007-12-08 00:05:47 +00:00
Spencer Janssen
4f7764ca8b Prune more imports 2007-12-07 23:51:16 +00:00
Spencer Janssen
e85228229b I use CopyWindow now 2007-12-07 23:40:18 +00:00
Spencer Janssen
dc11825588 Remove redundant imports 2007-12-07 23:38:27 +00:00
Spencer Janssen
5f190a315e Typo in extra-source-files 2007-12-05 05:03:11 +00:00
Spencer Janssen
05bca1c2aa Depend on X11>=1.4.0 2007-12-05 05:00:12 +00:00
Spencer Janssen
7a054e9d3e Remove TilePrime, it is subsumed by HintedTile 2007-12-05 04:57:46 +00:00
Spencer Janssen
58d540789b Update Sjanssen.hs 2007-12-05 04:56:48 +00:00
Brent Yorgey
7296b99306 LayoutScreens and Square: haddock updates 2007-12-04 20:40:39 +00:00
Brent Yorgey
258ccb3468 Droundy.hs: add spaces so haddock isn't confused by commented-out ||| combinator 2007-12-04 20:36:22 +00:00
David Roundy
2c856dceec my urgency-hook code also seems to crach... change in Droundy. 2007-12-01 16:23:10 +00:00
David Roundy
03d4f8ea9c disable avoidStruts in Droundy again.
Apparently, ManageDocks still crashes on X86-64...
2007-12-01 16:02:26 +00:00
David Roundy
c4117a1de0 fix bug where we failed to hide combo decorations. 2007-12-01 15:58:59 +00:00
David Roundy
e849a055e3 add to Droundy a non-working urgency hook and enable avoidStruts. 2007-12-01 13:29:10 +00:00
gwern0
e5c50cd0c8 update XSelection.hs; apparently the utf8-string library has updated
Note that this does not fix the apparent problems with actually using getSelection, even though it works fine from a GHCi prompt...
2007-11-30 16:14:29 +00:00
Brent Yorgey
dcd3bc5324 LayoutScreens: documentation fix 2007-11-30 16:54:23 +00:00
David Roundy
7794428303 tune Droundy config. 2007-11-30 14:51:38 +00:00
David Roundy
fc5277fe1c more coding on Mosaic. 2007-11-23 19:24:55 +00:00
David Roundy
14c60215a1 make Mosaic read (and partially try to obey) WM hints. 2007-11-23 16:25:38 +00:00
Brent Yorgey
7acf6462cb refactor XMonad.Prompt, add new modules XMonad.Prompt.{Input,Email}
XMonad.Prompt.Input is a new module which provides a framework for
prompting the user for input and passing it along to some other action,
useful for building actions which require user input.
XMonad.Prompt.Email is a simple example of the use of XMonad.Prompt.Input,
which prompts the user for a recipient, subject, and body, and sends
a one-line email.
I also made a small refactoring to XMonad.Prompt in order to support
XMonad.Prompt.Input.
2007-11-28 14:24:17 +00:00
Brent Yorgey
baa85def23 AppendFile: initial import
XMonad.Prompt.AppendFile is a new module which provides a prompt for
appending a single line of text to a file.  I use it for quickly
writing down ideas/todos/etc. to a special file when I can't be 
bothered to stop what I'm doing to write things down properly.
2007-11-27 22:42:58 +00:00
Brent Yorgey
98840048e5 DynamicWorkspaces: haddock updates 2007-11-27 22:00:33 +00:00
Brent Yorgey
760a240af1 WorkspaceDir: minor haddock update 2007-11-27 21:56:52 +00:00
Brent Yorgey
26e5824938 WmiiActions: haddock updates 2007-11-27 19:44:27 +00:00
Brent Yorgey
d6af9405ba WindowBringer: haddock updates 2007-11-27 19:39:48 +00:00
Brent Yorgey
3a6e31a64f Warp: haddock updates 2007-11-27 19:37:17 +00:00
Brent Yorgey
a24f632959 TagWindows: haddock updates 2007-11-27 19:32:13 +00:00
Brent Yorgey
99e858140c SwapWorkspaces: haddock updates 2007-11-27 19:26:34 +00:00
Brent Yorgey
eb6c642fd9 SimpleDate, Submap: modMask --> modMask x 2007-11-27 19:20:39 +00:00
Brent Yorgey
0cce3cff7e Submap: haddock updates 2007-11-27 19:18:41 +00:00
Brent Yorgey
913bd274b3 SinkAll: haddock updates 2007-11-27 19:13:18 +00:00
Brent Yorgey
dbff738cda SimpleDate: haddock updates; more specific imports 2007-11-27 19:08:32 +00:00
Brent Yorgey
8099d676de Doc/Developing: various edits 2007-11-27 19:03:45 +00:00
Brent Yorgey
971c34ba4a RotView: haddock updates 2007-11-27 18:57:41 +00:00
Brent Yorgey
b4937810cc LayoutCombinators: a few minor haddock fixes 2007-11-27 16:31:06 +00:00
Andrea Rossato
cc1a24c1c8 LayoutCombinators: changes infixes and added many other combinators. 2007-11-27 16:18:07 +00:00
Andrea Rossato
d5533e4dec CopyWindow: fixed docs 2007-11-25 12:14:18 +00:00
Spencer Janssen
f18819f306 Alleviate clashing symbols with XMonad.ManageHook.<||> 2007-11-27 00:42:58 +00:00
Brent Yorgey
2bcef79a1f xmonad-contrib.cabal: better order for the documentation links 2007-11-25 17:17:45 +00:00
Don Stewart
0c16884d6c links to documentatoin subsections in generated docs 2007-11-25 05:22:06 +00:00
Don Stewart
3ee8f201ce depend on X11 1.4.0 2007-11-25 03:46:56 +00:00
Brent Yorgey
93fd3f0f7d RotSlaves: haddock updates 2007-11-24 17:45:18 +00:00
Brent Yorgey
0564291490 MouseGestures: haddock updates 2007-11-24 17:33:51 +00:00
Brent Yorgey
a94c862a53 Extending.hs: a few edits 2007-11-24 17:14:52 +00:00
Andrea Rossato
503400b6f8 Developing: a start 2007-11-24 14:11:33 +00:00
Andrea Rossato
e07df4eb6b Extending: some more stuff 2007-11-24 14:11:06 +00:00
Andrea Rossato
e3b779303f Arossato: some changes. I now use Magnifier among my layouts 2007-11-24 14:09:18 +00:00
Andrea Rossato
97b8a0aefc DynamicLog: added a dynamicLogXmobar 2007-11-24 12:52:02 +00:00
Brent Yorgey
09faa86c16 Haddock docs: modMask --> modMask x 2007-11-24 02:26:35 +00:00
Brent Yorgey
f8a054f592 FocusNth: haddock updates 2007-11-24 02:22:49 +00:00
Brent Yorgey
82d9e02b96 FloatKeys: haddock updates 2007-11-24 00:37:02 +00:00
Brent Yorgey
3a8cf88fb5 FlexibleResize: haddock updates 2007-11-24 00:20:13 +00:00
Brent Yorgey
bc45ff76d1 FlexibleManipulate: add link to mouse binding documentation 2007-11-24 00:19:27 +00:00
Brent Yorgey
c24838627b FlexibleManipulate: haddock updates 2007-11-24 00:07:54 +00:00
Brent Yorgey
5648308b8e FindEmptyWorkspace: haddock updates 2007-11-23 23:54:27 +00:00
Brent Yorgey
4761b83657 Doc/Extending.hs: edits 2007-11-23 23:27:43 +00:00
Andrea Rossato
6339686032 Extending: added manageHook and logHook sections 2007-11-23 21:29:43 +00:00
Andrea Rossato
495b25c884 Magnifier: typo 2007-11-23 21:29:00 +00:00
Andrea Rossato
9cd120f599 LayoutCombinators: fix doc 2007-11-23 17:57:23 +00:00
Brent Yorgey
b13fd2d464 DwmPromote: haddock updates 2007-11-23 20:22:04 +00:00
Brent Yorgey
518cb7432f DeManage: haddock updates 2007-11-23 20:17:02 +00:00
Brent Yorgey
52df6deb52 CycleWS: haddock updates 2007-11-23 20:11:22 +00:00
Brent Yorgey
efb59f06f8 CopyWindow: haddock updates 2007-11-23 20:06:43 +00:00
Brent Yorgey
11a24393fe ConstrainedResize: haddock updates 2007-11-23 19:56:43 +00:00
Brent Yorgey
57d5cb0962 Doc/Extending.hs: add a section about configuring mouse bindings. 2007-11-23 18:45:01 +00:00
Brent Yorgey
eef80d1841 Commands.hs: haddock updates 2007-11-23 17:16:19 +00:00
Brent Yorgey
e6dcaa15c7 dafaultConfig --> defaultConfig 2007-11-23 16:47:22 +00:00
Andrea Rossato
6d7507d4a8 LayoutCombinators: haddock documentation 2007-11-23 15:43:11 +00:00
Andrea Rossato
63c531bb5e ToggleLayout: haddock fixes 2007-11-23 14:29:34 +00:00
Andrea Rossato
1e35714e1e LayoutHints: haddock fixes 2007-11-23 14:28:59 +00:00
Andrea Rossato
ec0d5129a3 LayouModifier: haddock docs 2007-11-23 14:25:19 +00:00
Andrea Rossato
8f641ff025 MagicFocus: haddock docs 2007-11-23 14:16:57 +00:00
Andrea Rossato
4e047d2666 Maximize: haddock fixes 2007-11-23 14:13:04 +00:00
Andrea Rossato
6cfb38608c MosaicAlt: haddock fixes 2007-11-23 14:10:21 +00:00
Andrea Rossato
79f22e7615 Named: haddock fixes 2007-11-23 14:05:57 +00:00
Andrea Rossato
6d35c4c723 NoBorders: haddock fixes 2007-11-23 14:05:35 +00:00
Andrea Rossato
b1af78da95 ResizableTile: haddock fixes 2007-11-23 14:05:11 +00:00
Andrea Rossato
ee4e14c9bd Roledex: haddock fixes 2007-11-23 14:04:51 +00:00
Andrea Rossato
de23c9ab0d Spiral: haddock docs 2007-11-23 13:50:23 +00:00
David Roundy
3885445b26 clean up mosaic a bit more. 2007-11-23 15:36:17 +00:00
Andrea Rossato
81fa770e4c Mosaic: fix docs 2007-11-23 12:53:39 +00:00
Andrea Rossato
7ce5f6e0da ThreeColumns: haddock docs 2007-11-23 12:46:59 +00:00
Andrea Rossato
f9e497687c TilePrime: haddock docs 2007-11-23 12:44:56 +00:00
Andrea Rossato
8682f617d0 TwoPane: haddock docs 2007-11-23 12:31:55 +00:00
Andrea Rossato
33bca8260f WindowNavigation: haddock documentation 2007-11-23 12:11:29 +00:00
Andrea Rossato
ea2102f93c WorkspaceDir: docs 2007-11-23 11:56:35 +00:00
Andrea Rossato
978d2fe54d HntedTile: alignement 2007-11-23 11:50:31 +00:00
Andrea Rossato
e472709986 Combo: some haddock formatting 2007-11-23 11:49:04 +00:00
David Roundy
51d6066d15 make CopyWindow export a fancy copy-window-anywhere function. 2007-11-23 12:10:20 +00:00
David Roundy
8b3ad50c57 remove need for faulty Read instance of NamedWindow. 2007-11-22 17:04:48 +00:00
Andrea Rossato
0004559b97 Magnifier: more refactoring and a few message handlers 2007-11-23 11:33:53 +00:00
Andrea Rossato
70175d85bf cabal: build Magnifier again. 2007-11-22 19:04:27 +00:00
Andrea Rossato
1645745f29 Magnifier: some fixes and refactoring. It now works properly. 2007-11-22 19:01:24 +00:00
Alec Berryman
e65e2e3dba Mosaic: unbreak build, remove unused import that ghc complains about 2007-11-22 17:59:25 +00:00
Andrea Rossato
402054c581 Extending: editing the key bindings require importing Data.Map 2007-11-22 13:39:01 +00:00
Andrea Rossato
378a9ea8b3 cabal: added mosaic and anneal 2007-11-22 13:38:37 +00:00
Andrea Rossato
5ea409d27d NamedWindow: Mosaic requires NamedWindow to have a Read instance 2007-11-22 13:38:02 +00:00
Andrea Rossato
90abd48f28 Added Anneal used by the original mosaic 2007-11-22 13:37:32 +00:00
Andrea Rossato
fb8b39b822 Make the original Mosaic work with LayoutClass 2007-11-22 13:36:58 +00:00
"Valery V. Vorotyntsev"
ecfa40bec9 Prompt/Man.hs: fixing haddock 2007-11-22 09:18:28 +00:00
Spencer Janssen
0ef0c613d7 Don't show HintedTile in the description 2007-11-22 07:26:15 +00:00
Devin Mullins
afce47a330 UrgencyHook: haddock fixes 2007-11-22 06:56:16 +00:00
joel.suovaniemi
c298c87da1 updated XPropManage to ManageHook type 2007-11-22 05:32:03 +00:00
Spencer Janssen
baf2ae570d More HintedTile refactoring 2007-11-22 05:31:54 +00:00
Spencer Janssen
bb74a0bc0d HintedTile:
- code formatting
 - refactoring, based on TilePrime work by Eric Mertens
 - use the current border width of the window, this improves interaction with
   the No/SmartBorders extensions
2007-11-22 05:11:57 +00:00
Spencer Janssen
1519612c23 HintedTile: orientation bug fix, remove wide and tall in favor of the Tall and Wide constructors. 2007-11-22 04:27:20 +00:00
Joachim Fasting
8a614b8328 Hooks/DynamicLog.hs: minor typo. 2007-11-19 13:12:18 +00:00
Brent Yorgey
27506065b2 Extending.hs: more edits and additions. 2007-11-22 03:44:32 +00:00
Brent Yorgey
0dd121e4f7 Doc.hs: edits and additions 2007-11-21 20:43:29 +00:00
Brent Yorgey
450262dca0 Extending.hs: edits and additions 2007-11-21 20:36:31 +00:00
Brent Yorgey
f8a5f32bb3 Configuring.hs: edits and additions 2007-11-21 20:33:12 +00:00
Brent Yorgey
c02e84f98b README: update reference to documentation 2007-11-21 20:26:43 +00:00
Andrea Rossato
1902145b6e Tabbed: haddock fixes 2007-11-21 18:17:10 +00:00
Andrea Rossato
1713fa33c7 HintedTile: haddock fixes 2007-11-21 18:16:35 +00:00
Andrea Rossato
e522c5e9db Grid: haddock fixes 2007-11-21 18:16:16 +00:00
Andrea Rossato
fd4e59e71c DragPane: haddock fixes 2007-11-21 18:15:55 +00:00
Andrea Rossato
e991fd9430 Dishes: haddock fixes 2007-11-21 18:15:29 +00:00
Andrea Rossato
aa42d25ad6 Combo: haddock fixes 2007-11-21 18:15:07 +00:00
Andrea Rossato
aad6a7d747 Circle: haddock fixes 2007-11-21 18:14:41 +00:00
Andrea Rossato
8cef719a61 Accordion: haddock fixes 2007-11-21 18:14:09 +00:00
Andrea Rossato
2a443363b8 Updated documentation of all prompts in XMonad.Prompt 2007-11-21 14:27:15 +00:00
Andrea Rossato
0388e0ae47 Font: haddock fix 2007-11-21 14:16:18 +00:00
Andrea Rossato
b5524bc6fd NamedWindows: haddock fix 2007-11-21 14:14:24 +00:00
Andrea Rossato
d5948af040 XUtils: haddock fix 2007-11-21 14:13:19 +00:00
Andrea Rossato
816b866c32 Shell: small doc fix 2007-11-21 14:10:13 +00:00
Andrea Rossato
c43dabf621 Tabbed: haddock documentation and code formatting 2007-11-21 14:09:08 +00:00
Andrea Rossato
e9621deeed HintedTile: typo 2007-11-21 14:08:28 +00:00
Andrea Rossato
51c1e2f67b HintedTile: ported to the LayoutClass 2007-11-21 11:23:31 +00:00
Brent Yorgey
e25d514503 PerWorkspace.hs: various fixes and updates 2007-11-20 17:33:07 +00:00
Brent Yorgey
9d6ec7f99f Doc.hs: remove modules from export list.
Apparently GHC 6.8.1 issues a warning when a re-exported module does not
itself export anything.
2007-11-20 17:29:47 +00:00
Andrea Rossato
85d3577080 A new documentation system
What to see a real Haddock abuse? Here you go. Removed
Documentation.hs and added a new name space: XMonad.Doc. By importing
other documentation modules we may also use the synopsis in XMonad.Doc.

If you believe that we should not have modules without code, well this
code is not for you: just that strange -- stuff ...;)
2007-11-20 15:15:52 +00:00
Andrea Rossato
6b17a40677 PerWorkspace.hs: minor haddock fixes
Also, we don't need to add those docstring annotation (%...), since
that system is not used anymore.
2007-11-20 10:32:50 +00:00
Brent Yorgey
31cebf1b0a new contrib module: Layout.PerWorkspace
This module allows you to configure layouts on a per-workspace basis,
rather than specifying the same layout for all workspaces.  (Of course,
you still really *are* specifying the same layout for all workspaces,
it just acts differently depending on the workspace. =)
2007-11-20 02:46:12 +00:00
Brent Yorgey
635a4f1fc5 NoBorders.hs: Haddock markup fix 2007-11-20 02:44:15 +00:00
Brent Yorgey
1733963b6c xmc/README: fix xmonad capitalisation, spelling fix 2007-11-20 02:41:18 +00:00
Don Stewart
34ff4ff6f2 Port overview from contrib.html to Documentation.hs 2007-11-19 18:31:27 +00:00
David Roundy
2d55592f21 remove Mosaic and Anneal. 2007-11-19 15:30:05 +00:00
Devin Mullins
334ab53672 remove MessageHooks
Duplicating xmonad-core and working around static-linking issues was getting
old quick. MessageHooks is now a branch of core, located at:
  http://code.haskell.org/~twifkak/xmonad-MessageHooks
2007-11-19 07:04:17 +00:00
Devin Mullins
494fb4c419 make handle Just Another Message Hook 2007-11-19 04:17:31 +00:00
Spencer Janssen
ce47c37dcd Anneal is only used by Mosaic which is disabled 2007-11-19 06:14:40 +00:00
Andrea Rossato
ee90d99853 Prompt: comment only 2007-11-19 00:03:57 +00:00
Spencer Janssen
0bef4068f0 Port XPrompt to XMonad.Util.Font, various other refactorings 2007-11-16 23:27:43 +00:00
Shachaf Ben-Kiki
6302d0b0b9 Miscellaneous spell-checking 2007-11-18 23:03:19 +00:00
Brent Yorgey
9498388041 RotSlaves.hs: documentation fix. 2007-11-18 21:58:58 +00:00
Brent Yorgey
cf3221f569 Documentation.hs: a lot more edits and additions. 2007-11-18 21:55:41 +00:00
Joachim Fasting
9ff17a46aa Prompt/*: add XConfig variable to keybindings in doc. 2007-11-18 14:48:49 +00:00
Joachim Fasting
0d383fa26f Prompt/XMonad.hs: minor typo in doc. 2007-11-18 14:47:22 +00:00
Joachim Fasting
e13d6fe0ff Actions/SinkAll.hs: update usage doc. 2007-11-18 14:41:53 +00:00
Joachim Fasting
c29c440a39 Prompt/Man.hs: remove docstring. 2007-11-18 14:32:40 +00:00
Andrea Rossato
e095e14be1 Documentation: added the section on editing layoutHook 2007-11-18 12:12:40 +00:00
Don Stewart
e640def6d7 needs pattern guards 2007-11-18 05:32:04 +00:00
Joachim Fasting
3d692c0d23 Prompt/Workspace.hs: suggest using defaultXPConfig in usage doc. 2007-11-17 23:09:40 +00:00
Joachim Fasting
8bef395ab9 Prompt/Workspace.hs: update module description. 2007-11-17 23:09:31 +00:00
Joachim Fasting
353687db43 Prompt/Window.hs: fix import statements in usage doc. 2007-11-17 23:08:54 +00:00
Joachim Fasting
7b5ee95ef6 Prompt/Ssh.hs: fix import statements in usage doc. 2007-11-17 23:08:14 +00:00
Joachim Fasting
3c03484bf3 Prompt/Man.hs: tweak import stuff in usage doc. 2007-11-17 23:07:34 +00:00
Joachim Fasting
342380e330 Prompt/Layout.hs: add missing import to usage doc. 2007-11-17 23:06:27 +00:00
Joachim Fasting
42da6bf450 Prompt/Shell.hs: fix invalid module import in usage doc. 2007-11-17 22:46:14 +00:00
Devin Mullins
0cb0d3eef4 experimental MessageHooks "branch" of main
Doesn't do much now, but is enough to allow me to define noFollow again. :)
I believe the need to change XConfig may force this to be an *actual* branch of
xmonad core, but I'm not sure yet.
2007-11-18 01:08:36 +00:00
Devin Mullins
ef6ef321cb Grid: tabs -> spaces 2007-11-17 20:11:40 +00:00
Brent Yorgey
d2f7e735f6 Documentation.hs: various stylistic edits, add a few more details 2007-11-17 17:39:24 +00:00
Andrea Rossato
8fcee53fa3 Documentation: added library description coding style and licensing policy - xmonad in small caps 2007-11-17 13:46:31 +00:00
Andrea Rossato
d3dfbb9bc9 Documentation: added more stuff 2007-11-17 11:42:17 +00:00
Devin Mullins
0ed0324496 cpp-options requires Cabal 1.2.1 2007-11-17 01:26:59 +00:00
Spencer Janssen
20da7a48d3 Use cpp-options 2007-11-16 23:23:01 +00:00
Brent Yorgey
bf84ca529f Config/Droundy.hs: -Wall police, add -fno-warn-orphans 2007-11-16 15:52:02 +00:00
Spencer Janssen
96a534cb68 Move XMonad.Util.Font to fix haddock generation 2007-11-16 21:57:20 +00:00
Andrea Rossato
06783babd9 cabal: I don't know how Hackage handles that so adopt a more general approach 2007-11-16 20:16:44 +00:00
Andrea Rossato
47702ebe31 Documentation.hs: minor fixes 2007-11-16 20:16:00 +00:00
Andrea Rossato
42297605be Arossato: my terminal is urxvt 2007-11-16 20:15:33 +00:00
Andrea Rossato
c4c25f499c Documentation: added the section for adding and removing key bindings 2007-11-16 15:51:10 +00:00
Andrea Rossato
8ba071ef60 Documentation: more stuff added 2007-11-16 15:40:59 +00:00
Spencer Janssen
1c665bc2ac utf8-string isn't needed 2007-11-16 13:37:38 +00:00
Spencer Janssen
0d73e44ea8 Depend on X11-xft >= 0.2 2007-11-16 13:09:26 +00:00
Spencer Janssen
10b5169387 XUtils: remove stringToPixel 2007-11-16 12:52:47 +00:00
Spencer Janssen
e6b8e1eb51 Export XMonadFont's constructors, use those constructors in XMonad.Prompt 2007-11-16 12:51:57 +00:00
Spencer Janssen
0494d0d5e5 Use Xft automatically if available 2007-11-16 12:42:11 +00:00
Spencer Janssen
65299e7d0c Font.hs: CPP around Xft calls, use a data type rather than Either 2007-11-16 12:35:52 +00:00
Spencer Janssen
32109d6f83 Font.hs: tabs 2007-11-16 12:25:51 +00:00
Clemens Fruhwirth
ce5928edd3 Add Font layer supporting an Xft backend. Make Tabbed.hs a user of this layer. 2007-11-16 12:06:53 +00:00
Andrea Rossato
711381e29a Documentation: typos and formatting 2007-11-16 12:29:29 +00:00
Andrea Rossato
2ebbf2dbd9 XUtils: a small haddock fix 2007-11-16 12:23:59 +00:00
Andrea Rossato
46c93c4ec2 XMonad.Util.Run: meny haddock fixes
I've also trasnformed gwern's comments to use '--' instead of {- -},
for uniformity.
2007-11-16 12:09:38 +00:00
"Valery V. Vorotyntsev"
6d4a670df3 CustomKeys.hs: typo 2007-11-16 11:25:31 +00:00
Andrea Rossato
663a032512 README: wrap long lines 2007-11-16 10:50:37 +00:00
Andrea Rossato
8a827d3471 Add Documentation.hs for documentation purposes
An empty module for documentation purpose with configuration
instructions.
2007-11-16 10:48:27 +00:00
Andrea Rossato
c30f6076ac Arossato: removed unneeded bits 2007-11-16 10:47:53 +00:00
Andrea Rossato
2249d3b3a7 RotSlaves: small haddock fix 2007-11-16 10:47:30 +00:00
Don Stewart
13860e0ed9 update run xmonad script 2007-11-15 22:57:04 +00:00
Andrea Rossato
2a3ac53d30 Prompt: haddock fixes 2007-11-15 20:48:28 +00:00
Andrea Rossato
3d39b52959 Arossato: documentation 2007-11-15 19:10:39 +00:00
Andrea Rossato
8cc3101ff1 Prompt: just code formatting 2007-11-15 19:10:12 +00:00
Andrea Rossato
c03da570a0 Prompt: add killWord edit action
With this bindings:
^ - Delete kill forward
^ - BackSpace kill backward
2007-11-15 19:07:34 +00:00
David Roundy
ffed7c0e02 remove unneeded Data.Bits imports. 2007-11-15 16:13:46 +00:00
"Valery V. Vorotyntsev"
533ef65e9d CustomKeys.hs: "complete rebinding" mechanism explained
Thanks to Don Stewart for his suggestion:
  http://article.gmane.org/gmane.comp.lang.haskell.xmonad/3339
2007-11-15 15:14:10 +00:00
"Valery V. Vorotyntsev"
d4f8502807 Tabbed.hs, SetWMName.hs: the modules need bitwise "or"
Tabbed.hs cleaned of trailing whitespace.
2007-11-15 14:37:58 +00:00
David Roundy
33fa0047c9 fix bug in WindowNavigation.
We weren't properly cleaning up in some cases, because we called focus,
which calls windows, while handling a message, which had the result that
changes to the layout were overwritten.  This had the result that
windowNavigation combined with DragPane left stray drag bars hanging
around.
2007-11-14 23:19:14 +00:00
Andrea Rossato
40ad31449f Tabbed: removed -fno-warn-orphans
I added it by mistake, but it is not needed. Sorry.
2007-11-14 23:05:44 +00:00
David Roundy
f978d76172 simplify NewSelect code. 2007-11-14 22:35:38 +00:00
David Roundy
0292c8e4f5 fix bug in LayoutCombinators. 2007-11-14 21:01:39 +00:00
Don Stewart
964a511cd9 no need to import Data.Bits 2007-11-14 18:39:55 +00:00
Andrea Rossato
61b795d2e2 ManageDocks.hs: haddock fixes 2007-11-14 19:13:27 +00:00
Andrea Rossato
622ddfc38b EZConfig.hs: haddock fixes 2007-11-14 19:11:09 +00:00
"Valery V. Vorotyntsev"
20e92a5d40 CustomKeys.hs: moved into `Util' directory
I still wonder why do we need all those configuration examples. :)
2007-11-14 15:34:18 +00:00
Andrea Rossato
011780d68c Arossato: removed unneeded bits 2007-11-14 17:25:00 +00:00
David Roundy
f7dd5d3fcc improve shrinking in Droundy.hs 2007-11-14 14:21:27 +00:00
Andrea Rossato
58e2029669 Arossato: just code formatting 2007-11-14 14:22:13 +00:00
Andrea Rossato
90aae189f0 Arossato: typo 2007-11-14 14:20:46 +00:00
Andrea Rossato
064e9257b7 Arossato: some keybindings tuning 2007-11-14 14:17:19 +00:00
Andrea Rossato
5ee39ecc53 Tabbed: added -fno-warn-orphans 2007-11-14 13:55:25 +00:00
Andrea Rossato
85952e9e53 Arossato: just code formattings 2007-11-14 13:53:52 +00:00
Andrea Rossato
4323d659d3 Config.Arossato: my hand has been forced to pick up a true combinator set... 2007-11-14 13:38:48 +00:00
Andrea Rossato
1eb69c2fdc UrgencyHook.hs: small haddock fix 2007-11-14 10:48:44 +00:00
Devin Mullins
5f6a80ca7a fix EZConfig documentation 2007-11-14 12:04:42 +00:00
Devin Mullins
7712f02ef8 remove dead code 2007-11-12 18:48:57 +00:00
"Valery V. Vorotyntsev"
68e5d0de9f CustomKeys.hs (customKeysFrom): new function
Update third-party configuration to fit your key preferences.
Extended documentation.
2007-11-13 20:18:52 +00:00
Don Stewart
8d03f9d5d7 pattern guards and newtype deriving required for ManageDocks.hs to build! 2007-11-14 03:26:25 +00:00
David Roundy
de6b1feabf add ToggleStruts capability to avoidStruts. 2007-11-13 20:34:34 +00:00
Andrea Rossato
46528b4f48 Arossato: cleanup and fine-tuning 2007-11-13 16:39:06 +00:00
David Roundy
6e24689652 make shrinker preserved over restart in tabbed. 2007-11-13 16:31:16 +00:00
gwern0
ea542ce5af REAME: one more try 2007-11-12 22:05:23 +00:00
gwern0
993ffa049e scripts/generate-configs: update docs 2007-11-12 14:46:43 +00:00
Don Stewart
ff56ab01cf HEADS UP: Rename XMonadContrib library as xmonad-contrib.
After building and install as normal, be sure to unregister your
old XMonadContrib library:

    $ ghc-pkg unregister --user XMonadContrib-0.4
    $ ghc-pkg unregister XMonadContrib-0.4

And then your ~/.xmonad/* stuff should link as normal.
2007-11-12 18:09:19 +00:00
"Valery V. Vorotyntsev"
9140b58b91 XMonad.Config.CustomKeys - new module
This module is another key bindings customization helper.

Differences from XMonad.Util.EZConfig by Devin Mullins:
  EZConfig   -- M.union/M.difference
  CustomKeys -- Monad.Reader + foldr'ed M.insert/M.delete

IMHO, both modules could evolve into something nice. :)
Please discuss at the mailing list.
2007-11-12 17:55:30 +00:00
David Roundy
c468f6e608 prune Droundy.hs. 2007-11-12 17:20:32 +00:00
Brent Yorgey
e0dfb3428d NoBorders.hs: remove modifierDescription definitions, so NoBorders and SmartBorder don't change the layout description. 2007-11-12 15:45:25 +00:00
Brent Yorgey
6cd8425c76 NoBorder.hs: documentation updates 2007-11-12 15:44:11 +00:00
Devin Mullins
fe5b0a0af1 fix intro doco for UrgencyHook
Ooh, this new XConfig l -> XConfig l' function makes the docs disappear!
2007-11-12 04:41:02 +00:00
Devin Mullins
5552c8c86d revert UrgencyHook behavior back to ICCCM non-compliance
Note: If you're using UrgencyHook, this will break your config.
@withUrgencyHook SomeUrgencyHook@ is XConfig -> XConfig, now. The layout hook
has been renamed to urgencyLayoutHook.

It may also be worth noting that, in order to recreate the old behavior without
using redoLayout (so that this may be ported to an eventHook), I had to hijack
logHook. Shouldn't harm anything, though.

TODO: update main docs
2007-11-12 04:33:25 +00:00
Devin Mullins
a35b7ab6f3 add StdoutUrgencyHook, to help debug weird client behavior 2007-11-12 01:58:55 +00:00
Spencer Janssen
25849e68e0 EZConfig: update for kind change in XConfig 2007-11-11 21:53:14 +00:00
David Roundy
e423e3eb34 changes to work with XConfig of kind * -> *. 2007-11-11 00:56:29 +00:00
Don Stewart
044bd10ee5 depend on X11==1.3.0.20071111 for new type defns and 64 bit clean 2007-11-11 20:10:55 +00:00
Don Stewart
929e0b8638 font size 15 pixels is the dzen default 2007-11-09 19:03:28 +00:00
David Roundy
a3d739db17 add two new modules, one to name layouts, another to select a layout.
The latter is pretty useless, as there's no way to find out what
layouts are available, but it can at least allow you to select between
any layouts that you happen to be using already (in one workspace or
another).  The former is handy any time you'd rather have a short name
for a layout (either for selecting, or for viewing in a status bar).
2007-11-11 19:50:36 +00:00
Devin Mullins
a96b55ecfe add helper module for writing configs
Looking for suggestions on this module. Does it belong here? Is there a better
name? Should the additional* functions pass the modMask to their second
argument? etc.
2007-11-11 07:52:22 +00:00
Devin Mullins
4835a3be3f let clients track their urgency, per ICCCM
This removes the dependency on redoLayout -- now WithUrgencyHook defines handleMess only.
2007-11-11 02:12:41 +00:00
Devin Mullins
92490057b4 wrap user code in userCode, go figure
(thanks à shachaf for that suggestion)
2007-11-11 00:26:17 +00:00
Devin Mullins
e31599860e add LANGUAGE PatternGuards to UrgencyHook 2007-11-11 00:22:38 +00:00
Devin Mullins
f4a5a3dc0c remove dead doco 2007-11-11 00:14:43 +00:00
Devin Mullins
c5410f7ee6 clarify config code... a bit 2007-11-11 00:09:33 +00:00
Devin Mullins
9d99b06220 fix doco for UrgencyHook 2007-11-11 00:00:46 +00:00
Devin Mullins
899bb99fad add NoUrgencyHook, for shachaf's sake 2007-11-10 23:58:57 +00:00
Devin Mullins
6a3e6d787f oops, export the configuration options 2007-11-10 23:33:13 +00:00
Devin Mullins
e4fe6c8994 add dzenUrgencyHook back
TODO: fix all the doco
2007-11-10 23:27:06 +00:00
Devin Mullins
11f65f5ccf remove dzenUrgencyHook* from Dzen module
To be replaced by UrgencyHook instances defined in the UrgencyHook module.
2007-11-10 23:11:15 +00:00
Devin Mullins
4ec92c5054 get UrgencyHook to compile
(The boilerplate, it burns!) Still isn't useful (to me) yet, as I haven't
ported dzenUrgencyHook to the new UrgencyHook class.
2007-11-10 22:43:03 +00:00
David Roundy
48f23960be fix bug in avoidStruts. 2007-11-10 21:42:05 +00:00
Devin Mullins
0c83b03914 typo fix in Util.Run 2007-11-10 21:13:28 +00:00
David Roundy
9c915ef65d add a few docs (very sparse) to DynamicWorkspaces. 2007-11-09 15:26:49 +00:00
David Roundy
77be696976 add withWorkspace prompt, which automatically creates workspace if nonexistent. 2007-11-09 15:21:24 +00:00
Spencer Janssen
283001699d Generalize safe/unsafeSpawn to MonadIO 2007-11-09 07:38:10 +00:00
gwern0
0e016a6fa5 Magnifier.hs: update so it at least compiles
Code modified on advice of Wachter; note I make absolutely no claims that the code runs correctly or doesn't eat your pets or does anything besides compile without any warnings.
2007-11-08 01:25:22 +00:00
gwern0
a5799ec85f Dzen.hs: resend doc update 2007-11-06 21:15:37 +00:00
gwern0
64d215327e Update docs in Util 2007-11-06 19:02:58 +00:00
David Roundy
39445183bc fix types to work with Mats fix to X11. 2007-11-08 19:23:18 +00:00
Mats Jansborg
107a957ff6 Change the type of properties from Word32 to CLong 2007-11-01 19:27:30 +00:00
David Roundy
7540b14963 fix bug in avoidStruts.
I've now tested this module, and it works on x86--but doesn't work on
x86-64, because ManageDocks doesn't work on 64-bit.  But in any case, it
works almost perfectly, with no user intervention needed (and no special
hooks).  The only catch is that it doesn't notice when a panel disappears,
so the layout won't adjust until the next refresh (e.g. if you change
focus, layout or workspace).
2007-11-08 17:52:50 +00:00
David Roundy
85766bb72a clean up Droundy.hs. 2007-11-07 14:41:06 +00:00
Andrea Rossato
c6c377a325 DynamicLog: typo in docs 2007-11-08 01:01:04 +00:00
Don Stewart
2b7a8d06da over pararenthesised arty fibonacci 2007-11-07 23:06:01 +00:00
Chris Mears
ab1f382566 Remove spurious import in Arossato's config. 2007-11-07 21:56:30 +00:00
Andrea Rossato
d1eb962214 Add my configuration file
Spencer and David: you really did a great job. Thank you guys!
2007-11-07 19:13:05 +00:00
Don Stewart
901522fc10 add higher order 'dzen' function
The intent is that:

    main = dzen xmonad

should just work, and indeed it does now, for launching a cool status
bar with minimal effort.
2007-11-07 18:31:07 +00:00
Spencer Janssen
e34a880460 Set defaultGaps for makeSimpleDzenConfig 2007-11-07 09:20:37 +00:00
Eric Mertens
4bfbc43023 DynamicLog: Add makeSimpleDzenConfig function
This function serves as an example for spawning a dzen2 instance and printing
the defaultPP to it.
2007-11-07 08:55:14 +00:00
Spencer Janssen
4fcd67ef05 Use spawnPipe in sjanssenConfig 2007-11-07 08:26:37 +00:00
Spencer Janssen
f98023d3c2 Add spawnPipe 2007-11-07 07:50:09 +00:00
Eric Mertens
68b04cba15 DynamicLog: add ppOutput field to PP
This allows the user to specify an alternate destination for logging output
instead of outputing to stdout (which is still the default).
2007-11-07 05:58:05 +00:00
Spencer Janssen
486806c051 Add EwmhDesktops to exposed-modules 2007-11-07 03:11:35 +00:00
gwern0
d76ebde249 Actions: update SinkAll doc 2007-11-06 19:21:58 +00:00
gwern0
c64b43be9f Prompt.hs: update names 2007-11-06 19:20:54 +00:00
gwern0
e13f9849ae EwmhDesktops: move to correct name, update so it compiles 2007-11-06 19:17:51 +00:00
gwern0
4109a68fdf Man.hs: -Wall option not necessary as that's turned on in the Cabal files 2007-11-06 19:06:59 +00:00
Lukas Mai
58072a2edc make Setup haddock work again 2007-11-06 14:18:29 +00:00
Lukas Mai
7b7b1ce800 change MultiToggle interface; add docs 2007-11-06 14:17:29 +00:00
Spencer Janssen
e780bb042a Remove SwitchTrans 2007-11-06 06:59:33 +00:00
Spencer Janssen
9f9997ca55 Remove MetaModule 2007-11-06 02:37:13 +00:00
Lukas Mai
edb3d350be add serializable SwitchTrans (a.k.a. MultiToggle) 2007-11-06 00:58:19 +00:00
l.mai
8d5afd87d7 make TilePrime compile again 2007-11-05 23:32:18 +00:00
l.mai
bd42371d9e add LayoutHints to MetaModule 2007-11-05 23:31:43 +00:00
l.mai
62a46c6df3 make LayoutHints compile again 2007-11-05 23:30:20 +00:00
Spencer Janssen
2d51577c4e Expose LayoutCombinators 2007-11-06 02:16:11 +00:00
Spencer Janssen
c1572fe940 Add LANGUAGE pragmas for ManageDocks 2007-11-06 02:15:07 +00:00
Spencer Janssen
9520922357 Combo builds now 2007-11-06 02:13:41 +00:00
Spencer Janssen
e1675284e2 Make Combo build on GHC 6.8 2007-11-06 02:11:26 +00:00
Spencer Janssen
7d1506fded Stupid mistake 2007-11-05 10:10:52 +00:00
Spencer Janssen
81a148a8d5 -Werror 2007-11-05 06:02:23 +00:00
David Roundy
0e4226bb4d fix Config.Droundy to compile again. 2007-11-05 20:53:39 +00:00
Spencer Janssen
2bb992c128 -Wall police 2007-11-05 06:00:36 +00:00
Spencer Janssen
9cd33f809e Minor updates to Sjanssen.hs 2007-11-05 05:50:22 +00:00
Spencer Janssen
387a4827cb Use configurations 2007-11-05 03:41:09 +00:00
Don Stewart
1ae326cfa7 -Wall is on 2007-11-05 03:18:15 +00:00
Spencer Janssen
50a61a49a2 Revert ghc-options changes 2007-11-05 03:03:27 +00:00
Don Stewart
2ef6f91fb1 forgot to add my config file 2007-11-05 02:58:56 +00:00
Don Stewart
080e11b376 build with optimisations on as usual, fix a few compile errors 2007-11-05 02:48:58 +00:00
Spencer Janssen
ee5ae195e0 Add XMonad.Config.Sjanssen 2007-11-05 00:58:32 +00:00
Spencer Janssen
d3a389e6b5 Move configs/droundy.hs to an actual library module 2007-11-04 20:29:57 +00:00
Spencer Janssen
9a42cf8721 Improve test hook.
--disable-optimizations makes testing much faster.
--user allows Cabal to satisfy dependencies from the user package database.
2007-11-04 20:29:19 +00:00
David Roundy
ecd07bf450 fix warnings in Combo. 2007-11-01 21:45:04 +00:00
David Roundy
3b6c939af0 make WorkspaceDir always store absolute pathnames. 2007-11-01 21:44:01 +00:00
David Roundy
3e9e9c8b03 add new off-center layout combinators. 2007-11-01 21:42:16 +00:00
David Roundy
69999d8018 add configs demo directory 2007-11-01 20:37:20 +00:00
Spencer Janssen
33740d99d6 Add Cabal stuff 2007-11-01 20:20:41 +00:00
David Roundy
722b99dd83 make Hierarchical LayoutCombinators. 2007-11-01 18:54:18 +00:00
David Roundy
c2a4c05faf fix selectWorkspace to work with new config. 2007-11-01 18:35:46 +00:00
Spencer Janssen
cd1884466a Hierarchify 2007-11-01 20:10:59 +00:00
Spencer Janssen
4a76d9e675 Use hierarchical module names from the core 2007-11-01 18:28:24 +00:00
David Roundy
418cc6511e code to define a strut-avoiding layout. 2007-10-23 22:00:25 +00:00
David Roundy
0a242c6a6e reenable JumpToLayout in NewSelect. 2007-11-01 18:11:28 +00:00
David Roundy
e397233808 -Wall police in Run. 2007-11-01 15:20:28 +00:00
David Roundy
35d1367d4d port Combo (dropping combo). 2007-11-01 15:29:15 +00:00
Spencer Janssen
fbfcff6cbf Port ToggleLayouts 2007-11-01 09:18:53 +00:00
Spencer Janssen
014f49aefd Port WorkspacePrompt 2007-11-01 09:04:25 +00:00
Spencer Janssen
ee98008f45 Port Accordion 2007-11-01 09:03:41 +00:00
Spencer Janssen
fb0f288dca Port Dishes 2007-11-01 09:03:12 +00:00
Spencer Janssen
1f698321d7 Dishes: tabs 2007-11-01 09:02:37 +00:00
Spencer Janssen
ea8cd6d2c7 Port DragPane 2007-11-01 08:57:33 +00:00
Spencer Janssen
5eab2d705d Port MosaicAlt 2007-11-01 08:55:24 +00:00
Spencer Janssen
a44890582b Port ResizableTile 2007-11-01 08:55:00 +00:00
Spencer Janssen
52989e5845 Port Roledex 2007-11-01 08:54:30 +00:00
Spencer Janssen
93ffacad82 Port Spiral 2007-11-01 08:54:02 +00:00
Spencer Janssen
69c623f834 Port TagWindows 2007-11-01 08:53:35 +00:00
Spencer Janssen
d53b331dc7 Port ThreeColumns 2007-11-01 08:52:29 +00:00
Spencer Janssen
ee9c7d35be Port TwoPane 2007-11-01 08:51:51 +00:00
Spencer Janssen
8eea95bc44 Port XMonadPrompt 2007-11-01 08:50:37 +00:00
Spencer Janssen
42854f5243 XMonadPrompt: tabs 2007-11-01 08:49:39 +00:00
Spencer Janssen
a9e93c7e3e Port WindowNavigation 2007-11-01 08:48:52 +00:00
Spencer Janssen
fe30292005 Port Submap 2007-11-01 08:47:44 +00:00
Spencer Janssen
4b134366b3 Port CycleWS 2007-11-01 08:44:31 +00:00
Spencer Janssen
2d81245280 NO TABS 2007-11-01 08:39:54 +00:00
Spencer Janssen
c4c7cc7924 Port Commands 2007-11-01 08:32:36 +00:00
Spencer Janssen
a1066224f7 XPrompt: don't import XMonad.config 2007-11-01 07:41:49 +00:00
Spencer Janssen
332ecc3e11 More porting 2007-11-01 07:35:06 +00:00
Spencer Janssen
e16479570a Port DynamicLog 2007-11-01 07:26:06 +00:00
Spencer Janssen
0b681cadc2 Port NoBorders 2007-11-01 07:08:59 +00:00
Spencer Janssen
bd97249b22 LayoutModifier: LayoutMessages have moved 2007-11-01 07:07:24 +00:00
Spencer Janssen
a4ea5e80ef Remove Config import from Run 2007-11-01 07:04:08 +00:00
Spencer Janssen
d64e43e858 Remove 'descriptions' stuff from NewSelect. I think we can do this without make LayoutClass larger 2007-11-01 03:38:44 +00:00
David Roundy
1a67657db8 add NewSelect layout combinator.
This patch adds a selection layout combinator ||| which
replaces Select, and makes the Layout data type unnecessary.
This combinator isn't yet feature-complete, as I didn't implement
backwards rotation (PrevLayout), but that's obviously doable.  This
patch requires the descriptions function be added to LayoutClass in
core.
2007-10-24 15:26:48 +00:00
"Valery V. Vorotyntsev"
92ef6cd811 ManPrompt.hs: auto-complete explicit paths (those with `/')
Bash's compgen is used for this (like in ShellPrompt.hs).

Enable all GHC warnings.

Improve documentation (slightly).
2007-11-04 20:20:56 +00:00
Devin Mullins
3fb0cf1391 clean up destroyed windows from urgents list 2007-11-03 15:03:58 +00:00
Devin Mullins
f2eec4b48b add focusUrgent action, for those too lazy to read 2007-11-03 05:54:58 +00:00
Devin Mullins
273f64955e changed urgent state from Set to list 2007-11-03 05:51:43 +00:00
Devin Mullins
6984a9f0cb fix examples 2007-11-03 02:20:11 +00:00
Devin Mullins
83cc45d972 add haddock for top-level Dzen bindings 2007-11-03 02:17:05 +00:00
Devin Mullins
fd268ab7b9 expose dzenWithArgs, dzenUrgencyHookWithArgs (for colors!) 2007-10-30 07:24:55 +00:00
Devin Mullins
5c9a9e68c4 use a global IORef to keep list of urgent windows 2007-10-27 06:48:10 +00:00
Brent Yorgey
b091f3e28f fix parse error in pattern match 2007-10-29 17:41:50 +00:00
David Roundy
8ab680ede3 allow use of multiple toggles in ToggleLayouts. 2007-10-26 21:06:43 +00:00
Brent Yorgey
fade0c609d WindowNavigation.hs: documentation fix (navigateBorder -> navigateColor) 2007-10-29 15:57:31 +00:00
"Valery V. Vorotyntsev"
9bc7e1ff0c MetaModule.hs: add ManPrompt, remove ViewPrev 2007-10-29 07:56:21 +00:00
Andrea Rossato
0b444e5264 XMonadPrompt: use a single blank 2007-10-29 09:16:18 +00:00
cardboard42
323040000f Added xmonadPromptC
I added xmonadPromptC which takes a user defined list of commands as in Command.runCommand
2007-10-27 01:48:11 +00:00
Spencer Janssen
6d147212f7 Factor out some of dzenPP's goodies 2007-10-29 01:55:56 +00:00
Spencer Janssen
69b05866b5 Don't reverse sjanssenPP 2007-10-28 22:48:43 +00:00
gwern0
5e214e9210 MetaModule.hs: someone forgot the (), so GHC was giving a warning. Small fix to quiet the warning. 2007-10-27 15:08:47 +00:00
"Valery V. Vorotyntsev"
27421129f6 ViewPrev.hs: deleted
Its functionality is now part of CycleWS module.
CycleWS.hs: Nelson Elhage added to authors.
2007-10-27 09:09:37 +00:00
Don Stewart
1ec36de78f add more details on using smartBorders 2007-10-26 22:45:10 +00:00
Don Stewart
9ef767dc77 add dynamicLogDzen, a dwm status bar, using dzen colour codes 2007-10-26 22:19:44 +00:00
Andrea Rossato
e7ec30009e XPrompt: removed unneeded parenteses 2007-10-26 22:15:05 +00:00
"Valery V. Vorotyntsev"
9f0a2a66f9 XPrompt.hs: use a single blank
Excessive blanks in prompts originate from here. Eliminate. :)
Rewrite `getLastWord' and `skipLastWord' in pointfree style.
2007-10-22 19:23:10 +00:00
"Valery V. Vorotyntsev"
df33392d08 ShellPrompt.hs (showXPrompt): use a single blank 2007-10-22 19:17:41 +00:00
Andrea Rossato
051eb3b814 ShellPrompt: remove harcoded path when calling bash 2007-10-26 21:23:34 +00:00
Andrea Rossato
d875c05252 ShellPrompt: reformat the comments to complay with the module style 2007-10-26 21:19:56 +00:00
Andrea Rossato
2b4179169b XPrompt: catch exceptions when running the completion function 2007-10-26 21:18:59 +00:00
Andrea Rossato
eda311fa78 CycleWS: StackSet.findIndex is now findTag 2007-10-26 21:18:02 +00:00
Brent Yorgey
31f5d1a912 Dzen.hs: replace 'findIndex' by 'findTag' to match renaming in core. 2007-10-22 20:43:35 +00:00
gwern0
e3a96e2b5a XPrompt.hs: add sensible bindings for Home and End 2007-10-26 03:50:26 +00:00
gwern0
89ffbc20a1 XPrompt.hs: add a pasteString function and keybinding 2007-10-26 03:49:20 +00:00
"Valery V. Vorotyntsev"
630166f9fa Run.hs: documentation fix 2007-10-24 14:42:44 +00:00
"Valery V. Vorotyntsev"
906c3ccc32 XPrompt.hs (uniqSort): new function
Moved from ShellPrompt. There are at least three happy users
of this function -- ShellPrompt, SshPrompt, and ManPrompt.
2007-10-24 14:22:41 +00:00
"Valery V. Vorotyntsev"
bd13af8f25 SshPrompt.hs: use `uniqSort' from XPrompt.hs
Remove excessive import lists.
2007-10-24 14:41:28 +00:00
"Valery V. Vorotyntsev"
414a3dab6a SshPrompt.hs (showXPrompt): use a single blank
Delete trailing whitespace. Fix documentation typo.
2007-10-22 19:20:37 +00:00
"Valery V. Vorotyntsev"
c7e078b73b ShellPrompt.hs: move `uniqSort' to XPrompt.hs 2007-10-24 14:38:20 +00:00
"Valery V. Vorotyntsev"
11a7df81d6 ManPrompt.hs: use `uniqSort' from XPrompt.hs
TODO list extended.
2007-10-24 14:39:05 +00:00
Eric Mertens
dee7d9ef95 TilePrime.hs: Handle nmaster = 0 reasonably 2007-10-25 00:17:50 +00:00
Devin Mullins
b1da605575 oops, add period 2007-10-24 12:54:48 +00:00
Devin Mullins
3044a447e6 expand Invisible comments 2007-10-24 12:52:13 +00:00
Spencer Janssen
f213257f65 Remove excessive import lists from ShellPrompt 2007-10-24 11:31:06 +00:00
Spencer Janssen
c65b9c06b9 Use new terminal config option 2007-10-24 11:02:19 +00:00
gwern0
32a01355bf Run.hs: do my usual segregation into safe and unsafe runInTerms 2007-10-24 00:39:11 +00:00
gwern0
ab941a450c Run.hs: specialize runInXTerm to use runInTerm per my mailing list suggestion 2007-10-24 00:18:56 +00:00
gwern0
98f6709902 Run.hs: +my suggested runInTerm general function 2007-10-24 00:16:28 +00:00
gwern0
877999d890 Run.hs, SshPrompt.hs, ShellPrompt.hs: mv runInXTerm back into Run.hs per suggestions 2007-10-24 00:13:41 +00:00
Dougal Stanton
725b3a82ca Comments for ConstrainedResize 2007-10-20 09:25:09 +00:00
Dougal Stanton
1ac15e3f83 Add ConstrainedResize module
Constrain the aspect ratio of floated windows by holding down shift
2007-10-19 17:35:08 +00:00
Devin Mullins
41a094601c fix stupid dzenUrgencyHook bug 2007-10-21 06:13:08 +00:00
"Valery V. Vorotyntsev"
37a58b9df2 CycleWS.hs (toggleWS): new function
This is a pointfree adaptation of ViewPrev.viewPrev;
after this patch is applied, it may be a good idea to merge
ViewPrev.hs into CycleWS.hs.
2007-10-19 20:53:23 +00:00
Dmitry Kurochkin
139ce1b8c4 XPrompt.hs: fix vertical alignment of completions. 2007-10-23 18:31:29 +00:00
David Roundy
8649c90c55 fix bug in DragPane (where we forgot that r was mirrored). 2007-10-23 15:24:48 +00:00
"Valery V. Vorotyntsev"
49f2ae8b98 ManPrompt.hs: a manual page prompt (new module) 2007-10-22 19:14:43 +00:00
mail
8eca4751e0 STRUT aware gap toggling (clean patch)
Without this patch, ManageDocks would only set the gap according to a window’s
STRUT when the window is first mapped. This information would then get lost when
the user toggle the gap.
   
Now, when the user toggles the Gap, all present windows are scanned for STRUT
settings, and the gap is set accordingly. No need to manually configure the gap
anymore.

This is the same patch as before, but independant of the Hooks patches, and with
more documentation.
2007-10-22 22:01:32 +00:00
David Roundy
86839154d1 add new LayoutCombinators module. 2007-10-23 13:56:38 +00:00
David Roundy
640896d6f4 export DragPane type. 2007-10-23 13:49:33 +00:00
David Roundy
515d514491 make DragPane work with any type (not just Windows). 2007-10-23 13:49:11 +00:00
gwern0
0fe340d50c SshPrompt.hs: while I'm here, replace nub with the faster Set trick 2007-10-19 18:15:14 +00:00
gwern0
b70448353f ShellPrompt.hs: fmt imports and update 2007-10-19 18:13:17 +00:00
gwern0
1bded83669 SshPrompt.hs: fmt imports and update 2007-10-19 18:12:55 +00:00
gwern0
6f04a51959 XSelection.hs: fmt imports and sigs 2007-10-19 18:12:32 +00:00
gwern0
75589eaf16 XSelection.hs: +2 functions, safePromptSelection and unsafePromptSelection
Analogous to Run.hs patch; these use safeSpawn and unsafeSpawn respectively.
2007-10-19 18:11:37 +00:00
gwern0
c7e40aa771 Run.hs: +2 functions, safeSpawn & unsafeSpawn
See their documentation. This is part of a re-organization of various 'run' commands; this two
make it easier to go through the shell or not, and will be re-used elsewhere.
2007-10-19 18:10:09 +00:00
gwern0
0917e5f56f Run.hs: fmt 2007-10-19 18:09:53 +00:00
gwern0
3483054089 Run.hs, ShellPrompt.sh: mv runInXTerm to ShellPrompt.hs 2007-10-19 18:09:00 +00:00
gwern0
890f586bb7 XSelection.hs: documentation format changes. 2007-10-19 01:00:57 +00:00
gwern0
984f9092c1 XSelection.hs: +type signature for auxiliary function 2007-10-19 01:00:34 +00:00
gwern0
f0eb0f0311 XSelection.hs: simplify creation of window
While spelunking in the xclip source code, I noticed it had much the same call to createSimpleWindow but with a simpler geometry - just 1x1 pixels, not the odd 200x100 of the original code. It seems to work the same and looks better and less mysterious, so unless arossato had a specific reason for those particular two numbers...
2007-10-19 01:00:13 +00:00
"Valery V. Vorotyntsev"
710aa7efb9 XPrompt.hs (keyPressHandle): Ctrl-g and Ctrl-c added to quit keystrokes
Obvious comments removed.
2007-10-20 17:09:36 +00:00
"Valery V. Vorotyntsev"
0febec2c69 XPrompt.hs: trailing whitespace cleaned 2007-10-20 17:07:19 +00:00
Shachaf Ben-Kiki
55b537f2a2 Fix pragmas in XMonadContrib 2007-10-22 01:17:38 +00:00
"Valery V. Vorotyntsev"
ab94a40160 test_XPrompt.hs: there is no ShellPrompt.rmPath 2007-10-19 20:58:30 +00:00
David Roundy
723e757910 introduce new combineTwo layout combinator.
This layout combinator is similar in spirit (and in code) to
the old combo combinator, but only allows two sublayouts.  As
a result, we don't need to wrap these in existentials, and reading
works seamlessly.  Also, we add the feature (which could also be
added to combo) of being able to change which sublayout a given
window is in through integration with WindowNavigation.

I envision combo being deprecated soon.  combineTwo isn't quite
so flexible, but it's much easier and is better-coded also.
2007-10-20 19:17:48 +00:00
David Roundy
73a5299fbe allow layout modifiers to modify a Message in transit.
This is a helpful feature (for, e.g. WindowNavigation) that
allows modifiers (if they so choose... the old API remains
supported) to easily send a single Message to the modified
layout in response to a Message.
2007-10-20 19:15:42 +00:00
Brent Yorgey
ba006db696 update UrgencyHook example config to reflect changes to WindowNavigation and core Config.hs 2007-10-19 14:55:26 +00:00
David Roundy
f2b5dfebed add ToggleLayouts module. 2007-10-18 21:45:25 +00:00
David Roundy
fbe5c23729 default to empty description for layout modifiers.
This is because modifierDescription is designed to be human-readable,
and show rarely creates a human-readable description.  And in many (if
not most) cases, an empty description is precisely what we want.
2007-10-18 20:26:04 +00:00
David Roundy
3c372e5f9a beautify description code for empty modifier-description. 2007-10-18 20:24:38 +00:00
Brent Yorgey
7910250fe4 change definition of 'description' function for LayoutModifier so an extra space is not added if the modifier description is empty. 2007-10-18 18:30:54 +00:00
l.mai
da02543042 -Wall police 2007-10-18 03:30:00 +00:00
Eric Mertens
61ed28a72b DynamicLog.hs: Add dzenColor 2007-10-18 17:45:23 +00:00
David Roundy
c80bf1e5eb add function to rename workspaces. 2007-10-18 14:56:04 +00:00
l.mai
27b9582201 fix WindowNavigation comment 2007-10-18 05:43:15 +00:00
Devin Mullins
883af044fb change example to dzenUrgencyHook 2007-10-18 02:20:26 +00:00
Devin Mullins
06aa06ecdb add dzenUrgencyHook as example (and the one I use) 2007-10-18 02:17:42 +00:00
Devin Mullins
567e10619b fixed Dzen and gave it a configurable timeout 2007-10-18 01:29:10 +00:00
Devin Mullins
02c2e69643 rename LayoutSelect & defaultLayout in comments 2007-10-16 05:18:19 +00:00
Devin Mullins
244edc1d3a add import to comments, for clarity 2007-10-12 04:45:55 +00:00
Devin Mullins
46b9061f4b documentation for UrgencyHook 2007-10-12 03:45:06 +00:00
Devin Mullins
ff65fdb6c6 d'oh, minor UrgencyHook cleanup 2007-10-12 03:25:58 +00:00
Devin Mullins
83756daeeb brand new UrgencyHook contrib, depends on X11-extras WMHints binding
It's a LayoutModifier which lets you define an urgencyHook function -- the
action gets performed wheneveran X client sends an XUrgencyHint message (i.e.
tries to "flash" the "taskbar").

This statically points to Config.urgencyHook, which requires that the user add
a line to Config.hs-boot, in addition to defining the urgencyHook.

Documentation forthcoming.
2007-10-11 05:16:41 +00:00
Eric Mertens
58d131746a TilePrime.hs: Give a description that distinguishs between horizontal/vertical 2007-10-18 06:37:49 +00:00
Spencer Janssen
107121680f Truncate title at 80 characters 2007-10-18 00:30:13 +00:00
Spencer Janssen
7b82a81080 shorten in sjanssenPP too 2007-10-18 00:28:21 +00:00
Spencer Janssen
f706345292 Truncate long window titles 2007-10-18 00:25:11 +00:00
Eric Mertens
fc393b5f2c DynamicLog.hs: Add ppWsSep field to PP to specify workspace separator.
This can be useful when you are using colors to distinguish between
workspaces and simply provides more functionality. The default behavior
remains the same.
2007-10-18 00:16:52 +00:00
Spencer Janssen
30e99281b2 Wrapping the empty string yields the empty string 2007-10-18 00:15:42 +00:00
Spencer Janssen
e4416696c1 DynamicLog: documentation only 2007-10-17 21:14:27 +00:00
Spencer Janssen
8340a26946 Allow the user to change the order of workspaces, layout, title 2007-10-17 21:13:03 +00:00
Spencer Janssen
840835f00a Don't wrap the layout description by default 2007-10-17 21:10:11 +00:00
Spencer Janssen
d5a014725d DynamicLog: not . null. Duh. 2007-10-17 21:09:12 +00:00
Spencer Janssen
005d65b57e A big dynamicLog refactor
We introduce the PP type to allow user customization of dynamicLog.
dynamicLogWithTitle has been eliminated because this is the default behavior
for dynamicLog now.
2007-10-17 21:04:31 +00:00
Spencer Janssen
9ef8512291 Don't toLower the layout description.
If we'd really like lower case layout descriptions, the 'description' method
in the LayoutClass instances should be changed instead.
2007-10-17 20:29:53 +00:00
Eric Mertens
fa81ef9e07 TilePrime.hs: Correct behavior when number of windows <= nmaster
Additionally this patch does various clean-ups that should not
affect functionality.
2007-10-17 20:51:53 +00:00
Spencer Janssen
3b71671751 Remove RunInXTerm in favor of Run 2007-10-17 20:22:01 +00:00
Christian Thiemann
830945336f Move runXXX functions to one module
This patch takes runProcessWithInput out of Dmenu, runProcessWithInputAndWait
out of Dzen, and runInXTerm out of RunInXTerm and collects them in one central
module called Run.  This way, other modules may include Run instead of Dmenu
to get what they want without giving the impression of making use of dmenu.
2007-10-12 14:52:33 +00:00
Shachaf Ben-Kiki
c437e3e384 Fix LANGUAGE pragmas 2007-10-17 19:46:22 +00:00
l.mai
aba2e77b68 use full screen for single window in TilePrime 2007-10-17 19:14:21 +00:00
Eric Mertens
3e5c834c75 RotSlaves.hs: Add rotAll functions 2007-10-17 17:32:56 +00:00
Joachim Fasting
5abd5e39a6 TilePrime.hs: add usage info. 2007-10-17 19:26:12 +00:00
Joachim Fasting
1d006c67f3 TilePrime.hs: add LANGAUGE pragma. 2007-10-17 18:20:42 +00:00
Joachim Fasting
ac633a1486 MetaModule.hs: add WorkspacePrompt. 2007-10-17 18:20:27 +00:00
David Roundy
1d20921fb2 add TilePrime to MetaModule. 2007-10-17 13:32:02 +00:00
Eric Mertens
cbd3af0b0e Initial import of TilePrime
This layout provides a standard tiling layout with support for resize hints
and filling the gaps created by them.
2007-10-17 05:20:17 +00:00
David Roundy
551e44ce55 code cleanup in selectWorkspace. 2007-10-16 23:12:18 +00:00
David Roundy
763a952c80 allow users to go to dynamically-added workspaces with mod-n. 2007-10-16 23:03:01 +00:00
David Roundy
e43eabfd93 add modules to deal with Workspaces (select, etc) by name using XPrompt. 2007-10-16 22:33:47 +00:00
David Roundy
1ec41467de make windowNavigation simpler to use in simplest case. 2007-10-16 21:43:37 +00:00
David Roundy
7efca8901c compute nice window border for WindowNavigation properly. 2007-10-16 21:33:16 +00:00
David Roundy
4c236753ec fix docs on WindowNavigation. 2007-10-16 21:03:49 +00:00
David Roundy
2f3a40d535 compute a reasonable navigation color based on focussed color. 2007-10-15 16:55:04 +00:00
Andrea Rossato
d7704a3c0d WindowNavigation: don't export the config constructor and some haddock fixes
I told to David I would have taken care of that: instead of exporting
the config constructor we export 2 functions: navigateColor and
noNavigateBorders. Updated documentation accordingly.
2007-10-13 09:05:24 +00:00
David Roundy
f785bad680 improvements in Combo. 2007-10-15 13:28:39 +00:00
191 changed files with 17672 additions and 5179 deletions

View File

@@ -1,90 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Anneal
-- Copyright : (c) David Roundy
-- License : BSD-style (see LICENSE)
--
-- Maintainer : David Roundy <droundy@darcs.org>
-- Stability : unstable
-- Portability : unportable
--
-- Requires the 'random' package
--
-----------------------------------------------------------------------------
module XMonadContrib.Anneal ( Rated(Rated), the_value, the_rating
, anneal, annealMax ) where
import System.Random ( StdGen, Random, mkStdGen, randomR )
import Control.Monad.State ( State, runState, put, get, gets, modify )
-- %import XMonadContrib.Anneal
data Rated a b = Rated !a !b
deriving ( Show )
instance Functor (Rated a) where
f `fmap` (Rated v a) = Rated v (f a)
the_value :: Rated a b -> b
the_value (Rated _ b) = b
the_rating :: Rated a b -> a
the_rating (Rated a _) = a
instance Eq a => Eq (Rated a b) where
(Rated a _) == (Rated a' _) = a == a'
instance Ord a => Ord (Rated a b) where
compare (Rated a _) (Rated a' _) = compare a a'
anneal :: a -> (a -> Double) -> (a -> [a]) -> Rated Double a
anneal st r sel = runAnneal st r (do_anneal sel)
annealMax :: a -> (a -> Double) -> (a -> [a]) -> Rated Double a
annealMax st r sel = runAnneal st (negate . r) (do_anneal sel)
do_anneal :: (a -> [a]) -> State (Anneal a) (Rated Double a)
do_anneal sel = do sequence_ $ replicate 100 da
gets best
where da = do select_metropolis sel
modify $ \s -> s { temperature = temperature s *0.99 }
data Anneal a = A { g :: StdGen
, best :: Rated Double a
, current :: Rated Double a
, rate :: a -> Rated Double a
, temperature :: Double }
runAnneal :: a -> (a -> Double) -> State (Anneal a) b -> b
runAnneal start r x = fst $ runState x (A { g = mkStdGen 137
, best = Rated (r start) start
, current = Rated (r start) start
, rate = \xx -> Rated (r xx) xx
, temperature = 1.0 })
select_metropolis :: (a -> [a]) -> State (Anneal a) ()
select_metropolis x = do c <- gets current
a <- select $ x $ the_value c
metropolis a
metropolis :: a -> State (Anneal a) ()
metropolis x = do r <- gets rate
c <- gets current
t <- gets temperature
let rx = r x
boltz = exp $ (the_rating c - the_rating rx) / t
if rx < c then do modify $ \s -> s { current = rx, best = rx }
else do p <- getOne (0,1)
if p < boltz
then modify $ \s -> s { current = rx }
else return ()
select :: [a] -> State (Anneal a) a
select [] = the_value `fmap` gets best
select [x] = return x
select xs = do n <- getOne (0,length xs - 1)
return (xs !! n)
getOne :: (Random a) => (a,a) -> State (Anneal x) a
getOne bounds = do s <- get
(x,g') <- return $ randomR bounds (g s)
put $ s { g = g' }
return x

View File

@@ -1,96 +0,0 @@
{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Combo
-- Copyright : (c) David Roundy <droundy@darcs.net>
-- License : BSD-style (see LICENSE)
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : unportable
--
-- A layout that combines multiple layouts.
--
-----------------------------------------------------------------------------
module XMonadContrib.Combo (
-- * Usage
-- $usage
combo
) where
import Control.Arrow ( first )
import Data.List ( delete )
import Data.Maybe ( isJust )
import XMonad
import StackSet ( integrate, Stack(..) )
import qualified StackSet as W ( differentiate )
-- $usage
--
-- To use this layout write, in your Config.hs:
--
-- > import XMonadContrib.Combo
--
-- and add something like
--
-- > combo (TwoPane 0.03 0.5) [(Full,1),(tabbed shrinkText defaultTConf,1)]
--
-- to your layouts.
--
-- The first argument to combo is a layout that will divide the screen into
-- one or more subscreens. The second argument is a list of layouts which
-- will be used to lay out the contents of each of those subscreens.
-- Paired with each of these layouts is an integer giving the number of
-- windows this section should hold. This number is ignored for the last
-- layout, which will hold any excess windows.
-- %import XMonadContrib.Combo
-- %layout , combo (twoPane 0.03 0.5) [(full,1),(tabbed shrinkText defaultTConf,1)]
combo :: (Eq a, Show a, Read a, ReadableLayout a, LayoutClass l (Layout a, Int))
=> (l (Layout a, Int)) -> [(Layout a, Int)] -> Combo l a
combo = Combo []
data Combo l a = Combo [a] (l (Layout a, Int)) [(Layout a, Int)]
deriving (Show, Read)
instance (Eq a, Show a, Read a, ReadableLayout a, LayoutClass l (Layout a, Int))
=> LayoutClass (Combo l) a where
doLayout (Combo f super origls) rinput s = arrange (integrate s)
where arrange [] = return ([], Just $ Combo [] super origls)
arrange [w] = return ([(w,rinput)], Just $ Combo [w] super origls)
arrange origws =
do (lrs, msuper') <- runLayout super rinput (W.differentiate $ take (length origws) origls)
let super' = maybe super id msuper'
f' = focus s:delete (focus s) f
lwrs [] _ = []
lwrs [((l,_),r)] ws = [((l,r),differentiate f' ws)]
lwrs (((l,n),r):xs) ws = ((l,r),differentiate f' $ take len1 ws) : lwrs xs (drop len1 ws)
where len1 = min n (length ws - length xs)
out <- mapM (uncurry $ uncurry runLayout) $ lwrs lrs origws
let origls' = zipWith foo (out++repeat ([],Nothing)) origls
foo (_, Nothing) x = x
foo (_, Just l') (_, n) = (l', n)
return (concat $ map fst out, Just $ Combo f' super' origls')
differentiate :: Eq q => [q] -> [q] -> Maybe (Stack q)
differentiate (z:zs) xs | z `elem` xs = Just $ Stack { focus=z
, up = reverse $ takeWhile (/=z) xs
, down = tail $ dropWhile (/=z) xs }
| otherwise = differentiate zs xs
differentiate [] xs = W.differentiate xs
handleMessage (Combo f super origls) m =
do mls <- broadcastPrivate m (map fst origls)
let mls' = (\x->zipWith first (map const x) origls) `fmap` mls
msuper <- broadcastPrivate m [super]
case msuper of
Just [super'] -> return $ Just $ Combo f super' $ maybe origls id mls'
_ -> return $ Combo f super `fmap` mls'
broadcastPrivate :: LayoutClass l b => SomeMessage -> [l b] -> X (Maybe [l b])
broadcastPrivate a ol = do nml <- mapM f ol
if any isJust nml
then return $ Just $ zipWith ((flip maybe) id) ol nml
else return Nothing
where f l = handleMessage l a `catchX` return Nothing

View File

@@ -1,110 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Commands
-- Copyright : (c) David Glasser 2007
-- License : BSD3
--
-- Maintainer : glasser@mit.edu
-- Stability : stable
-- Portability : portable
--
-- Allows you to run internal xmonad commands (X () actions) using
-- a dmenu menu in addition to key bindings. Requires dmenu and
-- the Dmenu XMonadContrib module.
--
-----------------------------------------------------------------------------
module XMonadContrib.Commands (
-- * Usage
-- $usage
commandMap,
runCommand,
runCommand',
workspaceCommands,
screenCommands,
defaultCommands
) where
import XMonad
import Operations
import StackSet hiding (workspaces)
import XMonadContrib.Dmenu (dmenu)
import {-# SOURCE #-} Config (workspaces,serialisedLayouts)
import qualified Data.Map as M
import System.Exit
import Data.Maybe
-- $usage
--
-- To use, modify your Config.hs to:
--
-- > import XMonadContrib.Commands
--
-- and add a keybinding to the runCommand action:
--
-- > , ((modMask .|. controlMask, xK_y), runCommand commands)
--
-- and define the list commands:
--
-- > commands :: [(String, X ())]
-- > commands = defaultCommands
--
-- A popup menu of internal xmonad commands will appear. You can
-- change the commands by changing the contents of the list
-- 'commands'. (If you like it enough, you may even want to get rid
-- of many of your other key bindings!)
-- %def commands :: [(String, X ())]
-- %def commands = defaultCommands
-- %import XMonadContrib.Commands
-- %keybind , ((modMask .|. controlMask, xK_y), runCommand commands)
commandMap :: [(String, X ())] -> M.Map String (X ())
commandMap c = M.fromList c
workspaceCommands :: [(String, X ())]
workspaceCommands = [((m ++ show i), windows $ f i)
| i <- workspaces
, (f, m) <- [(view, "view"), (shift, "shift")]
]
screenCommands :: [(String, X ())]
screenCommands = [((m ++ show sc), screenWorkspace (fromIntegral sc) >>= flip whenJust (windows . f))
| sc <- [0, 1]::[Int] -- TODO: adapt to screen changes
, (f, m) <- [(view, "screen"), (shift, "screen-to-")]
]
defaultCommands :: [(String, X ())]
defaultCommands = workspaceCommands ++ screenCommands
++ [ ("shrink" , sendMessage Shrink )
, ("expand" , sendMessage Expand )
, ("next-layout" , sendMessage NextLayout )
, ("previous-layout" , sendMessage PrevLayout )
, ("default-layout" , setLayout (head serialisedLayouts) )
, ("restart-wm" , sr >> restart Nothing True )
, ("restart-wm-no-resume", sr >> restart Nothing False )
, ("xterm" , spawn "xterm" )
, ("run" , spawn "exe=`dmenu_path | dmenu -b` && exec $exe" )
, ("kill" , kill )
, ("refresh" , refresh )
, ("focus-up" , windows $ focusUp )
, ("focus-down" , windows $ focusDown )
, ("swap-up" , windows $ swapUp )
, ("swap-down" , windows $ swapDown )
, ("swap-master" , windows $ swapMaster )
, ("sink" , withFocused $ windows . sink )
, ("quit-wm" , io $ exitWith ExitSuccess )
]
where sr = broadcastMessage ReleaseResources
runCommand :: [(String, X ())] -> X ()
runCommand cl = do
let m = commandMap cl
choice <- dmenu (M.keys m)
fromMaybe (return ()) (M.lookup choice m)
runCommand' :: String -> X ()
runCommand' c = do
let m = commandMap defaultCommands
fromMaybe (return ()) (M.lookup c m)

View File

@@ -1,79 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.CopyWindow
-- Copyright : (c) David Roundy <droundy@darcs.net>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : unportable
--
-- Provides a binding to duplicate a window on multiple workspaces,
-- providing dwm-like tagging functionality.
--
-----------------------------------------------------------------------------
module XMonadContrib.CopyWindow (
-- * Usage
-- $usage
copy, kill1
) where
import Prelude hiding ( filter )
import Control.Monad.State ( gets )
import qualified Data.List as L
import XMonad
import Operations ( windows, kill )
import StackSet
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.CopyWindow
--
-- > -- mod-[1..9] @@ Switch to workspace N
-- > -- mod-shift-[1..9] @@ Move client to workspace N
-- > -- mod-control-shift-[1..9] @@ Copy client to workspace N
-- > [((m .|. modMask, k), f i)
-- > | (i, k) <- zip workspaces [xK_1 ..]
-- > , (f, m) <- [(view, 0), (shift, shiftMask), (copy, shiftMask .|. controlMask)]]
--
-- you may also wish to redefine the binding to kill a window so it only
-- removes it from the current workspace, if it's present elsewhere:
--
-- > , ((modMask .|. shiftMask, xK_c ), kill1) -- @@ Close the focused window
-- %import XMonadContrib.CopyWindow
-- %keybind -- comment out default close window binding above if you uncomment this:
-- %keybind , ((modMask .|. shiftMask, xK_c ), kill1) -- @@ Close the focused window
-- %keybindlist ++
-- %keybindlist -- mod-[1..9] @@ Switch to workspace N
-- %keybindlist -- mod-shift-[1..9] @@ Move client to workspace N
-- %keybindlist -- mod-control-shift-[1..9] @@ Copy client to workspace N
-- %keybindlist [((m .|. modMask, k), f i)
-- %keybindlist | (i, k) <- zip workspaces [xK_1 ..]
-- %keybindlist , (f, m) <- [(view, 0), (shift, shiftMask), (copy, shiftMask .|. controlMask)]]
-- | copy. Copy a window to a new workspace.
copy :: WorkspaceId -> WindowSet -> WindowSet
copy n = copy'
where copy' s = if n `tagMember` s && n /= tag (workspace (current s))
then maybe s (go s) (peek s)
else s
go s w = view (tag (workspace (current s))) $ insertUp' w $ view n s
insertUp' a s = modify (Just $ Stack a [] [])
(\(Stack t l r) -> Just $ Stack a (L.delete a l) (L.delete a (t:r))) s
-- | Remove the focussed window from this workspace. If it's present in no
-- other workspace, then kill it instead. If we do kill it, we'll get a
-- delete notify back from X.
--
-- There are two ways to delete a window. Either just kill it, or if it
-- supports the delete protocol, send a delete event (e.g. firefox)
--
kill1 :: X ()
kill1 = do ss <- gets windowset
whenJust (peek ss) $ \w -> if member w $ delete'' w ss
then windows $ delete'' w
else kill
where delete'' w = modify Nothing (filter (/= w))

View File

@@ -1,99 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.CycleWS
-- Copyright : (c) Joachim Breitner <mail@joachim-breitner.de>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Joachim Breitner <mail@joachim-breitner.de>
-- Stability : unstable
-- Portability : unportable
--
-- Provides bindings to cycle forward or backward through the list
-- of workspaces, and to move windows there.
--
-----------------------------------------------------------------------------
module XMonadContrib.CycleWS (
-- * Usage
-- $usage
nextWS,
prevWS,
shiftToNext,
shiftToPrev,
) where
import Control.Monad.State ( gets )
import Data.List ( sortBy, findIndex )
import Data.Maybe ( fromMaybe )
import Data.Ord ( comparing )
import XMonad
import StackSet hiding (filter, findIndex)
import Operations
import {-# SOURCE #-} qualified Config (workspaces)
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.CycleWS
--
-- > , ((modMask, xK_Right), nextWS)
-- > , ((modMask, xK_Left), prevWS)
-- > , ((modMask .|. shiftMask, xK_Right), shiftToNext)
-- > , ((modMask .|. shiftMask, xK_Left), shiftToPrev)
--
-- If you want to follow the moved window, you can use both actions:
--
-- > , ((modMask .|. shiftMask, xK_Right), shiftToNext >> nextWS)
-- > , ((modMask .|. shiftMask, xK_Left), shiftToPrev >> prevWS)
--
-- %import XMonadContrib.CycleWS
-- %keybind , ((modMask, xK_Right), nextWS)
-- %keybind , ((modMask, xK_Left), prevWS)
-- %keybind , ((modMask .|. shiftMask, xK_Right), shiftToNext)
-- %keybind , ((modMask .|. shiftMask, xK_Left), shiftToPrev)
-- ---------------------
-- |
-- Switch to next workspace
nextWS :: X()
nextWS = switchWorkspace (1)
-- ---------------------
-- |
-- Switch to previous workspace
prevWS :: X()
prevWS = switchWorkspace (-1)
-- |
-- Move focused window to next workspace
shiftToNext :: X()
shiftToNext = shiftBy (1)
-- |
-- Move focused window to previous workspace
shiftToPrev :: X ()
shiftToPrev = shiftBy (-1)
switchWorkspace :: Int -> X ()
switchWorkspace d = wsBy d >>= windows . greedyView
shiftBy :: Int -> X ()
shiftBy d = wsBy d >>= windows . shift
wsBy :: Int -> X (WorkspaceId)
wsBy d = do
ws <- gets windowset
let orderedWs = sortBy (comparing wsIndex) (workspaces ws)
let now = fromMaybe 0 $ findWsIndex (workspace (current ws)) orderedWs
let next = orderedWs !! ((now + d) `mod` length orderedWs)
return $ tag next
wsIndex :: WindowSpace -> Maybe Int
wsIndex ws = findIndex (==(tag ws)) Config.workspaces
findWsIndex :: WindowSpace -> [WindowSpace] -> Maybe Int
findWsIndex ws wss = findIndex ((== tag ws) . tag) wss

View File

@@ -1,57 +0,0 @@
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Dishes
-- Copyright : (c) Jeremy Apthorp
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Jeremy Apthorp <nornagon@gmail.com>
-- Stability : unstable
-- Portability : portable
--
-- Dishes is a layout that stacks extra windows underneath the master
-- windows.
--
-----------------------------------------------------------------------------
module XMonadContrib.Dishes (
-- * Usage
-- $usage
Dishes (..)
) where
import Data.List
import XMonad
import Operations
import StackSet (integrate)
import Control.Monad (ap)
import Graphics.X11.Xlib
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.Dishes
--
-- and add the following line to your 'layouts'
--
-- > , Layout $ Dishes 2 (1%6)
-- %import XMonadContrib.Dishes
-- %layout , Layout $ Dishes 2 (1%6)
data Dishes a = Dishes Int Rational deriving (Show, Read)
instance LayoutClass Dishes a where
doLayout (Dishes nmaster h) r =
return . (\x->(x,Nothing)) .
ap zip (dishes h r nmaster . length) . integrate
pureMessage (Dishes nmaster h) m = fmap incmastern (fromMessage m)
where incmastern (IncMasterN d) = Dishes (max 0 (nmaster+d)) h
dishes :: Rational -> Rectangle -> Int -> Int -> [Rectangle]
dishes h s nmaster n = if n <= nmaster
then splitHorizontally n s
else ws
where
(m,rest) = splitVerticallyBy (1 - (fromIntegral $ n - nmaster) * h) s
ws = splitHorizontally nmaster m ++ splitVertically (n - nmaster) rest

View File

@@ -1,65 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Dmenu
-- Copyright : (c) Spencer Janssen <sjanssen@cse.unl.edu>
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Spencer Janssen <sjanssen@cse.unl.edu>
-- Stability : unstable
-- Portability : unportable
--
-- A convenient binding to dmenu.
--
-- Requires the process-1.0 package
--
-----------------------------------------------------------------------------
module XMonadContrib.Dmenu (
-- * Usage
-- $usage
dmenu, dmenuXinerama, dmenuMap,
runProcessWithInput
) where
import XMonad
import qualified StackSet as W
import qualified Data.Map as M
import System.Process
import System.IO
import Control.Monad.State
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.Dmenu
-- %import XMonadContrib.Dmenu
-- | Returns Just output if the command succeeded, and Nothing if it didn't.
-- This corresponds to dmenu's notion of exit code 1 for a cancelled invocation.
runProcessWithInput :: FilePath -> [String] -> String -> IO String
runProcessWithInput cmd args input = do
(pin, pout, perr, ph) <- runInteractiveProcess cmd args Nothing Nothing
hPutStr pin input
hClose pin
output <- hGetContents pout
when (output==output) $ return ()
hClose pout
hClose perr
waitForProcess ph
return output
-- | Starts dmenu on the current screen. Requires this patch to dmenu:
-- <http://www.jcreigh.com/dmenu/dmenu-3.2-xinerama.patch>
dmenuXinerama :: [String] -> X String
dmenuXinerama opts = do
curscreen <- (fromIntegral . W.screen . W.current) `liftM` gets windowset :: X Int
io $ runProcessWithInput "dmenu" ["-xs", show (curscreen+1)] (unlines opts)
dmenu :: [String] -> X String
dmenu opts = io $ runProcessWithInput "dmenu" [] (unlines opts)
dmenuMap :: M.Map String a -> X (Maybe a)
dmenuMap selectionMap = do
selection <- dmenu (M.keys selectionMap)
return $ M.lookup selection selectionMap

View File

@@ -1,160 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.DynamicLog
-- Copyright : (c) Don Stewart <dons@cse.unsw.edu.au>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Don Stewart <dons@cse.unsw.edu.au>
-- Stability : unstable
-- Portability : unportable
--
-- DynamicLog
--
-- Log events in:
--
-- > 1 2 [3] 4 8
--
-- format. Suitable to pipe into dzen.
--
-----------------------------------------------------------------------------
module XMonadContrib.DynamicLog (
-- * Usage
-- $usage
dynamicLog,
dynamicLogWithTitle,
dynamicLogWithTitleColored,
dynamicLogXinerama,
pprWindowSet,
pprWindowSetXinerama
) where
--
-- Useful imports
--
import XMonad
import {-# SOURCE #-} Config (workspaces)
import Operations () -- for ReadableSomeLayout instance
import Data.Maybe ( isJust )
import Data.List
import Data.Ord ( comparing )
import qualified StackSet as S
import Data.Monoid
import XMonadContrib.NamedWindows
import Data.Char
-- $usage
--
-- To use, set:
--
-- > import XMonadContrib.DynamicLog
-- > logHook = dynamicLog
--
-- To get the title of the currently focused window after the workspace list:
--
-- > import XMonadContrib.DynamicLog
-- > logHook = dynamicLogWithTitle
--
-- To have the window title highlighted in any color recognized by dzen:
--
-- > import XMonadContrib.DynamicLog
-- > logHook = dynamicLogWithTitleColored "white"
--
-- %import XMonadContrib.DynamicLog
-- %def -- comment out default logHook definition above if you uncomment any of these:
-- %def logHook = dynamicLog
-- %def logHook = dynamicLogWithTitle
-- %def logHook = dynamicLogWithTitleColored "white"
-- |
-- Perform an arbitrary action on each state change.
-- Examples include:
-- * do nothing
-- * log the state to stdout
--
-- |
-- An example log hook, print a status bar output to dzen, in the form:
--
-- > 1 2 [3] 4 7 : full
--
-- That is, the currently populated workspaces, and the current
-- workspace layout
--
dynamicLog :: X ()
dynamicLog = withWindowSet $ \ws -> do
let ld = description . S.layout . S.workspace . S.current $ ws
wn = pprWindowSet ws
io . putStrLn $ concat [wn ," : " ,map toLower ld]
-- | Appends title of currently focused window to log output, and the
-- current layout mode, to the normal dynamic log format.
-- Arguments are: pre-title text and post-title text
--
-- The result is rendered in the form:
--
-- > 1 2 [3] 4 7 : full : urxvt
--
dynamicLogWithTitle_ :: String -> String -> X ()
dynamicLogWithTitle_ pre post= do
-- layout description
ld <- withWindowSet $ return . description . S.layout . S.workspace . S.current
-- workspace list
ws <- withWindowSet $ return . pprWindowSet
-- window title
wt <- withWindowSet $ maybe (return "") (fmap show . getName) . S.peek
io . putStrLn $ concat [ws ," : " ,map toLower ld
, case wt of
[] -> []
s -> " : " ++ pre ++ s ++ post
]
dynamicLogWithTitle :: X ()
dynamicLogWithTitle = dynamicLogWithTitle_ "" ""
-- |
-- As for dynamicLogWithTitle but with colored window title (for dzen use)
--
dynamicLogWithTitleColored :: String -> X ()
dynamicLogWithTitleColored color = dynamicLogWithTitle_ ("^fg(" ++ color ++ ")") "^fg()"
pprWindowSet :: WindowSet -> String
pprWindowSet s = concatMap fmt $ sortBy cmp
(map S.workspace (S.current s : S.visible s) ++ S.hidden s)
where f Nothing Nothing = EQ
f (Just _) Nothing = LT
f Nothing (Just _) = GT
f (Just x) (Just y) = compare x y
wsIndex = flip elemIndex workspaces . S.tag
cmp a b = f (wsIndex a) (wsIndex b) `mappend` compare (S.tag a) (S.tag b)
this = S.tag (S.workspace (S.current s))
visibles = map (S.tag . S.workspace) (S.visible s)
fmt w | S.tag w == this = "[" ++ S.tag w ++ "]"
| S.tag w `elem` visibles = "<" ++ S.tag w ++ ">"
| isJust (S.stack w) = " " ++ S.tag w ++ " "
| otherwise = ""
-- |
-- Workspace logger with a format designed for Xinerama:
--
-- > [1 9 3] 2 7
--
-- where 1, 9, and 3 are the workspaces on screens 1, 2 and 3, respectively,
-- and 2 and 7 are non-visible, non-empty workspaces
--
dynamicLogXinerama :: X ()
dynamicLogXinerama = withWindowSet $ io . putStrLn . pprWindowSetXinerama
pprWindowSetXinerama :: WindowSet -> String
pprWindowSetXinerama ws = "[" ++ unwords onscreen ++ "] " ++ unwords offscreen
where onscreen = map (S.tag . S.workspace)
. sortBy (comparing S.screen) $ S.current ws : S.visible ws
offscreen = map S.tag . filter (isJust . S.stack)
. sortBy (comparing S.tag) $ S.hidden ws

View File

@@ -1,69 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.DynamicWorkspaces
-- Copyright : (c) David Roundy <droundy@darcs.net>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : unportable
--
-- Provides bindings to add and delete workspaces. Note that you may only
-- delete a workspace that is already empty.
--
-----------------------------------------------------------------------------
module XMonadContrib.DynamicWorkspaces (
-- * Usage
-- $usage
addWorkspace, removeWorkspace
) where
import Control.Monad.State ( gets )
import XMonad ( X, XState(..), Layout, WorkspaceId )
import Operations
import StackSet hiding (filter, modify, delete)
import Graphics.X11.Xlib ( Window )
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.DynamicWorkspaces
--
-- > , ((modMask .|. shiftMask, xK_Up), addWorkspace layouts)
-- > , ((modMask .|. shiftMask, xK_Down), removeWorkspace)
allPossibleTags :: [WorkspaceId]
allPossibleTags = map (:"") ['0'..]
addWorkspace :: Layout Window -> X ()
addWorkspace l = do s <- gets windowset
let newtag:_ = filter (not . (`tagMember` s)) allPossibleTags
windows (addWorkspace' newtag l)
removeWorkspace :: X ()
removeWorkspace = do s <- gets windowset
case s of
StackSet { current = Screen { workspace = torem }
, hidden = (w:_) }
-> do windows $ view (tag w)
windows (removeWorkspace' (tag torem))
_ -> return ()
addWorkspace' :: i -> l -> StackSet i l a sid sd -> StackSet i l a sid sd
addWorkspace' newtag l s@(StackSet { current = scr@(Screen { workspace = w })
, hidden = ws })
= s { current = scr { workspace = Workspace newtag l Nothing }
, hidden = w:ws }
removeWorkspace' :: (Eq i) => i -> StackSet i l a sid sd -> StackSet i l a sid sd
removeWorkspace' torem s@(StackSet { current = scr@(Screen { workspace = wc })
, hidden = (w:ws) })
| tag w == torem = s { current = scr { workspace = wc { stack = meld (stack w) (stack wc) } }
, hidden = ws }
where meld Nothing Nothing = Nothing
meld x Nothing = x
meld Nothing x = x
meld (Just x) (Just y) = differentiate (integrate x ++ integrate y)
removeWorkspace' _ s = s

63
Dzen.hs
View File

@@ -1,63 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Dzen
-- Copyright : (c) glasser@mit.edu
-- License : BSD
--
-- Maintainer : glasser@mit.edu
-- Stability : unstable
-- Portability : unportable
--
-- Handy wrapper for dzen.
--
-----------------------------------------------------------------------------
module XMonadContrib.Dzen (dzen, dzenScreen) where
import System.Posix.Process (forkProcess, getProcessStatus, createSession)
import System.IO
import System.Process
import System.Exit
import Control.Concurrent (threadDelay)
import Control.Monad.State
import qualified StackSet as W
import XMonad
-- wait is in us
runProcessWithInputAndWait :: FilePath -> [String] -> String -> Int -> IO ()
runProcessWithInputAndWait cmd args input timeout = do
pid <- forkProcess $ do
forkProcess $ do -- double fork it over to init
createSession
(pin, pout, perr, ph) <- runInteractiveProcess cmd args Nothing Nothing
hPutStr pin input
hFlush pin
threadDelay timeout
hClose pin
-- output <- hGetContents pout
-- when (output==output) $ return ()
hClose pout
hClose perr
waitForProcess ph
return ()
exitWith ExitSuccess
return ()
getProcessStatus True False pid
return ()
curScreen :: X ScreenId
curScreen = (W.screen . W.current) `liftM` gets windowset
toXineramaArg :: ScreenId -> String
toXineramaArg n = show ( ((fromIntegral n)+1)::Int )
-- Requires dzen >= 0.2.4.
dzen :: String -> X ()
dzen str = curScreen >>= \sc -> dzenScreen sc str
dzenScreen :: ScreenId -> String -> X()
dzenScreen sc str = io $ (runProcessWithInputAndWait "dzen2" ["-xs", screen] str 5000000)
where screen = toXineramaArg sc

View File

@@ -1,130 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.EwmhDesktops
-- Copyright : (c) Joachim Breitner <mail@joachim-breitner.de>
-- License : BSD
--
-- Maintainer : Joachim Breitner <mail@joachim-breitner.de>
-- Stability : unstable
-- Portability : unportable
--
-- Makes xmonad use the EWMH hints to tell panel applications about its
-- workspaces and the windows therein.
-----------------------------------------------------------------------------
module XMonadContrib.EwmhDesktops (
-- * Usage
-- $usage
ewmhDesktopsLogHook
) where
import Data.List (elemIndex, sortBy)
import Data.Ord (comparing)
import Data.Maybe (fromMaybe)
import Control.Monad.Reader
import XMonad
import qualified StackSet as W
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import XMonadContrib.SetWMName
-- $usage
-- Add the imports to your configuration file and add the logHook:
--
-- > import XMonadContrib.EwmhDesktops
--
-- > logHook :: X()
-- > logHook = do ewmhDesktopsLogHook
-- > return ()
-- %import XMonadContrib.EwmhDesktops
-- %def -- comment out default logHook definition above if you uncomment this:
-- %def logHook = ewmhDesktopsLogHook
-- |
-- Notifies pagers and window lists, such as those in the gnome-panel
-- of the current state of workspaces and windows.
ewmhDesktopsLogHook :: X ()
ewmhDesktopsLogHook = withWindowSet $ \s -> do
-- Bad hack because xmonad forgets the original order of things, it seems
-- see http://code.google.com/p/xmonad/issues/detail?id=53
let ws = sortBy (comparing W.tag) $ W.workspaces s
let wins = W.allWindows s
setSupported
-- Number of Workspaces
setNumberOfDesktops (length ws)
-- Names thereof
setDesktopNames (map W.tag ws)
-- Current desktop
fromMaybe (return ()) $ do
n <- W.lookupWorkspace 0 s
i <- elemIndex n $ map W.tag ws
return $ setCurrentDesktop i
setClientList wins
-- Per window Desktop
forM (zip ws [(0::Int)..]) $ \(w, wn) ->
forM (W.integrate' (W.stack w)) $ \win -> do
setWindowDesktop win wn
return ()
setNumberOfDesktops :: (Integral a) => a -> X ()
setNumberOfDesktops n = withDisplay $ \dpy -> do
a <- getAtom "_NET_NUMBER_OF_DESKTOPS"
c <- getAtom "CARDINAL"
r <- asks theRoot
io $ changeProperty32 dpy r a c propModeReplace [fromIntegral n]
setCurrentDesktop :: (Integral a) => a -> X ()
setCurrentDesktop i = withDisplay $ \dpy -> do
a <- getAtom "_NET_CURRENT_DESKTOP"
c <- getAtom "CARDINAL"
r <- asks theRoot
io $ changeProperty32 dpy r a c propModeReplace [fromIntegral i]
setDesktopNames :: [String] -> X ()
setDesktopNames names = withDisplay $ \dpy -> do
-- Names thereof
r <- asks theRoot
a <- getAtom "_NET_DESKTOP_NAMES"
c <- getAtom "UTF8_STRING"
let names' = map (fromIntegral.fromEnum) $
concatMap (("Workspace "++) . (++['\0'])) names
io $ changeProperty8 dpy r a c propModeReplace names'
setClientList :: [Window] -> X ()
setClientList wins = withDisplay $ \dpy -> do
-- (What order do we really need? Something about age and stacking)
r <- asks theRoot
c <- getAtom "WINDOW"
a <- getAtom "_NET_CLIENT_LIST"
io $ changeProperty32 dpy r a c propModeReplace (fmap fromIntegral wins)
a' <- getAtom "_NET_CLIENT_LIST_STACKING"
io $ changeProperty32 dpy r a' c propModeReplace (fmap fromIntegral wins)
setWindowDesktop :: (Integral a) => Window -> a -> X ()
setWindowDesktop win i = withDisplay $ \dpy -> do
a <- getAtom "_NET_WM_DESKTOP"
c <- getAtom "CARDINAL"
io $ changeProperty32 dpy win a c propModeReplace [fromIntegral i]
setSupported :: X ()
setSupported = withDisplay $ \dpy -> do
r <- asks theRoot
a <- getAtom "_NET_SUPPORTED"
c <- getAtom "ATOM"
supp <- mapM getAtom ["_NET_WM_STATE_HIDDEN"]
io $ changeProperty32 dpy r a c propModeReplace (fmap fromIntegral supp)
setWMName "xmonad"

65
Grid.hs
View File

@@ -1,65 +0,0 @@
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Grid
-- Copyright : (c) Lukas Mai
-- License : BSD-style (see LICENSE)
--
-- Maintainer : <l.mai@web.de>
-- Stability : unstable
-- Portability : unportable
--
-- A simple layout that attempts to put all windows in a square grid.
--
-----------------------------------------------------------------------------
module XMonadContrib.Grid (
-- * Usage
-- $usage
Grid(..)
) where
import XMonad
import StackSet
import Graphics.X11.Xlib.Types
-- $usage
-- Put the following in your Config.hs file:
--
-- > import XMonadContrib.Grid
-- > ...
-- > layouts = [ ...
-- > , Layout Grid
-- > ]
-- %import XMonadContrib.Grid
-- %layout , Layout Grid
data Grid a = Grid deriving (Read, Show)
instance LayoutClass Grid a where
pureLayout Grid r s = arrange r (integrate s)
arrange :: Rectangle -> [a] -> [(a, Rectangle)]
arrange (Rectangle rx ry rw rh) st = zip st rectangles
where
nwins = length st
ncols = ceiling . (sqrt :: Double -> Double) . fromIntegral $ nwins
mincs = nwins `div` ncols
extrs = nwins - ncols * mincs
chop :: Int -> Dimension -> [(Position, Dimension)]
chop n m = ((0, m - k * fromIntegral (pred n)) :) . map (flip (,) k) . tail . reverse . take n . tail . iterate (subtract k') $ m'
where
k :: Dimension
k = m `div` fromIntegral n
m' = fromIntegral m
k' :: Position
k' = fromIntegral k
xcoords = chop ncols rw
ycoords = chop mincs rh
ycoords' = chop (succ mincs) rh
(xbase, xext) = splitAt (ncols - extrs) xcoords
rectangles = combine ycoords xbase ++ combine ycoords' xext
where
combine ys xs = [Rectangle (rx + x) (ry + y) w h | (x, w) <- xs, (y, h) <- ys]

View File

@@ -1,98 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.HintedTile
-- Copyright : (c) Peter De Wachter <pdewacht@gmail.com>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Peter De Wachter <pdewacht@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- A gapless tiled layout that attempts to obey window size hints,
-- rather than simply ignoring them.
--
-----------------------------------------------------------------------------
module XMonadContrib.HintedTile (
-- * Usage
-- $usage
tall, wide) where
import XMonad
import Operations (Resize(..), IncMasterN(..), applySizeHints)
import qualified StackSet as W
import {-# SOURCE #-} Config (borderWidth)
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import Control.Monad
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import qualified XMonadContrib.HintedTile
--
-- > layouts = [ XMonadContrib.HintedTile.tall nmaster delta ratio, ... ]
-- %import qualified XMonadContrib.HintedTile
--
-- %layout , XMonadContrib.HintedTile.tall nmaster delta ratio
-- this sucks
addBorder, substractBorder :: (Dimension, Dimension) -> (Dimension, Dimension)
addBorder (w, h) = (w + 2 * borderWidth, h + 2 * borderWidth)
substractBorder (w, h) = (w - 2 * borderWidth, h - 2 * borderWidth)
tall, wide :: Int -> Rational -> Rational -> Layout Window
wide = tile splitVertically divideHorizontally
tall = tile splitHorizontally divideVertically
tile split divide nmaster delta frac =
Layout { doLayout = \r w' -> let w = W.integrate w'
in do { hints <- sequence (map getHints w)
; return (zip w (tiler frac r `uncurry` splitAt nmaster hints)
, Nothing) }
, modifyLayout = \m -> return $ fmap resize (fromMessage m) `mplus`
fmap incmastern (fromMessage m) }
where resize Shrink = tile split divide nmaster delta (frac-delta)
resize Expand = tile split divide nmaster delta (frac+delta)
incmastern (IncMasterN d) = tile split divide (max 0 (nmaster+d)) delta frac
tiler f r masters slaves = if null masters || null slaves
then divide (masters ++ slaves) r
else split f r (divide masters) (divide slaves)
getHints :: Window -> X SizeHints
getHints w = withDisplay $ \d -> io $ getWMNormalHints d w
--
-- Divide the screen vertically (horizontally) into n subrectangles
--
divideVertically, divideHorizontally :: [SizeHints] -> Rectangle -> [Rectangle]
divideVertically [] _ = [] -- there's a fold here, struggling to get out
divideVertically (hints:rest) (Rectangle sx sy sw sh) = (Rectangle sx sy w h) :
(divideVertically rest (Rectangle sx (sy + fromIntegral h) sw (sh - h)))
where (w, h) = addBorder $ applySizeHints hints $ substractBorder
(sw, sh `div` fromIntegral (1 + (length rest)))
divideHorizontally [] _ = []
divideHorizontally (hints:rest) (Rectangle sx sy sw sh) = (Rectangle sx sy w h) :
(divideHorizontally rest (Rectangle (sx + fromIntegral w) sy (sw - w) sh))
where (w, h) = addBorder $ applySizeHints hints $ substractBorder
(sw `div` fromIntegral (1 + (length rest)), sh)
-- Split the screen into two rectangles, using a rational to specify the ratio
splitHorizontally, splitVertically :: Rational -> Rectangle -> (Rectangle -> [Rectangle]) -> (Rectangle -> [Rectangle]) -> [Rectangle]
splitHorizontally f (Rectangle sx sy sw sh) left right = leftRects ++ rightRects
where leftw = floor $ fromIntegral sw * f
leftRects = left $ Rectangle sx sy leftw sh
rightx = (maximum . map rect_width) leftRects
rightRects = right $ Rectangle (sx + fromIntegral rightx) sy (sw - rightx) sh
splitVertically f (Rectangle sx sy sw sh) top bottom = topRects ++ bottomRects
where toph = floor $ fromIntegral sh * f
topRects = top $ Rectangle sx sy sw toph
bottomy = (maximum . map rect_height) topRects
bottomRects = bottom $ Rectangle sx (sy + fromIntegral bottomy) sw (sh - bottomy)

View File

@@ -1,57 +0,0 @@
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.LayoutHints
-- Copyright : (c) David Roundy <droundy@darcs.net>
-- License : BSD
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : portable
--
-- Make layouts respect size hints.
-----------------------------------------------------------------------------
module XMonadContrib.LayoutHints (
-- * usage
-- $usage
layoutHints,
LayoutHints) where
import Operations ( applySizeHints, D )
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras ( getWMNormalHints )
import {-#SOURCE#-} Config (borderWidth)
import XMonad hiding ( trace )
import XMonadContrib.LayoutModifier
-- $usage
-- > import XMonadContrib.LayoutHints
-- > layouts = [ layoutHints tiled , layoutHints $ Mirror tiled ]
-- %import XMonadContrib.LayoutHints
-- %layout , layoutHints $ tiled
-- %layout , layoutHints $ Mirror tiled
layoutHints :: (LayoutClass l a) => l a -> ModifiedLayout LayoutHints l a
layoutHints = ModifiedLayout LayoutHints
-- | Expand a size by the given multiple of the border width. The
-- multiple is most commonly 1 or -1.
adjBorders :: Dimension -> D -> D
adjBorders mult (w,h) = (w+2*mult*borderWidth, h+2*mult*borderWidth)
data LayoutHints a = LayoutHints deriving (Read, Show)
instance LayoutModifier LayoutHints Window where
modifierDescription _ = "Hinted"
redoLayout _ _ _ xs = do
xs' <- mapM applyHint xs
return (xs', Nothing)
where
applyHint (w,Rectangle a b c d) =
withDisplay $ \disp -> do
sh <- io $ getWMNormalHints disp w
let (c',d') = adjBorders 1 . applySizeHints sh . adjBorders (-1) $ (c,d)
return (w, Rectangle a b c' d')

View File

@@ -1,63 +0,0 @@
{-# -fglasgow-exts #-} -- For deriving Data/Typeable
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.LayoutModifier
-- Copyright : (c) David Roundy <droundy@darcs.net>
-- License : BSD
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : portable
--
-- A module for writing easy Layouts
-----------------------------------------------------------------------------
module XMonadContrib.LayoutModifier (
-- * Usage
-- $usage
LayoutModifier(..), ModifiedLayout(..)
) where
import Graphics.X11.Xlib ( Rectangle )
import XMonad
import StackSet ( Stack )
import Operations ( LayoutMessages(Hide, ReleaseResources) )
-- $usage
-- Use LayoutHelpers to help write easy Layouts.
class (Show (m a), Read (m a)) => LayoutModifier m a where
handleMess :: m a -> SomeMessage -> X (Maybe (m a))
handleMess m mess | Just Hide <- fromMessage mess = doUnhook
| Just ReleaseResources <- fromMessage mess = doUnhook
| otherwise = return Nothing
where doUnhook = do unhook m; return Nothing
redoLayout :: m a -> Rectangle -> Stack a -> [(a, Rectangle)]
-> X ([(a, Rectangle)], Maybe (m a))
redoLayout m _ _ wrs = do hook m; return (wrs, Nothing)
hook :: m a -> X ()
hook _ = return ()
unhook :: m a -> X ()
unhook _ = return ()
modifierDescription :: m a -> String
modifierDescription = show
instance (LayoutModifier m a, LayoutClass l a) => LayoutClass (ModifiedLayout m l) a where
doLayout (ModifiedLayout m l) r s =
do (ws, ml') <- doLayout l r s
(ws', mm') <- redoLayout m r s ws
let ml'' = case mm' of
Just m' -> Just $ (ModifiedLayout m') $ maybe l id ml'
Nothing -> ModifiedLayout m `fmap` ml'
return (ws', ml'')
handleMessage (ModifiedLayout m l) mess =
do ml' <- handleMessage l mess
mm' <- handleMess m mess
return $ case mm' of
Just m' -> Just $ (ModifiedLayout m') $ maybe l id ml'
Nothing -> (ModifiedLayout m) `fmap` ml'
description (ModifiedLayout m l) = modifierDescription m ++ " " ++ description l
data ModifiedLayout m l a = ModifiedLayout (m a) (l a) deriving ( Read, Show )

View File

@@ -1,51 +0,0 @@
{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.MagicFocus
-- Copyright : (c) Peter De Wachter <pdewacht@gmail.com>
-- License : BSD
--
-- Maintainer : Peter De Wachter <pdewacht@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- Automagically put the focused window in the master area.
-----------------------------------------------------------------------------
module XMonadContrib.MagicFocus
(-- * Usage
-- $usage
MagicFocus(MagicFocus)
) where
import Graphics.X11.Xlib
import XMonad
import StackSet
-- $usage
-- > import XMonadContrib.MagicFocus
-- > layouts = [ Layout $ MagicFocus tiled , Layout $ MagicFocus $ Mirror tiled ]
-- %import XMonadContrib.MagicFocus
-- %layout , Layout $ MagicFocus tiled
-- %layout , Layout $ MagicFocus $ Mirror tiled
data MagicFocus l a = MagicFocus (l a) deriving ( Show , Read )
instance (LayoutClass l Window) => LayoutClass (MagicFocus l) Window where
doLayout = magicFocus
magicFocus :: LayoutClass l Window => MagicFocus l Window -> Rectangle
-> Stack Window -> X ([(Window, Rectangle)], Maybe (MagicFocus l Window))
magicFocus (MagicFocus l) r s =
withWindowSet $ \wset -> do
(ws,nl) <- doLayout l r (swap s $ peek wset)
case nl of
Nothing -> return (ws, Nothing)
Just l' -> return (ws, Just $ MagicFocus l')
swap :: (Eq a) => Stack a -> Maybe a -> Stack a
swap (Stack f u d) focused | Just f == focused = Stack f [] (reverse u ++ d)
| otherwise = Stack f u d

View File

@@ -1,69 +0,0 @@
{-# OPTIONS_GHC -fglasgow-exts #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Magnifier
-- Copyright : (c) Peter De Wachter 2007
-- License : BSD-style (see xmonad/LICENSE)
--
-- Maintainer : Peter De Wachter <pdewacht@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- Screenshot : <http://caladan.rave.org/magnifier.png>
--
-- This layout hack increases the size of the window that has focus.
--
-----------------------------------------------------------------------------
module XMonadContrib.Magnifier (
-- * Usage
-- $usage
magnifier, magnifier') where
import Graphics.X11.Xlib (Window, Rectangle(..))
import XMonad
import StackSet
import XMonadContrib.LayoutHelpers
-- $usage
-- > import XMonadContrib.Magnifier
-- > layouts = [ magnifier tiled , magnifier $ mirror tiled ]
-- %import XMonadContrib.Magnifier
-- %layout , magnifier tiled
-- %layout , magnifier $ mirror tiled
-- | Increase the size of the window that has focus, unless it is the master window.
magnifier :: Layout Window -> Layout Window
magnifier = layoutModify (unlessMaster applyMagnifier) idModMod
-- | Increase the size of the window that has focus, even if it is the master window.
magnifier' :: Layout Window -> Layout Window
magnifier' = layoutModify applyMagnifier idModMod
unlessMaster :: ModDo Window -> ModDo Window
unlessMaster mainmod r s wrs = if null (up s) then return (wrs, Nothing)
else mainmod r s wrs
applyMagnifier :: ModDo Window
applyMagnifier r _ wrs = do focused <- withWindowSet (return . peek)
let mag (w,wr) ws | focused == Just w = ws ++ [(w, shrink r $ magnify wr)]
| otherwise = (w,wr) : ws
return (reverse $ foldr mag [] wrs, Nothing)
magnify :: Rectangle -> Rectangle
magnify (Rectangle x y w h) = Rectangle x' y' w' h'
where x' = x - fromIntegral (w' - w) `div` 2
y' = y - fromIntegral (h' - h) `div` 2
w' = round $ fromIntegral w * zoom
h' = round $ fromIntegral h * zoom
zoom = 1.5 :: Double
shrink :: Rectangle -> Rectangle -> Rectangle
shrink (Rectangle sx sy sw sh) (Rectangle x y w h) = Rectangle x' y' w' h'
where x' = max sx x
y' = max sy y
w' = min w (fromIntegral sx + sw - fromIntegral x')
h' = min h (fromIntegral sy + sh - fromIntegral y')

View File

@@ -1,102 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.ManageDocks
-- Copyright : (c) Joachim Breitner <mail@joachim-breitner.de>
-- License : BSD
--
-- Maintainer : Joachim Breitner <mail@joachim-breitner.de>
-- Stability : unstable
-- Portability : unportable
--
-- Makes xmonad detect windows with type DOCK and does not put them in
-- layouts. It also detects window with STRUT set and modifies the
-- gap accordingly.
--
-- Cheveats:
--
-- * Only acts on STRUT apps on creation, not if you move or close them
--
-- * To reset the gap, press Mod-b twice and restart xmonad (Mod-q)
-----------------------------------------------------------------------------
module XMonadContrib.ManageDocks (
-- * Usage
-- $usage
manageDocksHook
) where
import Control.Monad.Reader
import XMonad
import Operations
import qualified StackSet as W
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import Data.Word
-- $usage
-- Add the imports to your configuration file and add the mangeHook:
--
-- > import XMonadContrib.ManageDocks
--
-- > manageHook w _ _ _ = manageDocksHook w
--
-- and comment out the default `manageHook _ _ _ _ = return id` line.
-- %import XMonadContrib.ManageDocks
-- %def -- comment out default manageHook definition above if you uncomment this:
-- %def manageHook w _ _ _ = manageDocksHook w
-- |
-- Detects if the given window is of type DOCK and if so, reveals it, but does
-- not manage it. If the window has the STRUT property set, adjust the gap accordingly.
manageDocksHook :: Window -> X (WindowSet -> WindowSet)
manageDocksHook w = do
hasStrut <- getStrut w
maybe (return ()) setGap hasStrut
isDock <- checkDock w
if isDock then do
reveal w
return (W.delete w)
else do
return id
-- |
-- Checks if a window is a DOCK window
checkDock :: Window -> X (Bool)
checkDock w = do
a <- getAtom "_NET_WM_WINDOW_TYPE"
d <- getAtom "_NET_WM_WINDOW_TYPE_DOCK"
mbr <- getProp a w
case mbr of
Just [r] -> return (fromIntegral r == d)
_ -> return False
-- |
-- Gets the STRUT config, if present, in xmonad gap order
getStrut :: Window -> X (Maybe (Int, Int, Int, Int))
getStrut w = do
a <- getAtom "_NET_WM_STRUT"
mbr <- getProp a w
case mbr of
Just [l,r,t,b] -> return (Just (
fromIntegral t,
fromIntegral b,
fromIntegral l,
fromIntegral r))
_ -> return Nothing
-- |
-- Helper to read a property
getProp :: Atom -> Window -> X (Maybe [Word32])
getProp a w = withDisplay $ \dpy -> io $ getWindowProperty32 dpy a w
-- |
-- Modifies the gap, setting new max
setGap :: (Int, Int, Int, Int) -> X ()
setGap gap = modifyGap (\_ -> max4 gap)
-- |
-- Piecewise maximum of a 4-tuple of Ints
max4 :: (Int, Int, Int, Int) -> (Int, Int, Int, Int) -> (Int, Int, Int, Int)
max4 (a1,a2,a3,a4) (b1,b2,b3,b4) = (max a1 b1, max a2 b2, max a3 b3, max a4 b4)

View File

@@ -1,89 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.MetaModule
-- Copyright : (c) 2007 Spencer Janssen <sjanssen@cse.unl.edu>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Spencer Janssen <sjanssen@cse.unl.edu>
-- Stability : unstable
-- Portability : unportable
--
-- This is an artificial dependency on all the XMonadContrib.* modules. It is
-- intended to help xmonad hackers ensure that contrib modules build after API
-- changes.
--
-- Please add new modules to this list (in alphabetical order).
--
-----------------------------------------------------------------------------
module XMonadContrib.MetaModule () where
import XMonadContrib.Accordion ()
import XMonadContrib.Anneal ()
import XMonadContrib.Circle ()
import XMonadContrib.Commands ()
import XMonadContrib.Combo () -- broken under ghc head
import XMonadContrib.CopyWindow ()
import XMonadContrib.CycleWS ()
import XMonadContrib.DeManage ()
import XMonadContrib.DirectoryPrompt ()
import XMonadContrib.Dishes ()
import XMonadContrib.Dmenu ()
import XMonadContrib.DragPane ()
import XMonadContrib.DwmPromote ()
import XMonadContrib.DynamicLog ()
import XMonadContrib.DynamicWorkspaces ()
import XMonadContrib.Dzen ()
import XMonadContrib.EwmhDesktops ()
import XMonadContrib.FindEmptyWorkspace ()
import XMonadContrib.FlexibleResize ()
import XMonadContrib.FlexibleManipulate ()
import XMonadContrib.FloatKeys ()
import XMonadContrib.FocusNth ()
import XMonadContrib.Grid ()
import XMonadContrib.Invisible ()
-- import XMonadContrib.HintedTile ()
import XMonadContrib.LayoutModifier ()
import XMonadContrib.LayoutHints ()
import XMonadContrib.LayoutScreens ()
import XMonadContrib.MagicFocus ()
import XMonadContrib.ManageDocks ()
-- import XMonadContrib.Magnifier ()
import XMonadContrib.Maximize ()
-- import XMonadContrib.Mosaic ()
import XMonadContrib.MosaicAlt ()
import XMonadContrib.MouseGestures ()
import XMonadContrib.NamedWindows ()
import XMonadContrib.NoBorders ()
import XMonadContrib.ResizableTile ()
import XMonadContrib.Roledex ()
import XMonadContrib.RotSlaves ()
import XMonadContrib.RotView ()
import XMonadContrib.RunInXTerm ()
import XMonadContrib.SetWMName ()
import XMonadContrib.ShellPrompt ()
import XMonadContrib.SimpleDate ()
import XMonadContrib.SinkAll ()
import XMonadContrib.Spiral ()
import XMonadContrib.Square ()
import XMonadContrib.SshPrompt ()
import XMonadContrib.Submap ()
import XMonadContrib.SwapWorkspaces ()
import XMonadContrib.SwitchTrans ()
import XMonadContrib.Tabbed ()
import XMonadContrib.TagWindows ()
import XMonadContrib.ThreeColumns ()
import XMonadContrib.TwoPane ()
import XMonadContrib.ViewPrev ()
import XMonadContrib.XMonadPrompt ()
import XMonadContrib.XPrompt ()
import XMonadContrib.XPropManage ()
import XMonadContrib.XSelection ()
import XMonadContrib.XUtils ()
import XMonadContrib.Warp ()
import XMonadContrib.WindowBringer ()
import XMonadContrib.WindowNavigation ()
import XMonadContrib.WindowPrompt ()
import XMonadContrib.WmiiActions ()
import XMonadContrib.WorkspaceDir ()

407
Mosaic.hs
View File

@@ -1,407 +0,0 @@
{-# OPTIONS -fglasgow-exts #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Mosaic
-- Copyright : (c) David Roundy <droundy@darcs.net>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : unportable
--
-- This module defines a \"mosaic\" layout, which tries to give each window a
-- user-configurable relative area, while also trying to give them aspect
-- ratios configurable at run-time by the user.
--
-----------------------------------------------------------------------------
module XMonadContrib.Mosaic (
-- * Usage
-- $usage
mosaic, expandWindow, shrinkWindow, squareWindow, myclearWindow,
tallWindow, wideWindow, flexibleWindow,
getName, withNamedWindow ) where
import Control.Monad.State ( State, put, get, runState )
import System.Random ( StdGen, mkStdGen )
import Data.Ratio
import Graphics.X11.Xlib
import XMonad hiding ( trace )
import Operations ( full, Resize(Shrink, Expand) )
import qualified StackSet as W
import qualified Data.Map as M
import Data.List ( sort )
import Data.Typeable ( Typeable )
import Control.Monad ( mplus )
import XMonadContrib.NamedWindows
import XMonadContrib.Anneal
-- $usage
--
-- Key bindings:
--
-- You can use this module with the following in your Config.hs:
--
-- > import XMonadContrib.Mosaic
--
-- > layouts :: [Layout Window]
-- > layouts = [ mosaic 0.25 0.5 M.empty, full ]
--
-- In the key-bindings, do something like:
--
-- > , ((controlMask .|. modMask .|. shiftMask, xK_h), withNamedWindow (sendMessage . tallWindow))
-- > , ((controlMask .|. modMask .|. shiftMask, xK_l), withNamedWindow (sendMessage . wideWindow))
-- > , ((modMask .|. shiftMask, xK_h ), withNamedWindow (sendMessage . shrinkWindow))
-- > , ((modMask .|. shiftMask, xK_l ), withNamedWindow (sendMessage . expandWindow))
-- > , ((modMask .|. shiftMask, xK_s ), withNamedWindow (sendMessage . squareWindow))
-- > , ((modMask .|. shiftMask, xK_o ), withNamedWindow (sendMessage . myclearWindow))
-- > , ((controlMask .|. modMask .|. shiftMask, xK_o ), withNamedWindow (sendMessage . flexibleWindow))
--
-- %import XMonadContrib.Mosaic
-- %keybind , ((controlMask .|. modMask .|. shiftMask, xK_h), withNamedWindow (sendMessage . tallWindow))
-- %keybind , ((controlMask .|. modMask .|. shiftMask, xK_l), withNamedWindow (sendMessage . wideWindow))
-- %keybind , ((modMask .|. shiftMask, xK_h ), withNamedWindow (sendMessage . shrinkWindow))
-- %keybind , ((modMask .|. shiftMask, xK_l ), withNamedWindow (sendMessage . expandWindow))
-- %keybind , ((modMask .|. shiftMask, xK_s ), withNamedWindow (sendMessage . squareWindow))
-- %keybind , ((modMask .|. shiftMask, xK_o ), withNamedWindow (sendMessage . myclearWindow))
-- %keybind , ((controlMask .|. modMask .|. shiftMask, xK_o ), withNamedWindow (sendMessage . flexibleWindow))
-- %layout , mosaic 0.25 0.5 M.empty
data HandleWindow = ExpandWindow NamedWindow | ShrinkWindow NamedWindow
| SquareWindow NamedWindow | ClearWindow NamedWindow
| TallWindow NamedWindow | WideWindow NamedWindow
| FlexibleWindow NamedWindow
deriving ( Typeable, Eq )
instance Message HandleWindow
expandWindow, shrinkWindow, squareWindow, flexibleWindow, myclearWindow,tallWindow, wideWindow :: NamedWindow -> HandleWindow
expandWindow = ExpandWindow
shrinkWindow = ShrinkWindow
squareWindow = SquareWindow
flexibleWindow = FlexibleWindow
myclearWindow = ClearWindow
tallWindow = TallWindow
wideWindow = WideWindow
largeNumber :: Int
largeNumber = 50
defaultArea :: Double
defaultArea = 1
flexibility :: Double
flexibility = 0.1
mosaic :: Double -> Double -> M.Map NamedWindow [WindowHint] -> Layout Window
mosaic delta tileFrac hints = full { doLayout = \r -> mosaicL tileFrac hints r . W.integrate
, modifyLayout = return . mlayout }
where mlayout x = (m1 `fmap` fromMessage x) `mplus` (m2 `fmap` fromMessage x)
m1 Shrink = mosaic delta (tileFrac/(1+delta)) hints
m1 Expand = mosaic delta (tileFrac*(1+delta)) hints
m2 (ExpandWindow w) = mosaic delta tileFrac (multiply_area (1+delta) w hints)
m2 (ShrinkWindow w) = mosaic delta tileFrac (multiply_area (1/(1+ delta)) w hints)
m2 (SquareWindow w) = mosaic delta tileFrac (set_aspect_ratio 1 w hints)
m2 (FlexibleWindow w) = mosaic delta tileFrac (make_flexible w hints)
m2 (TallWindow w) = mosaic delta tileFrac (multiply_aspect (1/(1+delta)) w hints)
m2 (WideWindow w) = mosaic delta tileFrac (multiply_aspect (1+delta) w hints)
m2 (ClearWindow w) = mosaic delta tileFrac (M.delete w hints)
multiply_area :: Double -> NamedWindow
-> M.Map NamedWindow [WindowHint] -> M.Map NamedWindow [WindowHint]
multiply_area a = alterlist f where f [] = [RelArea (defaultArea*a)]
f (RelArea a':xs) = RelArea (a'*a) : xs
f (x:xs) = x : f xs
set_aspect_ratio :: Double -> NamedWindow
-> M.Map NamedWindow [WindowHint] -> M.Map NamedWindow [WindowHint]
set_aspect_ratio r = alterlist f where f [] = [AspectRatio r]
f (FlexibleAspectRatio _:x) = AspectRatio r:x
f (AspectRatio _:x) = AspectRatio r:x
f (x:xs) = x:f xs
make_flexible :: NamedWindow
-> M.Map NamedWindow [WindowHint] -> M.Map NamedWindow [WindowHint]
make_flexible = alterlist (map f) where f (AspectRatio r) = FlexibleAspectRatio r
f (FlexibleAspectRatio r) = AspectRatio r
f x = x
multiply_aspect :: Double -> NamedWindow
-> M.Map NamedWindow [WindowHint] -> M.Map NamedWindow [WindowHint]
multiply_aspect r = alterlist f where f [] = [FlexibleAspectRatio r]
f (AspectRatio r':x) = AspectRatio (r*r'):x
f (FlexibleAspectRatio r':x) = FlexibleAspectRatio (r*r'):x
f (x:xs) = x:f xs
findlist :: Ord k => k -> M.Map k [a] -> [a]
findlist = M.findWithDefault []
alterlist :: (Ord k, Ord a) => ([a] -> [a]) -> k -> M.Map k [a] -> M.Map k [a]
alterlist f k = M.alter f' k
where f' Nothing = f' (Just [])
f' (Just xs) = case f xs of
[] -> Nothing
xs' -> Just xs'
mosaicL :: Double -> M.Map NamedWindow [WindowHint]
-> Rectangle -> [Window] -> X ([(Window, Rectangle)],Maybe (Layout Window))
mosaicL _ _ _ [] = return ([], Nothing)
mosaicL f hints origRect origws
= do namedws <- mapM getName origws
let sortedws = reverse $ map the_value $ sort $ map (\w -> Rated (sumareas [w]) w) namedws
-- TODO: remove all this dead code
myv = runCountDown largeNumber $ mosaic_splits even_split origRect Vertical sortedws
myv2 = mc_mosaic sortedws Vertical
myh2 = mc_mosaic sortedws Horizontal
-- myv2 = maxL $ runCountDown largeNumber $
-- sequence $ replicate mediumNumber $
-- mosaic_splits one_split origRect Vertical sortedws
myh = runCountDown largeNumber $ mosaic_splits even_split origRect Horizontal sortedws
-- myh2 = maxL $ runCountDown largeNumber $
-- sequence $ replicate mediumNumber $
-- mosaic_splits one_split origRect Horizontal sortedws
return (map (\(nw,r)->(--trace ("rate1:"++ unlines [show nw,
-- show $ rate f meanarea (findlist nw hints) r,
-- show r,
-- show $ area r/meanarea,
-- show $ findlist nw hints]) $
unName nw,crop' (findlist nw hints) r)) $
flattenMosaic $ the_value $ maxL [myh,myv,myh2,myv2], Nothing)
where mosaic_splits _ _ _ [] = return $ Rated 0 $ M []
mosaic_splits _ r _ [w] = return $ Rated (rate f meanarea (findlist w hints) r) $ OM (w,r)
mosaic_splits spl r d ws = maxL `fmap` mapCD (spl r d) (init $ allsplits ws)
even_split :: Rectangle -> CutDirection -> [[NamedWindow]]
-> State CountDown (Rated Double (Mosaic (NamedWindow, Rectangle)))
even_split r d [ws] = even_split r d $ map (:[]) ws
even_split r d wss =
do let areas = map sumareas wss
let wsr_s :: [([NamedWindow], Rectangle)]
wsr_s = zip wss (partitionR d r areas)
submosaics <- mapM (\(ws',r') ->
mosaic_splits even_split r' (otherDirection d) ws') wsr_s
return $ fmap M $ catRated submosaics
{-
another_mosaic :: [NamedWindow] -> CutDirection
-> Rated Double (Mosaic (NamedWindow,Rectangle))
another_mosaic ws d = rate_mosaic ratew $
rect_mosaic origRect d $
zipML (example_mosaic ws) (map findarea ws)
-}
mc_mosaic :: [NamedWindow] -> CutDirection
-> Rated Double (Mosaic (NamedWindow,Rectangle))
mc_mosaic ws d = fmap (rect_mosaic origRect d) $
annealMax (zipML (example_mosaic ws) (map findarea ws))
(the_rating . rate_mosaic ratew . rect_mosaic origRect d )
changeMosaic
ratew :: (NamedWindow,Rectangle) -> Double
ratew (w,r) = rate f meanarea (findlist w hints) r
example_mosaic :: [NamedWindow] -> Mosaic NamedWindow
example_mosaic ws = M (map OM ws)
rect_mosaic :: Rectangle -> CutDirection -> Mosaic (a,Double) -> Mosaic (a,Rectangle)
rect_mosaic r _ (OM (w,_)) = OM (w,r)
rect_mosaic r d (M ws) = M $ zipWith (\w' r' -> rect_mosaic r' d' w') ws rs
where areas = map (sum . map snd . flattenMosaic) ws
rs = partitionR d r areas
d' = otherDirection d
rate_mosaic :: ((NamedWindow,Rectangle) -> Double)
-> Mosaic (NamedWindow,Rectangle) -> Rated Double (Mosaic (NamedWindow,Rectangle))
rate_mosaic r m = catRatedM $ fmap (\x -> Rated (r x) x) m
{-
one_split :: Rectangle -> CutDirection -> [[NamedWindow]]
-> State CountDown (Rated Double (Mosaic (NamedWindow, Rectangle)))
one_split r d [ws] = one_split r d $ map (:[]) ws
one_split r d wss =
do rnd <- mapM (const (fractional resolutionNumber)) [1..length wss]
let wsr_s :: [([NamedWindow], Rectangle)]
wsr_s = zip wss (partitionR d r rnd)
submosaics <- mapM (\(ws',r') ->
mosaic_splits even_split r' (otherDirection d) ws') wsr_s
return $ fmap M $ catRated submosaics
-}
partitionR :: CutDirection -> Rectangle -> [Double] -> [Rectangle]
partitionR _ _ [] = []
partitionR _ r [_] = [r]
partitionR d r (a:ars) = r1 : partitionR d r2 ars
where totarea = sum (a:ars)
(r1,r2) = split d (a/totarea) r
theareas = hints2area `fmap` hints
sumareas ws = sum $ map findarea ws
findarea :: NamedWindow -> Double
findarea w = M.findWithDefault 1 w theareas
meanarea = area origRect / fromIntegral (length origws)
maxL :: Ord a => [a] -> a
maxL [] = error "maxL on empty list"
maxL [a] = a
maxL (a:b:c) = maxL (max a b:c)
catRated :: Floating v => [Rated v a] -> Rated v [a]
catRated xs = Rated (product $ map the_rating xs) (map the_value xs)
catRatedM :: Floating v => Mosaic (Rated v a) -> Rated v (Mosaic a)
catRatedM (OM (Rated v x)) = Rated v (OM x)
catRatedM (M xs) = case catRated $ map catRatedM xs of Rated v xs' -> Rated v (M xs')
data CountDown = CD !StdGen !Int
tries_left :: State CountDown Int
tries_left = do CD _ n <- get
return (max 0 n)
mapCD :: (a -> State CountDown b) -> [a] -> State CountDown [b]
mapCD f xs = do n <- tries_left
let len = length xs
mapM (run_with_only ((n `div` len)+1) . f) $ take (n+1) xs
run_with_only :: Int -> State CountDown a -> State CountDown a
run_with_only limit j =
do CD g n <- get
let leftover = n - limit
if leftover < 0 then j
else do put $ CD g limit
x <- j
CD g' n' <- get
put $ CD g' (leftover + n')
return x
data WindowHint = RelArea Double
| AspectRatio Double
| FlexibleAspectRatio Double
deriving ( Show, Read, Eq, Ord )
fixedAspect :: [WindowHint] -> Bool
fixedAspect [] = False
fixedAspect (AspectRatio _:_) = True
fixedAspect (_:x) = fixedAspect x
rate :: Double -> Double -> [WindowHint] -> Rectangle -> Double
rate defaulta meanarea xs rr
| fixedAspect xs = (area (crop xs rr) / meanarea) ** weight
| otherwise = (area rr / meanarea)**(weight-flexibility)
* (area (crop (xs++[FlexibleAspectRatio defaulta]) rr) / meanarea)**flexibility
where weight = hints2area xs
crop :: [WindowHint] -> Rectangle -> Rectangle
crop (AspectRatio f:_) = cropit f
crop (FlexibleAspectRatio f:_) = cropit f
crop (_:hs) = crop hs
crop [] = id
crop' :: [WindowHint] -> Rectangle -> Rectangle
crop' (AspectRatio f:_) = cropit f
crop' (_:hs) = crop' hs
crop' [] = id
cropit :: Double -> Rectangle -> Rectangle
cropit f (Rectangle a b w h) | w -/- h > f = Rectangle a b (ceiling $ h -* f) h
| otherwise = Rectangle a b w (ceiling $ w -/ f)
hints2area :: [WindowHint] -> Double
hints2area [] = defaultArea
hints2area (RelArea r:_) = r
hints2area (_:x) = hints2area x
area :: Rectangle -> Double
area (Rectangle _ _ w h) = fromIntegral w * fromIntegral h
(-/-) :: (Integral a, Integral b) => a -> b -> Double
a -/- b = fromIntegral a / fromIntegral b
(-/) :: (Integral a) => a -> Double -> Double
a -/ b = fromIntegral a / b
(-*) :: (Integral a) => a -> Double -> Double
a -* b = fromIntegral a * b
split :: CutDirection -> Double -> Rectangle -> (Rectangle, Rectangle)
split Vertical frac (Rectangle sx sy sw sh) = (Rectangle sx sy sw h,
Rectangle sx (sy+fromIntegral h) sw (sh-h))
where h = floor $ fromIntegral sh * frac
split Horizontal frac (Rectangle sx sy sw sh) = (Rectangle sx sy w sh,
Rectangle (sx+fromIntegral w) sy (sw-w) sh)
where w = floor $ fromIntegral sw * frac
data CutDirection = Vertical | Horizontal
otherDirection :: CutDirection -> CutDirection
otherDirection Vertical = Horizontal
otherDirection Horizontal = Vertical
data Mosaic a = M [Mosaic a] | OM a
deriving ( Show )
instance Functor Mosaic where
fmap f (OM x) = OM (f x)
fmap f (M xs) = M (map (fmap f) xs)
zipMLwith :: (a -> b -> c) -> Mosaic a -> [b] -> Mosaic c
zipMLwith f (OM x) (y:_) = OM (f x y)
zipMLwith _ (OM _) [] = error "bad zipMLwith"
zipMLwith f (M xxs) yys = makeM $ foo xxs yys
where foo (x:xs) ys = zipMLwith f x (take (lengthM x) ys) :
foo xs (drop (lengthM x) ys)
foo [] _ = []
zipML :: Mosaic a -> [b] -> Mosaic (a,b)
zipML = zipMLwith (\a b -> (a,b))
lengthM :: Mosaic a -> Int
lengthM (OM _) = 1
lengthM (M x) = sum $ map lengthM x
changeMosaic :: Mosaic a -> [Mosaic a]
changeMosaic (OM _) = []
changeMosaic (M xs) = map makeM (concatenations xs) ++
map makeM (splits xs) ++
map M (tryAll changeMosaic xs)
tryAll :: (a -> [a]) -> [a] -> [[a]]
tryAll _ [] = []
tryAll f (x:xs) = map (:xs) (f x) ++ map (x:) (tryAll f xs)
splits :: [Mosaic a] -> [[Mosaic a]]
splits [] = []
splits (OM x:y) = map (OM x:) $ splits y
splits (M (x:y):z) = (x:makeM y:z) : map (makeM (x:y) :) (splits z)
splits (M []:x) = splits x
concatenations :: [Mosaic a] -> [[Mosaic a]]
concatenations (x:y:z) = (concatenateMosaic x y:z):(map (x:) $ concatenations (y:z))
concatenations _ = []
concatenateMosaic :: Mosaic a -> Mosaic a -> Mosaic a
concatenateMosaic (OM a) (OM b) = M [OM a, OM b]
concatenateMosaic (OM a) (M b) = M (OM a:b)
concatenateMosaic (M a) (OM b) = M (a++[OM b])
concatenateMosaic (M a) (M b) = M (a++b)
makeM :: [Mosaic a] -> Mosaic a
makeM [m] = m
makeM [] = error "makeM []"
makeM ms = M ms
flattenMosaic :: Mosaic a -> [a]
flattenMosaic (OM a) = [a]
flattenMosaic (M xs) = concatMap flattenMosaic xs
allsplits :: [a] -> [[[a]]]
allsplits [] = [[[]]]
allsplits [a] = [[[a]]]
allsplits (x:xs) = (map ([x]:) splitsrest) ++ (map (maphead (x:)) splitsrest)
where splitsrest = allsplits' xs
allsplits' :: [a] -> [[[a]]]
allsplits' [] = [[[]]]
allsplits' [a] = [[[a]]]
allsplits' (x:xs) = (map (maphead (x:)) splitsrest) ++ (map ([x]:) splitsrest)
where splitsrest = allsplits xs
maphead :: (a->a) -> [a] -> [a]
maphead f (x:xs) = f x : xs
maphead _ [] = []
runCountDown :: Int -> State CountDown a -> a
runCountDown n x = fst $ runState x (CD (mkStdGen n) n)

View File

@@ -1,116 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.MouseGestures
-- Copyright : (c) Lukas Mai
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : <l.mai@web.de>
-- Stability : unstable
-- Portability : unportable
--
-- Support for simple mouse gestures
--
-----------------------------------------------------------------------------
module XMonadContrib.MouseGestures (
-- * Usage
-- $usage
Direction(..),
mouseGesture
) where
import XMonad
import Operations
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import Control.Monad.Reader
import Data.IORef
import qualified Data.Map as M
import Data.Map (Map)
import System.IO
-- $usage
-- In your Config.hs:
--
-- > import XMonadContrib.MouseGestures
-- > ...
-- > mouseBindings = M.fromList $
-- > [ ...
-- > , ((modMask .|. shiftMask, button3), mouseGesture gestures)
-- > ]
-- > where
-- > gestures = M.fromList
-- > [ ([], focus)
-- > , ([U], \w -> focus w >> windows W.swapUp)
-- > , ([D], \w -> focus w >> windows W.swapDown)
-- > , ([R, D], \_ -> sendMessage NextLayout)
-- > ]
--
-- This is just an example, of course. You can use any mouse button and
-- gesture definitions you want.
data Direction = L | U | R | D
deriving (Eq, Ord, Show, Read, Enum, Bounded)
type Pos = (Position, Position)
delta :: Pos -> Pos -> Position
delta (ax, ay) (bx, by) = max (d ax bx) (d ay by)
where
d a b = abs (a - b)
dir :: Pos -> Pos -> Direction
dir (ax, ay) (bx, by) = trans . (/ pi) $ atan2 (fromIntegral $ ay - by) (fromIntegral $ bx - ax)
where
trans :: Double -> Direction
trans x
| rg (-3/4) (-1/4) x = D
| rg (-1/4) (1/4) x = R
| rg (1/4) (3/4) x = U
| otherwise = L
rg a z x = a <= x && x < z
debugging :: Int
debugging = 0
collect :: IORef (Pos, [(Direction, Pos, Pos)]) -> Position -> Position -> X ()
collect st nx ny = do
let np = (nx, ny)
stx@(op, ds) <- io $ readIORef st
when (debugging > 0) $ io $ putStrLn $ show "Mouse Gesture" ++ unwords (map show (extract stx)) ++ (if debugging > 1 then "; " ++ show op ++ "-" ++ show np else "")
case ds of
[]
| insignificant np op -> return ()
| otherwise -> io $ writeIORef st (op, [(dir op np, np, op)])
(d, zp, ap_) : ds'
| insignificant np zp -> return ()
| otherwise -> do
let
d' = dir zp np
ds''
| d == d' = (d, np, ap_) : ds'
| otherwise = (d', np, zp) : ds
io $ writeIORef st (op, ds'')
where
insignificant a b = delta a b < 10
extract :: (Pos, [(Direction, Pos, Pos)]) -> [Direction]
extract (_, xs) = reverse . map (\(x, _, _) -> x) $ xs
mouseGesture :: Map [Direction] (Window -> X ()) -> Window -> X ()
mouseGesture tbl win = withDisplay $ \dpy -> do
root <- asks theRoot
let win' = if win == none then root else win
acc <- io $ do
qp@(_, _, _, ix, iy, _, _, _) <- queryPointer dpy win'
when (debugging > 1) $ putStrLn $ show "queryPointer" ++ show qp
when (debugging > 1 && win' == none) $ putStrLn $ show "mouseGesture" ++ "zomg none"
newIORef ((fromIntegral ix, fromIntegral iy), [])
mouseDrag (collect acc) $ do
when (debugging > 0) $ io $ putStrLn $ show ""
gest <- io $ liftM extract $ readIORef acc
case M.lookup gest tbl of
Nothing -> return ()
Just f -> f win'

View File

@@ -1,99 +0,0 @@
{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.NoBorders
-- Copyright : (c) David Roundy <droundy@darcs.net>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : unportable
--
-- Make a given layout display without borders. This is useful for
-- full-screen or tabbed layouts, where you don't really want to waste a
-- couple of pixels of real estate just to inform yourself that the visible
-- window has focus.
--
-----------------------------------------------------------------------------
module XMonadContrib.NoBorders (
-- * Usage
-- $usage
noBorders,
smartBorders,
withBorder
) where
import Control.Monad.State ( gets )
import Graphics.X11.Xlib
import XMonad
import XMonadContrib.LayoutModifier
import {-# SOURCE #-} Config (borderWidth)
import qualified StackSet as W
import Data.List ((\\))
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.NoBorders
--
-- and modify the layouts to call noBorders on the layouts you want to lack
-- borders
--
-- > layouts = [ Layout (noBorders Full), ... ]
-- %import XMonadContrib.NoBorders
-- %layout -- prepend noBorders to default layouts above to remove their borders, like so:
-- %layout , noBorders Full
-- todo, use an InvisibleList.
data WithBorder a = WithBorder Dimension [a] deriving ( Read, Show )
instance LayoutModifier WithBorder Window where
modifierDescription (WithBorder 0 _) = "NoBorders"
modifierDescription (WithBorder n _) = "Borders " ++ show n
unhook (WithBorder _ s) = setBorders borderWidth s
redoLayout (WithBorder n s) _ _ wrs = do
setBorders borderWidth (s \\ ws)
setBorders n ws
return (wrs, Just $ WithBorder n ws)
where
ws = map fst wrs
noBorders :: LayoutClass l Window => l Window -> ModifiedLayout WithBorder l Window
noBorders = ModifiedLayout $ WithBorder 0 []
withBorder :: LayoutClass l a => Dimension -> l a -> ModifiedLayout WithBorder l a
withBorder b = ModifiedLayout $ WithBorder b []
setBorders :: Dimension -> [Window] -> X ()
setBorders bw ws = withDisplay $ \d -> mapM_ (\w -> io $ setWindowBorderWidth d w bw) ws
data SmartBorder a = SmartBorder [a] deriving (Read, Show)
instance LayoutModifier SmartBorder Window where
modifierDescription _ = "SmartBorder"
unhook (SmartBorder s) = setBorders borderWidth s
redoLayout (SmartBorder s) _ _ wrs = do
ss <- gets (W.screens . windowset)
if singleton ws && singleton ss
then do
setBorders borderWidth (s \\ ws)
setBorders 0 ws
return (wrs, Just $ SmartBorder ws)
else do
setBorders borderWidth s
return (wrs, Just $ SmartBorder [])
where
ws = map fst wrs
singleton = null . drop 1
smartBorders :: LayoutClass l a => l a -> ModifiedLayout SmartBorder l a
smartBorders = ModifiedLayout (SmartBorder [])

24
README
View File

@@ -1,20 +1,28 @@
3rd party xmonad extensions and contributions.
This repository can be overlayed on an xmonad repository.
Users may then import Haskell src from here, to extend their config
files.
Build and install through Cabal as for other Haskell packages:
runhaskell Setup configure --user --prefix=$HOME
runhaskell Setup build
runhaskell Setup install --user
(You may want to remove the --user flag when installing as root.)
scripts/ contains further external programs useful with xmonad.
Haskell code contributed to this repo should live under the
appropriate subdivision of the 'XMonad.' namespace (currently includes
Actions, Config, Hooks, Layout, Prompt, and Util). For example, to use
the Mosaic layout, one would import:
XMonadContrib.
name space. For example:
XMonadContrib.Mosaic
XMonad.Layout.Mosaic
------------------------------------------------------------------------
Code submitted to the contrib repo is licensed under the same license as
xmonad itself, with copyright held by the authors.
------------------------------------------------------------------------
Documentation for the extensions and configuration system is available
in Haddock form in the XMonad.Doc module and submodules.

View File

@@ -1,49 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.RotSlaves
-- Copyright : (c) Hans Philipp Annen <haphi@gmx.net>, Mischa Dieterle <der_m@freenet.de>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Hans Philipp Annen <haphi@gmx.net>
-- Stability : unstable
-- Portability : unportable
--
-- Rotate all windows except the master window
-- and keep the focus in place.
-----------------------------------------------------------------------------
module XMonadContrib.RotSlaves (
-- $usage
rotSlaves', rotSlavesUp, rotSlavesDown
) where
import StackSet
import Operations
import XMonad
-- $usage
--
-- To use this module, import it with:
--
-- > import XMonadContrib.RotSlaves
--
-- and add a keybinding:
--
-- > , ((modMask .|. shiftMask, xK_Tab ), rotSlavesUp)
--
--
-- This operation will rotate all windows except the master window, while the focus
-- stays where it is. It is useful together with the TwoPane-Layout (see XMonadContrib.TwoPane).
-- %import XMonadContrib.RotSlaves
-- %keybind , ((modMask .|. shiftMask, xK_Tab ), rotSlavesUp)
rotSlavesUp,rotSlavesDown :: X ()
rotSlavesUp = windows $ modify' (rotSlaves' (\l -> (tail l)++[head l]))
rotSlavesDown = windows $ modify' (rotSlaves' (\l -> [last l]++(init l)))
rotSlaves' :: ([a] -> [a]) -> Stack a -> Stack a
rotSlaves' _ s@(Stack _ [] []) = s
rotSlaves' f (Stack t [] rs) = Stack t [] (f rs) -- Master has focus
rotSlaves' f s@(Stack _ ls _ ) = Stack t' (reverse revls') rs' -- otherwise
where (master:ws) = integrate s
(revls',t':rs') = splitAt (length ls) (master:(f ws))

View File

@@ -1,53 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.RotView
-- Copyright : (c) David Roundy <droundy@darcs.net>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : unportable
--
-- Provides bindings to cycle through non-empty workspaces.
--
-----------------------------------------------------------------------------
module XMonadContrib.RotView (
-- * Usage
-- $usage
rotView
) where
import Control.Monad.State ( gets )
import Data.List ( sortBy, find )
import Data.Maybe ( isJust )
import Data.Ord ( comparing )
import XMonad
import StackSet hiding (filter)
import Operations
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.RotView
--
-- > , ((modMask .|. shiftMask, xK_Right), rotView True)
-- > , ((modMask .|. shiftMask, xK_Left), rotView False)
-- %import XMonadContrib.RotView
-- %keybind , ((modMask .|. shiftMask, xK_Right), rotView True)
-- %keybind , ((modMask .|. shiftMask, xK_Left), rotView False)
rotView :: Bool -> X ()
rotView forward = do
ws <- gets windowset
let currentTag = tag . workspace . current $ ws
sortWs = sortBy (comparing tag)
isNotEmpty = isJust . stack
sorted = sortWs (hidden ws)
pivoted = let (a,b) = span ((< currentTag) . tag) sorted in b ++ a
pivoted' | forward = pivoted
| otherwise = reverse pivoted
nextws = find isNotEmpty pivoted'
whenJust nextws (windows . view . tag)

View File

@@ -1,31 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.RunInXTerm
-- Copyright : (C) 2007 Andrea Rossato
-- License : BSD3
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : unportable
--
-- A simple module to launch commands in an X terminal
-- from XMonad
--
-----------------------------------------------------------------------------
module XMonadContrib.RunInXTerm (
-- * Usage
-- $usage
runInXTerm
) where
import XMonad
import System.Environment
-- $usage
-- For an example usage see "XMonadContrib.SshPrompt"
runInXTerm :: String -> X ()
runInXTerm com = do
c <- io $ catch (getEnv "XTERMCMD") (const $ return "xterm")
spawn ("exec " ++ c ++ " -e " ++ com)

3
Setup.lhs Normal file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env runhaskell
> import Distribution.Simple
> main = defaultMain

View File

@@ -1,109 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.ShellPrompt
-- Copyright : (C) 2007 Andrea Rossato
-- License : BSD3
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : unportable
--
-- A shell prompt for XMonad
--
-----------------------------------------------------------------------------
module XMonadContrib.ShellPrompt (
-- * Usage
-- $usage
shellPrompt
, getShellCompl
, split
) where
import XMonad
import XMonadContrib.XPrompt
import XMonadContrib.Dmenu
import Control.Monad
import Data.List
import Data.Set (toList, fromList)
import System.Directory
import System.IO
import System.Environment
-- $usage
--
-- 1. In Config.hs add:
--
-- > import XMonadContrib.XPrompt
-- > import XMonadContrib.ShellPrompt
--
-- 2. In your keybindings add something like:
--
-- > , ((modMask .|. controlMask, xK_x), shellPrompt defaultXPConfig)
--
-- %import XMonadContrib.XPrompt
-- %import XMonadContrib.ShellPrompt
-- %keybind , ((modMask .|. controlMask, xK_x), shellPrompt defaultXPConfig)
data Shell = Shell
instance XPrompt Shell where
showXPrompt Shell = "Run: "
shellPrompt :: XPConfig -> X ()
shellPrompt c = do
cmds <- io $ getCommands
mkXPrompt Shell c (getShellCompl cmds) spawn
getShellCompl :: [String] -> String -> IO [String]
getShellCompl cmds s | s == "" || last s == ' ' = return []
| otherwise = do
f <- fmap lines $ runProcessWithInput "/bin/bash" [] ("compgen -A file " ++ s ++ "\n")
return . map escape . uniqSort $ f ++ commandCompletionFunction cmds s
uniqSort :: Ord a => [a] -> [a]
uniqSort = toList . fromList
commandCompletionFunction :: [String] -> String -> [String]
commandCompletionFunction cmds str | '/' `elem` str = []
| otherwise = filter (isPrefixOf str) cmds
getCommands :: IO [String]
getCommands = do
p <- getEnv "PATH" `catch` const (return [])
let ds = split ':' p
fp d f = d ++ "/" ++ f
es <- forM ds $ \d -> do
exists <- doesDirectoryExist d
if exists
then getDirectoryContents d >>= filterM (isExecutable . fp d)
else return []
return . uniqSort . concat $ es
isExecutable :: FilePath ->IO Bool
isExecutable f = do
fe <- doesFileExist f
if fe
then fmap executable $ getPermissions f
else return False
split :: Eq a => a -> [a] -> [[a]]
split _ [] = []
split e l =
f : split e (rest ls)
where
(f,ls) = span (/=e) l
rest s | s == [] = []
| otherwise = tail s
escape :: String -> String
escape [] = ""
escape (' ':xs) = "\\ " ++ escape xs
escape (x:xs)
| isSpecialChar x = '\\' : x : escape xs
| otherwise = x : escape xs
isSpecialChar :: Char -> Bool
isSpecialChar = flip elem "\\@\"'#?$*()[]{};"

View File

@@ -1,194 +0,0 @@
{-# OPTIONS_GHC -fglasgow-exts #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.SwitchTrans
-- Copyright : (c) Lukas Mai
-- License : BSD-style (see LICENSE)
--
-- Maintainer : <l.mai@web.de>
-- Stability : unstable
-- Portability : unportable
--
--
-- Ordinary layout transformers are simple and easy to use but inflexible.
-- This module provides a more structured interface to them.
--
-- The basic idea is to have a base layout and a set of layout transformers,
-- of which at most one is active at any time. Enabling another transformer
-- first disables any currently active transformer; i.e. it works like
-- a group of radio buttons.
--
-- A side effect of this meta-layout is that layout transformers no longer
-- receive any messages; any message not handled by @SwitchTrans@ itself will
-- undo the current layout transformer, pass the message on to the base layout,
-- then reapply the transformer.
--
-- Another potential problem is that functions can't be (de-)serialized so this
-- layout will not preserve state across xmonad restarts.
--
-- Here's how you might use this in Config.hs:
--
-- > layouts =
-- > map (
-- > mkSwitch (M.fromList [
-- > ("full", const $ Layout $ noBorders Full)
-- > ]) .
-- > mkSwitch (M.fromList [
-- > ("mirror", Layout . Mirror)
-- > ])
-- > ) [ Layout tiled ]
--
-- (The @noBorders@ transformer is from "XMonadContrib.NoBorders".)
--
-- This example is probably overkill but it's very close to what I actually use.
-- Anyway, this layout behaves like the default @tiled@ layout, until you send it
-- @Enable@\/@Disable@\/@Toggle@ messages. From the definition of @keys@:
--
-- > ...
-- > , ((modMask, xK_f ), sendMessage $ Toggle "full")
-- > , ((modMask, xK_r ), sendMessage $ Toggle "mirror")
--
-- (You may want to use other keys. I don't use Xinerama so the default mod-r
-- binding is useless to me.)
--
-- After this, pressing @mod-f@ switches the current window to fullscreen mode.
-- Pressing @mod-f@ again switches it back. Similarly, @mod-r@ rotates the layout
-- by 90 degrees (and back). The nice thing is that your changes are kept:
-- Rotating first then changing the size of the master area then rotating back
-- does not undo the master area changes.
--
-- The reason I use two stacked @SwitchTrans@ transformers instead of @mkSwitch
-- (M.fromList [(\"full\", const $ Layout $ noBorders Full), (\"mirror\",
-- Layout . Mirror)])@ is that I use @mod-f@ to \"zoom in\" on interesting
-- windows, no matter what other layout transformers may be active. Having an
-- extra fullscreen mode on top of everything else means I can zoom in and out
-- without implicitly undoing \"normal\" layout transformers, like @Mirror@.
-- Remember, inside a @SwitchTrans@ there can be at most one active layout
-- transformer.
-----------------------------------------------------------------------------
module XMonadContrib.SwitchTrans (
Toggle(..),
Enable(..),
Disable(..),
mkSwitch
) where
import XMonad
import Operations
import qualified Data.Map as M
import Data.Map (Map)
--import System.IO
-- | Toggle the specified layout transformer.
data Toggle = Toggle String deriving (Eq, Typeable)
instance Message Toggle
-- | Enable the specified transformer.
data Enable = Enable String deriving (Eq, Typeable)
instance Message Enable
-- | Disable the specified transformer.
data Disable = Disable String deriving (Eq, Typeable)
instance Message Disable
data SwitchTrans a = SwitchTrans {
base :: Layout a,
currTag :: Maybe String,
currLayout :: Layout a,
currFilt :: Layout a -> Layout a,
filters :: Map String (Layout a -> Layout a)
}
instance Show (SwitchTrans a) where
show st = "SwitchTrans #<base: " ++ show (base st) ++ ", tag: " ++ show (currTag st) ++ ", layout: " ++ show (currLayout st) ++ ", ...>"
instance Read (SwitchTrans a) where
readsPrec _ _ = []
unLayout :: Layout a -> (forall l. (LayoutClass l a) => l a -> r) -> r
unLayout (Layout l) k = k l
acceptChange :: (LayoutClass l a) => SwitchTrans a -> ((l a -> SwitchTrans a) -> b -> c) -> X b -> X c
acceptChange st f action =
-- seriously, Dave, you need to stop this
fmap (f (\l -> st{ currLayout = Layout l})) action
instance LayoutClass SwitchTrans a where
description _ = "SwitchTrans"
doLayout st r s = currLayout st `unLayout` \l -> do
--io $ hPutStrLn stderr $ "[ST]{ " ++ show st
x{- @(_, w) -} <- acceptChange st (fmap . fmap) (doLayout l r s)
--io $ hPutStrLn stderr $ "[ST]} " ++ show w
return x
pureLayout st r s = currLayout st `unLayout` \l -> pureLayout l r s
handleMessage st m
| Just (Disable tag) <- fromMessage m
, M.member tag (filters st)
= provided (currTag st == Just tag) $ disable
| Just (Enable tag) <- fromMessage m
, Just alt <- M.lookup tag (filters st)
= provided (currTag st /= Just tag) $ enable tag alt
| Just (Toggle tag) <- fromMessage m
, Just alt <- M.lookup tag (filters st)
=
if (currTag st == Just tag) then
disable
else
enable tag alt
| Just ReleaseResources <- fromMessage m
= currLayout st `unLayout` \cl -> do
--io $ hPutStrLn stderr $ "[ST]~ " ++ show st
acceptChange st fmap (handleMessage cl m)
| Just Hide <- fromMessage m
= currLayout st `unLayout` \cl -> do
--io $ hPutStrLn stderr $ "[ST]< " ++ show st
x <- acceptChange st fmap (handleMessage cl m)
--io $ hPutStrLn stderr $ "[ST]> " ++ show x
return x
| otherwise = base st `unLayout` \b -> do
x <- handleMessage b m
case x of
Nothing -> return Nothing
Just b' -> currLayout st `unLayout` \cl -> do
handleMessage cl (SomeMessage ReleaseResources)
let b'' = Layout b'
return . Just $ st{ base = b'', currLayout = currFilt st b'' }
where
enable tag alt = currLayout st `unLayout` \cl -> do
--io $ hPutStrLn stderr $ "[ST]+ " ++ show cl ++ " -> " ++ show (alt (base st))
handleMessage cl (SomeMessage ReleaseResources)
return . Just $ st{
currTag = Just tag,
currFilt = alt,
currLayout = alt (base st) }
disable = currLayout st `unLayout` \cl -> do
--io $ hPutStrLn stderr $ "[ST]- " ++ show cl ++ " -> " ++ show (base st)
handleMessage cl (SomeMessage ReleaseResources)
return . Just $ st{
currTag = Nothing,
currFilt = id,
currLayout = base st }
-- | Take a transformer table and a base layout, and return a
-- SwitchTrans layout.
mkSwitch :: Map String (Layout a -> Layout a) -> Layout a -> Layout a
mkSwitch fs b = Layout st
where
st = SwitchTrans{
base = b,
currTag = Nothing,
currLayout = b,
currFilt = id,
filters = fs }
provided :: Bool -> X (Maybe a) -> X (Maybe a)
provided c x
| c = x
| otherwise = return Nothing

214
Tabbed.hs
View File

@@ -1,214 +0,0 @@
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Tabbed
-- Copyright : (c) 2007 David Roundy, Andrea Rossato
-- License : BSD-style (see xmonad/LICENSE)
--
-- Maintainer : droundy@darcs.net, andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : unportable
--
-- A tabbed layout for the Xmonad Window Manager
--
-----------------------------------------------------------------------------
module XMonadContrib.Tabbed (
-- * Usage:
-- $usage
tabbed
, shrinkText
, TConf (..), defaultTConf
) where
import Control.Monad.State ( gets )
import Control.Monad.Reader
import Data.Maybe
import Data.Bits
import Data.List
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import XMonad
import Operations
import qualified StackSet as W
import XMonadContrib.NamedWindows
import XMonadContrib.Invisible
import XMonadContrib.XUtils
-- $usage
-- You can use this module with the following in your configuration file:
--
-- > import XMonadContrib.Tabbed
--
-- > layouts :: [Layout Window]
-- > layouts = [ Layout tiled
-- > , Layout $ Mirror tiled
-- > , Layout Full
-- >
-- > -- Extension-provided layouts
-- > , Layout $ tabbed shrinkText defaultTConf
-- > ]
-- >
-- > , ... ]
--
-- You can also edit the default configuration options.
--
-- > myTabConfig = defaultTConf { inactiveBorderColor = "#FF0000"
-- > , activeTextColor = "#00FF00"}
--
-- and
--
-- > layouts = [ ...
-- > , Layout $ tabbed shrinkText myTabConfig ]
-- %import XMonadContrib.Tabbed
-- %layout , tabbed shrinkText defaultTConf
tabbed :: Shrinker -> TConf -> Tabbed a
tabbed s t = Tabbed (I Nothing) (I (Just s)) t
data TConf =
TConf { activeColor :: String
, inactiveColor :: String
, activeBorderColor :: String
, inactiveTextColor :: String
, inactiveBorderColor :: String
, activeTextColor :: String
, fontName :: String
, tabSize :: Int
} deriving (Show, Read)
defaultTConf :: TConf
defaultTConf =
TConf { activeColor = "#999999"
, inactiveColor = "#666666"
, activeBorderColor = "#FFFFFF"
, inactiveBorderColor = "#BBBBBB"
, activeTextColor = "#FFFFFF"
, inactiveTextColor = "#BFBFBF"
, fontName = "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"
, tabSize = 20
}
data TabState =
TabState { tabsWindows :: [(Window,Window)]
, scr :: Rectangle
, fontS :: FontStruct -- FontSet
}
data Tabbed a =
Tabbed (Invisible Maybe TabState) (Invisible Maybe Shrinker) TConf
deriving (Show, Read)
instance LayoutClass Tabbed Window where
doLayout (Tabbed ist ishr conf) = doLay ist ishr conf
handleMessage = handleMess
description _ = "Tabbed"
doLay :: Invisible Maybe TabState -> Invisible Maybe Shrinker -> TConf
-> Rectangle -> W.Stack Window -> X ([(Window, Rectangle)], Maybe (Tabbed Window))
doLay ist ishr c sc (W.Stack w [] []) = do
whenIJust ist $ \st -> mapM_ deleteWindow (map fst $ tabsWindows st)
return ([(w,sc)], Just $ Tabbed (I Nothing) ishr c)
doLay ist ishr conf sc@(Rectangle _ _ wid _) s@(W.Stack w _ _) = do
let ws = W.integrate s
width = wid `div` fromIntegral (length ws)
-- initialize state
st <- case ist of
(I Nothing ) -> initState conf sc ws
(I (Just ts)) -> if map snd (tabsWindows ts) == ws && scr ts == sc
then return ts
else do mapM_ deleteWindow (map fst $ tabsWindows ts)
tws <- createTabs conf sc ws
return (ts {scr = sc, tabsWindows = zip tws ws})
mapM_ showWindow $ map fst $ tabsWindows st
mapM_ (updateTab ishr conf (fontS st) width) $ tabsWindows st
return ([(w,shrink conf sc)], Just (Tabbed (I (Just st)) ishr conf))
handleMess :: Tabbed Window -> SomeMessage -> X (Maybe (Tabbed Window))
handleMess (Tabbed (I (Just st@(TabState {tabsWindows = tws}))) ishr conf) m
| Just e <- fromMessage m :: Maybe Event = handleEvent ishr conf st e >> return Nothing
| Just Hide == fromMessage m = mapM_ hideWindow (map fst tws) >> return Nothing
| Just ReleaseResources == fromMessage m = do mapM_ deleteWindow $ map fst tws
releaseFont (fontS st)
return $ Just $ Tabbed (I Nothing) (I Nothing) conf
handleMess _ _ = return Nothing
handleEvent :: Invisible Maybe Shrinker -> TConf -> TabState -> Event -> X ()
-- button press
handleEvent ishr conf (TabState {tabsWindows = tws, scr = screen, fontS = fs })
(ButtonEvent {ev_window = thisw, ev_subwindow = thisbw, ev_event_type = t })
| t == buttonPress, tl <- map fst tws, thisw `elem` tl || thisbw `elem` tl = do
case lookup thisw tws of
Just x -> do focus x
updateTab ishr conf fs width (thisw, x)
Nothing -> return ()
where width = rect_width screen `div` fromIntegral (length tws)
-- propertyNotify
handleEvent ishr conf (TabState {tabsWindows = tws, scr = screen, fontS = fs })
(PropertyEvent {ev_window = thisw })
| thisw `elem` (map snd tws) = do
let tabwin = (fst $ fromJust $ find ((== thisw) . snd) tws, thisw)
updateTab ishr conf fs width tabwin
where width = rect_width screen `div` fromIntegral (length tws)
-- expose
handleEvent ishr conf (TabState {tabsWindows = tws, scr = screen, fontS = fs })
(ExposeEvent {ev_window = thisw })
| thisw `elem` (map fst tws) = do
updateTab ishr conf fs width (thisw, fromJust $ lookup thisw tws)
where width = rect_width screen `div` fromIntegral (length tws)
handleEvent _ _ _ _ = return ()
initState :: TConf -> Rectangle -> [Window] -> X TabState
initState conf sc ws = do
fs <- initFont (fontName conf)
tws <- createTabs conf sc ws
return $ TabState (zip tws ws) sc fs
createTabs :: TConf -> Rectangle -> [Window] -> X [Window]
createTabs _ _ [] = return []
createTabs c (Rectangle x y wh ht) owl@(ow:ows) = do
let wid = wh `div` (fromIntegral $ length owl)
height = fromIntegral $ tabSize c
mask = Just (exposureMask .|. buttonPressMask)
d <- asks display
w <- createNewWindow (Rectangle x y wid height) mask (inactiveColor c)
io $ restackWindows d $ w : [ow]
ws <- createTabs c (Rectangle (x + fromIntegral wid) y (wh - wid) ht) ows
return (w:ws)
updateTab :: Invisible Maybe Shrinker -> TConf -> FontStruct -> Dimension -> (Window,Window) -> X ()
updateTab ishr c fs wh (tabw,ow) = do
nw <- getName ow
let ht = fromIntegral $ tabSize c :: Dimension
focusColor win ic ac = (maybe ic (\focusw -> if focusw == win
then ac else ic) . W.peek)
`fmap` gets windowset
(bc',borderc',tc') <- focusColor ow
(inactiveColor c, inactiveBorderColor c, inactiveTextColor c)
(activeColor c, activeBorderColor c, activeTextColor c)
let s = fromIMaybe shrinkText ishr
name = shrinkWhile s (\n -> textWidth fs n >
fromIntegral wh - fromIntegral (ht `div` 2)) (show nw)
paintAndWrite tabw fs wh ht 1 bc' borderc' tc' bc' AlignCenter name
shrink :: TConf -> Rectangle -> Rectangle
shrink c (Rectangle x y w h) =
Rectangle x (y + fromIntegral (tabSize c)) w (h - fromIntegral (tabSize c))
type Shrinker = String -> [String]
shrinkWhile :: Shrinker -> (String -> Bool) -> String -> String
shrinkWhile sh p x = sw $ sh x
where sw [n] = n
sw [] = ""
sw (n:ns) | p n = sw ns
| otherwise = n
shrinkText :: Shrinker
shrinkText "" = [""]
shrinkText cs = cs : shrinkText (init cs)

View File

@@ -1,26 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.ViewPrev
-- Copyright : (c) Nelson Elhage <nelhage@mit.edu>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Nelson Elhage <nelhage@mit.edu>
-- Stability : unstable
-- Portability : unportable
--
-- A module that implements a command to switch to the previously
-- viewed workspace
--
-----------------------------------------------------------------------------
module XMonadContrib.ViewPrev (
viewPrev
) where
import XMonad
import Operations
import qualified StackSet as W
viewPrev :: X ()
viewPrev = windows viewPrev'
where viewPrev' x = W.view (W.tag . head . W.hidden $ x) x

74
Warp.hs
View File

@@ -1,74 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Warp
-- Copyright : (c) daniel@wagner-home.com
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : daniel@wagner-home.com
-- Stability : unstable
-- Portability : unportable
--
-- This can be used to make a keybinding that warps the pointer to a given
-- window or screen.
--
-----------------------------------------------------------------------------
module XMonadContrib.Warp (
-- * Usage
-- $usage
warpToScreen,
warpToWindow
) where
import Data.Ratio
import Data.List
import Control.Monad.RWS
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import Operations
import XMonad
import StackSet as W
{- $usage
This can be used to make a keybinding that warps the pointer to a given
window or screen. For example, I've added the following keybindings to
my Config.hs:
> , ((modMask, xK_z ), warpToWindow (1%2) (1%2)) -- @@ Move pointer to currently focused window
>
>-- mod-ctrl-{w,e,r} @@ Move mouse pointer to screen 1, 2, or 3
>
> [((modMask .|. controlMask, key), warpToScreen sc (1%2) (1%2))
> | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]]
Note that warping to a particular screen may change the focus.
-}
-- %import XMonadContrib.Warp
-- %keybind , ((modMask, xK_z ), warpToWindow (1%2) (1%2)) -- @@ Move pointer to currently focused window
-- %keybindlist ++
-- %keybindlist -- mod-ctrl-{w,e,r} @@ Move mouse pointer to screen 1, 2, or 3
-- %keybindlist [((modMask .|. controlMask, key), warpToScreen sc (1%2) (1%2))
-- %keybindlist | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]]
fraction :: (Integral a, Integral b) => Rational -> a -> b
fraction f x = floor (f * fromIntegral x)
warp :: Window -> Position -> Position -> X ()
warp w x y = withDisplay $ \d -> io $ warpPointer d none w 0 0 0 0 x y
warpToWindow :: Rational -> Rational -> X ()
warpToWindow h v =
withDisplay $ \d ->
withFocused $ \w -> do
wa <- io $ getWindowAttributes d w
warp w (fraction h (wa_width wa)) (fraction v (wa_height wa))
warpToScreen :: ScreenId -> Rational -> Rational -> X ()
warpToScreen n h v = do
root <- asks theRoot
(StackSet {current = x, visible = xs}) <- gets windowset
whenJust (fmap (screenRect . W.screenDetail) . find ((n==) . W.screen) $ x : xs)
$ \r ->
warp root (rect_x r + fraction h (rect_width r))
(rect_y r + fraction v (rect_height r))

View File

@@ -1,84 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.WindowBringer
-- Copyright : Devin Mullins <me@twifkak.com>
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Devin Mullins <me@twifkak.com>
-- Stability : unstable
-- Portability : unportable
--
-- dmenu operations to bring windows to you, and bring you to windows.
-- That is to say, it pops up a dmenu with window names, in case you forgot
-- where you left your XChat.
--
-----------------------------------------------------------------------------
module XMonadContrib.WindowBringer (
-- * Usage
-- $usage
gotoMenu, bringMenu, windowMapWith
) where
import Control.Monad.State (gets)
import Data.Char (toLower)
import qualified Data.Map as M
import Graphics.X11.Xlib (Window())
import Operations (windows)
import qualified StackSet as W
import XMonad (X)
import qualified XMonad as X
import XMonadContrib.Dmenu (dmenuMap)
import XMonadContrib.NamedWindows (getName)
-- $usage
--
-- Place in your Config.hs:
--
-- > import XMonadContrib.WindowBringer
--
-- and in the keys definition:
--
-- > , ((modMask .|. shiftMask, xK_g ), gotoMenu)
-- > , ((modMask .|. shiftMask, xK_b ), bringMenu)
-- %import XMonadContrib.WindowBringer
-- %keybind , ((modMask .|. shiftMask, xK_g ), gotoMenu)
-- %keybind , ((modMask .|. shiftMask, xK_b ), bringMenu)
-- | Pops open a dmenu with window titles. Choose one, and you will be
-- taken to the corresponding workspace.
gotoMenu :: X ()
gotoMenu = workspaceMap >>= actionMenu (windows . W.greedyView)
where workspaceMap = windowMapWith (W.tag . fst)
-- | Pops open a dmenu with window titles. Choose one, and it will be
-- dragged, kicking and screaming, into your current workspace.
bringMenu :: X ()
bringMenu = windowMap >>= actionMenu (windows . bringWindow)
where windowMap = windowMapWith snd
bringWindow w ws = W.shiftWin (W.tag . W.workspace . W.current $ ws) w ws
-- | Calls dmenuMap to grab the appropriate element from the Map, and hands it
-- off to action if found.
actionMenu :: (a -> X ()) -> M.Map String a -> X ()
actionMenu action windowMap = dmenuMap windowMap >>= flip X.whenJust action
-- | Generates a Map from window name to <whatever you specify>. For use with
-- dmenuMap.
windowMapWith :: ((X.WindowSpace, Window) -> a) -> X (M.Map String a)
windowMapWith value = do -- TODO: extract the pure, creamy center.
ws <- gets X.windowset
M.fromList `fmap` concat `fmap` mapM keyValuePairs (W.workspaces ws)
where keyValuePairs ws = mapM (keyValuePair ws) $ W.integrate' (W.stack ws)
keyValuePair ws w = flip (,) (value (ws, w)) `fmap` decorateName ws w
-- | Returns the window name as will be listed in dmenu.
-- Lowercased, for your convenience (since dmenu is case-sensitive).
-- Tagged with the workspace ID, to guarantee uniqueness, and to let the user
-- know where he's going.
decorateName :: X.WindowSpace -> Window -> X String
decorateName ws w = do
name <- fmap (map toLower . show) $ getName w
return $ name ++ " [" ++ W.tag ws ++ "]"

View File

@@ -1,177 +0,0 @@
{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable
{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeSynonymInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.WorkspaceDir
-- Copyright : (c) 2007 David Roundy <droundy@darcs.net>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : unportable
--
-- WindowNavigation is an extension to allow easy navigation of a workspace.
--
-----------------------------------------------------------------------------
module XMonadContrib.WindowNavigation (
-- * Usage
-- $usage
windowNavigation,
Navigate(..), Direction(..),
WNConfig (..), defaultWNConfig
) where
import Graphics.X11.Xlib ( Rectangle(..), Window, Pixel, setWindowBorder )
import Control.Monad ( when )
import Control.Monad.Reader ( ask )
import Data.List ( nub, sortBy, (\\) )
import XMonad
import qualified StackSet as W
import Operations ( windows, focus, LayoutMessages(..) )
import XMonadContrib.LayoutModifier
import XMonadContrib.Invisible
import XMonadContrib.XUtils
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.WindowNavigation
-- >
-- > layoutHook = Layout $ windowNavigation defaultWNConfig $ Select ...
--
-- In keybindings:
--
-- > , ((modMask, xK_Right), sendMessage $ Go R)
-- > , ((modMask, xK_Left), sendMessage $ Go L)
-- > , ((modMask, xK_Up), sendMessage $ Go U)
-- > , ((modMask, xK_Down), sendMessage $ Go D)
-- %import XMonadContrib.WindowNavigation
-- %keybind , ((modMask, xK_Right), sendMessage $ Go R)
-- %keybind , ((modMask, xK_Left), sendMessage $ Go L)
-- %keybind , ((modMask, xK_Up), sendMessage $ Go U)
-- %keybind , ((modMask, xK_Down), sendMessage $ Go D)
-- %keybind , ((modMask .|. controlMask, xK_Right), sendMessage $ Swap R)
-- %keybind , ((modMask .|. controlMask, xK_Left), sendMessage $ Swap L)
-- %keybind , ((modMask .|. controlMask, xK_Up), sendMessage $ Swap U)
-- %keybind , ((modMask .|. controlMask, xK_Down), sendMessage $ Swap D)
-- %layout -- include 'windowNavigation' in layoutHook definition above.
-- %layout -- just before the list, like the following (don't uncomment next line):
-- %layout -- layoutHook = Layout $ windowNavigation defaultWNConfig $ ...
data Navigate = Go Direction | Swap Direction deriving ( Read, Show, Typeable )
data Direction = U | D | R | L deriving ( Read, Show, Eq )
instance Message Navigate
data WNConfig =
WNC { showNavigable :: Bool
, upColor :: String
, downColor :: String
, leftColor :: String
, rightColor :: String
} deriving (Show, Read)
defaultWNConfig :: WNConfig
defaultWNConfig = WNC True "#0000FF" "#00FFFF" "#FF0000" "#FF00FF"
data NavigationState a = NS Point [(a,Rectangle)]
data WindowNavigation a = WindowNavigation WNConfig (Invisible Maybe (NavigationState a)) deriving ( Read, Show )
windowNavigation :: LayoutClass l a => WNConfig -> l a -> ModifiedLayout WindowNavigation l a
windowNavigation conf = ModifiedLayout (WindowNavigation conf (I Nothing))
instance LayoutModifier WindowNavigation Window where
redoLayout (WindowNavigation conf (I state)) rscr s wrs =
do XConf { normalBorder = nbc } <- ask
[uc,dc,lc,rc] <- mapM stringToPixel [upColor conf, downColor conf, leftColor conf, rightColor conf]
let dirc U = uc
dirc D = dc
dirc L = lc
dirc R = rc
let w = W.focus s
r = case filter ((==w).fst) wrs of ((_,x):_) -> x
[] -> rscr
pt = case state of Just (NS ptold _) | ptold `inrect` r -> ptold
_ -> center r
wrs' = filter ((/=w) . fst) wrs
wnavigable = nub $ concatMap
(\d -> truncHead $ sortby d $ filter (inr d pt . snd) wrs') [U,D,R,L]
wnavigablec = nub $ concatMap
(\d -> map (\(win,_) -> (win,dirc d)) $
truncHead $ sortby d $ filter (inr d pt . snd) wrs') [U,D,R,L]
wothers = case state of Just (NS _ wo) -> map fst wo
_ -> []
mapM_ (sc nbc) (wothers \\ map fst wnavigable)
when (showNavigable conf) $ mapM_ (\(win,c) -> sc c win) wnavigablec
return (wrs, Just $ WindowNavigation conf $ I $ Just $ NS pt wnavigable)
handleMess (WindowNavigation conf (I (Just (NS pt wrs)))) m
| Just (Go d) <- fromMessage m =
case sortby d $ filter (inr d pt . snd) wrs of
[] -> return Nothing
((w,r):_) -> do focus w
return $ Just $ WindowNavigation conf $ I $ Just $
NS (centerd d pt r) wrs
| Just (Swap d) <- fromMessage m =
case sortby d $ filter (inr d pt . snd) wrs of
[] -> return Nothing
((w,_):_) -> do let swap st = unint (W.focus st) $ map (swapw (W.focus st)) $ W.integrate st
swapw y x | x == w = y
| x == y = w
| otherwise = x
unint f xs = case span (/= f) xs of
(u,_:dn) -> W.Stack { W.focus = f
, W.up = reverse u
, W.down = dn }
_ -> W.Stack { W.focus = f
, W.down = xs
, W.up = [] }
windows $ W.modify' swap
return Nothing
| Just Hide <- fromMessage m =
do XConf { normalBorder = nbc } <- ask
mapM_ (sc nbc . fst) wrs
return $ Just $ WindowNavigation conf $ I $ Just $ NS pt []
| Just ReleaseResources <- fromMessage m =
handleMess (WindowNavigation conf (I $ Just (NS pt wrs))) (SomeMessage Hide)
handleMess _ _ = return Nothing
truncHead :: [a] -> [a]
truncHead (x:_) = [x]
truncHead [] = []
sc :: Pixel -> Window -> X ()
sc c win = withDisplay $ \dpy -> io $ setWindowBorder dpy win c
center :: Rectangle -> Point
center (Rectangle x y w h) = P (fromIntegral x + fromIntegral w/2) (fromIntegral y + fromIntegral h/2)
centerd :: Direction -> Point -> Rectangle -> Point
centerd d (P xx yy) (Rectangle x y w h) | d == U || d == D = P xx (fromIntegral y + fromIntegral h/2)
| otherwise = P (fromIntegral x + fromIntegral w/2) yy
inr :: Direction -> Point -> Rectangle -> Bool
inr D (P x y) (Rectangle l yr w h) = x >= fromIntegral l && x < fromIntegral l + fromIntegral w &&
y < fromIntegral yr + fromIntegral h
inr U (P x y) (Rectangle l yr w _) = x >= fromIntegral l && x < fromIntegral l + fromIntegral w &&
y > fromIntegral yr
inr R (P a x) (Rectangle b l _ w) = x >= fromIntegral l && x < fromIntegral l + fromIntegral w &&
a < fromIntegral b
inr L (P a x) (Rectangle b l c w) = x >= fromIntegral l && x < fromIntegral l + fromIntegral w &&
a > fromIntegral b + fromIntegral c
inrect :: Point -> Rectangle -> Bool
inrect (P x y) (Rectangle a b w h) = x > fromIntegral a && x < fromIntegral a + fromIntegral w &&
y > fromIntegral b && y < fromIntegral b + fromIntegral h
sortby :: Direction -> [(a,Rectangle)] -> [(a,Rectangle)]
sortby U = sortBy (\(_,Rectangle _ y _ _) (_,Rectangle _ y' _ _) -> compare y' y)
sortby D = sortBy (\(_,Rectangle _ y _ _) (_,Rectangle _ y' _ _) -> compare y y')
sortby R = sortBy (\(_,Rectangle x _ _ _) (_,Rectangle x' _ _ _) -> compare x x')
sortby L = sortBy (\(_,Rectangle x _ _ _) (_,Rectangle x' _ _ _) -> compare x' x)
data Point = P Double Double

View File

@@ -1,89 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.WindowPrompt
-- Copyright : Devin Mullins <me@twifkak.com>
-- Andrea Rossato <andrea.rossato@unibz.it>
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Devin Mullins <me@twifkak.com>
-- Andrea Rossato <andrea.rossato@unibz.it>
-- Stability : unstable
-- Portability : unportable
--
-- xprompt operations to bring windows to you, and bring you to windows.
--
-----------------------------------------------------------------------------
module XMonadContrib.WindowPrompt
(
-- * Usage
-- $usage
windowPromptGoto,
windowPromptBring
) where
import qualified Data.Map as M
import Data.List
import qualified StackSet as W
import XMonad
import Operations (windows)
import XMonadContrib.XPrompt
import XMonadContrib.WindowBringer
-- $usage
-- WindowPrompt brings windows to you and you to windows.
-- That is to say, it pops up a prompt with window names, in case you forgot
-- where you left your XChat.
--
-- Place in your Config.hs:
--
-- > import XMonadContrib.XPrompt
-- > import XMonadContrib.WindowPrompt
--
-- and in the keys definition:
--
-- > , ((modMask .|. shiftMask, xK_g ), windowPromptGoto defaultXPConfig)
-- > , ((modMask .|. shiftMask, xK_b ), windowPromptBring defaultXPConfig)
-- %import XMonadContrib.XPrompt
-- %import XMonadContrib.WindowPrompt
-- %keybind , ((modMask .|. shiftMask, xK_g ), windowPromptGoto defaultXPConfig)
-- %keybind , ((modMask .|. shiftMask, xK_b ), windowPromptBring defaultXPConfig)
data WindowPrompt = Goto | Bring
instance XPrompt WindowPrompt where
showXPrompt Goto = "Go to window: "
showXPrompt Bring = "Bring me here: "
windowPromptGoto, windowPromptBring :: XPConfig -> X ()
windowPromptGoto c = doPrompt Goto c
windowPromptBring c = doPrompt Bring c
-- | Pops open a prompt with window titles. Choose one, and you will be
-- taken to the corresponding workspace.
doPrompt :: WindowPrompt -> XPConfig -> X ()
doPrompt t c = do
a <- case t of
Goto -> return . gotoAction =<< windowMapWith (W.tag . fst)
Bring -> return . bringAction =<< windowMapWith snd
wm <- windowMapWith id
mkXPrompt t c (compList wm) a
where
winAction a m = flip whenJust (windows . a) . flip M.lookup m . unescape
gotoAction = winAction W.greedyView
bringAction = winAction bringWindow
bringWindow w ws = W.shiftWin (W.tag . W.workspace . W.current $ ws) w ws
compList m s = return . filter (isPrefixOf s) . map (escape . fst) . M.toList $ m
escape [] = []
escape (' ':xs) = "\\ " ++ escape xs
escape (x :xs) = x : escape xs
unescape [] = []
unescape ('\\':' ':xs) = ' ' : unescape xs
unescape (x:xs) = x : unescape xs

View File

@@ -1,101 +0,0 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.WmiiActions
-- Copyright : (c) Juraj Hercek <juhe_xmonad@hck.sk>
-- License : BSD3
--
-- Maintainer : Juraj Hercek <juhe_xmonad@hck.sk>
-- Stability : unstable
-- Portability : unportable
--
-- Provides `actions' as known from Wmii window manager (
-- <http://wmii.suckless.org>). It also provides slightly better interface for
-- running dmenu on xinerama screens. If you want to use xinerama functions,
-- you have to apply following patch (see Dmenu.hs extension):
-- <http://www.jcreigh.com/dmenu/dmenu-3.2-xinerama.patch>. Don't forget to
-- recompile dmenu afterwards ;-).
-----------------------------------------------------------------------------
module XMonadContrib.WmiiActions (
-- * Usage
-- $usage
wmiiActions
, wmiiActionsXinerama
, executables
, executablesXinerama
) where
import XMonad
import XMonadContrib.Dmenu (dmenu, dmenuXinerama, runProcessWithInput)
import Control.Monad (filterM, liftM, liftM2)
import System.Directory (getDirectoryContents, doesFileExist, getPermissions, executable)
-- $usage
--
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.WmiiActions
--
-- and add following to the list of keyboard bindings:
--
-- > ,((modMask, xK_a), wmiiActions "/home/joe/.wmii-3.5/")
--
-- or, if you are using xinerama, you can use
--
-- > ,((modMask, xK_a), wmiiActionsXinerama "/home/joe/.wmii-3.5/")
--
-- however, make sure you have also xinerama build of dmenu (for more
-- information see "XMonadContrib.Dmenu" extension).
-- | The 'wmiiActions' function takes the file path as a first argument and
-- executes dmenu with all executables found in the provided path.
wmiiActions :: FilePath -> X ()
wmiiActions path =
wmiiActionsDmenu path dmenu
-- | The 'wmiiActionsXinerama' does the same as 'wmiiActions', but it shows
-- dmenu only on workspace which currently owns focus.
wmiiActionsXinerama :: FilePath -> X ()
wmiiActionsXinerama path =
wmiiActionsDmenu path dmenuXinerama
wmiiActionsDmenu :: FilePath -> ([String] -> X String) -> X ()
wmiiActionsDmenu path dmenuBrand =
let path' = path ++ "/" in
getExecutableFileList path' >>= dmenuBrand >>= spawn . (path' ++)
getExecutableFileList :: FilePath -> X [String]
getExecutableFileList path =
io $ getDirectoryContents path >>=
filterM (\x -> let x' = path ++ x in
liftM2 (&&)
(doesFileExist x')
(liftM executable (getPermissions x')))
{-
getExecutableFileList :: FilePath -> X [String]
getExecutableFileList path =
io $ getDirectoryContents path >>=
filterM (doesFileExist . (path ++)) >>=
filterM (liftM executable . getPermissions . (path ++))
-}
-- | The 'executables' function runs dmenu_path script providing list of
-- executable files accessible from $PATH variable.
executables :: X ()
executables = executablesDmenu dmenu
-- | The 'executablesXinerama' function does the same as 'executables' function
-- but on workspace which currently owns focus.
executablesXinerama :: X ()
executablesXinerama = executablesDmenu dmenuXinerama
executablesDmenu :: ([String] -> X String) -> X ()
executablesDmenu dmenuBrand =
getExecutablesList >>= dmenuBrand >>= spawn
getExecutablesList :: X [String]
getExecutablesList =
io $ liftM lines $ runProcessWithInput "dmenu_path" [] ""

View File

@@ -1,78 +0,0 @@
{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.WorkspaceDir
-- Copyright : (c) 2007 David Roundy <droundy@darcs.net>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : David Roundy <droundy@darcs.net>
-- Stability : unstable
-- Portability : unportable
--
-- WorkspaceDir is an extension to set the current directory in a workspace.
--
-- Actually, it sets the current directory in a layout, since there's no way I
-- know of to attach a behavior to a workspace. This means that any terminals
-- (or other programs) pulled up in that workspace (with that layout) will
-- execute in that working directory. Sort of handy, I think.
--
-- Requires the 'directory' package
--
-----------------------------------------------------------------------------
module XMonadContrib.WorkspaceDir (
-- * Usage
-- $usage
workspaceDir,
changeDir
) where
import System.Directory ( setCurrentDirectory )
import XMonad
import Operations ( sendMessage )
import XMonadContrib.Dmenu ( runProcessWithInput )
import XMonadContrib.XPrompt ( XPConfig )
import XMonadContrib.DirectoryPrompt ( directoryPrompt )
import XMonadContrib.LayoutModifier
-- $usage
-- You can use this module with the following in your Config.hs file:
--
-- > import XMonadContrib.WorkspaceDir
-- >
-- > layouts = map (workspaceDir "~") [ tiled, ... ]
--
-- In keybindings:
--
-- > , ((modMask .|. shiftMask, xK_x ), changeDir defaultXPConfig)
-- %import XMonadContrib.WorkspaceDir
-- %keybind , ((modMask .|. shiftMask, xK_x ), changeDir defaultXPConfig)
-- %layout -- prepend 'map (workspaceDir "~")' to layouts definition above,
-- %layout -- just before the list, like the following (don't uncomment next line):
-- %layout -- layouts = map (workspaceDir "~") [ tiled, ... ]
data Chdir = Chdir String deriving ( Typeable )
instance Message Chdir
data WorkspaceDir a = WorkspaceDir String deriving ( Read, Show )
instance LayoutModifier WorkspaceDir a where
hook (WorkspaceDir s) = scd s
handleMess (WorkspaceDir _) m = return $ do Chdir wd <- fromMessage m
Just (WorkspaceDir wd)
workspaceDir :: LayoutClass l a => String -> l a
-> ModifiedLayout WorkspaceDir l a
workspaceDir s = ModifiedLayout (WorkspaceDir s)
scd :: String -> X ()
scd x = do x' <- io (runProcessWithInput "bash" [] ("echo -n " ++ x) `catch` \_ -> return x)
catchIO $ setCurrentDirectory x'
changeDir :: XPConfig -> X ()
changeDir c = directoryPrompt c "Set working directory: " (sendMessage . Chdir)

120
XMonad/Actions/Commands.hs Normal file
View File

@@ -0,0 +1,120 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.Commands
-- Copyright : (c) David Glasser 2007
-- License : BSD3
--
-- Maintainer : glasser@mit.edu
-- Stability : stable
-- Portability : portable
--
-- Allows you to run internal xmonad commands (X () actions) using
-- a dmenu menu in addition to key bindings. Requires dmenu and
-- the Dmenu XMonad.Actions module.
--
-----------------------------------------------------------------------------
module XMonad.Actions.Commands (
-- * Usage
-- $usage
commandMap,
runCommand,
runCommand',
workspaceCommands,
screenCommands,
defaultCommands
) where
import XMonad
import XMonad.StackSet hiding (workspaces)
import XMonad.Util.Dmenu (dmenu)
import qualified Data.Map as M
import System.Exit
import Data.Maybe
-- $usage
--
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Actions.Commands
--
-- Then add a keybinding to the runCommand action:
--
-- > , ((modMask x .|. controlMask, xK_y), commands >>= runCommand)
--
-- and define the list of commands you want to use:
--
-- > commands :: X [(String, X ())]
-- > commands = defaultCommands
--
-- Whatever key you bound to will now cause a popup menu of internal
-- xmonad commands to appear. You can change the commands by changing
-- the contents of the list returned by 'commands'. (If you like it
-- enough, you may even want to get rid of many of your other key
-- bindings!)
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Create a 'Data.Map.Map' from @String@s to xmonad actions from a
-- list of pairs.
commandMap :: [(String, X ())] -> M.Map String (X ())
commandMap c = M.fromList c
-- | Generate a list of commands to switch to\/send windows to workspaces.
workspaceCommands :: X [(String, X ())]
workspaceCommands = asks (workspaces . config) >>= \spaces -> return
[((m ++ show i), windows $ f i)
| i <- spaces
, (f, m) <- [(view, "view"), (shift, "shift")] ]
-- | Generate a list of commands dealing with multiple screens.
screenCommands :: [(String, X ())]
screenCommands = [((m ++ show sc), screenWorkspace (fromIntegral sc) >>= flip whenJust (windows . f))
| sc <- [0, 1]::[Int] -- TODO: adapt to screen changes
, (f, m) <- [(view, "screen"), (shift, "screen-to-")]
]
-- | A nice pre-defined list of commands.
defaultCommands :: X [(String, X ())]
defaultCommands = do
wscmds <- workspaceCommands
return $ wscmds ++ screenCommands ++ otherCommands
where
sr = broadcastMessage ReleaseResources
otherCommands =
[ ("shrink" , sendMessage Shrink )
, ("expand" , sendMessage Expand )
, ("next-layout" , sendMessage NextLayout )
, ("default-layout" , asks (layoutHook . config) >>= setLayout )
, ("restart-wm" , sr >> restart "xmonad" True )
, ("restart-wm-no-resume", sr >> restart "xmonad" False )
, ("xterm" , spawn =<< asks (terminal . config) )
, ("run" , spawn "exe=`dmenu_path | dmenu -b` && exec $exe" )
, ("kill" , kill )
, ("refresh" , refresh )
, ("focus-up" , windows $ focusUp )
, ("focus-down" , windows $ focusDown )
, ("swap-up" , windows $ swapUp )
, ("swap-down" , windows $ swapDown )
, ("swap-master" , windows $ swapMaster )
, ("sink" , withFocused $ windows . sink )
, ("quit-wm" , io $ exitWith ExitSuccess )
]
-- | Given a list of command\/action pairs, prompt the user to choose a
-- command and return the corresponding action.
runCommand :: [(String, X ())] -> X ()
runCommand cl = do
let m = commandMap cl
choice <- dmenu (M.keys m)
fromMaybe (return ()) (M.lookup choice m)
-- | Given the name of a command from 'defaultCommands', return the
-- corresponding action (or the null action if the command is not
-- found).
runCommand' :: String -> X ()
runCommand' c = do
m <- fmap commandMap defaultCommands
fromMaybe (return ()) (M.lookup c m)

View File

@@ -0,0 +1,57 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.ConstrainedResize
-- Copyright : (c) Dougal Stanton
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : <dougal@dougalstanton.net>
-- Stability : unstable
-- Portability : unportable
--
-- Lets you constrain the aspect ratio of a floating
-- window (by, say, holding shift while you resize).
--
-- Useful for making a nice circular XClock window.
--
-----------------------------------------------------------------------------
module XMonad.Actions.ConstrainedResize (
-- * Usage
-- $usage
XMonad.Actions.ConstrainedResize.mouseResizeWindow
) where
import XMonad
-- $usage
--
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import qualified XMonad.Actions.ConstrainedResize as Sqr
--
-- Then add something like the following to your mouse bindings:
--
-- > , ((modMask x, button3), (\w -> focus w >> Sqr.mouseResizeWindow w False))
-- > , ((modMask x .|. shiftMask, button3), (\w -> focus w >> Sqr.mouseResizeWindow w True ))
--
-- The line without the shiftMask replaces the standard mouse resize
-- function call, so it's not completely necessary but seems neater
-- this way.
--
-- For detailed instructions on editing your mouse bindings, see
-- "XMonad.Doc.Extending#Editing_mouse_bindings".
-- | Resize (floating) window with optional aspect ratio constraints.
mouseResizeWindow :: Window -> Bool -> X ()
mouseResizeWindow w c = whenX (isClient w) $ withDisplay $ \d -> do
io $ raiseWindow d w
wa <- io $ getWindowAttributes d w
sh <- io $ getWMNormalHints d w
io $ warpPointer d none w 0 0 0 0 (fromIntegral (wa_width wa)) (fromIntegral (wa_height wa))
mouseDrag (\ex ey -> do
let x = ex - fromIntegral (wa_x wa)
y = ey - fromIntegral (wa_y wa)
sz = if c then (max x y, max x y) else (x,y)
io $ resizeWindow d w `uncurry`
applySizeHintsContents sh sz)
(float w)

View File

@@ -0,0 +1,116 @@
{-# LANGUAGE PatternGuards #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.CopyWindow
-- Copyright : (c) David Roundy <droundy@darcs.net>, Ivan Veselov <veselov@gmail.com>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : ???
-- Stability : unstable
-- Portability : unportable
--
-- Provides a binding to duplicate a window on multiple workspaces,
-- providing dwm-like tagging functionality.
--
-----------------------------------------------------------------------------
module XMonad.Actions.CopyWindow (
-- * Usage
-- $usage
copy, copyToAll, copyWindow, killAllOtherCopies, kill1
) where
import Prelude hiding (filter)
import qualified Data.List as L
import XMonad hiding (modify, workspaces)
import XMonad.StackSet
-- $usage
--
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:
--
-- > import XMonad.Actions.CopyWindow
--
-- Then add something like this to your keybindings:
--
-- > -- mod-[1..9] @@ Switch to workspace N
-- > -- mod-shift-[1..9] @@ Move client to workspace N
-- > -- mod-control-shift-[1..9] @@ Copy client to workspace N
-- > [((m .|. modMask x, k), windows $ f i)
-- > | (i, k) <- zip (workspaces x) [xK_1 ..]
-- > , (f, m) <- [(W.view, 0), (W.shift, shiftMask), (copy, shiftMask .|. controlMask)]]
--
-- To use the above key bindings you need also to import
-- "XMonad.StackSet":
--
-- > import qualified XMonad.StackSet as W
--
-- You may also wish to redefine the binding to kill a window so it only
-- removes it from the current workspace, if it's present elsewhere:
--
-- > , ((modMask x .|. shiftMask, xK_c ), kill1) -- @@ Close the focused window
--
-- Another possibility which this extension provides is 'making window
-- always visible' (i.e. always on current workspace), similar to corresponding
-- metacity functionality. This behaviour is emulated through copying given
-- window to all the workspaces and then removing it when it's unneeded on
-- all workspaces any more.
--
-- Here is the example of keybindings which provide these actions:
--
-- > , ((modMask x, xK_v )", windows copyToAll) -- @@ Make focused window always visible
-- > , ((modMask x .|. shiftMask, xK_v ), killAllOtherCopies) -- @@ Toggle window state back
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | copy. Copy the focussed window to a new workspace.
copy :: (Eq s, Eq i, Eq a) => i -> StackSet i l a s sd -> StackSet i l a s sd
copy n s | Just w <- peek s = copyWindow w n s
| otherwise = s
-- | copyToAll. Copy the focused window to all of workspaces.
copyToAll :: (Eq s, Eq i, Eq a) => StackSet i l a s sd -> StackSet i l a s sd
copyToAll s = foldr copy s $ map tag (workspaces s)
-- | copyWindow. Copy a window to a new workspace
copyWindow :: (Eq a, Eq i, Eq s) => a -> i -> StackSet i l a s sd -> StackSet i l a s sd
copyWindow w n = copy'
where copy' s = if n `tagMember` s
then view (currentTag s) $ insertUp' w $ view n s
else s
insertUp' a s = modify (Just $ Stack a [] [])
(\(Stack t l r) -> if a `elem` t:l++r
then Just $ Stack t l r
else Just $ Stack a (L.delete a l) (L.delete a (t:r))) s
-- | Remove the focused window from this workspace. If it's present in no
-- other workspace, then kill it instead. If we do kill it, we'll get a
-- delete notify back from X.
--
-- There are two ways to delete a window. Either just kill it, or if it
-- supports the delete protocol, send a delete event (e.g. firefox)
--
kill1 :: X ()
kill1 = do ss <- gets windowset
whenJust (peek ss) $ \w -> if member w $ delete'' w ss
then windows $ delete'' w
else kill
where delete'' w = modify Nothing (filter (/= w))
-- | Kill all other copies of focused window (if they're present)
-- 'All other' means here 'copies, which are not on current workspace'
--
-- Consider calling this function after copyToAll
--
killAllOtherCopies :: X ()
killAllOtherCopies = do ss <- gets windowset
whenJust (peek ss) $ \w -> windows $
view (currentTag ss) .
delFromAllButCurrent w
where
delFromAllButCurrent w ss = foldr ($) ss $
map (delWinFromWorkspace w . tag) $
hidden ss ++ map workspace (visible ss)
delWinFromWorkspace w wid ss = modify Nothing (filter (/= w)) $ view wid ss

View File

@@ -0,0 +1,85 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.CycleRecentWS
-- Copyright : (c) Michal Janeczek <janeczek@gmail.com>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Michal Janeczek <janeczek@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- Provides bindings to cycle through most recently used workspaces
-- with repeated presses of a single key (as long as modifier key is
-- held down). This is similar to how many window managers handle
-- window switching.
--
-----------------------------------------------------------------------------
module XMonad.Actions.CycleRecentWS (
-- * Usage
-- $usage
cycleRecentWS,
cycleWindowSets
) where
import XMonad hiding (workspaces)
import XMonad.StackSet
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:
--
-- > import XMonad.Actions.CycleRecentWS
-- >
-- > , ((modMask x, xK_Tab), cycleRecentWS [xK_Alt_L] xK_Tab xK_grave)
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Cycle through most recent workspaces with repeated presses of a key, while
-- a modifier key is held down. The recency of workspaces previewed while browsing
-- to the target workspace is not affected. That way a stack of most recently used
-- workspaces is maintained, similarly to how many window managers handle window
-- switching. For best effects use the same modkey+key combination as the one used
-- to invoke this action.
cycleRecentWS :: [KeySym] -- ^ A list of modifier keys used when invoking this action.
-- As soon as one of them is released, the final switch is made.
-> KeySym -- ^ Key used to switch to next (less recent) workspace.
-> KeySym -- ^ Key used to switch to previous (more recent) workspace.
-- If it's the same as the nextWorkspace key, it is effectively ignored.
-> X ()
cycleRecentWS = cycleWindowSets options
where options w = map (view `flip` w) (recentTags w)
recentTags w = map tag $ tail (workspaces w) ++ [head (workspaces w)]
cycref :: [a] -> Int -> a
cycref l i = l !! (i `mod` length l)
-- | Cycle through a finite list of WindowSets with repeated presses of a key, while
-- a modifier key is held down. For best effects use the same modkey+key combination
-- as the one used to invoke this action.
cycleWindowSets :: (WindowSet -> [WindowSet]) -- ^ A function used to create a list of WindowSets to choose from
-> [KeySym] -- ^ A list of modifier keys used when invoking this action.
-- As soon as one of them is released, the final WindowSet is chosen and the action exits.
-> KeySym -- ^ Key used to preview next WindowSet from the list of generated options
-> KeySym -- ^ Key used to preview previous WindowSet from the list of generated options.
-- If it's the same as nextOption key, it is effectively ignored.
-> X ()
cycleWindowSets genOptions mods keyNext keyPrev = do
options <- gets $ genOptions . windowset
XConf {theRoot = root, display = d} <- ask
let event = allocaXEvent $ \p -> do
maskEvent d (keyPressMask .|. keyReleaseMask) p
KeyEvent {ev_event_type = t, ev_keycode = c} <- getEvent p
s <- keycodeToKeysym d c 0
return (t, s)
let setOption n = do windows $ const $ options `cycref` n
(t, s) <- io event
case () of
() | t == keyPress && s == keyNext -> setOption (n+1)
| t == keyPress && s == keyPrev -> setOption (n-1)
| t == keyRelease && s `elem` mods -> return ()
| otherwise -> setOption n
io $ grabKeyboard d root False grabModeAsync grabModeAsync currentTime
setOption 0
io $ ungrabKeyboard d currentTime

View File

@@ -0,0 +1,51 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.CycleSelectedLayouts
-- Copyright : (c) Roman Cheplyaka
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Roman Cheplyaka <roma@ro-che.info>
-- Stability : unstable
-- Portability : unportable
--
-- This module allows to cycle through the given subset of layouts.
--
-----------------------------------------------------------------------------
module XMonad.Actions.CycleSelectedLayouts (
-- * Usage
-- $usage
cycleThroughLayouts) where
import XMonad
import Data.List (findIndex)
import Data.Maybe (fromMaybe)
import XMonad.Layout.LayoutCombinators (JumpToLayout(..))
import qualified XMonad.StackSet as S
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad hiding ((|||))
-- > import XMonad.Layout.LayoutCombinators ((|||))
-- > import XMonad.Actions.CycleSelectedLayouts
--
-- > , ((modMask x, xK_t ), cycleThroughLayouts ["Tall", "Mirror Tall"])
--
-- Make sure you are using NewSelect from XMonad.Layout.LayoutCombinators,
-- rather than the Select defined in xmonad core.
cycleToNext :: (Eq a) => [a] -> a -> Maybe a
cycleToNext lst a = do
-- not beautiful but simple and readable
ind <- findIndex (a==) lst
return $ lst !! if ind == length lst - 1 then 0 else ind+1
-- | If the current layout is in the list, cycle to the next layout. Otherwise,
-- apply the first layout from list.
cycleThroughLayouts :: [String] -> X ()
cycleThroughLayouts lst = do
winset <- gets windowset
let ld = description . S.layout . S.workspace . S.current $ winset
let newld = fromMaybe (head lst) (cycleToNext lst ld)
sendMessage $ JumpToLayout newld

294
XMonad/Actions/CycleWS.hs Normal file
View File

@@ -0,0 +1,294 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.CycleWS
-- Copyright : (c) Joachim Breitner <mail@joachim-breitner.de>,
-- Nelson Elhage <nelhage@mit.edu> (`toggleWS' function)
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Joachim Breitner <mail@joachim-breitner.de>
-- Stability : unstable
-- Portability : unportable
--
-- Provides bindings to cycle forward or backward through the list of
-- workspaces, to move windows between workspaces, and to cycle
-- between screens. More general combinators provide ways to cycle
-- through workspaces in various orders, to only cycle through some
-- subset of workspaces, and to cycle by more than one workspace at a
-- time.
--
-- Note that this module now subsumes the functionality of the former
-- @XMonad.Actions.RotView@. Former users of @rotView@ can simply replace
-- @rotView True@ with @moveTo Next NonEmptyWS@, and so on.
--
-- If you want to exactly replicate the action of @rotView@ (cycling
-- through workspace in order lexicographically by tag, instead of in
-- the order specified in the config), it can be implemented as:
--
-- > rotView b = do t <- findWorkspace getSortByTag (bToDir b) NonEmptyWS 1
-- > windows . greedyView $ t
-- > where bToDir True = Next
-- > bToDir False = Prev
--
-----------------------------------------------------------------------------
module XMonad.Actions.CycleWS (
-- * Usage
-- $usage
-- * Moving between workspaces
-- $moving
nextWS
, prevWS
, shiftToNext
, shiftToPrev
, toggleWS
-- * Moving between screens (xinerama)
, nextScreen
, prevScreen
, shiftNextScreen
, shiftPrevScreen
, swapNextScreen
, swapPrevScreen
-- * Moving between workspaces, take two!
-- $taketwo
, WSDirection(..)
, WSType(..)
, shiftTo
, moveTo
-- * The mother-combinator
, findWorkspace
) where
import Data.List ( findIndex )
import Data.Maybe ( isNothing, isJust )
import XMonad hiding (workspaces)
import XMonad.StackSet hiding (filter)
import XMonad.Util.WorkspaceCompare
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:
--
-- > import XMonad.Actions.CycleWS
-- >
-- > -- a basic CycleWS setup
-- >
-- > , ((modMask x, xK_Down), nextWS)
-- > , ((modMask x, xK_Up), prevWS)
-- > , ((modMask x .|. shiftMask, xK_Down), shiftToNext)
-- > , ((modMask x .|. shiftMask, xK_Up), shiftToPrev)
-- > , ((modMask x, xK_Right), nextScreen)
-- > , ((modMask x, xK_Left), prevScreen)
-- > , ((modMask x .|. shiftMask, xK_Right), shiftNextScreen)
-- > , ((modMask x .|. shiftMask, xK_Left), shiftPrevScreen)
-- > , ((modMask x, xK_z), toggleWS)
--
-- If you want to follow the moved window, you can use both actions:
--
-- > , ((modMask x .|. shiftMask, xK_Down), shiftToNext >> nextWS)
-- > , ((modMask x .|. shiftMask, xK_Up), shiftToPrev >> prevWS)
--
-- You can also get fancier with 'moveTo', 'shiftTo', and 'findWorkspace'.
-- For example:
--
-- > , ((modMask x , xK_f), moveTo Next EmptyWS) -- find a free workspace
-- > , ((modMask x .|. controlMask, xK_Right), -- a crazy keybinding!
-- > do t <- findWorkspace getXineramaWsCompare Next NonEmptyWS 2
-- > windows . view $ t )
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
{- $moving
The following commands for moving the view and windows between
workspaces are somewhat inflexible, but are very simple and probably
Do The Right Thing for most users.
All of the commands in this section cycle through workspaces in the
order in which they are given in your config.
-}
-- | Switch to the next workspace.
nextWS :: X ()
nextWS = switchWorkspace 1
-- | Switch to the previous workspace.
prevWS :: X ()
prevWS = switchWorkspace (-1)
-- | Move the focused window to the next workspace.
shiftToNext :: X ()
shiftToNext = shiftBy 1
-- | Move the focused window to the previous workspace.
shiftToPrev :: X ()
shiftToPrev = shiftBy (-1)
-- | Toggle to the workspace displayed previously.
toggleWS :: X ()
toggleWS = windows $ view =<< tag . head . hidden
switchWorkspace :: Int -> X ()
switchWorkspace d = wsBy d >>= windows . greedyView
shiftBy :: Int -> X ()
shiftBy d = wsBy d >>= windows . shift
wsBy :: Int -> X (WorkspaceId)
wsBy = findWorkspace getSortByIndex Next AnyWS
{- $taketwo
A few more general commands are also provided, which allow cycling
through subsets of workspaces.
For example,
> moveTo Next EmptyWS
will move to the first available workspace with no windows, and
> shiftTo Prev (WSIs $ return (('p' `elem`) . tag))
will move the focused window backwards to the first workspace containing
the letter 'p' in its name. =)
-}
-- | Direction to cycle through the sort order.
data WSDirection = Next | Prev
-- | What type of workspaces should be included in the cycle?
data WSType = EmptyWS -- ^ cycle through empty workspaces
| NonEmptyWS -- ^ cycle through non-empty workspaces
| HiddenWS -- ^ cycle through non-visible workspaces
| HiddenNonEmptyWS -- ^ cycle through non-empty non-visible workspaces
| AnyWS -- ^ cycle through all workspaces
| WSIs (X (WindowSpace -> Bool))
-- ^ cycle through workspaces satisfying
-- an arbitrary predicate
-- | Convert a WSType value to a predicate on workspaces.
wsTypeToPred :: WSType -> X (WindowSpace -> Bool)
wsTypeToPred EmptyWS = return (isNothing . stack)
wsTypeToPred NonEmptyWS = return (isJust . stack)
wsTypeToPred HiddenWS = do hs <- gets (map tag . hidden . windowset)
return (\w -> tag w `elem` hs)
wsTypeToPred HiddenNonEmptyWS = do ne <- wsTypeToPred NonEmptyWS
hi <- wsTypeToPred HiddenWS
return (\w -> hi w && ne w)
wsTypeToPred AnyWS = return (const True)
wsTypeToPred (WSIs p) = p
-- | View the next workspace in the given direction that satisfies
-- the given condition.
moveTo :: WSDirection -> WSType -> X ()
moveTo dir t = findWorkspace getSortByIndex dir t 1 >>= windows . greedyView
-- | Move the currently focused window to the next workspace in the
-- given direction that satisfies the given condition.
shiftTo :: WSDirection -> WSType -> X ()
shiftTo dir t = findWorkspace getSortByIndex dir t 1 >>= windows . shift
-- | Given a function @s@ to sort workspaces, a direction @dir@, a
-- predicate @p@ on workspaces, and an integer @n@, find the tag of
-- the workspace which is @n@ away from the current workspace in
-- direction @dir@ (wrapping around if necessary), among those
-- workspaces, sorted by @s@, which satisfy @p@.
--
-- For some useful workspace sorting functions, see
-- "XMonad.Util.WorkspaceCompare".
--
-- For ideas of what to do with a workspace tag once obtained, note
-- that 'moveTo' and 'shiftTo' are implemented by applying @(>>=
-- (windows . greedyView))@ and @(>>= (windows . shift))@, respectively,
-- to the output of 'findWorkspace'.
findWorkspace :: X WorkspaceSort -> WSDirection -> WSType -> Int -> X WorkspaceId
findWorkspace s dir t n = findWorkspaceGen s (wsTypeToPred t) (maybeNegate dir n)
where
maybeNegate Next d = d
maybeNegate Prev d = (-d)
findWorkspaceGen :: X WorkspaceSort -> X (WindowSpace -> Bool) -> Int -> X WorkspaceId
findWorkspaceGen _ _ 0 = gets (currentTag . windowset)
findWorkspaceGen sortX wsPredX d = do
wsPred <- wsPredX
sort <- sortX
ws <- gets windowset
let cur = workspace (current ws)
sorted = sort (workspaces ws)
pivoted = let (a,b) = span ((/= (tag cur)) . tag) sorted in b ++ a
ws' = filter wsPred $ pivoted
mCurIx = findWsIndex cur ws'
d' = if d > 0 then d - 1 else d
next = if null ws'
then cur
else case mCurIx of
Nothing -> ws' !! (d' `mod` length ws')
Just ix -> ws' !! ((ix + d) `mod` length ws')
return $ tag next
findWsIndex :: WindowSpace -> [WindowSpace] -> Maybe Int
findWsIndex ws wss = findIndex ((== tag ws) . tag) wss
-- | View next screen
nextScreen :: X ()
nextScreen = switchScreen 1
-- | View prev screen
prevScreen :: X ()
prevScreen = switchScreen (-1)
switchScreen :: Int -> X ()
switchScreen d = do s <- screenBy d
mws <- screenWorkspace s
case mws of
Nothing -> return ()
Just ws -> windows (view ws)
screenBy :: Int -> X (ScreenId)
screenBy d = do ws <- gets windowset
--let ss = sortBy screen (screens ws)
let now = screen (current ws)
return $ (now + fromIntegral d) `mod` fromIntegral (length (screens ws))
-- | Swap current screen with next screen
swapNextScreen :: X ()
swapNextScreen = swapScreen 1
-- | Swap current screen with previous screen
swapPrevScreen :: X ()
swapPrevScreen = swapScreen (-1)
swapScreen :: Int -> X ()
swapScreen d = do s <- screenBy d
mws <- screenWorkspace s
case mws of
Nothing -> return ()
Just ws -> windows (greedyView ws)
-- | Move focused window to workspace on next screen
shiftNextScreen :: X ()
shiftNextScreen = shiftScreenBy 1
-- | Move focused window to workspace on prev screen
shiftPrevScreen :: X ()
shiftPrevScreen = shiftScreenBy (-1)
shiftScreenBy :: Int -> X ()
shiftScreenBy d = do s <- screenBy d
mws <- screenWorkspace s
case mws of
Nothing -> return ()
Just ws -> windows (shift ws)

View File

@@ -1,56 +1,54 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.DeManage
-- Copyright : (c) Spencer Janssen <sjanssen@cse.unl.edu>
-- Module : XMonad.Actions.DeManage
-- Copyright : (c) Spencer Janssen <spencerjanssen@gmail.com>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Spencer Janssen <sjanssen@cse.unl.edu>
-- Maintainer : Spencer Janssen <spencerjanssen@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- This module provides a method to cease management of a window, without
-- unmapping it. This is especially useful for applications like kicker and
-- gnome-panel.
-- This module provides a method to cease management of a window
-- without unmapping it. This is especially useful for applications
-- like kicker and gnome-panel.
--
-- To make a panel display correctly with xmonad:
--
-- * Determine the pixel size of the panel, add that value to defaultGaps
-- * Determine the pixel size of the panel, add that value to
-- 'XMonad.Core.XConfig.defaultGaps'
--
-- * Launch the panel
--
-- * Give the panel window focus, then press mod-d
-- * Give the panel window focus, then press @mod-d@ (or whatever key
-- you have bound 'demanage' to)
--
-- * Convince the panel to move\/resize to the correct location. Changing the
-- panel's position setting several times seems to work.
--
-----------------------------------------------------------------------------
module XMonadContrib.DeManage (
module XMonad.Actions.DeManage (
-- * Usage
-- $usage
demanage
) where
import qualified StackSet as W
import qualified XMonad.StackSet as W
import XMonad
import Operations
import Control.Monad.State
import Graphics.X11 (Window)
-- $usage
-- To use demanage, add this import:
-- To use demanage, add this import to your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonadContrib.DeManage
-- > import XMonad.Actions.DeManage
--
-- And add a keybinding to it:
-- And add a keybinding, such as:
--
-- > , ((modMask, xK_d ), withFocused demanage)
-- > , ((modMask x, xK_d ), withFocused demanage)
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- %import XMonadContrib.DeManage
-- %keybind , ((modMask, xK_d ), withFocused demanage)
-- | Stop managing the current focused window.
-- | Stop managing the currently focused window.
demanage :: Window -> X ()
demanage w = do
-- use modify to defeat automatic 'unmanage' calls.

View File

@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.DwmPromote
-- Module : XMonad.Actions.DwmPromote
-- Copyright : (c) Miikka Koskinen 2007
-- License : BSD3-style (see LICENSE)
--
@@ -9,36 +9,38 @@
-- Portability : unportable
--
-- Dwm-like swap function for xmonad.
--
--
-- Swaps focused window with the master window. If focus is in the
-- master, swap it with the next window in the stack. Focus stays in the
-- master.
--
-----------------------------------------------------------------------------
module XMonadContrib.DwmPromote (
module XMonad.Actions.DwmPromote (
-- * Usage
-- $usage
-- $usage
dwmpromote
) where
import XMonad
import Operations (windows)
import StackSet
import XMonad.StackSet
-- $usage
--
-- To use, modify your Config.hs to:
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonadContrib.DwmPromote
-- > import XMonad.Actions.DwmPromote
--
-- and add a keybinding or substitute promote with dwmpromote:
-- then add a keybinding or substitute 'dwmpromote' in place of promote:
--
-- > , ((modMask, xK_Return), dwmpromote)
-- %import XMonadContrib.DwmPromote
-- %keybind , ((modMask, xK_Return), dwmpromote)
-- > , ((modMask x, xK_Return), dwmpromote)
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Swap the focused window with the master window. If focus is in
-- the master, swap it with the next window in the stack. Focus
-- stays in the master.
dwmpromote :: X ()
dwmpromote = windows $ modify' $
\c -> case c of

View File

@@ -0,0 +1,132 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.DynamicWorkspaces
-- Copyright : (c) David Roundy <droundy@darcs.net>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : none
-- Stability : unstable
-- Portability : unportable
--
-- Provides bindings to add and delete workspaces. Note that you may only
-- delete a workspace that is already empty.
--
-----------------------------------------------------------------------------
module XMonad.Actions.DynamicWorkspaces (
-- * Usage
-- $usage
addWorkspace, removeWorkspace,
addHiddenWorkspace,
withWorkspace,
selectWorkspace, renameWorkspace,
toNthWorkspace, withNthWorkspace
) where
import XMonad hiding (workspaces)
import XMonad.StackSet hiding (filter, modify, delete)
import XMonad.Prompt.Workspace
import XMonad.Prompt ( XPConfig, mkXPrompt, XPrompt(..) )
import XMonad.Util.WorkspaceCompare ( getSortByIndex )
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:
--
-- > import XMonad.Actions.DynamicWorkspaces
--
-- Then add keybindings like the following:
--
-- > , ((modMask x .|. shiftMask, xK_BackSpace), removeWorkspace)
-- > , ((modMask x .|. shiftMask, xK_v ), selectWorkspace defaultXPConfig)
-- > , ((modMask x, xK_m ), withWorkspace defaultXPConfig (windows . W.shift))
-- > , ((modMask x .|. shiftMask, xK_m ), withWorkspace defaultXPConfig (windows . copy))
-- > , ((modMask x .|. shiftMask, xK_r ), renameWorkspace defaultXPConfig)
--
-- > -- mod-[1..9] %! Switch to workspace N
-- > -- mod-shift-[1..9] %! Move client to workspace N
-- > ++
-- > zip (zip (repeat (modMask x)) [xK_1..xK_9]) (map (withNthWorkspace W.greedyView) [0..])
-- > ++
-- > zip (zip (repeat (modMask x .|. shiftMask)) [xK_1..xK_9]) (map (withNthWorkspace W.shift) [0..])
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
data Wor = Wor String
instance XPrompt Wor where
showXPrompt (Wor x) = x
mkCompl :: [String] -> String -> IO [String]
mkCompl l s = return $ filter (\x -> take (length s) x == s) l
withWorkspace :: XPConfig -> (String -> X ()) -> X ()
withWorkspace c job = do ws <- gets (workspaces . windowset)
sort <- getSortByIndex
let ts = map tag $ sort ws
job' t | t `elem` ts = job t
| otherwise = addHiddenWorkspace t >> job t
mkXPrompt (Wor "") c (mkCompl ts) job'
renameWorkspace :: XPConfig -> X ()
renameWorkspace conf = workspacePrompt conf $ \w ->
windows $ \s -> let sett wk = wk { tag = w }
setscr scr = scr { workspace = sett $ workspace scr }
sets q = q { current = setscr $ current q }
in sets $ removeWorkspace' w s
toNthWorkspace :: (String -> X ()) -> Int -> X ()
toNthWorkspace job wnum = do sort <- getSortByIndex
ws <- gets (map tag . sort . workspaces . windowset)
case drop wnum ws of
(w:_) -> job w
[] -> return ()
withNthWorkspace :: (String -> WindowSet -> WindowSet) -> Int -> X ()
withNthWorkspace job wnum = do sort <- getSortByIndex
ws <- gets (map tag . sort . workspaces . windowset)
case drop wnum ws of
(w:_) -> windows $ job w
[] -> return ()
selectWorkspace :: XPConfig -> X ()
selectWorkspace conf = workspacePrompt conf $ \w ->
do s <- gets windowset
if tagMember w s
then windows $ greedyView w
else addWorkspace w
-- | Add a new workspace with the given name.
addWorkspace :: String -> X ()
addWorkspace newtag = addHiddenWorkspace newtag >> windows (greedyView newtag)
-- | Add a new hidden workspace with the given name.
addHiddenWorkspace :: String -> X ()
addHiddenWorkspace newtag = do l <- asks (layoutHook . config)
windows (addHiddenWorkspace' newtag l)
-- | Remove the current workspace if it contains no windows.
removeWorkspace :: X ()
removeWorkspace = do s <- gets windowset
case s of
StackSet { current = Screen { workspace = torem }
, hidden = (w:_) }
-> do windows $ view (tag w)
windows (removeWorkspace' (tag torem))
_ -> return ()
addHiddenWorkspace' :: i -> l -> StackSet i l a sid sd -> StackSet i l a sid sd
addHiddenWorkspace' newtag l s@(StackSet { hidden = ws }) = s { hidden = Workspace newtag l Nothing:ws }
removeWorkspace' :: (Eq i) => i -> StackSet i l a sid sd -> StackSet i l a sid sd
removeWorkspace' torem s@(StackSet { current = scr@(Screen { workspace = wc })
, hidden = (w:ws) })
| tag w == torem = s { current = scr { workspace = wc { stack = meld (stack w) (stack wc) } }
, hidden = ws }
where meld Nothing Nothing = Nothing
meld x Nothing = x
meld Nothing x = x
meld (Just x) (Just y) = differentiate (integrate x ++ integrate y)
removeWorkspace' _ s = s

View File

@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.FindEmptyWorkspace
-- Module : XMonad.Actions.FindEmptyWorkspace
-- Copyright : (c) Miikka Koskinen 2007
-- License : BSD3-style (see LICENSE)
--
@@ -8,43 +8,38 @@
-- Stability : unstable
-- Portability : unportable
--
-- Find an empty workspace in XMonad.
-- Find an empty workspace.
--
-----------------------------------------------------------------------------
module XMonadContrib.FindEmptyWorkspace (
module XMonad.Actions.FindEmptyWorkspace (
-- * Usage
-- $usage
viewEmptyWorkspace, tagToEmptyWorkspace
) where
import Control.Monad.State
import Data.List
import Data.Maybe ( isNothing )
import XMonad
import StackSet
import Operations
import XMonad.StackSet
-- $usage
--
-- To use, modify your Config.hs to:
--
-- > import XMonadContrib.FindEmptyWorkspace
-- To use, import this module into your @~\/.xmonad\/xmonad.hs@:
--
-- and add a keybinding:
-- > import XMonad.Actions.FindEmptyWorkspace
--
-- > , ((modMask, xK_m ), viewEmptyWorkspace)
-- > , ((modMask .|. shiftMask, xK_m ), tagToEmptyWorkspace)
-- and add the desired keybindings, for example:
--
-- Now you can jump to an empty workspace with mod-m. Mod-shift-m will
-- tag the current window to an empty workspace and view it.
-- %import XMonadContrib.FindEmptyWorkspace
-- %keybind , ((modMask, xK_m ), viewEmptyWorkspace)
-- %keybind , ((modMask .|. shiftMask, xK_m ), tagToEmptyWorkspace)
-- > , ((modMask x, xK_m ), viewEmptyWorkspace)
-- > , ((modMask x .|. shiftMask, xK_m ), tagToEmptyWorkspace)
--
-- Now you can jump to an empty workspace with @mod-m@. @Mod-shift-m@
-- will tag the current window to an empty workspace and view it.
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Find the first hidden empty workspace in a StackSet. Returns
-- Nothing if all workspaces are in use. Function searches currently

View File

@@ -2,67 +2,79 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.FlexibleManipulate
-- Module : XMonad.Actions.FlexibleManipulate
-- Copyright : (c) Michael Sloan
-- License : BSD3-style (see LICENSE)
--
--
-- Maintainer : <mgsloan@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- Lets you move and resize floating windows without warping the mouse.
-- Move and resize floating windows without warping the mouse.
--
-----------------------------------------------------------------------------
-- Based on the FlexibleResize code by Lukas Mai (Mauke)
-- Based on the FlexibleResize code by Lukas Mai (mauke).
module XMonadContrib.FlexibleManipulate (
-- * Usage
-- $usage
mouseWindow, discrete, linear, resize, position
module XMonad.Actions.FlexibleManipulate (
-- * Usage
-- $usage
mouseWindow, discrete, linear, resize, position
) where
import XMonad
import Operations
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
-- $usage
-- Add this import to your Config.hs file:
-- First, add this import to your @~\/.xmonad\/xmonad.hs@:
--
-- > import qualified XMonadContrib.FlexibleManipulate as Flex
-- > import qualified XMonad.Actions.FlexibleManipulate as Flex
--
-- Set one of the mouse button bindings up like this:
-- Now set up the desired mouse binding, for example:
--
-- > mouseBindings = M.fromList
-- > [ ((modMask, button1), (\w -> focus w >> Flex.mouseWindow Flex.linear w)) ], ...
-- > , ((modMask x, button1), (\w -> focus w >> Flex.mouseWindow Flex.linear w))
--
-- Flex.linear indicates that positions between the edges and the middle
-- indicate a combination scale\/position.
-- Flex.discrete indicates that there are discrete pick regions. (window
-- is divided by thirds for each axis)
-- Flex.resize performs only resize of the window, based on which quadrant
-- the mouse is in
-- Flex.position is similar to the built-in mouseMoveWindow
-- * Flex.'linear' indicates that positions between the edges and the
-- middle indicate a combination scale\/position.
--
-- * Flex.'discrete' indicates that there are discrete pick
-- regions. (The window is divided by thirds for each axis.)
--
-- * Flex.'resize' performs only a resize of the window, based on which
-- quadrant the mouse is in.
--
-- * Flex.'position' is similar to the built-in
-- 'XMonad.Operations.mouseMoveWindow'.
--
-- You can also write your own function for this parameter. It should take
-- a value between 0 and 1 indicating position, and return a value indicating
-- the corresponding position if plain Flex.linear was used.
-- %import qualified XMonadContrib.FlexibleManipulate as Flex
-- %mousebind , ((modMask, button1), (\\w -> focus w >> Flex.mouseWindow Flex.linear w))
-- the corresponding position if plain Flex.'linear' was used.
--
-- For detailed instructions on editing your mouse bindings, see
-- "XMonad.Doc.Extending#Editing_mouse_bindings".
discrete, linear, resize, position :: Double -> Double
-- | Manipulate the window based on discrete pick regions; the window
-- is divided into regions by thirds along each axis.
discrete x | x < 0.33 = 0
| x > 0.66 = 1
| otherwise = 0.5
-- | Scale\/reposition the window by factors obtained from the mouse
-- position by linear interpolation. Dragging precisely on a corner
-- resizes that corner; dragging precisely in the middle moves the
-- window without resizing; anything else is an interpolation
-- between the two.
linear = id
-- | Only resize the window, based on the window quadrant the mouse is in.
resize x = if x < 0.5 then 0 else 1
-- | Only reposition the window.
position = const 0.5
-- | Given an interpolation function, implement an appropriate window
-- manipulation action.
mouseWindow :: (Double -> Double) -> Window -> X ()
mouseWindow f w = whenX (isClient w) $ withDisplay $ \d -> do
io $ raiseWindow d w
@@ -80,13 +92,13 @@ mouseWindow f w = whenX (isClient w) $ withDisplay $ \d -> do
npos = wpos + offset * atl
nbr = (wpos + wsize) + offset * abr
ntl = minP (nbr - (32, 32)) npos --minimum size
nwidth = applySizeHints sh $ mapP (round :: Double -> Integer) (nbr - ntl)
nwidth = applySizeHintsContents sh $ mapP (round :: Double -> Integer) (nbr - ntl)
moveResizeWindow d w (round $ fst ntl) (round $ snd ntl) `uncurry` nwidth
return ())
(float w)
float w
where
pointerPos (_,_,_,px,py,_,_,_) = (fromIntegral px,fromIntegral py) :: Pnt
winAttrs :: WindowAttributes -> [Pnt]
@@ -103,7 +115,7 @@ pairUp (x:y:xs) = (x, y) : (pairUp xs)
mapP :: (a -> b) -> (a, a) -> (b, b)
mapP f (x, y) = (f x, f y)
zipP :: (a -> b -> c) -> (a,a) -> (b,b) -> (c,c)
zipP :: (a -> b -> c) -> (a,a) -> (b,b) -> (c,c)
zipP f (ax,ay) (bx,by) = (f ax bx, f ay by)
minP :: Ord a => (a,a) -> (a,a) -> (a,a)

View File

@@ -1,40 +1,40 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.FlexibleResize
-- Module : XMonad.Actions.FlexibleResize
-- Copyright : (c) Lukas Mai
-- License : BSD3-style (see LICENSE)
--
--
-- Maintainer : <l.mai@web.de>
-- Stability : unstable
-- Portability : unportable
--
-- Lets you resize floating windows from any corner.
-- Resize floating windows from any corner.
--
-----------------------------------------------------------------------------
module XMonadContrib.FlexibleResize (
-- * Usage
-- $usage
XMonadContrib.FlexibleResize.mouseResizeWindow
module XMonad.Actions.FlexibleResize (
-- * Usage
-- $usage
XMonad.Actions.FlexibleResize.mouseResizeWindow
) where
import XMonad
import Operations
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import Foreign.C.Types
-- $usage
-- Put something like this in your Config.hs file:
-- To use, first import this module into your @~\/.xmonad\/xmonad.hs@ file:
--
-- > import qualified XMonadContrib.FlexibleResize as Flex
-- > mouseBindings = M.fromList
-- > [ ...
-- > , ((modMask, button3), (\w -> focus w >> Flex.mouseResizeWindow w)) ]
-- %import qualified XMonadContrib.FlexibleResize as Flex
-- %mousebind , ((modMask, button3), (\\w -> focus w >> Flex.mouseResizeWindow w))
-- > import qualified XMonad.Actions.FlexibleResize as Flex
--
-- Then add an appropriate mouse binding:
--
-- > , ((modMask x, button3), (\w -> focus w >> Flex.mouseResizeWindow w))
--
-- For detailed instructions on editing your mouse bindings, see
-- "XMonad.Doc.Extending#Editing_mouse_bindings".
-- | Resize a floating window from whichever corner the mouse is
-- closest to.
mouseResizeWindow :: Window -> X ()
mouseResizeWindow w = whenX (isClient w) $ withDisplay $ \d -> do
io $ raiseWindow d w
@@ -53,7 +53,7 @@ mouseResizeWindow w = whenX (isClient w) $ withDisplay $ \d -> do
let [px, py] = map (fromIntegral . ($ wa')) [wa_x, wa_y]
io $ moveResizeWindow d w (fx px (fromIntegral ex))
(fy py (fromIntegral ey))
`uncurry` applySizeHints sh (gx $ fromIntegral ex, gy $ fromIntegral ey))
`uncurry` applySizeHintsContents sh (gx $ fromIntegral ex, gy $ fromIntegral ey))
(float w)
where
firstHalf :: CInt -> Position -> Bool

View File

@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.FloatKeys
-- Module : XMonad.Actions.FloatKeys
-- Copyright : (c) Karsten Schoelzel <kuser@gmx.de>
-- License : BSD
--
@@ -11,7 +11,7 @@
-- Move and resize floating windows.
-----------------------------------------------------------------------------
module XMonadContrib.FloatKeys (
module XMonad.Actions.FloatKeys (
-- * Usage
-- $usage
keysMoveWindow,
@@ -19,44 +19,26 @@ module XMonadContrib.FloatKeys (
keysResizeWindow,
keysAbsResizeWindow) where
import Operations
import XMonad
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
-- $usage
-- > import XMonadContrib.FloatKeys
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > , ((modMask, xK_d ), withFocused (keysResizeWindow (-10,-10) (1,1)))
-- > , ((modMask, xK_s ), withFocused (keysResizeWindow (10,10) (1,1)))
-- > , ((modMask .|. shiftMask, xK_d ), withFocused (keysAbsResizeWindow (-10,-10) (1024,752)))
-- > , ((modMask .|. shiftMask, xK_s ), withFocused (keysAbsResizeWindow (10,10) (1024,752)))
-- > , ((modMask, xK_a ), withFocused (keysMoveWindowTo (512,384) (1%2,1%2)))
-- > import XMonad.Actions.FloatKeys
--
-- Then add appropriate key bindings, for example:
--
-- keysMoveWindow (dx, dy) moves the window by dx pixels to the right and dy pixels down
--
-- keysMoveWindowTo (x, y) (gx, gy) moves the window relative point (gx, gy) to the point (x,y)
-- where (gx,gy) gives a position relative to the window border, i.e.
-- gx = 0 is the left border and gx = 1 the right border
-- gy = 0 is the top border and gy = 1 the bottom border
--
-- examples on a 1024x768 screen: keysMoveWindowTo (512,384) (1%2, 1%2) centers the window on screen
-- keysMoveWindowTo (1024,0) (1, 0) puts it into the top right corner
--
-- keysResizeWindow (dx, dy) (gx, gy) changes the width by dx and the height by dy leaving the window
-- relative point (gx, gy) fixed
--
-- examples: keysResizeWindow (10, 0) (0, 0) makes the window 10 pixels larger to the right
-- keysResizeWindow (10, 0) (0, 1%2) does the same, unless sizeHints are applied
-- keysResizeWindow (10, 10) (1%2, 1%2) adds 5 pixels on each side
-- keysResizeWindow (-10, -10) (0, 1) shrinks the window in direction of the bottom-left corner
--
-- keysAbsResizeWindow (dx, dy) (ax, ay) changes the width by dx and the height by dy leaving the screen
-- absolut point (ax, ay) fixed
--
-- examples on a 1024x768 screen: keysAbsResizeWindow (10, 10) (0, 0) enlarge the window and if it is not in the top-left corner it will also be moved away
-- > , ((modMask x, xK_d ), withFocused (keysResizeWindow (-10,-10) (1,1)))
-- > , ((modMask x, xK_s ), withFocused (keysResizeWindow (10,10) (1,1)))
-- > , ((modMask x .|. shiftMask, xK_d ), withFocused (keysAbsResizeWindow (-10,-10) (1024,752)))
-- > , ((modMask x .|. shiftMask, xK_s ), withFocused (keysAbsResizeWindow (10,10) (1024,752)))
-- > , ((modMask x, xK_a ), withFocused (keysMoveWindowTo (512,384) (1%2,1%2)))
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | @keysMoveWindow (dx, dy)@ moves the window by @dx@ pixels to the
-- right and @dy@ pixels down.
keysMoveWindow :: D -> Window -> X ()
keysMoveWindow (dx,dy) w = whenX (isClient w) $ withDisplay $ \d -> do
io $ raiseWindow d w
@@ -65,6 +47,16 @@ keysMoveWindow (dx,dy) w = whenX (isClient w) $ withDisplay $ \d -> do
(fromIntegral (fromIntegral (wa_y wa) + dy))
float w
-- | @keysMoveWindowTo (x, y) (gx, gy)@ moves the window relative
-- point @(gx, gy)@ to the point @(x,y)@, where @(gx,gy)@ gives a
-- position relative to the window border, i.e. @gx = 0@ is the left
-- border, @gx = 1@ is the right border, @gy = 0@ is the top border, and
-- @gy = 1@ the bottom border.
--
-- For example, on a 1024x768 screen:
--
-- > keysMoveWindowTo (512,384) (1%2, 1%2) -- center the window on screen
-- > keysMoveWindowTo (1024,0) (1, 0) -- put window in the top right corner
keysMoveWindowTo :: P -> G -> Window -> X ()
keysMoveWindowTo (x,y) (gx, gy) w = whenX (isClient w) $ withDisplay $ \d -> do
io $ raiseWindow d w
@@ -76,16 +68,33 @@ keysMoveWindowTo (x,y) (gx, gy) w = whenX (isClient w) $ withDisplay $ \d -> do
type G = (Rational, Rational)
type P = (Position, Position)
-- | @keysResizeWindow (dx, dy) (gx, gy)@ changes the width by @dx@
-- and the height by @dy@, leaving the window-relative point @(gx,
-- gy)@ fixed.
--
-- For example:
--
-- > keysResizeWindow (10, 0) (0, 0) -- make the window 10 pixels larger to the right
-- > keysResizeWindow (10, 0) (0, 1%2) -- does the same, unless sizeHints are applied
-- > keysResizeWindow (10, 10) (1%2, 1%2) -- add 5 pixels on each side
-- > keysResizeWindow (-10, -10) (0, 1) -- shrink the window in direction of the bottom-left corner
keysResizeWindow :: D -> G -> Window -> X ()
keysResizeWindow = keysMoveResize keysResizeWindow'
-- | @keysAbsResizeWindow (dx, dy) (ax, ay)@ changes the width by @dx@
-- and the height by @dy@, leaving the screen absolute point @(ax,
-- ay)@ fixed.
--
-- For example:
--
-- > keysAbsResizeWindow (10, 10) (0, 0) -- enlarge the window; if it is not in the top-left corner it will also be moved down and to the right.
keysAbsResizeWindow :: D -> D -> Window -> X ()
keysAbsResizeWindow = keysMoveResize keysAbsResizeWindow'
keysAbsResizeWindow' :: SizeHints -> P -> D -> D -> D -> (P,D)
keysAbsResizeWindow' sh (x,y) (w,h) (dx,dy) (ax, ay) = ((round nx, round ny), (nw, nh))
where
(nw, nh) = applySizeHints sh (w + dx, h + dy)
(nw, nh) = applySizeHintsContents sh (w + dx, h + dy)
nx :: Rational
nx = fromIntegral (ax * w + nw * (fromIntegral x - ax)) / fromIntegral w
ny :: Rational
@@ -94,7 +103,7 @@ keysAbsResizeWindow' sh (x,y) (w,h) (dx,dy) (ax, ay) = ((round nx, round ny), (n
keysResizeWindow' :: SizeHints -> P -> D -> D -> G -> (P,D)
keysResizeWindow' sh (x,y) (w,h) (dx,dy) (gx, gy) = ((nx, ny), (nw, nh))
where
(nw, nh) = applySizeHints sh (w + dx, h + dy)
(nw, nh) = applySizeHintsContents sh (w + dx, h + dy)
nx = round $ fromIntegral x + gx * fromIntegral w - gx * fromIntegral nw
ny = round $ fromIntegral y + gy * fromIntegral h - gy * fromIntegral nh
@@ -105,7 +114,7 @@ keysMoveResize f move resize w = whenX (isClient w) $ withDisplay $ \d -> do
sh <- io $ getWMNormalHints d w
let wa_dim = (fromIntegral $ wa_width wa, fromIntegral $ wa_height wa)
wa_pos = (fromIntegral $ wa_x wa, fromIntegral $ wa_y wa)
(wn_pos, wn_dim) = f sh wa_pos wa_dim move resize
(wn_pos, wn_dim) = f sh wa_pos wa_dim move resize
io $ resizeWindow d w `uncurry` wn_dim
io $ moveWindow d w `uncurry` wn_pos
float w

View File

@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.FocusNth
-- Module : XMonad.Actions.FocusNth
-- Copyright : (c) Karsten Schoelzel <kuser@gmx.de>
-- License : BSD
--
@@ -8,41 +8,43 @@
-- Stability : unstable
-- Portability : unportable
--
-- Focus the nth window on the screen.
-- Focus the nth window of the current workspace.
-----------------------------------------------------------------------------
module XMonadContrib.FocusNth (
module XMonad.Actions.FocusNth (
-- * Usage
-- $usage
focusNth) where
import StackSet
import Operations
import XMonad.StackSet
import XMonad
-- $usage
-- > import XMonadContrib.FocusNth
-- Add the import to your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Actions.FocusNth
--
-- Then add appropriate keybindings, for example:
--
-- > -- mod4-[1..9] @@ Switch to window N
-- > ++ [((mod4Mask, k), focusNth i)
-- > ++ [((modMask x, k), focusNth i)
-- > | (i, k) <- zip [0 .. 8] [xK_1 ..]]
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- %import XMonadContrib.FocusNth
-- %keybdindextra ++
-- %keybdindextra -- mod4-[1..9] @@ Switch to window N
-- %keybdindextra [((mod4Mask, k), focusNth i)
-- %keybdindextra | (i, k) <- zip [0 .. 8] [xK_1 ..]]
-- | Give focus to the nth window of the current workspace.
focusNth :: Int -> X ()
focusNth = windows . modify' . focusNth'
focusNth' :: Int -> Stack a -> Stack a
focusNth' n s@(Stack _ ls rs) | (n < 0) || (n > length(ls) + length(rs)) = s
| otherwise = listToStack n (integrate s)
focusNth' n s@(Stack _ ls rs) | (n < 0) || (n > length(ls) + length(rs)) = s
| otherwise = listToStack n (integrate s)
listToStack :: Int -> [a] -> Stack a
listToStack n l = Stack t ls rs
where (t:rs) = drop n l
ls = reverse (take n l)
where
(t:rs) = drop n l
ls = reverse (take n l)

View File

@@ -0,0 +1,302 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.GridSelect
-- Copyright : Clemens Fruhwirth <clemens@endorphin.org>
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Clemens Fruhwirth <clemens@endorphin.org>
-- Stability : unstable
-- Portability : unportable
--
-- GridSelect displays a 2D grid of windows to navigate with cursor
-- keys and to select with return.
--
-----------------------------------------------------------------------------
module XMonad.Actions.GridSelect (
-- * Usage
-- $usage
GSConfig(..),
defaultGSConfig,
gridselect,
withSelectedWindow,
bringSelected,
goToSelected,
default_colorizer
) where
import Data.Maybe
import Data.Bits
import Control.Monad.State
import Control.Arrow
import Data.List as L
import XMonad
import XMonad.Util.Font
import XMonad.Prompt (mkUnmanagedWindow)
import XMonad.StackSet as W
import XMonad.Layout.Decoration
import XMonad.Util.NamedWindows
import XMonad.Actions.WindowBringer (bringWindow)
import Text.Printf
-- $usage
--
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Actions.GridSelect
--
-- Then add a keybinding, e.g.
--
-- > , ((modMask x, xK_g), goToSelected defaultGSConfig)
--
-- Screenshot: <http://clemens.endorphin.org/gridselect.png>
data GSConfig = GSConfig {
gs_cellheight :: Integer,
gs_cellwidth :: Integer,
gs_cellpadding :: Integer,
gs_colorizer :: Window -> Bool -> X (String, String),
gs_font :: String
}
type TwoDPosition = (Integer, Integer)
type TwoDWindowMap = [(TwoDPosition,(String,Window))]
data TwoDState = TwoDState { td_curpos :: TwoDPosition,
td_windowmap :: [(TwoDPosition,(String,Window))],
td_gsconfig :: GSConfig,
td_font :: XMonadFont,
td_paneX :: Integer,
td_paneY :: Integer,
td_drawingWin :: Window
}
type TwoD a = StateT TwoDState X a
diamondLayer :: (Enum b', Num b') => b' -> [(b', b')]
-- FIXME remove nub
diamondLayer n = let ul = [ (x,n-x) | x <- [0..n] ]
in nub $ ul ++ (map (negate *** id) ul) ++
(map (negate *** negate) ul) ++
(map (id *** negate) ul)
diamond :: (Enum a, Num a) => [(a, a)]
diamond = concatMap diamondLayer [0..]
diamondRestrict :: (Enum t, Num t, Ord t) => t -> t -> [(t, t)]
diamondRestrict x y = L.filter (\(x',y') -> abs x' <= x && abs y' <= y) .
L.takeWhile (\(x',y') -> abs x' + abs y' <= x+y) $ diamond
tupadd :: (Num t1, Num t) => (t, t1) -> (t, t1) -> (t, t1)
tupadd (a,b) (c,d) = (a+c,b+d)
findInWindowMap :: (Eq a) => a -> [(a, b)] -> Maybe (a, b)
findInWindowMap pos = find ((== pos) . fst)
drawWinBox :: Window -> XMonadFont -> (String, String) -> Integer -> Integer -> String -> Integer -> Integer -> Integer -> X ()
drawWinBox win font (fg,bg) ch cw text x y cp =
withDisplay $ \dpy -> do
gc <- liftIO $ createGC dpy win
bordergc <- liftIO $ createGC dpy win
liftIO $ do
Just fgcolor <- initColor dpy fg
Just bgcolor <- initColor dpy bg
Just bordercolor <- initColor dpy borderColor
setForeground dpy gc fgcolor
setBackground dpy gc bgcolor
setForeground dpy bordergc bordercolor
fillRectangle dpy win gc (fromInteger x) (fromInteger y) (fromInteger cw) (fromInteger ch)
drawRectangle dpy win bordergc (fromInteger x) (fromInteger y) (fromInteger cw) (fromInteger ch)
stext <- shrinkWhile (shrinkIt shrinkText)
(\n -> do size <- liftIO $ textWidthXMF dpy font n
return $ size > (fromInteger (cw-(2*cp))))
text
printStringXMF dpy win font gc bg fg (fromInteger (x+cp)) (fromInteger (y+(div ch 2))) stext
liftIO $ freeGC dpy gc
liftIO $ freeGC dpy bordergc
updateAllWindows :: TwoD ()
updateAllWindows =
do
TwoDState { td_windowmap = wins } <- get
updateWindows wins
updateWindows :: TwoDWindowMap -> TwoD ()
updateWindows windowmap = do
TwoDState { td_curpos = curpos,
td_drawingWin = win,
td_gsconfig = gsconfig,
td_font = font,
td_paneX = paneX,
td_paneY = paneY} <- get
let cellwidth = gs_cellwidth gsconfig
cellheight = gs_cellheight gsconfig
paneX' = div (paneX-cellwidth) 2
paneY' = div (paneY-cellheight) 2
updateWindow (pos@(x,y),(text, clientwindow)) = lift $ do
colors <- (gs_colorizer gsconfig) clientwindow (pos == curpos)
drawWinBox win font
colors
cellheight
cellwidth
text
(paneX'+x*cellwidth)
(paneY'+y*cellheight)
(gs_cellpadding gsconfig)
mapM updateWindow windowmap
return ()
eventLoop :: TwoD (Maybe Window)
eventLoop = do
(keysym,string,event) <- lift $ withDisplay $ \d -> liftIO $ allocaXEvent $ \e -> do
nextEvent d e
ev <- getEvent e
(ks,s) <- if ev_event_type ev == keyPress
then lookupString $ asKeyEvent e
else return (Nothing, "")
return (ks,s,ev)
handle (fromMaybe xK_VoidSymbol keysym,string) event
handle :: (KeySym, String)
-> Event
-> StateT TwoDState X (Maybe Window)
handle (ks,_) (KeyEvent {ev_event_type = t})
| t == keyPress && ks == xK_Escape = return Nothing
| t == keyPress && (ks == xK_Left || ks == xK_h) = diffAndRefresh (-1,0)
| t == keyPress && (ks == xK_Right || ks == xK_l) = diffAndRefresh (1,0)
| t == keyPress && (ks == xK_Down || ks == xK_j) = diffAndRefresh (0,1)
| t == keyPress && (ks == xK_Up || ks == xK_k) = diffAndRefresh (0,-1)
| t == keyPress && ks == xK_Return = do
(TwoDState { td_curpos = pos, td_windowmap = winmap }) <- get
return $ fmap (snd . snd) $ findInWindowMap pos winmap
where diffAndRefresh diff = do
state <- get
let windowmap = td_windowmap state
oldPos = td_curpos state
newPos = oldPos `tupadd` diff
newSelectedWin = findInWindowMap newPos windowmap
when (isJust newSelectedWin) $ do
put state { td_curpos = newPos }
updateWindows (catMaybes [(findInWindowMap oldPos windowmap), newSelectedWin])
eventLoop
handle _ (ExposeEvent { }) = do
updateAllWindows
eventLoop
handle _ _ = do
eventLoop
-- FIXME probably move that into Utils?
-- Conversion scheme as in http://en.wikipedia.org/wiki/HSV_color_space
hsv2rgb :: Fractional a => (Integer,a,a) -> (a,a,a)
hsv2rgb (h,s,v) =
let hi = (div h 60) `mod` 6 :: Integer
f = (((fromInteger h)/60) - (fromInteger hi)) :: Fractional a => a
q = v * (1-f)
p = v * (1-s)
t = v * (1-(1-f)*s)
in case hi of
0 -> (v,t,p)
1 -> (q,v,p)
2 -> (p,v,t)
3 -> (p,q,v)
4 -> (t,p,v)
5 -> (v,p,q)
_ -> error "The world is ending. x mod a >= a."
default_colorizer :: Window -> Bool -> X (String, String)
default_colorizer w active = do
classname <- runQuery className w
let seed x = toInteger (sum $ map ((*x).fromEnum) classname) :: Integer
(r,g,b) = hsv2rgb ((seed 83) `mod` 360,
(fromInteger ((seed 191) `mod` 1000))/2500+0.4,
(fromInteger ((seed 121) `mod` 1000))/2500+0.4)
if active
then return ("#faff69", "black")
else return ("#" ++ concat (map (twodigitHex.(round :: Double -> Integer).(*256)) [r, g, b] ), "white")
where
twodigitHex :: Integer -> String
twodigitHex a = printf "%02x" a
-- | Brings up a 2D grid of windows in the center of the screen, and one can
-- select a window with cursors keys. The selected window is returned.
gridselect :: GSConfig -> X (Maybe Window)
gridselect gsconfig =
withDisplay $ \dpy -> do
rootw <- liftIO $ rootWindow dpy (defaultScreen dpy)
s <- gets $ screenRect . W.screenDetail . W.current . windowset
windowList <- windowMap
win <- liftIO $ mkUnmanagedWindow dpy (defaultScreenOfDisplay dpy) rootw
(rect_x s) (rect_y s) (rect_width s) (rect_height s)
liftIO $ mapWindow dpy win
liftIO $ selectInput dpy win (exposureMask .|. keyPressMask)
status <- io $ grabKeyboard dpy win True grabModeAsync grabModeAsync currentTime
font <- initXMF (gs_font gsconfig)
let screenWidth = toInteger $ rect_width s;
screenHeight = toInteger $ rect_height s;
selectedWindow <- if (status == grabSuccess) then
do
let restriction :: Integer -> (GSConfig -> Integer) -> Double
restriction ss cs = ((fromInteger ss)/(fromInteger $ cs gsconfig)-1)/2
restrictX = floor $ restriction screenWidth gs_cellwidth
restrictY = floor $ restriction screenHeight gs_cellheight
winmap = zipWith (,) (diamondRestrict restrictX restrictY) windowList
selectedWindow <- evalStateT (do updateAllWindows; eventLoop)
(TwoDState (0,0)
winmap
gsconfig
font
screenWidth
screenHeight
win)
return selectedWindow
else
return Nothing
liftIO $ do
unmapWindow dpy win
destroyWindow dpy win
sync dpy False
releaseXMF font
return selectedWindow
-- | Brings up a 2D grid of windows in the center of the screen, and one can
-- select a window with cursors keys. The selected window is then passed to
-- a callback function.
withSelectedWindow :: (Window -> X ()) -> GSConfig -> X ()
withSelectedWindow callback conf = do
mbWindow <- gridselect conf
case mbWindow of
Just w -> callback w
Nothing -> return ()
windowMap :: X [(String,Window)]
windowMap = do
ws <- gets windowset
wins <- mapM keyValuePair (W.allWindows ws)
return wins
where keyValuePair w = flip (,) w `fmap` decorateName' w
decorateName' :: Window -> X String
decorateName' w = do
fmap show $ getName w
defaultGSConfig :: GSConfig
defaultGSConfig = GSConfig 50 130 10 default_colorizer "xft:Sans-8"
borderColor :: String
borderColor = "white"
-- | Brings selected window to the current workspace.
bringSelected :: GSConfig -> X ()
bringSelected = withSelectedWindow $ \w -> do
windows (bringWindow w)
XMonad.focus w
windows W.shiftMaster
-- | Switches to selected window's workspace and focuses that window.
goToSelected :: GSConfig -> X ()
goToSelected = withSelectedWindow $ windows . W.focusWindow

View File

@@ -0,0 +1,137 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.MouseGestures
-- Copyright : (c) Lukas Mai
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : <l.mai@web.de>
-- Stability : unstable
-- Portability : unportable
--
-- Support for simple mouse gestures.
--
-----------------------------------------------------------------------------
module XMonad.Actions.MouseGestures (
-- * Usage
-- $usage
Direction(..),
mouseGestureH,
mouseGesture,
mkCollect
) where
import XMonad
import XMonad.Hooks.ManageDocks (Direction(..))
import Data.IORef
import qualified Data.Map as M
import Data.Map (Map)
import Data.Maybe
import Control.Monad
-- $usage
--
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Actions.MouseGestures
-- > import qualified XMonad.StackSet as W
--
-- then add an appropriate mouse binding:
--
-- > , ((modMask x .|. shiftMask, button3), mouseGesture gestures)
--
-- where @gestures@ is a 'Data.Map.Map' from gestures to actions on
-- windows, for example:
--
-- > gestures = M.fromList
-- > [ ([], focus)
-- > , ([U], \w -> focus w >> windows W.swapUp)
-- > , ([D], \w -> focus w >> windows W.swapDown)
-- > , ([R, D], \_ -> sendMessage NextLayout)
-- > ]
--
-- This is just an example, of course; you can use any mouse button and
-- gesture definitions you want.
--
-- For detailed instructions on editing your mouse bindings, see
-- "XMonad.Doc.Extending#Editing_mouse_bindings".
type Pos = (Position, Position)
delta :: Pos -> Pos -> Position
delta (ax, ay) (bx, by) = max (d ax bx) (d ay by)
where
d a b = abs (a - b)
dir :: Pos -> Pos -> Direction
dir (ax, ay) (bx, by) = trans . (/ pi) $ atan2 (fromIntegral $ ay - by) (fromIntegral $ bx - ax)
where
trans :: Double -> Direction
trans x
| rg (-3/4) (-1/4) x = D
| rg (-1/4) (1/4) x = R
| rg (1/4) (3/4) x = U
| otherwise = L
rg a z x = a <= x && x < z
gauge :: (Direction -> X ()) -> Pos -> IORef (Maybe (Direction, Pos)) -> Position -> Position -> X ()
gauge hook op st nx ny = do
let np = (nx, ny)
stx <- io $ readIORef st
let
(~(Just od), pivot) = case stx of
Nothing -> (Nothing, op)
Just (d, zp) -> (Just d, zp)
cont = do
guard $ significant np pivot
return $ do
let d' = dir pivot np
when (isNothing stx || od /= d') $ hook d'
io $ writeIORef st (Just (d', np))
fromMaybe (return ()) cont
where
significant a b = delta a b >= 10
-- | @'mouseGestureH' moveHook endHook@ is a mouse button
-- event handler. It collects mouse movements, calling @moveHook@ for each
-- update; when the button is released, it calls @endHook@.
mouseGestureH :: (Direction -> X ()) -> X () -> X ()
mouseGestureH moveHook endHook = do
dpy <- asks display
root <- asks theRoot
(pos, acc) <- io $ do
(_, _, _, ix, iy, _, _, _) <- queryPointer dpy root
r <- newIORef Nothing
return ((fromIntegral ix, fromIntegral iy), r)
mouseDrag (gauge moveHook pos acc) endHook
-- | A utility function on top of 'mouseGestureH'. It uses a 'Data.Map.Map' to
-- look up the mouse gesture, then executes the corresponding action (if any).
mouseGesture :: Map [Direction] (Window -> X ()) -> Window -> X ()
mouseGesture tbl win = do
(mov, end) <- mkCollect
mouseGestureH (\d -> mov d >> return ()) $ end >>= \gest ->
case M.lookup gest tbl of
Nothing -> return ()
Just f -> f win
-- | A callback generator for 'mouseGestureH'. 'mkCollect' returns two
-- callback functions for passing to 'mouseGestureH'. The move hook will
-- collect mouse movements (and return the current gesture as a list); the end
-- hook will return a list of the completed gesture, which you can access with
-- 'Control.Monad.>>='.
mkCollect :: (MonadIO m, MonadIO m') => m (Direction -> m' [Direction], m' [Direction])
mkCollect = liftIO $ do
acc <- newIORef []
let
mov d = liftIO $ do
ds <- readIORef acc
let ds' = d : ds
writeIORef acc ds'
return $ reverse ds'
end = liftIO $ do
ds <- readIORef acc
writeIORef acc []
return $ reverse ds
return (mov, end)

View File

@@ -0,0 +1,133 @@
{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.MouseResize
-- Copyright : (c) 2007 Andrea Rossato
-- License : BSD-style (see xmonad/LICENSE)
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : unportable
--
-- A layout modifier to resize windows with the mouse by grabbing the
-- window's lower right corner.
--
-- This module must be used together with "XMonad.Layout.WindowArranger".
-----------------------------------------------------------------------------
module XMonad.Actions.MouseResize
( -- * Usage:
-- $usage
mouseResize
, MouseResize (..)
) where
import Control.Monad
import Data.Maybe
import XMonad
import XMonad.Layout.Decoration
import XMonad.Layout.LayoutModifier
import XMonad.Layout.WindowArranger
import XMonad.Util.XUtils
-- $usage
-- Usually this module is used to create layouts, but you can also use
-- it to resize windows in any layout, together with the
-- "XMonad.Layout.WindowArranger". For usage example see
-- "XMonad.Layout.SimpleFloat" or "XMonad.Layout.DecorationMadness".
--
-- You can use this module with the following in your
-- @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Actions.MouseResize
-- > import XMonad.Layout.WindowArranger
--
-- Then edit your @layoutHook@ by modifying a given layout:
--
-- > myLayouts = mouseResize $ windowArrange $ layoutHook defaultConfig
--
-- and then:
--
-- > main = xmonad defaultConfig { layoutHook = myLayouts }
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
mouseResize :: l a -> ModifiedLayout MouseResize l a
mouseResize = ModifiedLayout (MR [])
data MouseResize a = MR [((a,Rectangle),Maybe a)]
instance Show (MouseResize a) where show _ = ""
instance Read (MouseResize a) where readsPrec _ s = [(MR [], s)]
instance LayoutModifier MouseResize Window where
redoLayout _ _ Nothing wrs = return (wrs, Nothing)
redoLayout (MR st) _ (Just s) wrs
| [] <- st = initState >>= \nst -> return (wrs, Just $ MR nst)
| otherwise = processState >>= \nst -> return (wrs, Just $ MR nst)
where
wrs' = wrs_to_state [] . filter (isInStack s . fst) $ wrs
initState = mapM createInputWindow wrs'
processState = mapM (deleteInputWin . snd) st >> mapM createInputWindow wrs'
inputRectangle (Rectangle x y wh ht) = Rectangle (x + fi wh - 5) (y + fi ht - 5) 10 10
wrs_to_state rs ((w,r):xs)
| ir `isVisible` rs = ((w,r),Just ir) : wrs_to_state (r:ir:rs) xs
| otherwise = ((w,r),Nothing) : wrs_to_state (r: rs) xs
where ir = inputRectangle r
wrs_to_state _ [] = []
handleMess (MR s) m
| Just e <- fromMessage m :: Maybe Event = handleResize s e >> return Nothing
| Just Hide <- fromMessage m = releaseResources >> return (Just $ MR [])
| Just ReleaseResources <- fromMessage m = releaseResources >> return (Just $ MR [])
where releaseResources = mapM_ (deleteInputWin . snd) s
handleMess _ _ = return Nothing
handleResize :: [((Window,Rectangle),Maybe Window)] -> Event -> X ()
handleResize st ButtonEvent { ev_window = ew, ev_event_type = et }
| et == buttonPress
, Just (w,Rectangle wx wy _ _) <- getWin ew st = do
focus w
mouseDrag (\x y -> do
let rect = Rectangle wx wy
(max 1 . fi $ x - wx)
(max 1 . fi $ y - wy)
sendMessage (SetGeometry rect)) (return ())
where
getWin w (((win,r),tw):xs)
| Just w' <- tw
, w == w' = Just (win,r)
| otherwise = getWin w xs
getWin _ [] = Nothing
handleResize _ _ = return ()
createInputWindow :: ((Window,Rectangle), Maybe Rectangle) -> X ((Window,Rectangle),Maybe Window)
createInputWindow ((w,r),mr) = do
case mr of
Just tr -> withDisplay $ \d -> do
tw <- mkInputWindow d tr
io $ selectInput d tw (exposureMask .|. buttonPressMask)
showWindow tw
return ((w,r), Just tw)
Nothing -> return ((w,r), Nothing)
deleteInputWin :: Maybe Window -> X ()
deleteInputWin = maybe (return ()) deleteWindow
mkInputWindow :: Display -> Rectangle -> X Window
mkInputWindow d (Rectangle x y w h) = do
rw <- asks theRoot
let screen = defaultScreenOfDisplay d
visual = defaultVisualOfScreen screen
attrmask = cWOverrideRedirect
io $ allocaSetWindowAttributes $
\attributes -> do
set_override_redirect attributes True
createWindow d rw x y w h 0 0 inputOnly visual attrmask attributes

View File

@@ -0,0 +1,33 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.NoBorders
-- Copyright : (c) Lukas Mai
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Lukas Mai <l.mai@web.de>
-- Stability : unstable
-- Portability : unportable
--
-- This module provides helper functions for dealing with window borders.
--
-----------------------------------------------------------------------------
module XMonad.Actions.NoBorders (
toggleBorder
) where
import XMonad
-- | Toggle the border of the currently focused window. To use it, add a
-- keybinding like so:
--
-- > , ((modMask x, xK_g ), withFocused toggleBorder)
--
toggleBorder :: Window -> X ()
toggleBorder w = do
bw <- asks (borderWidth . config)
withDisplay $ \d -> io $ do
cw <- wa_border_width `fmap` getWindowAttributes d w
if cw == 0
then setWindowBorderWidth d w bw
else setWindowBorderWidth d w 0

View File

@@ -0,0 +1,50 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.PerWorkspaceKeys
-- Copyright : (c) Roman Cheplyaka, 2008
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Roman Cheplyaka <roma@ro-che.info>
-- Stability : unstable
-- Portability : unportable
--
-- Define key-bindings on per-workspace basis.
--
-----------------------------------------------------------------------------
module XMonad.Actions.PerWorkspaceKeys (
-- * Usage
-- $usage
chooseAction,
bindOn
) where
import XMonad
import XMonad.StackSet as S
import Data.List (find)
-- $usage
--
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Actions.PerWorkspaceKeys
--
-- > ,((0, xK_F2), bindOn [("1", spawn "rxvt"), ("2", spawn "xeyes"), ("", spawn "xmessage hello")])
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Uses supplied function to decide which action to run depending on current workspace name.
chooseAction :: (String->X()) -> X()
chooseAction f = withWindowSet (f . S.currentTag)
-- | If current workspace is listed, run appropriate action (only the first match counts!)
-- If it isn't listed, then run default action (marked with empty string, \"\"), or do nothing if default isn't supplied.
bindOn :: [(String, X())] -> X()
bindOn bindings = chooseAction chooser where
chooser ws = case find ((ws==).fst) bindings of
Just (_, action) -> action
Nothing -> case find ((""==).fst) bindings of
Just (_, action) -> action
Nothing -> return ()

229
XMonad/Actions/Plane.hs Normal file
View File

@@ -0,0 +1,229 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.Plane
-- Copyright : (c) Marco Túlio Gontijo e Silva <marcot@riseup.net>,
-- Leonardo Serra <leoserra@minaslivre.org>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Marco Túlio Gontijo e Silva <marcot@riseup.net>
-- Stability : unstable
-- Portability : unportable
--
-- This module has functions to navigate through workspaces in a bidimensional
-- manner. It allows the organization of workspaces in lines, and provides
-- functions to move and shift windows in all four directions (left, up, right
-- and down) possible in a surface.
--
-- This functionality was inspired by GNOME (finite) and KDE (infinite)
-- keybindings for workspace navigation, and by "XMonad.Actions.CycleWS" for
-- the idea of applying this approach to XMonad.
-----------------------------------------------------------------------------
module XMonad.Actions.Plane
(
-- * Usage
-- $usage
-- * Data types
Direction (..)
, Limits (..)
, Lines (..)
-- * Key bindings
, planeKeys
-- * Navigating through workspaces
, planeShift
, planeMove
)
where
import Control.Monad
import Data.List
import Data.Map hiding (split)
import Data.Maybe
import XMonad
import XMonad.StackSet hiding (workspaces)
import XMonad.Util.Run
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:
--
-- > import XMonad.Actions.Plane
-- >
-- > main = xmonad defaultConfig {keys = myKeys}
-- >
-- > myKeys conf = union (keys defaultConfig conf) $ myNewKeys conf
-- >
-- > myNewkeys (XConfig {modMask = modm}) = planeKeys modm (Lines 3) Finite
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Direction to go in the plane.
data Direction = ToLeft | ToUp | ToRight | ToDown deriving Enum
-- | Defines the behaviour when you're trying to move out of the limits.
data Limits
= Finite -- ^ Ignore the function call, and keep in the same workspace.
| Circular -- ^ Get on the other side, like in the Snake game.
| Linear -- ^ The plan comes as a row, so it goes to the next or prev if
-- the workspaces were numbered.
deriving Eq
-- | The number of lines in which the workspaces will be arranged. It's
-- possible to use a number of lines that is not a divisor of the number of
-- workspaces, but the results are better when using a divisor. If it's not a
-- divisor, the last line will have the remaining workspaces.
data Lines
= GConf -- ^ Use @gconftool-2@ to find out the number of lines.
| Lines Int -- ^ Specify the number of lines explicity.
-- | This is the way most people would like to use this module. It ataches the
-- 'KeyMask' passed as a parameter with 'xK_Left', 'xK_Up', 'xK_Right' and
-- 'xK_Down', associating it with 'planeMove' to the corresponding 'Direction'.
-- It also associates these bindings with 'shiftMask' to 'planeShift'.
planeKeys :: KeyMask -> Lines -> Limits -> Map (KeyMask, KeySym) (X ())
planeKeys modm ln limits =
fromList $
[ ((keyMask, keySym), function ln limits direction)
| (keySym, direction) <- zip [xK_Left .. xK_Down] $ enumFrom ToLeft
, (keyMask, function) <- [(modm, planeMove), (shiftMask .|. modm, planeShift)]
]
-- | Shift a window to the next workspace in 'Direction'. Note that this will
-- also move to the next workspace. It's a good idea to use the same 'Lines'
-- and 'Limits' for all the bindings.
planeShift :: Lines -> Limits -> Direction -> X ()
planeShift = plane shift'
shift' ::
(Eq s, Eq i, Ord a) => i -> StackSet i l a s sd -> StackSet i l a s sd
shift' area = greedyView area . shift area
-- | Move to the next workspace in 'Direction'.
planeMove :: Lines -> Limits -> Direction -> X ()
planeMove = plane greedyView
plane ::
(WorkspaceId -> WindowSet -> WindowSet) -> Lines -> Limits -> Direction ->
X ()
plane function numberLines_ limits direction = do
state <- get
xconf <- ask
numberLines <-
liftIO $
case numberLines_ of
Lines numberLines__ ->
return numberLines__
GConf ->
do
numberLines__ <-
runProcessWithInput gconftool parameters ""
case reads numberLines__ of
[(numberRead, _)] -> return numberRead
_ ->
do
trace $
"XMonad.Actions.Plane: Could not parse the output of " ++ gconftool ++
unwords parameters ++ ": " ++ numberLines__ ++ "; assuming 1."
return 1
let
notBorder :: Bool
notBorder = (replicate 2 (circular_ < currentWS) ++ replicate 2 (circular_ > currentWS)) !! fromEnum direction
circular_ :: Int
circular_ = circular currentWS
circular :: Int -> Int
circular =
[ onLine pred
, onColumn pred
, onLine succ
, onColumn succ
]
!! fromEnum direction
linear :: Int -> Int
linear =
[ onLine pred . onColumn pred
, onColumn pred . onLine pred
, onLine succ . onColumn succ
, onColumn succ . onLine succ
]
!! fromEnum direction
onLine :: (Int -> Int) -> Int -> Int
onLine f currentWS_
| line < areasLine = mod_ columns
| otherwise = mod_ areasColumn
where
line, column :: Int
(line, column) = split currentWS_
mod_ :: Int -> Int
mod_ columns_ = compose line $ mod (f column) columns_
onColumn :: (Int -> Int) -> Int -> Int
onColumn f currentWS_
| column < areasColumn || areasColumn == 0 = mod_ numberLines
| otherwise = mod_ $ pred numberLines
where
line, column :: Int
(line, column) = split currentWS_
mod_ :: Int -> Int
mod_ lines_ = compose (mod (f line) lines_) column
compose :: Int -> Int -> Int
compose line column = line * columns + column
split :: Int -> (Int, Int)
split currentWS_ =
(operation div, operation mod)
where
operation :: (Int -> Int -> Int) -> Int
operation f = f currentWS_ columns
areasLine :: Int
areasLine = div areas columns
areasColumn :: Int
areasColumn = mod areas columns
columns :: Int
columns =
if mod areas numberLines == 0 then preColumns else preColumns + 1
currentWS :: Int
currentWS = fromJust mCurrentWS
preColumns :: Int
preColumns = div areas numberLines
mCurrentWS :: Maybe Int
mCurrentWS = elemIndex (currentTag $ windowset state) areaNames
areas :: Int
areas = length areaNames
run :: (Int -> Int) -> X ()
run f = windows $ function $ areaNames !! f currentWS
areaNames :: [String]
areaNames = workspaces $ config xconf
when (isJust mCurrentWS) $
case limits of
Finite -> when notBorder $ run circular
Circular -> run circular
Linear -> if notBorder then run circular else run linear
gconftool :: String
gconftool = "gconftool-2"
parameters :: [String]
parameters = ["--get", "/apps/panel/applets/workspace_switcher_screen0/prefs/num_rows"]

49
XMonad/Actions/Promote.hs Normal file
View File

@@ -0,0 +1,49 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.Promote
-- Copyright : (c) Miikka Koskinen 2007
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : xmonad@s001.ethrael.com
-- Stability : unstable
-- Portability : unportable
--
-- Alternate promote function for xmonad.
--
-- Moves the focused window to the master pane. All other windows
-- retain their order. If focus is in the master, swap it with the
-- next window in the stack. Focus stays in the master.
--
-----------------------------------------------------------------------------
module XMonad.Actions.Promote (
-- * Usage
-- $usage
promote
) where
import XMonad
import XMonad.StackSet
-- $usage
--
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Actions.Promote
--
-- then add a keybinding or substitute 'promote' in place of swapMaster:
--
-- > , ((modMask x, xK_Return), promote)
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Move the focused window to the master pane. All other windows
-- retain their order. If focus is in the master, swap it with the
-- next windo in the stack. Focus stays in the master.
promote :: X ()
promote = windows $ modify' $
\c -> case c of
Stack _ [] [] -> c
Stack t [] (x:rs) -> Stack x [] (t:rs)
Stack t ls rs -> Stack t [] (reverse ls ++ rs)

View File

@@ -0,0 +1,62 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.RotSlaves
-- Copyright : (c) Hans Philipp Annen <haphi@gmx.net>, Mischa Dieterle <der_m@freenet.de>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Hans Philipp Annen <haphi@gmx.net>
-- Stability : unstable
-- Portability : unportable
--
-- Rotate all windows except the master window and keep the focus in
-- place.
-----------------------------------------------------------------------------
module XMonad.Actions.RotSlaves (
-- $usage
rotSlaves', rotSlavesUp, rotSlavesDown,
rotAll', rotAllUp, rotAllDown
) where
import XMonad.StackSet
import XMonad
-- $usage
--
-- To use this module, import it with:
--
-- > import XMonad.Actions.RotSlaves
--
-- and add whatever keybindings you would like, for example:
--
-- > , ((modMask x .|. shiftMask, xK_Tab ), rotSlavesUp)
--
-- This operation will rotate all windows except the master window,
-- while the focus stays where it is. It is useful together with the
-- TwoPane layout (see "XMonad.Layout.TwoPane").
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Rotate the windows in the current stack, excluding the first one
-- (master).
rotSlavesUp,rotSlavesDown :: X ()
rotSlavesUp = windows $ modify' (rotSlaves' (\l -> (tail l)++[head l]))
rotSlavesDown = windows $ modify' (rotSlaves' (\l -> [last l]++(init l)))
-- | The actual rotation, as a pure function on the window stack.
rotSlaves' :: ([a] -> [a]) -> Stack a -> Stack a
rotSlaves' _ s@(Stack _ [] []) = s
rotSlaves' f (Stack t [] rs) = Stack t [] (f rs) -- Master has focus
rotSlaves' f s@(Stack _ ls _ ) = Stack t' (reverse revls') rs' -- otherwise
where (master:ws) = integrate s
(revls',t':rs') = splitAt (length ls) (master:(f ws))
-- | Rotate all the windows in the current stack.
rotAllUp,rotAllDown :: X ()
rotAllUp = windows $ modify' (rotAll' (\l -> (tail l)++[head l]))
rotAllDown = windows $ modify' (rotAll' (\l -> [last l]++(init l)))
-- | The actual rotation, as a pure function on the window stack.
rotAll' :: ([a] -> [a]) -> Stack a -> Stack a
rotAll' f s = Stack r (reverse revls) rs
where (revls,r:rs) = splitAt (length (up s)) (f (integrate s))

288
XMonad/Actions/Search.hs Normal file
View File

@@ -0,0 +1,288 @@
{- | Module : XMonad.Actions.Search
Copyright : (C) 2007 Gwern Branwen
License : None; public domain
Maintainer : <gwern0@gmail.com>
Stability : unstable
Portability : unportable; depends on XSelection, XPrompt
A module for easily running Internet searches on web sites through xmonad.
Modeled after the handy Surfraw CLI search tools at <https://secure.wikimedia.org/wikipedia/en/wiki/Surfraw>.
Additional sites welcomed. -}
module XMonad.Actions.Search ( -- * Usage
-- $usage
search,
SearchEngine(..),
searchEngine,
promptSearch,
promptSearchBrowser,
selectSearch,
selectSearchBrowser,
amazon,
codesearch,
deb,
debbts,
debpts,
dictionary,
google,
hackage,
hoogle,
images,
imdb,
isohunt,
maps,
mathworld,
scholar,
thesaurus,
wayback,
wikipedia,
youtube
-- * Use case: searching with a submap
-- $tip
) where
import Data.Char (chr, ord, isAlpha, isMark, isDigit)
import Numeric (showIntAtBase)
import XMonad (X(), MonadIO, liftIO)
import XMonad.Prompt (XPrompt(showXPrompt), mkXPrompt, XPConfig(), historyCompletion)
import XMonad.Prompt.Shell (getBrowser)
import XMonad.Util.Run (safeSpawn)
import XMonad.Util.XSelection (getSelection)
{- $usage
This module is intended to allow easy access to databases on the
Internet through xmonad's interface. The idea is that one wants to
run a search but the query string and the browser to use must come
from somewhere. There are two places the query string can come from
- the user can type it into a prompt which pops up, or the query
could be available already in the X Windows copy\/paste buffer
(perhaps you just highlighted the string of interest).
Thus, there are two main functions: 'promptSearch', and
'selectSearch' (implemented using the more primitive 'search'). To
each of these is passed an engine function; this is a function that
knows how to search a particular site.
For example, the 'google' function knows how to search Google, and
so on. You pass 'promptSearch' and 'selectSearch' the engine you
want, the browser you want, and anything special they might need;
this whole line is then bound to a key of you choosing in your
xmonad.hs. For specific examples, see each function. This module
is easily extended to new sites by using 'searchEngine'.
The currently available search engines are:
* 'amazon' -- Amazon keyword search.
* 'codesearch' -- Google Labs Code Search search.
* 'deb' -- Debian package search.
* 'debbts' -- Debian Bug Tracking System.
* 'debpts -- Debian Package Tracking System.
* 'dictionary' -- dictionary.reference.com search.
* 'google' -- basic Google search.
* 'hackage' -- Hackage, the Haskell package database.
* 'hoogle' -- Hoogle, the Haskell libraries API search engine.
* 'images' -- Google images.
* 'imdb' -- the Internet Movie Database.
* 'isohunt' -- isoHunt search.
* 'maps' -- Google maps.
* 'mathworld' -- Wolfram MathWorld search.
* 'scholar' -- Google scholar academic search.
* 'thesaurus' -- thesaurus.reference.com search.
* 'wayback' -- the Wayback Machine.
* 'wikipedia' -- basic Wikipedia search.
* 'youtube' -- Youtube video search.
Feel free to add more! -}
{- $tip
In combination with "XMonad.Actions.Submap" you can create a powerful
and easy way to search without adding a whole bunch of bindings.
First import the necessary modules:
> import qualified XMonad.Prompt as P
> import qualified XMonad.Actions.Submap as SM
> import qualified XMonad.Actions.Search as S
Then add the following to your key bindings:
> ...
> -- Search commands
> , ((modm, xK_s), SM.submap $ searchEngineMap $ S.promptSearch P.defaultXPConfig)
> , ((modm .|. shiftMask, xK_s), SM.submap $ searchEngineMap $ S.selectSearch)
>
> ...
>
> searchEngineMap method = M.fromList $
> [ ((0, xK_g), method S.google)
> , ((0, xK_h), method S.hoogle)
> , ((0, xK_w), method S.wikipedia)
> ]
Or in combination with XMonad.Util.EZConfig:
> ...
> ] -- end of regular keybindings
> -- Search commands
> ++ [("M-s " ++ k, S.promptSearch P.defaultXPConfig f) | (k,f) <- searchList ]
> ++ [("M-S-s " ++ k, S.selectSearch f) | (k,f) <- searchList ]
>
> ...
>
> searchList :: [([Char], S.SearchEngine)]
> searchList = [ ("g", S.google)
> , ("h", S.hoohle)
> , ("w", S.wikipedia)
> ]
Make sure to set firefox to open new pages in a new window instead of
in a new tab: @Firefox -> Edit -> Preferences -> Tabs -> New pages
should be opened in...@
Now /mod-s/ + /g/\//h/\//w/ prompts you for a search string, then
opens a new firefox window that performs the search on Google, Hoogle
or Wikipedia respectively.
If you select something in whatever application and hit /mod-shift-s/ +
/g/\//h/\//w/ it will search the selected string with the specified
engine.
Happy searching! -}
-- | A customized prompt indicating we are searching, and the name of the site.
data Search = Search Name
instance XPrompt Search where
showXPrompt (Search name)= "Search [" ++ name ++ "]: "
-- | Escape the search string so search engines understand it.
-- Note that everything is escaped; we could be smarter and use 'isAllowedInURI'
-- but then that'd be hard enough to copy-and-paste we'd need to depend on @network@.
escape :: String -> String
escape = escapeURIString (\c -> isAlpha c || isDigit c || isMark c)
where -- Copied from Network.URI.
escapeURIString ::
(Char -> Bool) -- a predicate which returns 'False' if should escape
-> String -- the string to process
-> String -- the resulting URI string
escapeURIString = concatMap . escapeURIChar
escapeURIChar :: (Char->Bool) -> Char -> String
escapeURIChar p c
| p c = [c]
| otherwise = '%' : myShowHex (ord c) ""
where
myShowHex :: Int -> ShowS
myShowHex n r = case showIntAtBase 16 toChrHex n r of
[] -> "00"
[ch] -> ['0',ch]
cs -> cs
toChrHex d
| d < 10 = chr (ord '0' + fromIntegral d)
| otherwise = chr (ord 'A' + fromIntegral (d - 10))
type Browser = FilePath
type Query = String
type Site = String
type Name = String
data SearchEngine = SearchEngine Name Site
-- | Given a browser, a search engine, and a search term, perform the
-- requested search in the browser.
search :: Browser -> Site -> Query -> X ()
search browser site query = safeSpawn browser $ site ++ escape query
{- | Given a base URL, create the 'SearchEngine' that escapes the query and
appends it to the base. You can easily define a new engine locally using
exported functions without needing to modify "XMonad.Actions.Search":
> myNewEngine = searchEngine "site" "http://site.com/search="
The important thing is that the site has a interface which accepts the escaped query
string as part of the URL. Alas, the exact URL to feed searchEngine varies
from site to site, often considerably, so there's no general way to cover this.
Generally, examining the resultant URL of a search will allow you to reverse-engineer
it if you can't find the necessary URL already described in other projects such as Surfraw. -}
searchEngine :: Name -> Site -> SearchEngine
searchEngine = SearchEngine
-- The engines.
amazon, codesearch, deb, debbts, debpts, dictionary, google, hackage, hoogle, images,
imdb, isohunt, maps, mathworld, scholar, thesaurus, wayback, wikipedia,
youtube :: SearchEngine
amazon = searchEngine "amazon" "http://www.amazon.com/exec/obidos/external-search?index=all&keyword="
codesearch = searchEngine "codesearch" "http://www.google.com/codesearch?q="
deb = searchEngine "deb" "http://packages.debian.org/"
debbts = searchEngine "debbts" "http://bugs.debian.org/"
debpts = searchEngine "debpts" "http://packages.qa.debian.org/"
dictionary = searchEngine "dictionary" "http://dictionary.reference.com/browse/"
google = searchEngine "google" "http://www.google.com/search?num=100&q="
hackage = searchEngine "hackage" "http://hackage.haskell.org/cgi-bin/hackage-scripts/package/"
hoogle = searchEngine "hoogle" "http://www.haskell.org/hoogle/?q="
images = searchEngine "images" "http://images.google.fr/images?q="
imdb = searchEngine "imdb" "http://www.imdb.com/Find?select=all&for="
isohunt = searchEngine "isohunt" "http://isohunt.com/torrents/?ihq="
maps = searchEngine "maps" "http://maps.google.com/maps?q="
mathworld = searchEngine "mathworld" "http://mathworld.wolfram.com/search/?query="
scholar = searchEngine "scholar" "http://scholar.google.com/scholar?q="
thesaurus = searchEngine "thesaurus" "http://thesaurus.reference.com/search?q="
wikipedia = searchEngine "wikipedia" "https://secure.wikimedia.org/wikipedia/en/wiki/Special:Search?go=Go&search="
youtube = searchEngine "youtube" "http://www.youtube.com/results?search_type=search_videos&search_query="
{- This doesn't seem to work, but nevertheless, it seems to be the official
method at <http://web.archive.org/collections/web/advanced.html> to get the
latest backup. -}
wayback = searchEngine "wayback" "http://web.archive.org/"
{- | Like 'search', but for use with the output from a Prompt; it grabs the
Prompt's result, passes it to a given searchEngine and opens it in a given
browser. -}
promptSearchBrowser :: XPConfig -> Browser -> SearchEngine -> X ()
promptSearchBrowser config browser (SearchEngine name site) = mkXPrompt (Search name) config historyCompletion $ search browser site
{- | Like 'search', but in this case, the string is not specified but grabbed
from the user's response to a prompt. Example:
> , ((modm, xK_g), promptSearch greenXPConfig google)
This specializes "promptSearchBrowser" by supplying the browser argument as
supplied by 'getBrowser' from "XMonad.Prompt.Shell". -}
promptSearch :: XPConfig -> SearchEngine -> X ()
promptSearch config engine = liftIO getBrowser >>= \ browser -> promptSearchBrowser config browser engine
-- | Like 'search', but for use with the X selection; it grabs the selection,
-- passes it to a given searchEngine and opens it in a given browser.
selectSearchBrowser :: Browser -> SearchEngine -> X ()
selectSearchBrowser browser (SearchEngine _ site) = search browser site =<< getSelection
{- | Like 'search', but for use with the X selection; it grabs the selection,
passes it to a given searchEngine and opens it in the default browser . Example:
> , ((modm .|. shiftMask, xK_g), selectSearch google)
This specializes "selectSearchBrowser" by supplying the browser argument as
supplied by 'getBrowser' from "XMonad.Prompt.Shell". -}
selectSearch :: SearchEngine -> X ()
selectSearch engine = liftIO getBrowser >>= \browser -> selectSearchBrowser browser engine

View File

@@ -1,9 +1,9 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.SimpleDate
-- Module : XMonad.Actions.SimpleDate
-- Copyright : (c) Don Stewart 2007
-- License : BSD3-style (see LICENSE)
--
--
-- Maintainer : dons@cse.unsw.edu.au
-- Stability : stable
-- Portability : portable
@@ -13,27 +13,28 @@
--
-----------------------------------------------------------------------------
module XMonadContrib.SimpleDate (
module XMonad.Actions.SimpleDate (
-- * Usage
-- $usage
date
) where
import XMonad
import XMonad.Core
import XMonad.Util.Run
-- $usage
-- To use, modify your Config.hs to:
-- To use, import this module into @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonadContrib.SimpleDate
-- > import XMonad.Actions.SimpleDate
--
-- and add a keybinding:
-- and add a keybinding, for example:
--
-- > , ((modMask, xK_d ), date)
-- > , ((modMask x, xK_d ), date)
--
-- a popup date menu will now be bound to mod-d
-- %import XMonadContrib.SimpleDate
-- %keybind , ((modMask, xK_d ), date)
-- In this example, a popup date menu will now be bound to @mod-d@.
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
date :: X ()
date = spawn "(date; sleep 10) | dzen2"
date = unsafeSpawn "(date; sleep 10) | dzen2"

View File

@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
-- |
-- Module : XmonadContrib.SinkAll
-- Module : XMonad.Actions.SinkAll
-- License : BSD3-style (see LICENSE)
-- Stability : unstable
-- Portability : unportable
@@ -9,28 +9,32 @@
-- workspace back into tiling.
-----------------------------------------------------------------------------
module XMonadContrib.SinkAll (
module XMonad.Actions.SinkAll (
-- * Usage
-- $usage
sinkAll) where
import Operations
import XMonad
import StackSet
import Graphics.X11.Xlib
import XMonad.StackSet
-- $usage
-- > import XMonadContrib.SinkAll
-- > keys = [ ((modMask .|. shiftMask, xK_t), sinkAll) ]
-- %import XMonadContrib.SinkAll
-- %keybind , ((modMask .|. shiftMask, xK_t), sinkAll)
--
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Actions.SinkAll
--
-- then add a keybinding; for example:
--
-- , ((modMask x .|. shiftMask, xK_t), sinkAll)
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Un-float all floating windows on the current workspace.
sinkAll :: X ()
sinkAll = withAll sink
-- Apply a function to all windows on current workspace.
-- | Apply a function to all windows on current workspace.
withAll :: (Window -> WindowSet -> WindowSet) -> X ()
withAll f = windows $ \ws -> let all' = integrate' . stack . workspace . current $ ws
in foldr f ws all'

77
XMonad/Actions/SpawnOn.hs Normal file
View File

@@ -0,0 +1,77 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.SpawnOn
-- Copyright : (c) Spencer Janssen
-- License : BSD
--
-- Maintainer : Spencer Janssen <spencerjanssen@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- This module provides helper functions to be used in @manageHook@. Here's
-- how you might use this:
--
-- > import XMonad.Hooks.ManageHelpers
-- > main = do
-- > sp <- mkSpawner
-- > xmonad defaultConfig {
-- > ...
-- > manageHook = spawnHook sp <+> manageHook defaultConfig
-- > ...
-- > }
module XMonad.Actions.SpawnOn (
Spawner,
mkSpawner,
manageSpawn,
spawnHere,
spawnOn,
shellPromptHere,
shellPromptOn
) where
import Data.IORef
import System.Posix.Types (ProcessID)
import XMonad
import qualified XMonad.StackSet as W
import XMonad.Hooks.ManageHelpers
import XMonad.Prompt
import XMonad.Prompt.Shell
newtype Spawner = Spawner {pidsRef :: IORef [(ProcessID, WorkspaceId)]}
maxPids :: Int
maxPids = 5
mkSpawner :: (Functor m, MonadIO m) => m Spawner
mkSpawner = io . fmap Spawner $ newIORef []
manageSpawn :: Spawner -> ManageHook
manageSpawn sp = do
pids <- io . readIORef $ pidsRef sp
mp <- pid
case flip lookup pids =<< mp of
Just w -> doF (W.shift w)
Nothing -> doF id
mkPrompt :: (String -> X ()) -> XPConfig -> X ()
mkPrompt cb c = do
cmds <- io $ getCommands
mkXPrompt Shell c (getShellCompl cmds) cb
shellPromptHere :: Spawner -> XPConfig -> X ()
shellPromptHere sp = mkPrompt (spawnHere sp)
shellPromptOn :: Spawner -> WorkspaceId -> XPConfig -> X ()
shellPromptOn sp ws = mkPrompt (spawnOn sp ws)
spawnHere :: Spawner -> String -> X ()
spawnHere sp cmd = withWindowSet $ \ws -> spawnOn sp (currTag ws) cmd
where currTag = W.tag . W.workspace . W.current
spawnOn :: Spawner -> WorkspaceId -> String -> X ()
spawnOn sp ws cmd = do
p <- spawnPID cmd
io $ modifyIORef (pidsRef sp) (take maxPids . ((p, ws) :))

View File

@@ -1,70 +1,76 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Submap
-- Module : XMonad.Actions.Submap
-- Copyright : (c) Jason Creighton <jcreigh@gmail.com>
-- License : BSD3-style (see LICENSE)
--
--
-- Maintainer : Jason Creighton <jcreigh@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
-- A module that allows the user to create a sub-mapping of keys bindings.
-- A module that allows the user to create a sub-mapping of key bindings.
--
-----------------------------------------------------------------------------
module XMonadContrib.Submap (
module XMonad.Actions.Submap (
-- * Usage
-- $usage
submap
) where
import Control.Monad.Reader
import XMonad
import Operations (cleanMask)
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import XMonad hiding (keys)
import qualified Data.Map as M
import Control.Monad.Fix (fix)
{- $usage
First, import this module into your @~\/.xmonad\/xmonad.hs@:
> import XMonad.Actions.Submap
Allows you to create a sub-mapping of keys. Example:
> , ((modMask, xK_a), submap . M.fromList $
> , ((modMask x, xK_a), submap . M.fromList $
> [ ((0, xK_n), spawn "mpc next")
> , ((0, xK_p), spawn "mpc prev")
> , ((0, xK_z), spawn "mpc random")
> , ((0, xK_space), spawn "mpc toggle")
> ])
So, for example, to run 'spawn \"mpc next\"', you would hit mod-a (to trigger the
submapping) and then 'n' to run that action. (0 means \"no modifier\"). You are,
of course, free to use any combination of modifiers in the submapping. However,
anyModifier will not work, because that is a special value passed to XGrabKey()
and not an actual modifier.
So, for example, to run 'spawn \"mpc next\"', you would hit mod-a (to
trigger the submapping) and then 'n' to run that action. (0 means \"no
modifier\"). You are, of course, free to use any combination of
modifiers in the submapping. However, anyModifier will not work,
because that is a special value passed to XGrabKey() and not an actual
modifier.
For detailed instructions on editing your key bindings, see
"XMonad.Doc.Extending#Editing_key_bindings".
-}
-- %import XMonadContrib.Submap
-- %keybind , ((modMask, xK_a), submap . M.fromList $
-- %keybind [ ((0, xK_n), spawn "mpc next")
-- %keybind , ((0, xK_p), spawn "mpc prev")
-- %keybind , ((0, xK_z), spawn "mpc random")
-- %keybind , ((0, xK_space), spawn "mpc toggle")
-- %keybind ])
-- | Given a 'Data.Map.Map' from key bindings to X () actions, return
-- an action which waits for a user keypress and executes the
-- corresponding action, or does nothing if the key is not found in
-- the map.
submap :: M.Map (KeyMask, KeySym) (X ()) -> X ()
submap keys = do
XConf { theRoot = root, display = d } <- ask
io $ grabKeyboard d root False grabModeAsync grabModeAsync currentTime
keyspec <- io $ allocaXEvent $ \p -> fix $ \nextkey -> do
(m, s) <- io $ allocaXEvent $ \p -> fix $ \nextkey -> do
maskEvent d keyPressMask p
KeyEvent { ev_keycode = code, ev_state = m } <- getEvent p
keysym <- keycodeToKeysym d code 0
if isModifierKey keysym
then nextkey
else return (cleanMask m, keysym)
else return (m, keysym)
io $ ungrabKeyboard d currentTime
whenJust (M.lookup keyspec keys) id
m' <- cleanMask m
whenJust (M.lookup (m', s) keys) id

View File

@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.SwapWorkspaces
-- Module : XMonad.Actions.SwapWorkspaces
-- Copyright : (c) Devin Mullins <me@twifkak.com>
-- License : BSD3-style (see LICENSE)
--
@@ -13,40 +13,49 @@
--
-----------------------------------------------------------------------------
module XMonadContrib.SwapWorkspaces (
module XMonad.Actions.SwapWorkspaces (
-- * Usage
-- $usage
swapWithCurrent,
swapWorkspaces
swapTo,
swapWorkspaces,
WSDirection(..)
) where
import StackSet
import XMonad (windows, X())
import XMonad.StackSet
import XMonad.Actions.CycleWS
import XMonad.Util.WorkspaceCompare
-- $usage
-- Add this import to your Config.hs:
-- Add this import to your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonadContrib.SwapWorkspaces
-- > import XMonad.Actions.SwapWorkspaces
--
-- Throw this in your keys definition:
-- Then throw something like this in your keys definition:
--
-- > ++
-- > [((modMask .|. controlMask, k), windows $ swapWithCurrent i)
-- > [((modMask x .|. controlMask, k), windows $ swapWithCurrent i)
-- > | (i, k) <- zip workspaces [xK_1 ..]]
-- %import XMonadContrib.SwapWorkspaces
-- %keybindlist ++
-- %keybindlist [((modMask .|. controlMask, k), windows $ swapWithCurrent i)
-- %keybindlist | (i, k) <- zip workspaces [xK_1 ..]]
--
-- After installing this update, if you're on workspace 1, hitting mod-ctrl-5
-- will swap workspaces 1 and 5.
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Swaps the currently focused workspace with the given workspace tag, via
-- @swapWorkspaces@.
swapWithCurrent :: Eq i => i -> StackSet i l a s sd -> StackSet i l a s sd
swapWithCurrent t s = swapWorkspaces t (tag $ workspace $ current s) s
swapWithCurrent t s = swapWorkspaces t (currentTag s) s
-- | Takes two workspace tags and an existing StackSet and returns a new
-- | Say @swapTo Next@ or @swapTo Prev@ to move your current workspace.
-- This is an @X ()@ so can be hooked up to your keybindings directly.
swapTo :: WSDirection -> X ()
swapTo dir = findWorkspace getSortByIndex dir AnyWS 1 >>= windows . swapWithCurrent
-- | Takes two workspace tags and an existing XMonad.StackSet and returns a new
-- one with the two corresponding workspaces' tags swapped.
swapWorkspaces :: Eq i => i -> i -> StackSet i l a s sd -> StackSet i l a s sd
swapWorkspaces t1 t2 = mapWorkspace swap

View File

@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.TagWindows
-- Module : XMonad.Actions.TagWindows
-- Copyright : (c) Karsten Schoelzel <kuser@gmx.de>
-- License : BSD
--
@@ -11,7 +11,7 @@
-- Functions for tagging windows and selecting them by tags.
-----------------------------------------------------------------------------
module XMonadContrib.TagWindows (
module XMonad.Actions.TagWindows (
-- * Usage
-- $usage
addTag, delTag, unTag,
@@ -26,57 +26,54 @@ module XMonadContrib.TagWindows (
) where
import Data.List (nub,concat,sortBy)
import Control.Monad
import Control.Monad.State
import StackSet hiding (filter)
import Operations (windows, withFocused)
import XMonad.StackSet hiding (filter)
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import XMonadContrib.XPrompt
import XMonad
import XMonad.Prompt
import XMonad hiding (workspaces)
-- $usage
--
-- To use window tags add in your Config.hs:
--
-- > import XMonadContrib.TagWindows
-- > import XMonadContrib.XPrompt -- to use tagPrompt
--
-- and add keybindings like as follows:
-- To use window tags, import this module into your @~\/.xmonad\/xmonad.hs@:
--
-- > , ((modMask, xK_f ), withFocused (addTag "abc"))
-- > , ((modMask .|. controlMask, xK_f ), withFocused (delTag "abc"))
-- > , ((modMask .|. shiftMask, xK_f ), withTaggedGlobal "abc" sink)
-- > , ((modMask, xK_d ), withTaggedP "abc" (shiftWin "2"))
-- > , ((modMask .|. shiftMask, xK_d ), withTaggedGlobalP "abc" shiftHere)
-- > , ((modMask .|. controlMask, xK_d ), focusUpTaggedGlobal "abc")
-- > , ((modMask, xK_g ), tagPrompt defaultXPConfig (\s -> withFocused (addTag s)))
-- > , ((modMask .|. controlMask, xK_g ), tagDelPrompt defaultXPConfig)
-- > , ((modMask .|. shiftMask, xK_g ), tagPrompt defaultXPConfig (\s -> withTaggedGlobal s float))
-- > , ((modWinMask, xK_g ), tagPrompt defaultXPConfig (\s -> withTaggedP s (shiftWin "2")))
-- > , ((modWinMask .|. shiftMask, xK_g ), tagPrompt defaultXPConfig (\s -> withTaggedGlobalP s shiftHere))
-- > , ((modWinMask .|. controlMask, xK_g), tagPrompt defaultXPConfig (\s -> focusUpTaggedGlobal s))
-- > import XMonad.Actions.TagWindows
-- > import XMonad.Prompt -- to use tagPrompt
--
-- NOTE: Tags are saved as space seperated string and split with 'unwords' thus
-- if you add a tag "a b" the window will have the tags "a" and "b" but not "a b".
-- and add keybindings such as the following:
--
-- > , ((modMask x, xK_f ), withFocused (addTag "abc"))
-- > , ((modMask x .|. controlMask, xK_f ), withFocused (delTag "abc"))
-- > , ((modMask x .|. shiftMask, xK_f ), withTaggedGlobal "abc" sink)
-- > , ((modMask x, xK_d ), withTaggedP "abc" (shiftWin "2"))
-- > , ((modMask x .|. shiftMask, xK_d ), withTaggedGlobalP "abc" shiftHere)
-- > , ((modMask x .|. controlMask, xK_d ), focusUpTaggedGlobal "abc")
-- > , ((modMask x, xK_g ), tagPrompt defaultXPConfig (\s -> withFocused (addTag s)))
-- > , ((modMask x .|. controlMask, xK_g ), tagDelPrompt defaultXPConfig)
-- > , ((modMask x .|. shiftMask, xK_g ), tagPrompt defaultXPConfig (\s -> withTaggedGlobal s float))
-- > , ((modWinMask, xK_g ), tagPrompt defaultXPConfig (\s -> withTaggedP s (shiftWin "2")))
-- > , ((modWinMask .|. shiftMask, xK_g ), tagPrompt defaultXPConfig (\s -> withTaggedGlobalP s shiftHere))
-- > , ((modWinMask .|. controlMask, xK_g ), tagPrompt defaultXPConfig (\s -> focusUpTaggedGlobal s))
--
-- NOTE: Tags are saved as space separated strings and split with
-- 'unwords'. Thus if you add a tag \"a b\" the window will have
-- the tags \"a\" and \"b\" but not \"a b\".
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- %import XMonadContrib.TagWindows
-- %import XMonadContrib.XPrompt -- to use tagPrompt
-- set multiple tags for a window at once (overriding any previous tags)
-- | set multiple tags for a window at once (overriding any previous tags)
setTags :: [String] -> Window -> X ()
setTags = setTag . unwords
-- set a tag for a window (overriding any previous tags)
-- writes it to the "_XMONAD_TAGS" window property
-- | set a tag for a window (overriding any previous tags)
-- writes it to the \"_XMONAD_TAGS\" window property
setTag :: String -> Window -> X ()
setTag s w = withDisplay $ \d ->
io $ internAtom d "_XMONAD_TAGS" False >>= setTextProperty d w s
-- read all tags of a window
-- reads from the "_XMONAD_TAGS" window property
-- | read all tags of a window
-- reads from the \"_XMONAD_TAGS\" window property
getTags :: Window -> X [String]
getTags w = withDisplay $ \d ->
io $ catch (internAtom d "_XMONAD_TAGS" False >>=
@@ -85,36 +82,35 @@ getTags w = withDisplay $ \d ->
(\_ -> return [[]])
>>= return . words . unwords
-- check a window for the given tag
-- | check a window for the given tag
hasTag :: String -> Window -> X Bool
hasTag s w = (s `elem`) `liftM` getTags w
hasTag s w = (s `elem`) `fmap` getTags w
-- add a tag to the existing ones
-- | add a tag to the existing ones
addTag :: String -> Window -> X ()
addTag s w = do
tags <- getTags w
if (s `notElem` tags) then setTags (s:tags) w else return ()
-- remove a tag from a window, if it exists
-- | remove a tag from a window, if it exists
delTag :: String -> Window -> X ()
delTag s w = do
tags <- getTags w
setTags (filter (/= s) tags) w
-- remove all tags
-- | remove all tags
unTag :: Window -> X ()
unTag = setTag ""
-- Move the focus in a group of windows, which share the same given tag.
-- The Global variants move through all workspaces, whereas the other
-- ones operate only on the current workspace
-- | Move the focus in a group of windows, which share the same given tag.
-- The Global variants move through all workspaces, whereas the other
-- ones operate only on the current workspace
focusUpTagged, focusDownTagged, focusUpTaggedGlobal, focusDownTaggedGlobal :: String -> X ()
focusUpTagged = focusTagged' (reverse . wsToList)
focusDownTagged = focusTagged' wsToList
focusUpTaggedGlobal = focusTagged' (reverse . wsToListGlobal)
focusDownTaggedGlobal = focusTagged' wsToListGlobal
--
wsToList :: (Ord i) => StackSet i l a s sd -> [a]
wsToList ws = crs ++ cls
where
@@ -124,7 +120,7 @@ wsToList ws = crs ++ cls
wsToListGlobal :: (Ord i) => StackSet i l a s sd -> [a]
wsToListGlobal ws = concat ([crs] ++ rws ++ lws ++ [cls])
where
curtag = tag . workspace . current $ ws
curtag = currentTag ws
(crs, cls) = (cms down, cms (reverse . up))
cms f = maybe [] f (stack . workspace . current $ ws)
(lws, rws) = (mws (<), mws (>))
@@ -140,7 +136,7 @@ findM _ [] = return Nothing
findM p (x:xs) = do b <- p x
if b then return (Just x) else findM p xs
-- apply a pure function to windows with a tag
-- | apply a pure function to windows with a tag
withTaggedP, withTaggedGlobalP :: String -> (Window -> WindowSet -> WindowSet) -> X ()
withTaggedP t f = withTagged' t (winMap f)
withTaggedGlobalP t f = withTaggedGlobal' t (winMap f)
@@ -153,8 +149,7 @@ withTagged t f = withTagged' t (mapM_ f)
withTaggedGlobal t f = withTaggedGlobal' t (mapM_ f)
withTagged' :: String -> ([Window] -> X ()) -> X ()
withTagged' t m = gets windowset >>=
filterM (hasTag t) . integrate' . stack . workspace . current >>= m
withTagged' t m = gets windowset >>= filterM (hasTag t) . index >>= m
withTaggedGlobal' :: String -> ([Window] -> X ()) -> X ()
withTaggedGlobal' t m = gets windowset >>=
@@ -164,7 +159,7 @@ withFocusedP :: (Window -> WindowSet -> WindowSet) -> X ()
withFocusedP f = withFocused $ windows . f
shiftHere :: (Ord a, Eq s, Eq i) => a -> StackSet i l a s sd -> StackSet i l a s sd
shiftHere w s = shiftWin (tag . workspace . current $ s) w s
shiftHere w s = shiftWin (currentTag s) w s
shiftToScreen :: (Ord a, Eq s, Eq i) => s -> a -> StackSet i l a s sd -> StackSet i l a s sd
shiftToScreen sid w s = case filter (\m -> sid /= screen m) ((current s):(visible s)) of
@@ -191,15 +186,9 @@ tagComplList = gets (concat . map (integrate' . stack) . workspaces . windowset)
tagDelPrompt :: XPConfig -> X ()
tagDelPrompt c = do
sc <- tagDelComplList
if (sc /= [])
if (sc /= [])
then mkXPrompt TagPrompt c (mkComplFunFromList' sc) (\s -> withFocused (delTag s))
else return ()
tagDelComplList :: X [String]
tagDelComplList = gets windowset >>= maybe (return []) getTags . peek
mkComplFunFromList' :: [String] -> String -> IO [String]
mkComplFunFromList' l [] = return l
mkComplFunFromList' l s =
return $ filter (\x -> take (length s) x == s) l

View File

@@ -0,0 +1,92 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.UpdatePointer
-- Copyright : (c) Robert Marlow <robreim@bobturf.org>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Robert Marlow <robreim@bobturf.org>
-- Stability : stable
-- Portability : portable
--
-- Causes the pointer to follow whichever window focus changes to. Compliments
-- the idea of switching focus as the mouse crosses window boundaries to
-- keep the mouse near the currently focused window
--
-----------------------------------------------------------------------------
module XMonad.Actions.UpdatePointer
(
-- * Usage
-- $usage
updatePointer
, PointerPosition (..)
)
where
import XMonad
import Control.Monad
import XMonad.StackSet (member)
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad
-- > import XMonad.Actions.UpdatePointer
--
-- Enable it by including it in your logHook definition. Eg:
--
-- > logHook = updatePointer Nearest
--
-- which will move the pointer to the nearest point of a newly focused window, or
--
-- > logHook = updatePointer (Relative 0.5 0.5)
--
-- which will move the pointer to the center of a newly focused window.
--
-- To use this with an existing logHook, use >> :
--
-- > logHook = dynamicLog
-- > >> updatePointer (Relative 1 1)
--
-- which moves the pointer to the bottom-right corner of the focused window.
data PointerPosition = Nearest | Relative Rational Rational
-- | Update the pointer's location to the currently focused
-- window unless it's already there, or unless the user was changing
-- focus with the mouse
updatePointer :: PointerPosition -> X ()
updatePointer p = withFocused $ \w -> do
ws <- gets windowset
dpy <- asks display
root <- asks theRoot
mouseIsMoving <- asks mouseFocused
wa <- io $ getWindowAttributes dpy w
(_sameRoot,_,currentWindow,rootx,rooty,_,_,_) <- io $ queryPointer dpy root
unless (pointWithinRegion rootx rooty (wa_x wa) (wa_y wa) (wa_width wa) (wa_height wa)
|| mouseIsMoving
|| not (currentWindow `member` ws)) $
case p of
Nearest -> do
let x = moveWithin rootx (wa_x wa) ((wa_x wa) + (wa_width wa))
let y = moveWithin rooty (wa_y wa) ((wa_y wa) + (wa_height wa))
io $ warpPointer dpy none root 0 0 0 0 (fromIntegral x) (fromIntegral y)
Relative h v ->
io $ warpPointer dpy none w 0 0 0 0
(fraction h (wa_width wa)) (fraction v (wa_height wa))
where fraction x y = floor (x * fromIntegral y)
moveWithin :: Integral a => a -> a -> a -> a
moveWithin current lower upper =
if current < lower
then lower
else if current > upper
then upper
else current
-- Test that a point resides within a region.
-- This belongs somewhere more generally accessible than this module.
pointWithinRegion :: Integral a => a -> a -> a -> a -> a -> a -> Bool
pointWithinRegion px py rx ry rw rh =
within px rx (rx + rw) && within py ry (ry + rh)
where within x left right = x >= left && x <= right

109
XMonad/Actions/Warp.hs Normal file
View File

@@ -0,0 +1,109 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.Warp
-- Copyright : (c) daniel@wagner-home.com
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : daniel@wagner-home.com
-- Stability : unstable
-- Portability : unportable
--
-- Warp the pointer to a given window or screen.
--
-----------------------------------------------------------------------------
module XMonad.Actions.Warp (
-- * Usage
-- $usage
banish,
banishScreen,
Corner(..),
warpToScreen,
warpToWindow
) where
import Data.Ratio
import Data.List
import XMonad
import XMonad.StackSet as W
{- $usage
You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
> import XMonad.Actions.Warp
then add appropriate keybindings to warp the pointer; for example:
> , ((modMask x, xK_z ), warpToWindow (1%2) (1%2)) -- @@ Move pointer to currently focused window
>
>-- mod-ctrl-{w,e,r} @@ Move mouse pointer to screen 1, 2, or 3
>
> [((modMask x .|. controlMask, key), warpToScreen sc (1%2) (1%2))
> | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]]
Note that warping to a particular screen may change the focus.
-}
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
data Corner = UpperLeft | UpperRight | LowerLeft | LowerRight
{- | Move the mouse cursor to a corner of the focused window. Useful for
uncluttering things.
Internally, this uses numerical parameters. We parametrize on the 'Corner'
type so the user need not see the violence inherent in
the system.
'warpToScreen' and 'warpToWindow' can be used in a variety of
ways. Suppose you wanted to emulate Ratpoison's \'banish\' command,
which moves the mouse pointer to a corner? warpToWindow can do that! -}
banish :: Corner -> X ()
banish direction = case direction of
LowerRight -> warpToWindow 1 1
LowerLeft -> warpToWindow 0 1
UpperLeft -> warpToWindow 0 0
UpperRight -> warpToWindow 1 0
{- | Same as 'banish' but moves the mouse to the corner of the
currently focused screen -}
banishScreen :: Corner -> X ()
banishScreen direction = case direction of
LowerRight -> warpToCurrentScreen 1 1
LowerLeft -> warpToCurrentScreen 0 1
UpperLeft -> warpToCurrentScreen 0 0
UpperRight -> warpToCurrentScreen 1 0
where
warpToCurrentScreen h v =
do ws <- gets windowset
warpToScreen (W.screen $ current ws) h v
windows (const ws)
fraction :: (Integral a, Integral b) => Rational -> a -> b
fraction f x = floor (f * fromIntegral x)
warp :: Window -> Position -> Position -> X ()
warp w x y = withDisplay $ \d -> io $ warpPointer d none w 0 0 0 0 x y
-- | Warp the pointer to a given position relative to the currently
-- focused window. Top left = (0,0), bottom right = (1,1).
warpToWindow :: Rational -> Rational -> X ()
warpToWindow h v =
withDisplay $ \d ->
withFocused $ \w -> do
wa <- io $ getWindowAttributes d w
warp w (fraction h (wa_width wa)) (fraction v (wa_height wa))
-- | Warp the pointer to the given position (top left = (0,0), bottom
-- right = (1,1)) on the given screen.
warpToScreen :: ScreenId -> Rational -> Rational -> X ()
warpToScreen n h v = do
root <- asks theRoot
(StackSet {current = x, visible = xs}) <- gets windowset
whenJust (fmap (screenRect . W.screenDetail) . find ((n==) . W.screen) $ x : xs)
$ \r ->
warp root (rect_x r + fraction h (rect_width r))
(rect_y r + fraction v (rect_height r))

View File

@@ -0,0 +1,91 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.WindowBringer
-- Copyright : Devin Mullins <me@twifkak.com>
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Devin Mullins <me@twifkak.com>
-- Stability : unstable
-- Portability : unportable
--
-- dmenu operations to bring windows to you, and bring you to windows.
-- That is to say, it pops up a dmenu with window names, in case you forgot
-- where you left your XChat.
--
-----------------------------------------------------------------------------
module XMonad.Actions.WindowBringer (
-- * Usage
-- $usage
gotoMenu, gotoMenu', bringMenu, windowMap,
bringWindow
) where
import Data.Char (toLower)
import qualified Data.Map as M
import qualified XMonad.StackSet as W
import XMonad
import qualified XMonad as X
import XMonad.Util.Dmenu (menuMap)
import XMonad.Util.NamedWindows (getName)
-- $usage
--
-- Import the module into your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Actions.WindowBringer
--
-- and define appropriate key bindings:
--
-- > , ((modMask x .|. shiftMask, xK_g ), gotoMenu)
-- > , ((modMask x .|. shiftMask, xK_b ), bringMenu)
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Pops open a dmenu with window titles. Choose one, and you will be
-- taken to the corresponding workspace.
gotoMenu :: X ()
gotoMenu = actionMenu W.focusWindow
gotoMenu' :: String -> X ()
gotoMenu' menuCmd = actionMenu' menuCmd W.focusWindow
-- | Pops open a dmenu with window titles. Choose one, and it will be
-- dragged, kicking and screaming, into your current workspace.
bringMenu :: X ()
bringMenu = actionMenu bringWindow
-- | Brings the specified window into the current workspace.
bringWindow :: Window -> X.WindowSet -> X.WindowSet
bringWindow w ws = W.shiftWin (W.currentTag ws) w ws
-- | Calls dmenuMap to grab the appropriate Window, and hands it off to action
-- if found.
actionMenu :: (Window -> X.WindowSet -> X.WindowSet) -> X()
actionMenu action = actionMenu' "dmenu" action
actionMenu' :: String -> (Window -> X.WindowSet -> X.WindowSet) -> X()
actionMenu' menuCmd action = windowMap >>= menuMapFunction >>= flip X.whenJust (windows . action)
where
menuMapFunction :: M.Map String a -> X (Maybe a)
menuMapFunction selectionMap = menuMap menuCmd selectionMap
-- | A map from window names to Windows.
windowMap :: X (M.Map String Window)
windowMap = do
ws <- gets X.windowset
M.fromList `fmap` concat `fmap` mapM keyValuePairs (W.workspaces ws)
where keyValuePairs ws = mapM (keyValuePair ws) $ W.integrate' (W.stack ws)
keyValuePair ws w = flip (,) w `fmap` decorateName ws w
-- | Returns the window name as will be listed in dmenu.
-- Lowercased, for your convenience (since dmenu is case-sensitive).
-- Tagged with the workspace ID, to guarantee uniqueness, and to let the user
-- know where he's going.
decorateName :: X.WindowSpace -> Window -> X String
decorateName ws w = do
name <- fmap (map toLower . show) $ getName w
return $ name ++ " [" ++ W.tag ws ++ "]"

172
XMonad/Actions/WindowGo.hs Normal file
View File

@@ -0,0 +1,172 @@
{- |
Module : XMonad.Actions.WindowGo
License : Public domain
Maintainer : <gwern0@gmail.com>
Stability : unstable
Portability : unportable
Defines a few convenient operations for raising (traveling to) windows based on XMonad's Query
monad, such as 'runOrRaise'. runOrRaise will run a shell command unless it can
find a specified window; you would use this to automatically travel to your
Firefox or Emacs session, or start a new one (for example), instead of trying to
remember where you left it or whether you still have one running. -}
module XMonad.Actions.WindowGo (
-- * Usage
-- $usage
raise,
raiseNext,
runOrRaise,
runOrRaiseNext,
raiseMaybe,
raiseNextMaybe,
raiseBrowser,
raiseEditor,
runOrRaiseAndDo,
runOrRaiseMaster,
raiseAndDo,
raiseMaster,
module XMonad.ManageHook
) where
import Control.Monad (filterM)
import Data.Char (toLower)
import XMonad (Query(), X(), withWindowSet, spawn, runQuery, liftIO)
import Graphics.X11 (Window)
import XMonad.ManageHook
import XMonad.Operations (windows)
import XMonad.Prompt.Shell (getBrowser, getEditor)
import qualified XMonad.StackSet as W (allWindows, peek, swapMaster, focusWindow)
{- $usage
Import the module into your @~\/.xmonad\/xmonad.hs@:
> import XMonad.Actions.WindowGo
and define appropriate key bindings:
> , ((modMask x .|. shiftMask, xK_g), raise (className =? "Firefox"))
> , ((modMask x .|. shiftMask, xK_b), runOrRaise "firefox" (className =? "Firefox"))
(Note that Firefox v3 and up have a class-name of \"Firefox\" and \"Navigator\";
lower versions use other classnames such as \"Firefox-bin\". Either choose the
appropriate one, or cover your bases by using instead something like
@(className =? \"Firefox\" <||> className =? \"Firefox-bin\")@.)
For detailed instructions on editing your key bindings, see
"XMonad.Doc.Extending#Editing_key_bindings". -}
-- | 'action' is an executable to be run via 'spawn' (of "XMonad.Core") if the Window cannot be found.
-- Presumably this executable is the same one that you were looking for.
runOrRaise :: String -> Query Bool -> X ()
runOrRaise = raiseMaybe . spawn
-- | See 'raiseMaybe'. If the Window can't be found, quietly give up and do nothing.
raise :: Query Bool -> X ()
raise = raiseMaybe $ return ()
{- | 'raiseMaybe' queries all Windows based on a boolean provided by the
user. Currently, there are three such useful booleans defined in
"XMonad.ManageHook": title, resource, className. Each one tests based pretty
much as you would think. ManageHook also defines several operators, the most
useful of which is (=?). So a useful test might be finding a Window whose
class is Firefox. Firefox 3 declares the class \"Firefox\", so you'd want to
pass in a boolean like @(className =? \"Firefox\")@.
If the boolean returns @True@ on one or more windows, then XMonad will quickly
make visible the first result. If no @Window@ meets the criteria, then the
first argument comes into play.
The first argument is an arbitrary IO function which will be executed if the
tests fail. This is what enables 'runOrRaise' to use 'raiseMaybe': it simply runs
the desired program if it isn't found. But you don't have to do that. Maybe
you want to do nothing if the search fails (the definition of 'raise'), or
maybe you want to write to a log file, or call some prompt function, or
something crazy like that. This hook gives you that flexibility. You can do
some cute things with this hook. Suppose you want to do the same thing for
Mutt which you just did for Firefox - but Mutt runs inside a terminal window?
No problem: you search for a terminal window calling itself \"mutt\", and if
there isn't you run a terminal with a command to run Mutt! Here's an example
(borrowing 'runInTerm' from "XMonad.Utils.Run"):
> , ((modm, xK_m), raiseMaybe (runInTerm "-title mutt" "mutt") (title =? "mutt"))
-}
raiseMaybe :: X () -> Query Bool -> X ()
raiseMaybe f thatUserQuery = withWindowSet $ \s -> do
maybeResult <- filterM (runQuery thatUserQuery) (W.allWindows s)
case maybeResult of
[] -> f
(x:_) -> windows $ W.focusWindow x
-- | See 'runOrRaise' and 'raiseNextMaybe'. Version that allows cycling through matches.
runOrRaiseNext :: String -> Query Bool -> X ()
runOrRaiseNext = raiseNextMaybe . spawn
-- | See 'raise' and 'raiseNextMaybe'. Version that allows cycling through matches.
raiseNext :: Query Bool -> X ()
raiseNext = raiseNextMaybe $ return ()
{- | See 'raiseMaybe'.
'raiseNextMaybe' is an alternative version that allows cycling
through the matching windows. If the focused window matches the
query the next matching window is raised. If no matches are found
the function f is executed.
-}
raiseNextMaybe :: X () -> Query Bool -> X ()
raiseNextMaybe f thatUserQuery = withWindowSet $ \s -> do
ws <- filterM (runQuery thatUserQuery) (W.allWindows s)
case ws of
[] -> f
(x:_) -> let go (Just w) | (w `elem` ws) = next w $ cycle ws
go _ = windows $ W.focusWindow x
in go $ W.peek s
where
next w (x:y:_) | x==w = windows $ W.focusWindow y
next w (_:xs) = next w xs
next _ _ = error "raiseNextMaybe: empty list"
-- | Given a function which gets us a String, we try to raise a window with that classname,
-- or we then interpret that String as a executable name.
raiseVar :: IO String -> X ()
raiseVar getvar = liftIO getvar >>= \var -> runOrRaise var (fmap (map toLower) className =? var)
{- | 'raiseBrowser' and 'raiseEditor' grab $BROWSER and $EDITOR respectively and they either
take you to the specified program's window, or they try to run it. This is most useful
if your variables are simple and look like 'firefox' or 'emacs'. -}
raiseBrowser, raiseEditor :: X ()
raiseBrowser = raiseVar getBrowser
raiseEditor = raiseVar getEditor
{- | if the window is found the window is focused and the third argument is called
otherwise, the first argument is called
See 'raiseMaster' for an example -}
raiseAndDo :: X () -> Query Bool -> (Window -> X ())-> X ()
raiseAndDo raisef thatUserQuery afterRaise = withWindowSet $ \s -> do
maybeResult <- filterM (runQuery thatUserQuery) (W.allWindows s)
case maybeResult of
[] -> raisef
(x:_) -> do windows $ W.focusWindow x
afterRaise x
{- | if the window is found the window is focused and the third argument is called
otherwise, raisef is called -}
runOrRaiseAndDo :: String -> Query Bool -> (Window -> X ()) -> X ()
runOrRaiseAndDo = raiseAndDo . spawn
{- | if the window is found the window is focused and set to master
otherwise, the first argument is called
raiseMaster (runInTerm \"-title ghci\" \"zsh -c \'ghci\'\") (title =? \"ghci\") -}
raiseMaster :: X () -> Query Bool -> X ()
raiseMaster raisef thatUserQuery = raiseAndDo raisef thatUserQuery (\_ -> windows W.swapMaster)
{- | if the window is found the window is focused and set to master
otherwise, action is run
runOrRaiseMaster \"firefox\" (className =? \"Firefox\"))
-}
runOrRaiseMaster :: String -> Query Bool -> X ()
runOrRaiseMaster run query = runOrRaiseAndDo run query (\_ -> windows W.swapMaster)

View File

@@ -0,0 +1,214 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Actions.WindowNavigation
-- Copyright : (c) 2007 David Roundy <droundy@darcs.net>,
-- Devin Mullins <me@twifkak.com>
-- Maintainer : Devin Mullins <me@twifkak.com>
-- License : BSD3-style (see LICENSE)
--
-- This is a rewrite of "XMonad.Layout.WindowNavigation". WindowNavigation
-- lets you assign keys to move up\/down\/left\/right, based on actual cartesian
-- window coordinates, rather than just going j\/k on the stack.
--
-- This module is experimental. You'll have better luck with the original.
--
-- This module differs from the other in a few ways:
--
-- (1) You can go up\/down\/left\/right across multiple screens.
--
-- (2) It doesn't provide little border colors for your neighboring windows.
--
-- (3) It doesn't provide the \'Move\' action, which seems to be related to
-- the XMonad.Layout.Combo extension.
--
-- (4) It tries to be slightly smarter about tracking your current position.
--
-- (5) Configuration is different.
--
-----------------------------------------------------------------------------
module XMonad.Actions.WindowNavigation (
-- * Usage
-- $usage
withWindowNavigation,
withWindowNavigationKeys,
WNAction(..),
go, swap,
Direction(..)
) where
import XMonad
import XMonad.Hooks.ManageDocks (Direction(..))
import qualified XMonad.StackSet as W
import Control.Applicative ((<$>))
import Control.Arrow (second)
import Data.IORef
import Data.List (sortBy)
import Data.Map (Map())
import qualified Data.Map as M
import Data.Maybe (catMaybes, fromMaybe, listToMaybe)
import Data.Ord (comparing)
import qualified Data.Set as S
import Graphics.X11.Xlib
-- $usage
--
-- To use it, you're going to apply the 'withWindowNavigation' function.
-- 'withWindowNavigation' performs some IO operations, so the syntax you'll use
-- is the same as the spawnPipe example in "XMonad.Hooks.DynamicLog".
-- In particular:
--
-- > main = do
-- > config <- withWindowNavigation (xK_w, xK_a, xK_s, xK_d)
-- > $ defaultConfig { ... }
-- > xmonad config
--
-- Here, we pass in the keys for navigation in counter-clockwise order from up.
-- It creates keybindings for @modMask@ to move to window, and @modMask .|. shiftMask@
-- to swap windows.
--
-- If you want more flexibility over your keybindings, you can use
-- 'withWindowNavigationKeys', which takes a list of @keys@-esque entries rather
-- than a tuple of the four directional keys. See the source code of
-- 'withWindowNavigation' for an example.
-- TODO:
-- - monad for WNState?
-- - cleanup (including inr)
-- - more documentation
-- - tests? (esp. for edge cases in currentPosition)
-- - screen 1, 1+2/w 3, M-d, M-w, M-2 (1+2/w 2), M-e, M-a - goes to w 3, should be w 2
-- - solve the 2+3, middle right to bottom left problem
-- - command to iteratively swapUp/swapDown instead of directly swapping with target
-- - manageHook to draw window decos?
withWindowNavigation :: (KeySym, KeySym, KeySym, KeySym) -> XConfig l -> IO (XConfig l)
withWindowNavigation (u,l,d,r) conf =
withWindowNavigationKeys [ ((modMask conf , u), WNGo U),
((modMask conf , l), WNGo L),
((modMask conf , d), WNGo D),
((modMask conf , r), WNGo R),
((modMask conf .|. shiftMask, u), WNSwap U),
((modMask conf .|. shiftMask, l), WNSwap L),
((modMask conf .|. shiftMask, d), WNSwap D),
((modMask conf .|. shiftMask, r), WNSwap R) ]
conf
withWindowNavigationKeys :: [((KeyMask, KeySym), WNAction)] -> XConfig l -> IO (XConfig l)
withWindowNavigationKeys wnKeys conf = do
posRef <- newIORef M.empty
return conf { keys = \cnf -> M.fromList (map (second (fromWNAction posRef)) wnKeys)
`M.union` keys conf cnf,
logHook = logHook conf >> trackMovement posRef }
where fromWNAction posRef (WNGo dir) = go posRef dir
fromWNAction posRef (WNSwap dir) = swap posRef dir
data WNAction = WNGo Direction | WNSwap Direction
type WNState = Map WorkspaceId Point
-- go:
-- 1. get current position, verifying it matches the current window
-- 2. get target windowrect
-- 3. focus window
-- 4. set new position
go :: IORef WNState -> Direction -> X ()
go = withTargetWindow W.focusWindow
swap :: IORef WNState -> Direction -> X ()
swap = withTargetWindow swapWithFocused
where swapWithFocused targetWin winSet =
case W.peek winSet of
Just currentWin -> W.focusWindow currentWin $
mapWindows (swapWin currentWin targetWin) winSet
Nothing -> winSet
mapWindows f ss = W.mapWorkspace (mapWindows' f) ss
mapWindows' f ws@(W.Workspace { W.stack = s }) = ws { W.stack = mapWindows'' f <$> s }
mapWindows'' f (W.Stack focused up down) = W.Stack (f focused) (map f up) (map f down)
swapWin win1 win2 win = if win == win1 then win2 else if win == win2 then win1 else win
withTargetWindow :: (Window -> WindowSet -> WindowSet) -> IORef WNState -> Direction -> X ()
withTargetWindow adj posRef dir = fromCurrentPoint posRef $ \win pos -> do
targets <- filter ((/= win) . fst) <$> navigableTargets pos dir
whenJust (listToMaybe targets) $ \(targetWin, targetRect) -> do
windows (adj targetWin)
setPosition posRef pos targetRect
trackMovement :: IORef WNState -> X ()
trackMovement posRef = fromCurrentPoint posRef $ \win pos -> do
windowRect win >>= flip whenJust (setPosition posRef pos . snd)
fromCurrentPoint :: IORef WNState -> (Window -> Point -> X ()) -> X ()
fromCurrentPoint posRef f = withFocused $ \win -> do
currentPosition posRef >>= f win
-- Gets the current position from the IORef passed in, or if nothing (say, from
-- a restart), derives the current position from the current window. Also,
-- verifies that the position is congruent with the current window (say, if you
-- used mod-j/k or mouse or something).
currentPosition :: IORef WNState -> X Point
currentPosition posRef = do
root <- asks theRoot
currentWindow <- gets (W.peek . windowset)
currentRect <- maybe (Rectangle 0 0 0 0) snd <$> windowRect (fromMaybe root currentWindow)
wsid <- gets (W.currentTag . windowset)
mp <- M.lookup wsid <$> io (readIORef posRef)
return $ maybe (middleOf currentRect) (`inside` currentRect) mp
where middleOf (Rectangle x y w h) = Point (midPoint x w) (midPoint y h)
setPosition :: IORef WNState -> Point -> Rectangle -> X ()
setPosition posRef oldPos newRect = do
wsid <- gets (W.currentTag . windowset)
io $ modifyIORef posRef $ M.insert wsid (oldPos `inside` newRect)
inside :: Point -> Rectangle -> Point
Point x y `inside` Rectangle rx ry rw rh =
Point (x `within` (rx, rw)) (y `within` (ry, rh))
where pos `within` (lower, dim) = if pos >= lower && pos < lower + fromIntegral dim
then pos
else midPoint lower dim
midPoint :: Position -> Dimension -> Position
midPoint pos dim = pos + fromIntegral dim `div` 2
navigableTargets :: Point -> Direction -> X [(Window, Rectangle)]
navigableTargets point dir = navigable dir point <$> windowRects
-- Filters and sorts the windows in terms of what is closest from the Point in
-- the Direction.
navigable :: Direction -> Point -> [(Window, Rectangle)] -> [(Window, Rectangle)]
navigable d pt = sortby d . filter (inr d pt . snd)
-- Produces a list of normal-state windows, on any screen. Rectangles are
-- adjusted based on screen position relative to the current screen, because I'm
-- bad like that.
windowRects :: X [(Window, Rectangle)]
windowRects = fmap catMaybes . mapM windowRect . S.toList =<< gets mapped
windowRect :: Window -> X (Maybe (Window, Rectangle))
windowRect win = withDisplay $ \dpy -> do
(_, x, y, w, h, bw, _) <- io $ getGeometry dpy win
return $ Just $ (win, Rectangle x y (w + 2 * bw) (h + 2 * bw))
`catchX` return Nothing
-- Modified from droundy's implementation of WindowNavigation:
inr :: Direction -> Point -> Rectangle -> Bool
inr D (Point px py) (Rectangle rx ry w h) = px >= rx && px < rx + fromIntegral w &&
py < ry + fromIntegral h
inr U (Point px py) (Rectangle rx ry w _) = px >= rx && px < rx + fromIntegral w &&
py > ry
inr R (Point px py) (Rectangle rx ry _ h) = px < rx &&
py >= ry && py < ry + fromIntegral h
inr L (Point px py) (Rectangle rx ry w h) = px > rx + fromIntegral w &&
py >= ry && py < ry + fromIntegral h
sortby :: Direction -> [(a,Rectangle)] -> [(a,Rectangle)]
sortby D = sortBy $ comparing (rect_y . snd)
sortby R = sortBy $ comparing (rect_x . snd)
sortby U = reverse . sortby D
sortby L = reverse . sortby R

188
XMonad/Config/Arossato.hs Normal file
View File

@@ -0,0 +1,188 @@
{-# OPTIONS_GHC -fglasgow-exts -fno-warn-missing-signatures #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Config.Arossato
-- Copyright : (c) Andrea Rossato 2007
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : stable
-- Portability : portable
--
-- This module specifies my xmonad defaults.
--
------------------------------------------------------------------------
module XMonad.Config.Arossato
( -- * Usage
-- $usage
arossatoConfig
) where
import qualified Data.Map as M
import XMonad hiding ( (|||) )
import qualified XMonad.StackSet as W
import XMonad.Actions.CycleWS
import XMonad.Hooks.DynamicLog hiding (xmobar)
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.ServerMode
import XMonad.Layout.Accordion
import XMonad.Layout.LayoutCombinators
import XMonad.Layout.Magnifier
import XMonad.Layout.NoBorders
import XMonad.Layout.SimpleFloat
import XMonad.Layout.Tabbed
import XMonad.Layout.WindowArranger
import XMonad.Prompt
import XMonad.Prompt.Shell
import XMonad.Prompt.Ssh
import XMonad.Prompt.Theme
import XMonad.Prompt.Window
import XMonad.Prompt.XMonad
import XMonad.Util.Run
import XMonad.Util.Themes
-- $usage
-- The simplest way to use this configuration module is to use an
-- @~\/.xmonad\/xmonad.hs@ like this:
--
-- > module Main (main) where
-- >
-- > import XMonad
-- > import XMonad.Config.Arossato (arossatoConfig)
-- >
-- > main :: IO ()
-- > main = xmonad =<< arossatoConfig
--
-- NOTE: that I'm using xmobar and, if you don't have xmobar in your
-- PATH, this configuration will produce an error and xmonad will not
-- start. If you don't want to install xmobar get rid of this line at
-- the beginning of 'arossatoConfig'.
--
-- You can use this module also as a starting point for writing your
-- own configuration module from scratch. Save it as your
-- @~\/.xmonad\/xmonad.hs@ and:
--
-- 1. Change the module name from
--
-- > module XMonad.Config.Arossato
-- > ( -- * Usage
-- > -- $usage
-- > arossatoConfig
-- > ) where
--
-- to
--
-- > module Main where
--
-- 2. Add a line like:
--
-- > main = xmonad =<< arossatoConfig
--
-- 3. Start playing with the configuration options...;)
arossatoConfig = do
xmobar <- spawnPipe "xmobar" -- REMOVE this line if you do not have xmobar installed!
return $ defaultConfig
{ workspaces = ["home","var","dev","mail","web","doc"] ++
map show [7 .. 9 :: Int]
, logHook = myDynLog xmobar -- REMOVE this line if you do not have xmobar installed!
, manageHook = newManageHook
, layoutHook = eventHook ServerMode $
avoidStruts $
decorated |||
noBorders mytabs |||
otherLays
, terminal = "urxvt +sb"
, normalBorderColor = "white"
, focusedBorderColor = "black"
, keys = newKeys
, focusFollowsMouse = False
}
where
-- layouts
mytabs = tabbed shrinkText (theme smallClean)
decorated = simpleFloat' shrinkText (theme smallClean)
tiled = Tall 1 (3/100) (1/2)
otherLays = windowArrange $
magnifier tiled |||
noBorders Full |||
Mirror tiled |||
Accordion
-- manageHook
myManageHook = composeAll [ resource =? "win" --> doF (W.shift "doc") -- xpdf
, resource =? "firefox-bin" --> doF (W.shift "web")
]
newManageHook = myManageHook
-- xmobar
myDynLog h = dynamicLogWithPP defaultPP
{ ppCurrent = xmobarColor "yellow" "" . wrap "[" "]"
, ppTitle = xmobarColor "green" "" . shorten 40
, ppVisible = wrap "(" ")"
, ppOutput = hPutStrLn h
}
-- key bindings stuff
defKeys = keys defaultConfig
delKeys x = foldr M.delete (defKeys x) (toRemove x)
newKeys x = foldr (uncurry M.insert) (delKeys x) (toAdd x)
-- remove some of the default key bindings
toRemove x =
[ (modMask x , xK_j)
, (modMask x , xK_k)
, (modMask x , xK_p)
, (modMask x .|. shiftMask, xK_p)
, (modMask x .|. shiftMask, xK_q)
, (modMask x , xK_q)
] ++
-- I want modMask .|. shiftMask 1-9 to be free!
[(shiftMask .|. modMask x, k) | k <- [xK_1 .. xK_9]]
-- These are my personal key bindings
toAdd x =
[ ((modMask x , xK_F12 ), xmonadPrompt defaultXPConfig )
, ((modMask x , xK_F3 ), shellPrompt defaultXPConfig )
, ((modMask x , xK_F4 ), sshPrompt defaultXPConfig )
, ((modMask x , xK_F5 ), themePrompt defaultXPConfig )
, ((modMask x , xK_F6 ), windowPromptGoto defaultXPConfig )
, ((modMask x , xK_F7 ), windowPromptBring defaultXPConfig )
, ((modMask x , xK_comma ), prevWS )
, ((modMask x , xK_period), nextWS )
, ((modMask x , xK_Right ), windows W.focusDown )
, ((modMask x , xK_Left ), windows W.focusUp )
-- other stuff: launch some useful utilities
, ((modMask x , xK_F2 ), spawn "urxvt -fg white -bg black +sb" )
, ((modMask x .|. shiftMask, xK_F4 ), spawn "~/bin/dict.sh" )
, ((modMask x .|. shiftMask, xK_F5 ), spawn "~/bin/urlOpen.sh" )
, ((modMask x .|. shiftMask, xK_t ), spawn "~/bin/teaTime.sh" )
, ((modMask x , xK_c ), kill )
, ((modMask x .|. shiftMask, xK_comma ), sendMessage (IncMasterN 1 ) )
, ((modMask x .|. shiftMask, xK_period), sendMessage (IncMasterN (-1)) )
-- commands fo the Magnifier layout
, ((modMask x .|. controlMask , xK_plus ), sendMessage MagnifyMore)
, ((modMask x .|. controlMask , xK_minus), sendMessage MagnifyLess)
, ((modMask x .|. controlMask , xK_o ), sendMessage ToggleOff )
, ((modMask x .|. controlMask .|. shiftMask, xK_o ), sendMessage ToggleOn )
-- windowArranger
, ((modMask x .|. controlMask , xK_a ), sendMessage Arrange )
, ((modMask x .|. controlMask .|. shiftMask, xK_a ), sendMessage DeArrange )
, ((modMask x .|. controlMask , xK_Left ), sendMessage (DecreaseLeft 10))
, ((modMask x .|. controlMask , xK_Up ), sendMessage (DecreaseUp 10))
, ((modMask x .|. controlMask , xK_Right), sendMessage (IncreaseRight 10))
, ((modMask x .|. controlMask , xK_Down ), sendMessage (IncreaseDown 10))
, ((modMask x .|. shiftMask , xK_Left ), sendMessage (MoveLeft 10))
, ((modMask x .|. shiftMask , xK_Right), sendMessage (MoveRight 10))
, ((modMask x .|. shiftMask , xK_Down ), sendMessage (MoveDown 10))
, ((modMask x .|. shiftMask , xK_Up ), sendMessage (MoveUp 10))
-- gaps
, ((modMask x , xK_b ), sendMessage ToggleStruts )
] ++
-- Use modMask .|. shiftMask .|. controlMask 1-9 instead
[( (m .|. modMask x, k), windows $ f i)
| (i, k) <- zip (workspaces x) [xK_1 .. xK_9]
, (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask .|. controlMask)]
]

46
XMonad/Config/Azerty.hs Normal file
View File

@@ -0,0 +1,46 @@
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Config.Azerty
-- Copyright : (c) Devin Mullins <me@twifkak.com>
-- License : BSD
--
-- Maintainer : Devin Mullins <me@twifkak.com>
--
-- This module fixes some of the keybindings for the francophone among you who
-- use an AZERTY keyboard layout. Config stolen from TeXitoi's config on the
-- wiki.
module XMonad.Config.Azerty (
-- * Usage
-- $usage
azertyConfig, azertyKeys
) where
import XMonad
import qualified XMonad.StackSet as W
import qualified Data.Map as M
-- $usage
-- To use this module, start with the following @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad
-- > import XMonad.Config.Azerty
-- >
-- > main = xmonad azertyConfig
--
-- If you prefer, an azertyKeys function is provided which you can use as so:
--
-- > import qualified Data.Map as M
-- > main = xmonad someConfig { keys = \c -> azertyKeys c `M.union` keys someConfig c }
azertyConfig = defaultConfig { keys = \c -> azertyKeys c `M.union` keys defaultConfig c }
azertyKeys conf@(XConfig {modMask = modm}) = M.fromList $
[((modm, xK_semicolon), sendMessage (IncMasterN (-1)))]
++
[((m .|. modm, k), windows $ f i)
| (i, k) <- zip (workspaces conf) [0x26,0xe9,0x22,0x27,0x28,0x2d,0xe8,0x5f,0xe7,0xe0],
(f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]

35
XMonad/Config/Desktop.hs Normal file
View File

@@ -0,0 +1,35 @@
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Config.Desktop
-- Copyright : (c) Spencer Janssen <spencerjanssen@gmail.com>
-- License : BSD
--
-- Maintainer : Spencer Janssen <spencerjanssen@gmail.com>
--
-- This module provides a config suitable for use with a desktop
-- environment such as KDE or GNOME.
module XMonad.Config.Desktop (
desktopConfig,
desktopLayoutModifiers
) where
import XMonad
import XMonad.Config (defaultConfig)
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.EwmhDesktops
import qualified Data.Map as M
desktopConfig = defaultConfig
{ logHook = ewmhDesktopsLogHook
, layoutHook = desktopLayoutModifiers $ layoutHook defaultConfig
, manageHook = manageHook defaultConfig <+> manageDocks
, keys = \c -> desktopKeys c `M.union` keys defaultConfig c }
desktopKeys (XConfig {modMask = modm}) = M.fromList $
[ ((modm, xK_b), sendMessage ToggleStruts) ]
desktopLayoutModifiers layout = avoidStruts $ ewmhDesktopsLayout layout

185
XMonad/Config/Droundy.hs Normal file
View File

@@ -0,0 +1,185 @@
{-# OPTIONS_GHC -fno-warn-missing-signatures -fglasgow-exts -fno-warn-orphans #-}
-----------------------------------------------------------------------------
-- |
-- Copyright : (c) Spencer Janssen 2007
-- License : BSD3-style (see LICENSE)
--
------------------------------------------------------------------------
module XMonad.Config.Droundy ( config, mytab ) where
import XMonad hiding (keys, config, (|||))
import qualified XMonad (keys)
import XMonad.Config ( defaultConfig )
import qualified XMonad.StackSet as W
import qualified Data.Map as M
import System.Exit ( exitWith, ExitCode(ExitSuccess) )
import XMonad.Layout.Tabbed ( tabbed, defaultTheme,
shrinkText, Shrinker, shrinkIt, CustomShrink(CustomShrink) )
import XMonad.Layout.Combo ( combineTwo )
import XMonad.Layout.Named ( named )
import XMonad.Layout.LayoutCombinators
import XMonad.Layout.Square ( Square(Square) )
import XMonad.Layout.WindowNavigation ( Navigate(Move,Swap,Go), Direction(U,D,R,L),
windowNavigation )
import XMonad.Layout.BoringWindows ( boringWindows, markBoring, clearBoring,
focusUp, focusDown )
import XMonad.Layout.NoBorders ( smartBorders )
import XMonad.Layout.WorkspaceDir ( changeDir, workspaceDir )
import XMonad.Layout.ToggleLayouts ( toggleLayouts, ToggleLayout(ToggleLayout) )
import XMonad.Layout.ShowWName ( showWName )
import XMonad.Layout.Magnifier ( maximizeVertical, MagnifyMsg(Toggle) )
import XMonad.Prompt ( defaultXPConfig, font, height, XPConfig )
import XMonad.Prompt.Layout ( layoutPrompt )
import XMonad.Prompt.Shell ( shellPrompt )
import XMonad.Actions.CopyWindow ( kill1, copy )
import XMonad.Actions.DynamicWorkspaces ( withNthWorkspace, withWorkspace,
selectWorkspace, renameWorkspace, removeWorkspace )
import XMonad.Actions.CycleWS ( moveTo, WSType( HiddenNonEmptyWS ),
WSDirection( Prev, Next) )
import XMonad.Hooks.ManageDocks ( avoidStruts, manageDocks )
import XMonad.Hooks.EwmhDesktops ( ewmhDesktopsLogHook,
ewmhDesktopsLayout )
myXPConfig :: XPConfig
myXPConfig = defaultXPConfig {font="-*-lucida-medium-r-*-*-14-*-*-*-*-*-*-*"
,height=22}
------------------------------------------------------------------------
-- Key bindings:
-- | The xmonad key bindings. Add, modify or remove key bindings here.
--
-- (The comment formatting character is used when generating the manpage)
--
keys :: XConfig Layout -> M.Map (KeyMask, KeySym) (X ())
keys x = M.fromList $
-- launching and killing programs
[ ((modMask x .|. shiftMask, xK_c ), kill1) -- %! Close the focused window
, ((modMask x .|. shiftMask, xK_space ), sendMessage NextLayout) -- %! Rotate through the available layout algorithms
, ((modMask x .|. controlMask .|. shiftMask, xK_L ), setLayout $ layoutHook x) -- %! Reset the layouts on the current workspace to default
-- move focus up or down the window stack
, ((modMask x, xK_Tab ), focusDown) -- %! Move focus to the next window
, ((modMask x, xK_j ), focusDown) -- %! Move focus to the next window
, ((modMask x, xK_k ), focusUp ) -- %! Move focus to the previous window
, ((modMask x .|. shiftMask, xK_j ), windows W.swapDown ) -- %! Swap the focused window with the next window
, ((modMask x .|. shiftMask, xK_k ), windows W.swapUp ) -- %! Swap the focused window with the previous window
-- floating layer support
, ((modMask x, xK_t ), withFocused $ windows . W.sink) -- %! Push window back into tiling
-- quit, or restart
, ((modMask x .|. shiftMask, xK_Escape), io (exitWith ExitSuccess)) -- %! Quit xmonad
, ((modMask x , xK_Escape), restart "xmonad" True) -- %! Restart xmonad
, ((modMask x .|. shiftMask, xK_Right), moveTo Next HiddenNonEmptyWS)
, ((modMask x .|. shiftMask, xK_Left), moveTo Prev HiddenNonEmptyWS)
, ((modMask x, xK_Right), sendMessage $ Go R)
, ((modMask x, xK_Left), sendMessage $ Go L)
, ((modMask x, xK_Up), sendMessage $ Go U)
, ((modMask x, xK_Down), sendMessage $ Go D)
, ((modMask x .|. controlMask, xK_Right), sendMessage $ Swap R)
, ((modMask x .|. controlMask, xK_Left), sendMessage $ Swap L)
, ((modMask x .|. controlMask, xK_Up), sendMessage $ Swap U)
, ((modMask x .|. controlMask, xK_Down), sendMessage $ Swap D)
, ((modMask x .|. controlMask .|. shiftMask, xK_Right), sendMessage $ Move R)
, ((modMask x .|. controlMask .|. shiftMask, xK_Left), sendMessage $ Move L)
, ((modMask x .|. controlMask .|. shiftMask, xK_Up), sendMessage $ Move U)
, ((modMask x .|. controlMask .|. shiftMask, xK_Down), sendMessage $ Move D)
, ((0, xK_F2 ), spawn "gnome-terminal") -- %! Launch gnome-terminal
, ((0, xK_F3 ), shellPrompt myXPConfig) -- %! Launch program
, ((0, xK_F11 ), spawn "ksnapshot") -- %! Take snapshot
, ((modMask x .|. shiftMask, xK_b ), markBoring)
, ((controlMask .|. modMask x .|. shiftMask, xK_b ), clearBoring)
, ((modMask x .|. shiftMask, xK_x ), changeDir myXPConfig)
, ((modMask x .|. shiftMask, xK_BackSpace), removeWorkspace)
, ((modMask x .|. shiftMask, xK_v ), selectWorkspace myXPConfig)
, ((modMask x, xK_m ), withWorkspace myXPConfig (windows . W.shift))
, ((modMask x .|. shiftMask, xK_m ), withWorkspace myXPConfig (windows . copy))
, ((modMask x .|. shiftMask, xK_r), renameWorkspace myXPConfig)
, ((modMask x, xK_l ), layoutPrompt myXPConfig)
, ((modMask x .|. controlMask, xK_space), sendMessage ToggleLayout)
, ((modMask x, xK_space), sendMessage Toggle)
]
++
zip (zip (repeat $ modMask x) [xK_F1..xK_F12]) (map (withNthWorkspace W.greedyView) [0..])
++
zip (zip (repeat (modMask x .|. shiftMask)) [xK_F1..xK_F12]) (map (withNthWorkspace copy) [0..])
config = defaultConfig
{ borderWidth = 1 -- Width of the window border in pixels.
, XMonad.workspaces = ["mutt","iceweasel"]
, layoutHook = ewmhDesktopsLayout $ showWName $ workspaceDir "~" $
boringWindows $ smartBorders $ windowNavigation $
maximizeVertical $ toggleLayouts Full $ avoidStruts $
named "tabbed" mytab |||
named "xclock" (mytab ****//* combineTwo Square mytab mytab) |||
named "three" (mytab **//* mytab *//* combineTwo Square mytab mytab) |||
named "widescreen" ((mytab *||* mytab)
****//* combineTwo Square mytab mytab) -- |||
--mosaic 0.25 0.5
, manageHook = manageHook defaultConfig <+> manageDocks -- add panel-handling
, logHook = ewmhDesktopsLogHook -- actually, no logging here, just other stuff
, terminal = "xterm" -- The preferred terminal program.
, normalBorderColor = "#222222" -- Border color for unfocused windows.
, focusedBorderColor = "#00ff00" -- Border color for focused windows.
, XMonad.modMask = mod1Mask
, XMonad.keys = keys
}
mytab = tabbed CustomShrink defaultTheme
instance Shrinker CustomShrink where
shrinkIt shr s | Just s' <- dropFromHead " " s = shrinkIt shr s'
shrinkIt shr s | Just s' <- dropFromTail " " s = shrinkIt shr s'
shrinkIt shr s | Just s' <- dropFromTail "- Iceweasel" s = shrinkIt shr s'
shrinkIt shr s | Just s' <- dropFromTail "- KPDF" s = shrinkIt shr s'
shrinkIt shr s | Just s' <- dropFromHead "file://" s = shrinkIt shr s'
shrinkIt shr s | Just s' <- dropFromHead "http://" s = shrinkIt shr s'
shrinkIt _ s | n > 9 = s : map cut [2..(halfn-3)] ++ shrinkIt shrinkText s
where n = length s
halfn = n `div` 2
rs = reverse s
cut x = take (halfn - x) s ++ "..." ++ reverse (take (halfn-x) rs)
shrinkIt _ s = shrinkIt shrinkText s
dropFromTail :: String -> String -> Maybe String
dropFromTail "" _ = Nothing
dropFromTail t s | drop (length s - length t) s == t = Just $ take (length s - length t) s
| otherwise = Nothing
dropFromHead :: String -> String -> Maybe String
dropFromHead "" _ = Nothing
dropFromHead h s | take (length h) s == h = Just $ drop (length h) s
| otherwise = Nothing
{-
data FocusUrgencyHook = FocusUrgencyHook deriving (Read, Show)
instance UrgencyHook FocusUrgencyHook Window where
urgencyHook _ w = modify copyAndFocus
where copyAndFocus s
| Just w == W.peek (windowset s) = s
| has w $ W.stack $ W.workspace $ W.current $ windowset s =
s { windowset = until ((Just w ==) . W.peek)
W.focusUp $ windowset s }
| otherwise =
let t = W.currentTag $ windowset s
in s { windowset = until ((Just w ==) . W.peek)
W.focusUp $ copyWindow w t $ windowset s }
has _ Nothing = False
has x (Just (W.Stack t l rr)) = x `elem` (t : l ++ rr)
-}

55
XMonad/Config/Gnome.hs Normal file
View File

@@ -0,0 +1,55 @@
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Config.Gnome
-- Copyright : (c) Spencer Janssen <spencerjanssen@gmail.com>
-- License : BSD
--
-- Maintainer : Spencer Janssen <spencerjanssen@gmail.com>
--
-- This module provides a config suitable for use with the GNOME desktop
-- environment.
module XMonad.Config.Gnome (
-- * Usage
-- $usage
gnomeConfig,
gnomeRun
) where
import XMonad
import XMonad.Config.Desktop
import qualified Data.Map as M
-- $usage
-- To use this module, start with the following @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad
-- > import XMonad.Config.Gnome
-- >
-- > main = xmonad gnomeConfig
--
gnomeConfig = desktopConfig
{ terminal = "gnome-terminal"
, keys = \c -> gnomeKeys c `M.union` keys desktopConfig c }
gnomeKeys (XConfig {modMask = modm}) = M.fromList $
[ ((modm, xK_p), gnomeRun)
, ((modm .|. shiftMask, xK_q), spawn "gnome-session-save --kill") ]
-- | Launch the "Run Application" dialog. gnome-panel must be running for this
-- to work.
gnomeRun :: X ()
gnomeRun = withDisplay $ \dpy -> do
rw <- asks theRoot
gnome_panel <- getAtom "_GNOME_PANEL_ACTION"
panel_run <- getAtom "_GNOME_PANEL_ACTION_RUN_DIALOG"
io $ allocaXEvent $ \e -> do
setEventType e clientMessage
setClientMessageEvent e rw gnome_panel 32 panel_run 0
sendEvent dpy rw False structureNotifyMask e
sync dpy False

53
XMonad/Config/Kde.hs Normal file
View File

@@ -0,0 +1,53 @@
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Config.Kde
-- Copyright : (c) Spencer Janssen <spencerjanssen@gmail.com>
-- License : BSD
--
-- Maintainer : Spencer Janssen <spencerjanssen@gmail.com>
--
-- This module provides a config suitable for use with the KDE desktop
-- environment.
module XMonad.Config.Kde (
-- * Usage
-- $usage
kdeConfig,
kde4Config
) where
import XMonad
import XMonad.Config.Desktop
import qualified Data.Map as M
-- $usage
-- To use this module, start with the following @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad
-- > import XMonad.Config.Kde
-- >
-- > main = xmonad kdeConfig
--
-- For KDE 4, replace 'kdeConfig' with 'kde4Config'
--
kdeConfig = desktopConfig
{ terminal = "konsole"
, keys = \c -> kdeKeys c `M.union` keys desktopConfig c }
kde4Config = desktopConfig
{ terminal = "konsole"
, keys = \c -> kde4Keys c `M.union` keys desktopConfig c }
kdeKeys (XConfig {modMask = modm}) = M.fromList $
[ ((modm, xK_p), spawn "dcop kdesktop default popupExecuteCommand")
, ((modm .|. shiftMask, xK_q), spawn "dcop kdesktop default logout")
]
kde4Keys (XConfig {modMask = modm}) = M.fromList $
[ ((modm, xK_p), spawn "krunner")
, ((modm .|. shiftMask, xK_q), spawn "dbus-send --print-reply --dest=org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout int32:1 int32:0 int32:1")
]

49
XMonad/Config/Monad.hs Normal file
View File

@@ -0,0 +1,49 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- experimental, not expected to work
{- our goal:
config = do
add layout Full
set terminal "urxvt"
add keys [blah blah blah]
-}
{-
ideas:
composability!
"only once" features like avoidStruts, ewmhDesktops
-}
module XMonad.Config.Monad where
import XMonad hiding (terminal, keys)
import qualified XMonad as X
import Control.Monad.Writer
import Data.Monoid
import Data.Accessor
import Data.Accessor.Basic hiding (set)
-- Ugly! To fix this we'll need to change the kind of XConfig.
newtype LayoutList a = LL [Layout a] deriving Monoid
type W = Dual (Endo (XConfig LayoutList))
mkW = Dual . Endo
newtype Config a = C (WriterT W IO a)
deriving (Functor, Monad, MonadWriter W)
-- references:
layout = fromSetGet (\x c -> c { layoutHook = x }) layoutHook
terminal = fromSetGet (\x c -> c { X.terminal = x }) X.terminal
keys = fromSetGet (\x c -> c { X.keys = x }) X.keys
set :: Accessor (XConfig LayoutList) a -> a -> Config ()
set r x = tell (mkW $ r ^= x)
add r x = tell (mkW (r ^: mappend x))
--
example :: Config ()
example = do
add layout $ LL [Layout $ Full] -- make this better
set terminal "urxvt"

65
XMonad/Config/Sjanssen.hs Normal file
View File

@@ -0,0 +1,65 @@
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
module XMonad.Config.Sjanssen (sjanssenConfig, sjanssenConfigXmobar) where
import XMonad hiding (Tall(..))
import qualified XMonad.StackSet as W
import XMonad.Actions.CopyWindow
import XMonad.Layout.Tabbed
import XMonad.Layout.HintedTile
import XMonad.Config (defaultConfig)
import XMonad.Layout.NoBorders
import XMonad.Hooks.DynamicLog hiding (xmobar)
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.EwmhDesktops
import XMonad.Prompt
import XMonad.Actions.SpawnOn
import XMonad.Layout.LayoutScreens
import XMonad.Layout.TwoPane
import qualified Data.Map as M
sjanssenConfigXmobar = statusBar "xmobar" sjanssenPP strutkey =<< sjanssenConfig
where
strutkey (XConfig {modMask = modm}) = (modm, xK_b)
sjanssenConfig = do
sp <- mkSpawner
return $ defaultConfig
{ terminal = "urxvtc"
, workspaces = ["irc", "web"] ++ map show [3 .. 9 :: Int]
, mouseBindings = \(XConfig {modMask = modm}) -> M.fromList $
[ ((modm, button1), (\w -> focus w >> mouseMoveWindow w))
, ((modm, button2), (\w -> focus w >> windows W.swapMaster))
, ((modm.|. shiftMask, button1), (\w -> focus w >> mouseResizeWindow w)) ]
, keys = \c -> mykeys sp c `M.union` keys defaultConfig c
, layoutHook = modifiers layouts
, logHook = ewmhDesktopsLogHook
, manageHook = composeAll [className =? x --> doF (W.shift w)
| (x, w) <- [ ("Firefox", "web")
, ("Ktorrent", "7")
, ("Amarokapp", "7")]]
<+> manageHook defaultConfig <+> manageDocks <+> manageSpawn sp
}
where
tiled = HintedTile 1 0.03 0.5 TopLeft
layouts = (tiled Tall ||| (tiled Wide ||| Full)) ||| tabbed shrinkText myTheme
modifiers = smartBorders
mykeys sp (XConfig {modMask = modm, workspaces = ws}) = M.fromList $
[((modm, xK_p ), shellPromptHere sp myPromptConfig)
,((modm .|. shiftMask, xK_c ), kill1)
,((modm .|. shiftMask .|. controlMask, xK_c ), kill)
,((modm .|. shiftMask, xK_0 ), windows $ \w -> foldr copy w ws)
,((modm, xK_z ), layoutScreens 2 $ TwoPane 0.5 0.5)
,((modm .|. shiftMask, xK_z ), rescreen)
]
myFont = "xft:Bitstream Vera Sans Mono:pixelsize=10"
myTheme = defaultTheme { fontName = myFont }
myPromptConfig = defaultXPConfig
{ position = Top
, font = myFont
, showCompletionOnTab = True
, historyFilter = deleteConsecutive
, promptBorderWidth = 0 }

42
XMonad/Config/Xfce.hs Normal file
View File

@@ -0,0 +1,42 @@
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Config.Xfce
-- Copyright : (c) Ivan Miljenovic <Ivan.Miljenovic@gmail.com>
-- License : BSD
--
-- Maintainer : Ivan Miljenovic <Ivan.Miljenovic@gmail.com>
--
-- This module provides a config suitable for use with the Xfce desktop
-- environment.
module XMonad.Config.Xfce (
-- * Usage
-- $usage
xfceConfig
) where
import XMonad
import XMonad.Config.Desktop
import qualified Data.Map as M
-- $usage
-- To use this module, start with the following @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad
-- > import XMonad.Config.Xfce
-- >
-- > main = xmonad xfceConfig
--
xfceConfig = desktopConfig
{ terminal = "Terminal"
, keys = \c -> xfceKeys c `M.union` keys desktopConfig c }
xfceKeys (XConfig {modMask = modm}) = M.fromList $
[ ((modm, xK_p), spawn "xfrun4")
, ((modm .|. shiftMask, xK_p), spawn "xfce4-appfinder")
, ((modm .|. shiftMask, xK_q), spawn "xfce4-session-logout")
]

86
XMonad/Doc.hs Normal file
View File

@@ -0,0 +1,86 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Doc
-- Copyright : (C) 2007 Andrea Rossato
-- License : BSD3
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : portable
--
-- This is the main documentation module for the xmonad-contrib
-- library. It provides a brief overview of xmonad and a link to
-- documentation for configuring and extending xmonad.
--
-- A link to documentation describing xmonad internals is also provided.
-- This module is mainly intended for those wanting to contribute code,
-- or for those who are curious to know what's going on behind the scenes.
-----------------------------------------------------------------------------
module XMonad.Doc
(
-- * Overview
-- $overview
-- * Configuring xmonad
-- $configuring
-- * Extending xmonad with the xmonad-contrib library
-- $extending
-- * Developing xmonad: a brief code commentary
-- $developing
) where
import XMonad.Doc.Configuring ()
import XMonad.Doc.Extending ()
import XMonad.Doc.Developing ()
--------------------------------------------------------------------------------
--
-- Overview
--
--------------------------------------------------------------------------------
{- $overview
#Overview#
xmonad is a tiling window manager for X. The xmonad-contrib library
collects third party tiling algorithms, hooks, configurations,
scripts, and other extensions to xmonad. The source for this library
is available from <http://code.haskell.org/XMonadContrib> via darcs:
> darcs get http://code.haskell.org/XMonadContrib
Each stable release of xmonad is accompanied by a stable release of
the contrib library, which you should use if (and only if) you're
using a stable release of xmonad. You can find the most recent
tarball here:
<http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmonad-contrib>
-}
{- $configuring
"XMonad.Doc.Configuring" documents the process of configuring
xmonad. A brief tutorial will guide you through the basic
configuration steps.
-}
{- $extending
"XMonad.Doc.Extending" is dedicated to the xmonad-contrib library
itself. You will find an overview of extensions available in the
library and instructions for using them.
-}
{- $developing
"XMonad.Doc.Developing" consists of a brief description of the xmonad
internals. It is mainly intended for contributors and provides a
brief code commentary with links to the source documentation.
-}

153
XMonad/Doc/Configuring.hs Normal file
View File

@@ -0,0 +1,153 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Doc.Configuring
-- Copyright : (C) 2007 Don Stewart and Andrea Rossato
-- License : BSD3
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : portable
--
-- This is a brief tutorial that will teach you how to create a
-- basic xmonad configuration.
--
-- For more detailed instructions on extending xmonad with the
-- xmonad-contrib library, see "XMonad.Doc.Extending".
--
-----------------------------------------------------------------------------
module XMonad.Doc.Configuring
(
-- * Configuring xmonad
-- $configure
-- * A simple example
-- $example
-- * Checking whether your xmonad.hs is correct
-- $check
-- * Loading your configuration
-- $load
) where
--------------------------------------------------------------------------------
--
-- Configuring Xmonad
--
--------------------------------------------------------------------------------
{- $configure
#Configuring_xmonad#
xmonad can be configured by creating and editing the Haskell file:
> ~/.xmonad/xmonad.hs
If this file does not exist, xmonad will simply use default settings;
if it does exist, xmonad will use whatever settings you specify. Note
that this file can contain arbitrary Haskell code, which means that
you have quite a lot of flexibility in configuring xmonad.
NOTE for users of previous versions (< 0.5) of xmonad: this is a major
change in the way xmonad is configured. Prior to version 0.5,
configuring xmonad required editing an xmonad source file called
Config.hs, recompiling xmonad, and then restarting. From version 0.5
onwards, however, you should NOT edit this file. All you have to do
is edit xmonad.hs and restart with @mod-q@; xmonad does the
recompiling itself. The format of the configuration file has also
changed; it is now simpler and much shorter, only requiring you to
list those settings which are different from the defaults.
-}
{- $example
#A_simple_example#
Here is a basic example, which starts with the default xmonad
configuration and overrides the border width, default terminal, and
some colours:
> --
> -- An example, simple ~/.xmonad/xmonad.hs file.
> -- It overrides a few basic settings, reusing all the other defaults.
> --
>
> import XMonad
>
> main = xmonad $ defaultConfig
> { borderWidth = 2
> , terminal = "urxvt"
> , normalBorderColor = "#cccccc"
> , focusedBorderColor = "#cd8b00" }
This will run \'xmonad\', the window manager, with your settings
passed as arguments.
Overriding default settings like this (using \"record update
syntax\"), will yield the shortest config file, as you only have to
describe values that differ from the defaults.
As an alternative, you can copy the template @xmonad.hs@ file (found
either in the @man@ directory, if you have the xmonad source, or on
the xmonad wiki at
@http:\/\/haskell.org\/haskellwiki\/Xmonad\/Config_archive\/Template_xmonad.hs@)
into your @~\/.xmonad\/@ directory. This template file contains all
the default settings spelled out, and you should be able to simply
change the ones you would like to change.
To see what fields can be customized beyond the ones in the example
above, the definition of the 'XMonad.Core.XConfig' data structure can
be found in "XMonad.Core".
-}
{- $check
#Checking_whether_your_xmonad.hs_is_correct#
After changing your configuration, it is a good idea to check that it
is syntactically and type correct. You can do this easily by loading
your configuration file in the Haskell interpreter:
> $ ghci ~/.xmonad/xmonad.hs
> GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
> Loading package base ... linking ... done.
> Ok, modules loaded: Main.
>
> Prelude Main> :t main
> main :: IO ()
Ok, looks good.
Note, however, that if you skip this step and try restarting xmonad
with errors in your xmonad.hs, it's not the end of the world; xmonad
will simply display a window showing the errors and continue with the
previous configuration settings. (This assumes that you have the
\'xmessage\' utility installed; you probably do.)
-}
{- $load
#Loading_your_configuration#
To get xmonad to use your new settings, type @mod-q@. (Remember, the
mod key is \'alt\' by default, but you can configure it to be
something else, such as your Windows key if you have one.) xmonad will
attempt to compile this file, and run it. If everything goes well,
xmonad will seamlessly restart itself with the new settings, keeping
all your windows, layouts, etc. intact. (If you change anything
related to your layouts, you may need to hit @mod-shift-space@ after
restarting to see the changes take effect.) If something goes wrong,
the previous (default) settings will be used. Note this requires that
GHC and xmonad are in your @$PATH@. If GHC isn't in your path, you can
still compile @xmonad.hs@ yourself:
> $ cd ~/.xmonad
> $ /path/to/ghc --make xmonad.hs
> $ ls
> xmonad xmonad.hi xmonad.hs xmonad.o
When you hit @mod-q@, this newly compiled xmonad will be used.
-}

303
XMonad/Doc/Developing.hs Normal file
View File

@@ -0,0 +1,303 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Doc.Developing
-- Copyright : (C) 2007 Andrea Rossato
-- License : BSD3
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : portable
--
-- This module gives a brief overview of the xmonad internals. It is
-- intended for advanced users who are curious about the xmonad source
-- code and want an brief overview. This document may also be helpful
-- for the beginner\/intermediate Haskell programmer who is motivated
-- to write an xmonad extension as a way to deepen her understanding
-- of this powerful functional language; however, there is not space
-- here to go into much detail. For a more comprehensive document
-- covering some of the same material in more depth, see the guided
-- tour of the xmonad source on the xmonad wiki:
-- <http://haskell.org/haskellwiki/Xmonad/Guided_tour_of_the_xmonad_source>.
--
-- If you write an extension module and think it may be useful for
-- others, consider releasing it. Coding guidelines and licensing
-- policies are covered at the end of this document, and must be
-- followed if you want your code to be included in the official
-- repositories. For a basic tutorial on the nuts and bolts of
-- developing a new extension for xmonad, see the tutorial on the
-- wiki:
-- <http://haskell.org/haskellwiki/Xmonad/xmonad_development_tutorial>.
--
-----------------------------------------------------------------------------
module XMonad.Doc.Developing
(
-- * Writing new extensions
-- $writing
-- * Libraries for writing window managers
-- $xmonad-libs
-- * xmonad internals
-- $internals
-- ** The @main@ entry point
-- $main
-- ** The X monad and the internal state
-- $internalState
-- ** Event handling and messages
-- $events
-- ** The 'LayoutClass'
-- $layoutClass
-- * Coding style
-- $style
-- * Licensing policy
-- $license
) where
--------------------------------------------------------------------------------
--
-- Writing Extensions
--
--------------------------------------------------------------------------------
{- $writing
-}
{- $xmonad-libs
Starting with version 0.5, xmonad and xmonad-contrib are packaged and
distributed as libraries, instead of components which must be compiled
by the user into a binary (as they were prior to version 0.5). This
way of distributing xmonad has many advantages, since it allows
packaging by GNU\/Linux distributions while still allowing the user to
customize the window manager to fit her needs.
Basically, xmonad and the xmonad-contrib libraries let users write
their own window manager in just a few lines of code. While
@~\/.xmonad\/xmonad.hs@ at first seems to be simply a configuration
file, it is actually a complete Haskell program which uses the xmonad
and xmonad-contrib libraries to create a custom window manager.
This makes it possible not only to edit the default xmonad
configuration, as we have seen in the "XMonad.Doc.Extending" document,
but to use the Haskell programming language to extend the window
manager you are writing in any way you see fit.
-}
{- $internals
-}
{- $main
#The_main_entry_point#
xmonad installs a binary, @xmonad@, which must be executed by the
Xsession starting script. This binary, whose code can be read in
@Main.hs@ of the xmonad source tree, will use 'XMonad.Core.recompile'
to run @ghc@ in order to build a binary from @~\/.xmonad\/xmonad.hs@.
If this compilation process fails, for any reason, a default @main@
entry point will be used, which calls the 'XMonad.Main.xmonad'
function with a default configuration.
Thus, the real @main@ entry point, the one that even the users' custom
window manager application in @~\/.xmonad\/xmonad.hs@ must call, is
the 'XMonad.Main.xmonad' function. This function takes a configuration
as its only argument, whose type ('XMonad.Core.XConfig')
is defined in "XMonad.Core".
'XMonad.Main.xmonad' takes care of opening the connection with the X
server, initializing the state (or deserializing it when restarted)
and the configuration, and calling the event handler
('XMonad.Main.handle') that goes into an infinite loop (using
'Prelude.forever') waiting for events and acting accordingly.
-}
{- $internalState
The event loop which calls 'XMonad.Main.handle' to react to events is
run within the 'XMonad.Core.X' monad, which is a
'Control.Monad.State.StateT' transformer over 'IO', encapsulated
within a 'Control.Monad.Reader.ReaderT' transformer. The
'Control.Monad.State.StateT' transformer encapsulates the
(read\/writable) state of the window manager (of type
'XMonad.Core.XState'), whereas the 'Control.Monad.Reader.ReaderT'
transformer encapsulates the (read-only) configuration (of type
'XMonad.Core.XConf').
Thanks to GHC's newtype deriving feature, the instance of the
'Control.Monad.State.MonadState' class parametrized over
'XMonad.Core.XState' and the instance of the
'Control.Monad.Reader.MonadReader' class parametrized over
'XMonad.Core.XConf' are automatically derived for the 'XMonad.Core.X'
monad. This way we can use 'Control.Monad.State.get',
'Control.Monad.State.gets' and 'Control.Monad.State.modify' for the
'XMonad.Core.XState', and 'Control.Monad.Reader.ask' and
'Control.Monad.Reader.asks' for reading the 'XMonad.Core.XConf'.
'XMonad.Core.XState' is where all the sensitive information about
window management is stored. The most important field of the
'XMonad.Core.XState' is the 'XMonad.Core.windowset', whose type
('XMonad.Core.WindowSet') is a synonym for a
'XMonad.StackSet.StackSet' parametrized over a
'XMonad.Core.WorkspaceID' (a 'String'), a layout type wrapped inside
the 'XMonad.Layout.Layout' existential data type, the
'Graphics.X11.Types.Window' type, the 'XMonad.Core.ScreenID' and the
'XMonad.Core.ScreenDetail's.
What a 'XMonad.StackSet.StackSet' is and how it can be manipulated
with pure functions is described in the Haddock documentation of the
"XMonad.StackSet" module.
The 'XMonad.StackSet.StackSet' ('XMonad.Core.WindowSet') has four
fields:
* 'XMonad.StackSet.current', for the current, focused workspace. This
is a 'XMonad.StackSet.Screen', which is composed of a
'XMonad.StackSet.Workspace' together with the screen information (for
Xinerama support).
* 'XMonad.StackSet.visible', a list of 'XMonad.StackSet.Screen's for
the other visible (with Xinerama) workspaces. For non-Xinerama
setups, this list is always empty.
* 'XMonad.StackSet.hidden', the list of non-visible
'XMonad.StackSet.Workspace's.
* 'XMonad.StackSet.floating', a map from floating
'Graphics.X11.Types.Window's to 'XMonad.StackSet.RationalRect's
specifying their geometry.
The 'XMonad.StackSet.Workspace' type is made of a
'XMonad.StackSet.tag', a 'XMonad.StackSet.layout' and
a (possibly empty) 'XMonad.StackSet.stack' of windows.
"XMonad.StackSet" (which should usually be imported qualified, to
avoid name clashes with Prelude functions such as 'Prelude.delete' and
'Prelude.filter') provides many pure functions to manipulate the
'XMonad.StackSet.StackSet'. These functions are most commonly used as
an argument to 'XMonad.Operations.windows', which takes a pure
function to manipulate the 'XMonad.Core.WindowSet' and does all the
needed operations to refresh the screen and save the modified
'XMonad.Core.XState'.
During each 'XMonad.Operations.windows' call, the
'XMonad.StackSet.layout' field of the 'XMonad.StackSet.current' and
'XMonad.StackSet.visible' 'XMonad.StackSet.Workspace's are used to
physically arrange the 'XMonad.StackSet.stack' of windows on each
workspace.
The possibility of manipulating the 'XMonad.StackSet.StackSet'
('XMonad.Core.WindowSet') with pure functions makes it possible to
test all the properties of those functions with QuickCheck, providing
greater reliability of the core code. Every change to the
"XMonad.StackSet" module must be accompanied by appropriate QuickCheck
properties before being applied.
-}
{- $events
Event handling is the core activity of xmonad. Events generated by
the X server are most important, but there may also be events
generated by layouts or the user.
"XMonad.Core" defines a class that generalizes the concept of events,
'XMonad.Core.Message', constrained to types with a
'Data.Typeable.Typeable' instance definition (which can be
automatically derived by GHC). 'XMonad.Core.Message's are wrapped
within an existential type 'XMonad.Core.SomeMessage'. The
'Data.Typeable.Typeable' constraint allows for the definition of a
'XMonad.Core.fromMessage' function that can unwrap the message with
'Data.Typeable.cast'. X Events are instances of this class, along
with any messages used by xmonad itself or by extension modules.
Using the 'Data.Typeable.Typeable' class for any kind of
'XMonad.Core.Message's and events allows us to define polymorphic functions
for processing messages or unhandled events.
This is precisely what happens with X events: xmonad passes them to
'XMonad.Main.handle'. If the main event handling function doesn't have
anything to do with the event, the event is sent to all visible
layouts by 'XMonad.Operations.broadcastMessage'.
This messaging system allows the user to create new message types,
simply declare an instance of the 'Data.Typeable.Typeable' and use
'XMonad.Operations.sendMessage' to send commands to layouts.
And, finally, layouts may handle X events and other messages within the
same function... miracles of polymorphism.
-}
{- $layoutClass
#The_LayoutClass#
to do
-}
{- $style
These are the coding guidelines for contributing to xmonad and the
xmonad contributed extensions.
* Comment every top level function (particularly exported funtions), and
provide a type signature.
* Use Haddock syntax in the comments (see below).
* Follow the coding style of the other modules.
* Code should be compilable with "ghc-options: -Wall -Werror" set in the
xmonad-contrib.cabal file. There should be no warnings.
* Partial functions should be avoided: the window manager should not
crash, so never call 'error' or 'undefined'.
* Tabs are /illegal/. Use 4 spaces for indenting.
* Any pure function added to the core must have QuickCheck properties
precisely defining its behaviour. Tests for everything else are encouraged.
For examples of Haddock documentation syntax, have a look at other
extensions. Important points are:
* Every exported function (or even better, every function) should have
a Haddock comment explaining what it does, and providing examples.
* Literal chunks of code can be written in comments using
\"birdtrack\" notation (a greater-than symbol at the beginning of
each line). Be sure to leave a blank line before and after each
birdtrack-quoted section.
* Link to functions by surrounding the names in single quotes, modules
in double quotes.
* Literal quote marks and slashes should be escaped with a backslash.
To generate and view the Haddock documentation for your extension, run
> runhaskell Setup haddock
and then point your browser to @\/path\/to\/XMonadContrib\/dist\/doc\/html\/xmonad-contrib\/index.html@.
For more information, see the Haddock documentation:
<http://www.haskell.org/haddock/doc/html/index.html>.
For more information on the nuts and bolts of how to develop your own
extension, see the tutorial on the wiki:
<http://haskell.org/haskellwiki/Xmonad/xmonad_development_tutorial>.
-}
{- $license
New modules should identify the author, and be submitted under the
same license as xmonad (BSD3 license or freer).
-}

984
XMonad/Doc/Extending.hs Normal file
View File

@@ -0,0 +1,984 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Doc.Extending
-- Copyright : (C) 2007 Andrea Rossato
-- License : BSD3
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : portable
--
-- This module documents the xmonad-contrib library and
-- how to use it to extend the capabilities of xmonad.
--
-- Reading this document should not require a deep knowledge of
-- Haskell; the examples are intended to be useful and understandable
-- for those users who do not know Haskell and don't want to have to
-- learn it just to configure xmonad. You should be able to get by
-- just fine by ignoring anything you don't understand and using the
-- provided examples as templates. However, relevant Haskell features
-- are discussed when appropriate, so this document will hopefully be
-- useful for more advanced Haskell users as well.
--
-- Those wishing to be totally hardcore and develop their own xmonad
-- extensions (it's easier than it sounds, we promise!) should read
-- the documentation in "XMonad.Doc.Developing".
--
-- More configuration examples may be found on the Haskell wiki:
--
-- <http://haskell.org/haskellwiki/Xmonad/Config_archive>
--
-----------------------------------------------------------------------------
module XMonad.Doc.Extending
(
-- * The xmonad-contrib library
-- $library
-- ** Actions
-- $actions
-- ** Configurations
-- $configs
-- ** Hooks
-- $hooks
-- ** Layouts
-- $layouts
-- ** Prompts
-- $prompts
-- ** Utilities
-- $utils
-- * Extending xmonad
-- $extending
-- ** Editing key bindings
-- $keys
-- *** Adding key bindings
-- $keyAdding
-- *** Removing key bindings
-- $keyDel
-- *** Adding and removing key bindings
-- $keyAddDel
-- ** Editing mouse bindings
-- $mouse
-- ** Editing the layout hook
-- $layoutHook
-- ** Editing the manage hook
-- $manageHook
-- ** The log hook and external status bars
-- $logHook
) where
--------------------------------------------------------------------------------
--
-- The XmonadContrib Library
--
--------------------------------------------------------------------------------
{- $library
The xmonad-contrib (xmc) library is a set of extension modules
contributed by xmonad hackers and users, which provide additional
xmonad features. Examples include various layout modes (tabbed,
spiral, three-column...), prompts, program launchers, the ability to
manipulate windows and workspaces in various ways, alternate
navigation modes, and much more. There are also \"meta-modules\"
which make it easier to write new modules and extensions.
This is a concise yet complete overview of the xmonad-contrib modules.
For more information about any particular module, just click on its
name to view its Haddock documentation; each module should come with
extensive documentation. If you find a module that could be better
documented, or has incorrect documentation, please report it as a bug
(<http://code.google.com/p/xmonad/issues/list>)!
-}
{- $actions
In the @XMonad.Actions@ namespace you can find modules exporting
various functions that are usually intended to be bound to key
combinations or mouse actions, in order to provide functionality
beyond the standard keybindings provided by xmonad.
See "XMonad.Doc.Extending#Editing_key_bindings" for instructions on how to
edit your key bindings.
* "XMonad.Actions.Commands": running internal xmonad actions
interactively.
* "XMonad.Actions.ConstrainedResize": an aspect-ratio-constrained
window resizing mode.
* "XMonad.Actions.CopyWindow": duplicating windows on multiple
workspaces.
* "XMonad.Actions.CycleSelectedLayouts": bind a key to cycle through a
particular subset of your layouts.
* "XMonad.Actions.CycleWS": move between workspaces in various ways.
* "XMonad.Actions.DeManage": cease management of a window without
unmapping it.
* "XMonad.Actions.DwmPromote": dwm-like master window swapping.
* "XMonad.Actions.DynamicWorkspaces": add, delete, and rename workspaces.
* "XMonad.Actions.FindEmptyWorkspace": find an empty workspace.
* "XMonad.Actions.FlexibleManipulate": move\/resize windows without
warping the mouse.
* "XMonad.Actions.FlexibleResize": resize windows from any corner.
* "XMonad.Actions.FloatKeys": move\/resize floating windows with
keybindings.
* "XMonad.Actions.FocusNth": focus the nth window on the screen.
* "XMonad.Actions.MouseGestures": bind mouse gestures to actions.
* "XMonad.Actions.MouseResize": use with
"XMonad.Layout.WindowArranger" to resize windows with the mouse when
using a floating layout.
* "XMonad.Actions.NoBorders": forcibly remove borders from a window.
Not to be confused with "XMonad.Layout.NoBorders".
* "XMonad.Actions.PerWorkspaceKeys": configure keybindings
per-workspace.
* "XMonad.Actions.Promote": An action to move the focused window to
the master pane, or swap the master with the next window.
* "XMonad.Actions.RotSlaves": rotate non-master windows.
* "XMonad.Actions.Search": provide helpful functions for easily
running web searchs.
* "XMonad.Actions.SimpleDate": display the date in a popup menu.
* "XMonad.Actions.SinkAll": sink all floating windows.
* "XMonad.Actions.Submap": create key submaps, i.e. the ability to
bind actions to key sequences rather than being limited to single
key combinations.
* "XMonad.Actions.SwapWorkspaces": swap workspace tags.
* "XMonad.Actions.TagWindows": tag windows and select by tag.
* "XMonad.Actions.UpdatePointer": mouse-follows-focus.
* "XMonad.Actions.Warp": warp the pointer.
* "XMonad.Actions.WindowBringer": bring windows to you, and you to
windows.
* "XMonad.Actions.WindowGo": travel to windows based on various
criteria; conditionally start a program if a window does not exist,
or travel to that window if it does.
-}
{- $configs
In the @XMonad.Config@ namespace you can find modules exporting the
configurations used by some of the xmonad and xmonad-contrib
developers. You can look at them for examples while creating your own
configuration; you can also simply import them and use them as your
own configuration, possibly with some modifications.
* "XMonad.Config.Arossato"
* "XMonad.Config.Dons"
* "XMonad.Config.Droundy"
* "XMonad.Config.Sjanssen"
-}
{- $hooks
In the @XMonad.Hooks@ namespace you can find modules exporting
hooks. Hooks are actions that xmonad performs when certain events
occur. The two most important hooks are:
* 'XMonad.Core.manageHook': this hook is called when a new window
xmonad must take care of is created. This is a very powerful hook,
since it lets us examine the new window's properties and act
accordingly. For instance, we can configure xmonad to put windows
belonging to a given application in the float layer, not to manage
dock applications, or open them in a given workspace. See
"XMonad.Doc.Extending#Editing_the_manage_hook" for more information on
customizing 'XMonad.Core.manageHook'.
* 'XMonad.Core.logHook': this hook is called when the stack of windows
managed by xmonad has been changed, by calling the
'XMonad.Operations.windows' function. For instance
"XMonad.Hooks.DynamicLog" will produce a string (whose format can be
configured) to be printed to the standard output. This can be used
to display some information about the xmonad state in a status bar.
See "XMonad.Doc.Extending#The_log_hook_and_external_status_bars" for more
information.
Here is a list of the modules found in @XMonad.Hooks@:
* "XMonad.Hooks.DynamicLog": for use with 'XMonad.Core.logHook'; send
information about xmonad's state to standard output, suitable for
putting in a status bar of some sort. See
"XMonad.Doc.Extending#The_log_hook_and_external_status_bars".
* "XMonad.Hooks.EventHook": a hook to handle X events at the layout level.
* "XMonad.Hooks.EwmhDesktops": support for pagers in panel applications.
* "XMonad.Hooks.ManageDocks": handle DOCK and STRUT windows (such as
status bars) appropriately, by de-managing them and creating
appropriate gaps so as not to place other windows covering them.
* "XMonad.Hooks.ManageHelpers": provide helper functions to be used
in @manageHook@.
* "XMonad.Hooks.ServerMode": example use of "XMonad.Hooks.EventHook".
* "XMonad.Hooks.SetWMName": set the WM name. Useful when e.g. running
Java GUI programs.
* "XMonad.Hooks.UrgencyHook": configure an action to occur when a window
sets the urgent flag.
* "XMonad.Hooks.XPropManage": match on XProperties in your
'XMonad.Core.manageHook'.
-}
{- $layouts
In the @XMonad.Layout@ namespace you can find modules exporting
contributed tiling algorithms, such as a tabbed layout, a circle, a spiral,
three columns, and so on.
You will also find modules which provide facilities for combining
different layouts, such as "XMonad.Layout.Combo", or
"XMonad.Layout.LayoutCombinators".
Layouts can be also modified with layout modifiers. A general
interface for writing layout modifiers is implemented in
"XMonad.Layout.LayoutModifier".
For more information on using those modules for customizing your
'XMonad.Core.layoutHook' see "XMonad.Doc.Extending#Editing_the_layout_hook".
* "XMonad.Layout.Accordion": put non-focused windows in ribbons at the
top and bottom of the screen.
* "XMonad.Layout.Circle": an elliptical, overlapping layout.
* "XMonad.Layout.Combo": combine multiple layouts into one.
* "XMonad.Layout.Decoration": decorated layouts.
* "XMonad.Layout.DecorationMadness": some examples of decorated layouts.
* "XMonad.Layout.Dishes": stack extra windows underneath the master windows.
* "XMonad.Layout.DragPane": split the screen into two windows with a
draggable divider.
* "XMonad.Layout.DwmStyle": windows decorated in a dwm-like style.
* "XMonad.Layout.Grid": put windows in a square grid.
* "XMonad.Layout.HintedTile": gapless tiled layout that attempts to
obey window size hints.
* "XMonad.Layout.IM": a layout for multi-window instant message clients.
* "XMonad.Layout.LayoutCombinators": general layout combining.
* "XMonad.Layout.LayoutHints": make layouts respect window size hints.
* "XMonad.Layout.LayoutModifier": a general framework for creating
layout \"modifiers\"; useful for creating new layout modules.
* "XMonad.Layout.LayoutScreens": divide the screen into multiple
virtual \"screens\".
* "XMonad.Layout.MagicFocus": automagically put the focused window in
the master area.
* "XMonad.Layout.Magnifier": increase the size of the focused window
* "XMonad.Layout.Maximize": temporarily maximize the focused window.
* "XMonad.Layout.MosaicAlt": give each window a specified relative
amount of screen space.
* "XMonad.Layout.MultiToggle": dynamically apply and unapply layout
transformers.
* "XMonad.Layout.Named": change the names of layouts (as reported by
e.g. "XMonad.Hooks.DynamicLog").
* "XMonad.Layout.NoBorders": display windows without borders.
* "XMonad.Layout.PerWorkspace": configure layouts on a per-workspace basis.
* "XMonad.Layout.Reflect": reflect any layout vertically or horizontally.
* "XMonad.Layout.ResizableTile": tiled layout allowing you to change
width and height of windows.
* "XMonad.Layout.ResizeScreen": a layout modifier to change the screen
geometry on one side.
* "XMonad.Layout.Roledex": a \"completely pointless layout which acts
like Microsoft's Flip 3D\".
* "XMonad.Layout.ScratchWorkspace": implements a scratch workspace
which can be shown and hidden with keybindings.
* "XMonad.Layout.ShowWName": Show the name of the current workspace when switching.
* "XMonad.Layout.SimpleDecoration": add simple decorations to windows.
* "XMonad.Layout.SimpleFloat": a basic floating layout.
* "XMonad.Layout.Simplest": a basic, simple layout that just lays out
all windows with a fullscreen geometry. Used by
"XMonad.Layout.Tabbed".
* "XMonad.Layout.Spiral": Fibonacci spiral layout.
* "XMonad.Layout.Square": split the screen into a square area plus the rest.
* "XMonad.Layout.TabBarDecoration": add a bar of tabs to any layout.
* "XMonad.Layout.Tabbed": a tabbed layout.
* "XMonad.Layout.ThreeColumns": a layout with three columns instead of two.
* "XMonad.Layout.ToggleLayouts": toggle between two layouts.
* "XMonad.Layout.TwoPane": split the screen horizontally and show two
windows.
* "XMonad.Layout.WindowArranger": make any layout into a
pseudo-floating layout by allowing you to move and resize windows.
* "XMonad.Layout.WindowNavigation": navigate around a workspace
directionally instead of using mod-j\/k.
* "XMonad.Layout.WorkspaceDir": set the current working directory in a
workspace.
-}
{- $prompts
In the @XMonad.Prompt@ name space you can find modules providing
graphical prompts for getting user input and using it to perform
various actions.
The "XMonad.Prompt" provides a library for easily writing new prompt
modules.
These are the available prompts:
* "XMonad.Prompt.AppendFile": append lines of text to a file.
* "XMonad.Prompt.Directory": prompt for a directory.
* "XMonad.Prompt.DirExec": put a bunch of scripts you want in a
directory, then choose from among them with this prompt.
* "XMonad.Prompt.Email": an example of "XMonad.Prompt.Input", send
simple short e-mails from a prompt.
* "XMonad.Prompt.Input": useful for building general actions requiring
input from a prompt.
* "XMonad.Prompt.Layout": choose a layout from a prompt.
* "XMonad.Prompt.Man": open man pages.
* "XMonad.Prompt.RunOrRaise": choose a program, and run it if not
already running, or raise its window if it is.
* "XMonad.Prompt.Shell": run a shell command.
* "XMonad.Prompt.Ssh": open an ssh connection.
* "XMonad.Prompt.Theme": choose a decoration theme.
* "XMonad.Prompt.Window": choose an open window.
* "XMonad.Prompt.Workspace": choose a workspace.
* "XMonad.Prompt.XMonad": perform various xmonad actions by choosing
one from a prompt.
Usually a prompt is called by some key binding. See
"XMonad.Doc.Extending#Editing_key_bindings", which includes examples
of adding some prompts.
-}
{- $utils
In the @XMonad.Util@ namespace you can find modules exporting various
utility functions that are used by the other modules of the
xmonad-contrib library.
There are also utilities for helping in configuring xmonad or using
external utilities.
A non complete list with a brief description:
* "XMonad.Util.CustomKeys": configure key bindings (see
"XMonad.Doc.Extending#Editing_key_bindings").
* "XMonad.Util.Dmenu": a dmenu binding.
* "XMonad.Util.Dzen" "XMonad.Util.Dmenu" provide useful functions for
running dzen as a xmonad status bar and dmenu as a program launcher;
* "XMonad.Util.EZConfig": configure key bindings easily, including a
parser for writing key bindings in "M-C-x" style.
* "XMonad.Util.Font": A module for abstracting a font facility over
Core fonts and Xft
* "XMonad.Util.Invisible": a wrapper data type to store layout state
which should not be persisted across restarts.
* "XMonad.Util.Loggers": a collection of loggers that can be used in
conjunction with "XMonad.Hooks.DynamicLog".
* "XMonad.Util.NamedWindows": associate windows with their X titles.
Used by, e.g. "XMonad.Layout.Tabbed".
* "XMonad.Util.Run": a collection of functions for running external
processes.
* "XMonad.Util.Scratchpad": hotkey-launched floating terminal window.
* "XMonad.Util.Themes": a collection of themes to be used with
floating layouts.
* "XMonad.Util.Timer": set up a timer to handle deferred events.
* "XMonad.Util.WindowProperties": an EDSL for specifying and matching
on window properties.
* "XMonad.Util.WorkspaceCompare": general combinators for sorting
workspaces in various ways, used by several other modules which need
to sort workspaces (e.g. "XMonad.Hooks.DynamicLog").
* "XMonad.Util.Paste" provides utilities for pasting or sending keys and
strings to windows;
* "XMonad.Util.XSelection" provide utilities for using the mouse
selection;
* "XMonad.Util.XUtils" and "XMonad.Util.Font" are libraries for
accessing Xlib and XFT function in a convenient way.
-}
--------------------------------------------------------------------------------
--
-- Extending Xmonad
--
--------------------------------------------------------------------------------
{- $extending
#Extending_xmonad#
Since the @xmonad.hs@ file is just another Haskell module, you may
import and use any Haskell code or libraries you wish, such as
extensions from the xmonad-contrib library, or other code you write
yourself.
-}
{- $keys
#Editing_key_bindings#
Editing key bindings means changing the 'XMonad.Core.XConfig.keys'
field of the 'XMonad.Core.XConfig' record used by xmonad. For
example, you could write:
> import XMonad
>
> main = xmonad $ defaultConfig { keys = myKeys }
and provide an appropriate definition of @myKeys@, such as:
> myKeys x =
> [ ((modMask x, xK_F12), xmonadPrompt defaultXPConfig)
> , ((modMask x, xK_F3 ), shellPrompt defaultXPConfig)
> ]
This particular definition also requires importing "XMonad.Prompt",
"XMonad.Prompt.Shell", and "XMonad.Prompt.XMonad":
> import XMonadPrompt
> import ... -- and so on
For a list of the names of particular keys (such as xK_F12, and so
on), see
<http://hackage.haskell.org/packages/archive/X11/1.4.1/doc/html/Graphics-X11-Types.html>.
Usually, rather than completely redefining the key bindings, as we did
above, we want to simply add some new bindings and\/or remove existing
ones.
-}
{- $keyAdding
#Adding_key_bindings#
Adding key bindings can be done in different ways. The type signature
of 'XMonad.Core.XConfig.keys' is:
> keys :: XConfig Layout -> M.Map (ButtonMask,KeySym) (X ())
In order to add new key bindings, you need to first create an
appropriate 'Data.Map.Map' from a list of key bindings using
'Data.Map.fromList'. This 'Data.Map.Map' of new key bindings then
needs to be joined to a 'Data.Map.Map' of existing bindings using
'Data.Map.union'.
Since we are going to need some of the functions of the "Data.Map"
module, before starting we must first import this modules:
> import qualified Data.Map as M
For instance, if you have defined some additional key bindings like
these:
> myKeys x =
> [ ((modMask x, xK_F12), xmonadPrompt defaultXPConfig)
> , ((modMask x, xK_F3 ), shellPrompt defaultXPConfig)
> ]
then you can create a new key bindings map by joining the default one
with yours:
> newKeys x = M.union (keys defaultConfig x) (M.fromList (myKeys x))
Finally, you can use @newKeys@ in the 'XMonad.Core.XConfig.keys' field
of the configuration:
> main = xmonad $ defaultConfig { keys = newKeys }
All together, your @~\/.xmonad\/xmonad.hs@ would now look like this:
> module Main (main) where
>
> import XMonad
>
> import qualified Data.Map as M
> import Graphics.X11.Xlib
> import XMonad.Prompt
> import XMonad.Prompt.Shell
> import XMonad.Prompt.XMonad
>
> main :: IO ()
> main = xmonad $ defaultConfig { keys = newKeys }
>
> newKeys x = M.union (keys defaultConfig x) (M.fromList (myKeys x))
>
> myKeys x =
> [ ((modMask x, xK_F12), xmonadPrompt defaultXPConfig)
> , ((modMask x, xK_F3 ), shellPrompt defaultXPConfig)
> ]
There are much simpler ways to accomplish this, however, if you are
willing to use an extension module to help you configure your keys.
For instance, "XMonad.Util.EZConfig" and "XMonad.Util.CustomKeys" both
provide useful functions for editing your key bindings; "XMonad.Util.EZConfig" even lets you use emacs-style keybinding descriptions like \"M-C-<F12>\".
-}
{- $keyDel
#Removing_key_bindings#
Removing key bindings requires modifying the 'Data.Map.Map' which
stores the key bindings. This can be done with 'Data.Map.difference'
or with 'Data.Map.delete'.
For example, suppose you want to get rid of @mod-q@ and @mod-shift-q@
(you just want to leave xmonad running forever). To do this you need
to define @newKeys@ as a 'Data.Map.difference' between the default
map and the map of the key bindings you want to remove. Like so:
> newKeys x = M.difference (keys defaultConfig x) (M.fromList $ keysToRemove x)
>
> keysToRemove :: XConfig Layout -> [((KeyMask, KeySym),X ())]
> keysToRemove x =
> [ ((modMask x , xK_q ), return ())
> , ((modMask x .|. shiftMask, xK_q ), return ())
> ]
As you can see, it doesn't matter what actions we associate with the
keys listed in @keysToRemove@, so we just use @return ()@ (the
\"null\" action).
It is also possible to simply define a list of keys we want to unbind
and then use 'Data.Map.delete' to remove them. In that case we would
write something like:
> newKeys x = foldr M.delete (keys defaultConfig x) (keysToRemove x)
>
> keysToRemove :: XConfig Layout -> [(KeyMask, KeySym)]
> keysToRemove x =
> [ (modMask x , xK_q )
> , (modMask x .|. shiftMask, xK_q )
> ]
Another even simpler possibility is the use of some of the utilities
provided by the xmonad-contrib library. Look, for instance, at
'XMonad.Util.EZConfig.removeKeys'.
-}
{- $keyAddDel
#Adding_and_removing_key_bindings#
Adding and removing key bindings requires simply combining the steps
for removing and adding. Here is an example from
"XMonad.Config.Arossato":
> defKeys = keys defaultConfig
> delKeys x = foldr M.delete (defKeys x) (toRemove x)
> newKeys x = foldr (uncurry M.insert) (delKeys x) (toAdd x)
> -- remove some of the default key bindings
> toRemove x =
> [ (modMask x , xK_j )
> , (modMask x , xK_k )
> , (modMask x , xK_p )
> , (modMask x .|. shiftMask, xK_p )
> , (modMask x .|. shiftMask, xK_q )
> , (modMask x , xK_q )
> ] ++
> -- I want modMask .|. shiftMask 1-9 to be free!
> [(shiftMask .|. modMask x, k) | k <- [xK_1 .. xK_9]]
> -- These are my personal key bindings
> toAdd x =
> [ ((modMask x , xK_F12 ), xmonadPrompt defaultXPConfig )
> , ((modMask x , xK_F3 ), shellPrompt defaultXPConfig )
> ] ++
> -- Use modMask .|. shiftMask .|. controlMask 1-9 instead
> [( (m .|. modMask x, k), windows $ f i)
> | (i, k) <- zip (workspaces x) [xK_1 .. xK_9]
> , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask .|. controlMask)]
> ]
You can achieve the same result using the "XMonad.Util.CustomKeys"
module; take a look at the 'XMonad.Util.CustomKeys.customKeys'
function in particular.
-}
{- $mouse
#Editing_mouse_bindings#
Most of the previous discussion of key bindings applies to mouse
bindings as well. For example, you could configure button4 to close
the window you click on like so:
> import qualified Data.Map as M
>
> myMouse x = [ (0, button4), (\w -> focus w >> kill) ]
>
> newMouse x = M.union (mouseBindings defaultConfig x) (M.fromList (myMouse x))
>
> main = xmonad $ defaultConfig { ..., mouseBindings = newMouse, ... }
Overriding or deleting mouse bindings works similarly. You can also
configure mouse bindings much more easily using the
'XMonad.Util.EZConfig.additionalMouseBindings' and
'XMonad.Util.EZConfig.removeMouseBindings' functions from the
"XMonad.Util.EZConfig" module.
-}
{- $layoutHook
#Editing_the_layout_hook#
When you start an application that opens a new window, when you change
the focused window, or move it to another workspace, or change that
workspace's layout, xmonad will use the 'XMonad.Core.layoutHook' for
reordering the visible windows on the visible workspace(s).
Since different layouts may be attached to different workspaces, and
you can change them, xmonad needs to know which one to use. In this
sense the layoutHook may be thought as the list of layouts that
xmonad will use for laying out windows on the screen(s).
The problem is that the layout subsystem is implemented with an
advanced feature of the Haskell programming language: type classes.
This allows us to very easily write new layouts, combine or modify
existing layouts, create layouts with internal state, etc. See
"XMonad.Doc.Extending#The_LayoutClass" for more information. This
means that we cannot simply have a list of layouts as we used to have
before the 0.5 release: a list requires every member to belong to the
same type!
Instead the combination of layouts to be used by xmonad is created
with a specific layout combinator: 'XMonad.Layout.|||'.
Suppose we want a list with the 'XMonad.Layout.Full',
'XMonad.Layout.Tabbed.tabbed' and
'XMonad.Layout.Accordion.Accordion' layouts. First we import, in our
@~\/.xmonad\/xmonad.hs@, all the needed modules:
> import XMonad
>
> import XMonad.Layout.Tabbed
> import XMonad.Layout.Accordion
Then we create the combination of layouts we need:
> mylayoutHook = Full ||| tabbed shrinkText defaultTConf ||| Accordion
Now, all we need to do is change the 'XMonad.Core.layoutHook'
field of the 'XMonad.Core.XConfig' record, like so:
> main = xmonad $ defaultConfig { layoutHook = mylayoutHook }
Thanks to the new combinator, we can apply a layout modifier to a
whole combination of layouts, instead of applying it to each one. For
example, suppose we want to use the
'XMonad.Layout.NoBorders.noBorders' layout modifier, from the
"XMonad.Layout.NoBorders" module (which must be imported):
> mylayoutHook = noBorders (Full ||| tabbed shrinkText defaultTConf ||| Accordion)
If we want only the tabbed layout without borders, then we may write:
> mylayoutHook = Full ||| noBorders (tabbed shrinkText defaultTConf) ||| Accordion
Our @~\/.xmonad\/xmonad.hs@ will now look like this:
> import XMonad
>
> import XMonad.Layout.Tabbed
> import XMonad.Layout.Accordion
> import XMonad.Layout.NoBorders
>
> mylayoutHook = Full ||| noBorders (tabbed shrinkText defaultTConf) ||| Accordion
>
> main = xmonad $ defaultConfig { layoutHook = mylayoutHook }
That's it!
-}
{- $manageHook
#Editing_the_manage_hook#
The 'XMonad.Core.manageHook' is a very powerful tool for customizing
the behavior of xmonad with regard to new windows. Whenever a new
window is created, xmonad calls the 'XMonad.Core.manageHook', which
can thus be used to perform certain actions on the new window, such as
placing it in a specific workspace, ignoring it, or placing it in the
float layer.
The default 'XMonad.Core.manageHook' causes xmonad to float MPlayer
and Gimp, and to ignore gnome-panel, desktop_window, kicker, and
kdesktop.
The "XMonad.ManageHook" module provides some simple combinators that
can be used to alter the 'XMonad.Core.manageHook' by replacing or adding
to the default actions.
Let's start by analyzing the default 'XMonad.Config.manageHook', defined
in "XMonad.Config":
> manageHook :: ManageHook
> manageHook = composeAll
> [ className =? "MPlayer" --> doFloat
> , className =? "Gimp" --> doFloat
> , resource =? "desktop_window" --> doIgnore
> , resource =? "kdesktop" --> doIgnore ]
'XMonad.ManageHook.composeAll' can be used to compose a list of
different 'XMonad.Config.ManageHook's. In this example we have a list
of 'XMonad.Config.ManageHook's formed by the following commands: the
Mplayer's and the Gimp's windows, whose 'XMonad.ManageHook.className'
are, respectively \"Mplayer\" and \"Gimp\", are to be placed in the
float layer with the 'XMonad.ManageHook.doFloat' function; the windows
whose resource names are respectively \"desktop_window\" and
\kdesktop\" are to be ignored with the 'XMonad.ManageHook.doIgnore'
function.
This is another example of 'XMonad.Config.manageHook', taken from
"XMonad.Config.Arossato":
> myManageHook = composeAll [ resource =? "realplay.bin" --> doFloat
> , resource =? "win" --> doF (W.shift "doc") -- xpdf
> , resource =? "firefox-bin" --> doF (W.shift "web")
> ]
> newManageHook = myManageHook <+> manageHook defaultConfig
Again we use 'XMonad.ManageHook.composeAll' to compose a list of
different 'XMonad.Config.ManageHook's. The first one will put
RealPlayer on the float layer, the second one will put the xpdf
windows in the workspace named \"doc\", with 'XMonad.ManageHook.doF'
and 'XMonad.StackSet.shift' functions, and the third one will put all
firefox windows on the workspace called "web". Then we use the
'XMonad.ManageHook.<+>' combinator to compose @myManageHook@ with the
default 'XMonad.Config.manageHook' to form @newManageHook@.
Each 'XMonad.Config.ManageHook' has the form:
> property =? match --> action
Where @property@ can be:
* 'XMonad.ManageHook.title': the window's title
* 'XMonad.ManageHook.resource': the resource name
* 'XMonad.ManageHook.className': the resource class name.
* 'XMonad.ManageHook.stringProperty' @somestring@: the contents of the
property @somestring@.
(You can retrieve the needed information using the X utility named
@xprop@; for example, to find the resource class name, you can type
> xprop | grep WM_CLASS
at a prompt, then click on the window whose resource class you want to
know.)
@match@ is the string that will match the property value (for instance
the one you retrieved with @xprop@).
An @action@ can be:
* 'XMonad.ManageHook.doFloat': to place the window in the float layer;
* 'XMonad.ManageHook.doIgnore': to ignore the window;
* 'XMonad.ManageHook.doF': to execute a function with the window as
argument.
For example, suppose we want to add a 'XMonad.Config.manageHook' to
float RealPlayer, which usually has a 'XMonad.ManageHook.resource'
name of \"realplay.bin\".
First we need to import "XMonad.ManageHook":
> import XMonad.ManageHook
Then we create our own 'XMonad.Config.manageHook':
> myManageHook = resource =? "realplay.bin" --> doFloat
We can now use the 'XMonad.ManageHook.<+>' combinator to add our
'XMonad.Config.manageHook' to the default one:
> newManageHook = myManageHook <+> manageHook defaultConfig
(Of course, if we wanted to completely replace the default
'XMonad.Config.manageHook', this step would not be necessary.) Now,
all we need to do is change the 'XMonad.Core.manageHook' field of the
'XMonad.Core.XConfig' record, like so:
> main = xmonad defaultConfig { ..., manageHook = newManageHook, ... }
And we are done.
Obviously, we may wish to add more then one
'XMonad.Config.manageHook'. In this case we can use a list of hooks,
compose them all with 'XMonad.ManageHook.composeAll', and add the
composed to the default one.
For instance, if we want RealPlayer to float and thunderbird always
opened in the workspace named "mail", we can do so like this:
> myManageHook = composeAll [ resource =? "realplay.bin" --> doFloat
> , resource =? "thunderbird-bin" --> doF (W.shift "mail")
> ]
Remember to import the module that defines the 'XMonad.StackSet.shift'
function, "XMonad.StackSet", like this:
> import qualified XMonad.StackSet as W
And then we can add @myManageHook@ to the default one to create
@newManageHook@ as we did in the previous example.
One more thing to note about this system is that if
a window matches multiple rules in a 'XMonad.Config.manageHook', /all/
of the corresponding actions will be run (in the order in which they
are defined). This is a change from versions before 0.5, when only
the first rule that matched was run.
Finally, for additional rules and actions you can use in your
manageHook, check out the contrib module "XMonad.Hooks.ManageHelpers".
-}
{- $logHook
#The_log_hook_and_external_status_bars#
When the stack of the windows managed by xmonad changes for any
reason, xmonad will call 'XMonad.Core.logHook', which can be used to
output some information about the internal state of xmonad, such as the
layout that is presently in use, the workspace we are in, the focused
window's title, and so on.
Extracting information about the internal xmonad state can be somewhat
difficult if you are not familiar with the source code. Therefore,
it's usually easiest to use a module that has been designed
specifically for logging some of the most interesting information
about the internal state of xmonad: "XMonad.Hooks.DynamicLog". This
module can be used with an external status bar to print the produced
logs in a convenient way; the most commonly used status bars are dzen
and xmobar.
By default the 'XMonad.Core.logHook' doesn't produce anything. To
enable it you need first to import "XMonad.Hooks.DynamicLog":
> import XMonad.Hooks.DynamicLog
Then you just need to update the 'XMonad.Core.logHook' field of the
'XMonad.Core.XConfig' record with one of the provided functions. For
example:
> main = xmonad defaultConfig { logHook = dynamicLog }
More interesting configurations are also possible; see the
"XMonad.Hooks.DynamicLog" module for more possibilities.
You may now enjoy your extended xmonad experience.
Have fun!
-}

View File

@@ -0,0 +1,122 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.DynamicHooks
-- Copyright : (c) Braden Shepherdson 2008
-- License : BSD-style (as xmonad)
--
-- Maintainer : Braden.Shepherdson@gmail.com
-- Stability : unstable
-- Portability : unportable
--
-- One-shot and permanent ManageHooks that can be updated at runtime.
--
-----------------------------------------------------------------------------
module XMonad.Hooks.DynamicHooks (
-- * Usage
-- $usage
initDynamicHooks
,dynamicMasterHook
,addDynamicHook
,updateDynamicHook
,oneShotHook
) where
import XMonad
import System.IO
import Data.List
import Data.Maybe (listToMaybe)
import Data.Monoid
import Data.IORef
-- $usage
-- Provides two new kinds of 'ManageHooks' that can be defined at runtime.
--
-- * One-shot 'ManageHooks' that are deleted after they execute.
--
-- * Permanent 'ManageHooks' (unless you want to destroy them)
--
-- Note that you will lose all dynamically defined 'ManageHook's when you @mod+q@!
-- If you want them to last, you should create them as normal in your @xmonad.hs@.
--
-- First, you must execute 'initDynamicHooks' from 'main' in your @xmonad.hs@:
--
-- > dynHooksRef <- initDynamicHooks
--
-- and then pass this value to the other functions in this module.
--
-- You also need to add the base 'ManageHook':
--
-- > xmonad { manageHook = myManageHook <+> dynamicMasterHook dynHooksRef }
--
-- You must include this @dynHooksRef@ value when using the functions in this
-- module:
--
-- > xmonad { keys = myKeys `Data.Map.union` Data.Map.fromList
-- > [((modMask conf, xK_i), oneShotHook dynHooksRef
-- > "FFlaunchHook" (className =? "firefox") (doShift "3")
-- > >> spawn "firefox")
-- > ,((modMask conf, xK_u), addDynamicHook dynHooksRef
-- > (className =? "example" --> doFloat))
-- > ,((modMask conf, xK_y), updatePermanentHook dynHooksRef
-- > (const idHook))) ] -- resets the permanent hook.
--
data DynamicHooks = DynamicHooks
{ transients :: [(Query Bool, ManageHook)]
, permanent :: ManageHook }
-- | Creates the 'IORef' that stores the dynamically created 'ManageHook's.
initDynamicHooks :: IO (IORef DynamicHooks)
initDynamicHooks = newIORef (DynamicHooks { transients = [],
permanent = idHook })
-- this hook is always executed, and the IORef's contents checked.
-- note that transient hooks are run second, therefore taking precedence
-- over permanent ones on matters such as which workspace to shift to.
-- doFloat and doIgnore are idempotent.
-- | Master 'ManageHook' that must be in your @xmonad.hs@ 'ManageHook'.
dynamicMasterHook :: IORef DynamicHooks -> ManageHook
dynamicMasterHook ref = return True -->
(ask >>= \w -> liftX (do
dh <- io $ readIORef ref
(Endo f) <- runQuery (permanent dh) w
ts <- mapM (\(q,a) -> runQuery q w >>= \x -> return (x,(q, a))) (transients dh)
let (ts',nts) = partition fst ts
gs <- mapM (flip runQuery w . snd . snd) ts'
let (Endo g) = maybe (Endo id) id $ listToMaybe gs
io $ writeIORef ref $ dh { transients = map snd nts }
return $ Endo $ f . g
))
-- | Appends the given 'ManageHook' to the permanent dynamic 'ManageHook'.
addDynamicHook :: IORef DynamicHooks -> ManageHook -> X ()
addDynamicHook ref m = updateDynamicHook ref (<+> m)
-- | Modifies the permanent 'ManageHook' with an arbitrary function.
updateDynamicHook :: IORef DynamicHooks -> (ManageHook -> ManageHook) -> X ()
updateDynamicHook ref f =
io $ modifyIORef ref $ \dh -> dh { permanent = f (permanent dh) }
-- | Creates a one-shot 'ManageHook'. Note that you have to specify the two
-- parts of the 'ManageHook' separately. Where you would usually write:
--
-- > className =? "example" --> doFloat
--
-- you must call 'oneShotHook' as
--
-- > oneShotHook dynHooksRef (className =? "example) doFloat
--
oneShotHook :: IORef DynamicHooks -> Query Bool -> ManageHook -> X ()
oneShotHook ref q a =
io $ modifyIORef ref
$ \dh -> dh { transients = (q,a):(transients dh) }

466
XMonad/Hooks/DynamicLog.hs Normal file
View File

@@ -0,0 +1,466 @@
{-# LANGUAGE FlexibleContexts #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.DynamicLog
-- Copyright : (c) Don Stewart <dons@cse.unsw.edu.au>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Don Stewart <dons@cse.unsw.edu.au>
-- Stability : unstable
-- Portability : unportable
--
-- xmonad calls the logHook with every internal state update, which is
-- useful for (among other things) outputting status information to an
-- external status bar program such as xmobar or dzen. DynamicLog
-- provides several drop-in logHooks for this purpose, as well as
-- flexible tools for specifying your own formatting.
--
-----------------------------------------------------------------------------
module XMonad.Hooks.DynamicLog (
-- * Usage
-- $usage
-- * Drop-in loggers
dzen,
xmobar,
statusBar,
dynamicLog,
dynamicLogXinerama,
-- * Build your own formatter
dynamicLogWithPP,
dynamicLogString,
PP(..), defaultPP,
-- * Example formatters
dzenPP, xmobarPP, sjanssenPP, byorgeyPP,
-- * Formatting utilities
wrap, pad, shorten,
xmobarColor, dzenColor, dzenEscape,
-- * Internal formatting functions
pprWindowSet,
pprWindowSetXinerama
-- * To Do
-- $todo
) where
--
-- Useful imports
--
import XMonad
import Control.Monad
import Data.Maybe ( isJust, catMaybes )
import Data.List
import qualified Data.Map as M
import Data.Ord ( comparing )
import qualified XMonad.StackSet as S
import System.IO
import XMonad.Util.WorkspaceCompare
import XMonad.Util.NamedWindows
import XMonad.Util.Run
import XMonad.Layout.LayoutModifier
import XMonad.Util.Font
import XMonad.Hooks.UrgencyHook
import XMonad.Hooks.ManageDocks
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad
-- > import XMonad.Hooks.DynamicLog
--
-- If you just want a quick-and-dirty status bar with zero effort, try
-- the 'xmobar' or 'dzen' functions:
--
-- > main = xmonad =<< xmobar conf
--
-- There is also 'statusBar' if you'd like to use another status bar, or would
-- like to use different formatting options. The 'xmobar', 'dzen', and
-- 'statusBar' functions are preferred over the other options listed below, as
-- they take care of all the necessary plumbing -- no shell scripting required!
--
-- Alternatively, you can choose among several default status bar formats
-- ('dynamicLog' or 'dynamicLogXinerama') by simply setting your logHook to the
-- appropriate function, for instance:
--
-- > main = xmonad $ defaultConfig {
-- > ...
-- > logHook = dynamicLog
-- > ...
-- > }
--
-- For more flexibility, you can also use 'dynamicLogWithPP' and supply
-- your own pretty-printing format (by either defining one from scratch,
-- or customizing one of the provided examples).
-- For example:
--
-- > -- use sjanssen's pretty-printer format, but with the sections
-- > -- in reverse
-- > logHook = dynamicLogWithPP $ sjanssenPP { ppOrder = reverse }
--
-- Note that setting the @logHook@ only sets up xmonad's output; you
-- are responsible for starting your own status bar program (e.g. dzen
-- or xmobar) and making sure xmonad's output is piped into it
-- appropriately, either by putting it in your @.xsession@ or similar
-- file, or by using @spawnPipe@ in your @main@ function, for example:
--
-- > import XMonad.Util.Run -- for spawnPipe and hPutStrLn
-- >
-- > main = do
-- > h <- spawnPipe "xmobar -options -foo -bar"
-- > xmonad $ defaultConfig {
-- > ...
-- > logHook = dynamicLogWithPP $ defaultPP { ppOutput = hPutStrLn h }
--
-- If you use @spawnPipe@, be sure to redefine the 'ppOutput' field of
-- your pretty-printer as in the example above; by default the status
-- will be printed to stdout rather than the pipe you create.
--
-- Even if you don't use a statusbar, you can still use
-- 'dynamicLogString' to show on-screen notifications in response to
-- some events. For example, to show the current layout when it
-- changes, you could make a keybinding to cycle the layout and
-- display the current status:
--
-- > , ((mod1Mask, xK_a ), sendMessage NextLayout >> (dynamicLogString myPP >>= \d->spawn $"xmessage "++d))
--
-- $todo
--
-- * incorporate dynamicLogXinerama into the PP framework somehow
--
-- * add an xmobarEscape function
------------------------------------------------------------------------
-- | Run xmonad with a dzen status bar set to some nice defaults.
--
-- > main = xmonad =<< dzen conf
--
-- The intent is that the above config file should provide a nice
-- status bar with minimal effort.
--
-- If you wish to customize the status bar format at all, you'll have to
-- use the 'statusBar' function instead.
--
-- The binding uses the XMonad.Hooks.ManageDocks module to automatically
-- handle screen placement for dzen, and enables 'mod-b' for toggling
-- the menu bar.
--
dzen :: LayoutClass l Window
=> XConfig l -> IO (XConfig (ModifiedLayout AvoidStruts l))
dzen conf = statusBar ("dzen2 " ++ flags) dzenPP toggleStrutsKey conf
where
fg = "'#a8a3f7'" -- n.b quoting
bg = "'#3f3c6d'"
flags = "-e 'onstart=lower' -w 400 -ta l -fg " ++ fg ++ " -bg " ++ bg
-- | Run xmonad with a xmobar status bar set to some nice defaults.
--
-- > main = xmonad =<< xmobar conf
--
-- This works pretty much the same as 'dzen' function above.
--
xmobar :: LayoutClass l Window
=> XConfig l -> IO (XConfig (ModifiedLayout AvoidStruts l))
xmobar conf = statusBar "xmobar" xmobarPP toggleStrutsKey conf
-- | Modifies the given base configuration to launch the given status bar,
-- send status information to that bar, and allocate space on the screen edges
-- for the bar.
statusBar :: LayoutClass l Window
=> String -- ^ the command line to launch the status bar
-> PP -- ^ the pretty printing options
-> (XConfig Layout -> (KeyMask, KeySym))
-- ^ the desired key binding to toggle bar visibility
-> XConfig l -- ^ the base config
-> IO (XConfig (ModifiedLayout AvoidStruts l))
statusBar cmd pp k conf = do
h <- spawnPipe cmd
return $ conf
{ layoutHook = avoidStruts (layoutHook conf)
, logHook = do
logHook conf
dynamicLogWithPP pp { ppOutput = hPutStrLn h }
, manageHook = manageHook conf <+> manageDocks
, keys = liftM2 M.union keys' (keys conf)
}
where
keys' = (`M.singleton` sendMessage ToggleStruts) . k
-- |
-- Helper function which provides ToggleStruts keybinding
--
toggleStrutsKey :: XConfig t -> (KeyMask, KeySym)
toggleStrutsKey XConfig{modMask = modm} = (modm, xK_b )
------------------------------------------------------------------------
-- | An example log hook, which prints status information to stdout in
-- the default format:
--
-- > 1 2 [3] 4 7 : full : title
--
-- That is, the currently populated workspaces, the current
-- workspace layout, and the title of the focused window.
--
-- To customize the output format, see 'dynamicLogWithPP'.
--
dynamicLog :: X ()
dynamicLog = dynamicLogWithPP defaultPP
-- | Format the current status using the supplied pretty-printing format,
-- and write it to stdout.
dynamicLogWithPP :: PP -> X ()
dynamicLogWithPP pp = dynamicLogString pp >>= io . ppOutput pp
-- | The same as 'dynamicLogWithPP', except it simply returns the status
-- as a formatted string without actually printing it to stdout, to
-- allow for further processing, or use in some application other than
-- a status bar.
dynamicLogString :: PP -> X String
dynamicLogString pp = do
winset <- gets windowset
urgents <- readUrgents
sort' <- ppSort pp
-- layout description
let ld = description . S.layout . S.workspace . S.current $ winset
-- workspace list
let ws = pprWindowSet sort' urgents pp winset
-- window title
wt <- maybe (return "") (fmap show . getName) . S.peek $ winset
-- run extra loggers, ignoring any that generate errors.
extras <- sequence $ map (flip catchX (return Nothing)) $ ppExtras pp
return $ encodeOutput . sepBy (ppSep pp) . ppOrder pp $
[ ws
, ppLayout pp ld
, ppTitle pp wt
]
++ catMaybes extras
-- | Format the workspace information, given a workspace sorting function,
-- a list of urgent windows, a pretty-printer format, and the current
-- WindowSet.
pprWindowSet :: WorkspaceSort -> [Window] -> PP -> WindowSet -> String
pprWindowSet sort' urgents pp s = sepBy (ppWsSep pp) . map fmt . sort' $
map S.workspace (S.current s : S.visible s) ++ S.hidden s
where this = S.currentTag s
visibles = map (S.tag . S.workspace) (S.visible s)
fmt w = printer pp (S.tag w)
where printer | S.tag w == this = ppCurrent
| S.tag w `elem` visibles = ppVisible
| any (\x -> maybe False (== S.tag w) (S.findTag x s)) urgents = \ppC -> ppUrgent ppC . ppHidden ppC
| isJust (S.stack w) = ppHidden
| otherwise = ppHiddenNoWindows
-- |
-- Workspace logger with a format designed for Xinerama:
--
-- > [1 9 3] 2 7
--
-- where 1, 9, and 3 are the workspaces on screens 1, 2 and 3, respectively,
-- and 2 and 7 are non-visible, non-empty workspaces.
--
-- Unfortunately, at the present time, the current layout and window title
-- are not shown, and there is no way to incorporate the xinerama
-- workspace format shown above with 'dynamicLogWithPP'. Hopefully this
-- will change soon.
dynamicLogXinerama :: X ()
dynamicLogXinerama = withWindowSet $ io . putStrLn . pprWindowSetXinerama
pprWindowSetXinerama :: WindowSet -> String
pprWindowSetXinerama ws = "[" ++ unwords onscreen ++ "] " ++ unwords offscreen
where onscreen = map (S.tag . S.workspace)
. sortBy (comparing S.screen) $ S.current ws : S.visible ws
offscreen = map S.tag . filter (isJust . S.stack)
. sortBy (comparing S.tag) $ S.hidden ws
-- | Wrap a string in delimiters, unless it is empty.
wrap :: String -- ^ left delimiter
-> String -- ^ right delimiter
-> String -- ^ output string
-> String
wrap _ _ "" = ""
wrap l r m = l ++ m ++ r
-- | Pad a string with a leading and trailing space.
pad :: String -> String
pad = wrap " " " "
-- | Limit a string to a certain length, adding "..." if truncated.
shorten :: Int -> String -> String
shorten n xs | length xs < n = xs
| otherwise = (take (n - length end) xs) ++ end
where
end = "..."
-- | Output a list of strings, ignoring empty ones and separating the
-- rest with the given separator.
sepBy :: String -- ^ separator
-> [String] -- ^ fields to output
-> String
sepBy sep = concat . intersperse sep . filter (not . null)
-- | Use dzen escape codes to output a string with given foreground
-- and background colors.
dzenColor :: String -- ^ foreground color: a color name, or #rrggbb format
-> String -- ^ background color
-> String -- ^ output string
-> String
dzenColor fg bg = wrap (fg1++bg1) (fg2++bg2)
where (fg1,fg2) | null fg = ("","")
| otherwise = ("^fg(" ++ fg ++ ")","^fg()")
(bg1,bg2) | null bg = ("","")
| otherwise = ("^bg(" ++ bg ++ ")","^bg()")
-- | Escape any dzen metacharacters.
dzenEscape :: String -> String
dzenEscape = concatMap (\x -> if x == '^' then "^^" else [x])
-- | Use xmobar escape codes to output a string with given foreground
-- and background colors.
xmobarColor :: String -- ^ foreground color: a color name, or #rrggbb format
-> String -- ^ background color
-> String -- ^ output string
-> String
xmobarColor fg bg = wrap t "</fc>"
where t = concat ["<fc=", fg, if null bg then "" else "," ++ bg, ">"]
-- ??? add an xmobarEscape function?
-- | The 'PP' type allows the user to customize the formatting of
-- status information.
data PP = PP { ppCurrent :: WorkspaceId -> String
-- ^ how to print the tag of the currently focused
-- workspace
, ppVisible :: WorkspaceId -> String
-- ^ how to print tags of visible but not focused
-- workspaces (xinerama only)
, ppHidden :: WorkspaceId -> String
-- ^ how to print tags of hidden workspaces which
-- contain windows
, ppHiddenNoWindows :: WorkspaceId -> String
-- ^ how to print tags of empty hidden workspaces
, ppUrgent :: WorkspaceId -> String
-- ^ format to be applied to tags of urgent workspaces.
-- NOTE that 'ppUrgent' is applied /in addition to/
-- 'ppHidden'!
, ppSep :: String
-- ^ separator to use between different log sections
-- (window name, layout, workspaces)
, ppWsSep :: String
-- ^ separator to use between workspace tags
, ppTitle :: String -> String
-- ^ window title format
, ppLayout :: String -> String
-- ^ layout name format
, ppOrder :: [String] -> [String]
-- ^ how to order the different log sections. By
-- default, this function receives a list with three
-- formatted strings, representing the workspaces,
-- the layout, and the current window title,
-- respectively. If you have specified any extra
-- loggers in 'ppExtras', their output will also be
-- appended to the list. To get them in the reverse
-- order, you can just use @ppOrder = reverse@. If
-- you don't want to display the current layout, you
-- could use something like @ppOrder = \\(ws:_:t:_) ->
-- [ws,t]@, and so on.
, ppSort :: X ([WindowSpace] -> [WindowSpace])
-- ^ how to sort the workspaces. See
-- "XMonad.Util.WorkspaceCompare" for some useful
-- sorts.
, ppExtras :: [X (Maybe String)]
-- ^ loggers for generating extra information such as
-- time and date, system load, battery status, and so
-- on. See "XMonad.Util.Loggers" for examples, or create
-- your own!
, ppOutput :: String -> IO ()
-- ^ applied to the entire formatted string in order to
-- output it. Can be used to specify an alternative
-- output method (e.g. write to a pipe instead of
-- stdout), and\/or to perform some last-minute
-- formatting.
}
-- | The default pretty printing options, as seen in 'dynamicLog'.
defaultPP :: PP
defaultPP = PP { ppCurrent = wrap "[" "]"
, ppVisible = wrap "<" ">"
, ppHidden = id
, ppHiddenNoWindows = const ""
, ppUrgent = id
, ppSep = " : "
, ppWsSep = " "
, ppTitle = shorten 80
, ppLayout = id
, ppOrder = id
, ppOutput = putStrLn
, ppSort = getSortByIndex
, ppExtras = []
}
-- | Settings to emulate dwm's statusbar, dzen only.
dzenPP :: PP
dzenPP = defaultPP { ppCurrent = dzenColor "white" "#2b4f98" . pad
, ppVisible = dzenColor "black" "#999999" . pad
, ppHidden = dzenColor "black" "#cccccc" . pad
, ppHiddenNoWindows = const ""
, ppUrgent = dzenColor "red" "yellow"
, ppWsSep = ""
, ppSep = ""
, ppLayout = dzenColor "black" "#cccccc" .
(\ x -> case x of
"TilePrime Horizontal" -> " TTT "
"TilePrime Vertical" -> " []= "
"Hinted Full" -> " [ ] "
_ -> pad x
)
, ppTitle = ("^bg(#324c80) " ++) . dzenEscape
}
-- | Some nice xmobar defaults.
xmobarPP :: PP
xmobarPP = defaultPP { ppCurrent = xmobarColor "yellow" "" . wrap "[" "]"
, ppTitle = xmobarColor "green" "" . shorten 40
, ppVisible = wrap "(" ")"
}
-- | The options that sjanssen likes to use with xmobar, as an
-- example. Note the use of 'xmobarColor' and the record update on
-- 'defaultPP'.
sjanssenPP :: PP
sjanssenPP = defaultPP { ppCurrent = xmobarColor "white" "black"
, ppTitle = xmobarColor "#00ee00" "" . shorten 120
}
-- | The options that byorgey likes to use with dzen, as another example.
byorgeyPP :: PP
byorgeyPP = defaultPP { ppHiddenNoWindows = showNamedWorkspaces
, ppHidden = dzenColor "black" "#a8a3f7" . pad
, ppCurrent = dzenColor "yellow" "#a8a3f7" . pad
, ppUrgent = dzenColor "red" "yellow"
, ppSep = " | "
, ppWsSep = ""
, ppTitle = shorten 70
, ppOrder = reverse
}
where showNamedWorkspaces wsId = if any (`elem` wsId) ['a'..'z']
then pad wsId
else ""

107
XMonad/Hooks/EventHook.hs Normal file
View File

@@ -0,0 +1,107 @@
{-# OPTIONS_GHC -fglasgow-exts #-} -- for deriving Typeable
{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.EventHook
-- Copyright : (c) 2007 Andrea Rossato
-- License : BSD-style (see xmonad/LICENSE)
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : unportable
--
-- A layout modifier that implements an event hook at the layout level.
--
-- Since it operates at the 'Workspace' level, it will install itself
-- on the first current 'Workspace' and will broadcast a 'Message' to
-- all other 'Workspace's not to handle events.
-----------------------------------------------------------------------------
module XMonad.Hooks.EventHook
( -- * Usage
-- $usage
-- * Writing a hook
-- $hook
EventHook (..)
, eventHook
, HandleEvent
) where
import Data.Maybe
import XMonad
import XMonad.StackSet (Workspace (..), currentTag)
-- $usage
-- You can use this module with the following in your
-- @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Hooks.EventHook
--
-- Then edit your @layoutHook@ by adding the 'eventHook':
--
-- > layoutHook = eventHook EventHookExample $ avoidStruts $ simpleTabbed ||| Full ||| etc..
--
-- and then:
--
-- > main = xmonad defaultConfig { layoutHook = myLayouts }
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
-- $hook
-- Writing a hook is very simple.
--
-- This is a basic example to log all events:
--
-- > data EventHookExample = EventHookExample deriving ( Show, Read )
-- > instance EventHook EventHookExample where
-- > handleEvent _ e = io $ hPutStrLn stderr . show $ e --return ()
--
-- This is an 'EventHook' to log mouse button events:
--
-- > data EventHookButton = EventHookButton deriving ( Show, Read )
-- > instance EventHook EventHookButton where
-- > handleEvent _ (ButtonEvent {ev_window = w}) = do
-- > io $ hPutStrLn stderr $ "This is a button event on window " ++ (show w)
-- > handleEvent _ _ = return ()
--
-- Obviously you can compose event hooks:
--
-- > layoutHook = eventHook EventHookButton $ eventHook EventHookExample $ avoidStruts $ simpleTabbed ||| Full ||| etc..
eventHook :: EventHook eh => eh -> l a -> (HandleEvent eh l) a
eventHook = HandleEvent Nothing True
class (Read eh, Show eh) => EventHook eh where
handleEvent :: eh -> Event -> X ()
handleEvent _ _ = return ()
data HandleEvent eh l a = HandleEvent (Maybe WorkspaceId) Bool eh (l a) deriving ( Show, Read )
data EventHandleMsg = HandlerOff deriving ( Typeable )
instance Message EventHandleMsg
instance (EventHook eh, LayoutClass l a) => LayoutClass (HandleEvent eh l) a where
runLayout (Workspace i (HandleEvent Nothing True eh l) ms) r = do
broadcastMessage HandlerOff
iws <- gets (currentTag . windowset)
(wrs, ml) <- runLayout (Workspace i l ms) r
return (wrs, Just $ HandleEvent (Just iws) True eh (fromMaybe l ml))
runLayout (Workspace i (HandleEvent mi b eh l) ms) r = do
(wrs, ml) <- runLayout (Workspace i l ms) r
return (wrs, Just $ HandleEvent mi b eh (fromMaybe l ml))
handleMessage (HandleEvent i True eh l) m
| Just HandlerOff <- fromMessage m = return . Just $ HandleEvent i False eh l
| Just e <- fromMessage m = handleMessage l (SomeMessage e) >>= \ml ->
handleEvent eh e >>
maybe (return Nothing) (\l' -> return . Just $ HandleEvent i True eh l') ml
handleMessage (HandleEvent i b eh l) m = handleMessage l m >>=
maybe (return Nothing) (\l' -> return . Just $ HandleEvent i b eh l')
description (HandleEvent _ _ _ l) = description l

View File

@@ -0,0 +1,229 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.EwmhDesktops
-- Copyright : (c) 2007, 2008 Joachim Breitner <mail@joachim-breitner.de>
-- License : BSD
--
-- Maintainer : Joachim Breitner <mail@joachim-breitner.de>
-- Stability : unstable
-- Portability : unportable
--
-- Makes xmonad use the EWMH hints to tell panel applications about its
-- workspaces and the windows therein. It also allows the user to interact
-- with xmonad by clicking on panels and window lists.
-----------------------------------------------------------------------------
module XMonad.Hooks.EwmhDesktops (
-- * Usage
-- $usage
EwmhDesktopsHook,
ewmhDesktopsLogHook,
ewmhDesktopsLogHookCustom,
ewmhDesktopsLayout
) where
import Data.List
import Data.Maybe
import XMonad
import Control.Monad
import qualified XMonad.StackSet as W
import XMonad.Hooks.SetWMName
import XMonad.Util.WorkspaceCompare
import XMonad.Hooks.EventHook
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad
-- > import XMonad.Hooks.EwmhDesktops
-- >
-- > myLogHook :: X ()
-- > myLogHook = ewmhDesktopsLogHook
-- >
-- > myLayoutHook = ewmhDesktopsLayout $ avoidStruts $ layoutHook defaultConfig
-- >
-- > main = xmonad defaultConfig { layoutHook = myLayouts, logHook = myLogHook }
--
-- 'avoidStruts' is used to automatically leave space for dock programs, and
-- can be found in 'XMonad.Hooks.ManageDocks'.
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#The_log_hook_and_external_status_bars"
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
-- |
-- Notifies pagers and window lists, such as those in the gnome-panel
-- of the current state of workspaces and windows.
ewmhDesktopsLogHook :: X ()
ewmhDesktopsLogHook = ewmhDesktopsLogHookCustom id
-- |
-- Generalized version of ewmhDesktopsLogHook that allows an arbitrary
-- user-specified function to transform the workspace list (post-sorting)
ewmhDesktopsLogHookCustom :: ([WindowSpace] -> [WindowSpace]) -> X ()
ewmhDesktopsLogHookCustom f = withWindowSet $ \s -> do
sort' <- getSortByIndex
let ws = f $ sort' $ W.workspaces s
setSupported
-- Number of Workspaces
setNumberOfDesktops (length ws)
-- Names thereof
setDesktopNames (map W.tag ws)
-- all windows, with focused windows last
let wins = nub . concatMap (maybe [] (\(W.Stack x l r)-> reverse l ++ r ++ [x]) . W.stack) $ ws
setClientList wins
-- Current desktop
case (elemIndex (W.currentTag s) $ map W.tag ws) of
Nothing -> return ()
Just curr -> do
setCurrentDesktop curr
-- Per window Desktop
-- To make gnome-panel accept our xinerama stuff, we display
-- all visible windows on the current desktop.
forM_ (W.current s : W.visible s) $ \x ->
forM_ (W.integrate' (W.stack (W.workspace x))) $ \win -> do
setWindowDesktop win curr
forM_ (W.hidden s) $ \w ->
case elemIndex (W.tag w) (map W.tag ws) of
Nothing -> return ()
Just wn -> forM_ (W.integrate' (W.stack w)) $ \win -> do
setWindowDesktop win wn
setActiveWindow
return ()
-- |
-- Intercepts messages from pagers and similar applications and reacts on them.
-- Currently supports:
--
-- * _NET_CURRENT_DESKTOP (switching desktops)
--
-- * _NET_WM_DESKTOP (move windows to other desktops)
--
-- * _NET_ACTIVE_WINDOW (activate another window, changing workspace if needed)
--
ewmhDesktopsLayout :: layout a -> HandleEvent EwmhDesktopsHook layout a
ewmhDesktopsLayout = eventHook EwmhDesktopsHook
data EwmhDesktopsHook = EwmhDesktopsHook deriving ( Show, Read )
instance EventHook EwmhDesktopsHook where
handleEvent _ e@ClientMessageEvent {} = do handle e
handleEvent _ _ = return ()
handle :: Event -> X ()
handle ClientMessageEvent {
ev_window = w,
ev_message_type = mt,
ev_data = d
} = withWindowSet $ \s -> do
sort' <- getSortByIndex
let ws = sort' $ W.workspaces s
a_cd <- getAtom "_NET_CURRENT_DESKTOP"
a_d <- getAtom "_NET_WM_DESKTOP"
a_aw <- getAtom "_NET_ACTIVE_WINDOW"
a_cw <- getAtom "_NET_CLOSE_WINDOW"
a_ignore <- mapM getAtom ["XMONAD_TIMER"]
if mt == a_cd then do
let n = fromIntegral (head d)
if 0 <= n && n < length ws then
windows $ W.view (W.tag (ws !! n))
else trace $ "Bad _NET_CURRENT_DESKTOP with data[0]="++show n
else if mt == a_d then do
let n = fromIntegral (head d)
if 0 <= n && n < length ws then
windows $ W.shiftWin (W.tag (ws !! n)) w
else trace $ "Bad _NET_DESKTOP with data[0]="++show n
else if mt == a_aw then do
windows $ W.focusWindow w
else if mt == a_cw then do
killWindow w
else if mt `elem` a_ignore then do
return ()
else trace $ "Unknown ClientMessageEvent " ++ show mt
handle _ = undefined -- does not happen, as otherwise ewmhDesktopsHook would not match
setNumberOfDesktops :: (Integral a) => a -> X ()
setNumberOfDesktops n = withDisplay $ \dpy -> do
a <- getAtom "_NET_NUMBER_OF_DESKTOPS"
c <- getAtom "CARDINAL"
r <- asks theRoot
io $ changeProperty32 dpy r a c propModeReplace [fromIntegral n]
setCurrentDesktop :: (Integral a) => a -> X ()
setCurrentDesktop i = withDisplay $ \dpy -> do
a <- getAtom "_NET_CURRENT_DESKTOP"
c <- getAtom "CARDINAL"
r <- asks theRoot
io $ changeProperty32 dpy r a c propModeReplace [fromIntegral i]
setDesktopNames :: [String] -> X ()
setDesktopNames names = withDisplay $ \dpy -> do
-- Names thereof
r <- asks theRoot
a <- getAtom "_NET_DESKTOP_NAMES"
c <- getAtom "UTF8_STRING"
let names' = map (fromIntegral.fromEnum) $
concatMap (++['\0']) names
io $ changeProperty8 dpy r a c propModeReplace names'
setClientList :: [Window] -> X ()
setClientList wins = withDisplay $ \dpy -> do
-- (What order do we really need? Something about age and stacking)
r <- asks theRoot
c <- getAtom "WINDOW"
a <- getAtom "_NET_CLIENT_LIST"
io $ changeProperty32 dpy r a c propModeReplace (fmap fromIntegral wins)
a' <- getAtom "_NET_CLIENT_LIST_STACKING"
io $ changeProperty32 dpy r a' c propModeReplace (fmap fromIntegral wins)
setWindowDesktop :: (Integral a) => Window -> a -> X ()
setWindowDesktop win i = withDisplay $ \dpy -> do
a <- getAtom "_NET_WM_DESKTOP"
c <- getAtom "CARDINAL"
io $ changeProperty32 dpy win a c propModeReplace [fromIntegral i]
setSupported :: X ()
setSupported = withDisplay $ \dpy -> do
r <- asks theRoot
a <- getAtom "_NET_SUPPORTED"
c <- getAtom "ATOM"
supp <- mapM getAtom ["_NET_WM_STATE_HIDDEN"
,"_NET_NUMBER_OF_DESKTOPS"
,"_NET_CLIENT_LIST"
,"_NET_CLIENT_LIST_STACKING"
,"_NET_CURRENT_DESKTOP"
,"_NET_DESKTOP_NAMES"
,"_NET_ACTIVE_WINDOW"
,"_NET_WM_DESKTOP"
,"_NET_WM_STRUT"
]
io $ changeProperty32 dpy r a c propModeReplace (fmap fromIntegral supp)
setWMName "xmonad"
setActiveWindow :: X ()
setActiveWindow = withWindowSet $ \s -> withDisplay $ \dpy -> do
let w = fromMaybe none (W.peek s)
r <- asks theRoot
a <- getAtom "_NET_ACTIVE_WINDOW"
c <- getAtom "WINDOW"
io $ changeProperty32 dpy r a c propModeReplace [fromIntegral w]

View File

@@ -0,0 +1,77 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.FadeInactive
-- Copyright : (c) 2008 Justin Bogner <mail@justinbogner.com>
-- License : BSD
--
-- Maintainer : Justin Bogner <mail@justinbogner.com>
-- Stability : unstable
-- Portability : unportable
--
-- Makes XMonad set the _NET_WM_WINDOW_OPACITY atom for inactive windows,
-- which causes those windows to become slightly translucent if something
-- like xcompmgr is running
-----------------------------------------------------------------------------
module XMonad.Hooks.FadeInactive (
-- * Usage
-- $usage
setOpacity,
fadeInactiveLogHook
) where
import XMonad
import qualified XMonad.StackSet as W
import Control.Monad (forM_)
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad
-- > import XMonad.Hooks.FadeInactive
-- >
-- > myLogHook :: X ()
-- > myLogHook = fadeInactiveLogHook fadeAmount
-- > where fadeAmount = 0xdddddddd
-- >
-- > main = xmonad defaultConfig { logHook = myLogHook }
--
-- fadeAmount can be any integer
-- you will need to have xcompmgr <http://freedesktop.org/wiki/Software/xapps>
-- or something similar for this to do anything
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#The_log_hook_and_external_status_bars"
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
-- |
-- sets the opacity of a window
setOpacity :: Window -> Integer -> X ()
setOpacity w t = withDisplay $ \dpy -> do
a <- getAtom "_NET_WM_WINDOW_OPACITY"
c <- getAtom "CARDINAL"
io $ changeProperty32 dpy w a c propModeReplace [fromIntegral t]
-- |
-- fades a window out by setting the opacity
fadeOut :: Integer -> Window -> X ()
fadeOut amt = flip setOpacity amt
-- |
-- makes a window completely opaque
fadeIn :: Window -> X ()
fadeIn = flip setOpacity 0xffffffff
-- |
-- lowers the opacity of inactive windows to the specified amount
fadeInactiveLogHook :: Integer -> X ()
fadeInactiveLogHook amt = withWindowSet $ \s ->
forM_ (visibleWins s) (fadeOut amt) >>
withFocused fadeIn
where
visibleWins s = (maybe [] unfocused . W.stack . W.workspace) (W.current s) ++
concatMap (W.integrate' . W.stack . W.workspace) (W.visible s)
unfocused (W.Stack _ l r) = l ++ r

242
XMonad/Hooks/ManageDocks.hs Normal file
View File

@@ -0,0 +1,242 @@
{-# LANGUAGE PatternGuards, FlexibleInstances, MultiParamTypeClasses #-}
{-# OPTIONS -fglasgow-exts #-}
-- deriving Typeable
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.ManageDocks
-- Copyright : (c) Joachim Breitner <mail@joachim-breitner.de>
-- License : BSD
--
-- Maintainer : Joachim Breitner <mail@joachim-breitner.de>
-- Stability : unstable
-- Portability : unportable
--
-- This module provides tools to automatically manage 'dock' type programs,
-- such as gnome-panel, kicker, dzen, and xmobar.
module XMonad.Hooks.ManageDocks (
-- * Usage
-- $usage
manageDocks, checkDock, AvoidStruts, avoidStruts, avoidStrutsOn,
ToggleStruts(..), Direction(..)
) where
-----------------------------------------------------------------------------
import XMonad
import Foreign.C.Types (CLong)
import Control.Monad
import XMonad.Layout.LayoutModifier
import Data.List (delete)
-- $usage
-- To use this module, add the following import to @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Hooks.ManageDocks
--
-- The first component is a 'ManageHook' which recognizes these
-- windows and de-manages them, so that xmonad does not try to tile
-- them. To enable it:
--
-- > manageHook = ... <+> manageDocks
--
-- The second component is a layout modifier that prevents windows
-- from overlapping these dock windows. It is intended to replace
-- xmonad's so-called \"gap\" support. First, you must add it to your
-- list of layouts:
--
-- > layoutHook = avoidStruts (tall ||| mirror tall ||| ...)
-- > where tall = Tall 1 (3/100) (1/2)
--
-- 'AvoidStruts' also supports toggling the dock gaps; add a keybinding
-- similar to:
--
-- > ,((modMask x, xK_b ), sendMessage ToggleStruts)
--
-- If you have multiple docks, you can toggle their gaps individually.
-- For example, to toggle only the top gap:
--
-- > ,((modMask x .|. controlMask, xK_t), sendMessage $ ToggleStrut U)
--
-- Similarly, you can use 'D', 'L', and 'R' to individually toggle
-- gaps on the bottom, left, or right.
--
-- If you want certain docks to be avoided but others to be covered by
-- default, you can manually specify the sides of the screen on which
-- docks should be avoided, using 'avoidStrutsOn'. For example:
--
-- > layoutHook = avoidStrutsOn [U,L] (tall ||| mirror tall ||| ...)
--
-- /Important note/: if you are switching from manual gaps
-- (defaultGaps in your config) to avoidStruts (recommended, since
-- manual gaps will probably be phased out soon), be sure to switch
-- off all your gaps (with mod-b) /before/ reloading your config with
-- avoidStruts! Toggling struts with a 'ToggleStruts' message will
-- not work unless your gaps are set to zero.
--
-- For detailed instructions on editing your key bindings, see
-- "XMonad.Doc.Extending#Editing_key_bindings".
--
-- | An enumeration of the four cardinal directions\/sides of the
-- screen.
--
-- Ideally this would go in its own separate module in Util,
-- but ManageDocks is angling for inclusion into the xmonad core,
-- so keep the dependencies to a minimum.
data Direction = U -- ^ Up\/top
| D -- ^ Down\/bottom
| R -- ^ Right
| L -- ^ Left
deriving ( Read, Show, Eq, Ord, Enum, Bounded )
-- | Detects if the given window is of type DOCK and if so, reveals
-- it, but does not manage it. If the window has the STRUT property
-- set, adjust the gap accordingly.
manageDocks :: ManageHook
manageDocks = checkDock --> doIgnore
-- | Checks if a window is a DOCK or DESKTOP window
checkDock :: Query Bool
checkDock = ask >>= \w -> liftX $ do
a <- getAtom "_NET_WM_WINDOW_TYPE"
dock <- getAtom "_NET_WM_WINDOW_TYPE_DOCK"
desk <- getAtom "_NET_WM_WINDOW_TYPE_DESKTOP"
mbr <- getProp a w
case mbr of
Just [r] -> return $ elem (fromIntegral r) [dock, desk]
_ -> return False
-- | Gets the STRUT config, if present, in xmonad gap order
getStrut :: Window -> X [Strut]
getStrut w = do
spa <- getAtom "_NET_WM_STRUT_PARTIAL"
sa <- getAtom "_NET_WM_STRUT"
msp <- getProp spa w
case msp of
Just sp -> return $ parseStrutPartial sp
Nothing -> fmap (maybe [] parseStrut) $ getProp sa w
where
parseStrut xs@[_, _, _, _] = parseStrutPartial . take 12 $ xs ++ cycle [minBound, maxBound]
parseStrut _ = []
parseStrutPartial [l, r, t, b, ly1, ly2, ry1, ry2, tx1, tx2, bx1, bx2]
= filter (\(_, n, _, _) -> n /= 0)
[(L, l, ly1, ly2), (R, r, ry1, ry2), (U, t, tx1, tx2), (D, b, bx1, bx2)]
parseStrutPartial _ = []
-- | Helper to read a property
getProp :: Atom -> Window -> X (Maybe [CLong])
getProp a w = withDisplay $ \dpy -> io $ getWindowProperty32 dpy a w
-- | Goes through the list of windows and find the gap so that all
-- STRUT settings are satisfied.
calcGap :: [Direction] -> X (Rectangle -> Rectangle)
calcGap ss = withDisplay $ \dpy -> do
rootw <- asks theRoot
-- We don't keep track of dock like windows, so we find all of them here
(_,_,wins) <- io $ queryTree dpy rootw
struts <- (filter careAbout . concat) `fmap` mapM getStrut wins
-- we grab the window attributes of the root window rather than checking
-- the width of the screen because xlib caches this info and it tends to
-- be incorrect after RAndR
wa <- io $ getWindowAttributes dpy rootw
let screen = r2c $ Rectangle (fi $ wa_x wa) (fi $ wa_y wa) (fi $ wa_width wa) (fi $ wa_height wa)
return $ \r -> c2r $ foldr (reduce screen) (r2c r) struts
where careAbout (s,_,_,_) = s `elem` ss
-- | Adjust layout automagically: don't cover up any docks, status
-- bars, etc.
avoidStruts :: LayoutClass l a => l a -> ModifiedLayout AvoidStruts l a
avoidStruts = avoidStrutsOn [U,D,L,R]
-- | Adjust layout automagically: don't cover up docks, status bars,
-- etc. on the indicated sides of the screen. Valid sides are U
-- (top), D (bottom), R (right), or L (left).
avoidStrutsOn :: LayoutClass l a =>
[Direction]
-> l a
-> ModifiedLayout AvoidStruts l a
avoidStrutsOn ss = ModifiedLayout (AvoidStruts ss)
data AvoidStruts a = AvoidStruts [Direction] deriving ( Read, Show )
-- | Message type which can be sent to an 'AvoidStruts' layout
-- modifier to alter its behavior.
data ToggleStruts = ToggleStruts
| ToggleStrut Direction
deriving (Read,Show,Typeable)
instance Message ToggleStruts
instance LayoutModifier AvoidStruts a where
modifyLayout (AvoidStruts ss) w r = do
nr <- fmap ($ r) (calcGap ss)
runLayout w nr
handleMess (AvoidStruts ss) m
| Just ToggleStruts <- fromMessage m = return $ Just $ AvoidStruts (toggleAll ss)
| Just (ToggleStrut s) <- fromMessage m = return $ Just $ AvoidStruts (toggleOne s ss)
| otherwise = return Nothing
where toggleAll [] = [U,D,L,R]
toggleAll _ = []
toggleOne x xs | x `elem` xs = delete x xs
| otherwise = x : xs
-- | (Direction, height\/width, initial pixel, final pixel).
type Strut = (Direction, CLong, CLong, CLong)
-- | (Initial x pixel, initial y pixel,
-- final x pixel, final y pixel).
type RectC = (CLong, CLong, CLong, CLong)
fi :: (Integral a, Num b) => a -> b
fi = fromIntegral
-- | Invertible conversion.
r2c :: Rectangle -> RectC
r2c (Rectangle x y w h) = (fi x, fi y, fi x + fi w - 1, fi y + fi h - 1)
-- | Invertible conversion.
c2r :: RectC -> Rectangle
c2r (x1, y1, x2, y2) = Rectangle (fi x1) (fi y1) (fi $ x2 - x1 + 1) (fi $ y2 - y1 + 1)
-- TODO: Add these QuickCheck properties to the test suite, along with
-- suitable Arbitrary instances.
-- prop_r2c_c2r :: RectC -> Bool
-- prop_r2c_c2r r = r2c (c2r r) == r
-- prop_c2r_r2c :: Rectangle -> Bool
-- prop_c2r_r2c r = c2r (r2c r) == r
reduce :: RectC -> Strut -> RectC -> RectC
reduce (sx0, sy0, sx1, sy1) (s, n, l, h) (x0, y0, x1, y1) = case s of
L | p (y0, y1) -> (mx x0 sx0 , y0 , x1 , y1 )
R | p (y0, y1) -> (x0 , y0 , mn x1 sx1, y1 )
U | p (x0, x1) -> (x0 , mx y0 sy0, x1 , y1 )
D | p (x0, x1) -> (x0 , y0 , x1 , mn y1 sy1)
_ -> (x0 , y0 , x1 , y1 )
where
mx a b = max a (b + n)
mn a b = min a (b - n)
p r = r `overlaps` (l, h)
-- | Do the two ranges overlap?
--
-- Precondition for every input range @(x, y)@: @x '<=' y@.
--
-- A range @(x, y)@ is assumed to include every pixel from @x@ to @y@.
overlaps :: Ord a => (a, a) -> (a, a) -> Bool
(a, b) `overlaps` (x, y) =
inRange (a, b) x || inRange (a, b) y || inRange (x, y) a
where
inRange (i, j) k = i <= k && k <= j

View File

@@ -0,0 +1,215 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.ManageHelpers
-- Copyright : (c) Lukas Mai
-- License : BSD
--
-- Maintainer : Lukas Mai <l.mai@web.de>
-- Stability : unstable
-- Portability : unportable
--
-- This module provides helper functions to be used in @manageHook@. Here's
-- how you might use this:
--
-- > import XMonad.Hooks.ManageHelpers
-- > main =
-- > xmonad defaultConfig{
-- > ...
-- > manageHook = composeOne [
-- > isKDETrayWindow -?> doIgnore,
-- > transience,
-- > isFullscreen -?> doFullFloat,
-- > resource =? "stalonetray" -?> doIgnore
-- > ],
-- > ...
-- > }
module XMonad.Hooks.ManageHelpers (
Side(..),
composeOne,
(-?>), (/=?), (<==?), (</=?), (-->>), (-?>>),
isKDETrayWindow,
isFullscreen,
isDialog,
pid,
transientTo,
maybeToDefinite,
MaybeManageHook,
transience,
transience',
doRectFloat,
doFullFloat,
doCenterFloat,
doSideFloat,
doHideIgnore
) where
import XMonad
import qualified XMonad.StackSet as W
import Data.Maybe
import Data.Monoid
import System.Posix (ProcessID)
-- | Denotes a side of a screen. @S@ stands for South, @NE@ for Northwest
-- etc. @C@ stands for Center.
data Side = SC | NC | CE | CW | SE | SW | NE | NW | C
deriving (Read, Show, Eq)
-- | A ManageHook that may or may not have been executed; the outcome is embedded in the Maybe
type MaybeManageHook = Query (Maybe (Endo WindowSet))
-- | A grouping type, which can hold the outcome of a predicate Query.
-- This is analogous to group types in regular expressions.
-- TODO: create a better API for aggregating multiple Matches logically
data Match a = Match Bool a
-- | An alternative 'ManageHook' composer. Unlike 'composeAll' it stops as soon as
-- a candidate returns a 'Just' value, effectively running only the first match
-- (whereas 'composeAll' continues and executes all matching rules).
composeOne :: [MaybeManageHook] -> ManageHook
composeOne = foldr try idHook
where
try q z = do
x <- q
case x of
Just h -> return h
Nothing -> z
infixr 0 -?>, -->>, -?>>
-- | q \/=? x. if the result of q equals x, return False
(/=?) :: Eq a => Query a -> a -> Query Bool
q /=? x = fmap (/= x) q
-- | q <==? x. if the result of q equals x, return True grouped with q
(<==?) :: Eq a => Query a -> a -> Query (Match a)
q <==? x = fmap (`eq` x) q
where
eq q' x' = Match (q' == x') q'
-- | q <\/=? x. if the result of q notequals x, return True grouped with q
(</=?) :: Eq a => Query a -> a -> Query (Match a)
q </=? x = fmap (`neq` x) q
where
neq q' x' = Match (q' /= x') q'
-- | A helper operator for use in 'composeOne'. It takes a condition and an action;
-- if the condition fails, it returns 'Nothing' from the 'Query' so 'composeOne' will
-- go on and try the next rule.
(-?>) :: Query Bool -> ManageHook -> MaybeManageHook
p -?> f = do
x <- p
if x then fmap Just f else return Nothing
-- | A helper operator for use in 'composeAll'. It takes a condition and a function taking a grouped datum to action. If 'p' is true, it executes the resulting action.
(-->>) :: Query (Match a) -> (a -> ManageHook) -> ManageHook
p -->> f = do
Match b m <- p
if b then (f m) else mempty
-- | A helper operator for use in 'composeOne'. It takes a condition and a function taking a groupdatum to action. If 'p' is true, it executes the resulting action. If it fails, it returns 'Nothing' from the 'Query' so 'composeOne' will go on and try the next rule.
(-?>>) :: Query (Match a) -> (a -> ManageHook) -> MaybeManageHook
p -?>> f = do
Match b m <- p
if b then fmap Just (f m) else return Nothing
-- | A predicate to check whether a window is a KDE system tray icon.
isKDETrayWindow :: Query Bool
isKDETrayWindow = ask >>= \w -> liftX $ do
dpy <- asks display
kde_tray <- getAtom "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR"
r <- io $ getWindowProperty32 dpy kde_tray w
return $ case r of
Just [_] -> True
_ -> False
-- | A predicate to check whether a window wants to fill the whole screen.
-- See also 'doFullFloat'.
isFullscreen :: Query Bool
isFullscreen = ask >>= \w -> liftX $ do
dpy <- asks display
state <- getAtom "_NET_WM_STATE"
full <- getAtom "_NET_WM_STATE_FULLSCREEN"
r <- io $ getWindowProperty32 dpy state w
return $ case r of
Just xs -> fromIntegral full `elem` xs
_ -> False
-- | A predicate to check whether a window is a dialog.
isDialog :: Query Bool
isDialog = ask >>= \w -> liftX $ do
dpy <- asks display
w_type <- getAtom "_NET_WM_WINDOW_TYPE"
w_dialog <- getAtom "_NET_WM_WINDOW_TYPE_DIALOG"
r <- io $ getWindowProperty32 dpy w_type w
return $ case r of
Just xs -> fromIntegral w_dialog `elem` xs
_ -> False
pid :: Query (Maybe ProcessID)
pid = ask >>= \w -> liftX $ do
dpy <- asks display
a <- getAtom "_NET_WM_PID"
p <- io $ getWindowProperty32 dpy a w
return $ case p of
Just [x] -> Just (fromIntegral x)
_ -> Nothing
-- | A predicate to check whether a window is Transient.
-- It holds the result which might be the window it is transient to
-- or it might be 'Nothing'.
transientTo :: Query (Maybe Window)
transientTo = do
w <- ask
d <- (liftX . asks) display
liftIO $ getTransientForHint d w
-- | A convenience 'MaybeManageHook' that will check to see if a window
-- is transient, and then move it to its parent.
transience :: MaybeManageHook
transience = transientTo </=? Nothing -?>> move
where
move mw = maybe idHook (doF . move') mw
move' w s = maybe s (`W.shift` s) (W.findTag w s)
-- | 'transience' set to a 'ManageHook'
transience' :: ManageHook
transience' = maybeToDefinite transience
-- | converts 'MaybeManageHook's to 'ManageHook's
maybeToDefinite :: MaybeManageHook -> ManageHook
maybeToDefinite = fmap (fromMaybe mempty)
-- | Floats the new window in the given rectangle.
doRectFloat :: W.RationalRect -- ^ The rectangle to float the window in. 0 to 1; x, y, w, h.
-> ManageHook
doRectFloat r = ask >>= \w -> doF (W.float w r)
-- | Floats the window and makes it use the whole screen. Equivalent to
-- @'doRectFloat' $ 'W.RationalRect' 0 0 1 1@.
doFullFloat :: ManageHook
doFullFloat = doRectFloat $ W.RationalRect 0 0 1 1
-- | Floats a new window with its original size on the specified side of a
-- screen
doSideFloat :: Side -> ManageHook
doSideFloat side = ask >>= \w -> doF . W.float w . move . snd =<< liftX (floatLocation w)
where
move (W.RationalRect _ _ w h) = W.RationalRect cx cy w h
where
cx = if side `elem` [SC,C ,NC] then (1-w)/2
else if side `elem` [SW,CW,NW] then 0
else {- side `elem` [SE,CE,NE] -} 1-w
cy = if side `elem` [CE,C ,CW] then (1-h)/2
else if side `elem` [NE,NC,NW] then 0
else {- side `elem` [SE,SC,SW] -} 1-h
-- | Floats a new window with its original size, but centered.
doCenterFloat :: ManageHook
doCenterFloat = doSideFloat C
-- | Hides window and ignores it.
doHideIgnore :: ManageHook
doHideIgnore = ask >>= \w -> liftX (hide w) >> doF (W.delete w)

54
XMonad/Hooks/Script.hs Normal file
View File

@@ -0,0 +1,54 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.Script
-- Copyright : (c) Trevor Elliott <trevor@galois.com>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Trevor Elliott <trevor@galois.com>
-- Stability : unstable
-- Portability : unportable
--
-- Provides a simple interface for running a ~\/.xmonad\/hooks script with the
-- name of a hook.
--
-----------------------------------------------------------------------------
module XMonad.Hooks.Script (
-- * Usage
-- $usage
-- * Script Hook Interface
execScriptHook
) where
--
-- Useful Imports
--
import XMonad
import Control.Monad.Trans
import System.Directory
-- $usage
--
-- This module allows you to run a centrally located script with the text
-- name of a hook. The script is assumed to be located at @~\/.xmonad\/hooks@.
--
-- For example, if you wanted to run the hook "startup" in your script every
-- time your startup hook ran, you could modify your xmonad config as such:
--
-- > main = xmonad $ defaultConfig {
-- > ...
-- > startupHook = execScriptHook "startup"
-- > ...
-- > }
--
-- Now, everytime the startup hook runs, the command
-- @~\/.xmonad\/hooks startup@ will also.
-- | Execute a named script hook
execScriptHook :: MonadIO m => String -> m ()
execScriptHook hook = io $ do
home <- getHomeDirectory
let script = home ++ "/.xmonad/hooks "
spawn (script ++ hook)

103
XMonad/Hooks/ServerMode.hs Normal file
View File

@@ -0,0 +1,103 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.ServerMode
-- Copyright : (c) Andrea Rossato and David Roundy 2007
-- License : BSD-style (see xmonad/LICENSE)
--
-- Maintainer : andrea.rossato@unibz.it
-- Stability : unstable
-- Portability : unportable
--
-- This is an 'EventHook' that will receive commands from an external
-- client.
--
-- This is the example of a client:
--
-- > import Graphics.X11.Xlib
-- > import Graphics.X11.Xlib.Extras
-- > import System.Environment
-- > import Data.Char
-- >
-- > usage :: String -> String
-- > usage n = "Usage: " ++ n ++ " command number\nSend a command number to a running instance of XMonad"
-- >
-- > main :: IO ()
-- > main = do
-- > args <- getArgs
-- > pn <- getProgName
-- > let com = case args of
-- > [] -> error $ usage pn
-- > w -> (w !! 0)
-- > sendCommand com
-- >
-- > sendCommand :: String -> IO ()
-- > sendCommand s = do
-- > d <- openDisplay ""
-- > rw <- rootWindow d $ defaultScreen d
-- > a <- internAtom d "XMONAD_COMMAND" False
-- > allocaXEvent $ \e -> do
-- > setEventType e clientMessage
-- > setClientMessageEvent e rw a 32 (fromIntegral (read s)) currentTime
-- > sendEvent d rw False structureNotifyMask e
-- > sync d False
--
-- compile with: @ghc --make sendCommand.hs@
--
-- run with
--
-- > sendCommand command number
--
-- For instance:
--
-- > sendCommand 0
--
-- will ask to xmonad to print the list of command numbers in
-- stderr (so you can read it in @~\/.xsession-errors@).
-----------------------------------------------------------------------------
module XMonad.Hooks.ServerMode
( -- * Usage
-- $usage
ServerMode (..)
, eventHook
) where
import Control.Monad (when)
import Data.List
import System.IO
import XMonad
import XMonad.Actions.Commands
import XMonad.Hooks.EventHook
-- $usage
-- You can use this module with the following in your
-- @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Hooks.ServerMode
--
-- Then edit your @layoutHook@ by adding the 'eventHook':
--
-- > layoutHook = eventHook ServerMode $ avoidStruts $ simpleTabbed ||| Full ||| etc..
--
-- and then:
--
-- > main = xmonad defaultConfig { layoutHook = myLayouts }
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
data ServerMode = ServerMode deriving ( Show, Read )
instance EventHook ServerMode where
handleEvent _ (ClientMessageEvent {ev_message_type = mt, ev_data = dt}) = do
d <- asks display
a <- io $ internAtom d "XMONAD_COMMAND" False
when (mt == a && dt /= []) $ do
cl <- defaultCommands
let listOfCommands = map (uncurry (++)) . zip (map show ([1..] :: [Int])) . map ((++) " - " . fst)
case lookup (fromIntegral (head dt) :: Int) (zip [1..] cl) of
Just (c,_) -> runCommand' c
Nothing -> mapM_ (io . hPutStrLn stderr) . listOfCommands $ cl
handleEvent _ _ = return ()

View File

@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.SetWMName
-- Module : XMonad.Hooks.SetWMName
-- Copyright : © 2007 Ivan Tarasov <Ivan.Tarasov@gmail.com>
-- License : BSD
--
@@ -14,41 +14,39 @@
-- 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.
--
-- Remember that you need to call the setWMName action yourself (at least until
-- we have startup hooks). E.g., you can bind it in your Config.hs:
-- To your @~\/.xmonad\/xmonad.hs@ file, add the following line:
--
-- > ((modMask .|. controlMask .|. shiftMask, xK_z), setWMName "LG3D") -- @@ Java hack
-- > import XMonad.Hooks.SetWMName
--
-- and press the key combination before running the Java programs (you only
-- need to do it once per XMonad execution)
-- 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
-- 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
-- "XMonad.Doc.Extending#4".
-----------------------------------------------------------------------------
module XMonadContrib.SetWMName (
module XMonad.Hooks.SetWMName (
setWMName) where
import Control.Monad (join)
import Control.Monad.Reader (asks)
import Data.Bits ((.|.))
import Data.Char (ord)
import Data.List (nub)
import Data.Maybe (fromJust, listToMaybe, maybeToList)
import Data.Word (Word8)
import Foreign.C.Types (CChar)
import Foreign.Marshal.Alloc (alloca)
import XMonad
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Atom
import Graphics.X11.Xlib.Extras
-- | sets WM name
setWMName :: String -> X ()
@@ -65,7 +63,7 @@ setWMName name = 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 0 [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 0 (latin1StringToWord8List name)
changeProperty8 dpy supportWindow atom_NET_WM_NAME atom_UTF8_STRING 0 (latin1StringToCCharList name)
-- declare which _NET protocols are supported (append to the list if it exists)
supportedList <- fmap (join . maybeToList) $ getWindowProperty32 dpy atom_NET_SUPPORTED_ATOM root
changeProperty32 dpy root atom_NET_SUPPORTED_ATOM aTOM 0 (nub $ fromIntegral atom_NET_SUPPORTING_WM_CHECK : fromIntegral atom_NET_WM_NAME : supportedList)
@@ -73,8 +71,8 @@ setWMName name = do
netSupportingWMCheckAtom :: X Atom
netSupportingWMCheckAtom = getAtom "_NET_SUPPORTING_WM_CHECK"
latin1StringToWord8List :: String -> [Word8]
latin1StringToWord8List str = map (fromIntegral . ord) str
latin1StringToCCharList :: String -> [CChar]
latin1StringToCCharList str = map (fromIntegral . ord) str
getSupportWindow :: X Window
getSupportWindow = withDisplay $ \dpy -> do

438
XMonad/Hooks/UrgencyHook.hs Normal file
View File

@@ -0,0 +1,438 @@
{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, TypeSynonymInstances, PatternGuards #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.UrgencyHook
-- Copyright : Devin Mullins <me@twifkak.com>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Devin Mullins <me@twifkak.com>
-- Stability : unstable
-- Portability : unportable
--
-- UrgencyHook lets you configure an action to occur when a window demands
-- your attention. (In traditional WMs, this takes the form of \"flashing\"
-- on your \"taskbar.\" Blech.)
--
-----------------------------------------------------------------------------
module XMonad.Hooks.UrgencyHook (
-- * Usage
-- $usage
-- ** Pop up a temporary dzen
-- $temporary
-- ** Highlight in existing dzen
-- $existing
-- ** Useful keybinding
-- $keybinding
-- ** Note
-- $note
-- * Troubleshooting
-- $troubleshooting
-- * Example: Setting up irssi + rxvt-unicode
-- $example
-- ** Configuring irssi
-- $irssi
-- ** Configuring screen
-- $screen
-- ** Configuring rxvt-unicode
-- $urxvt
-- ** Configuring xmonad
-- $xmonad
-- * Stuff for your config file:
withUrgencyHook, withUrgencyHookC,
UrgencyConfig(..), urgencyConfig,
SuppressWhen(..), RemindWhen(..),
focusUrgent, clearUrgents,
dzenUrgencyHook,
DzenUrgencyHook(..),
NoUrgencyHook(..),
FocusHook(..),
minutes, seconds,
-- * Stuff for developers:
readUrgents, withUrgents,
StdoutUrgencyHook(..),
SpawnUrgencyHook(..),
UrgencyHook(urgencyHook)
) where
import XMonad
import qualified XMonad.StackSet as W
import XMonad.Hooks.EventHook
import XMonad.Util.Dzen (dzenWithArgs, seconds)
import XMonad.Util.NamedWindows (getName)
import XMonad.Util.Timer (TimerId, startTimer, handleTimer)
import Control.Applicative ((<$>))
import Control.Monad (when)
import Data.Bits (testBit)
import Data.IORef
import Data.List (delete)
import Data.Maybe (listToMaybe, maybeToList)
import qualified Data.Set as S
import Foreign (unsafePerformIO)
-- $usage
--
-- To wire this up, first add:
--
-- > import XMonad.Hooks.UrgencyHook
--
-- to your import list in your config file. Now, you have a decision to make:
-- When a window deems itself urgent, do you want to pop up a temporary dzen
-- bar telling you so, or do you have an existing dzen wherein you would like to
-- highlight urgent workspaces?
-- $temporary
--
-- Enable your urgency hook by wrapping your config record in a call to
-- 'withUrgencyHook'. For example:
--
-- > main = xmonad $ withUrgencyHook dzenUrgencyHook { args = ["-bg", "darkgreen", "-xs", "1"] }
-- > $ defaultConfig
--
-- This will pop up a dzen bar for five seconds telling you you've got an
-- urgent window.
-- $existing
--
-- In order for xmonad to track urgent windows, you must install an urgency hook.
-- You can use the above 'dzenUrgencyHook', or if you're not interested in the
-- extra popup, install NoUrgencyHook, as so:
--
-- > main = xmonad $ withUrgencyHook NoUrgencyHook
-- > $ defaultConfig
--
-- Now, your "XMonad.Hooks.DynamicLog" must be set up to display the urgent
-- windows. If you're using the 'dzen' or 'dzenPP' functions from that module,
-- then you should be good. Otherwise, you want to figure out how to set
-- 'ppUrgent'.
-- $keybinding
--
-- You can set up a keybinding to jump to the window that was recently marked
-- urgent. See an example at 'focusUrgent'.
-- $note
-- Note: UrgencyHook installs itself as a LayoutModifier, so if you modify your
-- urgency hook and restart xmonad, you may need to rejigger your layout by
-- hitting mod-shift-space.
-- $troubleshooting
--
-- There are three steps to get right:
--
-- 1. The X client must set the UrgencyHint flag. How to configure this
-- depends on the application. If you're using a terminal app, this is in
-- two parts:
--
-- * The console app must send a ^G (bell). In bash, a helpful trick is
-- @sleep 1; echo -e \'\a\'@.
--
-- * The terminal must convert the bell into UrgencyHint.
--
-- 2. XMonad must be configured to notice UrgencyHints. If you've added
-- withUrgencyHook, you may need to hit mod-shift-space to reset the layout.
--
-- 3. The dzen must run when told. Run @dzen2 -help@ and make sure that it
-- supports all of the arguments you told DzenUrgencyHook to pass it. Also,
-- set up a keybinding to the 'dzen' action in "XMonad.Util.Dzen" to test
-- if that works.
--
-- As best you can, try to isolate which one(s) of those is failing.
-- $example
--
-- This is a commonly asked example. By default, the window doesn't get flagged
-- urgent when somebody messages you in irssi. You will have to configure some
-- things. If you're using different tools than this, your mileage will almost
-- certainly vary. (For example, in Xchat2, it's just a simple checkbox.)
-- $irssi
-- @Irssi@ is not an X11 app, so it can't set the @UrgencyHint@ flag on @XWMHints@.
-- However, on all console applications is bestown the greatest of all notification
-- systems: the bell. That's right, Ctrl+G, ASCII code 7, @echo -e '\a'@, your
-- friend, the bell. To configure @irssi@ to send a bell when you receive a message:
--
-- > /set beep_msg_level MSGS NOTICES INVITES DCC DCCMSGS HILIGHT
--
-- Consult your local @irssi@ documentation for more detail.
-- $screen
-- A common way to run @irssi@ is within the lovable giant, @screen@. Some distros
-- (e.g. Ubuntu) like to configure @screen@ to trample on your poor console
-- applications -- in particular, to turn bell characters into evil, smelly
-- \"visual bells.\" To turn this off, add:
--
-- > vbell off # or remove the existing 'vbell on' line
--
-- to your .screenrc, or hit @C-a C-g@ within a running @screen@ session for an
-- immediate but temporary fix.
-- $urxvt
-- Rubber, meet road. Urxvt is the gateway between console apps and X11. To tell
-- urxvt to set an @UrgencyHint@ when it receives a bell character, first, have
-- an urxvt version 8.3 or newer, and second, set the following in your
-- @.Xdefaults@:
--
-- > urxvt.urgentOnBell: true
--
-- Depending on your setup, you may need to @xrdb@ that.
-- $xmonad
-- Hopefully you already read the section on how to configure xmonad. If not,
-- hopefully you know where to find it.
-- | This is the method to enable an urgency hook. It uses the default
-- 'urgencyConfig' to control behavior. To change this, use 'withUrgencyHook'
-- instead.
withUrgencyHook :: (LayoutClass l Window, UrgencyHook h) =>
h -> XConfig l -> XConfig (HandleEvent (WithUrgencyHook h) l)
withUrgencyHook hook conf = withUrgencyHookC hook urgencyConfig conf
-- | This lets you modify the defaults set in 'urgencyConfig'. An example:
--
-- > withUrgencyHookC dzenUrgencyHook { ... } urgencyConfig { suppressWhen = Focused }
--
-- (Don't type the @...@, you dolt.) See 'UrgencyConfig' for details on configuration.
withUrgencyHookC :: (LayoutClass l Window, UrgencyHook h) =>
h -> UrgencyConfig -> XConfig l -> XConfig (HandleEvent (WithUrgencyHook h) l)
withUrgencyHookC hook urgConf conf = conf {
layoutHook = eventHook (WithUrgencyHook hook urgConf) $ layoutHook conf,
logHook = cleanupUrgents (suppressWhen urgConf) >> logHook conf
}
-- | Global configuration, applied to all types of 'UrgencyHook'. See
-- 'urgencyConfig' for the defaults.
data UrgencyConfig = UrgencyConfig
{ suppressWhen :: SuppressWhen -- ^ when to trigger the urgency hook
, remindWhen :: RemindWhen -- ^ when to re-trigger the urgency hook
} deriving (Read, Show)
-- | A set of choices as to /when/ you should (or rather, shouldn't) be notified of an urgent window.
-- The default is 'Visible'. Prefix each of the following with \"don't bug me when\":
data SuppressWhen = Visible -- ^ the window is currently visible
| OnScreen -- ^ the window is on the currently focused physical screen
| Focused -- ^ the window is currently focused
| Never -- ^ ... aww, heck, go ahead and bug me, just in case.
deriving (Read, Show)
-- | A set of choices as to when you want to be re-notified of an urgent
-- window. Perhaps you focused on something and you miss the dzen popup bar. Or
-- you're AFK. Or you feel the need to be more distracted. I don't care.
--
-- The interval arguments are in seconds. See the 'minutes' helper.
data RemindWhen = Dont -- ^ triggering once is enough
| Repeatedly Int Interval -- ^ repeat <arg1> times every <arg2> seconds
| Every Interval -- ^ repeat every <arg1> until the urgency hint is cleared
deriving (Read, Show)
-- | A prettified way of multiplying by 60. Use like: @(5 `minutes`)@.
minutes :: Rational -> Rational
minutes secs = secs * 60
-- | The default 'UrgencyConfig'. suppressWhen = Visible, remindWhen = Dont.
-- Use a variation of this in your config just as you use a variation of
-- defaultConfig for your xmonad definition.
urgencyConfig :: UrgencyConfig
urgencyConfig = UrgencyConfig { suppressWhen = Visible, remindWhen = Dont }
-- | Focuses the most recently urgent window. Good for what ails ya -- I mean, your keybindings.
-- Example keybinding:
--
-- > , ((modMask , xK_BackSpace), focusUrgent)
focusUrgent :: X ()
focusUrgent = withUrgents $ flip whenJust (windows . W.focusWindow) . listToMaybe
-- | Just makes the urgents go away.
-- Example keybinding:
--
-- > , ((modMask .|. shiftMask, xK_BackSpace), clearUrgents)
clearUrgents :: X ()
clearUrgents = adjustUrgents (const []) >> adjustReminders (const [])
-- | Stores the global set of all urgent windows, across workspaces. Not exported -- use
-- 'readUrgents' or 'withUrgents' instead.
{-# NOINLINE urgents #-}
urgents :: IORef [Window]
urgents = unsafePerformIO (newIORef [])
-- (Hey, I don't like it any more than you do.)
-- | X action that returns a list of currently urgent windows. You might use
-- it, or 'withUrgents', in your custom logHook, to display the workspaces that
-- contain urgent windows.
readUrgents :: X [Window]
readUrgents = io $ readIORef urgents
-- | An HOF version of 'readUrgents', for those who prefer that sort of thing.
withUrgents :: ([Window] -> X a) -> X a
withUrgents f = readUrgents >>= f
adjustUrgents :: ([Window] -> [Window]) -> X ()
adjustUrgents f = io $ modifyIORef urgents f
type Interval = Rational
-- | An urgency reminder, as reified for 'RemindWhen'.
-- The last value is the countdown number, for 'Repeatedly'.
data Reminder = Reminder { timer :: TimerId
, window :: Window
, interval :: Interval
, remaining :: Maybe Int
} deriving Eq
-- | Stores the list of urgency reminders.
{-# NOINLINE reminders #-}
reminders :: IORef [Reminder]
reminders = unsafePerformIO (newIORef [])
readReminders :: X [Reminder]
readReminders = io $ readIORef reminders
adjustReminders :: ([Reminder] -> [Reminder]) -> X ()
adjustReminders f = io $ modifyIORef reminders f
clearUrgency :: Window -> X ()
clearUrgency w = adjustUrgents (delete w) >> adjustReminders (filter $ (w /=) . window)
data WithUrgencyHook h = WithUrgencyHook h UrgencyConfig
deriving (Read, Show)
-- The Non-ICCCM Manifesto:
-- Note: Some non-standard choices have been made in this implementation to
-- account for the fact that things are different in a tiling window manager:
-- 1. In normal window managers, windows may overlap, so clients wait for focus to
-- be set before urgency is cleared. In a tiling WM, it's sufficient to be able
-- see the window, since we know that means you can see it completely.
-- 2. The urgentOnBell setting in rxvt-unicode sets urgency even when the window
-- has focus, and won't clear until it loses and regains focus. This is stupid.
-- In order to account for these quirks, we track the list of urgent windows
-- ourselves, allowing us to clear urgency when a window is visible, and not to
-- set urgency if a window is visible. If you have a better idea, please, let us
-- know!
instance UrgencyHook h => EventHook (WithUrgencyHook h) where
handleEvent wuh event = case event of
PropertyEvent { ev_event_type = t, ev_atom = a, ev_window = w } -> do
when (t == propertyNotify && a == wM_HINTS) $ withDisplay $ \dpy -> do
WMHints { wmh_flags = flags } <- io $ getWMHints dpy w
if (testBit flags urgencyHintBit) then do
adjustUrgents (\ws -> if elem w ws then ws else w : ws)
callUrgencyHook wuh w
else
clearUrgency w
userCodeDef () =<< asks (logHook . config) -- call *after* IORef has been modified
DestroyWindowEvent {ev_window = w} ->
clearUrgency w
_ ->
mapM_ handleReminder =<< readReminders
where handleReminder reminder = handleTimer (timer reminder) event $ reminderHook wuh reminder
callUrgencyHook :: UrgencyHook h => WithUrgencyHook h -> Window -> X ()
callUrgencyHook (WithUrgencyHook hook UrgencyConfig { suppressWhen = sw, remindWhen = rw }) w =
whenX (not <$> shouldSuppress sw w) $ do
userCodeDef () $ urgencyHook hook w
case rw of
Repeatedly times int -> addReminder w int $ Just times
Every int -> addReminder w int Nothing
Dont -> return ()
addReminder :: Window -> Rational -> Maybe Int -> X ()
addReminder w int times = do
timerId <- startTimer int
let reminder = Reminder timerId w int times
adjustReminders (\rs -> if w `elem` map window rs then rs else reminder : rs)
reminderHook :: UrgencyHook h => WithUrgencyHook h -> Reminder -> X (Maybe a)
reminderHook (WithUrgencyHook hook _) reminder = do
case remaining reminder of
Just x | x > 0 -> remind $ Just (x - 1)
Just _ -> adjustReminders $ delete reminder
Nothing -> remind Nothing
return Nothing
where remind remaining' = do userCode $ urgencyHook hook (window reminder)
adjustReminders $ delete reminder
addReminder (window reminder) (interval reminder) remaining'
shouldSuppress :: SuppressWhen -> Window -> X Bool
shouldSuppress sw w = elem w <$> suppressibleWindows sw
cleanupUrgents :: SuppressWhen -> X ()
cleanupUrgents sw = mapM_ clearUrgency =<< suppressibleWindows sw
suppressibleWindows :: SuppressWhen -> X [Window]
suppressibleWindows Visible = gets $ S.toList . mapped
suppressibleWindows OnScreen = gets $ W.index . windowset
suppressibleWindows Focused = gets $ maybeToList . W.peek . windowset
suppressibleWindows Never = return []
--------------------------------------------------------------------------------
-- Urgency Hooks
-- | The class definition, and some pre-defined instances.
class (Read h, Show h) => UrgencyHook h where
urgencyHook :: h -> Window -> X ()
data NoUrgencyHook = NoUrgencyHook deriving (Read, Show)
instance UrgencyHook NoUrgencyHook where
urgencyHook _ _ = return ()
-- | Your set of options for configuring a dzenUrgencyHook.
data DzenUrgencyHook = DzenUrgencyHook {
duration :: Int, -- ^ number of microseconds to display the dzen
-- (hence, you'll probably want to use 'seconds')
args :: [String] -- ^ list of extra args (as 'String's) to pass to dzen
}
deriving (Read, Show)
instance UrgencyHook DzenUrgencyHook where
urgencyHook DzenUrgencyHook { duration = d, args = a } w = do
name <- getName w
ws <- gets windowset
whenJust (W.findTag w ws) (flash name)
where flash name index =
dzenWithArgs (show name ++ " requests your attention on workspace " ++ index) a d
{- | A hook which will automatically send you to anything which sets the urgent
flag (as opposed to printing some sort of message. You would use this as
usual, eg.
> withUrgencyHook FocusHook $ myconfig { ...
-}
data FocusHook = FocusHook deriving (Read, Show)
instance UrgencyHook FocusHook where
urgencyHook _ _ = focusUrgent
-- | Flashes when a window requests your attention and you can't see it.
-- Defaults to a duration of five seconds, and no extra args to dzen.
-- See 'DzenUrgencyHook'.
dzenUrgencyHook :: DzenUrgencyHook
dzenUrgencyHook = DzenUrgencyHook { duration = seconds 5, args = [] }
-- | Spawn a commandline thing, appending the window id to the prefix string
-- you provide. (Make sure to add a space if you need it.) Do your crazy
-- xcompmgr thing.
newtype SpawnUrgencyHook = SpawnUrgencyHook String deriving (Read, Show)
instance UrgencyHook SpawnUrgencyHook where
urgencyHook (SpawnUrgencyHook prefix) w = spawn $ prefix ++ show w
-- | For debugging purposes, really.
data StdoutUrgencyHook = StdoutUrgencyHook deriving (Read, Show)
instance UrgencyHook StdoutUrgencyHook where
urgencyHook _ w = io $ putStrLn $ "Urgent: " ++ show w

View File

@@ -1,6 +1,6 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.XPropManage
-- Module : XMonad.Hooks.XPropManage
-- Copyright : (c) Karsten Schoelzel <kuser@gmx.de>
-- License : BSD
--
@@ -11,7 +11,7 @@
-- A ManageHook matching on XProperties.
-----------------------------------------------------------------------------
module XMonadContrib.XPropManage (
module XMonad.Hooks.XPropManage (
-- * Usage
-- $usage
xPropManageHook, XPropMatch, pmX, pmP
@@ -19,23 +19,25 @@ module XMonadContrib.XPropManage (
import Data.Char (chr)
import Data.List (concat)
import Data.Monoid (mconcat, Endo(..))
import Control.Monad.State
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
import Control.Monad.Trans (lift)
import XMonad
import XMonad.ManageHook ((-->))
-- $usage
--
-- Add something like the following lines to Config.hs to use this module
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Hooks.XPropManage
-- > import qualified XMonad.StackSet as W
-- > import XMonad.Actions.TagWindows
-- > import Data.List
--
-- > import XMonadContrib.XPropManage
--
-- > manageHook = xPropManageHook xPropMatches
-- >
-- > xPropMatches :: [XPropMatch]
-- > xPropMatches = [ ([ (wM_CLASS, any ("gimp"==)))], (\w -> float w >> return (W.shift "2")))
-- > xPropMatches = [ ([ (wM_CLASS, any ("gimp"==))], (\w -> float w >> return (W.shift "2")))
-- > , ([ (wM_COMMAND, any ("screen" ==)), (wM_CLASS, any ("xterm" ==))], pmX (addTag "screen"))
-- > , ([ (wM_NAME, any ("Iceweasel" `isInfixOf`))], pmP (W.shift "3"))
-- > ]
@@ -64,17 +66,12 @@ pmX f w = f w >> return id
pmP :: (WindowSet -> WindowSet) -> Window -> X (WindowSet -> WindowSet)
pmP f _ = return f
xPropManageHook :: [XPropMatch] -> Window -> X (WindowSet -> WindowSet)
xPropManageHook tms w = withDisplay $ \d -> do
fs <- mapM (matchProp d w `uncurry`) tms
return (foldr (.) id fs)
matchProp :: Display -> Window -> [(Atom, [String] -> Bool)] -> (Window -> X (WindowSet -> WindowSet)) -> X (WindowSet -> WindowSet)
matchProp d w tm tf = do
m <- and `liftM` sequence (map (\(k,f) -> f `liftM` getProp d w k) tm)
case m of
True -> tf w
False -> return id
xPropManageHook :: [XPropMatch] -> ManageHook
xPropManageHook tms = mconcat $ map propToHook tms
where
propToHook (ms, f) = fmap and (mapM mkQuery ms) --> mkHook f
mkQuery (a, tf) = fmap tf (getQuery a)
mkHook func = ask >>= Query . lift . fmap Endo . func
getProp :: Display -> Window -> Atom -> X ([String])
getProp d w p = do
@@ -83,9 +80,11 @@ getProp d w p = do
| otherwise = id
return (filt p prop)
getQuery :: Atom -> Query [String]
getQuery p = ask >>= \w -> Query . lift $ withDisplay $ \d -> getProp d w p
splitAtNull :: String -> [String]
splitAtNull s = case dropWhile (== (chr 0)) s of
"" -> []
s' -> w : splitAtNull s''
where (w, s'') = break (== (chr 0)) s'

View File

@@ -2,7 +2,7 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Accordion
-- Module : XMonad.Layout.Accordion
-- Copyright : (c) glasser@mit.edu
-- License : BSD
--
@@ -14,23 +14,28 @@
-- of the screen.
-----------------------------------------------------------------------------
module XMonadContrib.Accordion (
module XMonad.Layout.Accordion (
-- * Usage
-- $usage
Accordion(Accordion)) where
import XMonad
import Operations
import qualified StackSet as W
import Graphics.X11.Xlib
import qualified XMonad.StackSet as W
import Data.Ratio
-- $usage
-- > import XMonadContrib.Accordion
-- > layouts = [ Layout Accordion ]
-- %import XMonadContrib.Accordion
-- %layout , Layout Accordion
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Layout.Accordion
--
-- Then edit your @layoutHook@ by adding the Accordion layout:
--
-- > myLayouts = Accordion ||| Full ||| etc..
-- > main = xmonad defaultConfig { layoutHook = myLayouts }
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
data Accordion a = Accordion deriving ( Read, Show )

View File

@@ -0,0 +1,67 @@
{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Layout.BoringWindows
-- Copyright : (c) 2008 David Roundy <droundy@darcs.net>
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : none
-- Stability : unstable
-- Portability : unportable
--
-- BoringWindows is an extension to allow windows to be marked boring
--
-----------------------------------------------------------------------------
module XMonad.Layout.BoringWindows (
-- * Usage
-- $usage
boringWindows,
markBoring, clearBoring,
focusUp, focusDown
) where
import XMonad hiding (Point)
import qualified XMonad.StackSet as W
import XMonad.Layout.LayoutModifier
import XMonad.Util.Invisible
data BoringMessage = FocusUp | FocusDown | IsBoring Window | ClearBoring
deriving ( Read, Show, Typeable )
instance Message BoringMessage
markBoring, clearBoring, focusUp, focusDown :: X ()
markBoring = withFocused (sendMessage . IsBoring)
clearBoring = sendMessage ClearBoring
focusUp = sendMessage FocusUp
focusDown = sendMessage FocusDown
data BoringWindows a = BoringWindows (Invisible [] a) deriving ( Show, Read, Typeable )
boringWindows :: (LayoutClass l a, Eq a) => l a -> ModifiedLayout BoringWindows l a
boringWindows = ModifiedLayout (BoringWindows (I []))
instance LayoutModifier BoringWindows Window where
handleMessOrMaybeModifyIt (BoringWindows (I bs)) m
| Just (IsBoring b) <- fromMessage m = return $ Just $ Left $ BoringWindows (I (b:bs))
| Just ClearBoring <- fromMessage m = return $ Just $ Left $ BoringWindows (I [])
| Just FocusUp <- fromMessage m = do windows $ W.modify' $ focusUp'
return Nothing
| Just FocusDown <- fromMessage m =
do windows $ W.modify' (reverseStack . focusUp' . reverseStack)
return Nothing
where focusUp' (W.Stack t ls rs)
| (a,l:ls') <- skipBoring ls = W.Stack l ls' (a++t:rs)
| otherwise = case skipBoring (reverse (t:rs)++ls) of
(a,x:xs) -> W.Stack x xs a
_ -> W.Stack t ls rs
skipBoring [] = ([],[])
skipBoring (x:xs) | x `elem` bs = case skipBoring xs of
(a,b) -> (x:a,b)
| otherwise = ([],x:xs)
handleMessOrMaybeModifyIt _ _ = return Nothing
-- | reverse a stack: up becomes down and down becomes up.
reverseStack :: W.Stack a -> W.Stack a
reverseStack (W.Stack t ls rs) = W.Stack t rs ls

View File

@@ -0,0 +1,110 @@
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Layout.CenteredMaster
-- Copyright : (c) 2009 Ilya Portnov
-- License : GNU GPL v3 or any later
--
-- Maintainer : Ilya Portnov <portnov84@rambler.ru>
-- Stability : unstable
-- Portability : unportable
--
-- Two layout modifiers. centerMaster places master window at center,
-- on top of all other windows, which are managed by base layout.
-- topRightMaster is similar, but places master window in top right corner
-- instead of center.
--
-----------------------------------------------------------------------------
module XMonad.Layout.CenteredMaster (
-- * Usage
-- $usage
centerMaster,
topRightMaster
) where
import XMonad
import XMonad.Layout.LayoutModifier
import qualified XMonad.StackSet as W
-- $usage
-- This module defines two new layout modifiers: centerMaster and topRightMaster.
-- centerMaster places master window at center of screen, on top of others.
-- All other windows in background are managed by base layout.
-- topRightMaster is like centerMaster, but places master window in top right corner instead of center.
--
-- Yo can use this module by adding folowing in your @xmonad.hs@:
--
-- > import XMonad.Layout.CenteredMaster
--
-- Then add layouts to your layoutHook:
--
-- > myLayoutHook = centerMaster Grid ||| ...
-- | Function that decides where master window should be placed
type Positioner = Rectangle -> Rectangle
-- | Data type for LayoutModifier
data CenteredMaster a = CenteredMaster deriving (Read,Show)
instance LayoutModifier CenteredMaster Window where
modifyLayout CenteredMaster = applyPosition (center (5/7) (5/7))
data TopRightMaster a = TopRightMaster deriving (Read,Show)
instance LayoutModifier TopRightMaster Window where
modifyLayout TopRightMaster = applyPosition (topRight (3/7) (1/2))
-- | Modifier that puts master window in center, other windows in background
-- are managed by given layout
centerMaster :: LayoutClass l a => l a -> ModifiedLayout CenteredMaster l a
centerMaster = ModifiedLayout CenteredMaster
-- | Modifier that puts master window in top right corner, other windows in background
-- are managed by given layout
topRightMaster :: LayoutClass l a => l a -> ModifiedLayout TopRightMaster l a
topRightMaster = ModifiedLayout TopRightMaster
-- | Internal function, doing main job
applyPosition :: (LayoutClass l a, Eq a) =>
Positioner
-> W.Workspace WorkspaceId (l a) a
-> Rectangle
-> X ([(a, Rectangle)], Maybe (l a))
applyPosition pos wksp rect = do
let stack = W.stack wksp
let ws = W.integrate' $ stack
if null ws then
runLayout wksp rect
else do
let first = head ws
let other = tail ws
let filtStack = stack >>= W.filter (first /=)
wrs <- runLayout (wksp {W.stack = filtStack}) rect
return ((first, place pos other rect) : fst wrs, snd wrs)
-- | Place master window (it's Rectangle is given), using the given Positioner.
-- If second argument is empty (that is, there is only one window on workspace),
-- place that window fullscreen.
place :: Positioner -> [a] -> Rectangle -> Rectangle
place _ [] rect = rect
place pos _ rect = pos rect
-- | Function that calculates Rectangle at top right corner of given Rectangle
topRight :: Float -> Float -> Rectangle -> Rectangle
topRight rx ry (Rectangle sx sy sw sh) = Rectangle x sy w h
where w = round (fromIntegral sw * rx)
h = round (fromIntegral sh * ry)
x = sx + fromIntegral (sw-w)
-- | Function that calculates Rectangle at center of given Rectangle.
center :: Float -> Float -> Rectangle -> Rectangle
center rx ry (Rectangle sx sy sw sh) = Rectangle x y w h
where w = round (fromIntegral sw * rx)
h = round (fromIntegral sh * ry)
x = sx + fromIntegral (sw-w) `div` 2
y = sy + fromIntegral (sh-h) `div` 2

View File

@@ -2,7 +2,7 @@
-----------------------------------------------------------------------------
-- |
-- Module : XMonadContrib.Circle
-- Module : XMonad.Layout.Circle
-- Copyright : (c) Peter De Wachter
-- License : BSD-style (see LICENSE)
--
@@ -14,24 +14,29 @@
--
-----------------------------------------------------------------------------
module XMonadContrib.Circle (
module XMonad.Layout.Circle (
-- * Usage
-- $usage
Circle (..)
) where -- actually it's an ellipse
import Data.List
import Graphics.X11.Xlib
import XMonad
import StackSet (integrate, peek)
import XMonad.StackSet (integrate, peek)
-- $usage
-- You can use this module with the following in your Config.hs file:
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonadContrib.Circle
-- > layouts = [ Layout Circle ]
-- %import XMonadContrib.Circle
-- > import XMonad.Layout.Circle
--
-- Then edit your @layoutHook@ by adding the Circle layout:
--
-- > myLayouts = Circle ||| Full ||| etc..
-- > main = xmonad defaultConfig { layoutHook = myLayouts }
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
data Circle a = Circle deriving ( Read, Show )

Some files were not shown because too many files have changed in this diff Show More