~ruther/dwl

5603a9dc13d8bca3959c213d7e11dbfcccd093b0 — Rutherther 8 months ago 0084341 + 3227713
Merge branch 'v0.7/namedscratchpads' into v0.7/patched-base
2 files changed, 137 insertions(+), 4 deletions(-)

M config.def.h
M dwl.c
M config.def.h => config.def.h +11 -4
@@ 22,11 22,12 @@ static int log_level = WLR_ERROR;

/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = {
	/* app_id             title       tags mask     isfloating  isterm  noswallow  monitor */
	/* app_id             title       tags mask     isfloating  isterm  noswallow  monitor scratchkey */
	/* examples: */
	{ "Gimp_EXAMPLE",     NULL,       0,            1,          0,      0,         -1 }, /* Start on currently visible tags floating, not tiled */
	{ "firefox_EXAMPLE",  NULL,       1 << 8,       0,          0,      0,         -1 }, /* Start on ONLY tag "9" */
	{ "foot",             NULL,       0,            0,          1,      1,         -1 }, /* make foot swallow clients that are not foot */
  { "Gimp_EXAMPLE",     NULL,       0,            1,          0,      0,         -1,     0 }, /* Start on currently visible tags floating, not tiled */
  { "firefox_EXAMPLE",  NULL,       1 << 8,       0,          0,      0,         -1,     0 }, /* Start on ONLY tag "9" */
  { "foot",             NULL,       0,            0,          1,      1,         -1,     0 }, /* make foot swallow clients that are not foot */
	{ NULL,               "scratchpad", 0,          1,          0,      0,         -1,     's' },
};

/* layout(s) */


@@ 129,12 130,18 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
static const char *termcmd[] = { "foot", NULL };
static const char *menucmd[] = { "wmenu-run", NULL };

/* named scratchpads - First arg only serves to match against key in rules*/
static const char *scratchpadcmd[] = { "s", "alacritty", "-t", "scratchpad", NULL };

static const Key keys[] = {
	/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
	/* modifier                  key                 function        argument */
	{ MODKEY,                    XKB_KEY_p,          spawn,          {.v = menucmd} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return,     spawn,          {.v = termcmd} },
	{ MODKEY,                    XKB_KEY_b,          togglebar,      {0} },
	{ MODKEY,                    XKB_KEY_grave,      togglescratch,  {.v = scratchpadcmd } },
	// { MODKEY,                    XKB_KEY_grave,      focusortogglescratch, {.v = scratchpadcmd } },
	// { MODKEY,                    XKB_KEY_grave,      focusortogglematchingscratch, {.v = scratchpadcmd } },
	{ MODKEY,                    XKB_KEY_j,          focusstack,     {.i = +1} },
	{ MODKEY,                    XKB_KEY_k,          focusstack,     {.i = -1} },
	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J,          movestack,      {.i = +1} },

M dwl.c => dwl.c +126 -0
@@ 144,6 144,7 @@ struct Client {
	unsigned int bw;
	uint32_t tags;
  int isfloating, isurgent, isfullscreen, issticky, isterm, noswallow;
	char scratchkey;
	uint32_t resize; /* configure serial of a pending resize */
	pid_t pid;
	Client *swallowing, *swallowedby;


@@ 254,6 255,7 @@ typedef struct {
	int isterm;
	int noswallow;
	int monitor;
	const char scratchkey;
} Rule;

typedef struct {


@@ 323,6 325,8 @@ static void dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource
static void dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource);
static void focusclient(Client *c, int lift);
static void focusmon(const Arg *arg);
static void focusortogglematchingscratch(const Arg *arg);
static void focusortogglescratch(const Arg *arg);
static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);


@@ 374,6 378,7 @@ static void setpsel(struct wl_listener *listener, void *data);
static void setsel(struct wl_listener *listener, void *data);
static void setup(void);
static void spawn(const Arg *arg);
static void spawnscratch(const Arg *arg);
static void startdrag(struct wl_listener *listener, void *data);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);


@@ 382,6 387,7 @@ static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
static void togglesticky(const Arg *arg);
static void togglefullscreen(const Arg *arg);
static void togglescratch(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);


@@ 518,6 524,7 @@ applyrules(Client *c)
	Monitor *mon = selmon, *m;

	c->isfloating = client_is_float_type(c);
	c->scratchkey = 0;
	if (!(appid = client_get_appid(c)))
		appid = broken;
	if (!(title = client_get_title(c)))


@@ 531,6 538,7 @@ applyrules(Client *c)
			c->isfloating = r->isfloating;
			c->isterm     = r->isterm;
			c->noswallow  = r->noswallow;
			c->scratchkey = r->scratchkey;
			newtags |= r->tags;
			i = 0;
			wl_list_for_each(m, &mons, link) {


@@ 1773,6 1781,91 @@ focusmon(const Arg *arg)
}

void
focusortogglematchingscratch(const Arg *arg)
{
	Client *c;
	unsigned int found = 0;
	unsigned int hide = 0;

	wl_list_for_each(c, &clients, link) {
		if (c->scratchkey == 0) {
			continue;
		}
		if (c->scratchkey == ((char**)arg->v)[0][0]) {
			if (VISIBLEON(c, selmon)) {
				if (found == 1) {
					if (hide == 1) {
						c->tags = 0;
						focusclient(focustop(selmon), 1);
					}
					continue;
				}
				if (focustop(selmon) == c) {
					// hide
					c->tags = 0;
					focusclient(focustop(selmon), 1);
					hide = 1;
				} else {
					// focus
					focusclient(c, 1);
				}
			} else {
				// show
				c->tags = selmon->tagset[selmon->seltags];
				// focus
				focusclient(c, 1);
			}
			found = 1;
			continue;
		}
		if (VISIBLEON(c, selmon)) {
			// hide
			c->tags = 0;
		}
	}

	if (found) {
		arrange(selmon);
	} else {
		spawnscratch(arg);
	}
}

void
focusortogglescratch(const Arg *arg)
{
	Client *c;
	unsigned int found = 0;

	/* search for first window that matches the scratchkey */
	wl_list_for_each(c, &clients, link)
		if (c->scratchkey == ((char**)arg->v)[0][0]) {
			found = 1;
			break;
		}

	if (found) {
		if (VISIBLEON(c, selmon)) {
			if (focustop(selmon) == c) {
				// hide
				c->tags = 0;
				focusclient(focustop(selmon), 1);
			} else {
				// focus
				focusclient(c, 1);
			}
		} else {
			// show
			c->tags = selmon->tagset[selmon->seltags];
			focusclient(c, 1);
		}
		arrange(selmon);
	} else{
		spawnscratch(arg);
	}
}

void
focusstack(const Arg *arg)
{
	/* Focus the next or previous client (in tiling order) on selmon */


@@ 3117,6 3210,16 @@ spawn(const Arg *arg)
	}
}

void spawnscratch(const Arg *arg)
{
	if (fork() == 0) {
		dup2(STDERR_FILENO, STDOUT_FILENO);
		setsid();
		execvp(((char **)arg->v)[1], ((char **)arg->v)+1);
		die("dwl: execvp %s failed:", ((char **)arg->v)[1]);
	}
}

void
startdrag(struct wl_listener *listener, void *data)
{


@@ 3229,6 3332,29 @@ togglesticky(const Arg *arg)
}

void
togglescratch(const Arg *arg)
{
	Client *c;
	unsigned int found = 0;

	/* search for first window that matches the scratchkey */
	wl_list_for_each(c, &clients, link)
		if (c->scratchkey == ((char**)arg->v)[0][0]) {
			found = 1;
			break;
		}

	if (found) {
		c->tags = VISIBLEON(c, selmon) ? 0 : selmon->tagset[selmon->seltags];

		focusclient(c->tags == 0 ? focustop(selmon) : c, 1);
		arrange(selmon);
	} else{
		spawnscratch(arg);
	}
}

void
toggletag(const Arg *arg)
{
	Monitor *m;

Do not follow this link