summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Bergeron <[email protected]>2025-05-17 09:07:28 -0400
committerB. Bergeron <[email protected]>2025-05-17 09:07:28 -0400
commit32723114e2ddcf4ac6d647635b38a572c2459271 (patch)
tree6cde6e4e2e3d2a2afa80c4b5298895631804d0e5
parent11bfcf4291bb0b72fd94b8bb69b7fabd3c3fea35 (diff)
Add documentation (list in commit description)HEADmaster
Functions: - add_client - update_struts - main - setup - close_focused - change_workspace - and some variables
-rw-r--r--src/sxwm.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/sxwm.c b/src/sxwm.c
index dd779df..306d8c0 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -102,13 +102,16 @@ Atom atom_net_wm_name;
Atom atom_utf8_string;
Cursor c_normal, c_move, c_resize;
+/* List of client for each workspace (linked list) */
Client *workspaces[NUM_WORKSPACES] = {NULL};
Config default_config;
Config user_config;
+/* The current workspace */
int current_ws = 0;
DragMode drag_mode = DRAG_NONE;
Client *drag_client = NULL;
Client *swap_target = NULL;
+/* The currently focused client */
Client *focused = NULL;
EventHandler evtable[LASTEvent];
Display *dpy;
@@ -119,7 +122,9 @@ int monsn = 0;
Bool global_floating = False;
long last_motion_time = 0;
+/* The full X11 screen width */
int scr_width;
+/* The full X11 screen height */
int scr_height;
int open_windows = 0;
int drag_start_x, drag_start_y;
@@ -130,18 +135,28 @@ int reserve_right = 0;
int reserve_top = 0;
int reserve_bottom = 0;
+/**
+ * Create a client, add it to a workspace, focus it under certain conditions,
+ * and link the window object to the client object.
+ *
+ * w - An X11 window object
+ * ws - The workspace in which to add the client
+ */
Client *add_client(Window w, int ws)
{
+ // Allocate a new client
Client *c = malloc(sizeof(Client));
if (!c) {
fprintf(stderr, "sxwm: could not alloc memory for client\n");
return NULL;
}
+ // Attribute some misc. values
c->win = w;
c->next = NULL;
c->ws = ws;
+ // Add client to current workspace (linked list)
if (!workspaces[ws]) {
workspaces[ws] = c;
}
@@ -152,17 +167,30 @@ Client *add_client(Window w, int ws)
tail->next = c;
}
+ // Focus on the new client if it's being added to the focused workspace and
+ // no other client is currently focused
if (ws == current_ws && !focused) {
focused = c;
}
open_windows++;
+
+ // Ask X11 to report these input even for window `w`:
+ // - EnterWindowMask Pointer enters windows
+ // - LeaveWindowMask Pointer leaves windows
+ // - FocusChangeMask Focus changes (???)
+ // - PropertyChangeMask Window properties change
+ // - StructureNotifyMask Window structure change
XSelectInput(dpy, w,
EnterWindowMask | LeaveWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask);
+ // Tell X11 that the window `w` is willing to participate in the
+ // "WM_DELETE_WINDOW" protocol. (In other words, this re-defined the
+ // window's WM_PROTOCOLS property)
Atom protos[] = {atom_wm_delete};
XSetWMProtocols(dpy, w, protos, 1);
+ // Copy the window's geometry value into the client struct
XWindowAttributes wa;
XGetWindowAttributes(dpy, w, &wa);
c->x = wa.x;
@@ -170,10 +198,20 @@ Client *add_client(Window w, int ws)
c->w = wa.width;
c->h = wa.height;
+ // If a client is focused, put the new client under the focused client's
+ // monitor...
+ //
+ // REVIEW: I think it would be best to put it inside the monitor occupied by
+ // the pointer.
if (focused) {
c->mon = focused->mon;
}
else {
+ // ...Otherwise, put it in the monitor in which the center of the client
+ // is currently in (Fallback: first monitor).
+ //
+ // cx = client h center, cy = client v center
+
/* need better way to determine mon */
int cx = c->x + c->w / 2, cy = c->y + c->h / 2;
c->mon = 0;
@@ -185,41 +223,58 @@ Client *add_client(Window w, int ws)
}
}
+ // Set default display value for client
c->fixed = False;
c->floating = False;
c->fullscreen = False;
+ // Follow globa_floating rule
if (global_floating) {
c->floating = True;
}
+ // Bring window to the front. Usefull only if the client was spawned in
+ // floating mode
XRaiseWindow(dpy, w);
return c;
}
+/**
+ * Change the current workspace.
+ *
+ * ws - the new workspace index
+ */
void change_workspace(int ws)
{
+ // Do nothing if the workspace doesn't exist or is already in view
if (ws >= NUM_WORKSPACES || ws == current_ws) {
return;
}
XGrabServer(dpy);
+ // Hide current workspace's windows
for (Client *c = workspaces[current_ws]; c; c = c->next) {
XUnmapWindow(dpy, c->win);
}
+ // Change the current workspace
current_ws = ws;
+ // Display the windows of the new workspace
for (Client *c = workspaces[current_ws]; c; c = c->next) {
XMapWindow(dpy, c->win);
}
+ // Probably tile windows back into workspace?
tile();
+
+ // If the new workspace is not empty, focus on its first window.
if (workspaces[current_ws]) {
focused = workspaces[current_ws];
XSetInputFocus(dpy, focused->win, RevertToPointerRoot, CurrentTime);
}
+ // Change the root window's _NET_CURRENT_DESKTOP property to the new one
long cd = current_ws;
XChangeProperty(dpy, root, XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False), XA_CARDINAL, 32, PropModeReplace,
(unsigned char *)&cd, 1);
@@ -232,8 +287,12 @@ int clean_mask(int mask)
return mask & ~(LockMask | Mod2Mask | Mod3Mask);
}
+/**
+ * Close the currently focused window
+ */
void close_focused(void)
{
+ // Do nothing if no window is focused
if (!focused) {
return;
}
@@ -859,10 +918,16 @@ void hdl_root_property(XEvent *xev)
}
}
+/**
+ * Update reserve_left, reserve_right, reserve_top, and reserve_bottom to
+ * encompase every (visible?) windows, excluding docks.
+ */
void update_struts(void)
{
+ // Reset the "reserve" values
reserve_left = reserve_right = reserve_top = reserve_bottom = 0;
+ // Get a list of every window and the window count
Window root_ret, parent_ret, *children;
unsigned int nchildren;
if (!XQueryTree(dpy, root, &root_ret, &parent_ret, &children, &nchildren))
@@ -881,6 +946,7 @@ void update_struts(void)
!types)
continue;
+ // Skip this window if it's a dock
Bool is_dock = False;
for (unsigned long j = 0; j < nitems; j++) {
if (types[j] == atom_net_wm_window_type_dock) {
@@ -892,6 +958,8 @@ void update_struts(void)
if (!is_dock)
continue;
+ // Using each window's _NET_WM_STRUT_PARTIAL (or _NET_WM_STRUT), update
+ // the reserve_ variables to encompase every (visible?) window
long *str = NULL;
Atom actual;
int sfmt;
@@ -1179,9 +1247,12 @@ void send_wm_take_focus(Window w)
void setup(void)
{
+ // Connect to X11
if ((dpy = XOpenDisplay(NULL)) == 0) {
errx(0, "can't open display. quitting...");
}
+
+ // Get the root window
root = XDefaultRootWindow(dpy);
setup_atoms();
@@ -1681,6 +1752,7 @@ void xev_case(XEvent *xev)
int main(int ac, char **av)
{
+ // Handle argument. Only -v/--version is supported.
if (ac > 1) {
if (strcmp(av[1], "-v") == 0 || strcmp(av[1], "--version") == 0) {
printf("%s\n%s\n%s", SXWM_VERSION, SXWM_AUTHOR, SXWM_LICINFO);