dwm-clientopacity-6.4.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) 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