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 |