The X(org)D(esktop)Pager is an attempt at writing a pager similar to the workspace switcher of XFCE, without all the extra Desktop Environment (DE) dependencies. This is useful for those that prefer a non-DE setup like xmonad, i3, etc. but would still like an Exposé-lite feature. XDPager assumes an EWMH compliant window manager.
make
xdpager
or hook it up to a keybindingXDPager provides a live view of the windows on all desktops sans-window content. Each desktop is drawn to a grid cell and labeled with its respective desktop name in the bottom left corner. XDPager has two operating modes: desktop and search.
In desktop mode, the cell background of the currently selected desktop is highlighted. The user can select a desktop and issue a switch desktop command to the window manager.
Key | Description |
---|---|
Arrow keys, hjkl, mouse pointer | selection navigation |
Return, mouse click | switch to selected desktop |
/ | switch to Search mode |
F2 | toggle text on windows between none, className, and _NET_WM_NAME |
F3 | increase the number of desktops per row |
F4 | decrease the number of desktops per row |
Escape | exit XDPager |
To enter search mode, press the forward slash key while in desktop mode. The stringPrefix
is display in the upper left corner of XDPager to signify this mode is active.
In search mode, the user can enter a text query that is equivalent to window.className.startsWith(query)
. Windows that match this predicate are outlined and the current window selection is additionally filled with color. The left/right arrow keys allow the user to rotate the selected window to the previous/next of the outlined windows. Pressing return will activate the window, which may include switching desktops.
Key | Description |
---|---|
Left, Right | rotate selection of matched windows |
Return | activate the selected window, including possibly switching desktops |
Escape | return to Desktop mode |
man
pages are TBD; XResources loading is TBD;
Configuration is loaded in a overwriting heirarchy of the following order:
config.c
The config file can be provided by command line arg -c
or $XDG_CONFIG_HOME/xdpager/xdpager-rc
. If no file is found, it is simply skipped.
Each line of the config file should be one of the following:
#
See config.c
for options that can be set by command line arguments. Note that some of these arguments are long form only.
Changes the behavior of moving the workspace selection.
navType | Description |
---|---|
NAV_NORMAL_SELECTION |
Workspace won't change until XK_Return is pressed or mouse click. |
NAV_MOVE_WITH_SELECTION |
Workspace will change when the selection changes. Typically used if xdpager is set as a sticky window. Consult your WM for limitations on sticky windows. |
NAV_MOVE_WITH_SELECTION_EXPERIMENTAL |
Workspace will change with the selection and xdpager will move to that workspace. Visually distracting depending on compositor effects, time to unmap/map/redraw, etc. Not recommended for now. |
TODO: add videos demonstrating these differences
The number of workspaces to render. XDPager will only display workspaces [0, nDesktops]. This will be irrelvant if dynamic workspaces are ever implemented.
The number of workspaces to show per row in the grid. If desktopsPerRow == nDesktops, XDPager renders a single row. If desktopsPerRow == 1, XDPager renders a single column.
The string prefix to indicates XDPager is in search mode. This string supports UTF8.
See config.h
for command line args desktopBg
, desktopFg
, selectedColor
, and fontColor
.
Fonts can be provided as a comma delimited string font
in fallback order. A separate windowFont
string of the same format is available if the window text should use a different set of fonts or fallback order.
Example: "monospace,Font Awesome 6 Free Solid" will use the
monospace
alias and fallback to Font Awesome for missing glyphs.
The following sections contain details you probably don't care about
_NET_NUM_DESKTOPS
atom on the root window._NET_CLIENT_LIST_STACKING
While XDPager relies on an EWMH compliant window manager, certain window managers (e.g. xmonad) don't fully comply with features they claim to support. Ideally, XDPager could simply watch _NET_CLIENT_LIST_STACKING
to determine which windows matter and which are above others. However, when a window manager doesn't maintain correct stacking order in this list, there is no way to tell which windows should be drawn first without asking for the children of the root window. Since the list of children has to be traversed anyway, XDPager just sources data from that.
Most window managers that comply with EWMH shouldn't have a problem.
WM_STATE
to determine which windows are visibleWM_CLASS
to determine the className for a window_NET_WM_DESKTOP
to determine which desktop a window is on_NET_DESKTOP_NAMES
to determine the names of the desktops_NET_CURRENT_DESKTOP
to determine the initial selected desktopWhy doesn't XDPager have live window content previews? Gnome/Cinnamon/whoever has a real fullscreen exposé feature!
XDPager is written with tiling window managers in mind (xmonad, i3, etc.) which treat non-visible windows differently than <your favorite DE>
. Typically, a window manager will unmap windows that aren't visible. The window managers of popular DEs cheat this by leaving offscreen window mapped. This project is not attempting to solve this limitation of the intended audience.
Why is this code so messy?
This is my first C program; I don't know what I'm doing