mirror of
https://github.com/xmonad/xmonad.git
synced 2025-08-02 13:11:53 -07:00
Compare commits
31 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
71cb355948 | ||
|
19069b3d4b | ||
|
969fca9406 | ||
|
61f00e65f1 | ||
|
db11089e70 | ||
|
e601a7d16d | ||
|
0dd23bddfa | ||
|
55b14d4850 | ||
|
9df514b378 | ||
|
ecf1a0ca0d | ||
|
d216e95f97 | ||
|
af3d3818c8 | ||
|
d065038c8a | ||
|
10bc213349 | ||
|
d22d93b43f | ||
|
871a80fee7 | ||
|
2d59f5157c | ||
|
0738262d9e | ||
|
63d6a66133 | ||
|
fe6215d309 | ||
|
c3cb4ad65f | ||
|
126f891d11 | ||
|
d3383ce0f5 | ||
|
c96a59fa0d | ||
|
12a45b4b99 | ||
|
462957b2f0 | ||
|
2e6312776b | ||
|
3897cab7c9 | ||
|
10b843ad21 | ||
|
bc320b69da | ||
|
89a8cc88c3 |
157
.travis.yml
157
.travis.yml
@@ -1,85 +1,118 @@
|
|||||||
# This file has been generated -- see https://github.com/hvr/multi-ghc-travis
|
# This Travis job script has been generated by a script via
|
||||||
|
#
|
||||||
|
# runghc make_travis_yml_2.hs '-o' '.travis.yml' 'xmonad.cabal' 'libxrandr-dev'
|
||||||
|
#
|
||||||
|
# For more information, see https://github.com/hvr/multi-ghc-travis
|
||||||
|
#
|
||||||
language: c
|
language: c
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
|
git:
|
||||||
|
submodules: false # whether to recursively clone submodules
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- $HOME/.cabsnap
|
|
||||||
- $HOME/.cabal/packages
|
- $HOME/.cabal/packages
|
||||||
|
- $HOME/.cabal/store
|
||||||
|
|
||||||
before_cache:
|
before_cache:
|
||||||
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
|
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
|
||||||
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
|
# remove files that are regenerated by 'cabal update'
|
||||||
|
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.*
|
||||||
|
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/*.json
|
||||||
|
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.cache
|
||||||
|
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar
|
||||||
|
- rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar.idx
|
||||||
|
|
||||||
|
- rm -rfv $HOME/.cabal/packages/head.hackage
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- env: CABALVER=1.16 GHCVER=7.6.3
|
- compiler: "ghc-8.4.3"
|
||||||
compiler: ": #GHC 7.6.3"
|
# env: TEST=--disable-tests BENCH=--disable-benchmarks
|
||||||
addons: {apt: {packages: [cabal-install-1.16,ghc-7.6.3], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.4.3,libxrandr-dev], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=1.18 GHCVER=7.8.4
|
- compiler: "ghc-8.2.2"
|
||||||
compiler: ": #GHC 7.8.4"
|
# env: TEST=--disable-tests BENCH=--disable-benchmarks
|
||||||
addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.2.2,libxrandr-dev], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=1.22 GHCVER=7.10.3
|
- compiler: "ghc-8.0.2"
|
||||||
compiler: ": #GHC 7.10.3"
|
# env: TEST=--disable-tests BENCH=--disable-benchmarks
|
||||||
addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.0.2,libxrandr-dev], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=1.24 GHCVER=8.0.1
|
- compiler: "ghc-7.10.3"
|
||||||
compiler: ": #GHC 8.0.1"
|
# env: TEST=--disable-tests BENCH=--disable-benchmarks
|
||||||
addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-7.10.3,libxrandr-dev], sources: [hvr-ghc]}}
|
||||||
|
- compiler: "ghc-7.8.4"
|
||||||
|
# env: TEST=--disable-tests BENCH=--disable-benchmarks
|
||||||
|
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-7.8.4,libxrandr-dev], sources: [hvr-ghc]}}
|
||||||
|
- compiler: "ghc-7.6.3"
|
||||||
|
# env: TEST=--disable-tests BENCH=--disable-benchmarks
|
||||||
|
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-7.6.3,libxrandr-dev], sources: [hvr-ghc]}}
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- unset CC
|
- HC=${CC}
|
||||||
- export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
|
- HCPKG=${HC/ghc/ghc-pkg}
|
||||||
|
- unset CC
|
||||||
|
- ROOTDIR=$(pwd)
|
||||||
|
- mkdir -p $HOME/.local/bin
|
||||||
|
- "PATH=/opt/ghc/bin:/opt/ghc-ppa-tools/bin:$HOME/local/bin:$PATH"
|
||||||
|
- HCNUMVER=$(( $(${HC} --numeric-version|sed -E 's/([0-9]+)\.([0-9]+)\.([0-9]+).*/\1 * 10000 + \2 * 100 + \3/') ))
|
||||||
|
- echo $HCNUMVER
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- cabal --version
|
- cabal --version
|
||||||
- echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
|
- echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]"
|
||||||
- if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
|
- BENCH=${BENCH---enable-benchmarks}
|
||||||
then
|
- TEST=${TEST---enable-tests}
|
||||||
zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
|
- HADDOCK=${HADDOCK-true}
|
||||||
$HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
|
- UNCONSTRAINED=${UNCONSTRAINED-true}
|
||||||
fi
|
- NOINSTALLEDCONSTRAINTS=${NOINSTALLEDCONSTRAINTS-false}
|
||||||
- travis_retry cabal update -v
|
- GHCHEAD=${GHCHEAD-false}
|
||||||
- sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
|
- travis_retry cabal update -v
|
||||||
- cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt
|
- "sed -i.bak 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config"
|
||||||
- sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
|
- rm -fv cabal.project cabal.project.local
|
||||||
|
- grep -Ev -- '^\s*--' ${HOME}/.cabal/config | grep -Ev '^\s*$'
|
||||||
# check whether current requested install-plan matches cached package-db snapshot
|
- "printf 'packages: \".\"\\n' > cabal.project"
|
||||||
- if diff -u $HOME/.cabsnap/installplan.txt installplan.txt;
|
- touch cabal.project.local
|
||||||
then
|
- "if ! $NOINSTALLEDCONSTRAINTS; then for pkg in $($HCPKG list --simple-output); do echo $pkg | grep -vw -- xmonad | sed 's/^/constraints: /' | sed 's/-[^-]*$/ installed/' >> cabal.project.local; done; fi"
|
||||||
echo "cabal build-cache HIT";
|
- cat cabal.project || true
|
||||||
rm -rfv .ghc;
|
- cat cabal.project.local || true
|
||||||
cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
|
- if [ -f "./configure.ac" ]; then
|
||||||
cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;
|
(cd "." && autoreconf -i);
|
||||||
else
|
fi
|
||||||
echo "cabal build-cache MISS";
|
- rm -f cabal.project.freeze
|
||||||
rm -rf $HOME/.cabsnap;
|
- cabal new-build -w ${HC} ${TEST} ${BENCH} --project-file="cabal.project" --dep -j2 all
|
||||||
mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
|
- cabal new-build -w ${HC} --disable-tests --disable-benchmarks --project-file="cabal.project" --dep -j2 all
|
||||||
cabal install --only-dependencies --enable-tests --enable-benchmarks;
|
- rm -rf .ghc.environment.* "."/dist
|
||||||
fi
|
- DISTDIR=$(mktemp -d /tmp/dist-test.XXXX)
|
||||||
|
|
||||||
# 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;
|
# 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.
|
# any command which exits with a non-zero exit code causes the build to fail.
|
||||||
script:
|
script:
|
||||||
- if [ -f configure.ac ]; then autoreconf -i; fi
|
# test that source-distributions can be generated
|
||||||
- cabal configure --enable-tests --enable-benchmarks -v2 # -v2 provides useful information for debugging
|
- (cd "." && cabal sdist)
|
||||||
- cabal build # this builds all libraries and executables (including tests/benchmarks)
|
- mv "."/dist/xmonad-*.tar.gz ${DISTDIR}/
|
||||||
- cabal test
|
- cd ${DISTDIR} || false
|
||||||
- cabal check
|
- find . -maxdepth 1 -name '*.tar.gz' -exec tar -xvf '{}' \;
|
||||||
- cabal sdist # tests that a source-distribution can be generated
|
- "printf 'packages: xmonad-*/*.cabal\\n' > cabal.project"
|
||||||
|
- touch cabal.project.local
|
||||||
|
- "if ! $NOINSTALLEDCONSTRAINTS; then for pkg in $($HCPKG list --simple-output); do echo $pkg | grep -vw -- xmonad | sed 's/^/constraints: /' | sed 's/-[^-]*$/ installed/' >> cabal.project.local; done; fi"
|
||||||
|
- cat cabal.project || true
|
||||||
|
- cat cabal.project.local || true
|
||||||
|
# this builds all libraries and executables (without tests/benchmarks)
|
||||||
|
- cabal new-build -w ${HC} --disable-tests --disable-benchmarks all
|
||||||
|
|
||||||
# Check that the resulting source distribution can be built & installed.
|
# build & run tests, build benchmarks
|
||||||
# If there are no other `.tar.gz` files in `dist`, this can be even simpler:
|
- cabal new-build -w ${HC} ${TEST} ${BENCH} all
|
||||||
# `cabal install --force-reinstalls dist/*-*.tar.gz`
|
- if [ "x$TEST" = "x--enable-tests" ]; then cabal new-test -w ${HC} ${TEST} ${BENCH} all; fi
|
||||||
- SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&
|
|
||||||
(cd dist && cabal install --force-reinstalls "$SRC_TGZ")
|
|
||||||
|
|
||||||
|
# cabal check
|
||||||
|
- (cd xmonad-* && cabal check)
|
||||||
|
|
||||||
|
# haddock
|
||||||
|
- rm -rf ./dist-newstyle
|
||||||
|
- if $HADDOCK; then cabal new-haddock -w ${HC} ${TEST} ${BENCH} all; else echo "Skipping haddock generation";fi
|
||||||
|
|
||||||
|
# Build without installed constraints for packages in global-db
|
||||||
|
- if $UNCONSTRAINED; then rm -f cabal.project.local; echo cabal new-build -w ${HC} --disable-tests --disable-benchmarks all; else echo "Not building without installed constraints"; fi
|
||||||
|
|
||||||
|
# REGENDATA ["-o",".travis.yml","xmonad.cabal","libxrandr-dev"]
|
||||||
# EOF
|
# EOF
|
||||||
|
23
CHANGES.md
23
CHANGES.md
@@ -1,5 +1,28 @@
|
|||||||
# Change Log / Release Notes
|
# Change Log / Release Notes
|
||||||
|
|
||||||
|
## 0.14 (July 30, 2018)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* The state file that xmonad uses while restarting itself is now
|
||||||
|
removed after it is processed. This fixes a bug that manifested
|
||||||
|
in several different ways:
|
||||||
|
|
||||||
|
- Names of old workspaces would be resurrected after a restart
|
||||||
|
- Screen sizes would be wrong after changing monitor configuration (#90)
|
||||||
|
- `spawnOnce` stopped working (xmonad/xmonad-contrib#155)
|
||||||
|
- Focus did not follow when moving between workspaces (#87)
|
||||||
|
- etc.
|
||||||
|
|
||||||
|
* Recover old behavior (in 0.12) when `focusFollowsMouse == True`:
|
||||||
|
the focus follows when the mouse enters another workspace
|
||||||
|
but not moving into any window.
|
||||||
|
|
||||||
|
* Compiles with GHC 8.4.1
|
||||||
|
|
||||||
|
* Restored compatability with GHC version prior to 8.0.1 by removing the
|
||||||
|
dependency on directory version 1.2.3.
|
||||||
|
|
||||||
## 0.13 (February 10, 2017)
|
## 0.13 (February 10, 2017)
|
||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
|
@@ -59,6 +59,81 @@ Here are some tips for getting your changes merged into xmonad:
|
|||||||
repository. Include a new configuration file that shows off your
|
repository. Include a new configuration file that shows off your
|
||||||
changes if possible by creating a PR on that repository as well.
|
changes if possible by creating a PR on that repository as well.
|
||||||
|
|
||||||
|
* Make sure you read the section on rebasing and squashing commits
|
||||||
|
below.
|
||||||
|
|
||||||
|
## Rebasing and Squashing Commits
|
||||||
|
|
||||||
|
Under no circumstances should you ever merge the master branch into
|
||||||
|
your feature branch. This makes it nearly impossible to review your
|
||||||
|
changes and we *will not accept your PR* if you do this.
|
||||||
|
|
||||||
|
Instead of merging you should rebase your changes on top of the master
|
||||||
|
branch. If a core team member asks you to "rebase your changes" this
|
||||||
|
is what they are talking about.
|
||||||
|
|
||||||
|
It's also helpful to squash all of your commits so that your pull
|
||||||
|
request only contains a single commit. Again, this makes it easier to
|
||||||
|
review your changes and identify the changes later on in the Git
|
||||||
|
history.
|
||||||
|
|
||||||
|
### How to Rebase Your Changes
|
||||||
|
|
||||||
|
The goal of rebasing is to bring recent changes from the master branch
|
||||||
|
into your feature branch. This often helps resolve conflicts where
|
||||||
|
you have changed a file that also changed in a recently merged pull
|
||||||
|
request (i.e. the `CHANGES.md` file). Here is how you do that.
|
||||||
|
|
||||||
|
1. Make sure that you have a `git remote` configured for the main
|
||||||
|
repository. I like to call this remote `upstream`:
|
||||||
|
|
||||||
|
$ git remote add upstream https://github.com/xmonad/xmonad-contrib.git
|
||||||
|
|
||||||
|
2. Pull from upstream and rewrite your changes on top of master. For
|
||||||
|
this to work you should not have any modified files in your
|
||||||
|
working directory. Run these commands from within your feature
|
||||||
|
branch (the branch you are asking to be merged):
|
||||||
|
|
||||||
|
$ git fetch --all
|
||||||
|
$ git pull --rebase upstream master
|
||||||
|
|
||||||
|
3. If the rebase was successful you can now push your feature branch
|
||||||
|
back to GitHub. You need to force the push since your commits
|
||||||
|
have been rewritten and have new IDs:
|
||||||
|
|
||||||
|
$ git push --force-with-lease
|
||||||
|
|
||||||
|
4. Your pull request should now be conflict-free and only contain the
|
||||||
|
changes that you actually made.
|
||||||
|
|
||||||
|
### How to Squash Commits
|
||||||
|
|
||||||
|
The goal of squashing commits is to produce a clean Git history where
|
||||||
|
each pull request contains just one commit.
|
||||||
|
|
||||||
|
1. Use `git log` to see how many commits you are including in your
|
||||||
|
pull request. (If you've already submitted your pull request you
|
||||||
|
can see this in the GitHub interface.)
|
||||||
|
|
||||||
|
2. Rebase all of those commits into a single commit. Assuming you
|
||||||
|
want to squash the last four (4) commits into a single commit:
|
||||||
|
|
||||||
|
$ git rebase -i HEAD~4
|
||||||
|
|
||||||
|
3. Git will open your editor and display the commits you are
|
||||||
|
rebasing with the word "pick" in front of them.
|
||||||
|
|
||||||
|
4. Leave the first listed commit as "pick" and change the remaining
|
||||||
|
commits from "pick" to "squash".
|
||||||
|
|
||||||
|
5. Save the file and exit your editor. Git will create a new commit
|
||||||
|
and open your editor so you can modify the commit message.
|
||||||
|
|
||||||
|
6. If everything was successful you can push your changed history
|
||||||
|
back up to GitHub:
|
||||||
|
|
||||||
|
$ git push --force-with-lease
|
||||||
|
|
||||||
[xmonad]: https://github.com/xmonad/xmonad
|
[xmonad]: https://github.com/xmonad/xmonad
|
||||||
[xmonad-contrib]: https://github.com/xmonad/xmonad-contrib
|
[xmonad-contrib]: https://github.com/xmonad/xmonad-contrib
|
||||||
[xmonad-testing]: https://github.com/xmonad/xmonad-testing
|
[xmonad-testing]: https://github.com/xmonad/xmonad-testing
|
||||||
|
@@ -221,9 +221,9 @@ keys conf@(XConfig {XMonad.modMask = modMask}) = M.fromList $
|
|||||||
, ((modMask .|. shiftMask, xK_q ), io (exitWith ExitSuccess)) -- %! Quit xmonad
|
, ((modMask .|. shiftMask, xK_q ), io (exitWith ExitSuccess)) -- %! Quit xmonad
|
||||||
, ((modMask , xK_q ), spawn "if type xmonad; then xmonad --recompile && xmonad --restart; else xmessage xmonad not in \\$PATH: \"$PATH\"; fi") -- %! Restart xmonad
|
, ((modMask , xK_q ), spawn "if type xmonad; then xmonad --recompile && xmonad --restart; else xmessage xmonad not in \\$PATH: \"$PATH\"; fi") -- %! Restart xmonad
|
||||||
|
|
||||||
, ((modMask .|. shiftMask, xK_slash ), spawn ("echo \"" ++ help ++ "\" | xmessage -file -")) -- %! Run xmessage with a summary of the default keybindings (useful for beginners)
|
, ((modMask .|. shiftMask, xK_slash ), helpCommand)
|
||||||
-- repeat the binding for non-American layout keyboards
|
-- repeat the binding for non-American layout keyboards
|
||||||
, ((modMask , xK_question), spawn ("echo \"" ++ help ++ "\" | xmessage -file -"))
|
, ((modMask , xK_question), helpCommand)
|
||||||
]
|
]
|
||||||
++
|
++
|
||||||
-- mod-[1..9] %! Switch to workspace N
|
-- mod-[1..9] %! Switch to workspace N
|
||||||
@@ -237,6 +237,9 @@ keys conf@(XConfig {XMonad.modMask = modMask}) = M.fromList $
|
|||||||
[((m .|. modMask, key), screenWorkspace sc >>= flip whenJust (windows . f))
|
[((m .|. modMask, key), screenWorkspace sc >>= flip whenJust (windows . f))
|
||||||
| (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]
|
| (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]
|
||||||
, (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]
|
, (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]
|
||||||
|
where
|
||||||
|
helpCommand :: X ()
|
||||||
|
helpCommand = spawn ("echo " ++ show help ++ " | xmessage -file -") -- %! Run xmessage with a summary of the default keybindings (useful for beginners)
|
||||||
|
|
||||||
-- | Mouse bindings: default actions bound to mouse events
|
-- | Mouse bindings: default actions bound to mouse events
|
||||||
mouseBindings :: XConfig Layout -> M.Map (KeyMask, Button) (Window -> X ())
|
mouseBindings :: XConfig Layout -> M.Map (KeyMask, Button) (Window -> X ())
|
||||||
|
@@ -39,6 +39,7 @@ import qualified Control.Exception.Extensible as E
|
|||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
|
import Data.Semigroup
|
||||||
import Data.Default
|
import Data.Default
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.IO
|
import System.IO
|
||||||
@@ -56,7 +57,8 @@ import Graphics.X11.Xlib.Extras (getWindowAttributes, WindowAttributes, Event)
|
|||||||
import Data.Typeable
|
import Data.Typeable
|
||||||
import Data.List ((\\))
|
import Data.List ((\\))
|
||||||
import Data.Maybe (isJust,fromMaybe)
|
import Data.Maybe (isJust,fromMaybe)
|
||||||
import Data.Monoid
|
import Data.Monoid hiding ((<>))
|
||||||
|
import System.Environment (lookupEnv)
|
||||||
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
@@ -71,7 +73,7 @@ data XState = XState
|
|||||||
, extensibleState :: !(M.Map String (Either String StateExtension))
|
, extensibleState :: !(M.Map String (Either String StateExtension))
|
||||||
-- ^ stores custom state information.
|
-- ^ stores custom state information.
|
||||||
--
|
--
|
||||||
-- The module "XMonad.Utils.ExtensibleState" in xmonad-contrib
|
-- The module "XMonad.Util.ExtensibleState" in xmonad-contrib
|
||||||
-- provides additional information and a simple interface for using this.
|
-- provides additional information and a simple interface for using this.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +153,9 @@ instance Applicative X where
|
|||||||
pure = return
|
pure = return
|
||||||
(<*>) = ap
|
(<*>) = ap
|
||||||
|
|
||||||
|
instance Semigroup a => Semigroup (X a) where
|
||||||
|
(<>) = liftM2 (<>)
|
||||||
|
|
||||||
instance (Monoid a) => Monoid (X a) where
|
instance (Monoid a) => Monoid (X a) where
|
||||||
mempty = return mempty
|
mempty = return mempty
|
||||||
mappend = liftM2 mappend
|
mappend = liftM2 mappend
|
||||||
@@ -165,6 +170,9 @@ newtype Query a = Query (ReaderT Window X a)
|
|||||||
runQuery :: Query a -> Window -> X a
|
runQuery :: Query a -> Window -> X a
|
||||||
runQuery (Query m) w = runReaderT m w
|
runQuery (Query m) w = runReaderT m w
|
||||||
|
|
||||||
|
instance Semigroup a => Semigroup (Query a) where
|
||||||
|
(<>) = liftM2 (<>)
|
||||||
|
|
||||||
instance Monoid a => Monoid (Query a) where
|
instance Monoid a => Monoid (Query a) where
|
||||||
mempty = return mempty
|
mempty = return mempty
|
||||||
mappend = liftM2 mappend
|
mappend = liftM2 mappend
|
||||||
@@ -460,7 +468,7 @@ getXMonadDir :: MonadIO m => m String
|
|||||||
getXMonadDir =
|
getXMonadDir =
|
||||||
findFirstDirWithEnv "XMONAD_CONFIG_DIR"
|
findFirstDirWithEnv "XMONAD_CONFIG_DIR"
|
||||||
[ getAppUserDataDirectory "xmonad"
|
[ getAppUserDataDirectory "xmonad"
|
||||||
, getXdgDirectory XdgConfig "xmonad"
|
, getXDGDirectory XDGConfig "xmonad"
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | Return the path to the xmonad cache directory. This directory is
|
-- | Return the path to the xmonad cache directory. This directory is
|
||||||
@@ -480,7 +488,7 @@ getXMonadCacheDir :: MonadIO m => m String
|
|||||||
getXMonadCacheDir =
|
getXMonadCacheDir =
|
||||||
findFirstDirWithEnv "XMONAD_CACHE_DIR"
|
findFirstDirWithEnv "XMONAD_CACHE_DIR"
|
||||||
[ getAppUserDataDirectory "xmonad"
|
[ getAppUserDataDirectory "xmonad"
|
||||||
, getXdgDirectory XdgCache "xmonad"
|
, getXDGDirectory XDGCache "xmonad"
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | Return the path to the xmonad data directory. This directory is
|
-- | Return the path to the xmonad data directory. This directory is
|
||||||
@@ -500,7 +508,7 @@ getXMonadDataDir :: MonadIO m => m String
|
|||||||
getXMonadDataDir =
|
getXMonadDataDir =
|
||||||
findFirstDirWithEnv "XMONAD_DATA_DIR"
|
findFirstDirWithEnv "XMONAD_DATA_DIR"
|
||||||
[ getAppUserDataDirectory "xmonad"
|
[ getAppUserDataDirectory "xmonad"
|
||||||
, getXdgDirectory XdgData "xmonad"
|
, getXDGDirectory XDGData "xmonad"
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | Helper function that will find the first existing directory and
|
-- | Helper function that will find the first existing directory and
|
||||||
@@ -536,6 +544,27 @@ findFirstDirWithEnv envName paths = do
|
|||||||
Nothing -> findFirstDirOf paths
|
Nothing -> findFirstDirOf paths
|
||||||
Just envPath -> findFirstDirOf (return envPath:paths)
|
Just envPath -> findFirstDirOf (return envPath:paths)
|
||||||
|
|
||||||
|
-- | Helper function to retrieve the various XDG directories.
|
||||||
|
-- This has been based on the implementation shipped with GHC version 8.0.1 or
|
||||||
|
-- higher. Put here to preserve compatibility with older GHC versions.
|
||||||
|
getXDGDirectory :: XDGDirectory -> FilePath -> IO FilePath
|
||||||
|
getXDGDirectory xdgDir suffix =
|
||||||
|
normalise . (</> suffix) <$>
|
||||||
|
case xdgDir of
|
||||||
|
XDGData -> get "XDG_DATA_HOME" ".local/share"
|
||||||
|
XDGConfig -> get "XDG_CONFIG_HOME" ".config"
|
||||||
|
XDGCache -> get "XDG_CACHE_HOME" ".cache"
|
||||||
|
where
|
||||||
|
get name fallback = do
|
||||||
|
env <- lookupEnv name
|
||||||
|
case env of
|
||||||
|
Nothing -> fallback'
|
||||||
|
Just path
|
||||||
|
| isRelative path -> fallback'
|
||||||
|
| otherwise -> return path
|
||||||
|
where
|
||||||
|
fallback' = (</> fallback) <$> getHomeDirectory
|
||||||
|
data XDGDirectory = XDGData | XDGConfig | XDGCache
|
||||||
|
|
||||||
-- | Get the name of the file used to store the xmonad window state.
|
-- | Get the name of the file used to store the xmonad window state.
|
||||||
stateFileName :: (Functor m, MonadIO m) => m FilePath
|
stateFileName :: (Functor m, MonadIO m) => m FilePath
|
||||||
|
@@ -368,7 +368,9 @@ handle e@(CrossingEvent {ev_window = w, ev_event_type = t})
|
|||||||
dpy <- asks display
|
dpy <- asks display
|
||||||
root <- asks theRoot
|
root <- asks theRoot
|
||||||
(_, _, w', _, _, _, _, _) <- io $ queryPointer dpy root
|
(_, _, w', _, _, _, _, _) <- io $ queryPointer dpy root
|
||||||
when (w == w') (focus w)
|
-- when Xlib cannot find a child that contains the pointer,
|
||||||
|
-- it returns None(0)
|
||||||
|
when (w' == 0 || w == w') (focus w)
|
||||||
|
|
||||||
-- left a window, check if we need to focus root
|
-- left a window, check if we need to focus root
|
||||||
handle e@(CrossingEvent {ev_event_type = t})
|
handle e@(CrossingEvent {ev_event_type = t})
|
||||||
|
@@ -465,14 +465,21 @@ writeStateToFile = do
|
|||||||
catchIO (writeFile path $ show stateData)
|
catchIO (writeFile path $ show stateData)
|
||||||
|
|
||||||
-- | Read the state of a previous xmonad instance from a file and
|
-- | Read the state of a previous xmonad instance from a file and
|
||||||
-- return that state.
|
-- return that state. The state file is removed after reading it.
|
||||||
readStateFile :: (LayoutClass l Window, Read (l Window)) => XConfig l -> X (Maybe XState)
|
readStateFile :: (LayoutClass l Window, Read (l Window)) => XConfig l -> X (Maybe XState)
|
||||||
readStateFile xmc = do
|
readStateFile xmc = do
|
||||||
path <- stateFileName
|
path <- stateFileName
|
||||||
raw <- userCode $ io (readFile path)
|
|
||||||
|
-- I'm trying really hard here to make sure we read the entire
|
||||||
|
-- contents of the file before it is removed from the file system.
|
||||||
|
sf' <- userCode . io $ do
|
||||||
|
raw <- withFile path ReadMode readStrict
|
||||||
|
return $! maybeRead reads raw
|
||||||
|
|
||||||
|
io (removeFile path)
|
||||||
|
|
||||||
return $ do
|
return $ do
|
||||||
sf <- maybeRead reads =<< raw
|
sf <- join sf'
|
||||||
|
|
||||||
let winset = W.ensureTags layout (workspaces xmc) $ W.mapLayout (fromMaybe layout . maybeRead lreads) (sfWins sf)
|
let winset = W.ensureTags layout (workspaces xmc) $ W.mapLayout (fromMaybe layout . maybeRead lreads) (sfWins sf)
|
||||||
extState = M.fromList . map (second Left) $ sfExt sf
|
extState = M.fromList . map (second Left) $ sfExt sf
|
||||||
@@ -491,6 +498,9 @@ readStateFile xmc = do
|
|||||||
[(x, "")] -> Just x
|
[(x, "")] -> Just x
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
|
readStrict :: Handle -> IO String
|
||||||
|
readStrict h = hGetContents h >>= \s -> length s `seq` return s
|
||||||
|
|
||||||
-- | Migrate state from a previously running xmonad instance that used
|
-- | Migrate state from a previously running xmonad instance that used
|
||||||
-- the older @--resume@ technique.
|
-- the older @--resume@ technique.
|
||||||
{-# DEPRECATED migrateState "will be removed some point in the future." #-}
|
{-# DEPRECATED migrateState "will be removed some point in the future." #-}
|
||||||
|
21
xmonad.cabal
21
xmonad.cabal
@@ -1,5 +1,5 @@
|
|||||||
name: xmonad
|
name: xmonad
|
||||||
version: 0.13
|
version: 0.14
|
||||||
homepage: http://xmonad.org
|
homepage: http://xmonad.org
|
||||||
synopsis: A tiling window manager
|
synopsis: A tiling window manager
|
||||||
description:
|
description:
|
||||||
@@ -32,7 +32,9 @@ tested-with:
|
|||||||
GHC==7.6.3,
|
GHC==7.6.3,
|
||||||
GHC==7.8.4,
|
GHC==7.8.4,
|
||||||
GHC==7.10.3,
|
GHC==7.10.3,
|
||||||
GHC==8.0.1
|
GHC==8.0.2,
|
||||||
|
GHC==8.2.2,
|
||||||
|
GHC==8.4.3
|
||||||
|
|
||||||
data-files: man/xmonad.hs, man/xmonad.1, man/xmonad.1.html
|
data-files: man/xmonad.hs, man/xmonad.1, man/xmonad.1.html
|
||||||
|
|
||||||
@@ -50,11 +52,6 @@ flag generatemanpage
|
|||||||
default: False
|
default: False
|
||||||
manual: True
|
manual: True
|
||||||
|
|
||||||
flag profiling
|
|
||||||
description: Enable profiling
|
|
||||||
default: False
|
|
||||||
manual: True
|
|
||||||
|
|
||||||
library
|
library
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
exposed-modules: XMonad
|
exposed-modules: XMonad
|
||||||
@@ -70,7 +67,7 @@ library
|
|||||||
build-depends: base < 5 && >=3,
|
build-depends: base < 5 && >=3,
|
||||||
containers,
|
containers,
|
||||||
data-default,
|
data-default,
|
||||||
directory >= 1.2.3,
|
directory,
|
||||||
extensible-exceptions,
|
extensible-exceptions,
|
||||||
filepath,
|
filepath,
|
||||||
setlocale,
|
setlocale,
|
||||||
@@ -78,7 +75,8 @@ library
|
|||||||
process,
|
process,
|
||||||
unix,
|
unix,
|
||||||
utf8-string >= 0.3 && < 1.1,
|
utf8-string >= 0.3 && < 1.1,
|
||||||
X11>=1.8 && < 1.9
|
X11>=1.8 && < 1.10,
|
||||||
|
semigroups
|
||||||
|
|
||||||
if true
|
if true
|
||||||
ghc-options: -funbox-strict-fields -Wall
|
ghc-options: -funbox-strict-fields -Wall
|
||||||
@@ -88,11 +86,6 @@ library
|
|||||||
if impl(ghc < 7.0.0)
|
if impl(ghc < 7.0.0)
|
||||||
extensions: UndecidableInstances
|
extensions: UndecidableInstances
|
||||||
-- needed for XMonad.Config's instance Default (XConfig a)
|
-- needed for XMonad.Config's instance Default (XConfig a)
|
||||||
|
|
||||||
|
|
||||||
if flag(profiling)
|
|
||||||
ghc-prof-options: -prof -auto-all
|
|
||||||
|
|
||||||
if flag(testing)
|
if flag(testing)
|
||||||
buildable: False
|
buildable: False
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user