mirror of
				https://codeberg.org/dwl/dwl-patches.git
				synced 2025-10-31 20:14:33 +00:00 
			
		
		
		
	 9c5d5d85f3
			
		
	
	
		9c5d5d85f3
		
			
		
	
	
	
	
		
			
			Eliminated wiki. Individual patches have a README.md explanation in their own subdirectory. Simplified submission of new patches and maintenance of existing patches. Instructions page (README.md autodisplayed) is now at https://codeberg.org/dwl/dwl-patches/
		
			
				
	
	
		
			619 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			619 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 24c197ea93388c222b72c2192b968aa80b444a9a Mon Sep 17 00:00:00 2001
 | |
| From: Micah N Gorrell <m@minego.net>
 | |
| Date: Wed, 27 Mar 2024 12:32:49 -0600
 | |
| Subject: [PATCH] varcol layout
 | |
| 
 | |
| ---
 | |
|  config.def.h |  25 ++-
 | |
|  dwl.c        |  29 ++++
 | |
|  varcol.c     | 429 +++++++++++++++++++++++++++++++++++++++++++++++++++
 | |
|  3 files changed, 480 insertions(+), 3 deletions(-)
 | |
|  create mode 100644 varcol.c
 | |
| 
 | |
| diff --git a/config.def.h b/config.def.h
 | |
| index 9009517..9345ff2 100644
 | |
| --- a/config.def.h
 | |
| +++ b/config.def.h
 | |
| @@ -21,16 +21,18 @@ static const float fullscreen_bg[]         = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
 | |
|  static int log_level = WLR_ERROR;
 | |
|  
 | |
|  static const Rule rules[] = {
 | |
| -	/* app_id     title       tags mask     isfloating   monitor */
 | |
| +	/* app_id     title       tags mask     isfloating   monitor  isLeft */
 | |
|  	/* examples:
 | |
| -	{ "Gimp",     NULL,       0,            1,           -1 },
 | |
| +	{ "Gimp",     NULL,       0,            1,           -1,      0 },
 | |
| +	{ "slack",    NULL,       0,            1,           -1,      1 },
 | |
|  	*/
 | |
| -	{ "firefox",  NULL,       1 << 8,       0,           -1 },
 | |
| +	{ "firefox",  NULL,       1 << 8,       0,           -1,      0 },
 | |
|  };
 | |
|  
 | |
|  /* layout(s) */
 | |
|  static const Layout layouts[] = {
 | |
|  	/* symbol     arrange function */
 | |
| +	{ "=O=",      varcol },  /* first entry is default */
 | |
|  	{ "[]=",      tile },
 | |
|  	{ "><>",      NULL },    /* no layout function means floating behavior */
 | |
|  	{ "[M]",      monocle },
 | |
| @@ -152,8 +154,25 @@ static const Key keys[] = {
 | |
|  	TAGKEYS(          XKB_KEY_7, XKB_KEY_ampersand,                  6),
 | |
|  	TAGKEYS(          XKB_KEY_8, XKB_KEY_asterisk,                   7),
 | |
|  	TAGKEYS(          XKB_KEY_9, XKB_KEY_parenleft,                  8),
 | |
| +
 | |
|  	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q,          quit,           {0} },
 | |
|  
 | |
| +	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Tab,        pushleft,       {0}},
 | |
| +	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_ISO_Left_Tab,pushleft,      {0}},
 | |
| + 
 | |
| +	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_I,          incncols,       {.i = +1 }},
 | |
| +	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_D,          incncols,       {.i = -1 }},
 | |
| +	{ MODKEY,                    XKB_KEY_h,          setcolfact,     {.f = -0.05 }},
 | |
| +	{ MODKEY,                    XKB_KEY_l,          setcolfact,     {.f = +0.05 }},
 | |
| +
 | |
| +	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Tab,        pushleft,       {0}},
 | |
| +	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_ISO_Left_Tab,pushleft,      {0}},
 | |
| +
 | |
| +	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_I,          incncols,       {.i = +1}},
 | |
| +	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_D,          incncols,       {.i = -1 }},
 | |
| +	{ MODKEY,                    XKB_KEY_h,          setcolfact,     {.f = -0.05 }},
 | |
| +	{ MODKEY,                    XKB_KEY_l,          setcolfact,     {.f = +0.05 }},
 | |
| +
 | |
|  	/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
 | |
|  	{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
 | |
|  	/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
 | |
| diff --git a/dwl.c b/dwl.c
 | |
| index 5867b0c..35343e7 100644
 | |
| --- a/dwl.c
 | |
| +++ b/dwl.c
 | |
| @@ -139,6 +139,8 @@ typedef struct {
 | |
|  	uint32_t tags;
 | |
|  	int isfloating, isurgent, isfullscreen;
 | |
|  	uint32_t resize; /* configure serial of a pending resize */
 | |
| +	int isLeft;
 | |
| +	float cfact;
 | |
|  } Client;
 | |
|  
 | |
|  typedef struct {
 | |
| @@ -205,6 +207,18 @@ struct Monitor {
 | |
|  	int gamma_lut_changed;
 | |
|  	int nmaster;
 | |
|  	char ltsymbol[16];
 | |
| +	float colfact[3];     /* Relative sizes of the different column types */
 | |
| +	int nmastercols;      /* The number of master columns to use */
 | |
| +	int nrightcols;       /* The number of right "stack" columns to use */
 | |
| +
 | |
| +	/*
 | |
| +		NOTE: This patch does not set these values, but leaves these here as a
 | |
| +		placeholder to make it easier to merge with patches that do set gaps.
 | |
| +	*/
 | |
| +	int gappih;           /* horizontal gap between windows */
 | |
| +	int gappiv;           /* vertical gap between windows */
 | |
| +	int gappoh;           /* horizontal outer gaps */
 | |
| +	int gappov;           /* vertical outer gaps */
 | |
|  };
 | |
|  
 | |
|  typedef struct {
 | |
| @@ -228,6 +242,7 @@ typedef struct {
 | |
|  	uint32_t tags;
 | |
|  	int isfloating;
 | |
|  	int monitor;
 | |
| +	int isLeft;
 | |
|  } Rule;
 | |
|  
 | |
|  typedef struct {
 | |
| @@ -284,6 +299,7 @@ static void focusstack(const Arg *arg);
 | |
|  static Client *focustop(Monitor *m);
 | |
|  static void fullscreennotify(struct wl_listener *listener, void *data);
 | |
|  static void handlesig(int signo);
 | |
| +static void incncols(const Arg *arg);
 | |
|  static void incnmaster(const Arg *arg);
 | |
|  static void inputdevice(struct wl_listener *listener, void *data);
 | |
|  static int keybinding(uint32_t mods, xkb_keysym_t sym);
 | |
| @@ -307,6 +323,7 @@ static void outputmgrtest(struct wl_listener *listener, void *data);
 | |
|  static void pointerfocus(Client *c, struct wlr_surface *surface,
 | |
|  		double sx, double sy, uint32_t time);
 | |
|  static void printstatus(void);
 | |
| +static void pushleft(const Arg *arg);
 | |
|  static void quit(const Arg *arg);
 | |
|  static void rendermon(struct wl_listener *listener, void *data);
 | |
|  static void requestdecorationmode(struct wl_listener *listener, void *data);
 | |
| @@ -314,6 +331,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data);
 | |
|  static void requestmonstate(struct wl_listener *listener, void *data);
 | |
|  static void resize(Client *c, struct wlr_box geo, int interact);
 | |
|  static void run(char *startup_cmd);
 | |
| +static void setcolfact(const Arg *arg);
 | |
|  static void setcursor(struct wl_listener *listener, void *data);
 | |
|  static void setcursorshape(struct wl_listener *listener, void *data);
 | |
|  static void setfloating(Client *c, int floating);
 | |
| @@ -340,6 +358,7 @@ static void unmapnotify(struct wl_listener *listener, void *data);
 | |
|  static void updatemons(struct wl_listener *listener, void *data);
 | |
|  static void updatetitle(struct wl_listener *listener, void *data);
 | |
|  static void urgent(struct wl_listener *listener, void *data);
 | |
| +static void varcol(Monitor *m);
 | |
|  static void view(const Arg *arg);
 | |
|  static void virtualkeyboard(struct wl_listener *listener, void *data);
 | |
|  static void virtualpointer(struct wl_listener *listener, void *data);
 | |
| @@ -351,6 +370,7 @@ static void zoom(const Arg *arg);
 | |
|  /* variables */
 | |
|  static const char broken[] = "broken";
 | |
|  static pid_t child_pid = -1;
 | |
| +static const float colfact[3] = { 0.1f, 0.6f, 0.3f }; /* The relative factors for the size of each column */
 | |
|  static int locked;
 | |
|  static void *exclusive_focus;
 | |
|  static struct wl_display *dpy;
 | |
| @@ -457,12 +477,16 @@ applyrules(Client *c)
 | |
|  		appid = broken;
 | |
|  	if (!(title = client_get_title(c)))
 | |
|  		title = broken;
 | |
| +	c->isLeft = 0;
 | |
|  
 | |
|  	for (r = rules; r < END(rules); r++) {
 | |
|  		if ((!r->title || strstr(title, r->title))
 | |
|  				&& (!r->id || strstr(appid, r->id))) {
 | |
|  			c->isfloating = r->isfloating;
 | |
|  			newtags |= r->tags;
 | |
| +			if (r->isLeft >= 0) {
 | |
| +				c->isLeft = r->isLeft;
 | |
| +			}
 | |
|  			i = 0;
 | |
|  			wl_list_for_each(m, &mons, link) {
 | |
|  				if (r->monitor == i++)
 | |
| @@ -882,6 +906,9 @@ createmon(struct wl_listener *listener, void *data)
 | |
|  	wlr_output_state_init(&state);
 | |
|  	/* Initialize monitor state using configured rules */
 | |
|  	m->tagset[0] = m->tagset[1] = 1;
 | |
| +	m->colfact[0] = colfact[0];
 | |
| +	m->colfact[1] = colfact[1];
 | |
| +	m->colfact[2] = colfact[2];
 | |
|  	for (r = monrules; r < END(monrules); r++) {
 | |
|  		if (!r->name || strstr(wlr_output->name, r->name)) {
 | |
|  			m->m.x = r->x;
 | |
| @@ -2929,6 +2956,8 @@ zoom(const Arg *arg)
 | |
|  	arrange(selmon);
 | |
|  }
 | |
|  
 | |
| +#include "varcol.c"
 | |
| +
 | |
|  #ifdef XWAYLAND
 | |
|  void
 | |
|  activatex11(struct wl_listener *listener, void *data)
 | |
| diff --git a/varcol.c b/varcol.c
 | |
| new file mode 100644
 | |
| index 0000000..30fdb85
 | |
| --- /dev/null
 | |
| +++ b/varcol.c
 | |
| @@ -0,0 +1,429 @@
 | |
| +#include <math.h>
 | |
| +
 | |
| +static inline void
 | |
| +client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min)
 | |
| +{
 | |
| +	struct wlr_xdg_toplevel *toplevel;
 | |
| +	struct wlr_xdg_toplevel_state *state;
 | |
| +#ifdef XWAYLAND
 | |
| +	if (client_is_x11(c)) {
 | |
| +		xcb_size_hints_t *size_hints = c->surface.xwayland->size_hints;
 | |
| +		if (size_hints) {
 | |
| +			max->width = size_hints->max_width;
 | |
| +			max->height = size_hints->max_height;
 | |
| +			min->width = size_hints->min_width;
 | |
| +			min->height = size_hints->min_height;
 | |
| +		}
 | |
| +		return;
 | |
| +	}
 | |
| +#endif
 | |
| +	toplevel = c->surface.xdg->toplevel;
 | |
| +	state = &toplevel->current;
 | |
| +	max->width = state->max_width;
 | |
| +	max->height = state->max_height;
 | |
| +	min->width = state->min_width;
 | |
| +	min->height = state->min_height;
 | |
| +}
 | |
| +
 | |
| +static int isleft(Client *c);
 | |
| +
 | |
| +/*
 | |
| +	Variable Column Layout
 | |
| +
 | |
| +	- Special 'left' column, with helper to move clients in or out of the left
 | |
| +	column. This is useful for things like chat, or status monitor windows that
 | |
| +	you want to keep visible.
 | |
| +
 | |
| +	- Variable number of master columns
 | |
| +	- Variable number of right columns
 | |
| +	- Variable number of master windows
 | |
| +
 | |
| +	// TODO Calculate remainders
 | |
| +*/
 | |
| +
 | |
| +/*
 | |
| +	Move a client within a column
 | |
| +
 | |
| +	w		The width of the column
 | |
| +	x		The left position of the column
 | |
| +	offset	The offset of this client within the column
 | |
| +	count	The number of clients in the column
 | |
| +*/
 | |
| +static void placeClientInColumn(Monitor *m, Client *c, int w, int x, int offset, int count, int totaln)
 | |
| +{
 | |
| +	struct wlr_box geom = {0};
 | |
| +	int monheight = m->w.height;
 | |
| +
 | |
| +	if (totaln > 1) {
 | |
| +		/* The total available space does not include the outer vertical gapps */
 | |
| +		monheight -= (2 * m->gappov);
 | |
| +
 | |
| +		/*
 | |
| +			Each client removes the inner vertical gapp from its own height,
 | |
| +			but that leaves us off by one so account for that here.
 | |
| +		*/
 | |
| +		monheight += m->gappiv;
 | |
| +	}
 | |
| +
 | |
| +	geom.width = w;
 | |
| +	geom.height = (int) floor(monheight / count);
 | |
| +
 | |
| +	geom.x = x;
 | |
| +	geom.y = m->w.y + (offset * geom.height);
 | |
| +
 | |
| +	/* Adjust the height to account for gapps AFTER adjusting the y position */
 | |
| +	if (totaln > 1) {
 | |
| +		geom.height -= m->gappiv;
 | |
| +	}
 | |
| +
 | |
| +	resize(c, geom, 0);
 | |
| +}
 | |
| +
 | |
| +/*
 | |
| +	variable column layout
 | |
| +
 | |
| +	This layout has a variable number of columns, in 3 categories.
 | |
| +		0-1 small left columns, containing clients that have been "pushed" left
 | |
| +		1-n master columns
 | |
| +		0-n right columns
 | |
| +*/
 | |
| +void varcol(Monitor *m)
 | |
| +{
 | |
| +	int				i, mastern, masterw, rightn, leftw, rightw, x, monwidth;
 | |
| +	unsigned int	leftn, totaln, coln, offset;
 | |
| +	float			colfacts;
 | |
| +	Client			*c, *tmp;
 | |
| +	int				nmastercols		= m->nmastercols;
 | |
| +	int				nrightcols		= m->nrightcols;
 | |
| +	struct wl_list	left_clients;
 | |
| +
 | |
| +	/*
 | |
| +		Remove each of window that belongs in the left column, so they can be
 | |
| +		reattached at the end of the list below.
 | |
| +	*/
 | |
| +	wl_list_init(&left_clients);
 | |
| +
 | |
| +	i = 0;
 | |
| +	wl_list_for_each_safe(c, tmp, &clients, link) {
 | |
| +		if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) {
 | |
| +			continue;
 | |
| +		}
 | |
| +
 | |
| +		if (i < m->nmaster) {
 | |
| +			/* Master */
 | |
| +			;
 | |
| +		} else if (isleft(c)) {
 | |
| +			/* Left; Detach and put in the left list */
 | |
| +			wl_list_remove(&c->link);
 | |
| +			wl_list_insert(&left_clients, &c->link);
 | |
| +		}
 | |
| +
 | |
| +		i++;
 | |
| +	}
 | |
| +
 | |
| +	/* Reattach the left clients to the main list */
 | |
| +	wl_list_for_each_reverse_safe(c, tmp, &left_clients, link) {
 | |
| +		wl_list_remove(&c->link);
 | |
| +		wl_list_insert(clients.prev, &c->link);
 | |
| +	}
 | |
| +
 | |
| +	/* Count the windows for each column type */
 | |
| +	totaln = leftn = rightn = mastern = 0;
 | |
| +	wl_list_for_each(c, &clients, link) {
 | |
| +		if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) {
 | |
| +			continue;
 | |
| +		}
 | |
| +
 | |
| +		if (mastern < m->nmaster) {
 | |
| +			mastern++;
 | |
| +		} else if (isleft(c)) {
 | |
| +			leftn++;
 | |
| +		} else {
 | |
| +			rightn++;
 | |
| +		}
 | |
| +
 | |
| +		totaln++;
 | |
| +	}
 | |
| +
 | |
| +	nmastercols	= MAX(MIN(mastern, nmastercols), 1);
 | |
| +	nrightcols	= MAX(MIN(rightn, nrightcols), 1);
 | |
| +
 | |
| +	if (mastern == 0) {
 | |
| +		return;
 | |
| +	}
 | |
| +
 | |
| +	/* Calculate the total colfacts value */
 | |
| +	colfacts = 0;
 | |
| +
 | |
| +	/* Left column */
 | |
| +	if (leftn > 0) {
 | |
| +		colfacts += m->colfact[0];
 | |
| +	}
 | |
| +
 | |
| +	/* Center column(s) */
 | |
| +	for (i = 0; i < nmastercols; i++) {
 | |
| +		colfacts += m->colfact[1];
 | |
| +	}
 | |
| +
 | |
| +	/* Right column(s) */
 | |
| +	if (rightn > 0) {
 | |
| +		for (i = 0; i < nrightcols; i++) {
 | |
| +			colfacts += m->colfact[2];
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	/* Calculate the usable width, with gapps removed */
 | |
| +	monwidth = m->w.width;
 | |
| +
 | |
| +	if (rightn > 0) {
 | |
| +		/* Gap to the left of reach right column */
 | |
| +		monwidth -= m->gappih * nrightcols;
 | |
| +	}
 | |
| +	if (leftn > 0) {
 | |
| +		/* Gap on the right of the left column */
 | |
| +		monwidth -= m->gappih;
 | |
| +	}
 | |
| +
 | |
| +	if (totaln > 1) {
 | |
| +		/* Outer gaps */
 | |
| +		monwidth -= (2 * m->gappoh);
 | |
| +	}
 | |
| +
 | |
| +	/* Calculate the width for each column type */
 | |
| +	leftw	= (int) ((monwidth / colfacts) * m->colfact[0]);
 | |
| +	masterw	= (int) ((monwidth / colfacts) * m->colfact[1]);
 | |
| +	rightw	= (int) ((monwidth / colfacts) * m->colfact[2]);
 | |
| +
 | |
| +	/* Adjust right and left column to fit all clients */
 | |
| +	wl_list_for_each(c, &clients, link) {
 | |
| +		struct wlr_box min = {0}, max = {0};
 | |
| +
 | |
| +		if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) {
 | |
| +			continue;
 | |
| +		}
 | |
| +
 | |
| +		/* Get client size hints */
 | |
| +		client_get_size_hints(c, &max, &min);
 | |
| +
 | |
| +		if (i < mastern) {
 | |
| +			/* Master columns */
 | |
| +
 | |
| +		} else if (!isleft(c)) {
 | |
| +			/* Right columns */
 | |
| +			x = min.width - rightw;
 | |
| +			if (x > 0) {
 | |
| +				rightw += x;
 | |
| +				masterw -= x;
 | |
| +			}
 | |
| +		} else if (leftn > 0) {
 | |
| +			/* left column */
 | |
| +			x = min.width - leftw;
 | |
| +			if (x > 0) {
 | |
| +				leftw += x;
 | |
| +				masterw -= x;
 | |
| +			}
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	/* Place each client */
 | |
| +	x = m->w.x;
 | |
| +	if (leftn > 0) {
 | |
| +		x += leftw;
 | |
| +		x += m->gappih;
 | |
| +	}
 | |
| +	if (totaln > 1) {
 | |
| +		x += m->gappoh;
 | |
| +	}
 | |
| +
 | |
| +	i = 0;
 | |
| +	wl_list_for_each(c, &clients, link) {
 | |
| +		struct wlr_box min = {0}, max = {0};
 | |
| +
 | |
| +		if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) {
 | |
| +			continue;
 | |
| +		}
 | |
| +
 | |
| +		/* Get client size hints */
 | |
| +		client_get_size_hints(c, &max, &min);
 | |
| +
 | |
| +		if (i < mastern) {
 | |
| +			/* Master columns */
 | |
| +
 | |
| +			/* Offset within the section */
 | |
| +			offset = i;
 | |
| +
 | |
| +			/* Max number of items in each master column */
 | |
| +			coln = (unsigned int) ceil((float) mastern / nmastercols);
 | |
| +
 | |
| +			placeClientInColumn(m, c, masterw, x, offset % coln, coln, totaln);
 | |
| +
 | |
| +			/* Only increment x if this is the last client in this column */
 | |
| +			if ((++offset % coln) == 0) {
 | |
| +				x += masterw;
 | |
| +				x += m->gappih;
 | |
| +			}
 | |
| +		} else if (!isleft(c)) {
 | |
| +			/* Right columns */
 | |
| +
 | |
| +			/* Offset within the section */
 | |
| +			offset = (i - mastern);
 | |
| +
 | |
| +			/* Max number of items in each right column */
 | |
| +			coln = (unsigned int) ceil((float) rightn / nrightcols);
 | |
| +
 | |
| +			placeClientInColumn(m, c, rightw, x, offset % coln, coln, totaln);
 | |
| +
 | |
| +			/* Only increment x if this is the last client in this column */
 | |
| +			if ((++offset % coln) == 0) {
 | |
| +				x += rightw;
 | |
| +				x += m->gappih;
 | |
| +			}
 | |
| +		} else if (leftn > 0) {
 | |
| +			/* left column */
 | |
| +			x = m->w.x;
 | |
| +			if (totaln > 1) {
 | |
| +				x += m->gappoh;
 | |
| +			}
 | |
| +
 | |
| +			/* Offset within the section */
 | |
| +			offset = i - (mastern + rightn);
 | |
| +
 | |
| +			/* There is only one left column */
 | |
| +			coln = leftn;
 | |
| +
 | |
| +			placeClientInColumn(m, c, leftw, x, offset, leftn, totaln);
 | |
| +		}
 | |
| +
 | |
| +		i++;
 | |
| +	}
 | |
| +}
 | |
| +
 | |
| +static int isleft(Client *c)
 | |
| +{
 | |
| +	if (c == NULL) {
 | |
| +		return 0;
 | |
| +	}
 | |
| +
 | |
| +	if (c->mon != NULL && c->mon->m.width <= 2000) {
 | |
| +		/* The left column is not worth using on a small monitor */
 | |
| +		return 0;
 | |
| +	}
 | |
| +
 | |
| +	return c->isLeft;
 | |
| +}
 | |
| +
 | |
| +/* Return non-zero if the currently selected client is in a master column */
 | |
| +static int ismaster(void)
 | |
| +{
 | |
| +	Client *c, *sel = focustop(selmon);
 | |
| +	int i;
 | |
| +
 | |
| +	if (!sel || !selmon || !selmon->lt[selmon->sellt]->arrange || sel->isfloating) {
 | |
| +		return 0;
 | |
| +	}
 | |
| +
 | |
| +	i = 0;
 | |
| +	wl_list_for_each(c, &clients, link) {
 | |
| +		if (!VISIBLEON(c, selmon) || c->isfloating || c->isfullscreen) {
 | |
| +			continue;
 | |
| +		}
 | |
| +
 | |
| +		if (sel == c) {
 | |
| +			/* c is the selected client, and is index i */
 | |
| +			if (i < selmon->nmaster) {
 | |
| +				return 1;
 | |
| +			} else {
 | |
| +				return 0;
 | |
| +			}
 | |
| +		}
 | |
| +		i++;
 | |
| +	}
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +/* A value >= 1.0 sets that colfact to that value - 1.0 */
 | |
| +void setcolfact(const Arg *arg)
 | |
| +{
 | |
| +	Client	*sel = focustop(selmon);
 | |
| +	int		index = 1;
 | |
| +
 | |
| +	if (!sel || !selmon || !selmon->lt[selmon->sellt]->arrange || sel->isfloating) {
 | |
| +		return;
 | |
| +	}
 | |
| +
 | |
| +	if (ismaster()) {
 | |
| +		index = 0;
 | |
| +		/* master */
 | |
| +		index = 0;
 | |
| +	} else if (isleft(sel)) {
 | |
| +		/* left */
 | |
| +		index = -1;
 | |
| +	} else {
 | |
| +		/* right */
 | |
| +		index = 1;
 | |
| +	}
 | |
| +	index++;
 | |
| +
 | |
| +	if (arg->f >= 1.0) {
 | |
| +		selmon->colfact[index] = arg->f - 1.0f;
 | |
| +	} else {
 | |
| +		/* Adjust the argument based on the selected column */
 | |
| +		selmon->colfact[index] += arg->f;
 | |
| +	}
 | |
| +
 | |
| +	if (selmon->colfact[index] < 0.1) {
 | |
| +		selmon->colfact[index] = 0.1f;
 | |
| +	} else if (selmon->colfact[index] > 0.9) {
 | |
| +		selmon->colfact[index] = 0.9f;
 | |
| +	}
 | |
| +	arrange(selmon);
 | |
| +}
 | |
| +
 | |
| +static void pushleft(const Arg *arg)
 | |
| +{
 | |
| +	Client	*sel = focustop(selmon);
 | |
| +
 | |
| +	if (!sel || !selmon || !selmon->lt[selmon->sellt]->arrange || sel->isfloating) {
 | |
| +		return;
 | |
| +	}
 | |
| +
 | |
| +	sel->isLeft = !sel->isLeft;
 | |
| +	focusclient(sel, 1);
 | |
| +	arrange(selmon);
 | |
| +}
 | |
| +
 | |
| +/*
 | |
| +	Modify either the right or master column count
 | |
| +*/
 | |
| +void incncols(const Arg *arg)
 | |
| +{
 | |
| +	Client	*sel = focustop(selmon);
 | |
| +
 | |
| +	if (!sel || !selmon || !selmon->lt[selmon->sellt]->arrange || sel->isfloating) {
 | |
| +		return;
 | |
| +	}
 | |
| +
 | |
| +	if (selmon->nmastercols < 1) selmon->nmastercols = 1;
 | |
| +	if (selmon->nrightcols < 1) selmon->nrightcols = 1;
 | |
| +
 | |
| +	if (ismaster()) {
 | |
| +		/* master */
 | |
| +		selmon->nmastercols += arg->i;
 | |
| +
 | |
| +		/* Auto adjust nmaster as well */
 | |
| +		selmon->nmaster = selmon->nmastercols;
 | |
| +	} else if (isleft(sel)) {
 | |
| +		/* left */
 | |
| +		;
 | |
| +	} else {
 | |
| +		/* right */
 | |
| +		selmon->nrightcols += arg->i;
 | |
| +	}
 | |
| +
 | |
| +	if (selmon->nmastercols < 1) selmon->nmastercols = 1;
 | |
| +	if (selmon->nrightcols < 1) selmon->nrightcols = 1;
 | |
| +
 | |
| +	arrange(selmon);
 | |
| +}
 | |
| +
 | |
| -- 
 | |
| 2.44.0
 | |
| 
 |