xmonad

来自 Arch Linux 中文维基

xmonad 是 X 下的一个平铺窗口管理器。窗口会自动排列、无间隙或重叠地平铺在屏幕上,从而最大限度地利用屏幕。窗口管理器功能可通过键盘访问:鼠标操作是可选的。

Xmonad 使用 Haskell 语言编写、配置并扩展功能的。用户可以将自定义布局算法、按键绑定和其他扩展功能写在配置文件中。

布局是动态应用的,并且在每个工作空间上可以使用不同的布局。 Xmonad 完全支持 Xinerama,后者可允许将窗口平铺在多个物理屏幕上。

安装[编辑 | 编辑源代码]

安装 xmonad 软件包,其提供了最基本的配置,最好还安装上 xmonad-contrib,可获得更有用的桌面配置以及其他平铺算法、配置和脚本等。

此外,可安装开发版本的 xmonad-gitAUR, 其还附带了些额外的依赖;以及同时安装 xmonad-contrib-gitAUR

注意: 记得在升级 xmonad 后运行 xmonad --recompile 命令,否则下次启动寻找共享库时可能会遇到问题。

如何启动[编辑 | 编辑源代码]

xinit 运行 xmonad.

或者,你也可以在 display manager(SDDM) 的会话菜单中选择 XMonad

请确保在启动 XMonad 之前你已经安装了至少一个默认终端模拟器 Xterm,当然你也可以在这之前修改 XMonad 的配置文件 ~/.xmonad/xmonad.hs 来指定一个默认的终端,这很重要,否则你将无法在新的窗口管理器下进行任何工作。

注意: 默认情况下,XMonad 之显示一个十字光标, 可以根据这个文章内容来更改默认显示, see Cursor themes#Change X shaped default cursor.

配置文件[编辑 | 编辑源代码]

创建一个配置目录 ~/.xmonad 和 配置文件 .xmonad/xmonad.hs ,然后根据下面的指导编写基础的配置项。

在更改配置文件 ~/.xmonad/xmonad.hs 后,使用 Mod+q 快捷键来重新启动 XMonad,使更改生效。

提示:默认的XMonad 的配置在没有 xmonad.hs 配置文件的情况下也是十分友好的

因为 xmonad 的配置文件使用的是 Haskell 语言编写,一般人需要自定义定制一个自己的配置文件可能是困难且耗费时间的,以下网站资源是一些关于 xmonad 的详细配置示例参考:

把更改和自定义内容写入 ~/.xmonad/xmonad.hs ,XMonad 将会从你的 def函数中读取相关参数的设定,

一个编写的 xmonad.hs 示例如下:

import XMonad

main = xmonad def
    { terminal    = "urxvt"  --默认终端
    , modMask     = mod4Mask --快捷前置键, 4是win键,1是alt也是默认的
    , borderWidth = 3        --边框宽度
    }

这里只更改了默认终端,快捷前置键和窗口边框的宽度,其他的设置还是 XMonad 的默认值 (默认值从 Xconfig继承)。

当配置越来越复杂的时候,可以把参数以赋值的形式传递给 def 函数中的变量,用更容易识别的变量名可以优化配置文件的格式布局,方便自己和其他人查看与维护。 下面是一个简单的例子:

import XMonad

myTerminal    = "urxvt"
myModMask     = mod4Mask -- Win key or Super_L
myBorderWidth = 3

main = do
  xmonad $ def
    { terminal    = myTerminal
    , modMask     = myModMask
    , borderWidth = myBorderWidth
    }


Also, order at top level (main, myTerminal, myModMask etc.), or within the {} does not matter in Haskell, as long as imports come first.


{
  terminal           = myTerminal,
  focusFollowsMouse  = myFocusFollowsMouse,
  borderWidth        = myBorderWidth,
  modMask            = myModMask,
  -- numlockMask deprecated in 0.9.1
  -- numlockMask        = myNumlockMask,
  workspaces         = myWorkspaces,
  normalBorderColor  = myNormalBorderColor,
  focusedBorderColor = myFocusedBorderColor,

  -- key bindings
  keys               = myKeys,
  mouseBindings      = myMouseBindings,

  -- hooks, layouts
  layoutHook         = myLayout,
  manageHook         = myManageHook,
  handleEventHook    = myEventHook,
  logHook            = myLogHook,
  startupHook        = myStartupHook
}

The package itself also includes a xmonad.hs, which is the latest official example xmonad.hs that comes with the xmonad Haskell module as an example of how to override everything. This should not be used as a template configuration, but as examples of parts you can pick to use in your own configuration. It is located in an architecture and version dependant directory in /usr/share/ (e.g. find /usr/share -name xmonad.hs).

A base desktop configuration[编辑 | 编辑源代码]

In xmonad-contrib is a better default configuration for average desktop uses. It also helps with problems in some modern programs like Chromium.

It can be added like so:

import XMonad
import XMonad.Config.Desktop

main = xmonad desktopConfig
    { terminal    = "urxvt"
    , modMask     = mod4Mask
    }

Exiting xmonad[编辑 | 编辑源代码]

To end the current xmonad session, press Mod+Shift+Q. By default, Mod is the Alt key.

Tips and tricks[编辑 | 编辑源代码]

X-Selection-Paste[编辑 | 编辑源代码]

The keyboard-centered operation in xmonad can be further supported with a keyboard shortcut for X-Selection-Paste.

Also, there exists a function "pasteSelection" in XMonad.Util.Paste that can be bound to a key using a line like:

xmonad.hs
  import XMonad.Util.Paste -- Remember to include this line
  
  -- X-selection-paste buffer
  , ((0, xK_Insert), pasteSelection)

Pressing the "Insert" key will now paste the mouse buffer in the active window.

Keyboard shortcuts[编辑 | 编辑源代码]

Default keyboard shortcuts are listed in the man page of xmonad.

本文或本章节的事实准确性存在争议。

原因: Shift+Insert pastes the PRIMARY buffer.(在 Talk:Xmonad 中讨论)

这篇文章的某些内容需要扩充。

原因: Why the 100ms delay? (在 Talk:Xmonad 中讨论)

Users who prefer to work with the keyboard rather than the mouse may benefit from a key binding to the paste operation of the middle mouse button. This is especially useful in a keyboard-centered environment. A workflow example is:

  1. In Firefox, select a string you want to web-search for (with the mouse).
  2. Hit Ctrl+k to enter the "search engine" field.
  3. Hit F9 to paste the buffer, instead of moving the mouse pointer to the field and middle-click to paste.
注意: Shift+Insert has a similar yet different functionality, see #Xorg: Shift+Insert inserts the clipboard buffer, not the x-selection-paste buffer. In some applications, these two buffers are mirrored.

The method suggested here uses the following three packages::

  • xsel to give access to the x-selection-buffer content.
  • Xbindkeys to bind a key-stroke to an action.
  • xvkbdAUR to pass the buffer string to the application by emulating keyboard input.

This example binds the x-selection-paste operation to the F9 key:

.xbindkeysrc
"xvkbd -no-jump-pointer -xsendevent -text "\D1`xsel`" 2>/dev/null"
    F9

The "\D1" code prefixes a 100 ms pause to inserting the selection buffer (see the xvkbd home page).

注意: Depending on your X configuration, you may need to drop the -xsendevent argument to xvkbd.

The key codes for keys other than F9 can be determined using xbindkeys -k.

References:

Targeting unbound keys[编辑 | 编辑源代码]

If you use xmonad as a stand alone window manager, you can edit the xmonad.hs to add unbound keyboard keys. You just need to find the Xf86 name of the key (such as XF86PowerDown) and look it up in /usr/include/X11/XF86keysym.h. It will give you a keycode (like 0x1008FF2A) which you can use to add a line like the following in the keybindings section of your xmonad.hs:

((0,               0x1008FF2A), spawn "sudo pm-suspend")

Increase the number of workspaces[编辑 | 编辑源代码]

By default, xmonad uses a set of 9 workspaces. You can change this by changing the workspaces parameter:

xmonad.hs
import XMonad
import XMonad.Util.EZConfig (additionalKeys)

main=do
  xmonad $ def
    { ...
    , workspaces = myWorkspaces
    , ...
    } `additionalKeys` myAdditionalKeys

myWorkspaces = ["1","2","3","4","5","6","7","8","9"] ++ (map snd myExtraWorkspaces) -- you can customize the names of the default workspaces by changing the list

myExtraWorkspaces = [(xK_0, "0")] -- list of (key, name)

myAdditionalKeys =
    [ -- ... your other hotkeys ...
    ] ++ [
        ((myModMask, key), (windows $ W.greedyView ws))
        | (key, ws) <- myExtraWorkspaces
    ] ++ [
        ((myModMask .|. shiftMask, key), (windows $ W.shift ws))
        | (key, ws) <- myExtraWorkspaces
    ]

Making room for docks/panels/trays (Xmobar, Tint2, Conky, etc)[编辑 | 编辑源代码]

Wrap your layouts with avoidStruts from XMonad.Hooks.ManageDocks for automatic dock/panel/trayer spacing:

import XMonad
import XMonad.Hooks.ManageDocks

main=do
  xmonad $ docks def
    { ...
    , layoutHook=avoidStruts $ layoutHook def
    , manageHook=manageHook def <+> manageDocks
    , ...
    }

If you ever want to toggle the gaps, this action can be added to your key bindings:

,((modMask x, xK_b     ), sendMessage ToggleStruts)

Equally sized gaps between windows[编辑 | 编辑源代码]

If your goal is to have equally sized gaps between individual windows and the screen, the following code will not work as expected:

layoutHook = spacing 10 $ Tall (1 (3/100) (1/2)) ||| Full

This makes each window have its own spacing in each direction. If you have two windows side-by-side, the spacing in the middle will be combined, creating a gap that is twice as large as needed.

A workaround is to specify both a screen and a window spacing, but only use the top and left margins for the screen and bottom and right margins for the windows. To do this, change the above code into:

 layoutHook = spacingRaw False (Border 10 0 10 0) True (Border 0 10 0 10) True $ Tall (1 (3/100) (1/2)) ||| Full

Using xmobar with xmonad[编辑 | 编辑源代码]

本文或本章节可能需要合并到xmobar

附注: Make use of the separate article available(在 Talk:Xmonad 中讨论)

xmobar is a light and minimalistic text-based bar, designed to work with xmonad. To use xmobar with xmonad, you will need two packages in addition to the xmonad package. These packages are xmonad-contrib and xmobar from the official repositories, or you can use xmobar-gitAUR from the AUR instead of the official xmobar package.

Here we will start xmobar from within xmonad, which reloads xmobar whenever you reload xmonad.

Open ~/.xmonad/xmonad.hs in your favorite editor, and choose one of the two following options:

Quick, less flexible[编辑 | 编辑源代码]

注意: There is also dzen2 which you can substitute for xmobar in either case.

Common imports:

import XMonad
import XMonad.Hooks.DynamicLog

The xmobar action starts xmobar and returns a modified configuration that includes all of the options described in #More configurable.

main = xmonad =<< xmobar def { modMask = mod4Mask {- or any other configurations here ... -}}

More configurable[编辑 | 编辑源代码]

As of xmonad(-contrib) 0.9, there is a new statusBar function in XMonad.Hooks.DynamicLog. It allows you to use your own configuration for:

  • The command used to execute the bar
  • The PP that determines what is being written to the bar
  • The key binding to toggle the gap for the bar

The following is an example of how to use it:

~/.xmonad/xmonad.hs
-- Imports.
import XMonad
import XMonad.Hooks.DynamicLog

-- The main function.
main = xmonad =<< statusBar myBar myPP toggleStrutsKey myConfig

-- Command to launch the bar.
myBar = "xmobar"

-- Custom PP, configure it as you like. It determines what is being written to the bar.
myPP = xmobarPP { ppCurrent = xmobarColor "#429942" "" . wrap "<" ">" }

-- Key binding to toggle the gap for the bar.
toggleStrutsKey XConfig {XMonad.modMask = modMask} = (modMask, xK_b)

-- Main configuration, override the defaults to your liking.
myConfig = def { modMask = mod4Mask }

Verify XMobar config[编辑 | 编辑源代码]

The template and default xmobarrc contains this.

At last, open up ~/.xmobarrc and make sure you have StdinReader in the template and run the plugin. E.g.

~/.xmobarrc
Config { ...
       , commands = [ Run StdinReader .... ]
         ...
       , template = " %StdinReader% ... "
       }

Now, all you should have to do is either to start, or restart, xmonad.

Controlling xmonad with external scripts[编辑 | 编辑源代码]

Here are a few ways to do it,

  • simulate keypress events using xdotool or similar programs. See this Ubuntu forums thread. The following command would simulate the keypress Super+n:
xdotool key Super+n
  • wmctrl -If you have desktopConfig or EwmhDesktops configured, this is a very easy to use and standard utility.

Launching another window manager within xmonad[编辑 | 编辑源代码]

If you are using xmonad-gitAUR, as of January of 2011, you can restart to another window manager from within xmonad. You just need to write a small script, and add stuff to your ~/.xmonad/xmonad.hs. Here is the script.

~/bin/obtoxmd
#!/bin/sh
openbox
xmonad

And here are the modifications you need to add to your ~/.xmonad/xmonad.hs:

~/.xmonad/xmonad.hs
import XMonad
--You need to add this import
import XMonad.Util.Replace

main do
    -- And this "replace"
    replace
    xmonad $ def
    {
    --Add the usual here
    }

You also need to add the following key binding:

~/xmonad/xmonad.hs
--Add a keybinding as follows:
((modm .|. shiftMask, xK_o     ), restart "/home/abijr/bin/obtoxmd" True)

Just remember to add a comma before or after and change the path to your actual script path. Now just Mod+q (restart xmonad to refresh the configuration), and then hit Mod+Shift+o and you should have Openbox running with the same windows open as in xmonad. To return to xmonad you should just exit Openbox. Here is a link to adamvo's ~/.xmonad/xmonad.hs which uses this setup Adamvo's xmonad.hs

KDE and xmonad[编辑 | 编辑源代码]

The xmonad wiki has instructions on how to run xmonad inside KDE

It also might be a good idea to set a global keyboard shortcut in KDE to start xmonad in case it is accidentally killed or closed.

Disable plasmashell[编辑 | 编辑源代码]

You might want to disable plasmashell (the KDE5 thing responsible for desktop background, taskbar, tray, etc.).

  cp /etc/xdg/autostart/plasmashell.desktop ~/.config/autostart/

Then edit ~/.config/autostart/plasmashell.desktop and replace Exec=plasmashell with Exec=. The result will look like this:

~/.config/autostart/plasmashell.desktop
[Desktop Entry]
Exec=
Name=Plasma Desktop Workspace
... # more stuff

IM Layout for Skype[编辑 | 编辑源代码]

In orded to create an IM layout for the newer versions of skype, the following code can be used:

xmonad.hs
myIMLayout = withIM (1%7) skype Grid
    where
      skype = And (ClassName "Skype") (Role "")

Example configurations[编辑 | 编辑源代码]

Below are some example configurations from fellow xmonad users. Feel free to add links to your own.

  • brisbin33 :: simple, useful, readable :: config screenshot
  • jelly :: Configuration with prompt, different layouts, twinview with xmobar :: xmonad.hs
  • MrElendig :: Simple configuration, with xmobar :: xmonad.hs, .xmobarrc, screenshot.
  • thayer :: A minimal mouse-friendly config ideal for netbooks :: configs screenshot
  • vicfryzel :: Beautiful and usable xmonad configuration, along with xmobar configuration, xinitrc, dmenu, and other scripts that make xmonad more usable. :: git repository, screenshot.
  • vogt :: Check out adamvo's config and many others in the official Xmonad/Config archive
  • wulax :: Example of using xmonad inside Xfce. Contains two layouts for GIMP. :: xmonad.hs, screenshot.
  • alex-courtis :: Clean xmonad, xmobar, media keys, screenshot, j4/dmenu; fonts rendered at the DPI reported by the monitor :: xmonad.hs, screenshot.

Troubleshooting[编辑 | 编辑源代码]

GNOME 3 and xmonad[编辑 | 编辑源代码]

本文或本章节的事实准确性存在争议。

原因: This no longer works with GNOME. It might still work with GNOME Flashback.(在 Talk:Xmonad 中讨论)


With the release of GNOME 3 custom GNOME sessions require additional steps to make GNOME play nicely with xmonad.

Add an xmonad session file for use by gnome-session (/usr/share/gnome-session/sessions/xmonad.session):

[GNOME Session]
Name=Xmonad session
RequiredComponents=gnome-panel;gnome-settings-daemon;
RequiredProviders=windowmanager;notifications;
DefaultProvider-windowmanager=xmonad
DefaultProvider-notifications=notification-daemon

Create a desktop file for GDM (/usr/share/xsessions/xmonad-gnome-session.desktop):

[Desktop Entry]
Name=Xmonad GNOME
Comment=Tiling window manager
TryExec=/usr/bin/gnome-session
Exec=gnome-session --session=xmonad
Type=XSession

Create or edit this file (/usr/share/applications/xmonad.desktop):

[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Xmonad
Exec=xmonad
NoDisplay=true
X-GNOME-WMName=Xmonad
X-GNOME-Autostart-Phase=WindowManager
X-GNOME-Provides=windowmanager
X-GNOME-Autostart-Notify=false

Finally, install xmonad-contrib and create or edit ~/.xmonad/xmonad.hs to have the following

import XMonad
import XMonad.Config.Gnome

main = xmonad gnomeConfig

xmonad should now appear in the list of GDM sessions and also play nicely with gnome-session itself.

Compositing in GNOME and xmonad[编辑 | 编辑源代码]

Some applications look better (e.g. GNOME Do) when composition is enabled. This, however, is not the case in the default xmonad window manager. To enable it add an additional .desktop file /usr/share/xsessions/xmonad-gnome-session-composite.desktop:

[Desktop Entry]
Name=Xmonad GNOME (Composite)
Comment=Tiling window manager
TryExec=/usr/bin/gnome-session
Exec=/usr/sbin/gnome-xmonad-composite
Type=XSession

And create /usr/sbin/gnome-xmonad-composite and chmod +x /usr/sbin/gnome-xmonad-composite:

xcompmgr &
gnome-session --session=xmonad

Now choose "Xmonad GNOME (Composite)" in the list of sessions during login. Reference xcompmgr(1) for additional "eye candy".

Xfce 4 and xmonad[编辑 | 编辑源代码]

Use xfceConfig instead of def after importing XMonad.Config.Xfce in ~/.xmonad/xmonad.hs, e.g. adapting the minimal configuration above:

import XMonad
import XMonad.Config.Xfce

main = xmonad xfceConfig
    { terminal    = "urxvt"
    , modMask     = mod4Mask
    }

Also add an entry to Settings > Session and Startup > Application Autostart that runs xmonad --replace.

Missing xmonad-i386-linux or xmonad-x86_64-linux[编辑 | 编辑源代码]

xmonad should automatically create the xmonad-i386-linux file (in ~/.xmonad/). If this it not the case, grab a configuration file from the xmonad wiki or create your own. Put the .hs and all others files in ~/.xmonad/ and run this command from the folder:

xmonad --recompile

Now you should see the file.

注意: A reason you may get an error message saying that xmonad-x86_64-linux is missing is that xmonad-contrib is not installed.

Problems with Java applications[编辑 | 编辑源代码]

If you have problems, like Java application Windows not resizing, or menus immediately closing after you click, see Java#Gray window, applications not resizing with WM, menus immediately closing.

Empty space at the bottom of gvim or terminals[编辑 | 编辑源代码]

See Vim#Empty space at the bottom of gVim windows for a solution which makes the area match the background color.

For rxvt-unicode, you can use rxvt-unicode-patchedAUR.

You can also configure xmonad to respect size hints, but this will leave a gap instead. See on Xmonad.Layout.LayoutHints.

Chromium/Chrome will not go fullscreen[编辑 | 编辑源代码]

If Chrome fails to go fullscreen when F11 is pressed, you can use the XMonad.Hooks.EwmhDesktops extension found in the xmonad-contrib package. Simply add the import statement to your ~/.xmonad/xmonad.hs:

import XMonad.Hooks.EwmhDesktops

and then add handleEventHook = fullscreenEventHook to the appropriate place; for example:

...
        xmonad $ def
            { modMask            = mod4Mask
            , handleEventHook    = fullscreenEventHook
            }
...

After a recompile/restart of xmonad, Chromium should now respond to F11 (fullscreen) as expected.

Multitouch / touchegg[编辑 | 编辑源代码]

Touchégg polls the window manager for the _NET_CLIENT_LIST (in order to fetch a list of windows it should listen for mouse events on.) By default, xmonad does not supply this property. To enable this, use the XMonad.Hooks.EwmhDesktops extension found in the xmonad-contrib package.

Keybinding issues with an azerty keyboard layout[编辑 | 编辑源代码]

Users with a keyboard with azerty layout can run into issues with certain keybindings. Using the XMonad.Config.Azerty module will solve this.

GNOME 3 mod4+p changes display configuration instead of launching dmenu[编辑 | 编辑源代码]

If you do not need the capability to switch the display-setup in the gnome-control-center, just execute

dconf write /org/gnome/settings-daemon/plugins/xrandr/active false

as your user, to disable the xrandr plugin which grabs Super+p.

Problems with focused border in VirtualBox[编辑 | 编辑源代码]

A known issue with Virtualbox (Ticket #6479) can cause problems with the focused window border. A solution can be found by installing a compositing manager like xcompmgr which overrides the incorrect behavior of vboxvideo.

Steam games (Half-Life, Left 4 Dead, …) and xmonad[编辑 | 编辑源代码]

There seems to be some trouble with xmonad and Source engine based games like Half-Life. If they do not start or get stuck with a black screen, a workaround is to start them in windowed mode. To do so, right click on the game in your Steam library and choose properties, click on launch options and enter [1]:

-windowed

Another solution is to float the window of the game using the manage hook. For example, the following line can be used for Half-Life:

 className =? "hl_linux" --> doFloat

This can also be worked around by making xmonad pay attention to EWMH hints and including its fullscreen hook [2]:

  main = xmonad $ ewmh def{ handleEventHook =
           handleEventHook def <+> fullscreenEventHook }

This has a few other effects and makes it behave more akin to fullscreen apps in other WMs.

LibreOffice - focus flicking between main window and dialog[编辑 | 编辑源代码]

The LibreOffice UI defaults to the gtk engine outside a desktop environment. This may cause problems with some xmonad configurations resulting in focus rapidly flicking between the LibreOffice main window and any open LibreOffice dialog window. Effectively locking the application. In this case the environment variable SAL_USE_VCLPLUGIN can be set to explicitly force LibreOffice to use another UI theme as outlined in LibreOffice#Theme For instance

  export SAL_USE_VCLPLUGIN=gen lowriter

to use the general (QT) UI.

Problems with finding shared libraries after update[编辑 | 编辑源代码]

The xmonad executable is located in ~/.xmonad/. After upgrading xmonad, an old executable might persist and need in that case be removed for xmonad to compile a new executable. Alternatively use xmonad --recompile.

In the case that xmonad --recompile cannot find any modules at all (including XMonad itself), try regenerating the package database cache

sudo ghc-pkg recache

Broken/missing XMonad.Prompt and window decorations[编辑 | 编辑源代码]

XMonad by default uses the font -misc-fixed-*-*-*-*-10-*-*-*-*-*-*-* [3]. If this font is missing those windows simply fail to render at all. Easiest fix is to install (xorg-fonts-misc.

See also[编辑 | 编辑源代码]