mirror of
https://github.com/xmonad/xmonad.git
synced 2025-08-03 05:31:54 -07:00
Compare commits
147 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1396343a58 | ||
|
c9334fbae7 | ||
|
c496c31158 | ||
|
31f63bb162 | ||
|
ddb4292d5a | ||
|
765e059470 | ||
|
c4cf4715f7 | ||
|
fa124f5658 | ||
|
855ff2f73c | ||
|
5a04fa185d | ||
|
706f54862c | ||
|
1d43cd203f | ||
|
8421b100dd | ||
|
0156e2963b | ||
|
32afd5e7e8 | ||
|
404e50d560 | ||
|
05d6037f53 | ||
|
2f58567912 | ||
|
f2aa84e102 | ||
|
2b7e278f7f | ||
|
bd69d20d01 | ||
|
35fa7bf4a2 | ||
|
a239a00977 | ||
|
afb66dd55c | ||
|
1b7dea7acc | ||
|
8e820945f4 | ||
|
21cc6ebd93 | ||
|
050ba6420d | ||
|
67b5510dde | ||
|
327c2cf0c1 | ||
|
96b3628b54 | ||
|
dc4d304802 | ||
|
c264e4cdb3 | ||
|
bb895d8415 | ||
|
897597463a | ||
|
937493256d | ||
|
8ec512b437 | ||
|
e563e01a5f | ||
|
0e4c1e6837 | ||
|
5c2ba06902 | ||
|
efffa8946a | ||
|
431bb4b57c | ||
|
3c80296733 | ||
|
f289b3b134 | ||
|
0932779f15 | ||
|
9138046ec5 | ||
|
a24e9b4c7f | ||
|
1aac6611d8 | ||
|
51e507e953 | ||
|
10abd059b7 | ||
|
d4c607c4f9 | ||
|
28bc7dacde | ||
|
b7a76a5e8c | ||
|
58f3e8c6f1 | ||
|
00045cfc2a | ||
|
69134f9e8a | ||
|
025a78508c | ||
|
b03fa7a67b | ||
|
64fbf6a09d | ||
|
eeac754ac7 | ||
|
5ee76ca48f | ||
|
aa9dd2696a | ||
|
19cba6b25f | ||
|
a09ca446fb | ||
|
5641038500 | ||
|
990555c8ab | ||
|
a207e30751 | ||
|
970893f556 | ||
|
460096dfc5 | ||
|
0817c6a7ff | ||
|
b59473b016 | ||
|
c2aeaffc03 | ||
|
7f95f5ef07 | ||
|
57b715972b | ||
|
a9866836d9 | ||
|
099233812e | ||
|
9cb13bdd3d | ||
|
86bb4d2a21 | ||
|
30103efbc8 | ||
|
a16541b834 | ||
|
202fecf7ba | ||
|
dd1e02555e | ||
|
4931bc4e41 | ||
|
67267b7346 | ||
|
4806b51a23 | ||
|
98e5d1583d | ||
|
dc48e9e9c9 | ||
|
572d02d8e8 | ||
|
f53db04285 | ||
|
2324d21202 | ||
|
f2c9c75f67 | ||
|
1364ee4b1f | ||
|
a17fa0d28b | ||
|
b394435443 | ||
|
faf5cf7b27 | ||
|
9d0fd62cb2 | ||
|
386d4e6295 | ||
|
ea295dabcc | ||
|
4b3e5e0d07 | ||
|
4b2107a07a | ||
|
3ae5f46052 | ||
|
f734f19c1a | ||
|
391c0fc0c9 | ||
|
5ecdf7591d | ||
|
301428e5df | ||
|
63f73e18f9 | ||
|
57c3a13125 | ||
|
e6329968ff | ||
|
c1670303c0 | ||
|
1d1c012cb9 | ||
|
a19ffb0404 | ||
|
5aa70bd88a | ||
|
2502fd8d55 | ||
|
d0942e37ad | ||
|
40f8246080 | ||
|
be8fd7fdc9 | ||
|
6e35910b62 | ||
|
2f2d105098 | ||
|
cd86480ff7 | ||
|
5c7c28060c | ||
|
78719507a9 | ||
|
f4d25fcef4 | ||
|
314390937c | ||
|
cf4d6f31b1 | ||
|
044d9244e5 | ||
|
ab99c17a68 | ||
|
d170e99bc5 | ||
|
96452213f4 | ||
|
c19eb06807 | ||
|
6d7da8dc25 | ||
|
f96b3f0398 | ||
|
34f257ad6f | ||
|
f94ad61a27 | ||
|
3977a7a4e2 | ||
|
3cd839f0ac | ||
|
a9abc4e09c | ||
|
25a4ed69da | ||
|
262dc4779f | ||
|
a2259bb309 | ||
|
3d8238b35d | ||
|
fd9de8903f | ||
|
fb1f33258e | ||
|
d0f12af1ae | ||
|
df6b40c980 | ||
|
b771abeadc | ||
|
2db596fbe8 | ||
|
0f31b24bd2 |
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
6
.github/workflows/generatemanpage.yml
vendored
6
.github/workflows/generatemanpage.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone project
|
- name: Clone project
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
@@ -26,8 +26,8 @@ jobs:
|
|||||||
- name: Commit/push if changed
|
- name: Commit/push if changed
|
||||||
run: |
|
run: |
|
||||||
set -ex
|
set -ex
|
||||||
git config user.name github-actions
|
git config user.name 'github-actions[bot]'
|
||||||
git config user.email github-actions@github.com
|
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
||||||
git diff --quiet --exit-code && exit
|
git diff --quiet --exit-code && exit
|
||||||
git commit -a -m 'man: Update'
|
git commit -a -m 'man: Update'
|
||||||
git push
|
git push
|
||||||
|
25
.github/workflows/haskell-ci-hackage.patch
vendored
25
.github/workflows/haskell-ci-hackage.patch
vendored
@@ -37,32 +37,37 @@ set in GitHub repository secrets.
|
|||||||
jobs:
|
jobs:
|
||||||
linux:
|
linux:
|
||||||
name: Haskell-CI - Linux - ${{ matrix.compiler }}
|
name: Haskell-CI - Linux - ${{ matrix.compiler }}
|
||||||
@@ -31,6 +38,7 @@
|
@@ -33,6 +40,7 @@
|
||||||
compilerVersion: 9.0.2
|
compilerVersion: 9.8.1
|
||||||
setup-method: ghcup
|
setup-method: ghcup
|
||||||
allow-failure: false
|
allow-failure: false
|
||||||
+ upload: true
|
+ upload: true
|
||||||
- compiler: ghc-8.10.7
|
- compiler: ghc-9.6.4
|
||||||
compilerKind: ghc
|
compilerKind: ghc
|
||||||
compilerVersion: 8.10.7
|
compilerVersion: 9.6.4
|
||||||
@@ -209,8 +217,80 @@
|
@@ -257,6 +265,10 @@
|
||||||
${CABAL} -vnormal check
|
|
||||||
- name: haddock
|
- name: haddock
|
||||||
run: |
|
run: |
|
||||||
- $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
|
$CABAL v2-haddock --disable-documentation $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
|
||||||
|
+ - name: haddock for hackage
|
||||||
|
+ if: matrix.upload
|
||||||
|
+ run: |
|
||||||
+ $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH --haddock-for-hackage --builddir $GITHUB_WORKSPACE/haddock all
|
+ $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH --haddock-for-hackage --builddir $GITHUB_WORKSPACE/haddock all
|
||||||
- name: unconstrained build
|
- name: unconstrained build
|
||||||
run: |
|
run: |
|
||||||
rm -f cabal.project.local
|
rm -f cabal.project.local
|
||||||
$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
|
@@ -267,3 +279,75 @@
|
||||||
|
with:
|
||||||
|
key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
|
||||||
|
path: ~/.cabal/store
|
||||||
+ - name: upload artifacts (sdist)
|
+ - name: upload artifacts (sdist)
|
||||||
+ if: matrix.upload
|
+ if: matrix.upload
|
||||||
+ uses: actions/upload-artifact@v2
|
+ uses: actions/upload-artifact@v3
|
||||||
+ with:
|
+ with:
|
||||||
+ path: ${{ github.workspace }}/sdist/*.tar.gz
|
+ path: ${{ github.workspace }}/sdist/*.tar.gz
|
||||||
+ - name: upload artifacts (haddock)
|
+ - name: upload artifacts (haddock)
|
||||||
+ if: matrix.upload
|
+ if: matrix.upload
|
||||||
+ uses: actions/upload-artifact@v2
|
+ uses: actions/upload-artifact@v3
|
||||||
+ with:
|
+ with:
|
||||||
+ path: ${{ github.workspace }}/haddock/*-docs.tar.gz
|
+ path: ${{ github.workspace }}/haddock/*-docs.tar.gz
|
||||||
+ - name: hackage upload (candidate)
|
+ - name: hackage upload (candidate)
|
||||||
|
93
.github/workflows/haskell-ci.yml
vendored
93
.github/workflows/haskell-ci.yml
vendored
@@ -8,9 +8,9 @@
|
|||||||
#
|
#
|
||||||
# For more information, see https://github.com/haskell-CI/haskell-ci
|
# For more information, see https://github.com/haskell-CI/haskell-ci
|
||||||
#
|
#
|
||||||
# version: 0.14.3
|
# version: 0.17.20240109
|
||||||
#
|
#
|
||||||
# REGENDATA ("0.14.3",["github","cabal.project"])
|
# REGENDATA ("0.17.20240109",["github","cabal.project"])
|
||||||
#
|
#
|
||||||
name: Haskell-CI
|
name: Haskell-CI
|
||||||
on:
|
on:
|
||||||
@@ -26,7 +26,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
linux:
|
linux:
|
||||||
name: Haskell-CI - Linux - ${{ matrix.compiler }}
|
name: Haskell-CI - Linux - ${{ matrix.compiler }}
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-20.04
|
||||||
timeout-minutes:
|
timeout-minutes:
|
||||||
60
|
60
|
||||||
container:
|
container:
|
||||||
@@ -35,9 +35,25 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- compiler: ghc-9.2.2
|
- compiler: ghc-9.8.1
|
||||||
compilerKind: ghc
|
compilerKind: ghc
|
||||||
compilerVersion: 9.2.2
|
compilerVersion: 9.8.1
|
||||||
|
setup-method: ghcup
|
||||||
|
allow-failure: false
|
||||||
|
upload: true
|
||||||
|
- compiler: ghc-9.6.4
|
||||||
|
compilerKind: ghc
|
||||||
|
compilerVersion: 9.6.4
|
||||||
|
setup-method: ghcup
|
||||||
|
allow-failure: false
|
||||||
|
- compiler: ghc-9.4.8
|
||||||
|
compilerKind: ghc
|
||||||
|
compilerVersion: 9.4.8
|
||||||
|
setup-method: ghcup
|
||||||
|
allow-failure: false
|
||||||
|
- compiler: ghc-9.2.8
|
||||||
|
compilerKind: ghc
|
||||||
|
compilerVersion: 9.2.8
|
||||||
setup-method: ghcup
|
setup-method: ghcup
|
||||||
allow-failure: false
|
allow-failure: false
|
||||||
- compiler: ghc-9.0.2
|
- compiler: ghc-9.0.2
|
||||||
@@ -45,7 +61,6 @@ jobs:
|
|||||||
compilerVersion: 9.0.2
|
compilerVersion: 9.0.2
|
||||||
setup-method: ghcup
|
setup-method: ghcup
|
||||||
allow-failure: false
|
allow-failure: false
|
||||||
upload: true
|
|
||||||
- compiler: ghc-8.10.7
|
- compiler: ghc-8.10.7
|
||||||
compilerKind: ghc
|
compilerKind: ghc
|
||||||
compilerVersion: 8.10.7
|
compilerVersion: 8.10.7
|
||||||
@@ -61,11 +76,6 @@ jobs:
|
|||||||
compilerVersion: 8.6.5
|
compilerVersion: 8.6.5
|
||||||
setup-method: hvr-ppa
|
setup-method: hvr-ppa
|
||||||
allow-failure: false
|
allow-failure: false
|
||||||
- compiler: ghc-8.4.4
|
|
||||||
compilerKind: ghc
|
|
||||||
compilerVersion: 8.4.4
|
|
||||||
setup-method: hvr-ppa
|
|
||||||
allow-failure: false
|
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
- name: apt
|
- name: apt
|
||||||
@@ -74,10 +84,10 @@ jobs:
|
|||||||
apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
|
apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
|
||||||
if [ "${{ matrix.setup-method }}" = ghcup ]; then
|
if [ "${{ matrix.setup-method }}" = ghcup ]; then
|
||||||
mkdir -p "$HOME/.ghcup/bin"
|
mkdir -p "$HOME/.ghcup/bin"
|
||||||
curl -sL https://downloads.haskell.org/ghcup/0.1.17.5/x86_64-linux-ghcup-0.1.17.5 > "$HOME/.ghcup/bin/ghcup"
|
curl -sL https://downloads.haskell.org/ghcup/0.1.20.0/x86_64-linux-ghcup-0.1.20.0 > "$HOME/.ghcup/bin/ghcup"
|
||||||
chmod a+x "$HOME/.ghcup/bin/ghcup"
|
chmod a+x "$HOME/.ghcup/bin/ghcup"
|
||||||
"$HOME/.ghcup/bin/ghcup" install ghc "$HCVER"
|
"$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)
|
||||||
"$HOME/.ghcup/bin/ghcup" install cabal 3.6.2.0
|
"$HOME/.ghcup/bin/ghcup" install cabal 3.10.2.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y libx11-dev libxext-dev libxinerama-dev libxrandr-dev libxss-dev
|
apt-get install -y libx11-dev libxext-dev libxinerama-dev libxrandr-dev libxss-dev
|
||||||
else
|
else
|
||||||
@@ -85,9 +95,9 @@ jobs:
|
|||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y "$HCNAME" libx11-dev libxext-dev libxinerama-dev libxrandr-dev libxss-dev
|
apt-get install -y "$HCNAME" libx11-dev libxext-dev libxinerama-dev libxrandr-dev libxss-dev
|
||||||
mkdir -p "$HOME/.ghcup/bin"
|
mkdir -p "$HOME/.ghcup/bin"
|
||||||
curl -sL https://downloads.haskell.org/ghcup/0.1.17.5/x86_64-linux-ghcup-0.1.17.5 > "$HOME/.ghcup/bin/ghcup"
|
curl -sL https://downloads.haskell.org/ghcup/0.1.20.0/x86_64-linux-ghcup-0.1.20.0 > "$HOME/.ghcup/bin/ghcup"
|
||||||
chmod a+x "$HOME/.ghcup/bin/ghcup"
|
chmod a+x "$HOME/.ghcup/bin/ghcup"
|
||||||
"$HOME/.ghcup/bin/ghcup" install cabal 3.6.2.0
|
"$HOME/.ghcup/bin/ghcup" install cabal 3.10.2.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
|
||||||
fi
|
fi
|
||||||
env:
|
env:
|
||||||
HCKIND: ${{ matrix.compilerKind }}
|
HCKIND: ${{ matrix.compilerKind }}
|
||||||
@@ -101,17 +111,19 @@ jobs:
|
|||||||
echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
|
echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
|
||||||
HCDIR=/opt/$HCKIND/$HCVER
|
HCDIR=/opt/$HCKIND/$HCVER
|
||||||
if [ "${{ matrix.setup-method }}" = ghcup ]; then
|
if [ "${{ matrix.setup-method }}" = ghcup ]; then
|
||||||
HC=$HOME/.ghcup/bin/$HCKIND-$HCVER
|
HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER")
|
||||||
|
HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#')
|
||||||
|
HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#')
|
||||||
echo "HC=$HC" >> "$GITHUB_ENV"
|
echo "HC=$HC" >> "$GITHUB_ENV"
|
||||||
echo "HCPKG=$HOME/.ghcup/bin/$HCKIND-pkg-$HCVER" >> "$GITHUB_ENV"
|
echo "HCPKG=$HCPKG" >> "$GITHUB_ENV"
|
||||||
echo "HADDOCK=$HOME/.ghcup/bin/haddock-$HCVER" >> "$GITHUB_ENV"
|
echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV"
|
||||||
echo "CABAL=$HOME/.ghcup/bin/cabal-3.6.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
|
echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
|
||||||
else
|
else
|
||||||
HC=$HCDIR/bin/$HCKIND
|
HC=$HCDIR/bin/$HCKIND
|
||||||
echo "HC=$HC" >> "$GITHUB_ENV"
|
echo "HC=$HC" >> "$GITHUB_ENV"
|
||||||
echo "HCPKG=$HCDIR/bin/$HCKIND-pkg" >> "$GITHUB_ENV"
|
echo "HCPKG=$HCDIR/bin/$HCKIND-pkg" >> "$GITHUB_ENV"
|
||||||
echo "HADDOCK=$HCDIR/bin/haddock" >> "$GITHUB_ENV"
|
echo "HADDOCK=$HCDIR/bin/haddock" >> "$GITHUB_ENV"
|
||||||
echo "CABAL=$HOME/.ghcup/bin/cabal-3.6.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
|
echo "CABAL=$HOME/.ghcup/bin/cabal-3.10.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
|
HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
|
||||||
@@ -160,28 +172,17 @@ jobs:
|
|||||||
- name: update cabal index
|
- name: update cabal index
|
||||||
run: |
|
run: |
|
||||||
$CABAL v2-update -v
|
$CABAL v2-update -v
|
||||||
- name: cache (tools)
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
key: ${{ runner.os }}-${{ matrix.compiler }}-tools-c0dbbd39
|
|
||||||
path: ~/.haskell-ci-tools
|
|
||||||
- name: install cabal-plan
|
- name: install cabal-plan
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/.cabal/bin
|
mkdir -p $HOME/.cabal/bin
|
||||||
curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz
|
curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.7.3.0/cabal-plan-0.7.3.0-x86_64-linux.xz > cabal-plan.xz
|
||||||
echo 'de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz' | sha256sum -c -
|
echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c -
|
||||||
xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan
|
xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan
|
||||||
rm -f cabal-plan.xz
|
rm -f cabal-plan.xz
|
||||||
chmod a+x $HOME/.cabal/bin/cabal-plan
|
chmod a+x $HOME/.cabal/bin/cabal-plan
|
||||||
cabal-plan --version
|
cabal-plan --version
|
||||||
- name: install hlint
|
|
||||||
run: |
|
|
||||||
if [ $((HCNUMVER >= 90000 && HCNUMVER < 90200)) -ne 0 ] ; then HLINTVER=$(cd /tmp && (${CABAL} v2-install -v $ARG_COMPILER --dry-run hlint --constraint='hlint >=3.4 && <3.5' | perl -ne 'if (/\bhlint-(\d+(\.\d+)*)\b/) { print "$1"; last; }')); echo "HLint version $HLINTVER" ; fi
|
|
||||||
if [ $((HCNUMVER >= 90000 && HCNUMVER < 90200)) -ne 0 ] ; then if [ ! -e $HOME/.haskell-ci-tools/hlint-$HLINTVER/hlint ]; then echo "Downloading HLint version $HLINTVER"; mkdir -p $HOME/.haskell-ci-tools; curl --write-out 'Status Code: %{http_code} Redirects: %{num_redirects} Total time: %{time_total} Total Dsize: %{size_download}\n' --silent --location --output $HOME/.haskell-ci-tools/hlint-$HLINTVER.tar.gz "https://github.com/ndmitchell/hlint/releases/download/v$HLINTVER/hlint-$HLINTVER-x86_64-linux.tar.gz"; tar -xzv -f $HOME/.haskell-ci-tools/hlint-$HLINTVER.tar.gz -C $HOME/.haskell-ci-tools; fi ; fi
|
|
||||||
if [ $((HCNUMVER >= 90000 && HCNUMVER < 90200)) -ne 0 ] ; then mkdir -p $CABAL_DIR/bin && ln -sf "$HOME/.haskell-ci-tools/hlint-$HLINTVER/hlint" $CABAL_DIR/bin/hlint ; fi
|
|
||||||
if [ $((HCNUMVER >= 90000 && HCNUMVER < 90200)) -ne 0 ] ; then hlint --version ; fi
|
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: source
|
path: source
|
||||||
- name: initial cabal.project for sdist
|
- name: initial cabal.project for sdist
|
||||||
@@ -220,8 +221,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all
|
$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all
|
||||||
cabal-plan
|
cabal-plan
|
||||||
- name: cache
|
- name: restore cache
|
||||||
uses: actions/cache@v2
|
uses: actions/cache/restore@v3
|
||||||
with:
|
with:
|
||||||
key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
|
key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
|
||||||
path: ~/.cabal/store
|
path: ~/.cabal/store
|
||||||
@@ -239,29 +240,35 @@ jobs:
|
|||||||
- name: tests
|
- name: tests
|
||||||
run: |
|
run: |
|
||||||
$CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --test-show-details=direct
|
$CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --test-show-details=direct
|
||||||
- name: hlint
|
|
||||||
run: |
|
|
||||||
if [ $((HCNUMVER >= 90000 && HCNUMVER < 90200)) -ne 0 ] ; then (cd ${PKGDIR_xmonad} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 src) ; fi
|
|
||||||
if [ $((HCNUMVER >= 90000 && HCNUMVER < 90200)) -ne 0 ] ; then (cd ${PKGDIR_xmonad} && hlint -h ${GITHUB_WORKSPACE}/source/.hlint.yaml -XHaskell2010 .) ; fi
|
|
||||||
- name: cabal check
|
- name: cabal check
|
||||||
run: |
|
run: |
|
||||||
cd ${PKGDIR_xmonad} || false
|
cd ${PKGDIR_xmonad} || false
|
||||||
${CABAL} -vnormal check
|
${CABAL} -vnormal check
|
||||||
- name: haddock
|
- name: haddock
|
||||||
|
run: |
|
||||||
|
$CABAL v2-haddock --disable-documentation $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
|
||||||
|
- name: haddock for hackage
|
||||||
|
if: matrix.upload
|
||||||
run: |
|
run: |
|
||||||
$CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH --haddock-for-hackage --builddir $GITHUB_WORKSPACE/haddock all
|
$CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH --haddock-for-hackage --builddir $GITHUB_WORKSPACE/haddock all
|
||||||
- name: unconstrained build
|
- name: unconstrained build
|
||||||
run: |
|
run: |
|
||||||
rm -f cabal.project.local
|
rm -f cabal.project.local
|
||||||
$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
|
$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
|
||||||
|
- name: save cache
|
||||||
|
uses: actions/cache/save@v3
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
|
||||||
|
path: ~/.cabal/store
|
||||||
- name: upload artifacts (sdist)
|
- name: upload artifacts (sdist)
|
||||||
if: matrix.upload
|
if: matrix.upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ github.workspace }}/sdist/*.tar.gz
|
path: ${{ github.workspace }}/sdist/*.tar.gz
|
||||||
- name: upload artifacts (haddock)
|
- name: upload artifacts (haddock)
|
||||||
if: matrix.upload
|
if: matrix.upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ github.workspace }}/haddock/*-docs.tar.gz
|
path: ${{ github.workspace }}/haddock/*-docs.tar.gz
|
||||||
- name: hackage upload (candidate)
|
- name: hackage upload (candidate)
|
||||||
|
22
.github/workflows/hlint.yaml
vendored
Normal file
22
.github/workflows/hlint.yaml
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: hlint
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
hlint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 'Set up HLint'
|
||||||
|
uses: haskell-actions/hlint-setup@v2
|
||||||
|
with:
|
||||||
|
version: '3.5'
|
||||||
|
|
||||||
|
- name: 'Run HLint'
|
||||||
|
uses: haskell-actions/hlint-run@v2
|
||||||
|
with:
|
||||||
|
path: '.'
|
||||||
|
fail-on: status
|
6
.github/workflows/nix.yml
vendored
6
.github/workflows/nix.yml
vendored
@@ -6,13 +6,13 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04 # FIXME
|
||||||
name: Nix Flake - Linux
|
name: Nix Flake - Linux
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v13
|
uses: cachix/install-nix-action@v25
|
||||||
with:
|
with:
|
||||||
install_url: https://nixos-nix-install-tests.cachix.org/serve/i6laym9jw3wg9mw6ncyrk6gjx4l34vvx/install
|
install_url: https://nixos-nix-install-tests.cachix.org/serve/i6laym9jw3wg9mw6ncyrk6gjx4l34vvx/install
|
||||||
install_options: '--tarball-url-prefix https://nixos-nix-install-tests.cachix.org/serve'
|
install_options: '--tarball-url-prefix https://nixos-nix-install-tests.cachix.org/serve'
|
||||||
@@ -20,6 +20,6 @@ jobs:
|
|||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Clone project
|
- name: Clone project
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Build
|
- name: Build
|
||||||
run: nix build --print-build-logs
|
run: nix build --print-build-logs
|
||||||
|
6
.github/workflows/packdeps.yml
vendored
6
.github/workflows/packdeps.yml
vendored
@@ -13,16 +13,16 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone project
|
- name: Clone project
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Setup Haskell
|
- name: Setup Haskell
|
||||||
uses: haskell/actions/setup@v1
|
uses: haskell-actions/setup@v2
|
||||||
with:
|
with:
|
||||||
# packdeps doesn't build with newer as of 2021-10
|
# packdeps doesn't build with newer as of 2021-10
|
||||||
ghc-version: '8.8'
|
ghc-version: '8.8'
|
||||||
- name: Install packdeps
|
- name: Install packdeps
|
||||||
run: |
|
run: |
|
||||||
set -ex
|
set -ex
|
||||||
echo "$HOME/.cabal/bin" >> $GITHUB_PATH
|
cd # go somewhere without a cabal.project
|
||||||
cabal install packdeps
|
cabal install packdeps
|
||||||
- name: Check package bounds (all)
|
- name: Check package bounds (all)
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
39
.github/workflows/stack.yml
vendored
39
.github/workflows/stack.yml
vendored
@@ -12,30 +12,21 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- resolver: lts-12
|
- resolver: lts-14 # GHC 8.6
|
||||||
ghc: 8.4.4
|
- resolver: lts-16 # GHC 8.8
|
||||||
- resolver: lts-14
|
- resolver: lts-18 # GHC 8.10
|
||||||
ghc: 8.6.5
|
- resolver: lts-19 # GHC 9.0
|
||||||
- resolver: lts-16
|
- resolver: lts-20 # GHC 9.2
|
||||||
ghc: 8.8.4
|
- resolver: lts-21 # GHC 9.4
|
||||||
- resolver: lts-18
|
|
||||||
ghc: 8.10.7
|
|
||||||
- resolver: lts-19
|
|
||||||
ghc: 9.0.2
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone project
|
- name: Clone project
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Prepare apt sources
|
|
||||||
run: |
|
|
||||||
set -ex
|
|
||||||
sudo add-apt-repository -y ppa:hvr/ghc
|
|
||||||
sudo apt update -y
|
|
||||||
|
|
||||||
- name: Install C dependencies
|
- name: Install C dependencies
|
||||||
run: |
|
run: |
|
||||||
set -ex
|
set -ex
|
||||||
|
sudo apt update -y
|
||||||
sudo apt install -y \
|
sudo apt install -y \
|
||||||
libx11-dev \
|
libx11-dev \
|
||||||
libxext-dev \
|
libxext-dev \
|
||||||
@@ -44,14 +35,6 @@ jobs:
|
|||||||
libxss-dev \
|
libxss-dev \
|
||||||
#
|
#
|
||||||
|
|
||||||
- name: Install GHC
|
|
||||||
# use system ghc (if available) in stack, don't waste GH Actions cache space
|
|
||||||
continue-on-error: true
|
|
||||||
run: |
|
|
||||||
set -ex
|
|
||||||
sudo apt install -y ghc-${{ matrix.ghc }}
|
|
||||||
echo /opt/ghc/${{ matrix.ghc }}/bin >> $GITHUB_PATH
|
|
||||||
|
|
||||||
- name: Refresh caches once a month
|
- name: Refresh caches once a month
|
||||||
id: cache-date
|
id: cache-date
|
||||||
# GHA writes caches on the first miss and then never updates them again;
|
# GHA writes caches on the first miss and then never updates them again;
|
||||||
@@ -59,16 +42,16 @@ jobs:
|
|||||||
# date is prefixed with an epoch number to let us manually refresh the
|
# date is prefixed with an epoch number to let us manually refresh the
|
||||||
# cache when needed. This is a workaround for https://github.com/actions/cache/issues/2
|
# cache when needed. This is a workaround for https://github.com/actions/cache/issues/2
|
||||||
run: |
|
run: |
|
||||||
echo "::set-output name=date::1-$(date +%Y-%m)"
|
date +date=1-%Y-%m >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Cache Haskell package metadata
|
- name: Cache Haskell package metadata
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.stack/pantry
|
path: ~/.stack/pantry
|
||||||
key: stack-pantry-${{ runner.os }}-${{ steps.cache-date.outputs.date }}
|
key: stack-pantry-${{ runner.os }}-${{ steps.cache-date.outputs.date }}
|
||||||
|
|
||||||
- name: Cache Haskell dependencies
|
- name: Cache Haskell dependencies
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.stack/*
|
~/.stack/*
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -27,3 +27,6 @@ tags
|
|||||||
/cabal.sandbox.config
|
/cabal.sandbox.config
|
||||||
/dist-newstyle/
|
/dist-newstyle/
|
||||||
/dist/
|
/dist/
|
||||||
|
|
||||||
|
# nix artifacts
|
||||||
|
result
|
||||||
|
44
CHANGES.md
44
CHANGES.md
@@ -1,6 +1,42 @@
|
|||||||
# Change Log / Release Notes
|
# Change Log / Release Notes
|
||||||
|
|
||||||
## 0.17.1 (September 3, 2021)
|
## 0.18.0 (February 3, 2024)
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
|
||||||
|
* Dropped support for GHC 8.4.
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* Exported `sendRestart` and `sendReplace` from `XMonad.Operations`.
|
||||||
|
|
||||||
|
* Exported `buildLaunch` from `XMonad.Main`.
|
||||||
|
|
||||||
|
* `Tall` does not draw windows with zero area.
|
||||||
|
|
||||||
|
* `XMonad.Operations.floatLocation` now applies size hints. This means windows
|
||||||
|
will snap to these hints as soon as they're floated (mouse move, keybinding).
|
||||||
|
Previously that only happened on mouse resize.
|
||||||
|
|
||||||
|
* Recompilation now detects `flake.nix` and `default.nix` (can be a
|
||||||
|
symlink) and switches to using `nix build` as appropriate.
|
||||||
|
|
||||||
|
* Added `unGrab` to `XMonad.Operations`; this releases XMonad's passive
|
||||||
|
keyboard grab, so other applications (like `scrot`) can do their
|
||||||
|
thing.
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Duplicated floats (e.g. from X.A.CopyToAll) no longer escape to inactive
|
||||||
|
screens.
|
||||||
|
|
||||||
|
## 0.17.2 (April 2, 2023)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Fixed the build with GHC 9.6.
|
||||||
|
|
||||||
|
## 0.17.1 (September 3, 2022)
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
@@ -8,6 +44,9 @@
|
|||||||
|
|
||||||
* Exported `cacheNumlockMask` and `mkGrabs` from `XMonad.Operations`.
|
* Exported `cacheNumlockMask` and `mkGrabs` from `XMonad.Operations`.
|
||||||
|
|
||||||
|
* Added `willFloat` function to `XMonad.ManageHooks` to detect whether the
|
||||||
|
(about to be) managed window will be a floating window or not.
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* Fixed border color of windows with alpha channel. Now all windows have the
|
* Fixed border color of windows with alpha channel. Now all windows have the
|
||||||
@@ -65,9 +104,6 @@
|
|||||||
* Added `withUnfocused` function to `XMonad.Operations`, allowing for `X`
|
* Added `withUnfocused` function to `XMonad.Operations`, allowing for `X`
|
||||||
operations to be applied to unfocused windows.
|
operations to be applied to unfocused windows.
|
||||||
|
|
||||||
* Added `willFloat` function to `XMonad.ManageHooks` to detect whether the
|
|
||||||
(about to be) managed window will be a floating window or not
|
|
||||||
|
|
||||||
[these build scripts]: https://github.com/xmonad/xmonad-testing/tree/master/build-scripts
|
[these build scripts]: https://github.com/xmonad/xmonad-testing/tree/master/build-scripts
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
35
INSTALL.md
35
INSTALL.md
@@ -101,7 +101,7 @@ This will give you the latest `HEAD`; if you want you can also check
|
|||||||
out a tagged release, e.g.:
|
out a tagged release, e.g.:
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ git clone --branch v0.17.1 https://github.com/xmonad/xmonad
|
$ git clone --branch v0.17.2 https://github.com/xmonad/xmonad
|
||||||
$ git clone --branch v0.17.1 https://github.com/xmonad/xmonad-contrib
|
$ git clone --branch v0.17.1 https://github.com/xmonad/xmonad-contrib
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -123,7 +123,9 @@ Unless you already know which one you prefer, use Stack, which is easier.
|
|||||||
|
|
||||||
#### Install Stack
|
#### Install Stack
|
||||||
|
|
||||||
The easiest way to get [stack] is probably via your system's package
|
Probably one of the best ways to get [stack] is to use [GHCup], which is the main Haskell installer according to language's official [website][GHCup] and community [survey]. GHCup is [widely available] and is considered less error prone than other installation options.
|
||||||
|
|
||||||
|
You can also use your system's package
|
||||||
manager:
|
manager:
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
@@ -145,9 +147,6 @@ stack via its [documentation][stack]):
|
|||||||
$ curl -sSL https://get.haskellstack.org/ | sh
|
$ curl -sSL https://get.haskellstack.org/ | sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Yet another way would be via [ghcup]; this is similar to installers like
|
|
||||||
`rustup`, in case you prefer that.
|
|
||||||
|
|
||||||
#### Create a New Project
|
#### Create a New Project
|
||||||
|
|
||||||
Let's create a stack project. Since we're already in the correct
|
Let's create a stack project. Since we're already in the correct
|
||||||
@@ -222,7 +221,9 @@ be that you don't have the required C libraries installed. See
|
|||||||
|
|
||||||
#### Install cabal-install
|
#### Install cabal-install
|
||||||
|
|
||||||
The easiest way to get [cabal-install] is probably via your system's package
|
Probably one of the best ways to get [cabal-install] is to use [GHCup], which is the main Haskell installer according to language's official [website][GHCup] and community [survey]. GHCup is [widely available] and is considered less error prone than other installation options.
|
||||||
|
|
||||||
|
You can also use your system's package
|
||||||
manager:
|
manager:
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
@@ -231,22 +232,22 @@ $ sudo dnf install cabal-install # Fedora
|
|||||||
$ sudo pacman -S cabal-install # Arch
|
$ sudo pacman -S cabal-install # Arch
|
||||||
```
|
```
|
||||||
|
|
||||||
If your distribution does not package cabal-install, [ghcup][] is another
|
See also <https://www.haskell.org/cabal/#install-upgrade>.
|
||||||
option. See also <https://www.haskell.org/cabal/#install-upgrade>.
|
|
||||||
|
|
||||||
#### Create a New Project
|
#### Create a New Project
|
||||||
|
|
||||||
Let's create a cabal project. Since we're already in the correct
|
If you want to use `xmonad` or `xmonad-contrib` from git, you will need a
|
||||||
directory (`~/.config/xmonad`) with `xmonad` and `xmonad-contrib`
|
`cabal.project` file. If you want to use both from [Hackage][], you should
|
||||||
subdirectories, we'll instruct cabal to use them. Create a file named
|
skip this step.
|
||||||
`cabal.project` containing:
|
|
||||||
|
Create a file named `cabal.project` containing:
|
||||||
|
|
||||||
```
|
```
|
||||||
packages: */*.cabal
|
packages: */*.cabal
|
||||||
```
|
```
|
||||||
|
|
||||||
(If you skip this step, cabal will use the latest releases from [Hackage][]
|
(If you do this step without using [git] checkouts, you will get an error from
|
||||||
instead.)
|
cabal in the next step. Simply remove `cabal.project` and try again.)
|
||||||
|
|
||||||
#### Install Everything
|
#### Install Everything
|
||||||
|
|
||||||
@@ -255,7 +256,7 @@ libraries and then build the xmonad binary:
|
|||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cabal update
|
$ cabal update
|
||||||
$ cabal install --package-env=$HOME/.config/xmonad --lib xmonad xmonad-contrib
|
$ cabal install --package-env=$HOME/.config/xmonad --lib base xmonad xmonad-contrib
|
||||||
$ cabal install --package-env=$HOME/.config/xmonad xmonad
|
$ cabal install --package-env=$HOME/.config/xmonad xmonad
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -393,7 +394,9 @@ executable will also be within that directory and not in
|
|||||||
[git]: https://git-scm.com/
|
[git]: https://git-scm.com/
|
||||||
[stack]: https://docs.haskellstack.org/en/stable/README/
|
[stack]: https://docs.haskellstack.org/en/stable/README/
|
||||||
[cabal-install]: https://www.haskell.org/cabal/
|
[cabal-install]: https://www.haskell.org/cabal/
|
||||||
[ghcup]: https://www.haskell.org/ghcup/
|
[GHCup]: https://www.haskell.org/ghcup/
|
||||||
|
[survey]: https://taylor.fausak.me/2022/11/18/haskell-survey-results/
|
||||||
|
[widely available]: https://www.haskell.org/ghcup/install/#supported-platforms
|
||||||
[what xmonad would do]: https://github.com/xmonad/xmonad/blob/master/src/XMonad/Core.hs#L659-L667
|
[what xmonad would do]: https://github.com/xmonad/xmonad/blob/master/src/XMonad/Core.hs#L659-L667
|
||||||
[Hackage]: https://hackage.haskell.org/
|
[Hackage]: https://hackage.haskell.org/
|
||||||
[scripts/build]: https://github.com/xmonad/xmonad-contrib/blob/master/scripts/build
|
[scripts/build]: https://github.com/xmonad/xmonad-contrib/blob/master/scripts/build
|
||||||
|
@@ -117,7 +117,12 @@ When the time comes to release another version of xmonad and xmonad-contrib:
|
|||||||
|
|
||||||
See [old announcements][old-announce] ([even older][older-announce]) for inspiration.
|
See [old announcements][old-announce] ([even older][older-announce]) for inspiration.
|
||||||
|
|
||||||
7. Bump version for development (add `.9`) and prepare fresh sections in
|
7. Trigger xmonad-docs build to generate and persist docs for the just
|
||||||
|
released version:
|
||||||
|
|
||||||
|
- https://github.com/xmonad/xmonad-docs/actions/workflows/stack.yml
|
||||||
|
|
||||||
|
8. Bump version for development (add `.9`) and prepare fresh sections in
|
||||||
[`CHANGES.md`](CHANGES.md).
|
[`CHANGES.md`](CHANGES.md).
|
||||||
|
|
||||||
[packdeps]: https://hackage.haskell.org/package/packdeps
|
[packdeps]: https://hackage.haskell.org/package/packdeps
|
||||||
|
@@ -6,9 +6,9 @@
|
|||||||
<a href="https://github.com/xmonad/xmonad/blob/readme/LICENSE"><img alt="License" src="https://img.shields.io/github/license/xmonad/xmonad"></a>
|
<a href="https://github.com/xmonad/xmonad/blob/readme/LICENSE"><img alt="License" src="https://img.shields.io/github/license/xmonad/xmonad"></a>
|
||||||
<a href="https://haskell.org/"><img alt="Made in Haskell" src="https://img.shields.io/badge/Made%20in-Haskell-%235e5086?logo=haskell"></a>
|
<a href="https://haskell.org/"><img alt="Made in Haskell" src="https://img.shields.io/badge/Made%20in-Haskell-%235e5086?logo=haskell"></a>
|
||||||
<br>
|
<br>
|
||||||
<a href="https://github.com/xmonad/xmonad/actions/workflows/stack.yml"><img alt="Stack" src="https://img.shields.io/github/workflow/status/xmonad/xmonad/Stack?label=Stack&logo=githubactions&logoColor=white"></a>
|
<a href="https://github.com/xmonad/xmonad/actions/workflows/stack.yml"><img alt="Stack" src="https://img.shields.io/github/actions/workflow/status/xmonad/xmonad/stack.yml?label=Stack&logo=githubactions&logoColor=white"></a>
|
||||||
<a href="https://github.com/xmonad/xmonad/actions/workflows/haskell-ci.yml"><img alt="Cabal" src="https://img.shields.io/github/workflow/status/xmonad/xmonad/Haskell-CI?label=Cabal&logo=githubactions&logoColor=white"></a>
|
<a href="https://github.com/xmonad/xmonad/actions/workflows/haskell-ci.yml"><img alt="Cabal" src="https://img.shields.io/github/actions/workflow/status/xmonad/xmonad/haskell-ci.yml?label=Cabal&logo=githubactions&logoColor=white"></a>
|
||||||
<a href="https://github.com/xmonad/xmonad/actions/workflows/nix.yml"><img alt="Nix" src="https://img.shields.io/github/workflow/status/xmonad/xmonad/Nix?label=Nix&logo=githubactions&logoColor=white"></a>
|
<a href="https://github.com/xmonad/xmonad/actions/workflows/nix.yml"><img alt="Nix" src="https://img.shields.io/github/actions/workflow/status/xmonad/xmonad/nix.yml?label=Nix&logo=githubactions&logoColor=white"></a>
|
||||||
<br>
|
<br>
|
||||||
<a href="https://github.com/sponsors/xmonad"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/xmonad?label=GitHub%20Sponsors&logo=githubsponsors"></a>
|
<a href="https://github.com/sponsors/xmonad"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/xmonad?label=GitHub%20Sponsors&logo=githubsponsors"></a>
|
||||||
<a href="https://opencollective.com/xmonad"><img alt="Open Collective" src="https://img.shields.io/opencollective/all/xmonad?label=Open%20Collective&logo=opencollective"></a>
|
<a href="https://opencollective.com/xmonad"><img alt="Open Collective" src="https://img.shields.io/opencollective/all/xmonad?label=Open%20Collective&logo=opencollective"></a>
|
||||||
|
109
TUTORIAL.md
109
TUTORIAL.md
@@ -77,6 +77,11 @@ a live xmonad session in some capacity. If you have set up your
|
|||||||
`~/.xinitrc` as directed in the xmonad guided tour, you should be good
|
`~/.xinitrc` as directed in the xmonad guided tour, you should be good
|
||||||
to go! If not, just smack an `exec xmonad` at the bottom of that file.
|
to go! If not, just smack an `exec xmonad` at the bottom of that file.
|
||||||
|
|
||||||
|
In particular, it might be a good idea to set a wallpaper beforehand.
|
||||||
|
Otherwise, when switching workspaces or closing windows, you might start
|
||||||
|
seeing "shadows" of windows that were there before, unable to interact
|
||||||
|
with them.
|
||||||
|
|
||||||
## Installing Xmobar
|
## Installing Xmobar
|
||||||
|
|
||||||
What we need to do now—provided we want to use a bar at all—is to
|
What we need to do now—provided we want to use a bar at all—is to
|
||||||
@@ -263,7 +268,7 @@ myLayout = tiled ||| Mirror tiled ||| Full
|
|||||||
```
|
```
|
||||||
|
|
||||||
The so-called `where`-clause above simply consists of local declarations
|
The so-called `where`-clause above simply consists of local declarations
|
||||||
that might clutter things up where they all declared at the top-level
|
that might clutter things up were they all declared at the top-level
|
||||||
like this
|
like this
|
||||||
|
|
||||||
``` haskell
|
``` haskell
|
||||||
@@ -379,12 +384,16 @@ effect (and some applications, like chromium, will misbehave and need
|
|||||||
some [Hacks] to make this work), we will also add the relevant function
|
some [Hacks] to make this work), we will also add the relevant function
|
||||||
to get "proper" fullscreen behaviour here.
|
to get "proper" fullscreen behaviour here.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
_IF YOU ARE ON A VERSION `< 0.17.0`_: The `ewmhFullscreen` function does
|
_IF YOU ARE ON A VERSION `< 0.17.0`_: The `ewmhFullscreen` function does
|
||||||
not exist in these versions. Instead of it, you can try to add
|
not exist in these versions. Instead of it, you can try to add
|
||||||
`fullscreenEventHook` to your `handleEventHook` to achieve similar
|
`fullscreenEventHook` to your `handleEventHook` to achieve similar
|
||||||
functionality (how to do this is explained in the documentation of
|
functionality (how to do this is explained in the documentation of
|
||||||
[XMonad.Hooks.EwmhDesktops]).
|
[XMonad.Hooks.EwmhDesktops]).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
To use the two combinators, we compose them with the `xmonad` function
|
To use the two combinators, we compose them with the `xmonad` function
|
||||||
in the following way:
|
in the following way:
|
||||||
|
|
||||||
@@ -430,7 +439,7 @@ Much better!
|
|||||||
## Make XMonad and Xmobar Talk to Each Other
|
## Make XMonad and Xmobar Talk to Each Other
|
||||||
|
|
||||||
Onto the main dish. First, we have to import the necessary modules.
|
Onto the main dish. First, we have to import the necessary modules.
|
||||||
Add the following to your list of imports:
|
Add the following to your list of imports
|
||||||
|
|
||||||
``` haskell
|
``` haskell
|
||||||
import XMonad.Hooks.DynamicLog
|
import XMonad.Hooks.DynamicLog
|
||||||
@@ -438,23 +447,27 @@ import XMonad.Hooks.StatusBar
|
|||||||
import XMonad.Hooks.StatusBar.PP
|
import XMonad.Hooks.StatusBar.PP
|
||||||
```
|
```
|
||||||
|
|
||||||
_IF YOU ARE ON A VERSION `< 0.17.0`_: The `XMonad.Hooks.StatusBar` and
|
and replace your `main` function above with:
|
||||||
`XMonad.Hooks.StatusBar.PP` modules don't exist yet. You can find
|
|
||||||
everything you need in the `XMonad.Hooks.DynamicLog` module, so remove
|
|
||||||
these two imports.
|
|
||||||
|
|
||||||
Replace your `main` function above with:
|
|
||||||
|
|
||||||
``` haskell
|
``` haskell
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = xmonad $ ewmhFullscreen $ ewmh $ xmobarProp $ myConfig
|
main = xmonad $ ewmhFullscreen $ ewmh $ xmobarProp $ myConfig
|
||||||
```
|
```
|
||||||
|
|
||||||
_IF YOU ARE ON A VERSION `< 0.17.0`_: The `xmobarProp` function does not
|
---
|
||||||
exist in these versions. Instead of it, use `xmobar` via
|
|
||||||
`main = xmonad . ewmh =<< xmobar myConfig` and carefully read the part
|
_IF YOU ARE ON A VERSION `< 0.17.0`_: The `XMonad.Hooks.StatusBar` and
|
||||||
about pipes later on (`xmobar` uses pipes to make xmobar talk to
|
`XMonad.Hooks.StatusBar.PP` modules don't exist yet. You can find
|
||||||
xmonad).
|
everything you need in the `XMonad.Hooks.DynamicLog` module, so remove
|
||||||
|
these two imports.
|
||||||
|
|
||||||
|
Further, the `xmobarProp` function does not exist in older versions.
|
||||||
|
Instead of it, use `xmobar` via `main = xmonad . ewmh =<< xmobar
|
||||||
|
myConfig` and carefully read the part about pipes later on (`xmobar`
|
||||||
|
uses pipes to make xmobar talk to xmonad). Do note the lack of
|
||||||
|
`ewmhFullscreen`, as explained above!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
As a quick side-note, we could have also written
|
As a quick side-note, we could have also written
|
||||||
|
|
||||||
@@ -540,11 +553,15 @@ when things are not being read! For this reason we have to use
|
|||||||
(this is useful, for example, for [XMonad.Util.ClickableWorkspaces],
|
(this is useful, for example, for [XMonad.Util.ClickableWorkspaces],
|
||||||
which is a new feature in `0.17.0`).
|
which is a new feature in `0.17.0`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
_IF YOU ARE ON A VERSION `< 0.17.0`_: As discussed above, the `xmobar`
|
_IF YOU ARE ON A VERSION `< 0.17.0`_: As discussed above, the `xmobar`
|
||||||
function uses pipes, so you actually do want to use the `StdinReader`.
|
function uses pipes, so you actually do want to use the `StdinReader`.
|
||||||
Simply replace _all_ occurences of `XMonadLog` with `StdinReader`
|
Simply replace _all_ occurences of `XMonadLog` with `StdinReader`
|
||||||
below (don't forget the template!)
|
below (don't forget the template!)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Configuring Xmobar
|
## Configuring Xmobar
|
||||||
|
|
||||||
Now, before this will work, we have to configure xmobar. Here's a nice
|
Now, before this will work, we have to configure xmobar. Here's a nice
|
||||||
@@ -660,6 +677,8 @@ main = xmonad
|
|||||||
$ myConfig
|
$ myConfig
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
_IF YOU ARE ON A VERSION `< 0.17.0`_: `xmobar` has a similar definition,
|
_IF YOU ARE ON A VERSION `< 0.17.0`_: `xmobar` has a similar definition,
|
||||||
relying on `statusBar` alone: `xmobar = statusBar "xmobar" xmobarPP
|
relying on `statusBar` alone: `xmobar = statusBar "xmobar" xmobarPP
|
||||||
toggleStrutsKey`. Sadly, the `defToggleStrutsKey` function is not yet
|
toggleStrutsKey`. Sadly, the `defToggleStrutsKey` function is not yet
|
||||||
@@ -668,7 +687,6 @@ _IF YOU ARE ON A VERSION `< 0.17.0`_: `xmobar` has a similar definition,
|
|||||||
``` haskell
|
``` haskell
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = xmonad
|
main = xmonad
|
||||||
. ewmhFullscreen
|
|
||||||
. ewmh
|
. ewmh
|
||||||
=<< statusBar "xmobar" def toggleStrutsKey myConfig
|
=<< statusBar "xmobar" def toggleStrutsKey myConfig
|
||||||
where
|
where
|
||||||
@@ -676,6 +694,8 @@ main = xmonad
|
|||||||
toggleStrutsKey XConfig{ modMask = m } = (m, xK_b)
|
toggleStrutsKey XConfig{ modMask = m } = (m, xK_b)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
The `defToggleStrutsKey` here is just the key with which you can toggle
|
The `defToggleStrutsKey` here is just the key with which you can toggle
|
||||||
the bar; it is bound to `M-b`. If you want to change this, you can also
|
the bar; it is bound to `M-b`. If you want to change this, you can also
|
||||||
define your own:
|
define your own:
|
||||||
@@ -772,6 +792,8 @@ myXmobarPP = def
|
|||||||
lowWhite = xmobarColor "#bbbbbb" ""
|
lowWhite = xmobarColor "#bbbbbb" ""
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
_IF YOU ARE ON A VERSION `< 0.17`_: Both `logTitles` and `xmobarBorder`
|
_IF YOU ARE ON A VERSION `< 0.17`_: Both `logTitles` and `xmobarBorder`
|
||||||
are not available yet, so you will have to remove them. As an
|
are not available yet, so you will have to remove them. As an
|
||||||
alternative to `xmobarBorder`, a common way to "mark" the currently
|
alternative to `xmobarBorder`, a common way to "mark" the currently
|
||||||
@@ -779,6 +801,8 @@ _IF YOU ARE ON A VERSION `< 0.17`_: Both `logTitles` and `xmobarBorder`
|
|||||||
`ppCurrent = wrap (blue "[") (blue "]")` and see if you like it. Also
|
`ppCurrent = wrap (blue "[") (blue "]")` and see if you like it. Also
|
||||||
read the bit about `ppOrder` further down!
|
read the bit about `ppOrder` further down!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
That's a lot! But don't worry, take a deep breath and remind yourself
|
That's a lot! But don't worry, take a deep breath and remind yourself
|
||||||
of what you read above in the documentation of the [PP record]. Even if
|
of what you read above in the documentation of the [PP record]. Even if
|
||||||
you haven't read the documentation yet, most of the fields should be
|
you haven't read the documentation yet, most of the fields should be
|
||||||
@@ -882,10 +906,10 @@ apt-get install nm-applet feh xfce4-power-manager
|
|||||||
|
|
||||||
First, configure xscreensaver how you like it with the
|
First, configure xscreensaver how you like it with the
|
||||||
`xscreensaver-demo` command. Now, we will set these things up in
|
`xscreensaver-demo` command. Now, we will set these things up in
|
||||||
`~/.xinitrc` (we could also do most of this in xmonad's `startupHook`,
|
`~/.xinitrc`. If you want to use XMonad with a desktop environment, see
|
||||||
but `~/.xinitrc` is perhaps more standard). If you want to use xmonad
|
[Basic Desktop Environment Integration] for how to do this. For a
|
||||||
with a desktop environment, see [Basic Desktop Environment Integration]
|
version using XMonad's built in functionality instead, see the [next
|
||||||
for how to do this.
|
section][using-the-startupHook].
|
||||||
|
|
||||||
Your `~/.xinitrc` may wind up looking like this:
|
Your `~/.xinitrc` may wind up looking like this:
|
||||||
|
|
||||||
@@ -933,6 +957,38 @@ Mission accomplished!
|
|||||||
Of course substitute the wallpaper for one of your own. If you like the
|
Of course substitute the wallpaper for one of your own. If you like the
|
||||||
one used above, you can find it [here](https://i.imgur.com/9MQHuZx.png).
|
one used above, you can find it [here](https://i.imgur.com/9MQHuZx.png).
|
||||||
|
|
||||||
|
### Using the `startupHook`
|
||||||
|
|
||||||
|
Instead of the `.xinitrc` file, one can also use XMonad's built in
|
||||||
|
`startupHook` in order to auto start programs. The
|
||||||
|
[XMonad.Util.SpawnOnce] library is perfect for this use case, allowing
|
||||||
|
programs to start only once, and not with every invocation of `M-q`!
|
||||||
|
|
||||||
|
This requires but a small change in `myConfig`:
|
||||||
|
|
||||||
|
``` haskell
|
||||||
|
-- import XMonad.Util.SpawnOnce (spawnOnce)
|
||||||
|
|
||||||
|
myConfig = def
|
||||||
|
{ modMask = mod4Mask -- Rebind Mod to the Super key
|
||||||
|
, layoutHook = myLayout -- Use custom layouts
|
||||||
|
, startupHook = myStartupHook
|
||||||
|
}
|
||||||
|
`additionalKeysP`
|
||||||
|
[ ("M-S-z", spawn "xscreensaver-command -lock")
|
||||||
|
, ("M-C-s", unGrab *> spawn "scrot -s" )
|
||||||
|
, ("M-f" , spawn "firefox" )
|
||||||
|
]
|
||||||
|
|
||||||
|
myStartupHook :: X ()
|
||||||
|
myStartupHook = do
|
||||||
|
spawnOnce "trayer --edge top --align right --SetDockType true \
|
||||||
|
\--SetPartialStrut true --expand true --width 10 \
|
||||||
|
\--transparent true --tint 0x5f5f5f --height 18"
|
||||||
|
spawnOnce "feh --bg-fill --no-fehbg ~/.wallpapers/haskell-red-noise.png"
|
||||||
|
-- … and so on …
|
||||||
|
```
|
||||||
|
|
||||||
## Final Touches
|
## Final Touches
|
||||||
|
|
||||||
There may be some programs that you don't want xmonad to tile. The
|
There may be some programs that you don't want xmonad to tile. The
|
||||||
@@ -1238,21 +1294,22 @@ either :)
|
|||||||
[Basic Desktop Environment Integration]: https://wiki.haskell.org/Xmonad/Basic_Desktop_Environment_Integration
|
[Basic Desktop Environment Integration]: https://wiki.haskell.org/Xmonad/Basic_Desktop_Environment_Integration
|
||||||
|
|
||||||
[Hacks]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Util-Hacks.html
|
[Hacks]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Util-Hacks.html
|
||||||
[PP record]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html#t:PP
|
|
||||||
[INSTALL.md]: INSTALL.md
|
[INSTALL.md]: INSTALL.md
|
||||||
|
[PP record]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html#t:PP
|
||||||
[XMonad.Config]: https://github.com/xmonad/xmonad/blob/master/src/XMonad/Config.hs
|
[XMonad.Config]: https://github.com/xmonad/xmonad/blob/master/src/XMonad/Config.hs
|
||||||
[XMonad.ManageHook]: https://xmonad.github.io/xmonad-docs/xmonad/XMonad-ManageHook.html
|
|
||||||
[XMonad.Util.Loggers]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Util-Loggers.html
|
|
||||||
[XMonad.Util.EZConfig]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Util-EZConfig.html
|
|
||||||
[XMonad.Layout.Renamed]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Layout-Renamed.html
|
|
||||||
[XMonad.Layout.Magnifier]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Layout-Magnifier.html
|
|
||||||
[XMonad.Doc.Contributing]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Doc-Configuring.html
|
[XMonad.Doc.Contributing]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Doc-Configuring.html
|
||||||
[XMonad.Hooks.EwmhDesktops]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Hooks-EwmhDesktops.html
|
[XMonad.Hooks.EwmhDesktops]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Hooks-EwmhDesktops.html
|
||||||
[XMonad.Layout.ThreeColumns]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Layout-ThreeColumns.html
|
|
||||||
[XMonad.Hooks.ManageHelpers]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageHelpers.html
|
[XMonad.Hooks.ManageHelpers]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageHelpers.html
|
||||||
|
[XMonad.Layout.Magnifier]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Layout-Magnifier.html
|
||||||
|
[XMonad.Layout.Renamed]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Layout-Renamed.html
|
||||||
|
[XMonad.Layout.ThreeColumns]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Layout-ThreeColumns.html
|
||||||
|
[XMonad.ManageHook]: https://xmonad.github.io/xmonad-docs/xmonad/XMonad-ManageHook.html
|
||||||
[XMonad.Util.ClickableWorkspaces]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Util-ClickableWorkspaces.html
|
[XMonad.Util.ClickableWorkspaces]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Util-ClickableWorkspaces.html
|
||||||
|
[XMonad.Util.EZConfig]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Util-EZConfig.html
|
||||||
|
[XMonad.Util.Loggers]: https://xmonad.github.io/xmonad-docs/xmonad-contrib/XMonad-Util-Loggers.html
|
||||||
|
[XMonad.Util.SpawnOnce]: https://hackage.haskell.org/package/xmonad-contrib/docs/XMonad-Util-SpawnOnce.html
|
||||||
|
|
||||||
[xmobar]: https://xmobar.org/
|
[xmobar]: https://codeberg.org/xmobar/xmobar
|
||||||
[battery]: https://codeberg.org/xmobar/xmobar/src/branch/master/doc/plugins.org#batteryp-dirs-args-refreshrate
|
[battery]: https://codeberg.org/xmobar/xmobar/src/branch/master/doc/plugins.org#batteryp-dirs-args-refreshrate
|
||||||
[xmobar.hs]: https://codeberg.org/xmobar/xmobar/src/branch/master/etc/xmobar.hs
|
[xmobar.hs]: https://codeberg.org/xmobar/xmobar/src/branch/master/etc/xmobar.hs
|
||||||
[Wikipedia page]: https://en.wikipedia.org/wiki/ICAO_airport_code#Prefixes
|
[Wikipedia page]: https://en.wikipedia.org/wiki/ICAO_airport_code#Prefixes
|
||||||
|
@@ -5,11 +5,6 @@ apt:
|
|||||||
libxrandr-dev
|
libxrandr-dev
|
||||||
libxss-dev
|
libxss-dev
|
||||||
|
|
||||||
hlint: True
|
|
||||||
hlint-job: 9.0.2
|
|
||||||
hlint-yaml: .hlint.yaml
|
|
||||||
hlint-version: ==3.4.*
|
|
||||||
|
|
||||||
github-patches:
|
github-patches:
|
||||||
.github/workflows/haskell-ci-hackage.patch
|
.github/workflows/haskell-ci-hackage.patch
|
||||||
|
|
||||||
@@ -17,3 +12,6 @@ raw-project
|
|||||||
optimization: False
|
optimization: False
|
||||||
package xmonad
|
package xmonad
|
||||||
flags: +pedantic
|
flags: +pedantic
|
||||||
|
|
||||||
|
-- avoid --haddock-all which overwrites *-docs.tar.gz with tests docs
|
||||||
|
haddock-components: libs
|
||||||
|
43
flake.nix
43
flake.nix
@@ -15,17 +15,26 @@
|
|||||||
else [ "haskell" "packages" compiler ]
|
else [ "haskell" "packages" compiler ]
|
||||||
);
|
);
|
||||||
fromHOL = hol: comp: final: prev: with prev.lib; with attrsets;
|
fromHOL = hol: comp: final: prev: with prev.lib; with attrsets;
|
||||||
setAttrByPath (hpath comp)
|
let
|
||||||
((getAttrFromPath (hpath comp) prev).override (old: {
|
path = hpath comp;
|
||||||
|
root = head path;
|
||||||
|
branch = tail path;
|
||||||
|
hpkgs' = (getAttrFromPath path prev).override (old: {
|
||||||
overrides = composeExtensions (old.overrides or (_: _: {}))
|
overrides = composeExtensions (old.overrides or (_: _: {}))
|
||||||
(hol final prev);
|
(hol final prev);
|
||||||
}));
|
});
|
||||||
|
in {
|
||||||
|
${root} = recursiveUpdate prev.${root} (setAttrByPath branch hpkgs');
|
||||||
|
};
|
||||||
hoverlay = final: prev: hself: hsuper:
|
hoverlay = final: prev: hself: hsuper:
|
||||||
with prev.haskell.lib.compose; {
|
with prev.haskell.lib.compose; {
|
||||||
xmonad = hself.callCabal2nix "xmonad"
|
xmonad = hself.callCabal2nix "xmonad"
|
||||||
(git-ignore-nix.lib.gitignoreSource ./.) { };
|
(git-ignore-nix.lib.gitignoreSource ./.) { };
|
||||||
};
|
};
|
||||||
overlay = fromHOL hoverlay { };
|
defComp = if builtins.pathExists ./comp.nix
|
||||||
|
then import ./comp.nix
|
||||||
|
else { };
|
||||||
|
overlay = fromHOL hoverlay defComp;
|
||||||
overlays = [ overlay ];
|
overlays = [ overlay ];
|
||||||
nixosModule = { config, pkgs, lib, ... }: with lib; with attrsets;
|
nixosModule = { config, pkgs, lib, ... }: with lib; with attrsets;
|
||||||
let
|
let
|
||||||
@@ -64,12 +73,32 @@
|
|||||||
nixosModules = [ nixosModule ];
|
nixosModules = [ nixosModule ];
|
||||||
in flake-utils.lib.eachDefaultSystem (system:
|
in flake-utils.lib.eachDefaultSystem (system:
|
||||||
let pkgs = import nixpkgs { inherit system overlays; };
|
let pkgs = import nixpkgs { inherit system overlays; };
|
||||||
|
hpkg = pkgs.lib.attrsets.getAttrFromPath (hpath defComp) pkgs;
|
||||||
|
modifyDevShell =
|
||||||
|
if builtins.pathExists ./develop.nix
|
||||||
|
then import ./develop.nix
|
||||||
|
else _: x: x;
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
devShell = pkgs.haskellPackages.shellFor {
|
devShell = hpkg.shellFor (modifyDevShell pkgs {
|
||||||
packages = p: [ p.xmonad ];
|
packages = p: [ p.xmonad ];
|
||||||
};
|
});
|
||||||
defaultPackage = pkgs.haskellPackages.xmonad;
|
defaultPackage = hpkg.xmonad;
|
||||||
|
# An auxiliary NixOS module that modernises the standard xmonad NixOS module
|
||||||
|
# and wrapper script used, replacing them with versions from unstable.
|
||||||
|
# Currently, due to the NIX_GHC --> XMONAD_GHC env var change, this is
|
||||||
|
# necessary in order for Mod-q recompilation to work out-of-the-box.
|
||||||
|
modernise =
|
||||||
|
let
|
||||||
|
xmonadModFile = "services/x11/window-managers/xmonad.nix";
|
||||||
|
unpkgs = import unstable { inherit system; };
|
||||||
|
replaceWrapper = _: _:
|
||||||
|
{ xmonad-with-packages = unpkgs.xmonad-with-packages; };
|
||||||
|
in {
|
||||||
|
disabledModules = [ xmonadModFile ];
|
||||||
|
imports = [ (unstable + "/nixos/modules/" + xmonadModFile) ];
|
||||||
|
nixpkgs.overlays = [ replaceWrapper ];
|
||||||
|
};
|
||||||
}) // {
|
}) // {
|
||||||
inherit hoverlay overlay overlays nixosModule nixosModules;
|
inherit hoverlay overlay overlays nixosModule nixosModules;
|
||||||
lib = { inherit hpath fromHOL; };
|
lib = { inherit hpath fromHOL; };
|
||||||
|
101
man/xmonad.1
101
man/xmonad.1
@@ -1,10 +1,10 @@
|
|||||||
.\" Automatically generated by Pandoc 2.5
|
.\" Automatically generated by Pandoc 2.9.2.1
|
||||||
.\"
|
.\"
|
||||||
.TH "XMONAD" "1" "27 October 2021" "Tiling Window Manager" ""
|
.TH "XMONAD" "1" "27 October 2021" "Tiling Window Manager" ""
|
||||||
.hy
|
.hy
|
||||||
.SH Name
|
.SH Name
|
||||||
.PP
|
.PP
|
||||||
xmonad \- Tiling Window Manager
|
xmonad - Tiling Window Manager
|
||||||
.SH Description
|
.SH Description
|
||||||
.PP
|
.PP
|
||||||
\f[I]xmonad\f[R] is a minimalist tiling window manager for X, written in
|
\f[I]xmonad\f[R] is a minimalist tiling window manager for X, written in
|
||||||
@@ -36,27 +36,27 @@ featureful window manager in less than 1200 lines of code, with an
|
|||||||
emphasis on correctness and robustness.
|
emphasis on correctness and robustness.
|
||||||
Internal properties of the window manager are checked using a
|
Internal properties of the window manager are checked using a
|
||||||
combination of static guarantees provided by the type system, and
|
combination of static guarantees provided by the type system, and
|
||||||
type\-based automated testing.
|
type-based automated testing.
|
||||||
A benefit of this is that the code is simple to understand, and easy to
|
A benefit of this is that the code is simple to understand, and easy to
|
||||||
modify.
|
modify.
|
||||||
.SH Usage
|
.SH Usage
|
||||||
.PP
|
.PP
|
||||||
\f[I]xmonad\f[R] places each window into a \[lq]workspace\[rq].
|
\f[I]xmonad\f[R] places each window into a \[lq]workspace\[rq].
|
||||||
Each workspace can have any number of windows, which you can cycle
|
Each workspace can have any number of windows, which you can cycle
|
||||||
though with mod\-j and mod\-k.
|
though with mod-j and mod-k.
|
||||||
Windows are either displayed full screen, tiled horizontally, or tiled
|
Windows are either displayed full screen, tiled horizontally, or tiled
|
||||||
vertically.
|
vertically.
|
||||||
You can toggle the layout mode with mod\-space, which will cycle through
|
You can toggle the layout mode with mod-space, which will cycle through
|
||||||
the available modes.
|
the available modes.
|
||||||
.PP
|
.PP
|
||||||
You can switch to workspace N with mod\-N.
|
You can switch to workspace N with mod-N.
|
||||||
For example, to switch to workspace 5, you would press mod\-5.
|
For example, to switch to workspace 5, you would press mod-5.
|
||||||
Similarly, you can move the current window to another workspace with
|
Similarly, you can move the current window to another workspace with
|
||||||
mod\-shift\-N.
|
mod-shift-N.
|
||||||
.PP
|
.PP
|
||||||
When running with multiple monitors (Xinerama), each screen has exactly
|
When running with multiple monitors (Xinerama), each screen has exactly
|
||||||
1 workspace visible.
|
1 workspace visible.
|
||||||
mod\-{w,e,r} switch the focus between screens, while shift\-mod\-{w,e,r}
|
mod-{w,e,r} switch the focus between screens, while shift-mod-{w,e,r}
|
||||||
move the current window to that screen.
|
move the current window to that screen.
|
||||||
When \f[I]xmonad\f[R] starts, workspace 1 is on screen 1, workspace 2 is
|
When \f[I]xmonad\f[R] starts, workspace 1 is on screen 1, workspace 2 is
|
||||||
on screen 2, etc.
|
on screen 2, etc.
|
||||||
@@ -67,115 +67,115 @@ and visible workspaces are swapped.
|
|||||||
xmonad has several flags which you may pass to the executable.
|
xmonad has several flags which you may pass to the executable.
|
||||||
These flags are:
|
These flags are:
|
||||||
.TP
|
.TP
|
||||||
.B \[en]recompile
|
\[en]recompile
|
||||||
Recompiles your \f[I]xmonad.hs\f[R] configuration
|
Recompiles your \f[I]xmonad.hs\f[R] configuration
|
||||||
.TP
|
.TP
|
||||||
.B \[en]restart
|
\[en]restart
|
||||||
Causes the currently running \f[I]xmonad\f[R] process to restart
|
Causes the currently running \f[I]xmonad\f[R] process to restart
|
||||||
.TP
|
.TP
|
||||||
.B \[en]replace
|
\[en]replace
|
||||||
Replace the current window manager with xmonad
|
Replace the current window manager with xmonad
|
||||||
.TP
|
.TP
|
||||||
.B \[en]version
|
\[en]version
|
||||||
Display version of \f[I]xmonad\f[R]
|
Display version of \f[I]xmonad\f[R]
|
||||||
.TP
|
.TP
|
||||||
.B \[en]verbose\-version
|
\[en]verbose-version
|
||||||
Display detailed version of \f[I]xmonad\f[R]
|
Display detailed version of \f[I]xmonad\f[R]
|
||||||
.SS Default keyboard bindings
|
.SS Default keyboard bindings
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-return
|
mod-shift-return
|
||||||
Launch terminal
|
Launch terminal
|
||||||
.TP
|
.TP
|
||||||
.B mod\-p
|
mod-p
|
||||||
Launch dmenu
|
Launch dmenu
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-p
|
mod-shift-p
|
||||||
Launch gmrun
|
Launch gmrun
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-c
|
mod-shift-c
|
||||||
Close the focused window
|
Close the focused window
|
||||||
.TP
|
.TP
|
||||||
.B mod\-space
|
mod-space
|
||||||
Rotate through the available layout algorithms
|
Rotate through the available layout algorithms
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-space
|
mod-shift-space
|
||||||
Reset the layouts on the current workspace to default
|
Reset the layouts on the current workspace to default
|
||||||
.TP
|
.TP
|
||||||
.B mod\-n
|
mod-n
|
||||||
Resize viewed windows to the correct size
|
Resize viewed windows to the correct size
|
||||||
.TP
|
.TP
|
||||||
.B mod\-tab
|
mod-tab
|
||||||
Move focus to the next window
|
Move focus to the next window
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-tab
|
mod-shift-tab
|
||||||
Move focus to the previous window
|
Move focus to the previous window
|
||||||
.TP
|
.TP
|
||||||
.B mod\-j
|
mod-j
|
||||||
Move focus to the next window
|
Move focus to the next window
|
||||||
.TP
|
.TP
|
||||||
.B mod\-k
|
mod-k
|
||||||
Move focus to the previous window
|
Move focus to the previous window
|
||||||
.TP
|
.TP
|
||||||
.B mod\-m
|
mod-m
|
||||||
Move focus to the master window
|
Move focus to the master window
|
||||||
.TP
|
.TP
|
||||||
.B mod\-return
|
mod-return
|
||||||
Swap the focused window and the master window
|
Swap the focused window and the master window
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-j
|
mod-shift-j
|
||||||
Swap the focused window with the next window
|
Swap the focused window with the next window
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-k
|
mod-shift-k
|
||||||
Swap the focused window with the previous window
|
Swap the focused window with the previous window
|
||||||
.TP
|
.TP
|
||||||
.B mod\-h
|
mod-h
|
||||||
Shrink the master area
|
Shrink the master area
|
||||||
.TP
|
.TP
|
||||||
.B mod\-l
|
mod-l
|
||||||
Expand the master area
|
Expand the master area
|
||||||
.TP
|
.TP
|
||||||
.B mod\-t
|
mod-t
|
||||||
Push window back into tiling
|
Push window back into tiling
|
||||||
.TP
|
.TP
|
||||||
.B mod\-comma
|
mod-comma
|
||||||
Increment the number of windows in the master area
|
Increment the number of windows in the master area
|
||||||
.TP
|
.TP
|
||||||
.B mod\-period
|
mod-period
|
||||||
Deincrement the number of windows in the master area
|
Deincrement the number of windows in the master area
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-q
|
mod-shift-q
|
||||||
Quit xmonad
|
Quit xmonad
|
||||||
.TP
|
.TP
|
||||||
.B mod\-q
|
mod-q
|
||||||
Restart xmonad
|
Restart xmonad
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-slash
|
mod-shift-slash
|
||||||
Run xmessage with a summary of the default keybindings (useful for
|
Run xmessage with a summary of the default keybindings (useful for
|
||||||
beginners)
|
beginners)
|
||||||
.TP
|
.TP
|
||||||
.B mod\-question
|
mod-question
|
||||||
Run xmessage with a summary of the default keybindings (useful for
|
Run xmessage with a summary of the default keybindings (useful for
|
||||||
beginners)
|
beginners)
|
||||||
.TP
|
.TP
|
||||||
.B mod\-[1..9]
|
mod-[1..9]
|
||||||
Switch to workspace N
|
Switch to workspace N
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-[1..9]
|
mod-shift-[1..9]
|
||||||
Move client to workspace N
|
Move client to workspace N
|
||||||
.TP
|
.TP
|
||||||
.B mod\-{w,e,r}
|
mod-{w,e,r}
|
||||||
Switch to physical/Xinerama screens 1, 2, or 3
|
Switch to physical/Xinerama screens 1, 2, or 3
|
||||||
.TP
|
.TP
|
||||||
.B mod\-shift\-{w,e,r}
|
mod-shift-{w,e,r}
|
||||||
Move client to screen 1, 2, or 3
|
Move client to screen 1, 2, or 3
|
||||||
.TP
|
.TP
|
||||||
.B mod\-button1
|
mod-button1
|
||||||
Set the window to floating mode and move by dragging
|
Set the window to floating mode and move by dragging
|
||||||
.TP
|
.TP
|
||||||
.B mod\-button2
|
mod-button2
|
||||||
Raise the window to the top of the stack
|
Raise the window to the top of the stack
|
||||||
.TP
|
.TP
|
||||||
.B mod\-button3
|
mod-button3
|
||||||
Set the window to floating mode and resize by dragging
|
Set the window to floating mode and resize by dragging
|
||||||
.SH Examples
|
.SH Examples
|
||||||
.PP
|
.PP
|
||||||
@@ -188,7 +188,7 @@ exec xmonad
|
|||||||
.SH Customization
|
.SH Customization
|
||||||
.PP
|
.PP
|
||||||
xmonad is customized in your \f[I]xmonad.hs\f[R], and then restarted
|
xmonad is customized in your \f[I]xmonad.hs\f[R], and then restarted
|
||||||
with mod\-q.
|
with mod-q.
|
||||||
You can choose where your configuration file lives by
|
You can choose where your configuration file lives by
|
||||||
.IP "1." 3
|
.IP "1." 3
|
||||||
Setting \f[C]XMONAD_DATA_DIR,\f[R] \f[C]XMONAD_CONFIG_DIR\f[R], and
|
Setting \f[C]XMONAD_DATA_DIR,\f[R] \f[C]XMONAD_CONFIG_DIR\f[R], and
|
||||||
@@ -201,14 +201,13 @@ Creating \f[I]xmonad.hs\f[R] in \f[C]XDG_CONFIG_HOME\f[R].
|
|||||||
Note that, in this case, xmonad will use \f[C]XDG_DATA_HOME\f[R] and
|
Note that, in this case, xmonad will use \f[C]XDG_DATA_HOME\f[R] and
|
||||||
\f[C]XDG_CACHE_HOME\f[R] for its data and cache directory respectively.
|
\f[C]XDG_CACHE_HOME\f[R] for its data and cache directory respectively.
|
||||||
.PP
|
.PP
|
||||||
You can find many extensions to the core feature set in the xmonad\-
|
You can find many extensions to the core feature set in the xmonad-
|
||||||
contrib package, available through your package manager or from
|
contrib package, available through your package manager or from
|
||||||
xmonad.org (https://xmonad.org).
|
xmonad.org (https://xmonad.org).
|
||||||
.SS Modular Configuration
|
.SS Modular Configuration
|
||||||
.PP
|
.PP
|
||||||
As of \f[I]xmonad\-0.9\f[R], any additional Haskell modules may be
|
As of \f[I]xmonad-0.9\f[R], any additional Haskell modules may be placed
|
||||||
placed in \f[I]\[ti]/.xmonad/lib/\f[R] are available in GHC\[cq]s
|
in \f[I]\[ti]/.xmonad/lib/\f[R] are available in GHC\[cq]s searchpath.
|
||||||
searchpath.
|
|
||||||
Hierarchical modules are supported: for example, the file
|
Hierarchical modules are supported: for example, the file
|
||||||
\f[I]\[ti]/.xmonad/lib/XMonad/Stack/MyAdditions.hs\f[R] could contain:
|
\f[I]\[ti]/.xmonad/lib/XMonad/Stack/MyAdditions.hs\f[R] could contain:
|
||||||
.IP
|
.IP
|
||||||
@@ -220,7 +219,7 @@ module XMonad.Stack.MyAdditions (function1) where
|
|||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
Your xmonad.hs may then import XMonad.Stack.MyAdditions as if that
|
Your xmonad.hs may then import XMonad.Stack.MyAdditions as if that
|
||||||
module was contained within xmonad or xmonad\-contrib.
|
module was contained within xmonad or xmonad-contrib.
|
||||||
.SH Bugs
|
.SH Bugs
|
||||||
.PP
|
.PP
|
||||||
Probably.
|
Probably.
|
||||||
|
@@ -7,74 +7,75 @@
|
|||||||
<meta name="author" content="" />
|
<meta name="author" content="" />
|
||||||
<meta name="dcterms.date" content="2021-10-27" />
|
<meta name="dcterms.date" content="2021-10-27" />
|
||||||
<title>XMONAD(1) Tiling Window Manager</title>
|
<title>XMONAD(1) Tiling Window Manager</title>
|
||||||
<style type="text/css">
|
<style>
|
||||||
code{white-space: pre-wrap;}
|
code{white-space: pre-wrap;}
|
||||||
span.smallcaps{font-variant: small-caps;}
|
span.smallcaps{font-variant: small-caps;}
|
||||||
span.underline{text-decoration: underline;}
|
span.underline{text-decoration: underline;}
|
||||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||||
</style>
|
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||||
<style type="text/css">
|
ul.task-list{list-style: none;}
|
||||||
a.sourceLine { display: inline-block; line-height: 1.25; }
|
pre > code.sourceCode { white-space: pre; position: relative; }
|
||||||
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
|
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
|
||||||
a.sourceLine:empty { height: 1.2em; }
|
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||||||
.sourceCode { overflow: visible; }
|
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||||||
code.sourceCode { white-space: pre; position: relative; }
|
div.sourceCode { margin: 1em 0; }
|
||||||
div.sourceCode { margin: 1em 0; }
|
pre.sourceCode { margin: 0; }
|
||||||
pre.sourceCode { margin: 0; }
|
@media screen {
|
||||||
@media screen {
|
div.sourceCode { overflow: auto; }
|
||||||
div.sourceCode { overflow: auto; }
|
}
|
||||||
}
|
@media print {
|
||||||
@media print {
|
pre > code.sourceCode { white-space: pre-wrap; }
|
||||||
code.sourceCode { white-space: pre-wrap; }
|
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
||||||
a.sourceLine { text-indent: -1em; padding-left: 1em; }
|
}
|
||||||
}
|
pre.numberSource code
|
||||||
pre.numberSource a.sourceLine
|
{ counter-reset: source-line 0; }
|
||||||
{ position: relative; left: -4em; }
|
pre.numberSource code > span
|
||||||
pre.numberSource a.sourceLine::before
|
{ position: relative; left: -4em; counter-increment: source-line; }
|
||||||
{ content: attr(title);
|
pre.numberSource code > span > a:first-child::before
|
||||||
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
{ content: counter(source-line);
|
||||||
border: none; pointer-events: all; display: inline-block;
|
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||||||
-webkit-touch-callout: none; -webkit-user-select: none;
|
border: none; display: inline-block;
|
||||||
-khtml-user-select: none; -moz-user-select: none;
|
-webkit-touch-callout: none; -webkit-user-select: none;
|
||||||
-ms-user-select: none; user-select: none;
|
-khtml-user-select: none; -moz-user-select: none;
|
||||||
padding: 0 4px; width: 4em;
|
-ms-user-select: none; user-select: none;
|
||||||
color: #aaaaaa;
|
padding: 0 4px; width: 4em;
|
||||||
}
|
color: #aaaaaa;
|
||||||
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
|
}
|
||||||
div.sourceCode
|
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
|
||||||
{ }
|
div.sourceCode
|
||||||
@media screen {
|
{ }
|
||||||
a.sourceLine::before { text-decoration: underline; }
|
@media screen {
|
||||||
}
|
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||||||
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
|
}
|
||||||
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
|
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
|
||||||
code span.at { color: #7d9029; } /* Attribute */
|
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
|
||||||
code span.bn { color: #40a070; } /* BaseN */
|
code span.at { color: #7d9029; } /* Attribute */
|
||||||
code span.bu { } /* BuiltIn */
|
code span.bn { color: #40a070; } /* BaseN */
|
||||||
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
|
code span.bu { } /* BuiltIn */
|
||||||
code span.ch { color: #4070a0; } /* Char */
|
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
|
||||||
code span.cn { color: #880000; } /* Constant */
|
code span.ch { color: #4070a0; } /* Char */
|
||||||
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
|
code span.cn { color: #880000; } /* Constant */
|
||||||
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
|
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
|
||||||
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
|
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
|
||||||
code span.dt { color: #902000; } /* DataType */
|
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
|
||||||
code span.dv { color: #40a070; } /* DecVal */
|
code span.dt { color: #902000; } /* DataType */
|
||||||
code span.er { color: #ff0000; font-weight: bold; } /* Error */
|
code span.dv { color: #40a070; } /* DecVal */
|
||||||
code span.ex { } /* Extension */
|
code span.er { color: #ff0000; font-weight: bold; } /* Error */
|
||||||
code span.fl { color: #40a070; } /* Float */
|
code span.ex { } /* Extension */
|
||||||
code span.fu { color: #06287e; } /* Function */
|
code span.fl { color: #40a070; } /* Float */
|
||||||
code span.im { } /* Import */
|
code span.fu { color: #06287e; } /* Function */
|
||||||
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
|
code span.im { } /* Import */
|
||||||
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
|
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
|
||||||
code span.op { color: #666666; } /* Operator */
|
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
|
||||||
code span.ot { color: #007020; } /* Other */
|
code span.op { color: #666666; } /* Operator */
|
||||||
code span.pp { color: #bc7a00; } /* Preprocessor */
|
code span.ot { color: #007020; } /* Other */
|
||||||
code span.sc { color: #4070a0; } /* SpecialChar */
|
code span.pp { color: #bc7a00; } /* Preprocessor */
|
||||||
code span.ss { color: #bb6688; } /* SpecialString */
|
code span.sc { color: #4070a0; } /* SpecialChar */
|
||||||
code span.st { color: #4070a0; } /* String */
|
code span.ss { color: #bb6688; } /* SpecialString */
|
||||||
code span.va { color: #19177c; } /* Variable */
|
code span.st { color: #4070a0; } /* String */
|
||||||
code span.vs { color: #4070a0; } /* VerbatimString */
|
code span.va { color: #19177c; } /* Variable */
|
||||||
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
code span.vs { color: #4070a0; } /* VerbatimString */
|
||||||
|
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -83,16 +84,18 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warni
|
|||||||
<p class="author"></p>
|
<p class="author"></p>
|
||||||
<p class="date">27 October 2021</p>
|
<p class="date">27 October 2021</p>
|
||||||
</header>
|
</header>
|
||||||
<nav id="TOC">
|
<nav id="TOC" role="doc-toc">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#name">Name</a></li>
|
<li><a href="#name">Name</a></li>
|
||||||
<li><a href="#description">Description</a></li>
|
<li><a href="#description">Description</a></li>
|
||||||
<li><a href="#usage">Usage</a><ul>
|
<li><a href="#usage">Usage</a>
|
||||||
|
<ul>
|
||||||
<li><a href="#flags">Flags</a></li>
|
<li><a href="#flags">Flags</a></li>
|
||||||
<li><a href="#default-keyboard-bindings">Default keyboard bindings</a></li>
|
<li><a href="#default-keyboard-bindings">Default keyboard bindings</a></li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li><a href="#examples">Examples</a></li>
|
<li><a href="#examples">Examples</a></li>
|
||||||
<li><a href="#customization">Customization</a><ul>
|
<li><a href="#customization">Customization</a>
|
||||||
|
<ul>
|
||||||
<li><a href="#modular-configuration">Modular Configuration</a></li>
|
<li><a href="#modular-configuration">Modular Configuration</a></li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li><a href="#bugs">Bugs</a></li>
|
<li><a href="#bugs">Bugs</a></li>
|
||||||
@@ -238,8 +241,8 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warni
|
|||||||
<p>You can find many extensions to the core feature set in the xmonad- contrib package, available through your package manager or from <a href="https://xmonad.org">xmonad.org</a>.</p>
|
<p>You can find many extensions to the core feature set in the xmonad- contrib package, available through your package manager or from <a href="https://xmonad.org">xmonad.org</a>.</p>
|
||||||
<h2 id="modular-configuration">Modular Configuration</h2>
|
<h2 id="modular-configuration">Modular Configuration</h2>
|
||||||
<p>As of <em>xmonad-0.9</em>, any additional Haskell modules may be placed in <em>~/.xmonad/lib/</em> are available in GHC’s searchpath. Hierarchical modules are supported: for example, the file <em>~/.xmonad/lib/XMonad/Stack/MyAdditions.hs</em> could contain:</p>
|
<p>As of <em>xmonad-0.9</em>, any additional Haskell modules may be placed in <em>~/.xmonad/lib/</em> are available in GHC’s searchpath. Hierarchical modules are supported: for example, the file <em>~/.xmonad/lib/XMonad/Stack/MyAdditions.hs</em> could contain:</p>
|
||||||
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">module</span> <span class="dt">XMonad.Stack.MyAdditions</span> (function1) <span class="kw">where</span></a>
|
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a><span class="kw">module</span> <span class="dt">XMonad.Stack.MyAdditions</span> (function1) <span class="kw">where</span></span>
|
||||||
<a class="sourceLine" id="cb1-2" title="2"> function1 <span class="ot">=</span> <span class="fu">error</span> <span class="st">"function1: Not implemented yet!"</span></a></code></pre></div>
|
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a> function1 <span class="ot">=</span> <span class="fu">error</span> <span class="st">"function1: Not implemented yet!"</span></span></code></pre></div>
|
||||||
<p>Your xmonad.hs may then import XMonad.Stack.MyAdditions as if that module was contained within xmonad or xmonad-contrib.</p>
|
<p>Your xmonad.hs may then import XMonad.Stack.MyAdditions as if that module was contained within xmonad or xmonad-contrib.</p>
|
||||||
<h1 id="bugs">Bugs</h1>
|
<h1 id="bugs">Bugs</h1>
|
||||||
<p>Probably. If you find any, please report them to the <a href="https://github.com/xmonad/xmonad/issues">bugtracker</a></p>
|
<p>Probably. If you find any, please report them to the <a href="https://github.com/xmonad/xmonad/issues">bugtracker</a></p>
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
{-# OPTIONS_GHC -fno-warn-missing-signatures -fno-warn-orphans #-}
|
{-# OPTIONS_GHC -fno-warn-missing-signatures -fno-warn-orphans #-}
|
||||||
{-# LANGUAGE TypeFamilies #-}
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
|
{-# LANGUAGE TypeOperators #-}
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- |
|
-- |
|
||||||
-- Module : XMonad.Config
|
-- Module : XMonad.Config
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
{-# LANGUAGE CPP #-}
|
||||||
{-# LANGUAGE DeriveTraversable #-}
|
{-# LANGUAGE DeriveTraversable #-}
|
||||||
{-# LANGUAGE ExistentialQuantification #-}
|
{-# LANGUAGE ExistentialQuantification #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
@@ -6,6 +7,7 @@
|
|||||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE NamedFieldPuns #-}
|
{-# LANGUAGE NamedFieldPuns #-}
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
|
{-# LANGUAGE DerivingVia #-}
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- |
|
-- |
|
||||||
@@ -31,7 +33,7 @@ module XMonad.Core (
|
|||||||
StateExtension(..), ExtensionClass(..), ConfExtension(..),
|
StateExtension(..), ExtensionClass(..), ConfExtension(..),
|
||||||
runX, catchX, userCode, userCodeDef, io, catchIO, installSignalHandlers, uninstallSignalHandlers,
|
runX, catchX, userCode, userCodeDef, io, catchIO, installSignalHandlers, uninstallSignalHandlers,
|
||||||
withDisplay, withWindowSet, isRoot, runOnWorkspaces,
|
withDisplay, withWindowSet, isRoot, runOnWorkspaces,
|
||||||
getAtom, spawn, spawnPID, xfork, xmessage, recompile, trace, whenJust, whenX,
|
getAtom, spawn, spawnPID, xfork, xmessage, recompile, trace, whenJust, whenX, ifM,
|
||||||
getXMonadDir, getXMonadCacheDir, getXMonadDataDir, stateFileName, binFileName,
|
getXMonadDir, getXMonadCacheDir, getXMonadDataDir, stateFileName, binFileName,
|
||||||
atom_WM_STATE, atom_WM_PROTOCOLS, atom_WM_DELETE_WINDOW, atom_WM_TAKE_FOCUS, withWindowAttributes,
|
atom_WM_STATE, atom_WM_PROTOCOLS, atom_WM_DELETE_WINDOW, atom_WM_TAKE_FOCUS, withWindowAttributes,
|
||||||
ManageHook, Query(..), runQuery, Directories'(..), Directories, getDirectories,
|
ManageHook, Query(..), runQuery, Directories'(..), Directories, getDirectories,
|
||||||
@@ -44,14 +46,16 @@ import Control.Exception (fromException, try, bracket_, throw, finally, SomeExce
|
|||||||
import qualified Control.Exception as E
|
import qualified Control.Exception as E
|
||||||
import Control.Applicative ((<|>), empty)
|
import Control.Applicative ((<|>), empty)
|
||||||
import Control.Monad.Fail
|
import Control.Monad.Fail
|
||||||
|
import Control.Monad.Fix (fix)
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad (void)
|
import Control.Monad (filterM, guard, void, when)
|
||||||
import Data.Semigroup
|
import Data.Semigroup
|
||||||
import Data.Traversable (for)
|
import Data.Traversable (for)
|
||||||
import Data.Time.Clock (UTCTime)
|
import Data.Time.Clock (UTCTime)
|
||||||
import Data.Default.Class
|
import Data.Default.Class
|
||||||
import System.Environment (lookupEnv)
|
import System.Environment (lookupEnv)
|
||||||
|
import Data.List (isInfixOf, intercalate, (\\))
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.IO
|
import System.IO
|
||||||
import System.Info
|
import System.Info
|
||||||
@@ -66,8 +70,8 @@ import System.Exit
|
|||||||
import Graphics.X11.Xlib
|
import Graphics.X11.Xlib
|
||||||
import Graphics.X11.Xlib.Extras (getWindowAttributes, WindowAttributes, Event)
|
import Graphics.X11.Xlib.Extras (getWindowAttributes, WindowAttributes, Event)
|
||||||
import Data.Typeable
|
import Data.Typeable
|
||||||
import Data.List (isInfixOf, (\\))
|
|
||||||
import Data.Maybe (isJust,fromMaybe)
|
import Data.Maybe (isJust,fromMaybe)
|
||||||
|
import Data.Monoid (Ap(..))
|
||||||
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
@@ -163,12 +167,7 @@ newtype ScreenDetail = SD { screenRect :: Rectangle }
|
|||||||
--
|
--
|
||||||
newtype X a = X (ReaderT XConf (StateT XState IO) a)
|
newtype X a = X (ReaderT XConf (StateT XState IO) a)
|
||||||
deriving (Functor, Applicative, Monad, MonadFail, MonadIO, MonadState XState, MonadReader XConf)
|
deriving (Functor, Applicative, Monad, MonadFail, MonadIO, MonadState XState, MonadReader XConf)
|
||||||
|
deriving (Semigroup, Monoid) via Ap X a
|
||||||
instance Semigroup a => Semigroup (X a) where
|
|
||||||
(<>) = liftM2 (<>)
|
|
||||||
|
|
||||||
instance (Monoid a) => Monoid (X a) where
|
|
||||||
mempty = pure mempty
|
|
||||||
|
|
||||||
instance Default a => Default (X a) where
|
instance Default a => Default (X a) where
|
||||||
def = return def
|
def = return def
|
||||||
@@ -176,16 +175,11 @@ instance Default a => Default (X a) where
|
|||||||
type ManageHook = Query (Endo WindowSet)
|
type ManageHook = Query (Endo WindowSet)
|
||||||
newtype Query a = Query (ReaderT Window X a)
|
newtype Query a = Query (ReaderT Window X a)
|
||||||
deriving (Functor, Applicative, Monad, MonadReader Window, MonadIO)
|
deriving (Functor, Applicative, Monad, MonadReader Window, MonadIO)
|
||||||
|
deriving (Semigroup, Monoid) via Ap Query a
|
||||||
|
|
||||||
runQuery :: Query a -> Window -> X a
|
runQuery :: Query a -> Window -> X a
|
||||||
runQuery (Query m) = runReaderT m
|
runQuery (Query m) = runReaderT m
|
||||||
|
|
||||||
instance Semigroup a => Semigroup (Query a) where
|
|
||||||
(<>) = liftM2 (<>)
|
|
||||||
|
|
||||||
instance Monoid a => Monoid (Query a) where
|
|
||||||
mempty = pure mempty
|
|
||||||
|
|
||||||
instance Default a => Default (Query a) where
|
instance Default a => Default (Query a) where
|
||||||
def = return def
|
def = return def
|
||||||
|
|
||||||
@@ -421,9 +415,13 @@ data StateExtension =
|
|||||||
data ConfExtension = forall a. Typeable a => ConfExtension a
|
data ConfExtension = forall a. Typeable a => ConfExtension a
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------
|
-- ---------------------------------------------------------------------
|
||||||
-- | General utilities
|
-- General utilities
|
||||||
--
|
|
||||||
-- Lift an 'IO' action into the 'X' monad
|
-- | If-then-else lifted to a 'Monad'.
|
||||||
|
ifM :: Monad m => m Bool -> m a -> m a -> m a
|
||||||
|
ifM mb t f = mb >>= \b -> if b then t else f
|
||||||
|
|
||||||
|
-- | Lift an 'IO' action into the 'X' monad
|
||||||
io :: MonadIO m => IO a -> m a
|
io :: MonadIO m => IO a -> m a
|
||||||
io = liftIO
|
io = liftIO
|
||||||
|
|
||||||
@@ -451,7 +449,11 @@ xfork x = io . forkProcess . finally nullStdin $ do
|
|||||||
x
|
x
|
||||||
where
|
where
|
||||||
nullStdin = do
|
nullStdin = do
|
||||||
|
#if MIN_VERSION_unix(2,8,0)
|
||||||
|
fd <- openFd "/dev/null" ReadOnly defaultFileFlags
|
||||||
|
#else
|
||||||
fd <- openFd "/dev/null" ReadOnly Nothing defaultFileFlags
|
fd <- openFd "/dev/null" ReadOnly Nothing defaultFileFlags
|
||||||
|
#endif
|
||||||
dupTo fd stdInput
|
dupTo fd stdInput
|
||||||
closeFd fd
|
closeFd fd
|
||||||
|
|
||||||
@@ -578,21 +580,31 @@ srcFileName, libFileName :: Directories -> FilePath
|
|||||||
srcFileName Directories{ cfgDir } = cfgDir </> "xmonad.hs"
|
srcFileName Directories{ cfgDir } = cfgDir </> "xmonad.hs"
|
||||||
libFileName Directories{ cfgDir } = cfgDir </> "lib"
|
libFileName Directories{ cfgDir } = cfgDir </> "lib"
|
||||||
|
|
||||||
buildScriptFileName, stackYamlFileName :: Directories -> FilePath
|
buildScriptFileName, stackYamlFileName, nixFlakeFileName, nixDefaultFileName :: Directories -> FilePath
|
||||||
buildScriptFileName Directories{ cfgDir } = cfgDir </> "build"
|
buildScriptFileName Directories{ cfgDir } = cfgDir </> "build"
|
||||||
stackYamlFileName Directories{ cfgDir } = cfgDir </> "stack.yaml"
|
stackYamlFileName Directories{ cfgDir } = cfgDir </> "stack.yaml"
|
||||||
|
nixFlakeFileName Directories{ cfgDir } = cfgDir </> "flake.nix"
|
||||||
|
nixDefaultFileName Directories{ cfgDir } = cfgDir </> "default.nix"
|
||||||
|
|
||||||
-- | Compilation method for xmonad configuration.
|
-- | Compilation method for xmonad configuration.
|
||||||
data Compile = CompileGhc | CompileStackGhc FilePath | CompileScript FilePath
|
data Compile
|
||||||
|
= CompileGhc
|
||||||
|
| CompileStackGhc FilePath
|
||||||
|
| CompileNixFlake
|
||||||
|
| CompileNixDefault
|
||||||
|
| CompileScript FilePath
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
-- | Detect compilation method by looking for known file names in xmonad
|
-- | Detect compilation method by looking for known file names in xmonad
|
||||||
-- configuration directory.
|
-- configuration directory.
|
||||||
detectCompile :: Directories -> IO Compile
|
detectCompile :: Directories -> IO Compile
|
||||||
detectCompile dirs = tryScript <|> tryStack <|> useGhc
|
detectCompile dirs =
|
||||||
|
tryScript <|> tryStack <|> tryNixFlake <|> tryNixDefault <|> useGhc
|
||||||
where
|
where
|
||||||
buildScript = buildScriptFileName dirs
|
buildScript = buildScriptFileName dirs
|
||||||
stackYaml = stackYamlFileName dirs
|
stackYaml = stackYamlFileName dirs
|
||||||
|
flakeNix = nixFlakeFileName dirs
|
||||||
|
defaultNix = nixDefaultFileName dirs
|
||||||
|
|
||||||
tryScript = do
|
tryScript = do
|
||||||
guard =<< doesFileExist buildScript
|
guard =<< doesFileExist buildScript
|
||||||
@@ -606,6 +618,18 @@ detectCompile dirs = tryScript <|> tryStack <|> useGhc
|
|||||||
trace $ "Suggested resolution to use it: chmod u+x " <> show buildScript
|
trace $ "Suggested resolution to use it: chmod u+x " <> show buildScript
|
||||||
empty
|
empty
|
||||||
|
|
||||||
|
tryNixFlake = do
|
||||||
|
guard =<< doesFileExist flakeNix
|
||||||
|
canonNixFlake <- canonicalizePath flakeNix
|
||||||
|
trace $ "XMonad will use nix flake at " <> show canonNixFlake <> " to recompile"
|
||||||
|
pure CompileNixFlake
|
||||||
|
|
||||||
|
tryNixDefault = do
|
||||||
|
guard =<< doesFileExist defaultNix
|
||||||
|
canonNixDefault <- canonicalizePath defaultNix
|
||||||
|
trace $ "XMonad will use nix file at " <> show canonNixDefault <> " to recompile"
|
||||||
|
pure CompileNixDefault
|
||||||
|
|
||||||
tryStack = do
|
tryStack = do
|
||||||
guard =<< doesFileExist stackYaml
|
guard =<< doesFileExist stackYaml
|
||||||
canonStackYaml <- canonicalizePath stackYaml
|
canonStackYaml <- canonicalizePath stackYaml
|
||||||
@@ -613,11 +637,18 @@ detectCompile dirs = tryScript <|> tryStack <|> useGhc
|
|||||||
pure $ CompileStackGhc canonStackYaml
|
pure $ CompileStackGhc canonStackYaml
|
||||||
|
|
||||||
useGhc = do
|
useGhc = do
|
||||||
trace $ "XMonad will use ghc to recompile, because neither "
|
trace $ "XMonad will use ghc to recompile, because none of "
|
||||||
<> show buildScript <> " nor " <> show stackYaml <> " exists."
|
<> intercalate ", "
|
||||||
|
[ show buildScript
|
||||||
|
, show stackYaml
|
||||||
|
, show flakeNix
|
||||||
|
, show defaultNix
|
||||||
|
] <> " exist."
|
||||||
pure CompileGhc
|
pure CompileGhc
|
||||||
|
|
||||||
isExecutable f = E.catch (executable <$> getPermissions f) (\(SomeException _) -> return False)
|
-- | Determine whether or not the file found at the provided filepath is executable.
|
||||||
|
isExecutable :: FilePath -> IO Bool
|
||||||
|
isExecutable f = E.catch (executable <$> getPermissions f) (\(SomeException _) -> return False)
|
||||||
|
|
||||||
-- | Should we recompile xmonad configuration? Is it newer than the compiled
|
-- | Should we recompile xmonad configuration? Is it newer than the compiled
|
||||||
-- binary?
|
-- binary?
|
||||||
@@ -642,6 +673,8 @@ shouldCompile dirs CompileStackGhc{} = do
|
|||||||
if binT < stackYamlT
|
if binT < stackYamlT
|
||||||
then True <$ trace "XMonad recompiling because some files have changed."
|
then True <$ trace "XMonad recompiling because some files have changed."
|
||||||
else shouldCompile dirs CompileGhc
|
else shouldCompile dirs CompileGhc
|
||||||
|
shouldCompile _dirs CompileNixFlake{} = True <$ trace "XMonad recompiling because flake recompilation is being used."
|
||||||
|
shouldCompile _dirs CompileNixDefault{} = True <$ trace "XMonad recompiling because nix recompilation is being used."
|
||||||
shouldCompile _dirs CompileScript{} =
|
shouldCompile _dirs CompileScript{} =
|
||||||
True <$ trace "XMonad recompiling because a custom build script is being used."
|
True <$ trace "XMonad recompiling because a custom build script is being used."
|
||||||
|
|
||||||
@@ -661,6 +694,10 @@ compile dirs method =
|
|||||||
CompileStackGhc stackYaml ->
|
CompileStackGhc stackYaml ->
|
||||||
run "stack" ["build", "--silent", "--stack-yaml", stackYaml] .&&.
|
run "stack" ["build", "--silent", "--stack-yaml", stackYaml] .&&.
|
||||||
run "stack" ("ghc" : "--stack-yaml" : stackYaml : "--" : ghcArgs)
|
run "stack" ("ghc" : "--stack-yaml" : stackYaml : "--" : ghcArgs)
|
||||||
|
CompileNixFlake ->
|
||||||
|
run "nix" ["build"] >>= andCopyFromResultDir
|
||||||
|
CompileNixDefault ->
|
||||||
|
run "nix-build" [] >>= andCopyFromResultDir
|
||||||
CompileScript script ->
|
CompileScript script ->
|
||||||
run script [binFileName dirs]
|
run script [binFileName dirs]
|
||||||
where
|
where
|
||||||
@@ -674,6 +711,18 @@ compile dirs method =
|
|||||||
, "-outputdir", buildDirName dirs
|
, "-outputdir", buildDirName dirs
|
||||||
, "-o", binFileName dirs
|
, "-o", binFileName dirs
|
||||||
]
|
]
|
||||||
|
andCopyFromResultDir exitCode = do
|
||||||
|
if exitCode == ExitSuccess then copyFromResultDir else return exitCode
|
||||||
|
findM p = foldr (\x -> ifM (p x) (pure $ Just x)) (pure Nothing)
|
||||||
|
catchAny :: IO a -> (SomeException -> IO a) -> IO a
|
||||||
|
catchAny = E.catch
|
||||||
|
copyFromResultDir = do
|
||||||
|
let binaryDirectory = cfgDir dirs </> "result" </> "bin"
|
||||||
|
binFiles <- map (binaryDirectory </>) <$> catchAny (listDirectory binaryDirectory) (\_ -> return [])
|
||||||
|
mfilepath <- findM isExecutable binFiles
|
||||||
|
case mfilepath of
|
||||||
|
Just filepath -> copyFile filepath (binFileName dirs) >> return ExitSuccess
|
||||||
|
Nothing -> return $ ExitFailure 1
|
||||||
|
|
||||||
-- waitForProcess =<< System.Process.runProcess, but without closing the err handle
|
-- waitForProcess =<< System.Process.runProcess, but without closing the err handle
|
||||||
runProc cwd err exe args = do
|
runProc cwd err exe args = do
|
||||||
|
@@ -62,9 +62,13 @@ data Tall a = Tall { tallNMaster :: !Int -- ^ The default number o
|
|||||||
|
|
||||||
-- a nice pure layout, lots of properties for the layout, and its messages, in Properties.hs
|
-- a nice pure layout, lots of properties for the layout, and its messages, in Properties.hs
|
||||||
instance LayoutClass Tall a where
|
instance LayoutClass Tall a where
|
||||||
pureLayout (Tall nmaster _ frac) r s = zip ws rs
|
pureLayout (Tall nmaster _ frac) r s
|
||||||
|
| frac == 0 = drop nmaster layout
|
||||||
|
| frac == 1 = take nmaster layout
|
||||||
|
| otherwise = layout
|
||||||
where ws = W.integrate s
|
where ws = W.integrate s
|
||||||
rs = tile frac r nmaster (length ws)
|
rs = tile frac r nmaster (length ws)
|
||||||
|
layout = zip ws rs
|
||||||
|
|
||||||
pureMessage (Tall nmaster delta frac) m =
|
pureMessage (Tall nmaster delta frac) m =
|
||||||
msum [fmap resize (fromMessage m)
|
msum [fmap resize (fromMessage m)
|
||||||
|
@@ -15,18 +15,18 @@
|
|||||||
--
|
--
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
module XMonad.Main (xmonad, launch) where
|
module XMonad.Main (xmonad, buildLaunch, launch) where
|
||||||
|
|
||||||
import System.Locale.SetLocale
|
import System.Locale.SetLocale
|
||||||
import qualified Control.Exception as E
|
import qualified Control.Exception as E
|
||||||
import Data.Bits
|
import Data.Bits
|
||||||
import Data.List ((\\))
|
import Data.List ((\\))
|
||||||
import Data.Foldable (traverse_)
|
import Data.Foldable (traverse_)
|
||||||
import Data.Function
|
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
|
import Control.Monad (filterM, guard, unless, void, when)
|
||||||
import Data.Maybe (fromMaybe, isJust)
|
import Data.Maybe (fromMaybe, isJust)
|
||||||
import Data.Monoid (getAll)
|
import Data.Monoid (getAll)
|
||||||
|
|
||||||
@@ -131,25 +131,6 @@ buildLaunch dirs = do
|
|||||||
args <- getArgs
|
args <- getArgs
|
||||||
executeFile bin False args Nothing
|
executeFile bin False args Nothing
|
||||||
|
|
||||||
sendRestart :: IO ()
|
|
||||||
sendRestart = do
|
|
||||||
dpy <- openDisplay ""
|
|
||||||
rw <- rootWindow dpy $ defaultScreen dpy
|
|
||||||
xmonad_restart <- internAtom dpy "XMONAD_RESTART" False
|
|
||||||
allocaXEvent $ \e -> do
|
|
||||||
setEventType e clientMessage
|
|
||||||
setClientMessageEvent' e rw xmonad_restart 32 []
|
|
||||||
sendEvent dpy rw False structureNotifyMask e
|
|
||||||
sync dpy False
|
|
||||||
|
|
||||||
-- | a wrapper for 'replace'
|
|
||||||
sendReplace :: IO ()
|
|
||||||
sendReplace = do
|
|
||||||
dpy <- openDisplay ""
|
|
||||||
let dflt = defaultScreen dpy
|
|
||||||
rootw <- rootWindow dpy dflt
|
|
||||||
replace dpy dflt rootw
|
|
||||||
|
|
||||||
-- | Entry point into xmonad for custom builds.
|
-- | Entry point into xmonad for custom builds.
|
||||||
--
|
--
|
||||||
-- This function isn't meant to be called by the typical xmonad user
|
-- This function isn't meant to be called by the typical xmonad user
|
||||||
@@ -484,36 +465,3 @@ grabButtons = do
|
|||||||
ems <- extraModifiers
|
ems <- extraModifiers
|
||||||
ba <- asks buttonActions
|
ba <- asks buttonActions
|
||||||
mapM_ (\(m,b) -> mapM_ (grab b . (m .|.)) ems) (M.keys ba)
|
mapM_ (\(m,b) -> mapM_ (grab b . (m .|.)) ems) (M.keys ba)
|
||||||
|
|
||||||
-- | @replace@ to signals compliant window managers to exit.
|
|
||||||
replace :: Display -> ScreenNumber -> Window -> IO ()
|
|
||||||
replace dpy dflt rootw = do
|
|
||||||
-- check for other WM
|
|
||||||
wmSnAtom <- internAtom dpy ("WM_S" ++ show dflt) False
|
|
||||||
currentWmSnOwner <- xGetSelectionOwner dpy wmSnAtom
|
|
||||||
when (currentWmSnOwner /= 0) $ do
|
|
||||||
-- prepare to receive destroyNotify for old WM
|
|
||||||
selectInput dpy currentWmSnOwner structureNotifyMask
|
|
||||||
|
|
||||||
-- create off-screen window
|
|
||||||
netWmSnOwner <- allocaSetWindowAttributes $ \attributes -> do
|
|
||||||
set_override_redirect attributes True
|
|
||||||
set_event_mask attributes propertyChangeMask
|
|
||||||
let screen = defaultScreenOfDisplay dpy
|
|
||||||
visual = defaultVisualOfScreen screen
|
|
||||||
attrmask = cWOverrideRedirect .|. cWEventMask
|
|
||||||
createWindow dpy rootw (-100) (-100) 1 1 0 copyFromParent copyFromParent visual attrmask attributes
|
|
||||||
|
|
||||||
-- try to acquire wmSnAtom, this should signal the old WM to terminate
|
|
||||||
xSetSelectionOwner dpy wmSnAtom netWmSnOwner currentTime
|
|
||||||
|
|
||||||
-- SKIPPED: check if we acquired the selection
|
|
||||||
-- SKIPPED: send client message indicating that we are now the WM
|
|
||||||
|
|
||||||
-- wait for old WM to go away
|
|
||||||
fix $ \again -> do
|
|
||||||
evt <- allocaXEvent $ \event -> do
|
|
||||||
windowEvent dpy currentWmSnOwner structureNotifyMask event
|
|
||||||
get_EventType event
|
|
||||||
|
|
||||||
when (evt /= destroyNotify) again
|
|
||||||
|
@@ -64,10 +64,6 @@ x <&&> y = ifM x y (pure False)
|
|||||||
(<||>) :: Monad m => m Bool -> m Bool -> m Bool
|
(<||>) :: Monad m => m Bool -> m Bool -> m Bool
|
||||||
x <||> y = ifM x (pure True) y
|
x <||> y = ifM x (pure True) y
|
||||||
|
|
||||||
-- | If-then-else lifted to a 'Monad'.
|
|
||||||
ifM :: Monad m => m Bool -> m a -> m a -> m a
|
|
||||||
ifM mb t f = mb >>= \b -> if b then t else f
|
|
||||||
|
|
||||||
-- | Return the window title.
|
-- | Return the window title.
|
||||||
title :: Query String
|
title :: Query String
|
||||||
title = ask >>= \w -> liftX $ do
|
title = ask >>= \w -> liftX $ do
|
||||||
@@ -77,7 +73,7 @@ title = ask >>= \w -> liftX $ do
|
|||||||
(internAtom d "_NET_WM_NAME" False >>= getTextProperty d w)
|
(internAtom d "_NET_WM_NAME" False >>= getTextProperty d w)
|
||||||
`E.catch` \(SomeException _) -> getTextProperty d w wM_NAME
|
`E.catch` \(SomeException _) -> getTextProperty d w wM_NAME
|
||||||
extract prop = do l <- wcTextPropertyToTextList d prop
|
extract prop = do l <- wcTextPropertyToTextList d prop
|
||||||
return $ if null l then "" else head l
|
return $ fromMaybe "" $ listToMaybe l
|
||||||
io $ bracket getProp (xFree . tp_value) extract `E.catch` \(SomeException _) -> return ""
|
io $ bracket getProp (xFree . tp_value) extract `E.catch` \(SomeException _) -> return ""
|
||||||
|
|
||||||
-- | Return the application name; i.e., the /first/ string returned by
|
-- | Return the application name; i.e., the /first/ string returned by
|
||||||
|
@@ -33,10 +33,11 @@ module XMonad.Operations (
|
|||||||
-- * Keyboard and Mouse
|
-- * Keyboard and Mouse
|
||||||
cleanMask, extraModifiers,
|
cleanMask, extraModifiers,
|
||||||
mouseDrag, mouseMoveWindow, mouseResizeWindow,
|
mouseDrag, mouseMoveWindow, mouseResizeWindow,
|
||||||
setButtonGrab, setFocusX, cacheNumlockMask, mkGrabs,
|
setButtonGrab, setFocusX, cacheNumlockMask, mkGrabs, unGrab,
|
||||||
|
|
||||||
-- * Messages
|
-- * Messages
|
||||||
sendMessage, broadcastMessage, sendMessageWithNoRefresh,
|
sendMessage, broadcastMessage, sendMessageWithNoRefresh,
|
||||||
|
sendRestart, sendReplace,
|
||||||
|
|
||||||
-- * Save and Restore State
|
-- * Save and Restore State
|
||||||
StateFile (..), writeStateToFile, readStateFile, restart,
|
StateFile (..), writeStateToFile, readStateFile, restart,
|
||||||
@@ -70,9 +71,10 @@ import qualified Data.Map as M
|
|||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
|
|
||||||
import Control.Arrow (second)
|
import Control.Arrow (second)
|
||||||
|
import Control.Monad.Fix (fix)
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
import Control.Monad (void)
|
import Control.Monad (forM, forM_, guard, join, unless, void, when)
|
||||||
import qualified Control.Exception as C
|
import qualified Control.Exception as C
|
||||||
|
|
||||||
import System.IO
|
import System.IO
|
||||||
@@ -195,6 +197,7 @@ windows f = do
|
|||||||
let m = W.floating ws
|
let m = W.floating ws
|
||||||
flt = [(fw, scaleRationalRect viewrect r)
|
flt = [(fw, scaleRationalRect viewrect r)
|
||||||
| fw <- filter (`M.member` m) (W.index this)
|
| fw <- filter (`M.member` m) (W.index this)
|
||||||
|
, fw `notElem` vis
|
||||||
, Just r <- [M.lookup fw m]]
|
, Just r <- [M.lookup fw m]]
|
||||||
vs = flt ++ rs
|
vs = flt ++ rs
|
||||||
|
|
||||||
@@ -472,6 +475,28 @@ mkGrabs ks = withDisplay $ \dpy -> do
|
|||||||
, extraMod <- extraMods
|
, extraMod <- extraMods
|
||||||
]
|
]
|
||||||
|
|
||||||
|
-- | Release XMonad's keyboard grab, so other grabbers can do their thing.
|
||||||
|
--
|
||||||
|
-- Start a keyboard action with this if it is going to run something
|
||||||
|
-- that needs to do a keyboard, pointer, or server grab. For example,
|
||||||
|
--
|
||||||
|
-- > , ((modm .|. controlMask, xK_p), unGrab >> spawn "scrot")
|
||||||
|
--
|
||||||
|
-- (Other examples are certain screen lockers and "gksu".)
|
||||||
|
-- This avoids needing to insert a pause/sleep before running the
|
||||||
|
-- command.
|
||||||
|
--
|
||||||
|
-- XMonad retains the keyboard grab during key actions because if they
|
||||||
|
-- use a submap, they need the keyboard to be grabbed, and if they had
|
||||||
|
-- to assert their own grab then the asynchronous nature of X11 allows
|
||||||
|
-- race conditions between XMonad, other clients, and the X server that
|
||||||
|
-- would cause keys to sometimes be "leaked" to the focused window.
|
||||||
|
unGrab :: X ()
|
||||||
|
unGrab = withDisplay $ \d -> io $ do
|
||||||
|
ungrabKeyboard d currentTime
|
||||||
|
ungrabPointer d currentTime
|
||||||
|
sync d False
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
-- Message handling
|
-- Message handling
|
||||||
|
|
||||||
@@ -518,6 +543,59 @@ setLayout l = do
|
|||||||
handleMessage (W.layout ws) (SomeMessage ReleaseResources)
|
handleMessage (W.layout ws) (SomeMessage ReleaseResources)
|
||||||
windows $ const $ ss{ W.current = c{ W.workspace = ws{ W.layout = l } } }
|
windows $ const $ ss{ W.current = c{ W.workspace = ws{ W.layout = l } } }
|
||||||
|
|
||||||
|
-- | Signal xmonad to restart itself.
|
||||||
|
sendRestart :: IO ()
|
||||||
|
sendRestart = do
|
||||||
|
dpy <- openDisplay ""
|
||||||
|
rw <- rootWindow dpy $ defaultScreen dpy
|
||||||
|
xmonad_restart <- internAtom dpy "XMONAD_RESTART" False
|
||||||
|
allocaXEvent $ \e -> do
|
||||||
|
setEventType e clientMessage
|
||||||
|
setClientMessageEvent' e rw xmonad_restart 32 []
|
||||||
|
sendEvent dpy rw False structureNotifyMask e
|
||||||
|
sync dpy False
|
||||||
|
|
||||||
|
-- | Signal compliant window managers to exit.
|
||||||
|
sendReplace :: IO ()
|
||||||
|
sendReplace = do
|
||||||
|
dpy <- openDisplay ""
|
||||||
|
let dflt = defaultScreen dpy
|
||||||
|
rootw <- rootWindow dpy dflt
|
||||||
|
replace dpy dflt rootw
|
||||||
|
|
||||||
|
-- | Signal compliant window managers to exit.
|
||||||
|
replace :: Display -> ScreenNumber -> Window -> IO ()
|
||||||
|
replace dpy dflt rootw = do
|
||||||
|
-- check for other WM
|
||||||
|
wmSnAtom <- internAtom dpy ("WM_S" ++ show dflt) False
|
||||||
|
currentWmSnOwner <- xGetSelectionOwner dpy wmSnAtom
|
||||||
|
when (currentWmSnOwner /= 0) $ do
|
||||||
|
-- prepare to receive destroyNotify for old WM
|
||||||
|
selectInput dpy currentWmSnOwner structureNotifyMask
|
||||||
|
|
||||||
|
-- create off-screen window
|
||||||
|
netWmSnOwner <- allocaSetWindowAttributes $ \attributes -> do
|
||||||
|
set_override_redirect attributes True
|
||||||
|
set_event_mask attributes propertyChangeMask
|
||||||
|
let screen = defaultScreenOfDisplay dpy
|
||||||
|
visual = defaultVisualOfScreen screen
|
||||||
|
attrmask = cWOverrideRedirect .|. cWEventMask
|
||||||
|
createWindow dpy rootw (-100) (-100) 1 1 0 copyFromParent copyFromParent visual attrmask attributes
|
||||||
|
|
||||||
|
-- try to acquire wmSnAtom, this should signal the old WM to terminate
|
||||||
|
xSetSelectionOwner dpy wmSnAtom netWmSnOwner currentTime
|
||||||
|
|
||||||
|
-- SKIPPED: check if we acquired the selection
|
||||||
|
-- SKIPPED: send client message indicating that we are now the WM
|
||||||
|
|
||||||
|
-- wait for old WM to go away
|
||||||
|
fix $ \again -> do
|
||||||
|
evt <- allocaXEvent $ \event -> do
|
||||||
|
windowEvent dpy currentWmSnOwner structureNotifyMask event
|
||||||
|
get_EventType event
|
||||||
|
|
||||||
|
when (evt /= destroyNotify) again
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
-- Utilities
|
-- Utilities
|
||||||
|
|
||||||
@@ -648,6 +726,7 @@ floatLocation w =
|
|||||||
|
|
||||||
where go = withDisplay $ \d -> do
|
where go = withDisplay $ \d -> do
|
||||||
ws <- gets windowset
|
ws <- gets windowset
|
||||||
|
sh <- io $ getWMNormalHints d w
|
||||||
wa <- io $ getWindowAttributes d w
|
wa <- io $ getWindowAttributes d w
|
||||||
let bw = (fromIntegral . wa_border_width) wa
|
let bw = (fromIntegral . wa_border_width) wa
|
||||||
point_sc <- pointScreen (fi $ wa_x wa) (fi $ wa_y wa)
|
point_sc <- pointScreen (fi $ wa_x wa) (fi $ wa_y wa)
|
||||||
@@ -662,13 +741,14 @@ floatLocation w =
|
|||||||
sr = screenRect . W.screenDetail $ sc
|
sr = screenRect . W.screenDetail $ sc
|
||||||
x = (fi (wa_x wa) - fi (rect_x sr)) % fi (rect_width sr)
|
x = (fi (wa_x wa) - fi (rect_x sr)) % fi (rect_width sr)
|
||||||
y = (fi (wa_y wa) - fi (rect_y sr)) % fi (rect_height sr)
|
y = (fi (wa_y wa) - fi (rect_y sr)) % fi (rect_height sr)
|
||||||
width = fi (wa_width wa + bw*2) % fi (rect_width sr)
|
(width, height) = applySizeHintsContents sh (wa_width wa, wa_height wa)
|
||||||
height = fi (wa_height wa + bw*2) % fi (rect_height sr)
|
rwidth = fi (width + bw*2) % fi (rect_width sr)
|
||||||
|
rheight = fi (height + bw*2) % fi (rect_height sr)
|
||||||
-- adjust x/y of unmanaged windows if we ignored or didn't get pointScreen,
|
-- adjust x/y of unmanaged windows if we ignored or didn't get pointScreen,
|
||||||
-- it might be out of bounds otherwise
|
-- it might be out of bounds otherwise
|
||||||
rr = if managed || point_sc `sr_eq` Just sc
|
rr = if managed || point_sc `sr_eq` Just sc
|
||||||
then W.RationalRect x y width height
|
then W.RationalRect x y rwidth rheight
|
||||||
else W.RationalRect (0.5 - width/2) (0.5 - height/2) width height
|
else W.RationalRect (0.5 - rwidth/2) (0.5 - rheight/2) rwidth rheight
|
||||||
|
|
||||||
return (W.screen sc, rr)
|
return (W.screen sc, rr)
|
||||||
|
|
||||||
|
@@ -106,7 +106,10 @@ import qualified Data.Map as M (Map,insert,delete,empty)
|
|||||||
--
|
--
|
||||||
-- <https://dspace.library.uu.nl/handle/1874/2532 R. Hinze and J. Jeuring, Functional Pearl: Weaving a Web>
|
-- <https://dspace.library.uu.nl/handle/1874/2532 R. Hinze and J. Jeuring, Functional Pearl: Weaving a Web>
|
||||||
--
|
--
|
||||||
-- and Conor McBride's zipper differentiation paper.
|
-- and
|
||||||
|
--
|
||||||
|
-- <http://strictlypositive.org/diff.pdf Conor McBride, The Derivative of a Regular Type is its Type of One-Hole Contexts>.
|
||||||
|
--
|
||||||
-- Another good reference is: <https://wiki.haskell.org/Zipper The Zipper, Haskell wikibook>
|
-- Another good reference is: <https://wiki.haskell.org/Zipper The Zipper, Haskell wikibook>
|
||||||
|
|
||||||
-- $xinerama
|
-- $xinerama
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
resolver: lts-19.6
|
resolver: lts-21.12
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
- ./
|
- ./
|
||||||
@@ -6,13 +6,6 @@ packages:
|
|||||||
extra-deps:
|
extra-deps:
|
||||||
- X11-1.10
|
- X11-1.10
|
||||||
|
|
||||||
flags:
|
|
||||||
xmonad:
|
|
||||||
# stack doesn't support automatic flags
|
|
||||||
# https://cabal.readthedocs.io/en/latest/cabal-package.html#resolution-of-conditions-and-flags
|
|
||||||
# https://github.com/commercialhaskell/stack/issues/1313#issuecomment-157259270
|
|
||||||
quickcheck-classes: false
|
|
||||||
|
|
||||||
nix:
|
nix:
|
||||||
packages:
|
packages:
|
||||||
- zlib
|
- zlib
|
||||||
|
@@ -166,11 +166,16 @@ tests =
|
|||||||
-- tall layout
|
-- tall layout
|
||||||
|
|
||||||
,("tile 1 window fullsize", property prop_tile_fullscreen)
|
,("tile 1 window fullsize", property prop_tile_fullscreen)
|
||||||
|
,("tile max ratio", property prop_tile_max_ratio)
|
||||||
|
,("tile min ratio", property prop_tile_min_ratio)
|
||||||
,("tiles never overlap", property prop_tile_non_overlap)
|
,("tiles never overlap", property prop_tile_non_overlap)
|
||||||
,("split horizontal", property prop_split_horizontal)
|
,("split horizontal", property prop_split_horizontal)
|
||||||
,("split vertical", property prop_split_vertical)
|
,("split vertical", property prop_split_vertical)
|
||||||
|
|
||||||
,("pure layout tall", property prop_purelayout_tall)
|
,("pure layout tall", property prop_purelayout_tall)
|
||||||
|
{- Following two test cases should be automatically generated by QuickCheck ideally, but it fails. -}
|
||||||
|
,("pure layout tall: ratio = 0", property (\n d rect -> prop_purelayout_tall n d 0 rect))
|
||||||
|
,("pure layout tall: ratio = 1", property (\n d rect -> prop_purelayout_tall n d 1 rect))
|
||||||
,("send shrink tall", property prop_shrink_tall)
|
,("send shrink tall", property prop_shrink_tall)
|
||||||
,("send expand tall", property prop_expand_tall)
|
,("send expand tall", property prop_expand_tall)
|
||||||
,("send incmaster tall", property prop_incmaster_tall)
|
,("send incmaster tall", property prop_incmaster_tall)
|
||||||
|
@@ -11,8 +11,9 @@ import XMonad.Layout
|
|||||||
|
|
||||||
import Graphics.X11.Xlib.Types (Rectangle(..))
|
import Graphics.X11.Xlib.Types (Rectangle(..))
|
||||||
|
|
||||||
import Data.Maybe
|
import Control.Applicative
|
||||||
import Data.List (sort)
|
import Data.List (sort)
|
||||||
|
import Data.Maybe
|
||||||
import Data.Ratio
|
import Data.Ratio
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
@@ -27,6 +28,22 @@ prop_tile_non_overlap rect windows nmaster = noOverlaps (tile pct rect nmaster w
|
|||||||
where _ = rect :: Rectangle
|
where _ = rect :: Rectangle
|
||||||
pct = 3 % 100
|
pct = 3 % 100
|
||||||
|
|
||||||
|
-- with a ratio of 1, no stack windows are drawn of there is at least
|
||||||
|
-- one master window around.
|
||||||
|
prop_tile_max_ratio = extremeRatio 1 drop
|
||||||
|
|
||||||
|
-- with a ratio of 0, no master windows are drawn at all if there are
|
||||||
|
-- any stack windows around.
|
||||||
|
prop_tile_min_ratio = extremeRatio 0 take
|
||||||
|
|
||||||
|
extremeRatio amount getRects rect = do
|
||||||
|
w@(NonNegative windows) <- arbitrary `suchThat` (> NonNegative 0)
|
||||||
|
NonNegative nmaster <- arbitrary `suchThat` (< w)
|
||||||
|
let tiled = tile amount rect nmaster windows
|
||||||
|
pure $ if nmaster == 0
|
||||||
|
then prop_tile_non_overlap rect windows nmaster
|
||||||
|
else all ((== 0) . rect_width) $ getRects nmaster tiled
|
||||||
|
|
||||||
-- splitting horizontally yields sensible results
|
-- splitting horizontally yields sensible results
|
||||||
prop_split_horizontal (NonNegative n) x =
|
prop_split_horizontal (NonNegative n) x =
|
||||||
noOverflows (+) (rect_x x) (rect_width x) ==>
|
noOverflows (+) (rect_x x) (rect_width x) ==>
|
||||||
@@ -49,13 +66,20 @@ prop_split_vertical (r :: Rational) x =
|
|||||||
|
|
||||||
|
|
||||||
-- pureLayout works.
|
-- pureLayout works.
|
||||||
prop_purelayout_tall n r1 r2 rect = do
|
prop_purelayout_tall n d r rect = do
|
||||||
x <- (arbitrary :: Gen T) `suchThat` (isJust . peek)
|
x <- (arbitrary :: Gen T) `suchThat` (isJust . peek)
|
||||||
let layout = Tall n r1 r2
|
let layout = Tall n d r
|
||||||
st = fromJust . stack . workspace . current $ x
|
st = fromJust . stack . workspace . current $ x
|
||||||
ts = pureLayout layout rect st
|
ts = pureLayout layout rect st
|
||||||
|
ntotal = length (index x)
|
||||||
return $
|
return $
|
||||||
length ts == length (index x)
|
(if r == 0 then
|
||||||
|
-- (<=) for Bool is the logical implication
|
||||||
|
(0 <= n && n <= ntotal) <= (length ts == ntotal - n)
|
||||||
|
else if r == 1 then
|
||||||
|
(0 <= n && n <= ntotal) <= (length ts == n)
|
||||||
|
else
|
||||||
|
length ts == ntotal)
|
||||||
&&
|
&&
|
||||||
noOverlaps (map snd ts)
|
noOverlaps (map snd ts)
|
||||||
&&
|
&&
|
||||||
|
@@ -1,9 +1,5 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
|
|
||||||
#ifdef VERSION_quickcheck_classes
|
|
||||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
#endif
|
|
||||||
|
|
||||||
module Properties.Stack where
|
module Properties.Stack where
|
||||||
|
|
||||||
@@ -15,13 +11,11 @@ import qualified XMonad.StackSet as S (filter)
|
|||||||
|
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
|
||||||
#ifdef VERSION_quickcheck_classes
|
|
||||||
import Data.Proxy
|
import Data.Proxy
|
||||||
import Test.QuickCheck.Classes (
|
import Test.QuickCheck.Classes (
|
||||||
Laws (lawsTypeclass, lawsProperties), Proxy1 (Proxy1),
|
Laws (lawsTypeclass, lawsProperties), Proxy1 (Proxy1),
|
||||||
foldableLaws, traversableLaws,
|
foldableLaws, traversableLaws,
|
||||||
)
|
)
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- The list returned by index should be the same length as the actual
|
-- The list returned by index should be the same length as the actual
|
||||||
@@ -65,7 +59,6 @@ prop_differentiate xs =
|
|||||||
where _ = xs :: [Int]
|
where _ = xs :: [Int]
|
||||||
|
|
||||||
|
|
||||||
#ifdef VERSION_quickcheck_classes
|
|
||||||
-- Check type class laws of 'Data.Foldable.Foldable' and 'Data.Traversable.Traversable'.
|
-- Check type class laws of 'Data.Foldable.Foldable' and 'Data.Traversable.Traversable'.
|
||||||
newtype TestStack a = TestStack (Stack a)
|
newtype TestStack a = TestStack (Stack a)
|
||||||
deriving (Eq, Read, Show, Foldable, Functor)
|
deriving (Eq, Read, Show, Foldable, Functor)
|
||||||
@@ -82,6 +75,3 @@ prop_laws_Stack = format (foldableLaws p) <> format (traversableLaws p)
|
|||||||
p = Proxy :: Proxy TestStack
|
p = Proxy :: Proxy TestStack
|
||||||
format laws = [ ("Stack: " <> lawsTypeclass laws <> ": " <> name, prop)
|
format laws = [ ("Stack: " <> lawsTypeclass laws <> ": " <> name, prop)
|
||||||
| (name, prop) <- lawsProperties laws ]
|
| (name, prop) <- lawsProperties laws ]
|
||||||
#else
|
|
||||||
prop_laws_Stack = []
|
|
||||||
#endif
|
|
||||||
|
17
xmonad.cabal
17
xmonad.cabal
@@ -1,5 +1,5 @@
|
|||||||
name: xmonad
|
name: xmonad
|
||||||
version: 0.17.1
|
version: 0.18.0
|
||||||
synopsis: A tiling window manager
|
synopsis: A tiling window manager
|
||||||
description: xmonad is a tiling window manager for X. Windows are arranged
|
description: xmonad is a tiling window manager for X. Windows are arranged
|
||||||
automatically to tile the screen without gaps or overlap, maximising
|
automatically to tile the screen without gaps or overlap, maximising
|
||||||
@@ -27,7 +27,7 @@ author: Spencer Janssen, Don Stewart, Adam Vogt, David Roundy, Jason
|
|||||||
Ondřej Súkup, Paul Hebble, Shachaf Ben-Kiki, Siim Põder, Tim McIver,
|
Ondřej Súkup, Paul Hebble, Shachaf Ben-Kiki, Siim Põder, Tim McIver,
|
||||||
Trevor Elliott, Wouter Swierstra, Conrad Irwin, Tim Thelion, Tony Zorman
|
Trevor Elliott, Wouter Swierstra, Conrad Irwin, Tim Thelion, Tony Zorman
|
||||||
maintainer: xmonad@haskell.org
|
maintainer: xmonad@haskell.org
|
||||||
tested-with: GHC == 8.4.4 || == 8.6.5 || == 8.8.4 || == 8.10.7 || == 9.0.2 || == 9.2.2
|
tested-with: GHC == 8.6.5 || == 8.8.4 || == 8.10.7 || == 9.0.2 || == 9.2.8 || == 9.4.8 || == 9.6.4 || == 9.8.1
|
||||||
category: System
|
category: System
|
||||||
homepage: http://xmonad.org
|
homepage: http://xmonad.org
|
||||||
bug-reports: https://github.com/xmonad/xmonad/issues
|
bug-reports: https://github.com/xmonad/xmonad/issues
|
||||||
@@ -54,8 +54,6 @@ flag pedantic
|
|||||||
default: False
|
default: False
|
||||||
manual: True
|
manual: True
|
||||||
|
|
||||||
flag quickcheck-classes
|
|
||||||
|
|
||||||
library
|
library
|
||||||
exposed-modules: XMonad
|
exposed-modules: XMonad
|
||||||
XMonad.Config
|
XMonad.Config
|
||||||
@@ -83,7 +81,7 @@ library
|
|||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
-- Keep this in sync with the oldest version in 'tested-with'
|
-- Keep this in sync with the oldest version in 'tested-with'
|
||||||
if impl(ghc > 8.4.4)
|
if impl(ghc > 8.6.5)
|
||||||
ghc-options: -Wno-unused-imports
|
ghc-options: -Wno-unused-imports
|
||||||
|
|
||||||
if flag(pedantic)
|
if flag(pedantic)
|
||||||
@@ -96,7 +94,7 @@ executable xmonad
|
|||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
-- Keep this in sync with the oldest version in 'tested-with'
|
-- Keep this in sync with the oldest version in 'tested-with'
|
||||||
if impl(ghc > 8.4.4)
|
if impl(ghc > 8.6.5)
|
||||||
ghc-options: -Wno-unused-imports
|
ghc-options: -Wno-unused-imports
|
||||||
|
|
||||||
if flag(pedantic)
|
if flag(pedantic)
|
||||||
@@ -125,15 +123,14 @@ test-suite properties
|
|||||||
hs-source-dirs: tests
|
hs-source-dirs: tests
|
||||||
build-depends: base
|
build-depends: base
|
||||||
, QuickCheck >= 2
|
, QuickCheck >= 2
|
||||||
|
, quickcheck-classes >= 0.4.3
|
||||||
, X11
|
, X11
|
||||||
, containers
|
, containers
|
||||||
, xmonad
|
, xmonad
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
if flag(quickcheck-classes) && impl(ghc > 8.5)
|
if impl(ghc > 9.8)
|
||||||
-- no quickcheck-classes in LTS-12
|
ghc-options: -Wno-x-partial
|
||||||
-- GHC 8.4 and lower needs too much boilerplate (Eq1, Show1, …)
|
|
||||||
build-depends: quickcheck-classes >= 0.4.3
|
|
||||||
|
|
||||||
if flag(pedantic)
|
if flag(pedantic)
|
||||||
ghc-options: -Werror
|
ghc-options: -Werror
|
||||||
|
Reference in New Issue
Block a user