92 Commits
v0.15 ... v0.16

Author SHA1 Message Date
Peter Simons
60101b9a70 Bump version number to 0.16 for the upcoming release. 2019-09-22 10:33:26 +02:00
Peter Simons
5f1fc602ab CHANGES.md: document changes from 303f0c24bc 2019-09-22 10:11:10 +02:00
Peter Simons
303f0c24bc cabal.project: the new setlocale version works fine 2019-09-22 10:02:29 +02:00
Peter Simons
8df80e7805 travis.yml: re-generate with the latest version of haskell-ci 2019-09-21 21:10:12 +02:00
Peter Simons
36dba39c44 cabal.project: don't hard-code paths to ../xmonad and ../x11
Not everyone has those repositories checked out at those paths. IMHO, it would
be much better to configure these as "optional-packages". In any case, users
should probably configure those in their cabal.project.local.
2019-09-21 21:07:56 +02:00
Peter Simons
8847b3b2f6 cabal.project: configure allower-newer for setlocale
This allows us to compile with GHC 8.8.1.
2019-09-21 21:03:13 +02:00
Peter Simons
1b061245af xmonad-contrib.cabal: update our tested-with declaration 2019-09-21 21:03:13 +02:00
Peter Simons
94662bffc6 XMonad.Util.Invisible: fix build with GHC 8.8.1
This change needs base-4.9.0.0 or later so that we can
include Control.Monad.Fail. We could jump through hoops to
support older compilers still, but it feels like it's not
worthwhile.
2019-09-21 21:03:13 +02:00
Brent Yorgey
23102a6d5c Merge pull request #289 from berkeleyinc/improved-left-right-tabbed
Improved tabbedRight and tabbedLeft in XMonad.Layout.Tabbed
2019-09-16 16:47:28 -05:00
Brent Yorgey
728f9bc270 Merge pull request #299 from pkinsky/master
Add configurable border width fields to XMonad.Layout.Decoration.Theme
2019-08-12 08:32:22 -05:00
Brent Yorgey
d9856b955a Merge pull request #303 from obszczymucha/master
Add SplitShiftDirectional message into BinarySpacePartition layout.
2019-08-12 07:22:52 -05:00
Brent Yorgey
603fc4ccb7 Merge branch 'master' into master 2019-08-12 07:22:39 -05:00
Brent Yorgey
65e7153874 Merge pull request #309 from ryantrinkle/pass-generate-and-copy
Add XMonad.Prompt.Pass.passGenerateAndCopy
2019-08-10 16:45:14 -05:00
Ryan Trinkle
6a0dc1685c Add XMonad.Prompt.Pass.passGenerateAndCopy 2019-08-10 10:25:34 -04:00
Brent Yorgey
41e8708eb5 Merge pull request #308 from kurnevsky/fuzzy-sort
Make fuzzy sort show shorter strings first
2019-08-08 21:45:23 -05:00
Evgeny Kurnevsky
18979de5f6 Make fuzzy sort show shorter strings first. 2019-08-08 09:12:48 +03:00
Brent Yorgey
5ffb4e7f52 Merge pull request #307 from ryantrinkle/pass-traverse-symlinks
Make XMonad.Prompt.Pass traverse symlinks for its tab completion
2019-08-07 22:22:27 -05:00
Ryan Trinkle
52a3800b96 Make XMonad.Prompt.Pass traverse symlinks for its tab completion 2019-08-07 13:09:40 -04:00
Brent Yorgey
dd89eae446 Merge pull request #300 from roosemberth/refocuslast
RefocusLast Module
2019-05-26 20:32:30 -05:00
Obszczymucha
6b68ec5c00 Add SplitShiftDirectional message into BinarySpacePartition layout. 2019-05-26 16:01:06 +10:00
Sibi
db80842e65 Merge pull request #301 from h-jones-uk/master
Fix broken internal Haddock links
2019-05-08 21:04:13 +05:30
Henri Jones
4e4856c722 Fix broken internal Haddock links 2019-05-07 22:32:05 +01:00
Roosembert Palacios
b5eb418fa4 cabal: Export module XMonad.Hooks.RefocusLast
Signed-off-by: Roosembert Palacios <roosembert.palacios@epfl.ch>
2019-05-01 23:53:38 +02:00
L. S. Leary
04b32ae021 X.H.RefocusLast: added action to swap current window with last + minor refactoring. 2019-05-01 23:53:07 +02:00
L. S. Leary
9c6d1e696f X.H.RefocusLast: added runtime toggle and refactored predicate system. 2019-05-01 16:56:44 +02:00
L. S. Leary
dad911913c RefocusLast bug fix, extension to support float-only refocusing and
improved support for refocusing on non-current workspaces.
2019-05-01 16:56:39 +02:00
Paul Kinsky
b3f5a09673 record changes 2019-04-17 16:40:48 -07:00
Brent Yorgey
4ad6ecf892 Merge pull request #297 from ajgrf/bg-ratio
Hooks.WallpaperSetter: Preserve aspect ratio while scaling images
2019-04-10 22:07:22 -05:00
Brent Yorgey
fcd296e87a Merge branch 'master' into bg-ratio 2019-04-10 22:07:06 -05:00
Brent Yorgey
fddd5ea1fe Merge pull request #298 from orhan89/pass-otp
Support OTP in XMonad.Prompt.Pass
2019-04-05 04:44:09 -05:00
Ricky Hariady
c3cee11ad6 Support OTP in XMonad.Prompt.Pass
update CHANGES.md
2019-04-05 09:31:49 +07:00
Brent Yorgey
22e6d4b017 Merge pull request #296 from ajgrf/adwaita-theme
XMonad.Util.Themes: Add adwaitaTheme and adwaitaDarkTheme
2019-04-02 05:50:26 -05:00
Alex Griffin
fcced8991a Hooks.WallpaperSetter: Preserve aspect ratio while scaling images 2019-03-18 16:32:35 -05:00
Alex Griffin
bfb52a5025 XMonad.Util.Themes: Add adwaitaTheme and adwaitaDarkTheme 2019-03-13 14:48:10 -05:00
Brent Yorgey
c53436f3a6 Merge pull request #178 from bforte/module-MutexScratchpads
add new module X.U.ExclusiveScratchpads
2019-03-06 15:14:51 -06:00
Brent Yorgey
66c1977c29 Merge branch 'master' into module-MutexScratchpads 2019-03-06 15:14:27 -06:00
Brent Yorgey
a18395a13c Merge pull request #295 from alhirzel/add-isOnAnyVisibleWS
Actions.GroupNavigation: fix bad import
2019-03-03 21:15:56 -06:00
Alex Hirzel
ca69574cfe Actions.GroupNavigation: add CMS import 2019-03-03 10:59:58 -05:00
Alex Hirzel
faa252e309 Actions.GroupNavigation: another import issue 2019-03-03 10:20:22 -05:00
Alex Hirzel
71fec4f61a Actions.GroupNavigation: fix bad import 2019-03-03 10:08:25 -05:00
Brent Yorgey
0301d6e21b Merge pull request #294 from alhirzel/add-isOnAnyVisibleWS
Add isOnAnyVisibleWS function to Actions.GroupNavigation
2019-03-03 08:57:04 -06:00
Alex Hirzel
0cfe3a288e whitespace reformat in changelog 2019-03-02 09:36:47 -05:00
Alex Hirzel
84c63abda6 Add changelog entry for isOnAnyVisibleWS 2019-03-02 09:36:36 -05:00
Alex Hirzel
e12511c658 Actions.GroupNavigation: move "Utilities" header for documentation 2019-03-02 09:32:16 -05:00
Alex Hirzel
52890f6007 Actions.GroupNavigation: document isOnAnyVisibleWS 2019-02-27 23:08:07 -05:00
Alex Hirzel
51bc32ea75 Actions.GroupNavigation: add isOnAnyVisibleWS 2019-02-27 23:08:07 -05:00
Alex Hirzel
cce7f50372 Actions.GroupNavigation: hlint fixes 2019-02-27 23:08:04 -05:00
Brent Yorgey
ba9b108a68 Merge pull request #263 from bgamari/ewmh-wakeup-reduction
Wakeup reduction in EwmhDesktops
2019-02-27 21:21:37 -06:00
Brent Yorgey
e12c047870 move change from #284 to the right place 2019-02-13 05:54:03 -06:00
Brent Yorgey
2ce876c330 Merge pull request #284 from skewerr/master
X.A.DynamicWorkspaceOrder: add transformation-aware withNthWorkspace
2019-02-13 05:49:42 -06:00
Brent Yorgey
3faa9b2c38 Merge pull request #292 from wz1000/master
Use absolute paths in DynamicProjects
2019-02-13 05:40:18 -06:00
Zubin Duggal
6720eefce7 update CHANGES.md 2019-02-13 16:19:01 +05:30
Zubin Duggal
cf789504e8 Use absolute paths in DynamicProjects 2019-02-13 16:06:10 +05:30
Brent Yorgey
deaaf6b177 Merge pull request #287 from mgsloan/bracket-prompt-resources
Use bracket pattern in XMonad.Prompt
2019-02-12 09:14:02 -06:00
Brent Yorgey
60b35ff431 Merge branch 'master' into bracket-prompt-resources 2019-02-12 09:13:51 -06:00
Brent Yorgey
cd404eb644 Merge pull request #291 from mgsloan/fix-prompt-max-rows-wrap-around-217
Fix XMonad.Prompt wraparound when maxComplRows not Nothing #217
2019-02-12 09:08:23 -06:00
Michael Sloan
d9f43c78d6 Fix XMonad.Prompt wraparound when maxComplRows not Nothing #217 2019-02-10 04:47:16 -08:00
Michael Sloan
b9603a0e10 Also destroy completion window on exceptions #180 2019-02-10 04:18:56 -08:00
Michael Sloan
09a5fa111c Use bracket pattern in XMonad.Prompt 2019-02-10 04:18:30 -08:00
Michael Sloan
41a2db5563 Refactoring: helper for mkXPromptWithReturn and mkXPromptWithModes 2019-02-10 03:51:40 -08:00
Yclept Nemo
1706160b14 Merge pull request #245 from orbisvicis/vimishPrompt
Vimish Prompt
2019-01-26 16:23:49 -05:00
Yclept Nemo
207d5962e2 Vim for 'XMonad.Prompt': backwards compatibility
Colors in 'XPState' continue to use 'XPColor' since it provides a
cleaner interface. For backwards compatibility color changes to
'XPConfig' were reverted. To avoid accessor clashes you'll have to deal
with slightly different names:

| 'XPState'/'XPColor' | 'XPConfig'  |
| ------------------- | ----------- |
| bgNormal            | bgColor     |
| fgNormal            | fgColor     |
| bgHighlight         | bgHLight    |
| fgHighlight         | fgHLight    |
| border              | borderColor |
2019-01-26 15:18:27 -05:00
Yclept Nemo
c7e02726bf Vim for 'XMonad.Prompt': advertise changes 2019-01-26 15:03:18 -05:00
Yclept Nemo
b0d6e0f942 Vim for 'XMonad.Prompt':
A vim-like keymap, yay! And dynamic colors and a reworked event loop.
Also fixes 'showCompletionOnTab' which was broken, and many new or
improved prompt interface functions.

Changes moveWord/moveWord' but updates the old keymaps to retain the
original behavior. See the documentation to do the same to your XMonad
configuration.

P.S. That bug I mention was there before my changes.
2019-01-26 14:49:52 -05:00
Brent Yorgey
a774168415 Merge pull request #264 from namo626/module/TwoPanePersistent
Added module X.L.TwoPanePersistent
2019-01-22 11:15:36 -06:00
Brent Yorgey
17da8bc8ee Merge pull request #259 from u11gh/passEditPrompt
Add passEditPrompt to Xmonad.Prompt.Pass
2019-01-21 16:49:38 -06:00
Brent Yorgey
c2c0585d7e Merge branch 'master' into module/TwoPanePersistent 2019-01-21 11:03:26 -06:00
yuri
7a6d24712f Merge branch 'improved-left-right-tabbed' of github.com:berkeleyinc/xmonad-contrib into improved-left-right-tabbed 2019-01-09 07:42:58 +01:00
yuri
13260cae58 Merge branch 'improved-left-right-tabbed' of github.com:berkeleyinc/xmonad-contrib into improved-left-right-tabbed 2019-01-09 07:42:46 +01:00
yuri
07f4ce8029 Merge branch 'improved-left-right-tabbed' of github.com:berkeleyinc/xmonad-contrib into improved-left-right-tabbed 2019-01-09 07:41:49 +01:00
yuri
298cdd6114 improving tabbedRight/tabbedLeft by having their tabs' height set by decoHeight 2019-01-09 07:41:10 +01:00
yuri
36356dd8f5 improving tabbedRight/tabbedLeft by having their tabs' height set by decoHeight 2019-01-09 07:37:03 +01:00
Wilson Sales
dd905d2603 X.A.DynamicWorkspaceOrder: add transformation-aware withNthWorkspace
The user may modify the list of workspace tags that results form
applying the dynamic order. This way one may filter workspaces they
don't want in the order (e.g. "NSP") or apply any transformation he
wishes to the list of tags.
2018-11-08 19:02:59 -02:00
L. S. Leary
dda242a459 Relocate change in CHANGES.md. 2018-10-18 05:49:30 +13:00
Leary
204524328d Merge pull request #282 from anthraxx/fixup/prompt-fuzzymatch
XMonad.Prompt sorter for FuzzyMatch
2018-10-18 05:36:51 +13:00
anthraxx
6dcc36c904 XMonad.Prompt.FuzzyMatch: favor modern windowPrompt in docs
Use modern windowPrompt in docs instead of the deprecated
windowPromptGoto.
2018-09-25 22:16:06 +02:00
anthraxx
705494eb4c XMonad.Prompt.FuzzyMatch: fix missing docs code block 2018-09-25 22:16:06 +02:00
Sergey Alirzaev
6b9fb096d6 employ the prompt sorter for the window selector
as in https://markmail.org/thread/kgrybzqarqzqiige
2018-09-25 22:15:45 +02:00
namo626
913183463a added module X.L.TwoPanePersistent
updated CHANGES.md
2018-06-22 18:40:14 -04:00
Ben Gamari
92fe5f34ff EwmhDesktops: Cache properties independently 2018-06-19 12:39:24 -04:00
Ben Gamari
8c309f87b8 EwmhDesktops: Cache active window as well 2018-06-19 11:54:20 -04:00
Ben Gamari
f6f925c823 Use extensible state instead of IORef 2018-06-19 11:54:18 -04:00
Ben Gamari
203e63b055 EwmhDesktops: Only update properties when something changed 2018-06-19 10:03:20 -04:00
Ben Gamari
e814f748b5 EwmhDesktops: Cache property values to avoid needless property changes 2018-06-19 01:47:08 -04:00
Ulf Jasper
ed32ccd080 Add passEditPrompt to Xmonad.Prompt.Pass 2018-06-05 19:34:06 +02:00
bforte
2314dd628a reimplemented with X.A.Minimize 2017-05-10 00:57:49 +02:00
Bruce Forte
95cd118c9a forgot importing <$> 2017-05-07 14:15:49 +02:00
Bruce Forte
53481b2269 Update xmonad-contrib.cabal 2017-05-07 14:01:38 +02:00
Bruce Forte
c1c7c30532 renamed the module to X.U.ExclusiveScratchpads 2017-05-07 14:00:40 +02:00
Bruce Forte
617099badd Update CHANGES.md 2017-05-07 13:38:34 +02:00
Bruce Forte
b05f5f12cf import (<$>) because travis failed 2017-05-06 04:12:44 +02:00
bforte
270ca2da23 add new module X.U.MutexScratchpads 2017-05-06 00:37:28 +02:00
23 changed files with 2042 additions and 510 deletions

View File

@@ -1,99 +1,149 @@
# This file has been generated -- see https://github.com/hvr/multi-ghc-travis
# This Travis job script has been generated by a script via
#
# haskell-ci '-o' '.travis.yml' 'xmonad-contrib.cabal' '--apt' 'libxrandr-dev'
#
# For more information, see https://github.com/haskell-CI/haskell-ci
#
# version: 0.5.20190916
#
language: c
sudo: false
dist: xenial
git:
# whether to recursively clone submodules
submodules: false
cache:
directories:
- $HOME/.cabsnap
- $HOME/.cabal/packages
- $HOME/.cabal/store
before_cache:
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
- rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
# remove files that are regenerated by 'cabal update'
- rm -fv $CABALHOME/packages/hackage.haskell.org/00-index.*
- rm -fv $CABALHOME/packages/hackage.haskell.org/*.json
- rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.cache
- rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
- rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
- rm -rfv $CABALHOME/packages/head.hackage
matrix:
include:
- env: GHCVER=8.6.1 CABALVER=2.4
compiler: ": #GHC 8.6.1"
addons: { apt: { packages: [cabal-install-2.4, ghc-8.6.1, libxrandr-dev]
, sources: [hvr-ghc]
} }
- env: GHCVER=8.4.3 CABALVER=2.2
compiler: ": #GHC 8.4.3"
addons: { apt: { packages: [cabal-install-2.2, ghc-8.4.3, libxrandr-dev]
, sources: [hvr-ghc]
} }
- env: GHCVER=8.2.2 CABALVER=2.0
compiler: ": #GHC 8.2.2"
addons: { apt: { packages: [cabal-install-2.0, ghc-8.2.2, libxrandr-dev]
, sources: [hvr-ghc]
} }
- env: GHCVER=8.0.1 CABALVER=1.24
compiler: ": #GHC 8.0.1"
addons: { apt: { packages: [cabal-install-1.24, ghc-8.0.1, libxrandr-dev]
, sources: [hvr-ghc]
} }
- compiler: ghc-8.8.1
addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0","libxrandr-dev"]}}
- compiler: ghc-8.6.5
addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0","libxrandr-dev"]}}
- compiler: ghc-8.4.4
addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0","libxrandr-dev"]}}
- compiler: ghc-8.2.2
addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0","libxrandr-dev"]}}
- compiler: ghc-8.0.2
addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-3.0","libxrandr-dev"]}}
before_install:
- unset CC
- export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
- HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//')
- WITHCOMPILER="-w $HC"
- HADDOCK=$(echo "/opt/$CC/bin/haddock" | sed 's/-/\//')
- HCPKG="$HC-pkg"
- unset CC
- CABAL=/opt/ghc/bin/cabal
- CABALHOME=$HOME/.cabal
- export PATH="$CABALHOME/bin:$PATH"
- TOP=$(pwd)
- "HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')"
- echo $HCNUMVER
- CABAL="$CABAL -vnormal+nowrap+markoutput"
- set -o pipefail
- |
echo 'function blue(s) { printf "\033[0;34m" s "\033[0m " }' >> .colorful.awk
echo 'BEGIN { state = "output"; }' >> .colorful.awk
echo '/^-----BEGIN CABAL OUTPUT-----$/ { state = "cabal" }' >> .colorful.awk
echo '/^-----END CABAL OUTPUT-----$/ { state = "output" }' >> .colorful.awk
echo '!/^(-----BEGIN CABAL OUTPUT-----|-----END CABAL OUTPUT-----)/ {' >> .colorful.awk
echo ' if (state == "cabal") {' >> .colorful.awk
echo ' print blue($0)' >> .colorful.awk
echo ' } else {' >> .colorful.awk
echo ' print $0' >> .colorful.awk
echo ' }' >> .colorful.awk
echo '}' >> .colorful.awk
- cat .colorful.awk
- |
color_cabal_output () {
awk -f $TOP/.colorful.awk
}
- echo text | color_cabal_output
install:
- cabal --version
- echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
- if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
then
zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
$HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
fi
- travis_retry cabal update -v
# build xmonad from HEAD
- git clone https://github.com/xmonad/xmonad.git
- cabal install xmonad/
- sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
- cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt
- sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
# check whether current requested install-plan matches cached package-db snapshot
- if diff -u $HOME/.cabsnap/installplan.txt installplan.txt;
then
echo "cabal build-cache HIT";
rm -rfv .ghc;
cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;
else
echo "cabal build-cache MISS";
rm -rf $HOME/.cabsnap;
mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
fi
- cabal install --only-dependencies --enable-tests --enable-benchmarks;
# snapshot package-db on cache miss
- if [ ! -d $HOME/.cabsnap ];
then
echo "snapshotting package-db to build-cache";
mkdir $HOME/.cabsnap;
cp -a $HOME/.ghc $HOME/.cabsnap/ghc;
cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
fi
# Here starts the actual work to be performed for the package under test;
# any command which exits with a non-zero exit code causes the build to fail.
- ${CABAL} --version
- echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]"
- TEST=--enable-tests
- BENCH=--enable-benchmarks
- HEADHACKAGE=false
- rm -f $CABALHOME/config
- |
echo "verbose: normal +nowrap +markoutput" >> $CABALHOME/config
echo "remote-build-reporting: anonymous" >> $CABALHOME/config
echo "write-ghc-environment-files: always" >> $CABALHOME/config
echo "remote-repo-cache: $CABALHOME/packages" >> $CABALHOME/config
echo "logs-dir: $CABALHOME/logs" >> $CABALHOME/config
echo "world-file: $CABALHOME/world" >> $CABALHOME/config
echo "extra-prog-path: $CABALHOME/bin" >> $CABALHOME/config
echo "symlink-bindir: $CABALHOME/bin" >> $CABALHOME/config
echo "installdir: $CABALHOME/bin" >> $CABALHOME/config
echo "build-summary: $CABALHOME/logs/build.log" >> $CABALHOME/config
echo "store-dir: $CABALHOME/store" >> $CABALHOME/config
echo "install-dirs user" >> $CABALHOME/config
echo " prefix: $CABALHOME" >> $CABALHOME/config
echo "repository hackage.haskell.org" >> $CABALHOME/config
echo " url: http://hackage.haskell.org/" >> $CABALHOME/config
- |
echo "program-default-options" >> $CABALHOME/config
echo " ghc-options: $GHCJOBS +RTS -M6G -RTS" >> $CABALHOME/config
- cat $CABALHOME/config
- rm -fv cabal.project cabal.project.local cabal.project.freeze
- travis_retry ${CABAL} v2-update -v
# Generate cabal.project
- rm -rf cabal.project cabal.project.local cabal.project.freeze
- touch cabal.project
- |
echo "packages: ." >> cabal.project
- |
- "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(xmonad-contrib)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done"
- cat cabal.project || true
- cat cabal.project.local || true
- if [ -f "./configure.ac" ]; then (cd "." && autoreconf -i); fi
- ${CABAL} v2-freeze $WITHCOMPILER ${TEST} ${BENCH} | color_cabal_output
- "cat cabal.project.freeze | sed -E 's/^(constraints: *| *)//' | sed 's/any.//'"
- rm cabal.project.freeze
- ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} --dep -j2 all | color_cabal_output
- ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks --dep -j2 all | color_cabal_output
script:
- if [ -f configure.ac ]; then autoreconf -i; fi
- cabal configure --enable-tests --enable-benchmarks -v2 # -v2 provides useful information for debugging
- cabal build # this builds all libraries and executables (including tests/benchmarks)
- cabal test
# - cabal check # complains about -Werror even though it is
# hidden behind a manual flag with default false
- cabal sdist # tests that a source-distribution can be generated
# Check that the resulting source distribution can be built & installed.
# If there are no other `.tar.gz` files in `dist`, this can be even simpler:
# `cabal install --force-reinstalls dist/*-*.tar.gz`
- SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&
(cd dist && cabal install --force-reinstalls "$SRC_TGZ")
- DISTDIR=$(mktemp -d /tmp/dist-test.XXXX)
# Packaging...
- ${CABAL} v2-sdist all | color_cabal_output
# Unpacking...
- mv dist-newstyle/sdist/*.tar.gz ${DISTDIR}/
- cd ${DISTDIR} || false
- find . -maxdepth 1 -type f -name '*.tar.gz' -exec tar -xvf '{}' \;
- find . -maxdepth 1 -type f -name '*.tar.gz' -exec rm '{}' \;
- PKGDIR_xmonad_contrib="$(find . -maxdepth 1 -type d -regex '.*/xmonad-contrib-[0-9.]*')"
# Generate cabal.project
- rm -rf cabal.project cabal.project.local cabal.project.freeze
- touch cabal.project
- |
echo "packages: ${PKGDIR_xmonad_contrib}" >> cabal.project
- |
- "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(xmonad-contrib)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done"
- cat cabal.project || true
- cat cabal.project.local || true
# Building...
# this builds all libraries and executables (without tests/benchmarks)
- ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks all | color_cabal_output
# Building with tests and benchmarks...
# build & run tests, build benchmarks
- ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} all | color_cabal_output
# cabal check...
- (cd ${PKGDIR_xmonad_contrib} && ${CABAL} -vnormal check)
# haddock...
- ${CABAL} v2-haddock $WITHCOMPILER --with-haddock $HADDOCK ${TEST} ${BENCH} all | color_cabal_output
# Building without installed constraints for packages in global-db...
- rm -f cabal.project.local
- ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks all | color_cabal_output
# REGENDATA ["-o",".travis.yml","xmonad-contrib.cabal","--apt","libxrandr-dev"]
# EOF

View File

@@ -1,6 +1,117 @@
# Change Log / Release Notes
## unknown
## 0.16
### Breaking Changes
* `XMonad.Layout.Decoration`
- Added `Theme` record fields for controlling decoration border width for active/inactive/urgent windows.
* `XMonad.Prompt`
- Prompt ships a vim-like keymap, see `vimLikeXPKeymap` and
`vimLikeXPKeymap'`. A reworked event loop supports new vim-like prompt
actions.
- Prompt supports dynamic colors. Colors are now specified by the `XPColor`
type in `XPState` while `XPConfig` colors remain unchanged for backwards
compatibility.
- Fixes `showCompletionOnTab`.
- The behavior of `moveWord` and `moveWord'` has changed; brought in line
with the documentation and now internally consistent. The old keymaps
retain the original behavior; see the documentation to do the same your
XMonad configuration.
* `XMonad.Util.Invisble`
- Requires `MonadFail` for `Read` instance
### New Modules
* `XMonad.Layout.TwoPanePersistent`
A layout that is like TwoPane but keeps track of the slave window that is
currently beside the master. In TwoPane, the default behavior when the master
is focused is to display the next window in the stack on the slave pane. This
is a problem when a different slave window is selected without changing the stack
order.
* `XMonad.Util.ExclusiveScratchpads`
Named scratchpads that can be mutually exclusive: This new module extends the
idea of named scratchpads such that you can define "families of scratchpads"
that are exclusive on the same screen. It also allows to remove this
constraint of being mutually exclusive with another scratchpad.
### Bug Fixes and Minor Changes
* `XMonad.Layout.Tabbed`
tabbedLeft and tabbedRight will set their tabs' height and width according to decoHeight/decoWidth
* `XMonad.Prompt`
Added `sorter` to `XPConfig` used to sort the possible completions by how
well they match the search string (example: `XMonad.Prompt.FuzzyMatch`).
Fixes a potential bug where an error during prompt execution would
leave the window open and keep the keyboard grabbed. See issue
[#180](https://github.com/xmonad/xmonad-contrib/issues/180).
Fixes [issue #217](https://github.com/xmonad/xmonad-contrib/issues/217), where
using tab to wrap around the completion rows would fail when maxComplRows is
restricting the number of rows of output.
* `XMonad.Prompt.Pass`
Added 'passOTPPrompt' to support getting OTP type password. This require
pass-otp (https://github.com/tadfisher/pass-otp) has been setup in the running
machine.
Added 'passGenerateAndCopyPrompt', which both generates a new password and
copies it to the clipboard. These two actions are commonly desirable to
take together, e.g. when establishing a new account.
Made password prompts traverse symlinks when gathering password names for
autocomplete.
* `XMonad.Actions.DynamicProjects`
Make the input directory read from the prompt in `DynamicProjects`
absolute wrt the current directory.
Before this, the directory set by the prompt was treated like a relative
directory. This means that when you switch from a project with directory
`foo` into a project with directory `bar`, xmonad actually tries to `cd`
into `foo/bar`, instead of `~/bar` as expected.
* `XMonad.Actions.DynamicWorkspaceOrder`
Add a version of `withNthWorkspace` that takes a `[WorkspaceId] ->
[WorkspaceId]` transformation to apply over the list of workspace tags
resulting from the dynamic order.
* `XMonad.Actions.GroupNavigation`
Add a utility function `isOnAnyVisibleWS :: Query Bool` to allow easy
cycling between all windows on all visible workspaces.
* `XMonad.Hooks.WallpaperSetter`
Preserve the aspect ratio of wallpapers that xmonad sets. When previous
versions would distort images to fit the screen size, it will now find a
best fit by cropping instead.
* `XMonad.Util.Themes`
Add adwaitaTheme and adwaitaDarkTheme to match their respective
GTK themes.
* 'XMonad.Layout.BinarySpacePartition'
Add a new `SplitShiftDirectional` message that allows moving windows by
splitting its neighbours.
* `XMonad.Prompt.FuzzyMatch`
Make fuzzy sort show shorter strings first.
## 0.15
@@ -164,6 +275,12 @@
Provides a simple transformer for use with `XMonad.Layout.MultiToggle` to
dynamically toggle `XMonad.Layout.TabBarDecoration`.
* `XMonad.Hooks.RefocusLast`
Provides hooks and actions that keep track of recently focused windows on a
per workspace basis and automatically refocus the last window on loss of the
current (if appropriate as determined by user specified criteria).
* `XMonad.Layout.StateFull`
Provides `StateFull`: a stateful form of `Full` that does not misbehave when
@@ -349,6 +466,8 @@
- New function `passTypePrompt` which uses `xdotool` to type in a password
from the store, bypassing the clipboard.
- New function `passEditPrompt` for editing a password from the
store.
- Now handles password labels with spaces and special characters inside
them.

View File

@@ -50,7 +50,7 @@ import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe, isNothing)
import Data.Monoid ((<>))
import System.Directory (setCurrentDirectory, getHomeDirectory)
import System.Directory (setCurrentDirectory, getHomeDirectory, makeAbsolute)
import XMonad
import XMonad.Actions.DynamicWorkspaces
import XMonad.Prompt
@@ -182,7 +182,8 @@ instance XPrompt ProjectPrompt where
modifyProject (\p -> p { projectName = name })
modeAction (ProjectPrompt DirMode _) buf auto = do
let dir = if null auto then buf else auto
let dir' = if null auto then buf else auto
dir <- io $ makeAbsolute dir'
modifyProject (\p -> p { projectDirectory = dir })
--------------------------------------------------------------------------------

View File

@@ -30,6 +30,7 @@ module XMonad.Actions.DynamicWorkspaceOrder
, moveToGreedy
, shiftTo
, withNthWorkspace'
, withNthWorkspace
) where
@@ -183,13 +184,19 @@ moveToGreedy dir t = doTo dir t getSortByOrder (windows . W.greedyView)
shiftTo :: Direction1D -> WSType -> X ()
shiftTo dir t = doTo dir t getSortByOrder (windows . W.shift)
-- | Do something with the nth workspace in the dynamic order after
-- transforming it. The callback is given the workspace's tag as well
-- as the 'WindowSet' of the workspace itself.
withNthWorkspace' :: ([WorkspaceId] -> [WorkspaceId]) -> (String -> WindowSet -> WindowSet) -> Int -> X ()
withNthWorkspace' tr job wnum = do
sort <- getSortByOrder
ws <- gets (tr . map W.tag . sort . W.workspaces . windowset)
case drop wnum ws of
(w:_) -> windows $ job w
[] -> return ()
-- | Do something with the nth workspace in the dynamic order. The
-- callback is given the workspace's tag as well as the 'WindowSet'
-- of the workspace itself.
withNthWorkspace :: (String -> WindowSet -> WindowSet) -> Int -> X ()
withNthWorkspace job wnum = do
sort <- getSortByOrder
ws <- gets (map W.tag . sort . W.workspaces . windowset)
case drop wnum ws of
(w:_) -> windows $ job w
[] -> return ()
withNthWorkspace = withNthWorkspace' id

View File

@@ -16,7 +16,7 @@
-- query.
--
-- Also provides a method for jumping back to the most recently used
-- window in any given group.
-- window in any given group, and predefined groups.
--
----------------------------------------------------------------------
@@ -27,9 +27,14 @@ module XMonad.Actions.GroupNavigation ( -- * Usage
, nextMatchOrDo
, nextMatchWithThis
, historyHook
-- * Utilities
-- $utilities
, isOnAnyVisibleWS
) where
import Control.Monad.Reader
import Control.Monad.State
import Data.Foldable as Fold
import Data.Map as Map
import Data.Sequence as Seq
@@ -142,7 +147,7 @@ orderedWorkspaceList ss wsids = rotateTo isCurWS wspcs'
where
wspcs = SS.workspaces ss
wspcsMap = Fold.foldl' (\m ws -> Map.insert (SS.tag ws) ws m) Map.empty wspcs
wspcs' = fmap (\wsid -> wspcsMap ! wsid) wsids
wspcs' = fmap (wspcsMap !) wsids
isCurWS ws = SS.tag ws == SS.tag (SS.workspace $ SS.current ss)
--- History navigation, requires a layout modifier -------------------
@@ -167,7 +172,7 @@ updateHistory :: HistoryDB -> X HistoryDB
updateHistory (HistoryDB oldcur oldhist) = withWindowSet $ \ss -> do
let newcur = SS.peek ss
wins = Set.fromList $ SS.allWindows ss
newhist = flt (flip Set.member wins) (ins oldcur oldhist)
newhist = flt (`Set.member` wins) (ins oldcur oldhist)
return $ HistoryDB newcur (del newcur newhist)
where
ins x xs = maybe xs (<| xs) x
@@ -216,3 +221,22 @@ findM cond xs = findM' cond (viewl xs)
if isMatch
then return (Just x')
else findM qry xs'
-- $utilities
-- #utilities#
-- Below are handy queries for use with 'nextMatch', 'nextMatchOrDo',
-- and 'nextMatchWithThis'.
-- | A query that matches all windows on visible workspaces. This is
-- useful for configurations with multiple screens, and matches even
-- invisible windows.
isOnAnyVisibleWS :: Query Bool
isOnAnyVisibleWS = do
w <- ask
ws <- liftX $ gets windowset
let allVisible = concat $ maybe [] SS.integrate . SS.stack . SS.workspace <$> SS.current ws:SS.visible ws
visibleWs = w `elem` allVisible
unfocused = maybe True (w /=) $ SS.peek ws
return $ visibleWs && unfocused

View File

@@ -467,7 +467,7 @@ Here is a list of the modules found in @XMonad.Hooks@:
* "XMonad.Hooks.DebugStack":
Dump the state of the StackSet. A logHook and handleEventHook are also provided.
* "Xmonad.Hooks.DynamicBars":
* "XMonad.Hooks.DynamicBars":
Manage per-screen status bars.
* "XMonad.Hooks.DynamicHooks":

View File

@@ -29,12 +29,15 @@ import Control.Applicative((<$>))
import Data.List
import Data.Maybe
import Data.Monoid
import qualified Data.Map.Strict as M
import System.IO.Unsafe
import XMonad
import Control.Monad
import qualified XMonad.StackSet as W
import XMonad.Hooks.SetWMName
import qualified XMonad.Util.ExtensibleState as E
import XMonad.Util.XUtils (fi)
import XMonad.Util.WorkspaceCompare
import XMonad.Util.WindowProperties (getProp32)
@@ -70,6 +73,58 @@ ewmhDesktopsStartup = setSupported
-- of the current state of workspaces and windows.
ewmhDesktopsLogHook :: X ()
ewmhDesktopsLogHook = ewmhDesktopsLogHookCustom id
-- |
-- Cached desktop names (e.g. @_NET_NUMBER_OF_DESKTOPS@ and
-- @_NET_DESKTOP_NAMES@).
newtype DesktopNames = DesktopNames [String]
deriving (Eq)
instance ExtensionClass DesktopNames where
initialValue = DesktopNames []
-- |
-- Cached client list (e.g. @_NET_CLIENT_LIST@).
newtype ClientList = ClientList [Window]
deriving (Eq)
instance ExtensionClass ClientList where
initialValue = ClientList []
-- |
-- Cached current desktop (e.g. @_NET_CURRENT_DESKTOP@).
newtype CurrentDesktop = CurrentDesktop Int
deriving (Eq)
instance ExtensionClass CurrentDesktop where
initialValue = CurrentDesktop 0
-- |
-- Cached window-desktop assignments (e.g. @_NET_CLIENT_LIST_STACKING@).
newtype WindowDesktops = WindowDesktops (M.Map Window Int)
deriving (Eq)
instance ExtensionClass WindowDesktops where
initialValue = WindowDesktops M.empty
-- |
-- The value of @_NET_ACTIVE_WINDOW@, cached to avoid unnecessary property
-- updates.
newtype ActiveWindow = ActiveWindow Window
deriving (Eq)
instance ExtensionClass ActiveWindow where
initialValue = ActiveWindow none
-- | Compare the given value against the value in the extensible state. Run the
-- action if it has changed.
whenChanged :: (Eq a, ExtensionClass a) => a -> X () -> X ()
whenChanged v action = do
v0 <- E.get
unless (v == v0) $ do
action
E.put v
-- |
-- Generalized version of ewmhDesktopsLogHook that allows an arbitrary
-- user-specified function to transform the workspace list (post-sorting)
@@ -78,28 +133,32 @@ ewmhDesktopsLogHookCustom f = withWindowSet $ \s -> do
sort' <- getSortByIndex
let ws = f $ sort' $ W.workspaces s
-- Number of Workspaces
setNumberOfDesktops (length ws)
-- Set number of workspaces and names thereof
let desktopNames = map W.tag ws
whenChanged (DesktopNames desktopNames) $ do
setNumberOfDesktops (length desktopNames)
setDesktopNames desktopNames
-- 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
-- Set client list; all windows, with focused windows last
let clientList = nub . concatMap (maybe [] (\(W.Stack x l r) -> reverse l ++ r ++ [x]) . W.stack) $ ws
whenChanged (ClientList clientList) $ setClientList clientList
-- Remap the current workspace to handle any renames that f might be doing.
let maybeCurrent' = W.tag <$> listToMaybe (f [W.workspace $ W.current s])
maybeCurrent = join (flip elemIndex (map W.tag ws) <$> maybeCurrent')
current = join (flip elemIndex (map W.tag ws) <$> maybeCurrent')
whenChanged (CurrentDesktop $ fromMaybe 0 current) $ do
mapM_ setCurrentDesktop current
fromMaybe (return ()) $ setCurrentDesktop <$> maybeCurrent
sequence_ $ zipWith setWorkspaceWindowDesktops [0..] ws
setActiveWindow
return ()
-- Set window-desktop mapping
let windowDesktops =
let f wsId workspace = M.fromList [ (winId, wsId) | winId <- W.integrate' $ W.stack workspace ]
in M.unions $ zipWith f [0..] ws
whenChanged (WindowDesktops windowDesktops) $ do
mapM_ (uncurry setWindowDesktop) (M.toList windowDesktops)
-- Set active window
let activeWindow' = fromMaybe none (W.peek s)
whenChanged (ActiveWindow activeWindow') $ setActiveWindow activeWindow'
-- |
-- Intercepts messages from pagers and similar applications and reacts on them.
@@ -221,10 +280,6 @@ setClientList wins = withDisplay $ \dpy -> do
a' <- getAtom "_NET_CLIENT_LIST_STACKING"
io $ changeProperty32 dpy r a' c propModeReplace (fmap fromIntegral wins)
setWorkspaceWindowDesktops :: (Integral a) => a -> WindowSpace -> X()
setWorkspaceWindowDesktops index workspace =
mapM_ (flip setWindowDesktop index) (W.integrate' $ W.stack workspace)
setWindowDesktop :: (Integral a) => Window -> a -> X ()
setWindowDesktop win i = withDisplay $ \dpy -> do
a <- getAtom "_NET_WM_DESKTOP"
@@ -250,9 +305,8 @@ setSupported = withDisplay $ \dpy -> do
setWMName "xmonad"
setActiveWindow :: X ()
setActiveWindow = withWindowSet $ \s -> withDisplay $ \dpy -> do
let w = fromMaybe none (W.peek s)
setActiveWindow :: Window -> X ()
setActiveWindow w = withDisplay $ \dpy -> do
r <- asks theRoot
a <- getAtom "_NET_ACTIVE_WINDOW"
c <- getAtom "WINDOW"

295
XMonad/Hooks/RefocusLast.hs Normal file
View File

@@ -0,0 +1,295 @@
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, MultiWayIf #-}
--------------------------------------------------------------------------------
-- |
-- Module : XMonad.Hooks.RefocusLast
-- Description : Hooks and actions to refocus the previous window.
-- Copyright : (c) 2018 L. S. Leary
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : L. S. Leary
-- Stability : unstable
-- Portability : unportable
--
-- Provides hooks and actions that keep track of recently focused windows on a
-- per workspace basis and automatically refocus the last window on loss of the
-- current (if appropriate as determined by user specified criteria).
--------------------------------------------------------------------------------
-- --< Imports & Exports >-- {{{
module XMonad.Hooks.RefocusLast (
-- * Usage
-- $Usage
-- * Hooks
refocusLastLogHook,
refocusLastLayoutHook,
refocusLastWhen,
-- ** Predicates
-- $Predicates
refocusingIsActive,
isFloat,
-- * Actions
toggleRefocusing,
toggleFocus,
swapWithLast,
refocusWhen,
shiftRLWhen,
updateRecentsOn,
-- * Types
-- $Types
RecentWins(..),
RecentsMap(..),
RefocusLastLayoutHook(..),
RefocusLastToggle(..)
) where
import XMonad
import qualified XMonad.StackSet as W
import qualified XMonad.Util.ExtensibleState as XS
import XMonad.Util.Stack (findS, mapZ_)
import XMonad.Layout.LayoutModifier
import Data.Maybe (fromMaybe)
import Data.Monoid (All(..))
import Data.Foldable (asum)
import qualified Data.Map.Strict as M
import Control.Monad (when)
-- }}}
-- --< Usage >-- {{{
-- $Usage
-- To use this module, you must either include 'refocusLastLogHook' in your log
-- hook __or__ 'refocusLastLayoutHook' in your layout hook; don't use both.
-- This suffices to make use of both 'toggleFocus' and 'shiftRLWhen' but will
-- not refocus automatically upon loss of the current window; for that you must
-- include in your event hook @'refocusLastWhen' pred@ for some valid @pred@.
--
-- The event hooks that trigger refocusing only fire when a window is lost
-- completely, not when it's simply e.g. moved to another workspace. Hence you
-- will need to use @'shiftRLWhen' pred@ or @'refocusWhen' pred@ as appropriate
-- if you want the same behaviour in such cases.
--
-- Example configuration:
--
-- > import XMonad
-- > import XMonad.Hooks.RefocusLast
-- > import qualified Data.Map.Strict as M
-- >
-- > main :: IO ()
-- > main = xmonad def
-- > { handleEventHook = refocusLastWhen myPred <+> handleEventHook def
-- > , logHook = refocusLastLogHook <+> logHook def
-- > -- , layoutHook = refocusLastLayoutHook $ layoutHook def
-- > , keys = refocusLastKeys <+> keys def
-- > } where
-- > myPred = refocusingIsActive <||> isFloat
-- > refocusLastKeys cnf
-- > = M.fromList
-- > $ ((modMask cnf , xK_a), toggleFocus)
-- > : ((modMask cnf .|. shiftMask, xK_a), swapWithLast)
-- > : ((modMask cnf , xK_b), toggleRefocusing)
-- > : [ ( (modMask cnf .|. shiftMask, n)
-- > , windows =<< shiftRLWhen myPred wksp
-- > )
-- > | (n, wksp) <- zip [xK_1..xK_9] (workspaces cnf)
-- > ]
--
-- }}}
-- --< Types >-- {{{
-- $Types
-- The types and constructors used in this module are exported principally to
-- aid extensibility; typical users will have nothing to gain from this section.
-- | Data type holding onto the previous and current @Window@.
data RecentWins = Recent { previous :: !Window, current :: !Window }
deriving (Show, Read, Eq)
-- | Newtype wrapper for a @Map@ holding the @RecentWins@ for each workspace.
-- Is an instance of @ExtensionClass@ with persistence of state.
newtype RecentsMap = RecentsMap (M.Map WorkspaceId RecentWins)
deriving (Show, Read, Eq, Typeable)
instance ExtensionClass RecentsMap where
initialValue = RecentsMap M.empty
extensionType = PersistentExtension
-- | A 'LayoutModifier' that updates the 'RecentWins' for a workspace upon
-- relayout.
data RefocusLastLayoutHook a = RefocusLastLayoutHook
deriving (Show, Read)
instance LayoutModifier RefocusLastLayoutHook a where
modifyLayout _ w@(W.Workspace tg _ _) r = updateRecentsOn tg >> runLayout w r
-- | A newtype on @Bool@ to act as a universal toggle for refocusing.
newtype RefocusLastToggle = RefocusLastToggle { refocusing :: Bool }
deriving (Show, Read, Eq, Typeable)
instance ExtensionClass RefocusLastToggle where
initialValue = RefocusLastToggle { refocusing = True }
extensionType = PersistentExtension
-- }}}
-- --< Public Hooks >-- {{{
-- | A log hook recording the current workspace's most recently focused windows
-- into extensible state.
refocusLastLogHook :: X ()
refocusLastLogHook = withWindowSet (updateRecentsOn . W.currentTag)
-- | Records a workspace's recently focused windows into extensible state upon
-- relayout. Potentially a less wasteful alternative to @refocusLastLogHook@,
-- as it does not run on @WM_NAME@ @propertyNotify@ events.
refocusLastLayoutHook :: l a -> ModifiedLayout RefocusLastLayoutHook l a
refocusLastLayoutHook = ModifiedLayout RefocusLastLayoutHook
-- | Given a predicate on the event window determining whether or not to act,
-- construct an event hook that runs iff the core xmonad event handler will
-- unmanage the window, and which shifts focus to the last focused window on
-- the appropriate workspace if desired.
refocusLastWhen :: Query Bool -> Event -> X All
refocusLastWhen p event = All True <$ case event of
UnmapEvent { ev_send_event = synth, ev_window = w } -> do
e <- gets (fromMaybe 0 . M.lookup w . waitingUnmap)
when (synth || e == 0) (refocusLast w)
DestroyWindowEvent { ev_window = w } -> refocusLast w
_ -> return ()
where
refocusLast w = whenX (runQuery p w) . withWindowSet $ \ws ->
whenJust (W.findTag w ws) $ \tag ->
withRecentsIn tag () $ \lw cw ->
when (w == cw) . modify $ \xs ->
xs { windowset = tryFocusIn tag [lw] ws }
-- }}}
-- --< Predicates >-- {{{
-- $Predicates
-- Impure @Query Bool@ predicates on event windows for use as arguments to
-- 'refocusLastWhen', 'shiftRLWhen' and 'refocusWhen'. Can be combined with
-- '<||>' or '<&&>'. Use like e.g.
--
-- > , handleEventHook = refocusLastWhen refocusingIsActive
--
-- or in a keybinding:
--
-- > windows =<< shiftRLWhen (refocusingIsActive <&&> isFloat) "3"
--
-- It's also valid to use a property lookup like @className =? "someProgram"@ as
-- a predicate, and it should function as expected with e.g. @shiftRLWhen@.
-- In the event hook on the other hand, the window in question has already been
-- unmapped or destroyed, so external lookups to X properties don't work:
-- only the information fossilised in xmonad's state is available.
-- | Holds iff refocusing is toggled active.
refocusingIsActive :: Query Bool
refocusingIsActive = (liftX . XS.gets) refocusing
-- | Holds iff the event window is a float.
isFloat :: Query Bool
isFloat = ask >>= \w -> (liftX . gets) (M.member w . W.floating . windowset)
-- }}}
-- --< Public Actions >-- {{{
-- | Toggle automatic refocusing at runtime. Has no effect unless the
-- @refocusingIsActive@ predicate has been used.
toggleRefocusing :: X ()
toggleRefocusing = XS.modify (RefocusLastToggle . not . refocusing)
-- | Refocuses the previously focused window; acts as a toggle.
-- Is not affected by @toggleRefocusing@.
toggleFocus :: X ()
toggleFocus = withRecents $ \lw cw ->
when (cw /= lw) . windows $ tryFocus [lw]
-- | Swaps the current and previous windows of the current workspace.
-- Is not affected by @toggleRefocusing@.
swapWithLast :: X ()
swapWithLast = withRecents $ \lw cw ->
when (cw /= lw) . windows . modify''. mapZ_ $ \w ->
if | (w == lw) -> cw
| (w == cw) -> lw
| otherwise -> w
where modify'' f = W.modify (f Nothing) (f . Just)
-- | Given a target workspace and a predicate on its current window, produce a
-- 'windows' suitable function that will refocus that workspace appropriately.
-- Allows you to hook refocusing into any action you can run through
-- @windows@. See the implementation of @shiftRLWhen@ for a straight-forward
-- usage example.
refocusWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet)
refocusWhen p tag = withRecentsIn tag id $ \lw cw -> do
b <- runQuery p cw
return (if b then tryFocusIn tag [cw, lw] else id)
-- | Sends the focused window to the specified workspace, refocusing the last
-- focused window if the predicate holds on the current window. Note that the
-- native version of this, @windows . W.shift@, has a nice property that this
-- does not: shifting a window to another workspace then shifting it back
-- preserves its place in the stack. Can be used in a keybinding like e.g.
--
-- > windows =<< shiftRLWhen refocusingIsActive "3"
--
-- or
--
-- > (windows <=< shiftRLWhen refocusingIsActive) "3"
--
-- where '<=<' is imported from "Control.Monad".
shiftRLWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet)
shiftRLWhen p to = withWindowSet $ \ws -> do
refocus <- refocusWhen p (W.currentTag ws)
let shift = maybe id (W.shiftWin to) (W.peek ws)
return (refocus . shift)
-- | Perform an update to the 'RecentWins' for the specified workspace.
-- The RefocusLast log and layout hooks are both implemented trivially in
-- terms of this function. Only exported to aid extensibility.
updateRecentsOn :: WorkspaceId -> X ()
updateRecentsOn tag = withWindowSet $ \ws ->
whenJust (W.peek $ W.view tag ws) $ \fw -> do
m <- getRecentsMap
let insertRecent l c = XS.put . RecentsMap $ M.insert tag (Recent l c) m
case M.lookup tag m of
Just (Recent _ cw) -> when (cw /= fw) (insertRecent cw fw)
Nothing -> insertRecent fw fw
-- }}}
-- --< Private Utilities >-- {{{
-- | Focuses the first window in the list it can find on the current workspace.
tryFocus :: [Window] -> WindowSet -> WindowSet
tryFocus wins = W.modify' $ \s ->
fromMaybe s . asum $ (\w -> findS (== w) s) <$> wins
-- | Operate the above on a specified workspace.
tryFocusIn :: WorkspaceId -> [Window] -> WindowSet -> WindowSet
tryFocusIn tag wins ws =
W.view (W.currentTag ws) . tryFocus wins . W.view tag $ ws
-- | Get the RecentsMap out of extensible state and remove its newtype wrapper.
getRecentsMap :: X (M.Map WorkspaceId RecentWins)
getRecentsMap = XS.get >>= \(RecentsMap m) -> return m
-- | Perform an X action dependent on successful lookup of the RecentWins for
-- the specified workspace, or return a default value.
withRecentsIn :: WorkspaceId -> a -> (Window -> Window -> X a) -> X a
withRecentsIn tag dflt f = M.lookup tag <$> getRecentsMap
>>= maybe (return dflt) (\(Recent lw cw) -> f lw cw)
-- | The above specialised to the current workspace and unit.
withRecents :: (Window -> Window -> X ()) -> X ()
withRecents f = withWindowSet $ \ws -> withRecentsIn (W.currentTag ws) () f
-- }}}

View File

@@ -221,7 +221,7 @@ layerCommand (rect, path) = do
res <- getPicRes path
return $ case needsRotation rect <$> res of
Nothing -> ""
Just rotate ->
Just rotate -> let size = show (rect_width rect) ++ "x" ++ show (rect_height rect) in
" \\( '"++path++"' "++(if rotate then "-rotate 90 " else "")
++ " -scale "++(show$rect_width rect)++"x"++(show$rect_height rect)++"! \\)"
++ " -scale "++size++"^ -gravity center -extent "++size++" +gravity \\)"
++ " -geometry +"++(show$rect_x rect)++"+"++(show$rect_y rect)++" -composite "

View File

@@ -6,6 +6,7 @@
-- Module : XMonad.Layout.BinarySpacePartition
-- Copyright : (c) 2013 Ben Weitzman <benweitzman@gmail.com>
-- 2015 Anton Pirogov <anton.pirogov@gmail.com>
-- 2019 Mateusz Karbowy <obszczymucha@gmail.com
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Ben Weitzman <benweitzman@gmail.com>
@@ -29,6 +30,7 @@ module XMonad.Layout.BinarySpacePartition (
, FocusParent(..)
, SelectMoveNode(..)
, Direction2D(..)
, SplitShiftDirectional(..)
) where
import XMonad
@@ -66,19 +68,21 @@ import Data.Ratio ((%))
--
-- If you don't want to use the mouse, add the following key bindings to resize the splits with the keyboard:
--
-- > , ((modm .|. altMask, xK_l ), sendMessage $ ExpandTowards R)
-- > , ((modm .|. altMask, xK_h ), sendMessage $ ExpandTowards L)
-- > , ((modm .|. altMask, xK_j ), sendMessage $ ExpandTowards D)
-- > , ((modm .|. altMask, xK_k ), sendMessage $ ExpandTowards U)
-- > , ((modm .|. altMask .|. ctrlMask , xK_l ), sendMessage $ ShrinkFrom R)
-- > , ((modm .|. altMask .|. ctrlMask , xK_h ), sendMessage $ ShrinkFrom L)
-- > , ((modm .|. altMask .|. ctrlMask , xK_j ), sendMessage $ ShrinkFrom D)
-- > , ((modm .|. altMask .|. ctrlMask , xK_k ), sendMessage $ ShrinkFrom U)
-- > , ((modm, xK_r ), sendMessage Rotate)
-- > , ((modm, xK_s ), sendMessage Swap)
-- > , ((modm, xK_n ), sendMessage FocusParent)
-- > , ((modm .|. ctrlMask, xK_n ), sendMessage SelectNode)
-- > , ((modm .|. shiftMask, xK_n ), sendMessage MoveNode)
-- > , ((modm .|. altMask, xK_l ), sendMessage $ ExpandTowards R)
-- > , ((modm .|. altMask, xK_h ), sendMessage $ ExpandTowards L)
-- > , ((modm .|. altMask, xK_j ), sendMessage $ ExpandTowards D)
-- > , ((modm .|. altMask, xK_k ), sendMessage $ ExpandTowards U)
-- > , ((modm .|. altMask .|. ctrlMask , xK_l ), sendMessage $ ShrinkFrom R)
-- > , ((modm .|. altMask .|. ctrlMask , xK_h ), sendMessage $ ShrinkFrom L)
-- > , ((modm .|. altMask .|. ctrlMask , xK_j ), sendMessage $ ShrinkFrom D)
-- > , ((modm .|. altMask .|. ctrlMask , xK_k ), sendMessage $ ShrinkFrom U)
-- > , ((modm, xK_r ), sendMessage Rotate)
-- > , ((modm, xK_s ), sendMessage Swap)
-- > , ((modm, xK_n ), sendMessage FocusParent)
-- > , ((modm .|. ctrlMask, xK_n ), sendMessage SelectNode)
-- > , ((modm .|. shiftMask, xK_n ), sendMessage MoveNode)
-- > , ((modm .|. shiftMask .|. ctrlMask , xK_j ), sendMessage $ SplitShift Prev)
-- > , ((modm .|. shiftMask .|. ctrlMask , xK_k ), sendMessage $ SplitShift Next)
--
-- Here's an alternative key mapping, this time using additionalKeysP,
-- arrow keys, and slightly different behavior when resizing windows
@@ -92,7 +96,9 @@ import Data.Ratio ((%))
-- > , ("M-M1-C-<Up>", sendMessage $ ShrinkFrom D)
-- > , ("M-M1-C-<Down>", sendMessage $ ExpandTowards D)
-- > , ("M-s", sendMessage $ BSP.Swap)
-- > , ("M-M1-s", sendMessage $ Rotate) ]
-- > , ("M-M1-s", sendMessage $ Rotate)
-- > , ("M-S-C-j", sendMessage $ SplitShift Prev)
-- > , ("M-S-C-k", sendMessage $ SplitShift Next)
--
-- If you have many windows open and the layout begins to look too hard to manage, you can 'Balance'
-- the layout, so that the current splittings are discarded and windows are tiled freshly in a way that
@@ -133,6 +139,10 @@ instance Message SelectMoveNode
data Axis = Horizontal | Vertical deriving (Show, Read, Eq)
-- |Message for shifting window by splitting its neighbour
data SplitShiftDirectional = SplitShift Direction1D deriving Typeable
instance Message SplitShiftDirectional
oppositeDirection :: Direction2D -> Direction2D
oppositeDirection U = D
oppositeDirection D = U
@@ -273,6 +283,42 @@ swapCurrent :: Zipper a -> Maybe (Zipper a)
swapCurrent l@(_, []) = Just l
swapCurrent (n, c:cs) = Just (n, swapCrumb c:cs)
insertLeftLeaf :: Tree Split -> Zipper Split -> Maybe (Zipper Split)
insertLeftLeaf (Leaf n) ((Node x l r), crumb:cs) = Just (Node (Split (oppositeAxis . axis . parentVal $ crumb) 0.5) (Leaf n) (Node x l r), crumb:cs)
insertLeftLeaf (Leaf n) (Leaf x, crumb:cs) = Just (Node (Split (oppositeAxis . axis . parentVal $ crumb) 0.5) (Leaf n) (Leaf x), crumb:cs)
insertLeftLeaf (Node _ _ _) z = Just z
insertRightLeaf :: Tree Split -> Zipper Split -> Maybe (Zipper Split)
insertRightLeaf (Leaf n) ((Node x l r), crumb:cs) = Just (Node (Split (oppositeAxis . axis . parentVal $ crumb) 0.5) (Node x l r) (Leaf n), crumb:cs)
insertRightLeaf (Leaf n) (Leaf x, crumb:cs) = Just (Node (Split (oppositeAxis . axis . parentVal $ crumb) 0.5) (Leaf x) (Leaf n), crumb:cs)
insertRightLeaf (Node _ _ _) z = Just z
findRightLeaf :: Zipper Split -> Maybe (Zipper Split)
findRightLeaf n@(Node _ _ _, _) = goRight n >>= findRightLeaf
findRightLeaf l@(Leaf _, _) = Just l
findLeftLeaf :: Zipper Split -> Maybe (Zipper Split)
findLeftLeaf n@(Node _ _ _, _) = goLeft n
findLeftLeaf l@(Leaf _, _) = Just l
findTheClosestLeftmostLeaf :: Zipper Split -> Maybe (Zipper Split)
findTheClosestLeftmostLeaf s@(_, (RightCrumb _ _):_) = goUp s >>= goLeft >>= findRightLeaf
findTheClosestLeftmostLeaf s@(_, (LeftCrumb _ _):_) = goUp s >>= findTheClosestLeftmostLeaf
findTheClosestRightmostLeaf :: Zipper Split -> Maybe (Zipper Split)
findTheClosestRightmostLeaf s@(_, (RightCrumb _ _):_) = goUp s >>= findTheClosestRightmostLeaf
findTheClosestRightmostLeaf s@(_, (LeftCrumb _ _):_) = goUp s >>= goRight >>= findLeftLeaf
splitShiftLeftCurrent :: Zipper Split -> Maybe (Zipper Split)
splitShiftLeftCurrent l@(_, []) = Just l
splitShiftLeftCurrent l@(_, (RightCrumb _ _):_) = Just l -- Do nothing. We can swap windows instead.
splitShiftLeftCurrent l@(n, c:cs) = removeCurrent l >>= findTheClosestLeftmostLeaf >>= insertRightLeaf n
splitShiftRightCurrent :: Zipper Split -> Maybe (Zipper Split)
splitShiftRightCurrent l@(_, []) = Just l
splitShiftRightCurrent l@(_, (LeftCrumb _ _):_) = Just l -- Do nothing. We can swap windows instead.
splitShiftRightCurrent l@(n, c:cs) = removeCurrent l >>= findTheClosestRightmostLeaf >>= insertLeftLeaf n
isAllTheWay :: Direction2D -> Zipper Split -> Bool
isAllTheWay _ (_, []) = True
isAllTheWay R (_, LeftCrumb s _:_)
@@ -513,6 +559,12 @@ swapNth (BinarySpacePartition _ _ _ Nothing) = emptyBSP
swapNth b@(BinarySpacePartition _ _ _ (Just (Leaf _))) = b
swapNth b = doToNth swapCurrent b
splitShiftNth :: Direction1D -> BinarySpacePartition a -> BinarySpacePartition a
splitShiftNth _ (BinarySpacePartition _ _ _ Nothing) = emptyBSP
splitShiftNth _ b@(BinarySpacePartition _ _ _ (Just (Leaf _))) = b
splitShiftNth Prev b = doToNth splitShiftLeftCurrent b
splitShiftNth Next b = doToNth splitShiftRightCurrent b
growNthTowards :: Direction2D -> BinarySpacePartition a -> BinarySpacePartition a
growNthTowards _ (BinarySpacePartition _ _ _ Nothing) = emptyBSP
growNthTowards _ b@(BinarySpacePartition _ _ _ (Just (Leaf _))) = b
@@ -687,6 +739,7 @@ instance LayoutClass BinarySpacePartition Window where
, fmap rotateTr (fromMessage m)
, fmap (balanceTr r) (fromMessage m)
, fmap move (fromMessage m)
, fmap splitShift (fromMessage m)
]
resize (ExpandTowards dir) = growNthTowards dir b
resize (ShrinkFrom dir) = shrinkNthFrom dir b
@@ -699,6 +752,7 @@ instance LayoutClass BinarySpacePartition Window where
balanceTr r Balance = resetFoc $ rebalanceNth b r
move MoveNode = resetFoc $ moveNode b
move SelectNode = b --should not happen here, is done above, as we need X monad
splitShift (SplitShift dir) = resetFoc $ splitShiftNth dir b
b = numerateLeaves b_orig
resetFoc bsp = bsp{getFocusedNode=(getFocusedNode bsp){refLeaf=(-1)}

View File

@@ -68,18 +68,21 @@ decoration s t ds = ModifiedLayout (Decoration (I Nothing) s t ds)
--
-- For a collection of 'Theme's see "XMonad.Util.Themes"
data Theme =
Theme { activeColor :: String -- ^ Color of the active window
, inactiveColor :: String -- ^ Color of the inactive window
, urgentColor :: String -- ^ Color of the urgent window
, activeBorderColor :: String -- ^ Color of the border of the active window
, inactiveBorderColor :: String -- ^ Color of the border of the inactive window
, urgentBorderColor :: String -- ^ Color of the border of the urgent window
, activeTextColor :: String -- ^ Color of the text of the active window
, inactiveTextColor :: String -- ^ Color of the text of the inactive window
, urgentTextColor :: String -- ^ Color of the text of the urgent window
, fontName :: String -- ^ Font name
, decoWidth :: Dimension -- ^ Maximum width of the decorations (if supported by the 'DecorationStyle')
, decoHeight :: Dimension -- ^ Height of the decorations
Theme { activeColor :: String -- ^ Color of the active window
, inactiveColor :: String -- ^ Color of the inactive window
, urgentColor :: String -- ^ Color of the urgent window
, activeBorderColor :: String -- ^ Color of the border of the active window
, inactiveBorderColor :: String -- ^ Color of the border of the inactive window
, urgentBorderColor :: String -- ^ Color of the border of the urgent window
, activeBorderWidth :: Dimension -- ^ Width of the border of the active window
, inactiveBorderWidth :: Dimension -- ^ Width of the border of the inactive window
, urgentBorderWidth :: Dimension -- ^ Width of the border of the urgent window
, activeTextColor :: String -- ^ Color of the text of the active window
, inactiveTextColor :: String -- ^ Color of the text of the inactive window
, urgentTextColor :: String -- ^ Color of the text of the urgent window
, fontName :: String -- ^ Font name
, decoWidth :: Dimension -- ^ Maximum width of the decorations (if supported by the 'DecorationStyle')
, decoHeight :: Dimension -- ^ Height of the decorations
, windowTitleAddons :: [(String, Align)] -- ^ Extra text to appear in a window's title bar.
-- Refer to for a use "XMonad.Layout.ImageButtonDecoration"
, windowTitleIcons :: [([[Bool]], Placement)] -- ^ Extra icons to appear in a window's title bar.
@@ -94,6 +97,9 @@ instance Default Theme where
, activeBorderColor = "#FFFFFF"
, inactiveBorderColor = "#BBBBBB"
, urgentBorderColor = "##00FF00"
, activeBorderWidth = 1
, inactiveBorderWidth = 1
, urgentBorderWidth = 1
, activeTextColor = "#FFFFFF"
, inactiveTextColor = "#BFBFBF"
, urgentTextColor = "#FF0000"
@@ -395,9 +401,10 @@ updateDeco sh t fs ((w,_),(Just dw,Just (Rectangle _ _ wh ht))) = do
| win `elem` ur -> uc
| otherwise -> ic) . W.peek)
`fmap` gets windowset
(bc,borderc,tc) <- focusColor w (inactiveColor t, inactiveBorderColor t, inactiveTextColor t)
(activeColor t, activeBorderColor t, activeTextColor t)
(urgentColor t, urgentBorderColor t, urgentTextColor t)
(bc,borderc,borderw,tc) <-
focusColor w (inactiveColor t, inactiveBorderColor t, inactiveBorderWidth t, inactiveTextColor t)
(activeColor t, activeBorderColor t, activeBorderWidth t, activeTextColor t)
(urgentColor t, urgentBorderColor t, urgentBorderWidth t, urgentTextColor t)
let s = shrinkIt sh
name <- shrinkWhile s (\n -> do size <- io $ textWidthXMF dpy fs n
return $ size > fromIntegral wh - fromIntegral (ht `div` 2)) (show nw)
@@ -405,7 +412,7 @@ updateDeco sh t fs ((w,_),(Just dw,Just (Rectangle _ _ wh ht))) = do
strs = name : map fst (windowTitleAddons t)
i_als = map snd (windowTitleIcons t)
icons = map fst (windowTitleIcons t)
paintTextAndIcons dw fs wh ht 1 bc borderc tc bc als strs i_als icons
paintTextAndIcons dw fs wh ht borderw bc borderc tc bc als strs i_als icons
updateDeco _ _ _ (_,(Just w,Nothing)) = hideWindow w
updateDeco _ _ _ _ = return ()

View File

@@ -214,7 +214,7 @@ infixr 5 |||
-- layouts, and use those.
--
-- For the ability to select a layout from a prompt, see
-- "Xmonad.Prompt.Layout".
-- "XMonad.Prompt.Layout".
-- | A reimplementation of the combinator of the same name from the
-- xmonad core, providing layout choice, and the ability to support

View File

@@ -226,8 +226,12 @@ instance Eq a => DecorationStyle TabbedDecoration a where
ny = n y hh
upperTab = Rectangle nx y wid (fi ht)
lowerTab = Rectangle nx (y + fi (hh - ht)) wid (fi ht)
leftTab = Rectangle x ny (fi wt) hid
rightTab = Rectangle (x + fi (wh - wt)) ny (fi wt) hid
fixHeightLoc i = y + fi (((fi ht) * fi i))
fixHeightTab k = Rectangle k
(maybe y (fixHeightLoc)
$ w `elemIndex` ws) (fi wt) (fi ht)
rightTab = fixHeightTab (x + fi (wh - wt))
leftTab = fixHeightTab x
numWindows = length ws
shrink (Tabbed loc _ ) (Rectangle _ _ dw dh) (Rectangle x y w h)
= case loc of

View File

@@ -0,0 +1,98 @@
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Layout.TwoPanePersistent
-- Copyright : (c) Chayanon Wichitrnithed
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Chayanon Wichitrnithed <namowi@gatech.edu>
-- Stability : unstable
-- Portability : unportable
--
-- This layout is the same as "XMonad.Layout.TwoPane" except that it keeps track of the slave window
-- that is alongside the master pane. In other words, it prevents the slave pane
-- from changing after the focus goes back to the master pane.
-----------------------------------------------------------------------------
module XMonad.Layout.TwoPanePersistent
(
-- * Usage
-- $usage
TwoPanePersistent(..)
) where
import XMonad.StackSet (focus, up, down, Stack, Stack(..))
import XMonad hiding (focus)
-- $usage
-- Import the module in @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Layout.TwoPanePersistent
--
-- Then add the layout to the @layoutHook@:
--
-- > myLayout = TwoPanePersistent Nothing (3/100) (1/2) ||| Full ||| etc..
-- > main = xmonad def { layoutHook = myLayout }
data TwoPanePersistent a = TwoPanePersistent
{ slaveWin :: (Maybe a) -- ^ slave window; if 'Nothing' or not in the current workspace,
-- the window below the master will go into the slave pane
, dFrac :: Rational -- ^ shrink/expand size
, mFrac :: Rational -- ^ initial master size
} deriving (Show, Read)
instance (Show a, Eq a) => LayoutClass TwoPanePersistent a where
doLayout l r s =
case reverse (up s) of
-- master is focused
[] -> return $ focusedMaster l s r
-- slave is focused
(master:_) -> return $ focusedSlave l s r master
pureMessage (TwoPanePersistent w delta split) x =
case fromMessage x of
Just Shrink -> Just (TwoPanePersistent w delta (split - delta))
Just Expand -> Just (TwoPanePersistent w delta (split + delta))
_ -> Nothing
description _ = "TwoPanePersistent"
----------------------------------------------------------------------------------------
focusedMaster :: (Eq a) => TwoPanePersistent a -> Stack a -> Rectangle
-> ( [(a, Rectangle)], Maybe (TwoPanePersistent a) )
focusedMaster (TwoPanePersistent w delta split) s r =
let (left, right) = splitHorizontallyBy split r in
case down s of
-- there exist windows below the master
(next:_) -> let nextSlave = ( [(focus s, left), (next, right)]
, Just $ TwoPanePersistent (Just next) delta split )
in case w of
-- if retains state, preserve the layout
Just win -> if win `elem` (down s) && (focus s /= win)
then ( [(focus s, left), (win, right)]
, Just $ TwoPanePersistent w delta split )
else nextSlave
-- if no previous state, default to the next slave window
Nothing -> nextSlave
-- the master is the only window
[] -> ( [(focus s, r)]
, Just $ TwoPanePersistent Nothing delta split )
focusedSlave :: TwoPanePersistent a -> Stack a -> Rectangle -> a
-> ( [(a, Rectangle)], Maybe (TwoPanePersistent a) )
focusedSlave (TwoPanePersistent _ delta split) s r m =
( [(m, left), (focus s, right)]
, Just $ TwoPanePersistent (Just $ focus s) delta split )
where (left, right) = splitHorizontallyBy split r

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,7 @@ import Data.Function
import Data.List
-- $usage
--
--
-- This module offers two aspects of fuzzy matching of completions offered by
-- XMonad.Prompt.
--
@@ -48,22 +48,22 @@ import Data.List
-- 11. "FastSPR" is ranked before "FasterSPR" because its match starts at
-- position 5 while the match in "FasterSPR" starts at position 7.
--
-- To use these functions in an XPrompt, for example, for windowPromptGoto:
-- To use these functions in an XPrompt, for example, for windowPrompt:
--
-- > import XMonad.Prompt
-- > import XMonad.Prompt.Window ( windowPromptGoto )
-- > import XMonad.Prompt.Window ( windowPrompt )
-- > import XMonad.Prompt.FuzzyMatch
-- >
-- > myXPConfig = def { searchPredicate = fuzzyMatch
-- , sorter = fuzzySort
-- }
--
-- > , sorter = fuzzySort
-- > }
--
-- then add this to your keys definition:
--
-- > , ((modm .|. shiftMask, xK_g), windowPromptGoto myXPConfig)
-- > , ((modm .|. shiftMask, xK_g), windowPrompt myXPConfig Goto allWindows)
--
-- For detailed instructions on editing the key bindings, see
-- "Xmonad.Doc.Extending#Editing_key_bindings".
-- "XMonad.Doc.Extending#Editing_key_bindings".
-- | Returns True if the first argument is a subsequence of the second argument,
-- that is, it can be obtained from the second sequence by deleting elements.
@@ -77,7 +77,7 @@ fuzzyMatch xxs@(x:xs) (y:ys) | toLower x == toLower y = fuzzyMatch xs ys
-- measured first by the length of the substring containing the match and second
-- by the positions of the matching characters in the string.
fuzzySort :: String -> [String] -> [String]
fuzzySort q = map snd . sortBy (compare `on` fst) . map (rankMatch q)
fuzzySort q = map snd . sort . map (rankMatch q)
rankMatch :: String -> String -> ((Int, Int), String)
rankMatch q s = (minimum $ rankMatches q s, s)
@@ -95,7 +95,7 @@ findOccurrences :: String -> Char -> [Int]
findOccurrences s c = map snd $ filter ((toLower c ==) . toLower . fst) $ zip s [0..]
extendMatches :: [(Int, Int)] -> [Int] -> [(Int, Int)]
extendMatches spans xs = map last $ groupBy ((==) `on` snd) $ extendMatches' spans xs
extendMatches spans = map last . groupBy ((==) `on` snd) . extendMatches' spans
extendMatches' :: [(Int, Int)] -> [Int] -> [(Int, Int)]
extendMatches' [] _ = []

View File

@@ -8,23 +8,33 @@
-- Stability : unstable
-- Portability : unportable
--
-- This module provides 4 <XMonad.Prompt> to ease password manipulation (generate, read, remove):
-- This module provides 5 <XMonad.Prompt>s to ease password
-- manipulation (generate, read, edit, remove):
--
-- - two to lookup passwords in the password-store; one of which copies to the
-- clipboard, and the other uses @xdotool@ to type the password directly.
-- - two to lookup passwords in the password-store; one of which
-- copies to the clipboard, and the other uses @xdotool@ to type the
-- password directly.
--
-- - one to generate a password for a given password label that the user inputs.
-- - one to generate a password for a given password label that the
-- user inputs.
--
-- - one to delete a stored password for a given password label that the user inputs.
-- - one to edit a password for a given password label that the user
-- inputs.
--
-- All those prompts benefit from the completion system provided by the module <XMonad.Prompt>.
-- - one to delete a stored password for a given password label that
-- the user inputs.
--
-- The password store is setup through an environment variable PASSWORD_STORE_DIR,
-- or @$HOME\/.password-store@ if it is unset.
-- All those prompts benefit from the completion system provided by
-- the module <XMonad.Prompt>.
--
-- The password store is setup through an environment variable
-- PASSWORD_STORE_DIR, or @$HOME\/.password-store@ if it is unset.
-- The editor is determined from the environment variable EDITOR.
--
-- Source:
--
-- - The password store implementation is <http://git.zx2c4.com/password-store the password-store cli>.
-- - The <https://www.passwordstore.org/ password store>
-- implementation is <http://git.zx2c4.com/password-store here>.
--
-- - Inspired by <http://babushk.in/posts/combining-xmonad-and-pass.html>
--
@@ -34,8 +44,11 @@ module XMonad.Prompt.Pass (
-- * Usage
-- $usage
passPrompt
, passOTPPrompt
, passGeneratePrompt
, passGenerateAndCopyPrompt
, passRemovePrompt
, passEditPrompt
, passTypePrompt
) where
@@ -58,10 +71,12 @@ import XMonad.Util.Run (runProcessWithInput)
--
-- > import XMonad.Prompt.Pass
--
-- Then add a keybinding for 'passPrompt', 'passGeneratePrompt' or 'passRemovePrompt':
-- Then add a keybinding for 'passPrompt', 'passGeneratePrompt',
-- 'passRemovePrompt', 'passEditPrompt' or 'passTypePrompt':
--
-- > , ((modMask , xK_p) , passPrompt xpconfig)
-- > , ((modMask .|. controlMask, xK_p) , passGeneratePrompt xpconfig)
-- > , ((modMask .|. shiftMask, xK_p) , passEditPrompt xpconfig)
-- > , ((modMask .|. controlMask .|. shiftMask, xK_p), passRemovePrompt xpconfig)
--
-- For detailed instructions on:
@@ -112,6 +127,11 @@ mkPassPrompt promptLabel passwordFunction xpconfig = do
passPrompt :: XPConfig -> X ()
passPrompt = mkPassPrompt "Select password" selectPassword
-- | A prompt to retrieve a OTP from a given entry.
--
passOTPPrompt :: XPConfig -> X ()
passOTPPrompt = mkPassPrompt "Select OTP" selectOTP
-- | A prompt to generate a password for a given entry.
-- This can be used to override an already stored entry.
-- (Beware that no confirmation is asked)
@@ -119,6 +139,13 @@ passPrompt = mkPassPrompt "Select password" selectPassword
passGeneratePrompt :: XPConfig -> X ()
passGeneratePrompt = mkPassPrompt "Generate password" generatePassword
-- | A prompt to generate a password for a given entry and immediately copy it
-- to the clipboard. This can be used to override an already stored entry.
-- (Beware that no confirmation is asked)
--
passGenerateAndCopyPrompt :: XPConfig -> X ()
passGenerateAndCopyPrompt = mkPassPrompt "Generate and copy password" generateAndCopyPassword
-- | A prompt to remove a password for a given entry.
-- (Beware that no confirmation is asked)
--
@@ -131,22 +158,45 @@ passRemovePrompt = mkPassPrompt "Remove password" removePassword
passTypePrompt :: XPConfig -> X ()
passTypePrompt = mkPassPrompt "Type password" typePassword
-- | A prompt to edit a given entry.
-- This doesn't touch the clipboard.
--
passEditPrompt :: XPConfig -> X ()
passEditPrompt = mkPassPrompt "Edit password" editPassword
-- | Select a password.
--
selectPassword :: String -> X ()
selectPassword passLabel = spawn $ "pass --clip \"" ++ escapeQuote passLabel ++ "\""
-- | Select a OTP.
--
selectOTP :: String -> X ()
selectOTP passLabel = spawn $ "pass otp --clip \"" ++ escapeQuote passLabel ++ "\""
-- | Generate a 30 characters password for a given entry.
-- If the entry already exists, it is updated with a new password.
--
generatePassword :: String -> X ()
generatePassword passLabel = spawn $ "pass generate --force \"" ++ escapeQuote passLabel ++ "\" 30"
-- | Generate a 30 characters password for a given entry.
-- If the entry already exists, it is updated with a new password.
-- After generating the password, it is copied to the clipboard.
--
generateAndCopyPassword :: String -> X ()
generateAndCopyPassword passLabel = spawn $ "pass generate --force -c \"" ++ escapeQuote passLabel ++ "\" 30"
-- | Remove a password stored for a given entry.
--
removePassword :: String -> X ()
removePassword passLabel = spawn $ "pass rm --force \"" ++ escapeQuote passLabel ++ "\""
-- | Edit a password stored for a given entry.
--
editPassword :: String -> X ()
editPassword passLabel = spawn $ "pass edit \"" ++ escapeQuote passLabel ++ "\""
-- | Type a password stored for a given entry using xdotool.
--
typePassword :: String -> X ()
@@ -163,6 +213,7 @@ escapeQuote = concatMap escape
getPasswords :: FilePath -> IO [String]
getPasswords passwordStoreDir = do
files <- runProcessWithInput "find" [
"-L", -- Traverse symlinks
passwordStoreDir,
"-type", "f",
"-name", "*.gpg",

View File

@@ -0,0 +1,263 @@
{-# LANGUAGE LambdaCase #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Util.ExclusiveScratchpads
-- Copyright : Bruce Forte (2017)
-- License : BSD-style (see LICENSE)
--
-- Maintainer : Bruce Forte
-- Stability : unstable
-- Portability : unportable
--
-- Named scratchpads that can be mutually exclusive.
--
-----------------------------------------------------------------------------
module XMonad.Util.ExclusiveScratchpads (
-- * Usage
-- $usage
mkXScratchpads,
xScratchpadsManageHook,
-- * Keyboard related
scratchpadAction,
hideAll,
resetExclusiveSp,
-- * Mouse related
setNoexclusive,
resizeNoexclusive,
floatMoveNoexclusive,
-- * Types
ExclusiveScratchpad(..),
ExclusiveScratchpads,
-- * Hooks
nonFloating,
defaultFloating,
customFloating
) where
import Control.Applicative ((<$>))
import Control.Monad ((<=<),filterM,liftM2)
import Data.Monoid (appEndo)
import XMonad
import XMonad.Actions.Minimize
import XMonad.Actions.TagWindows (addTag,delTag)
import XMonad.Hooks.ManageHelpers (doRectFloat,isInProperty)
import qualified XMonad.StackSet as W
-- $usage
--
-- For this module to work properly, you need to use "XMonad.Layout.BoringWindows" and
-- "XMonad.Layout.Minimize", please refer to the documentation of these modules for more
-- information on how to configure them.
--
-- To use this module, put the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Utils.ExclusiveScratchpads
-- > import XMonad.ManageHook (title,appName)
-- > import qualified XMonad.StackSet as W
--
-- Add exclusive scratchpads, for example:
--
-- > exclusiveSps = mkXScratchpads [ ("htop", "urxvt -name htop -e htop", title =? "htop")
-- > , ("xclock", "xclock", appName =? "xclock")
-- > ] $ customFloating $ W.RationalRect (1/4) (1/4) (1/2) (1/2)
--
-- The scratchpads don\'t have to be exclusive, you can create them like this (see 'ExclusiveScratchpad'):
--
-- > regularSps = [ XSP "term" "urxvt -name scratchpad" (appName =? "scratchpad") defaultFloating [] ]
--
-- Create a list that contains all your scratchpads like this:
--
-- > scratchpads = exclusiveSps ++ regularSps
--
-- Add the hooks to your managehook (see "XMonad.Doc.Extending#Editing_the_manage_hook"), eg.:
--
-- > manageHook = myManageHook <+> xScratchpadsManageHook scratchpads
--
-- And finally add some keybindings (see "XMonad.Doc.Extending#Editing_key_bindings"):
--
-- > , ((modMask, xK_h), scratchpadAction scratchpads "htop")
-- > , ((modMask, xK_c), scratchpadAction scratchpads "xclock")
-- > , ((modMask, xK_t), scratchpadAction scratchpads "term")
-- > , ((modMask, xK_h), hideAll scratchpads)
--
-- Now you can get your scratchpads by pressing the corresponding keys, if you
-- have the @htop@ scratchpad on your current screen and you fetch the @xclock@
-- scratchpad then @htop@ gets hidden.
--
-- If you move a scratchpad it still gets hidden when you fetch a scratchpad of
-- the same family, to change that behaviour and make windows not exclusive
-- anymore when they get resized or moved add these mouse bindings
-- (see "XMonad.Doc.Extending#Editing_mouse_bindings"):
--
-- > , ((mod4Mask, button1), floatMoveNoexclusive scratchpads)
-- > , ((mod4Mask, button3), resizeNoexclusive scratchpads)
--
-- To reset a moved scratchpad to the original position that you set with its hook,
-- call @resetExclusiveSp@ when it is in focus. For example if you want to extend
-- Mod-Return to reset the placement when a scratchpad is in focus but keep the
-- default behaviour for tiled windows, set these key bindings:
--
-- > , ((modMask, xK_Return), windows W.swapMaster >> resetExclusiveSp scratchpads)
--
-- __Note:__ This is just an example, in general you can add more than two
-- exclusive scratchpads and multiple families of such.
data ExclusiveScratchpad = XSP { name :: String -- ^ Name of the scratchpad
, cmd :: String -- ^ Command to spawn the scratchpad
, query :: Query Bool -- ^ Query to match the scratchpad
, hook :: ManageHook -- ^ Hook to specify the placement policy
, exclusive :: [String] -- ^ Names of exclusive scratchpads
}
type ExclusiveScratchpads = [ExclusiveScratchpad]
-- -----------------------------------------------------------------------------------
-- | Create 'ExclusiveScratchpads' from @[(name,cmd,query)]@ with a common @hook@
mkXScratchpads :: [(String,String,Query Bool)] -- ^ List of @(name,cmd,query)@ of the
-- exclusive scratchpads
-> ManageHook -- ^ The common @hook@ that they use
-> ExclusiveScratchpads
mkXScratchpads xs h = foldl accumulate [] xs
where
accumulate a (n,c,q) = XSP n c q h (filter (n/=) names) : a
names = map (\(n,_,_) -> n) xs
-- | Create 'ManageHook' from 'ExclusiveScratchpads'
xScratchpadsManageHook :: ExclusiveScratchpads -- ^ List of exclusive scratchpads from
-- which a 'ManageHook' should be generated
-> ManageHook
xScratchpadsManageHook = composeAll . fmap (\sp -> query sp --> hook sp)
-- | Pop up/hide the scratchpad by name and possibly hide its exclusive
scratchpadAction :: ExclusiveScratchpads -- ^ List of exclusive scratchpads
-> String -- ^ Name of the scratchpad to toggle
-> X ()
scratchpadAction xs n =
let ys = filter ((n==).name) xs in
case ys of [] -> return ()
(sp:_) -> let q = query sp in withWindowSet $ \s -> do
ws <- filterM (runQuery q) $ W.allWindows s
case ws of [] -> do spawn (cmd sp)
hideOthers xs n
windows W.shiftMaster
(w:_) -> do toggleWindow w
whenX (runQuery isExclusive w) (hideOthers xs n)
where
toggleWindow w = liftM2 (&&) (runQuery isMaximized w) (onCurrentScreen w) >>= \case
True -> whenX (onCurrentScreen w) (minimizeWindow w)
False -> do windows (flip W.shiftWin w =<< W.currentTag)
maximizeWindowAndFocus w
windows W.shiftMaster
onCurrentScreen w = withWindowSet (return . elem w . currentWindows)
-- | Hide all 'ExclusiveScratchpads' on the current screen
hideAll :: ExclusiveScratchpads -- ^ List of exclusive scratchpads
-> X ()
hideAll xs = mapWithCurrentScreen q minimizeWindow
where q = joinQueries (map query xs) <&&> isExclusive <&&> isMaximized
-- | If the focused window is a scratchpad, the scratchpad gets reset to the original
-- placement specified with the hook and becomes exclusive again
resetExclusiveSp :: ExclusiveScratchpads -- ^ List of exclusive scratchpads
-> X ()
resetExclusiveSp xs = withFocused $ \w -> whenX (isScratchpad xs w) $ do
let ys = filterM (flip runQuery w . query) xs
unlessX (null <$> ys) $ do
mh <- (head . map hook) <$> ys -- ys /= [], so `head` is fine
n <- (head . map name) <$> ys -- same
(windows . appEndo <=< runQuery mh) w
hideOthers xs n
delTag "_XSP_NOEXCLUSIVE" w
where unlessX = whenX . fmap not
-- -----------------------------------------------------------------------------------
-- | Hide the scratchpad of the same family by name if it's on the focused workspace
hideOthers :: ExclusiveScratchpads -> String -> X ()
hideOthers xs n =
let ys = concatMap exclusive $ filter ((n==).name) xs
qs = map query $ filter ((`elem` ys).name) xs
q = joinQueries qs <&&> isExclusive <&&> isMaximized in
mapWithCurrentScreen q minimizeWindow
-- | Conditionally map a function on all windows of the current screen
mapWithCurrentScreen :: Query Bool -> (Window -> X ()) -> X ()
mapWithCurrentScreen q f = withWindowSet $ \s -> do
ws <- filterM (runQuery q) $ currentWindows s
mapM_ f ws
-- | Extract all windows on the current screen from a StackSet
currentWindows :: W.StackSet i l a sid sd -> [a]
currentWindows = W.integrate' . W.stack . W.workspace . W.current
-- | Check if given window is a scratchpad
isScratchpad :: ExclusiveScratchpads -> Window -> X Bool
isScratchpad xs w = withWindowSet $ \s -> do
let q = joinQueries $ map query xs
ws <- filterM (runQuery q) $ W.allWindows s
return $ elem w ws
-- | Build a disjunction from a list of clauses
joinQueries :: [Query Bool] -> Query Bool
joinQueries = foldl (<||>) (liftX $ return False)
-- | Useful queries
isExclusive, isMaximized :: Query Bool
isExclusive = (notElem "_XSP_NOEXCLUSIVE" . words) <$> stringProperty "_XMONAD_TAGS"
isMaximized = not <$> isInProperty "_NET_WM_STATE" "_NET_WM_STATE_HIDDEN"
-- -----------------------------------------------------------------------------------
-- | Make a window not exclusive anymore
setNoexclusive :: ExclusiveScratchpads -- ^ List of exclusive scratchpads
-> Window -- ^ Window which should be made not
-- exclusive anymore
-> X ()
setNoexclusive xs w = whenX (isScratchpad xs w) $ addTag "_XSP_NOEXCLUSIVE" w
-- | Float and drag the window, make it not exclusive anymore
floatMoveNoexclusive :: ExclusiveScratchpads -- ^ List of exclusive scratchpads
-> Window -- ^ Window which should be moved
-> X ()
floatMoveNoexclusive xs w = setNoexclusive xs w
>> focus w
>> mouseMoveWindow w
>> windows W.shiftMaster
-- | Resize window, make it not exclusive anymore
resizeNoexclusive :: ExclusiveScratchpads -- ^ List of exclusive scratchpads
-> Window -- ^ Window which should be resized
-> X ()
resizeNoexclusive xs w = setNoexclusive xs w
>> focus w
>> mouseResizeWindow w
>> windows W.shiftMaster
-- -----------------------------------------------------------------------------------
-- | Manage hook that makes the window non-floating
nonFloating :: ManageHook
nonFloating = idHook
-- | Manage hook that makes the window floating with the default placement
defaultFloating :: ManageHook
defaultFloating = doFloat
-- | Manage hook that makes the window floating with custom placement
customFloating :: W.RationalRect -- ^ @RationalRect x y w h@ that specifies relative position,
-- height and width (see "XMonad.StackSet#RationalRect")
-> ManageHook
customFloating = doRectFloat

View File

@@ -37,7 +37,7 @@ data Placement = OffsetLeft Int Int -- ^ An exact amount of pixels from the up
-- In the module we suppose that those matrices are represented as [[Bool]],
-- so the lengths of the inner lists must be the same.
--
-- See "Xmonad.Layout.Decoration" for usage examples
-- See "XMonad.Layout.Decoration" for usage examples
-- | Gets the ('width', 'height') of an image
imageDims :: [[Bool]] -> (Int, Int)

View File

@@ -23,6 +23,7 @@ module XMonad.Util.Invisible (
) where
import Control.Applicative
import Control.Monad.Fail
-- $usage
-- A wrapper data type to store layout state that shouldn't be persisted across
@@ -30,10 +31,10 @@ import Control.Applicative
-- Invisible derives trivial definitions for Read and Show, so the wrapped data
-- type need not do so.
newtype Invisible m a = I (m a) deriving (Monad, Applicative, Functor)
newtype Invisible m a = I (m a) deriving (Monad, MonadFail, Applicative, Functor)
instance (Functor m, Monad m) => Read (Invisible m a) where
readsPrec _ s = [(fail "Read Invisible", s)]
instance (Functor m, Monad m, MonadFail m) => Read (Invisible m a) where
readsPrec _ s = [(Control.Monad.Fail.fail "Read Invisible", s)]
instance Monad m => Show (Invisible m a) where
show _ = ""

View File

@@ -19,6 +19,8 @@ module XMonad.Util.Themes
, ppThemeInfo
, xmonadTheme
, smallClean
, adwaitaTheme
, adwaitaDarkTheme
, robertTheme
, darkTheme
, deiflTheme
@@ -91,6 +93,8 @@ ppThemeInfo t = themeName t <> themeDescription t <> "by" <> themeAuthor t
listOfThemes :: [ThemeInfo]
listOfThemes = [ xmonadTheme
, smallClean
, adwaitaTheme
, adwaitaDarkTheme
, darkTheme
, deiflTheme
, oxymor00nTheme
@@ -132,6 +136,48 @@ smallClean =
}
}
-- | Matching decorations for Adwaita GTK theme
adwaitaTheme :: ThemeInfo
adwaitaTheme =
newTheme { themeName = "adwaitaTheme"
, themeAuthor = "Alex Griffin"
, themeDescription = "Matching decorations for Adwaita GTK theme"
, theme = def { activeColor = "#dfdcd8"
, inactiveColor = "#f6f5f4"
, urgentColor = "#3584e4"
, activeBorderColor = "#bfb8b1"
, inactiveBorderColor = "#cdc7c2"
, urgentBorderColor = "#1658a7"
, activeTextColor = "#2e3436"
, inactiveTextColor = "#929595"
, urgentTextColor = "#ffffff"
, fontName = "xft:Cantarell:bold:size=11"
, decoWidth = 400
, decoHeight = 35
}
}
-- | Matching decorations for Adwaita-dark GTK theme
adwaitaDarkTheme :: ThemeInfo
adwaitaDarkTheme =
newTheme { themeName = "adwaitaDarkTheme"
, themeAuthor = "Alex Griffin"
, themeDescription = "Matching decorations for Adwaita-dark GTK theme"
, theme = def { activeColor = "#2d2d2d"
, inactiveColor = "#353535"
, urgentColor = "#15539e"
, activeBorderColor = "#070707"
, inactiveBorderColor = "#1c1c1c"
, urgentBorderColor = "#030c17"
, activeTextColor = "#eeeeec"
, inactiveTextColor = "#929291"
, urgentTextColor = "#ffffff"
, fontName = "xft:Cantarell:bold:size=11"
, decoWidth = 400
, decoHeight = 35
}
}
-- | Don's preferred colors - from DynamicLog...;)
donaldTheme :: ThemeInfo
donaldTheme =

View File

@@ -1,3 +1,2 @@
packages: ./
../xmonad/
../x11/
packages:
xmonad-contrib.cabal

View File

@@ -1,5 +1,5 @@
name: xmonad-contrib
version: 0.15
version: 0.16
homepage: http://xmonad.org/
synopsis: Third party extensions for xmonad
description:
@@ -36,7 +36,7 @@ cabal-version: >= 1.6
build-type: Simple
bug-reports: https://github.com/xmonad/xmonad-contrib/issues
tested-with: GHC==7.8.4, GHC==7.10.3, GHC==8.0.1, GHC==8.2.2, GHC==8.4.3, GHC==8.6.1
tested-with: GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.5, GHC==8.8.1
source-repository head
type: git
@@ -52,7 +52,7 @@ flag testing
default: False
library
build-depends: base >= 4.5 && < 5,
build-depends: base >= 4.9 && < 5,
bytestring >= 0.10 && < 0.11,
containers >= 0.5 && < 0.7,
directory,
@@ -181,6 +181,7 @@ library
XMonad.Hooks.Minimize
XMonad.Hooks.Place
XMonad.Hooks.PositionStoreHooks
XMonad.Hooks.RefocusLast
XMonad.Hooks.RestoreMinimized
XMonad.Hooks.ScreenCorners
XMonad.Hooks.Script
@@ -285,6 +286,7 @@ library
XMonad.Layout.ToggleLayouts
XMonad.Layout.TrackFloating
XMonad.Layout.TwoPane
XMonad.Layout.TwoPanePersistent
XMonad.Layout.WindowArranger
XMonad.Layout.WindowNavigation
XMonad.Layout.WindowSwitcherDecoration
@@ -316,6 +318,7 @@ library
XMonad.Util.Dmenu
XMonad.Util.Dzen
XMonad.Util.EZConfig
XMonad.Util.ExclusiveScratchpads
XMonad.Util.ExtensibleState
XMonad.Util.Font
XMonad.Util.Image