diff options
Diffstat (limited to 'docs/sxwm-dev.html')
| -rw-r--r-- | docs/sxwm-dev.html | 1119 |
1 files changed, 1119 insertions, 0 deletions
diff --git a/docs/sxwm-dev.html b/docs/sxwm-dev.html new file mode 100644 index 0000000..80062e8 --- /dev/null +++ b/docs/sxwm-dev.html @@ -0,0 +1,1119 @@ +<head> + <meta charset="UTF-8"> + <title>mallocd.com</title> + + <link rel="stylesheet" href="../style.css" type="text/css"> + + <link rel="preconnect" href="https://fonts.googleapis.com"> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> + <link href="https://fonts.googleapis.com/css2?family=Libertinus+Serif:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&display=swap" rel="stylesheet"> +</head> + +<h1>sxwm developer docs</h1> +<h2>Table of Contents</h2> +<ul> +<li><p><a href="#headers">Headers</a></p> +</li> +<li><p><a href="#sxwmc">sxwm.c</a></p> +<ul> +<li><a href="#function-table">Function Table</a></li> +<li><a href="#functions">Functions</a></li> +</ul> +</li> +</ul> +<h2>Headers</h2> +<table> +<thead> +<tr> +<th>Header</th> +<th>Job</th> +</tr> +</thead> +<tbody><tr> +<td><code>signal.h</code></td> +<td>Signal handling functions and definitions</td> +</tr> +<tr> +<td><code>unistd.h</code></td> +<td>Standard POSIX functionality</td> +</tr> +<tr> +<td><code>X11/Xatom.h</code></td> +<td>Definitions for Atom types</td> +</tr> +<tr> +<td><code>X11/Xlib.h</code></td> +<td>Core X Window System protocol and routines for creating windows</td> +</tr> +<tr> +<td><code>X11/Xproto.h</code></td> +<td>Protocol definitions for X Window System communication</td> +</tr> +<tr> +<td><code>X11/Xutil.h</code></td> +<td>Used for getting hints about windows</td> +</tr> +<tr> +<td><code>X11/extensions/Xinerama.h</code></td> +<td>Xinerama extension definitions for multi-monitor setups</td> +</tr> +<tr> +<td><code>X11/Xcursor/Xcursor.h</code></td> +<td>Modern cursor handling</td> +</tr> +<tr> +<td><code>linux/limits.h</code></td> +<td>Linux specific limits for various data types</td> +</tr> +<tr> +<td></td> +<td></td> +</tr> +<tr> +<td><code>defs.h</code></td> +<td>Project structs, macros, constants</td> +</tr> +<tr> +<td><code>extern.h</code></td> +<td>External functions to call to control wm</td> +</tr> +<tr> +<td><code>parser.h</code></td> +<td>Config file parser components</td> +</tr> +</tbody></table> +<h2>sxwm.c</h2> +<h3>Function Table</h3> +<table> +<thead> +<tr> +<th>Name</th> +<th>Params (short)</th> +<th>Returns</th> +<th>Summary</th> +</tr> +</thead> +<tbody><tr> +<td><a href="#add_client">add_client</a></td> +<td>(Window w, int ws)</td> +<td>Client *</td> +<td>Allocate, link, and initialize a managed client.</td> +</tr> +<tr> +<td><a href="#apply_fullscreen">apply_fullscreen</a></td> +<td>(Client *c, Bool on)</td> +<td>void</td> +<td>Enter or exit fullscreen and update EWMH.</td> +</tr> +<tr> +<td><a href="#centre_window">centre_window</a></td> +<td>(void)</td> +<td>void</td> +<td>Center focused floating window on its monitor.</td> +</tr> +<tr> +<td><a href="#change_workspace">change_workspace</a></td> +<td>(int ws)</td> +<td>void</td> +<td>Switch visible workspace; remap and retile.</td> +</tr> +<tr> +<td><a href="#check_parent">check_parent</a></td> +<td>(pid_t p, pid_t c)</td> +<td>int</td> +<td>Return c if p is an ancestor of c, else 0.</td> +</tr> +<tr> +<td><a href="#clean_mask">clean_mask</a></td> +<td>(int mask)</td> +<td>int</td> +<td>Clear Lock, NumLock, Mode_switch bits.</td> +</tr> +<tr> +<td><a href="#close_focused">close_focused</a></td> +<td>(void)</td> +<td>void</td> +<td>Send WM_DELETE or kill focused window.</td> +</tr> +<tr> +<td><a href="#dec_gaps">dec_gaps</a></td> +<td>(void)</td> +<td>void</td> +<td>Decrease gaps and retile.</td> +</tr> +<tr> +<td><a href="#find_client">find_client</a></td> +<td>(Window w)</td> +<td>Client *</td> +<td>Find a client by top-level window.</td> +</tr> +<tr> +<td><a href="#find_toplevel">find_toplevel</a></td> +<td>(Window w)</td> +<td>Window</td> +<td>Walk up to the toplevel window.</td> +</tr> +<tr> +<td><a href="#focus_next">focus_next</a></td> +<td>(void)</td> +<td>void</td> +<td>Focus next mapped client on current monitor.</td> +</tr> +<tr> +<td><a href="#focus_prev">focus_prev</a></td> +<td>(void)</td> +<td>void</td> +<td>Focus previous mapped client on current monitor.</td> +</tr> +<tr> +<td><a href="#focus_next_mon">focus_next_mon</a></td> +<td>(void)</td> +<td>void</td> +<td>Focus first client on next monitor or warp cursor.</td> +</tr> +<tr> +<td><a href="#focus_prev_mon">focus_prev_mon</a></td> +<td>(void)</td> +<td>void</td> +<td>Focus first client on prev monitor or warp cursor.</td> +</tr> +<tr> +<td><a href="#get_monitor_for">get_monitor_for</a></td> +<td>(Client *c)</td> +<td>int</td> +<td>Monitor index for client center point.</td> +</tr> +<tr> +<td><a href="#get_parent_process">get_parent_process</a></td> +<td>(pid_t c)</td> +<td>pid_t</td> +<td>Read /proc to get parent pid.</td> +</tr> +<tr> +<td><a href="#get_pid">get_pid</a></td> +<td>(Window w)</td> +<td>pid_t</td> +<td>Read _NET_WM_PID from window.</td> +</tr> +<tr> +<td><a href="#get_workspace_for_window">get_workspace_for_window</a></td> +<td>(Window w)</td> +<td>int</td> +<td>Resolve workspace by class rules.</td> +</tr> +<tr> +<td><a href="#grab_button">grab_button</a></td> +<td>(Mask btn, Mask mod, Window w, Bool, Mask)</td> +<td>void</td> +<td>XGrabButton helper.</td> +</tr> +<tr> +<td><a href="#grab_keys">grab_keys</a></td> +<td>(void)</td> +<td>void</td> +<td>Grab all configured keybindings.</td> +</tr> +<tr> +<td><a href="#hdl_button">hdl_button</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>ButtonPress handler (swap/move/resize/focus).</td> +</tr> +<tr> +<td><a href="#hdl_button_release">hdl_button_release</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Finish swap or drag; ungrab pointer.</td> +</tr> +<tr> +<td><a href="#hdl_client_msg">hdl_client_msg</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Handle EWMH messages (desktop/state).</td> +</tr> +<tr> +<td><a href="#hdl_config_ntf">hdl_config_ntf</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Root ConfigureNotify: refresh monitors and retile.</td> +</tr> +<tr> +<td><a href="#hdl_config_req">hdl_config_req</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>ConfigureRequest: honor for floating/fullscreen.</td> +</tr> +<tr> +<td><a href="#hdl_dummy">hdl_dummy</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>No-op handler.</td> +</tr> +<tr> +<td><a href="#hdl_destroy_ntf">hdl_destroy_ntf</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Client destroy: unlink, unswallow, refocus.</td> +</tr> +<tr> +<td><a href="#hdl_keypress">hdl_keypress</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Dispatch keybinding actions.</td> +</tr> +<tr> +<td><a href="#hdl_mapping_ntf">hdl_mapping_ntf</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Refresh keymap and regrab keys.</td> +</tr> +<tr> +<td><a href="#hdl_map_req">hdl_map_req</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Classify new window, add_client, map, swallow, etc.</td> +</tr> +<tr> +<td><a href="#hdl_motion">hdl_motion</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Pointer motion during drag; snap and clamp.</td> +</tr> +<tr> +<td><a href="#hdl_property_ntf">hdl_property_ntf</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>React to _NET_CURRENT_DESKTOP, struts, state.</td> +</tr> +<tr> +<td><a href="#hdl_unmap_ntf">hdl_unmap_ntf</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Mark unmapped and refresh layout.</td> +</tr> +<tr> +<td><a href="#inc_gaps">inc_gaps</a></td> +<td>(void)</td> +<td>void</td> +<td>Increase gaps and retile.</td> +</tr> +<tr> +<td><a href="#init_defaults">init_defaults</a></td> +<td>(void)</td> +<td>void</td> +<td>Populate default_config and copy to user_config.</td> +</tr> +<tr> +<td><a href="#is_child_proc">is_child_proc</a></td> +<td>(pid_t parent, pid_t child)</td> +<td>Bool</td> +<td>Check PPID chain within a limit.</td> +</tr> +<tr> +<td><a href="#move_master_next">move_master_next</a></td> +<td>(void)</td> +<td>void</td> +<td>Rotate master to tail.</td> +</tr> +<tr> +<td><a href="#move_master_prev">move_master_prev</a></td> +<td>(void)</td> +<td>void</td> +<td>Move tail to master.</td> +</tr> +<tr> +<td><a href="#move_next_mon">move_next_mon</a></td> +<td>(void)</td> +<td>void</td> +<td>Move focused to next monitor.</td> +</tr> +<tr> +<td><a href="#move_prev_mon">move_prev_mon</a></td> +<td>(void)</td> +<td>void</td> +<td>Move focused to previous monitor.</td> +</tr> +<tr> +<td><a href="#move_to_workspace">move_to_workspace</a></td> +<td>(int ws)</td> +<td>void</td> +<td>Send focused to ws and retile current.</td> +</tr> +<tr> +<td><a href="#move_win_down">move_win_down</a></td> +<td>(void)</td> +<td>void</td> +<td>Nudge focused floating down.</td> +</tr> +<tr> +<td><a href="#move_win_left">move_win_left</a></td> +<td>(void)</td> +<td>void</td> +<td>Nudge focused floating left.</td> +</tr> +<tr> +<td><a href="#move_win_right">move_win_right</a></td> +<td>(void)</td> +<td>void</td> +<td>Nudge focused floating right.</td> +</tr> +<tr> +<td><a href="#move_win_up">move_win_up</a></td> +<td>(void)</td> +<td>void</td> +<td>Nudge focused floating up.</td> +</tr> +<tr> +<td><a href="#other_wm">other_wm</a></td> +<td>(void)</td> +<td>void</td> +<td>Probe SubstructureRedirect to detect other WM.</td> +</tr> +<tr> +<td><a href="#other_wm_err">other_wm_err</a></td> +<td>(Display *d, XErrorEvent *ee)</td> +<td>int</td> +<td>Print and exit if another WM is running.</td> +</tr> +<tr> +<td><a href="#parse_col">parse_col</a></td> +<td>(const char *hex)</td> +<td>long</td> +<td>Parse hex color and allocate pixel.</td> +</tr> +<tr> +<td><a href="#quit">quit</a></td> +<td>(void)</td> +<td>void</td> +<td>Close display and cursors; stop main loop.</td> +</tr> +<tr> +<td><a href="#reload_config">reload_config</a></td> +<td>(void)</td> +<td>void</td> +<td>Free config data, reparse, regrab, retile.</td> +</tr> +<tr> +<td><a href="#remove_scratchpad">remove_scratchpad</a></td> +<td>(int n)</td> +<td>void</td> +<td>Detach scratchpad n and remap its client.</td> +</tr> +<tr> +<td><a href="#resize_master_add">resize_master_add</a></td> +<td>(void)</td> +<td>void</td> +<td>Grow master width on focused monitor.</td> +</tr> +<tr> +<td><a href="#resize_master_sub">resize_master_sub</a></td> +<td>(void)</td> +<td>void</td> +<td>Shrink master width on focused monitor.</td> +</tr> +<tr> +<td><a href="#resize_stack_add">resize_stack_add</a></td> +<td>(void)</td> +<td>void</td> +<td>Grow custom height for focused stack client.</td> +</tr> +<tr> +<td><a href="#resize_stack_sub">resize_stack_sub</a></td> +<td>(void)</td> +<td>void</td> +<td>Shrink custom height for focused stack client.</td> +</tr> +<tr> +<td><a href="#resize_win_down">resize_win_down</a></td> +<td>(void)</td> +<td>void</td> +<td>Resize focused floating window down.</td> +</tr> +<tr> +<td><a href="#resize_win_left">resize_win_left</a></td> +<td>(void)</td> +<td>void</td> +<td>Resize focused floating window left.</td> +</tr> +<tr> +<td><a href="#resize_win_right">resize_win_right</a></td> +<td>(void)</td> +<td>void</td> +<td>Resize focused floating window right.</td> +</tr> +<tr> +<td><a href="#resize_win_up">resize_win_up</a></td> +<td>(void)</td> +<td>void</td> +<td>Resize focused floating window up.</td> +</tr> +<tr> +<td><a href="#run">run</a></td> +<td>(void)</td> +<td>void</td> +<td>Main event loop.</td> +</tr> +<tr> +<td><a href="#reset_opacity">reset_opacity</a></td> +<td>(Window w)</td> +<td>void</td> +<td>Remove window opacity property.</td> +</tr> +<tr> +<td><a href="#scan_existing_windows">scan_existing_windows</a></td> +<td>(void)</td> +<td>void</td> +<td>Manage already viewable children on startup.</td> +</tr> +<tr> +<td><a href="#select_input">select_input</a></td> +<td>(Window w, Mask masks)</td> +<td>void</td> +<td>XSelectInput wrapper.</td> +</tr> +<tr> +<td><a href="#send_wm_take_focus">send_wm_take_focus</a></td> +<td>(Window w)</td> +<td>void</td> +<td>Send WM_TAKE_FOCUS if supported.</td> +</tr> +<tr> +<td><a href="#setup">setup</a></td> +<td>(void)</td> +<td>void</td> +<td>Init display, atoms, config, grabs, handlers.</td> +</tr> +<tr> +<td><a href="#setup_atoms">setup_atoms</a></td> +<td>(void)</td> +<td>void</td> +<td>Intern atoms and publish EWMH on root.</td> +</tr> +<tr> +<td><a href="#set_frame_extents">set_frame_extents</a></td> +<td>(Window w)</td> +<td>void</td> +<td>Publish border widths via _NET_FRAME_EXTENTS.</td> +</tr> +<tr> +<td><a href="#set_input_focus">set_input_focus</a></td> +<td>(Client *c, Bool raise, Bool warp)</td> +<td>void</td> +<td>Focus client and update EWMH active window.</td> +</tr> +<tr> +<td><a href="#set_opacity">set_opacity</a></td> +<td>(Window w, double op)</td> +<td>void</td> +<td>Write _NET_WM_WINDOW_OPACITY.</td> +</tr> +<tr> +<td><a href="#set_win_scratchpad">set_win_scratchpad</a></td> +<td>(int n)</td> +<td>void</td> +<td>Assign focused to scratchpad slot n.</td> +</tr> +<tr> +<td><a href="#set_wm_state">set_wm_state</a></td> +<td>(Window w, long state)</td> +<td>void</td> +<td>Write ICCCM WM_STATE.</td> +</tr> +<tr> +<td><a href="#snap_coordinate">snap_coordinate</a></td> +<td>(int pos, int size, int scr, int snap)</td> +<td>int</td> +<td>Snap coord to edges within distance.</td> +</tr> +<tr> +<td><a href="#spawn">spawn</a></td> +<td>(const char * const *argv)</td> +<td>void</td> +<td>Run pipeline argv split by "</td> +</tr> +<tr> +<td><a href="#startup_exec">startup_exec</a></td> +<td>(void)</td> +<td>void</td> +<td>Run autostart commands from config.</td> +</tr> +<tr> +<td><a href="#swallow_window">swallow_window</a></td> +<td>(Client *swallower, Client *swallowed)</td> +<td>void</td> +<td>Hide swallower and show child.</td> +</tr> +<tr> +<td><a href="#swap_clients">swap_clients</a></td> +<td>(Client *a, Client *b)</td> +<td>void</td> +<td>Swap two list nodes in current workspace.</td> +</tr> +<tr> +<td><a href="#switch_previous_workspace">switch_previous_workspace</a></td> +<td>(void)</td> +<td>void</td> +<td>Change to previous_workspace.</td> +</tr> +<tr> +<td><a href="#tile">tile</a></td> +<td>(void)</td> +<td>void</td> +<td>Tiling layout with gaps and per-monitor master.</td> +</tr> +<tr> +<td><a href="#toggle_floating">toggle_floating</a></td> +<td>(void)</td> +<td>void</td> +<td>Toggle focused floating state.</td> +</tr> +<tr> +<td><a href="#toggle_floating_global">toggle_floating_global</a></td> +<td>(void)</td> +<td>void</td> +<td>Toggle all clients floating on/off.</td> +</tr> +<tr> +<td><a href="#toggle_fullscreen">toggle_fullscreen</a></td> +<td>(void)</td> +<td>void</td> +<td>Toggle fullscreen on focused.</td> +</tr> +<tr> +<td><a href="#toggle_monocle">toggle_monocle</a></td> +<td>(void)</td> +<td>void</td> +<td>Toggle monocle layout.</td> +</tr> +<tr> +<td><a href="#toggle_scratchpad">toggle_scratchpad</a></td> +<td>(int n)</td> +<td>void</td> +<td>Map/unmap scratchpad n and focus.</td> +</tr> +<tr> +<td><a href="#unswallow_window">unswallow_window</a></td> +<td>(Client *c)</td> +<td>void</td> +<td>Restore swallower and unlink relation.</td> +</tr> +<tr> +<td><a href="#update_borders">update_borders</a></td> +<td>(void)</td> +<td>void</td> +<td>Paint borders and publish active window.</td> +</tr> +<tr> +<td><a href="#update_client_desktop_properties">update_client_desktop_properties</a></td> +<td>(void)</td> +<td>void</td> +<td>Write _NET_WM_DESKTOP for every client.</td> +</tr> +<tr> +<td><a href="#update_modifier_masks">update_modifier_masks</a></td> +<td>(void)</td> +<td>void</td> +<td>Detect NumLock and Mode_switch masks.</td> +</tr> +<tr> +<td><a href="#update_mons">update_mons</a></td> +<td>(void)</td> +<td>void</td> +<td>Query Xinerama and rebuild monitor array.</td> +</tr> +<tr> +<td><a href="#update_net_client_list">update_net_client_list</a></td> +<td>(void)</td> +<td>void</td> +<td>Publish client windows to _NET_CLIENT_LIST.</td> +</tr> +<tr> +<td><a href="#update_struts">update_struts</a></td> +<td>(void)</td> +<td>void</td> +<td>Read dock struts and reserve monitor edges.</td> +</tr> +<tr> +<td><a href="#update_workarea">update_workarea</a></td> +<td>(void)</td> +<td>void</td> +<td>Publish per-monitor workareas.</td> +</tr> +<tr> +<td><a href="#warp_cursor">warp_cursor</a></td> +<td>(Client *c)</td> +<td>void</td> +<td>Move pointer to window center on root.</td> +</tr> +<tr> +<td><a href="#window_has_ewmh_state">window_has_ewmh_state</a></td> +<td>(Window w, Atom state)</td> +<td>Bool</td> +<td>Test membership in _NET_WM_STATE.</td> +</tr> +<tr> +<td><a href="#window_set_ewmh_state">window_set_ewmh_state</a></td> +<td>(Window w, Atom state, Bool add)</td> +<td>void</td> +<td>Add/remove EWMH state atom.</td> +</tr> +<tr> +<td><a href="#window_should_float">window_should_float</a></td> +<td>(Window w)</td> +<td>Bool</td> +<td>Match should_float rules.</td> +</tr> +<tr> +<td><a href="#window_should_start_fullscreen">window_should_start_fullscreen</a></td> +<td>(Window w)</td> +<td>Bool</td> +<td>Match start_fullscreen rules.</td> +</tr> +<tr> +<td><a href="#xerr">xerr</a></td> +<td>(Display *d, XErrorEvent *ee)</td> +<td>int</td> +<td>Ignore benign X errors.</td> +</tr> +<tr> +<td><a href="#xev_case">xev_case</a></td> +<td>(XEvent *e)</td> +<td>void</td> +<td>Dispatch via evtable by type.</td> +</tr> +<tr> +<td><a href="#main">main</a></td> +<td>(int ac, char **av)</td> +<td>int</td> +<td>CLI: -v/--version; else start WM.</td> +</tr> +</tbody></table> +<hr> +<h3>Functions</h3> +<p>Below, each entry shows the compact signature and a detailed description. Use anchors in the table to jump here.</p> +<h4>add_client</h4> +<pre><code class="language-c">(Window w, int ws) -> Client * +</code></pre> +<blockquote> +<p>Returns NULL on allocation failure.</p> +</blockquote> +<p>Create and register a client in workspace ws. Select inputs, grab mouse<br>buttons, set protocols (WM_DELETE_WINDOW), capture initial geometry, set<br>monitor by cursor position, set _NET_WM_DESKTOP, and raise the window.<br>Sets global focus if it is the first client in the current workspace.</p> +<h4>apply_fullscreen</h4> +<pre><code class="language-c">(Client *c, Bool on) -> void +</code></pre> +<p>Enter: save geometry, clear floating, set fullscreen, remove borders,<br>resize to monitor bounds, raise, set EWMH state. Exit: restore geometry<br>and border, clear state, recompute monitor if tiled, then retile and<br>repaint borders.</p> +<h4>centre_window</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If the focused client exists, is mapped and floating, move it to the<br>center of its current monitor workarea and apply via XMoveWindow.</p> +<h4>change_workspace</h4> +<pre><code class="language-c">(int ws) -> void +</code></pre> +<p>Abort if ws is invalid or already current. Grab server. Remember which<br>scratchpads are visible and unmap them. Unmap all non-scratchpad windows<br>in the current workspace. Switch current_ws, remap windows in the target<br>workspace, move visible scratchpads into the new workspace, and map them.<br>Retile, choose focus (prefer visible scratchpad, else first window on the<br>current monitor), set input focus, update _NET_CURRENT_DESKTOP and<br>per-client _NET_WM_DESKTOP. Ungrab server and sync. Maintain<br>previous_workspace and in_ws_switch flags.</p> +<h4>check_parent</h4> +<pre><code class="language-c">(pid_t p, pid_t c) -> int +</code></pre> +<p>Walk the process tree via get_parent_process until p or 0 is reached.<br>Return c if p is an ancestor of c, else 0.</p> +<h4>clean_mask</h4> +<pre><code class="language-c">(int mask) -> int +</code></pre> +<p>Strip LockMask, NumLock, and Mode_switch bits so key matching is stable.</p> +<h4>close_focused</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If focused exists, clear scratchpad binding if any. If the client supports<br>WM_DELETE_WINDOW, send a ClientMessage. Otherwise unmap and kill the<br>client. Layout updates are handled by subsequent notifications.</p> +<h4>dec_gaps</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If user_config.gaps > 0, decrement and retile, then repaint borders.</p> +<h4>find_client</h4> +<pre><code class="language-c">(Window w) -> Client * +</code></pre> +<p>Linear search across all workspaces for a client with top-level window w.</p> +<h4>find_toplevel</h4> +<pre><code class="language-c">(Window w) -> Window +</code></pre> +<p>Walk up the X window tree via XQueryTree until the root parent is reached<br>and return that top-level window id.</p> +<h4>focus_next</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>From the current focus (or head), loop forward (wrap) to the next mapped<br>client on current_mon. If found, set focus and call set_input_focus.</p> +<h4>focus_prev</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>From the current focus (or head), walk backward (wrap) to the previous<br>mapped client on current_mon. If found, set focus and call set_input_focus.</p> +<h4>focus_next_mon</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If multiple monitors, focus the first mapped, non-fullscreen client on the<br>next monitor. If none exist, warp the pointer to the next monitor center.</p> +<h4>focus_prev_mon</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Same as focus_next_mon but targeting the previous monitor.</p> +<h4>get_monitor_for</h4> +<pre><code class="language-c">(Client *c) -> int +</code></pre> +<p>Compute the client center and return the monitor whose bounds contain it.<br>Fallback to 0 if none match.</p> +<h4>get_parent_process</h4> +<pre><code class="language-c">(pid_t c) -> pid_t +</code></pre> +<p>Read /proc/%u/stat and parse the parent PID for process c. Return 0 on<br>failure.</p> +<h4>get_pid</h4> +<pre><code class="language-c">(Window w) -> pid_t +</code></pre> +<p>Read _NET_WM_PID from the window as a 32-bit XA_CARDINAL and return it, or<br>0 if missing.</p> +<h4>get_workspace_for_window</h4> +<pre><code class="language-c">(Window w) -> int +</code></pre> +<p>Check XClassHint against user_config.open_in_workspace rules. If a class<br>or name matches, return that workspace id. Else return current_ws.</p> +<h4>grab_button</h4> +<pre><code class="language-c">(Mask button, Mask mod, Window w, Bool owner_events, Mask masks) -> void +</code></pre> +<p>Call XGrabButton with async mode on root and sync on non-root windows.</p> +<h4>grab_keys</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Ungrab all keys, then for each binding in user_config.binds, compute<br>keycode and grab with guard modifier combinations so bindings remain<br>usable with Lock, NumLock, or Mode_switch active.</p> +<h4>hdl_button</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>ButtonPress handler. On tiled windows:</p> +<ul> +<li>Mod+Shift+Left: begin swap drag (DRAG_SWAP).</li> +<li>Mod+Left or Mod+Right: toggle_floating to allow drag.</li> +<li>Plain Left: focus the clicked window.</li> +</ul> +<p>On floating windows, begin DRAG_MOVE (left) or DRAG_RESIZE (right),<br>recording drag origin and grabbing the pointer.</p> +<h4>hdl_button_release</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>If in DRAG_SWAP and a target is set, swap clients, retile, and repaint.<br>Always ungrab the pointer and clear drag state.</p> +<h4>hdl_client_msg</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>Handle _NET_CURRENT_DESKTOP by calling change_workspace. Handle<br>_NET_WM_STATE actions for _NET_WM_STATE_FULLSCREEN: add/remove/toggle via<br>apply_fullscreen and raise on entry.</p> +<h4>hdl_config_ntf</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>On root ConfigureNotify, refresh monitors, retile, and repaint borders.</p> +<h4>hdl_config_req</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>Honor ConfigureRequest for floating or fullscreen clients by forwarding<br>geometry. Ignore for tiled clients (layout is enforced by WM).</p> +<h4>hdl_dummy</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>No operation.</p> +<h4>hdl_destroy_ntf</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>Unlink the destroyed client. If it swallowed another, remap it. If it was<br>swallowed, remap the swallower. Pick a new focus on the same monitor if<br>possible. Update _NET_CLIENT_LIST, retile current workspace, repaint, and<br>refocus if applicable.</p> +<h4>hdl_keypress</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>Match keycode+mods (cleaned) against user_config.binds and dispatch:</p> +<ul> +<li>TYPE_CMD: spawn argv</li> +<li>TYPE_FUNC: call function</li> +<li>TYPE_WS_CHANGE / TYPE_WS_MOVE</li> +<li>TYPE_SP_REMOVE / TYPE_SP_TOGGLE / TYPE_SP_CREATE<br>Update _NET_CLIENT_LIST when workspace topology changes.</li> +</ul> +<h4>hdl_mapping_ntf</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>Refresh keyboard mapping, detect modifier masks, and regrab keys.</p> +<h4>hdl_map_req</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>Ignore invisible or override-redirect windows. If already managed and on<br>current workspace, ensure mapped and optionally focus. Otherwise:<br>classify window type, decide floating or tiled (consider utility/dialog,<br>modal, size hints, transient), enforce max clients, choose target<br>workspace via rules, call add_client, set WM_STATE, center floating, set<br>borders, attempt swallowing (class rules + parent PID), honor requested<br>fullscreen, map if on current workspace, and update borders/focus.</p> +<h4>hdl_motion</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>Throttle by motion_throttle. Identify monitor under pointer. For DRAG_SWAP<br>track hovered tiled target and show swap border. For DRAG_MOVE compute new<br>position, apply snapping inside monitor workarea, auto-toggle to floating<br>if moved far enough, and move window. For DRAG_RESIZE grow from bottom<br>right and clamp to monitor workarea.</p> +<h4>hdl_property_ntf</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>On root:</p> +<ul> +<li>_NET_CURRENT_DESKTOP: read and change_workspace.</li> +<li>_NET_WM_STRUT_PARTIAL: update_struts, retile, repaint.</li> +</ul> +<p>On client:</p> +<ul> +<li>_NET_WM_STATE: mirror fullscreen flag using apply_fullscreen.</li> +</ul> +<h4>hdl_unmap_ntf</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>If not switching workspaces, mark the client as unmapped. Update client<br>list, retile, and repaint.</p> +<h4>inc_gaps</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Increment gaps and retile, then repaint borders.</p> +<h4>init_defaults</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Fill default_config (modkey, gaps, border colors via parse_col, movement<br>steps, per-monitor master widths, rule arrays, throttles, snap distance,<br>and flags). Copy to user_config.</p> +<h4>is_child_proc</h4> +<pre><code class="language-c">(pid_t parent_pid, pid_t child_pid) -> Bool +</code></pre> +<p>Walk PPID chain up to a limit using /proc. Return True if parent_pid is<br>found. Print simple diagnostics on failures.</p> +<h4>move_master_next</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Rotate the head node to the tail of the current workspace list. Retile,<br>optionally warp to the old focused window, send WM_TAKE_FOCUS, repaint.</p> +<h4>move_master_prev</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Move the tail node to head (becomes new master). Retile, optional warp,<br>send focus, repaint.</p> +<h4>move_next_mon</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If focused and multiple monitors, reassign focused to next monitor. If<br>floating, center and clamp inside the target monitor. Retile and optionally<br>warp cursor. Repaint.</p> +<h4>move_prev_mon</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Same as move_next_mon but previous monitor.</p> +<h4>move_to_workspace</h4> +<pre><code class="language-c">(int ws) -> void +</code></pre> +<p>Unmap focused, unlink from current list, push to target workspace head,<br>update _NET_WM_DESKTOP, retile current workspace, and refocus its head.</p> +<h4>move_win_down</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>For a focused floating client, move by move_window_amt down via XMoveWindow.</p> +<h4>move_win_left</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>For a focused floating client, move left by move_window_amt.</p> +<h4>move_win_right</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>For a focused floating client, move right by move_window_amt.</p> +<h4>move_win_up</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>For a focused floating client, move up by move_window_amt.</p> +<h4>other_wm</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Temporarily set error handler to other_wm_err, attempt to select<br>SubstructureRedirectMask on root to detect another WM, then restore.</p> +<h4>other_wm_err</h4> +<pre><code class="language-c">(Display *d, XErrorEvent *ee) -> int +</code></pre> +<blockquote> +<p>Always exits with failure.</p> +</blockquote> +<p>Print a message and exit because another WM has the redirect. Returns 0<br>but does not reach caller.</p> +<h4>parse_col</h4> +<pre><code class="language-c">(const char *hex) -> long +</code></pre> +<p>Parse and allocate an XColor from a hex string. On failure, return the<br>default white pixel. OR 0xff into the high byte to set an alpha-like<br>component and return the pixel.</p> +<h4>quit</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Close display and free cursors. Print a message and clear running flag.<br>Optional mass-kill code is commented out.</p> +<h4>reload_config</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Free binding commands and rule arrays, wipe user_config, re-init defaults,<br>re-parse config (fallback to defaults on error), regrab keys and buttons<br>on root and clients, rebuild root grabs, update desktop props and client<br>list, sync, retile, and repaint.</p> +<h4>remove_scratchpad</h4> +<pre><code class="language-c">(int n) -> void +</code></pre> +<p>If scratchpad slot n holds a client, remap it and clear the slot. Update<br>client list and borders.</p> +<h4>resize_master_add</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Increase user_config.master_width for the focused monitor by<br>resize_master_amt (bounded). Retile and repaint.</p> +<h4>resize_master_sub</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Decrease user_config.master_width for the focused monitor by<br>resize_master_amt (bounded). Retile and repaint.</p> +<h4>resize_stack_add</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If focused is a stack client (tiled and not master), increase its<br>custom_stack_height by resize_stack_amt and retile.</p> +<h4>resize_stack_sub</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If focused is a stack client, decrease custom_stack_height (bounded to a<br>minimum) and retile.</p> +<h4>resize_win_down</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If focused is floating, grow height by resize_window_amt, clamp to monitor<br>workarea, and apply via XResizeWindow.</p> +<h4>resize_win_left</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If focused is floating, shrink width by resize_window_amt (bounded), and<br>apply.</p> +<h4>resize_win_right</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If focused is floating, grow width by resize_window_amt (bounded), and<br>apply.</p> +<h4>resize_win_up</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>If focused is floating, shrink height by resize_window_amt (bounded), and<br>apply.</p> +<h4>run</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Set running flag and loop on XNextEvent, dispatching through xev_case<br>until running is cleared.</p> +<h4>reset_opacity</h4> +<pre><code class="language-c">(Window w) -> void +</code></pre> +<p>Delete _NET_WM_WINDOW_OPACITY property to restore default compositor<br>opacity.</p> +<h4>scan_existing_windows</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Query root children. For each viewable, non-override-redirect child,<br>synthesize a MapRequest and feed it to hdl_map_req so sxwm begins<br>managing existing windows on startup.</p> +<h4>select_input</h4> +<pre><code class="language-c">(Window w, Mask masks) -> void +</code></pre> +<p>Wrapper for XSelectInput.</p> +<h4>send_wm_take_focus</h4> +<pre><code class="language-c">(Window w) -> void +</code></pre> +<p>If the window supports WM_TAKE_FOCUS, send the ClientMessage so clients<br>that require it can accept focus.</p> +<h4>setup</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Open display, set root, setup_atoms, probe for other WM, load defaults and<br>parse config, compute modifier masks, grab keys, run autostart, load and<br>set cursors, cache screen size, update monitors, select root events,<br>grab root mouse buttons, initialize event table, scan existing windows,<br>and ignore SIGCHLD to prevent zombies.</p> +<h4>setup_atoms</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Intern all required EWMH/ICCCM atoms, create _NET_SUPPORTING_WM_CHECK,<br>publish number of desktops, names, current desktop, supported atom list<br>on root, and compute initial workarea.</p> +<h4>set_frame_extents</h4> +<pre><code class="language-c">(Window w) -> void +</code></pre> +<p>Write border width on all four sides to _NET_FRAME_EXTENTS.</p> +<h4>set_input_focus</h4> +<pre><code class="language-c">(Client *c, Bool raise_win, Bool warp) -> void +</code></pre> +<p>If c is mapped: set global focus, call XSetInputFocus on toplevel, send<br>WM_TAKE_FOCUS, optionally raise if floating, publish _NET_ACTIVE_WINDOW,<br>repaint borders, and optionally warp pointer. If c is NULL: focus root<br>and clear _NET_ACTIVE_WINDOW. Flush.</p> +<h4>set_opacity</h4> +<pre><code class="language-c">(Window w, double opacity) -> void +</code></pre> +<p>Clamp opacity to [0.0, 1.0], convert to 32-bit fixed point, and write<br>_NET_WM_WINDOW_OPACITY.</p> +<h4>set_win_scratchpad</h4> +<pre><code class="language-c">(int n) -> void +</code></pre> +<p>Assign focused window to scratchpad slot n by storing and unmapping it.<br>If a different client was already in the slot, remap it and clear the<br>slot first.</p> +<h4>set_wm_state</h4> +<pre><code class="language-c">(Window w, long state) -> void +</code></pre> +<p>Write ICCCM WM_STATE with state and None icon window.</p> +<h4>snap_coordinate</h4> +<pre><code class="language-c">(int pos, int size, int screen_size, int snap_dist) -> int +</code></pre> +<p>Snap left edge to 0 or right edge to screen_size when within snap_dist,<br>otherwise return pos unchanged.</p> +<h4>spawn</h4> +<pre><code class="language-c">(const char * const *argv) -> void +</code></pre> +<p>Split argv by "|" into N commands, create N-1 pipes, fork N children,<br>wire stdin/stdout with dup2, execvp each stage, close fds in parent, and<br>free temporary allocations. Close the X connection fd in children.</p> +<h4>startup_exec</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>For each non-NULL user_config.to_run[i], build argv, call spawn, and free<br>argv pieces.</p> +<h4>swallow_window</h4> +<pre><code class="language-c">(Client *swallower, Client *swallowed) -> void +</code></pre> +<p>If eligible and not already linked: unmap swallower, link both ways, copy<br>geometry/floating state, move/resize swallowed if floating, retile and<br>repaint.</p> +<h4>swap_clients</h4> +<pre><code class="language-c">(Client *a, Client *b) -> void +</code></pre> +<p>Swap two nodes in the singly-linked list of the current workspace,<br>handling the adjacent case and the general case.</p> +<h4>switch_previous_workspace</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Call change_workspace(previous_workspace).</p> +<h4>tile</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Recompute struts, then for each monitor: build list of visible, non-<br>floating, non-fullscreen clients on that monitor. If monocle layout enabled, configure<br>every window to take all the space then leave. Otherwise, places master at left<br>with width master_width[m], stack on right with gaps. Compute stack<br>heights using per-client custom_stack_height or auto-split; enforce<br>minimums and absorb rounding remainder at bottom. Configure windows,<br>optionally raise floating windows, and repaint borders. Skip layout if a<br>single fullscreen client exists.</p> +<h4>toggle_floating</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Toggle focused floating state. If leaving fullscreen, clear it and restore<br>borders. When entering floating, capture current server-side geometry.<br>When leaving floating, recompute monitor. Retile, repaint, and if floating,<br>raise and refocus.</p> +<h4>toggle_floating_global</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Flip global_floating. If any tiled exists, set all to floating (storing<br>current geometry) and raise them; otherwise leave state. Retile and repaint.</p> +<h4>toggle_fullscreen</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Toggle fullscreen on focused via apply_fullscreen.</p> +<h4>toggle_monocle</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Enable/disable the monocle layout. Most of the logic is near the top of <a href="#tile">tile</a></p> +<h4>toggle_scratchpad</h4> +<pre><code class="language-c">(int n) -> void +</code></pre> +<p>Move scratchpad n into current workspace if needed. Update _NET_WM_DESKTOP,<br>set its monitor to the focused monitor, and map or unmap. On mapping,<br>focus it. Retile, repaint, and update client list.</p> +<h4>unswallow_window</h4> +<pre><code class="language-c">(Client *c) -> void +</code></pre> +<p>If c has a swallower, unlink the relation, remap the swallower, focus it,<br>then retile and repaint.</p> +<h4>update_borders</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Set border pixel for each client on the current workspace to focused or<br>unfocused color. Publish _NET_ACTIVE_WINDOW with focused id if any.</p> +<h4>update_client_desktop_properties</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>For every client in every workspace, write its _NET_WM_DESKTOP value.</p> +<h4>update_modifier_masks</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Read X modifier mapping; detect which modifier bit holds Num_Lock and<br>Mode_switch keycodes. Update numlock_mask and mode_switch_mask.</p> +<h4>update_mons</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Free old monitor array, query Xinerama for screens if active, else fall<br>back to a single monitor covering the display. Define cursor for each<br>screen root.</p> +<h4>update_net_client_list</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Flatten all client windows and write _NET_CLIENT_LIST on root.</p> +<h4>update_struts</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Reset reserves on monitors. For each DOCK window, read<br>_NET_WM_STRUT_PARTIAL and expand per-monitor reserves based on the dock<br>location. Update workarea afterward.</p> +<h4>update_workarea</h4> +<pre><code class="language-c">(void) -> void +</code></pre> +<p>Publish per-monitor workareas (x, y, w, h) to _NET_WORKAREA.</p> +<h4>warp_cursor</h4> +<pre><code class="language-c">(Client *c) -> void +</code></pre> +<p>Move pointer to the window center on root and sync.</p> +<h4>window_has_ewmh_state</h4> +<pre><code class="language-c">(Window w, Atom state) -> Bool +</code></pre> +<p>Read _NET_WM_STATE and test for membership of state.</p> +<h4>window_set_ewmh_state</h4> +<pre><code class="language-c">(Window w, Atom state, Bool add) -> void +</code></pre> +<p>Read existing _NET_WM_STATE, rebuild the list without state, and append<br>state if add is True. Write the result or delete the property if empty.</p> +<h4>window_should_float</h4> +<pre><code class="language-c">(Window w) -> Bool +</code></pre> +<p>Check XClassHint and match name/class against user_config.should_float.</p> +<h4>window_should_start_fullscreen</h4> +<pre><code class="language-c">(Window w) -> Bool +</code></pre> +<p>Check XClassHint and match name/class against user_config.start_fullscreen.</p> +<h4>xerr</h4> +<pre><code class="language-c">(Display *d, XErrorEvent *ee) -> int +</code></pre> +<p>Ignore common benign X errors (BadWindow, BadDrawable, BadMatch) and<br>return 0.</p> +<h4>xev_case</h4> +<pre><code class="language-c">(XEvent *xev) -> void +</code></pre> +<p>If type is in range, dispatch to evtable[type]. Otherwise print an error.</p> +<h4>main</h4> +<pre><code class="language-c">(int ac, char **av) -> int +</code></pre> +<blockquote> +<p>EXIT_SUCCESS</p> +</blockquote> +<p>If <code>-v</code> or <code>--version</code>, print version, author, and license info. Otherwise<br>call setup(), print "sxwm: starting...", then run() and return success.</p> +<hr> |
