1Glitch is a minimal X11 window manager controlled by keyboard shortcuts.
  2
  3> [!IMPORTANT]
  4> I built this window manager for personal use. There are no guarantees of
  5> stability. Main purpose is to learn X11 and also to have a window manager that
  6> is simple and that I can easily modify to my liking.
  7
  8<img width="2276" height="1380" alt="glitch" src="https://github.com/user-attachments/assets/03692400-303b-40fe-99e8-b134cc09d47e" />
  9
 10## Key Features
 11
 12- **Window Movement**: Move windows by pixel values
 13- **Window Resizing**: Resize windows
 14- **Desktop Management**: Multiple desktops and moving windows between them
 15- **Window Control**: Kill, fullscreen, PiP, and always-on-top
 16- **Maximization**: Vertical and horizontal maximization
 17- **Edge Snapping**: Snap windows to screen edges
 18- **Window Centering**: Center windows on screen
 19- **Audio Control**: Toggle microphone mute with on-screen status
 20- **Tiling Layout**: Toggle between floating and tiling layouts per desktop
 21- **Application Launcher**: Integrated .desktop-aware launcher with usage-based sorting
 22- **On-screen Indicators**: Live status for desktop, layout, mic, and clock
 23- **Live Reload**: Reload configuration without restart
 24
 25## Technical Details
 26
 27- Built on X11/Xlib for low-level window management
 28- Uses EWMH (Extended Window Manager Hints) for fullscreen and state functionality
 29- Integrated PulseAudio support for real-time microphone status tracking
 30- Uses GIO/GLib for standard-compliant .desktop file parsing and application discovery
 31- Persistent usage tracking for applications to provide "most used" sorting
 32- Xft-based on-screen widgets for system status (Clock, Mic, Layout, Desktop)
 33- Maintains state for maximized windows to enable toggle behavior
 34- Implements proper X11 event handling and window attribute management
 35
 36## Requirements
 37
 38- C compiler (GCC or Clang)
 39- GNU Make
 40- pkg-config
 41- X11 and Freetype development libraries
 42- libXft development library
 43- PulseAudio development library
 44- GLib/GIO development libraries
 45
 46### Installing Dependencies
 47
 48**Void Linux:**
 49
 50```sh
 51sudo xbps-install libX11-devel freetype-devel libXft-devel pulseaudio-devel glib-devel pkg-config
 52```
 53
 54## Compilation
 55
 56```sh
 57# Build normally
 58make
 59
 60# Use a specific compiler
 61CC=clang make
 62CC=gcc make
 63
 64# Build with debug symbols
 65DEBUG=1 make
 66
 67# Compile with optimization levels
 68OPTIMIZE=2 make
 69
 70# Clean build
 71make clean && make
 72```
 73
 74### Testing in Virtual Display
 75
 76For safe testing without affecting your main session:
 77
 78```sh
 79# Start Xephyr virtual display (requires Xephyr installed)
 80make virt
 81
 82# In another terminal, run the window manager in the virtual display
 83DISPLAY=:69 ./glitch
 84```
 85
 86## Installation
 87
 88```sh
 89# Install to /usr/local/bin by default
 90sudo make install
 91```
 92
 93## Running Glitch
 94
 95### Starting the Window Manager
 96
 97**From a display manager (login screen):**
 98- Add Glitch to your display manager's session list
 99- Select it from the session menu
100
101```sh
102# Exit current window manager first, then:
103./glitch
104
105# Start X server and window manager
106startx ./glitch
107```
108
109## Configuration
110
111Glitch uses a simple configuration system based on C header files. The
112configuration is compiled into the binary, so you need to recompile after making
113changes.
114
115### Setting Up Configuration
116
1171. **Copy the default configuration**:
118   ```sh
119   cp config.def.h config.h
120   ```
121
1222. **Edit your configuration**:
123   ```sh
124   vim config.h  # or your preferred editor
125   ```
126
1273. **Recompile the window manager**:
128   ```sh
129   make clean && make
130   ```
131
1324. **Restart or Reload**:
133   - Quit and restart, or
134   - Use `Mod+Shift+r` to reload in-place
135
136   You can also sen `SIGUSR1` to trigger restart with
137   ```sh
138   kill -s SIGUSR1 $(pidof glitch)
139   ```
140
141### Configuration Structure
142
143The configuration uses two main arrays:
144
1451. **`shortcuts[]`** - Maps keys to shell commands
1462. **`keybinds[]`** - Maps keys to window manager functions
147
148### Default Key Bindings
149
150Modifier key: `Mod4` (Super/Windows key)
151
152#### Window Movement
153
154```c
155{ MODKEY,               XK_Left,    move_window_x,       { .i = -75 } },
156{ MODKEY,               XK_Right,   move_window_x,       { .i = +75 } },
157{ MODKEY,               XK_Up,      move_window_y,       { .i = -75 } },
158{ MODKEY,               XK_Down,    move_window_y,       { .i = +75 } },
159{ MODKEY,               XK_c,       center_window,       { 0 } },
160```
161
162#### Window Resizing
163
164```c
165{ MODKEY | ShiftMask,   XK_Left,    resize_window_x,     { .i = -75 } },
166{ MODKEY | ShiftMask,   XK_Right,   resize_window_x,     { .i = +75 } },
167{ MODKEY | ShiftMask,   XK_Up,      resize_window_y,     { .i = -75 } },
168{ MODKEY | ShiftMask,   XK_Down,    resize_window_y,     { .i = +75 } },
169```
170
171#### Desktop Management
172
173```c
174// Switch to desktop
175{ MODKEY,               XK_1,       goto_desktop,        { .i = 1 } },
176// ... up to XK_9
177
178// Move window to desktop
179{ MODKEY | ShiftMask,   XK_1,       send_window_to_desktop, { .i = 1 } },
180// ... up to XK_9
181```
182
183#### Window Control
184
185```c
186{ MODKEY,               XK_f,       toggle_fullscreen,   { 0 } },
187{ MODKEY,               XK_q,       close_window,        { 0 } },
188{ MODKEY,               XK_m,       toggle_mic_mute,     { 0 } },
189{ MODKEY,               XK_p,       toggle_launcher,     { 0 } },
190{ MODKEY,               XK_space,   toggle_layout,       { 0 } },
191{ MODKEY | ShiftMask,   XK_q,       quit,                { 0 } },
192{ MODKEY | ShiftMask,   XK_r,       reload,              { 0 } },
193{ MODKEY | ShiftMask,   XK_s,       toggle_pip,          { 0 } },
194{ MODKEY | ShiftMask,   XK_t,       toggle_always_on_top,{ 0 } },
195{ Mod1Mask,             XK_Tab,     cycle_active_window, { .i = 0 } },
196{ Mod1Mask | ShiftMask, XK_Tab,     cycle_active_window, { .i = 1 } },
197```
198
199#### Window Maximization
200
201```c
202{ MODKEY,               XK_x,       window_hmaximize,    { 0 } },
203{ MODKEY,               XK_z,       window_vmaximize,    { 0 } },
204```
205
206#### Window Snapping
207
208```c
209{ MODKEY | ControlMask, XK_Up,      window_snap_up,      { 0 } },
210{ MODKEY | ControlMask, XK_Down,    window_snap_down,    { 0 } },
211{ MODKEY | ControlMask, XK_Right,   window_snap_right,   { 0 } },
212{ MODKEY | ControlMask, XK_Left,    window_snap_left,    { 0 } },
213```
214
215### Shell Commands
216
217Defined in `shortcuts[]` array:
218- `Mod+Return`: Terminal (st)
219- `Mod+p`: Internal application launcher
220- `Mod+w`: Browser (brave)
221- `Mod+e`: File Manager (thunar)
222- `Mod+s`: Screen magnifier (xmagnify)
223- `Mod+r`: Screen recorder (SSR)
224- `Mod+l`: Screen lock (xlock)
225- `Control+Escape`: Screenshot (maim)
226
227## Function Reference
228
229| Function | Category | Parameters | Description |
230| --- | --- | --- | --- |
231| `move_window_x` | Movement | `arg->i` (pixels) | Move window horizontally (positive = right) |
232| `move_window_y` | Movement | `arg->i` (pixels) | Move window vertically (positive = down) |
233| `resize_window_x` | Resize | `arg->i` (pixels) | Resize window width (positive = wider) |
234| `resize_window_y` | Resize | `arg->i` (pixels) | Resize window height (positive = taller) |
235| `center_window` | Movement | None | Center window on screen |
236| `window_snap_up` | Snap | None | Snap window to top edge |
237| `window_snap_down` | Snap | None | Snap window to bottom edge |
238| `window_snap_left` | Snap | None | Snap window to left edge |
239| `window_snap_right` | Snap | None | Snap window to right edge |
240| `goto_desktop` | Desktop | `arg->i` (desktop #) | Switch to specified desktop |
241| `send_window_to_desktop` | Desktop | `arg->i` (desktop #) | Move window to specified desktop |
242| `cycle_active_window` | Focus | `arg->i` (0=fwd, 1=back) | Cycle focus through windows |
243| `close_window` | Control | None | Gracefully close active window |
244| `quit` | Control | None | Exit the window manager |
245| `toggle_fullscreen` | Control | None | Toggle fullscreen mode |
246| `toggle_pip` | Control | None | Toggle Picture-in-Picture mode |
247| `toggle_always_on_top` | Control | None | Toggle Always-on-Top status |
248| `window_hmaximize` | Maximize | None | Toggle horizontal maximize |
249| `window_vmaximize` | Maximize | None | Toggle vertical maximize |
250| `toggle_mic_mute` | Audio | None | Toggle microphone mute state |
251| `toggle_launcher` | Control | None | Toggle integrated app launcher |
252| `toggle_layout` | Layout | None | Toggle between floating/tiling |
253| `reload` | System | None | Reload configuration/restart WM |