sites

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

dwm-clientopacity-6.4.diff (12855B)


      1 From 10dd5df95f551d81d0a814dcdb2bde20e405fb91 Mon Sep 17 00:00:00 2001
      2 From: sympodius <mail@sympodius.net>
      3 Date: Mon, 13 Mar 2023 16:28:16 +0000
      4 Subject: [PATCH] [dwm][patch][clientopacity] Adds opacity on a per client
      5  basis
      6 
      7 ---
      8  config.def.h | 80 ++++++++++++++++++++++++++++------------------------
      9  dwm.c        | 61 ++++++++++++++++++++++++++++++++++++++-
     10  2 files changed, 103 insertions(+), 38 deletions(-)
     11 
     12 diff --git a/config.def.h b/config.def.h
     13 index 9efa774..9ca812d 100644
     14 --- a/config.def.h
     15 +++ b/config.def.h
     16 @@ -5,6 +5,8 @@ static const unsigned int borderpx  = 1;        /* border pixel of windows */
     17  static const unsigned int snap      = 32;       /* snap pixel */
     18  static const int showbar            = 1;        /* 0 means no bar */
     19  static const int topbar             = 1;        /* 0 means bottom bar */
     20 +static const double activeopacity   = 0.9f;     /* Window opacity when it's focused (0 <= opacity <= 1) */
     21 +static const double inactiveopacity = 0.7f;     /* Window opacity when it's inactive (0 <= opacity <= 1) */
     22  static const char *fonts[]          = { "monospace:size=10" };
     23  static const char dmenufont[]       = "monospace:size=10";
     24  static const char col_gray1[]       = "#222222";
     25 @@ -26,9 +28,9 @@ static const Rule rules[] = {
     26  	 *	WM_CLASS(STRING) = instance, class
     27  	 *	WM_NAME(STRING) = title
     28  	 */
     29 -	/* class      instance    title       tags mask     isfloating   monitor */
     30 -	{ "Gimp",     NULL,       NULL,       0,            1,           -1 },
     31 -	{ "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 },
     32 +	/* class      instance    title       tags mask     isfloating   focusopacity    unfocusopacity     monitor */
     33 +	{ "Gimp",     NULL,       NULL,       0,            1,           1.0,            inactiveopacity,   -1 },
     34 +	{ "Firefox",  NULL,       NULL,       1 << 8,       0,           activeopacity,  inactiveopacity,   -1 },
     35  };
     36  
     37  /* layout(s) */
     38 @@ -61,40 +63,44 @@ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont,
     39  static const char *termcmd[]  = { "st", NULL };
     40  
     41  static const Key keys[] = {
     42 -	/* modifier                     key        function        argument */
     43 -	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
     44 -	{ MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
     45 -	{ MODKEY,                       XK_b,      togglebar,      {0} },
     46 -	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
     47 -	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
     48 -	{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
     49 -	{ MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
     50 -	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
     51 -	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
     52 -	{ MODKEY,                       XK_Return, zoom,           {0} },
     53 -	{ MODKEY,                       XK_Tab,    view,           {0} },
     54 -	{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
     55 -	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
     56 -	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
     57 -	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
     58 -	{ MODKEY,                       XK_space,  setlayout,      {0} },
     59 -	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
     60 -	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
     61 -	{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
     62 -	{ MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
     63 -	{ MODKEY,                       XK_period, focusmon,       {.i = +1 } },
     64 -	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
     65 -	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
     66 -	TAGKEYS(                        XK_1,                      0)
     67 -	TAGKEYS(                        XK_2,                      1)
     68 -	TAGKEYS(                        XK_3,                      2)
     69 -	TAGKEYS(                        XK_4,                      3)
     70 -	TAGKEYS(                        XK_5,                      4)
     71 -	TAGKEYS(                        XK_6,                      5)
     72 -	TAGKEYS(                        XK_7,                      6)
     73 -	TAGKEYS(                        XK_8,                      7)
     74 -	TAGKEYS(                        XK_9,                      8)
     75 -	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
     76 +	/* modifier                     key        function              argument */
     77 +	{ MODKEY,                       XK_p,      spawn,                {.v = dmenucmd } },
     78 +	{ MODKEY|ShiftMask,             XK_Return, spawn,                {.v = termcmd } },
     79 +	{ MODKEY,                       XK_b,      togglebar,            {0} },
     80 +	{ MODKEY,                       XK_j,      focusstack,           {.i = +1 } },
     81 +	{ MODKEY,                       XK_k,      focusstack,           {.i = -1 } },
     82 +	{ MODKEY,                       XK_i,      incnmaster,           {.i = +1 } },
     83 +	{ MODKEY,                       XK_d,      incnmaster,           {.i = -1 } },
     84 +	{ MODKEY,                       XK_h,      setmfact,             {.f = -0.05} },
     85 +	{ MODKEY,                       XK_l,      setmfact,             {.f = +0.05} },
     86 +	{ MODKEY,                       XK_Return, zoom,                 {0} },
     87 +	{ MODKEY,                       XK_Tab,    view,                 {0} },
     88 +	{ MODKEY|ShiftMask,             XK_c,      killclient,           {0} },
     89 +	{ MODKEY,                       XK_t,      setlayout,            {.v = &layouts[0]} },
     90 +	{ MODKEY,                       XK_f,      setlayout,            {.v = &layouts[1]} },
     91 +	{ MODKEY,                       XK_m,      setlayout,            {.v = &layouts[2]} },
     92 +	{ MODKEY,                       XK_space,  setlayout,            {0} },
     93 +	{ MODKEY|ShiftMask,             XK_space,  togglefloating,       {0} },
     94 +	{ MODKEY,                       XK_0,      view,                 {.ui = ~0 } },
     95 +	{ MODKEY|ShiftMask,             XK_0,      tag,                  {.ui = ~0 } },
     96 +	{ MODKEY,                       XK_comma,  focusmon,             {.i = -1 } },
     97 +	{ MODKEY,                       XK_period, focusmon,             {.i = +1 } },
     98 +	{ MODKEY|ShiftMask,             XK_comma,  tagmon,               {.i = -1 } },
     99 +	{ MODKEY|ShiftMask,             XK_period, tagmon,               {.i = +1 } },
    100 +        { MODKEY|ShiftMask,             XK_a,      changefocusopacity,   {.f = +0.025}},
    101 +        { MODKEY|ShiftMask,             XK_s,      changefocusopacity,   {.f = -0.025}},
    102 +	{ MODKEY|ShiftMask,             XK_z,      changeunfocusopacity, {.f = +0.025}},
    103 +        { MODKEY|ShiftMask,             XK_x,      changeunfocusopacity, {.f = -0.025}},
    104 +	TAGKEYS(                        XK_1,                            0)
    105 +	TAGKEYS(                        XK_2,                            1)
    106 +	TAGKEYS(                        XK_3,                            2)
    107 +	TAGKEYS(                        XK_4,                            3)
    108 +	TAGKEYS(                        XK_5,                            4)
    109 +	TAGKEYS(                        XK_6,                            5)
    110 +	TAGKEYS(                        XK_7,                            6)
    111 +	TAGKEYS(                        XK_8,                            7)
    112 +	TAGKEYS(                        XK_9,                            8)
    113 +	{ MODKEY|ShiftMask,             XK_q,      quit,                 {0} },
    114  };
    115  
    116  /* button definitions */
    117 diff --git a/dwm.c b/dwm.c
    118 index c2bd871..71cf33c 100644
    119 --- a/dwm.c
    120 +++ b/dwm.c
    121 @@ -62,7 +62,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
    122  enum { SchemeNorm, SchemeSel }; /* color schemes */
    123  enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
    124         NetWMFullscreen, NetActiveWindow, NetWMWindowType,
    125 -       NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
    126 +       NetWMWindowTypeDialog, NetClientList, NetWMWindowsOpacity, NetLast }; /* EWMH atoms */
    127  enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
    128  enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
    129         ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
    130 @@ -95,6 +95,8 @@ struct Client {
    131  	int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
    132  	Client *next;
    133  	Client *snext;
    134 +        double opacity;
    135 +        double unfocusopacity;
    136  	Monitor *mon;
    137  	Window win;
    138  };
    139 @@ -138,6 +140,8 @@ typedef struct {
    140  	const char *title;
    141  	unsigned int tags;
    142  	int isfloating;
    143 +	double opacity;
    144 +        double unfocusopacity;
    145  	int monitor;
    146  } Rule;
    147  
    148 @@ -149,6 +153,8 @@ static void arrangemon(Monitor *m);
    149  static void attach(Client *c);
    150  static void attachstack(Client *c);
    151  static void buttonpress(XEvent *e);
    152 +static void changefocusopacity(const Arg *arg);
    153 +static void changeunfocusopacity(const Arg *arg);
    154  static void checkotherwm(void);
    155  static void cleanup(void);
    156  static void cleanupmon(Monitor *mon);
    157 @@ -185,6 +191,7 @@ static void monocle(Monitor *m);
    158  static void motionnotify(XEvent *e);
    159  static void movemouse(const Arg *arg);
    160  static Client *nexttiled(Client *c);
    161 +static void opacity(Client *c, double opacity);
    162  static void pop(Client *c);
    163  static void propertynotify(XEvent *e);
    164  static void quit(const Arg *arg);
    165 @@ -287,6 +294,8 @@ applyrules(Client *c)
    166  	/* rule matching */
    167  	c->isfloating = 0;
    168  	c->tags = 0;
    169 +	c->opacity = activeopacity;
    170 +	c->unfocusopacity = inactiveopacity;
    171  	XGetClassHint(dpy, c->win, &ch);
    172  	class    = ch.res_class ? ch.res_class : broken;
    173  	instance = ch.res_name  ? ch.res_name  : broken;
    174 @@ -299,6 +308,8 @@ applyrules(Client *c)
    175  		{
    176  			c->isfloating = r->isfloating;
    177  			c->tags |= r->tags;
    178 +			c->opacity = r->opacity;
    179 +			c->unfocusopacity = r->unfocusopacity;
    180  			for (m = mons; m && m->num != r->monitor; m = m->next);
    181  			if (m)
    182  				c->mon = m;
    183 @@ -457,6 +468,36 @@ buttonpress(XEvent *e)
    184  			buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
    185  }
    186  
    187 +void
    188 +changefocusopacity(const Arg *arg)
    189 +{
    190 +        if (!selmon->sel)
    191 +                return;
    192 +        selmon->sel->opacity+=arg->f;
    193 +        if(selmon->sel->opacity > 1.0)
    194 +                selmon->sel->opacity = 1.0;
    195 +
    196 +        if(selmon->sel->opacity < 0.1)
    197 +                selmon->sel->opacity = 0.1;
    198 +
    199 +        opacity(selmon->sel, selmon->sel->opacity);
    200 +}
    201 +
    202 +void
    203 +changeunfocusopacity(const Arg *arg)
    204 +{
    205 +        if (!selmon->sel)
    206 +                return;
    207 +        selmon->sel->unfocusopacity+=arg->f;
    208 +        if(selmon->sel->unfocusopacity > 1.0)
    209 +                selmon->sel->unfocusopacity = 1.0;
    210 +
    211 +        if(selmon->sel->unfocusopacity < 0.1)
    212 +                selmon->sel->unfocusopacity = 0.1;
    213 +
    214 +        opacity(selmon->sel, selmon->sel->unfocusopacity);
    215 +}
    216 +
    217  void
    218  checkotherwm(void)
    219  {
    220 @@ -803,6 +844,8 @@ focus(Client *c)
    221  		grabbuttons(c, 1);
    222  		XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
    223  		setfocus(c);
    224 +		c->opacity = MIN(1.0, MAX(0, c->opacity));
    225 +		opacity(c, c->opacity);
    226  	} else {
    227  		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
    228  		XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
    229 @@ -1052,6 +1095,7 @@ manage(Window w, XWindowAttributes *wa)
    230  		c->mon = selmon;
    231  		applyrules(c);
    232  	}
    233 +	opacity(c, c->opacity);
    234  
    235  	if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
    236  		c->x = c->mon->wx + c->mon->ww - WIDTH(c);
    237 @@ -1209,6 +1253,18 @@ nexttiled(Client *c)
    238  	return c;
    239  }
    240  
    241 +void
    242 +opacity(Client *c, double opacity)
    243 +{
    244 +        if(opacity > 0 && opacity < 1) {
    245 +                unsigned long real_opacity[] = { opacity * 0xffffffff };
    246 +                XChangeProperty(dpy, c->win, netatom[NetWMWindowsOpacity], XA_CARDINAL,
    247 +                                32, PropModeReplace, (unsigned char *)real_opacity,
    248 +                                1);
    249 +        } else
    250 +                XDeleteProperty(dpy, c->win, netatom[NetWMWindowsOpacity]);
    251 +}
    252 +
    253  void
    254  pop(Client *c)
    255  {
    256 @@ -1579,6 +1635,7 @@ setup(void)
    257  	netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
    258  	netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
    259  	netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
    260 +	netatom[NetWMWindowsOpacity] = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
    261  	/* init cursors */
    262  	cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
    263  	cursor[CurResize] = drw_cur_create(drw, XC_sizing);
    264 @@ -1760,6 +1817,8 @@ unfocus(Client *c, int setfocus)
    265  	if (!c)
    266  		return;
    267  	grabbuttons(c, 0);
    268 +	c->unfocusopacity = MIN(1.0, MAX(0, c->unfocusopacity));
    269 +	opacity(c, c->unfocusopacity);
    270  	XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
    271  	if (setfocus) {
    272  		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
    273 -- 
    274 2.39.2
    275