sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dwm-scratchpad-20200727-bb2e7222baeec7776930354d0e9f210cc2aaad5f.diff (4213B)


      1 diff --git a/config.def.h b/config.def.h
      2 index 1c0b587..48cf601 100644
      3 --- a/config.def.h
      4 +++ b/config.def.h
      5 @@ -94,6 +94,9 @@ static Key keys[] = {
      6  	TAGKEYS(                        XK_8,                      7)
      7  	TAGKEYS(                        XK_9,                      8)
      8  	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
      9 +	{ MODKEY,                       XK_minus, scratchpad_show, {0} },
     10 +	{ MODKEY|ShiftMask,             XK_minus, scratchpad_hide, {0} },
     11 +	{ MODKEY,                       XK_equal,scratchpad_remove,{0} },
     12  };
     13  
     14  /* button definitions */
     15 diff --git a/dwm.c b/dwm.c
     16 index 9fd0286..c647493 100644
     17 --- a/dwm.c
     18 +++ b/dwm.c
     19 @@ -195,6 +195,12 @@ static void resizemouse(const Arg *arg);
     20  static void restack(Monitor *m);
     21  static void run(void);
     22  static void scan(void);
     23 +static void scratchpad_hide ();
     24 +static _Bool scratchpad_last_showed_is_killed (void);
     25 +static void scratchpad_remove ();
     26 +static void scratchpad_show ();
     27 +static void scratchpad_show_client (Client * c);
     28 +static void scratchpad_show_first (void);
     29  static int sendevent(Client *c, Atom proto);
     30  static void sendmon(Client *c, Monitor *m);
     31  static void setclientstate(Client *c, long state);
     32 @@ -269,11 +275,15 @@ static Drw *drw;
     33  static Monitor *mons, *selmon;
     34  static Window root, wmcheckwin;
     35  
     36 +/* scratchpad */
     37 +# define SCRATCHPAD_MASK (1u << sizeof tags / sizeof * tags)
     38 +static Client * scratchpad_last_showed = NULL;
     39 +
     40  /* configuration, allows nested code to access above variables */
     41  #include "config.h"
     42  
     43  /* compile-time check if all tags fit into an unsigned int bit array. */
     44 -struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
     45 +struct NumTags { char limitexceeded[LENGTH(tags) > 30 ? -1 : 1]; };
     46  
     47  /* function implementations */
     48  void
     49 @@ -309,7 +319,8 @@ applyrules(Client *c)
     50  		XFree(ch.res_class);
     51  	if (ch.res_name)
     52  		XFree(ch.res_name);
     53 -	c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
     54 +	if (c->tags != SCRATCHPAD_MASK)
     55 +		c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
     56  }
     57  
     58  int
     59 @@ -1408,6 +1419,98 @@ scan(void)
     60  	}
     61  }
     62  
     63 +static void scratchpad_hide ()
     64 +{
     65 +	if (selmon -> sel)
     66 +	{
     67 +		selmon -> sel -> tags = SCRATCHPAD_MASK;
     68 +		selmon -> sel -> isfloating = 1;
     69 +		focus(NULL);
     70 +		arrange(selmon);
     71 +	}
     72 +}
     73 +
     74 +static _Bool scratchpad_last_showed_is_killed (void)
     75 +{
     76 +	_Bool killed = 1;
     77 +	for (Client * c = selmon -> clients; c != NULL; c = c -> next)
     78 +	{
     79 +		if (c == scratchpad_last_showed)
     80 +		{
     81 +			killed = 0;
     82 +			break;
     83 +		}
     84 +	}
     85 +	return killed;
     86 +}
     87 +
     88 +static void scratchpad_remove ()
     89 +{
     90 +	if (selmon -> sel && scratchpad_last_showed != NULL && selmon -> sel == scratchpad_last_showed)
     91 +		scratchpad_last_showed = NULL;
     92 +}
     93 +
     94 +static void scratchpad_show ()
     95 +{
     96 +	if (scratchpad_last_showed == NULL || scratchpad_last_showed_is_killed ())
     97 +		scratchpad_show_first ();
     98 +	else
     99 +	{
    100 +		if (scratchpad_last_showed -> tags != SCRATCHPAD_MASK)
    101 +		{
    102 +			scratchpad_last_showed -> tags = SCRATCHPAD_MASK;
    103 +			focus(NULL);
    104 +			arrange(selmon);
    105 +		}
    106 +		else
    107 +		{
    108 +			_Bool found_current = 0;
    109 +			_Bool found_next = 0;
    110 +			for (Client * c = selmon -> clients; c != NULL; c = c -> next)
    111 +			{
    112 +				if (found_current == 0)
    113 +				{
    114 +					if (c == scratchpad_last_showed)
    115 +					{
    116 +						found_current = 1;
    117 +						continue;
    118 +					}
    119 +				}
    120 +				else
    121 +				{
    122 +					if (c -> tags == SCRATCHPAD_MASK)
    123 +					{
    124 +						found_next = 1;
    125 +						scratchpad_show_client (c);
    126 +						break;
    127 +					}
    128 +				}
    129 +			}
    130 +			if (found_next == 0) scratchpad_show_first ();
    131 +		}
    132 +	}
    133 +}
    134 +
    135 +static void scratchpad_show_client (Client * c)
    136 +{
    137 +	scratchpad_last_showed = c;
    138 +	c -> tags = selmon->tagset[selmon->seltags];
    139 +	focus(c);
    140 +	arrange(selmon);
    141 +}
    142 +
    143 +static void scratchpad_show_first (void)
    144 +{
    145 +	for (Client * c = selmon -> clients; c != NULL; c = c -> next)
    146 +	{
    147 +		if (c -> tags == SCRATCHPAD_MASK)
    148 +		{
    149 +			scratchpad_show_client (c);
    150 +			break;
    151 +		}
    152 +	}
    153 +}
    154 +
    155  void
    156  sendmon(Client *c, Monitor *m)
    157  {
    158 @@ -1781,6 +1884,8 @@ unmanage(Client *c, int destroyed)
    159  		XSetErrorHandler(xerror);
    160  		XUngrabServer(dpy);
    161  	}
    162 +	if (scratchpad_last_showed == c)
    163 +		scratchpad_last_showed = NULL;
    164  	free(c);
    165  	focus(NULL);
    166  	updateclientlist();