summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2022-08-11 18:57:38 +0300
committereug-vs <eugene@eug-vs.xyz>2022-08-11 18:57:38 +0300
commite7ebe190d266649371ac901bdc4b152f64ec7f85 (patch)
tree57c47d4cb35207c63f24e90147d6bc2dd7ee38b9
parent620143fb42cbc10f6ca2de50b7efdb37bcf4f37b (diff)
downloadebuild-repository-e7ebe190d266649371ac901bdc4b152f64ec7f85.tar.gz
add patches to profile
-rw-r--r--profiles/eug-vs/patches/x11-libs/libXft/bgra.patch861
-rw-r--r--profiles/eug-vs/patches/x11-misc/dmenu/0001-chore-remove-config.h-on-clean.patch25
-rw-r--r--profiles/eug-vs/patches/x11-misc/dmenu/0002-feat-use-Fira-Code-and-gruvbox-cyan.patch33
-rw-r--r--profiles/eug-vs/patches/x11-misc/dmenu/0003-feat-use-gray-background.patch25
-rw-r--r--profiles/eug-vs/patches/x11-misc/dmenu/0004-feat-use-classic-background.patch25
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0001-feat-change-MOD-to-SUPER.patch29
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0002-feat-remove-config.h-on-clean-install.patch25
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0003-feat-only-use-config.def.h.patch38
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0004-feat-bind-exit-to-E-and-kill-client-to-Q.patch34
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0005-feat-apply-swallow-patch.patch377
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0006-feat-swap-h-l-and-behavior.patch42
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0007-feat-resize-on-MOD-r.patch24
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0008-feat-use-Fira-Code.patch83
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0009-feat-apply-attachaside-patch.patch105
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0010-feat-change-master-width-to-75.patch25
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0011-patch-actual-fullscreen.patch66
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0012-patch-systray.patch749
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0013-feat-remove-accent-color.patch30
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0014-fix-add-missing-terminal-flag-to-st.patch37
-rw-r--r--profiles/eug-vs/patches/x11-wm/dwm/0015-feat-use-classic-dwm-colors.patch30
20 files changed, 2663 insertions, 0 deletions
diff --git a/profiles/eug-vs/patches/x11-libs/libXft/bgra.patch b/profiles/eug-vs/patches/x11-libs/libXft/bgra.patch
new file mode 100644
index 0000000..5c594cc
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-libs/libXft/bgra.patch
@@ -0,0 +1,861 @@
+From 723092ece088559f1af299236305911f4ee4d450 Mon Sep 17 00:00:00 2001
+From: Maxime Coste <mawww@kakoune.org>
+Date: Thu, 28 Jan 2021 19:59:10 +1100
+Subject: [PATCH 1/3] Introduce a _XftCompositeString helper function
+
+Dispatch to XRenderCompositeString{8,16,32} based off the given width.
+
+Signed-off-by: Maxime Coste <mawww@kakoune.org>
+---
+ src/xftrender.c | 61 ++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 18 deletions(-)
+
+diff --git a/src/xftrender.c b/src/xftrender.c
+index a352737..181c27a 100644
+--- a/src/xftrender.c
++++ b/src/xftrender.c
+@@ -25,6 +25,47 @@
+ #define NUM_LOCAL 1024
+ #define NUM_ELT_LOCAL 128
+
++/*
++ * Dispatch glyph drawing to the correct XRenderCompositeString function
++ */
++static void
++_XftCompositeString (Display *dpy,
++ int op,
++ Picture src,
++ Picture dst,
++ XRenderPictFormat *format,
++ GlyphSet glyphset,
++ int srcx,
++ int srcy,
++ int dstx,
++ int dsty,
++ int charwidth,
++ unsigned int *chars,
++ int nchars)
++{
++ if (nchars == 0)
++ return;
++
++ switch (charwidth) {
++ case 1:
++ default:
++ XRenderCompositeString8 (dpy, op,
++ src, dst, format, glyphset,
++ srcx, srcy, dstx, dsty, (char*)chars, nchars);
++ break;
++ case 2:
++ XRenderCompositeString16(dpy, op,
++ src, dst, format, glyphset,
++ srcx, srcy, dstx, dsty, (unsigned short*)chars, nchars);
++ break;
++ case 4:
++ XRenderCompositeString32(dpy, op,
++ src, dst, format, glyphset,
++ srcx, srcy, dstx, dsty, (unsigned int*)chars, nchars);
++ break;
++ }
++}
++
+ /*
+ * Use the Render extension to draw the glyphs
+ */
+@@ -114,24 +155,8 @@ XftGlyphRender (Display *dpy,
+ case 4: char32[i] = (unsigned int) wire; break;
+ }
+ }
+- switch (width) {
+- case 1:
+- default:
+- XRenderCompositeString8 (dpy, op,
+- src, dst, font->format, font->glyphset,
+- srcx, srcy, x, y, char8, nglyphs);
+- break;
+- case 2:
+- XRenderCompositeString16(dpy, op,
+- src, dst, font->format, font->glyphset,
+- srcx, srcy, x, y, char16, nglyphs);
+- break;
+- case 4:
+- XRenderCompositeString32(dpy, op,
+- src, dst, font->format, font->glyphset,
+- srcx, srcy, x, y, char32, nglyphs);
+- break;
+- }
++ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset,
++ srcx, srcy, x, y, width, chars, nglyphs);
+ if (chars != char_local)
+ free (chars);
+ bail1:
+--
+GitLab
+
+
+From e0fc4ce7e87ab9c4b47e5c8e693f070dfd0d2f7b Mon Sep 17 00:00:00 2001
+From: Maxime Coste <mawww@kakoune.org>
+Date: Thu, 28 Jan 2021 20:05:13 +1100
+Subject: [PATCH 2/3] Introduce a _XftCompositeText helper function
+
+Dispatch to XRenderCompositeText{8,16,32} based off the given width.
+
+Signed-off-by: Maxime Coste <mawww@kakoune.org>
+---
+ src/xftrender.c | 83 +++++++++++++++++++++++++++++--------------------
+ 1 file changed, 49 insertions(+), 34 deletions(-)
+
+diff --git a/src/xftrender.c b/src/xftrender.c
+index 181c27a..5852b2e 100644
+--- a/src/xftrender.c
++++ b/src/xftrender.c
+@@ -164,6 +164,49 @@ bail1:
+ _XftFontManageMemory (dpy, pub);
+ }
+
++/*
++ * Dispatch glyph drawing to the correct XRenderCompositeText function
++ */
++static void
++_XftCompositeText (Display *dpy,
++ int op,
++ Picture src,
++ Picture dst,
++ XRenderPictFormat *format,
++ int srcx,
++ int srcy,
++ int dstx,
++ int dsty,
++ int eltwidth,
++ XGlyphElt8 *elts,
++ int nelt)
++{
++ if (nelt == 0)
++ return;
++
++ switch (eltwidth) {
++ case 1:
++ default:
++ XRenderCompositeText8 (dpy, op,
++ src, dst, format,
++ srcx, srcy, dstx, dsty,
++ (XGlyphElt8*)elts, nelt);
++ break;
++ case 2:
++ XRenderCompositeText16(dpy, op,
++ src, dst, format,
++ srcx, srcy, dstx, dsty,
++ (XGlyphElt16*)elts, nelt);
++ break;
++ case 4:
++ XRenderCompositeText32(dpy, op,
++ src, dst, format,
++ srcx, srcy, dstx, dsty,
++ (XGlyphElt32*)elts, nelt);
++ break;
++ }
++}
++
+ _X_EXPORT void
+ XftGlyphSpecRender (Display *dpy,
+ int op,
+@@ -345,23 +388,9 @@ XftGlyphSpecRender (Display *dpy,
+ elts[nelt].nchars = n;
+ nelt++;
+ }
+- switch (width) {
+- case 1:
+- XRenderCompositeText8 (dpy, op, src, dst, font->format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- elts, nelt);
+- break;
+- case 2:
+- XRenderCompositeText16 (dpy, op, src, dst, font->format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- (XGlyphElt16 *) elts, nelt);
+- break;
+- case 4:
+- XRenderCompositeText32 (dpy, op, src, dst, font->format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- (XGlyphElt32 *) elts, nelt);
+- break;
+- }
++ _XftCompositeText(dpy, op, src, dst, font->format,
++ srcx, srcy, glyphs[0].x, glyphs[0].y,
++ width, elts, nelt);
+
+ if (elts != elts_local)
+ free (elts);
+@@ -635,23 +664,9 @@ XftGlyphFontSpecRender (Display *dpy,
+ elts[nelt].nchars = n;
+ nelt++;
+ }
+- switch (width) {
+- case 1:
+- XRenderCompositeText8 (dpy, op, src, dst, format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- elts, nelt);
+- break;
+- case 2:
+- XRenderCompositeText16 (dpy, op, src, dst, format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- (XGlyphElt16 *) elts, nelt);
+- break;
+- case 4:
+- XRenderCompositeText32 (dpy, op, src, dst, format,
+- srcx, srcy, glyphs[0].x, glyphs[0].y,
+- (XGlyphElt32 *) elts, nelt);
+- break;
+- }
++ _XftCompositeText(dpy, op, src, dst, format,
++ srcx, srcy, glyphs[0].x, glyphs[0].y,
++ width, elts, nelt);
+
+ if (elts != elts_local)
+ free (elts);
+--
+GitLab
+
+
+From d385aa3e5320d18918413df0e8aef3a713a47e0b Mon Sep 17 00:00:00 2001
+From: Maxime Coste <mawww@kakoune.org>
+Date: Tue, 22 Oct 2019 22:46:49 +1100
+Subject: [PATCH 3/3] Add support for BGRA glyphs display and scaling
+
+Display is done using an XRender Picture, as XRender
+glyphs are incompatible with BGRA rendering due to
+their use of the glyph bitmap as a mask.
+
+Scaling is done by averaging all relevant pixel, which gives
+much better result than nearest pixel sampling while staying
+simple enough and not too computationally expensive.
+
+This enables color emoji rendering support.
+
+Fixes: #6
+
+Signed-off-by: Maxime Coste <mawww@kakoune.org>
+---
+ src/xftfreetype.c | 18 +++-
+ src/xftglyphs.c | 234 +++++++++++++++++++++++++++++++++++++++++++---
+ src/xftint.h | 2 +
+ src/xftrender.c | 69 +++++++++++---
+ 4 files changed, 293 insertions(+), 30 deletions(-)
+
+diff --git a/src/xftfreetype.c b/src/xftfreetype.c
+index 1f79a81..4325d65 100644
+--- a/src/xftfreetype.c
++++ b/src/xftfreetype.c
+@@ -523,7 +523,7 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
+ /*
+ * Compute glyph load flags
+ */
+- fi->load_flags = FT_LOAD_DEFAULT;
++ fi->load_flags = FT_LOAD_DEFAULT | FT_LOAD_COLOR;
+
+ #ifndef XFT_EMBEDDED_BITMAP
+ #define XFT_EMBEDDED_BITMAP "embeddedbitmap"
+@@ -775,6 +775,7 @@ XftFontOpenInfo (Display *dpy,
+ FcChar32 hash_value;
+ FcChar32 rehash_value;
+ FcBool antialias;
++ FcBool color;
+ int max_glyph_memory;
+ int alloc_size;
+ int ascent, descent, height;
+@@ -831,12 +832,18 @@ XftFontOpenInfo (Display *dpy,
+ if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
+ antialias = FcFalse;
+
++ color = FT_HAS_COLOR(face) ? FcTrue : FcFalse;
++
+ /*
+ * Find the appropriate picture format
+ */
+ if (fi->render)
+ {
+- if (antialias)
++ if (color)
++ {
++ format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
++ }
++ else if (antialias)
+ {
+ switch (fi->rgba) {
+ case FC_RGBA_RGB:
+@@ -968,6 +975,13 @@ XftFontOpenInfo (Display *dpy,
+ * which doesn't happen in XftFontInfoFill
+ */
+ font->info.antialias = antialias;
++
++ /*
++ * Set color value, which is only known once the
++ * font was loaded
++ */
++ font->info.color = color;
++
+ /*
+ * bump XftFile reference count
+ */
+diff --git a/src/xftglyphs.c b/src/xftglyphs.c
+index b536df4..e0bad10 100644
+--- a/src/xftglyphs.c
++++ b/src/xftglyphs.c
+@@ -26,6 +26,8 @@
+
+ #include FT_SYNTHESIS_H
+
++#include FT_GLYPH_H
++
+ /*
+ * Validate the memory info for a font
+ */
+@@ -78,9 +80,11 @@ _XftFontValidateMemory (Display *dpy, XftFont *public)
+ static int
+ _compute_xrender_bitmap_size( FT_Bitmap* target,
+ FT_GlyphSlot slot,
+- FT_Render_Mode mode )
++ FT_Render_Mode mode,
++ FT_Matrix* matrix )
+ {
+ FT_Bitmap* ftbit;
++ FT_Vector vector;
+ int width, height, pitch;
+
+ if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
+@@ -91,6 +95,16 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
+
+ width = (int)ftbit->width;
+ height = (int)ftbit->rows;
++
++ if ( matrix && mode == FT_RENDER_MODE_NORMAL )
++ {
++ vector.x = ftbit->width;
++ vector.y = ftbit->rows;
++ FT_Vector_Transform(&vector, matrix);
++
++ width = (int)vector.x;
++ height = (int)vector.y;
++ }
+ pitch = (width+3) & ~3;
+
+ switch ( ftbit->pixel_mode )
+@@ -112,6 +126,10 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
+ }
+ break;
+
++ case FT_PIXEL_MODE_BGRA:
++ pitch = width * 4;
++ break;
++
+ case FT_PIXEL_MODE_LCD:
+ if ( mode != FT_RENDER_MODE_LCD )
+ return -1;
+@@ -142,6 +160,105 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
+ return pitch * height;
+ }
+
++/* this functions converts the glyph bitmap found in a FT_GlyphSlot
++ * into a different format while scaling by applying the given matrix
++ * (see _compute_xrender_bitmap_size)
++ *
++ * you should call this function after _compute_xrender_bitmap_size
++ *
++ * target :: target bitmap descriptor. Note that its 'buffer' pointer
++ * must point to memory allocated by the caller
++ *
++ * source :: the source bitmap descriptor
++ *
++ * matrix :: the scaling matrix to apply
++ */
++static void
++_scaled_fill_xrender_bitmap( FT_Bitmap* target,
++ FT_Bitmap* source,
++ const FT_Matrix* matrix )
++{
++ unsigned char* src_buf = source->buffer;
++ unsigned char* dst_line = target->buffer;
++ int src_pitch = source->pitch;
++ int width = target->width;
++ int height = target->rows;
++ int pitch = target->pitch;
++ int h;
++ FT_Vector vector;
++ FT_Matrix inverse = *matrix;
++ int sampling_width;
++ int sampling_height;
++ int sample_count;
++
++ if ( src_pitch < 0 )
++ src_buf -= src_pitch * (source->rows - 1);
++
++ FT_Matrix_Invert(&inverse);
++
++ /* compute how many source pixels a target pixel spans */
++ vector.x = 1;
++ vector.y = 1;
++ FT_Vector_Transform(&vector, &inverse);
++ sampling_width = vector.x / 2;
++ sampling_height = vector.y / 2;
++ sample_count = (2 * sampling_width + 1) * (2 * sampling_height + 1);
++
++ for ( h = height; h > 0; h--, dst_line += pitch )
++ {
++ int x;
++
++ for ( x = 0; x < width; x++ )
++ {
++ unsigned char* src;
++
++#define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
++
++ /* compute target pixel location in source space */
++ vector.x = (x * 0x10000) + 0x10000 / 2;
++ vector.y = ((height - h) * 0x10000) + 0x10000 / 2;
++ FT_Vector_Transform(&vector, &inverse);
++ vector.x = CLAMP(FT_RoundFix(vector.x) / 0x10000, 0, source->width - 1);
++ vector.y = CLAMP(FT_RoundFix(vector.y) / 0x10000, 0, source->rows - 1);
++
++ switch ( source->pixel_mode )
++ {
++ case FT_PIXEL_MODE_MONO: /* convert mono to 8-bit gray, scale using nearest pixel */
++ src = src_buf + (vector.y * src_pitch);
++ if ( src[(vector.x >> 3)] & (0x80 >> (vector.x & 7)) )
++ dst_line[x] = 0xff;
++ break;
++
++ case FT_PIXEL_MODE_GRAY: /* scale using nearest pixel */
++ src = src_buf + (vector.y * src_pitch);
++ dst_line[x] = src[vector.x];
++ break;
++
++ case FT_PIXEL_MODE_BGRA: /* scale by averaging all relevant source pixels, keep BGRA format */
++ {
++ int sample_x, sample_y;
++ int bgra[4] = {};
++ for (sample_y = - sampling_height; sample_y < sampling_height + 1; ++sample_y)
++ {
++ int src_y = CLAMP(vector.y + sample_y, 0, source->rows - 1);
++ src = src_buf + (src_y * src_pitch);
++ for (sample_x = - sampling_width; sample_x < sampling_width + 1; ++sample_x)
++ {
++ int src_x = CLAMP(vector.x + sample_x, 0, source->width - 1);
++ for (int i = 0; i < 4; ++i)
++ bgra[i] += src[src_x * 4 + i];
++ }
++ }
++
++ for (int i = 0; i < 4; ++i)
++ dst_line[4 * x + i] = bgra[i] / sample_count;
++ break;
++ }
++ }
++ }
++ }
++}
++
+ /* this functions converts the glyph bitmap found in a FT_GlyphSlot
+ * into a different format (see _compute_xrender_bitmap_size)
+ *
+@@ -244,6 +361,11 @@ _fill_xrender_bitmap( FT_Bitmap* target,
+ }
+ break;
+
++ case FT_PIXEL_MODE_BGRA: /* Preserve BGRA format */
++ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
++ memcpy( dstLine, srcLine, width * 4 );
++ break;
++
+ case FT_PIXEL_MODE_LCD:
+ if ( !bgr )
+ {
+@@ -339,6 +461,55 @@ _fill_xrender_bitmap( FT_Bitmap* target,
+ }
+ }
+
++/* This function creates a Picture for the given glyph on the default root window
++ * It will only work in Xinerama mode
++ *
++ * dpy :: target display
++ *
++ * format :: target pixmap format
++ *
++ * width :: picture width
++ *
++ * width :: picture height
++ *
++ * data :: bitmap data
++ *
++ */
++static Picture
++_create_glyph_bgra_picture (Display *dpy,
++ XRenderPictFormat *format,
++ int width,
++ int height,
++ unsigned char *data)
++{
++ XImage image = {
++ width, height, 0, ZPixmap, (char *)data,
++ dpy->byte_order, dpy->bitmap_unit, dpy->bitmap_bit_order, 32,
++ 32, 0, 32,
++ 0, 0, 0
++ };
++ Picture picture;
++ Pixmap pixmap;
++ GC gc;
++
++ pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, 32);
++ if (!pixmap)
++ return None;
++
++ gc = XCreateGC(dpy, pixmap, 0, NULL);
++ if (!gc)
++ return None;
++
++ XInitImage(&image);
++ XPutImage(dpy, pixmap, gc, &image, 0, 0, 0, 0, width, height);
++ picture = XRenderCreatePicture(dpy, pixmap, format, 0, NULL);
++
++ XFreeGC(dpy, gc);
++ XFreePixmap(dpy, pixmap);
++
++ return picture;
++}
++
+ _X_EXPORT void
+ XftFontLoadGlyphs (Display *dpy,
+ XftFont *pub,
+@@ -365,6 +536,8 @@ XftFontLoadGlyphs (Display *dpy,
+ FT_Vector vector;
+ FT_Face face;
+ FT_Render_Mode mode = FT_RENDER_MODE_MONO;
++ FcBool transform;
++ FcBool glyph_transform;
+
+ if (!info)
+ return;
+@@ -374,6 +547,8 @@ XftFontLoadGlyphs (Display *dpy,
+ if (!face)
+ return;
+
++ if (font->info.color)
++ mode = FT_RENDER_MODE_NORMAL;
+ if (font->info.antialias)
+ {
+ switch (font->info.rgba) {
+@@ -390,6 +565,8 @@ XftFontLoadGlyphs (Display *dpy,
+ }
+ }
+
++ transform = font->info.transform && mode != FT_RENDER_MODE_MONO;
++
+ while (nglyph--)
+ {
+ glyphindex = *glyphs++;
+@@ -440,7 +617,7 @@ XftFontLoadGlyphs (Display *dpy,
+ /*
+ * Compute glyph metrics from FreeType information
+ */
+- if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
++ if (transform)
+ {
+ /*
+ * calculate the true width by transforming all four corners.
+@@ -487,7 +664,7 @@ XftFontLoadGlyphs (Display *dpy,
+ * Clip charcell glyphs to the bounding box
+ * XXX transformed?
+ */
+- if (font->info.spacing >= FC_CHARCELL && !font->info.transform)
++ if (font->info.spacing >= FC_CHARCELL && !transform)
+ {
+ if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
+ {
+@@ -519,18 +696,20 @@ XftFontLoadGlyphs (Display *dpy,
+ }
+ }
+
++ glyph_transform = transform;
+ if ( glyphslot->format != FT_GLYPH_FORMAT_BITMAP )
+ {
+ error = FT_Render_Glyph( face->glyph, mode );
+ if (error)
+ continue;
++ glyph_transform = False;
+ }
+
+ FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_NONE );
+
+ if (font->info.spacing >= FC_MONO)
+ {
+- if (font->info.transform)
++ if (transform)
+ {
+ if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
+ {
+@@ -613,14 +792,27 @@ XftFontLoadGlyphs (Display *dpy,
+ }
+ }
+
+- size = _compute_xrender_bitmap_size( &local, glyphslot, mode );
++ size = _compute_xrender_bitmap_size( &local, glyphslot, mode, glyph_transform ? &font->info.matrix : NULL );
+ if ( size < 0 )
+ continue;
+
+ xftg->metrics.width = (unsigned short)local.width;
+ xftg->metrics.height = (unsigned short)local.rows;
+- xftg->metrics.x = (short)(- glyphslot->bitmap_left);
+- xftg->metrics.y = (short)( glyphslot->bitmap_top);
++ if (transform)
++ {
++ vector.x = - glyphslot->bitmap_left;
++ vector.y = glyphslot->bitmap_top;
++
++ FT_Vector_Transform(&vector, &font->info.matrix);
++
++ xftg->metrics.x = (short)vector.x;
++ xftg->metrics.y = (short)vector.y;
++ }
++ else
++ {
++ xftg->metrics.x = (short)(- glyphslot->bitmap_left);
++ xftg->metrics.y = (short)( glyphslot->bitmap_top);
++ }
+
+ /*
+ * If the glyph is relatively large (> 1% of server memory),
+@@ -645,9 +837,12 @@ XftFontLoadGlyphs (Display *dpy,
+
+ local.buffer = bufBitmap;
+
+- _fill_xrender_bitmap( &local, glyphslot, mode,
+- (font->info.rgba == FC_RGBA_BGR ||
+- font->info.rgba == FC_RGBA_VBGR ) );
++ if (mode == FT_RENDER_MODE_NORMAL && glyph_transform)
++ _scaled_fill_xrender_bitmap(&local, &glyphslot->bitmap, &font->info.matrix);
++ else
++ _fill_xrender_bitmap( &local, glyphslot, mode,
++ (font->info.rgba == FC_RGBA_BGR ||
++ font->info.rgba == FC_RGBA_VBGR ) );
+
+ /*
+ * Copy or convert into local buffer.
+@@ -662,6 +857,7 @@ XftFontLoadGlyphs (Display *dpy,
+ */
+ glyph = (Glyph) glyphindex;
+
++ xftg->picture = 0;
+ xftg->glyph_memory = (size_t)size + sizeof (XftGlyph);
+ if (font->format)
+ {
+@@ -685,15 +881,21 @@ XftFontLoadGlyphs (Display *dpy,
+ }
+ }
+ }
+- else if ( mode != FT_RENDER_MODE_NORMAL )
++ else if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA || mode != FT_RENDER_MODE_NORMAL)
+ {
+ /* invert ARGB <=> BGRA */
+ if (ImageByteOrder (dpy) != XftNativeByteOrder ())
+ XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
+ }
+- XRenderAddGlyphs (dpy, font->glyphset, &glyph,
+- &xftg->metrics, 1,
+- (char *) bufBitmap, size);
++
++ if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
++ xftg->picture = _create_glyph_bgra_picture(dpy, font->format,
++ local.width, local.rows,
++ bufBitmap);
++ else
++ XRenderAddGlyphs (dpy, font->glyphset, &glyph,
++ &xftg->metrics, 1,
++ (char *) bufBitmap, size);
+ }
+ else
+ {
+@@ -744,7 +946,9 @@ XftFontUnloadGlyphs (Display *dpy,
+ {
+ if (font->format)
+ {
+- if (font->glyphset)
++ if (xftg->picture)
++ XRenderFreePicture(dpy, xftg->picture);
++ else if (font->glyphset)
+ {
+ glyphBuf[nused++] = (Glyph) glyphindex;
+ if (nused == sizeof (glyphBuf) / sizeof (glyphBuf[0]))
+diff --git a/src/xftint.h b/src/xftint.h
+index ced9a02..1af40fe 100644
+--- a/src/xftint.h
++++ b/src/xftint.h
+@@ -85,6 +85,7 @@ typedef struct _XftGlyph {
+ XGlyphInfo metrics;
+ void *bitmap;
+ unsigned long glyph_memory;
++ Picture picture;
+ } XftGlyph;
+
+ /*
+@@ -134,6 +135,7 @@ struct _XftFontInfo {
+ FT_F26Dot6 xsize, ysize; /* pixel size */
+ FcBool antialias; /* doing antialiasing */
+ FcBool embolden; /* force emboldening */
++ FcBool color; /* contains color glyphs */
+ int rgba; /* subpixel order */
+ int lcd_filter; /* lcd filter */
+ FT_Matrix matrix; /* glyph transformation matrix */
+diff --git a/src/xftrender.c b/src/xftrender.c
+index 5852b2e..bd001be 100644
+--- a/src/xftrender.c
++++ b/src/xftrender.c
+@@ -84,12 +84,14 @@ XftGlyphRender (Display *dpy,
+ int nglyphs)
+ {
+ XftFontInt *font = (XftFontInt *) pub;
+- int i;
++ int i, j;
+ FT_UInt missing[XFT_NMISSING];
+ int nmissing;
+ FT_UInt g, max;
+ int size, width;
++ int dstx, dsty;
+ Glyph wire;
++ XftGlyph* glyph;
+ char *char8;
+ unsigned short *char16;
+ unsigned int *char32;
+@@ -141,22 +143,46 @@ XftGlyphRender (Display *dpy,
+ if (!chars)
+ goto bail1;
+ }
++ dstx = x;
++ dsty = y;
+ char8 = (char *) chars;
+ char16 = (unsigned short *) chars;
+ char32 = (unsigned int *) chars;
+- for (i = 0; i < nglyphs; i++)
++ for (i = 0, j = 0; i < nglyphs; i++)
+ {
+ wire = (Glyph) glyphs[i];
+ if (wire >= font->num_glyphs || !font->glyphs[wire])
+ wire = 0;
+- switch (width) {
+- case 1: char8[i] = (char) wire; break;
+- case 2: char16[i] = (unsigned short) wire; break;
+- case 4: char32[i] = (unsigned int) wire; break;
++ glyph = font->glyphs[wire];
++ if (glyph->picture)
++ {
++ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset,
++ srcx, srcy, x, y, width, chars, j);
++ XRenderComposite(dpy, PictOpOver, glyph->picture, None,
++ dst, 0, 0, 0, 0, dstx, dsty - glyph->metrics.y,
++ glyph->metrics.width, glyph->metrics.height);
++
++ dstx += glyph->metrics.xOff;
++ dsty += glyph->metrics.yOff;
++
++ x = dstx;
++ y = dsty;
++ j = 0;
++ }
++ else
++ {
++ switch (width) {
++ case 1: char8[j] = (char) wire; break;
++ case 2: char16[j] = (unsigned short) wire; break;
++ case 4: char32[j] = (unsigned int) wire; break;
++ }
++ dstx += glyph->metrics.xOff;
++ dsty += glyph->metrics.yOff;
++ ++j;
+ }
+ }
+ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset,
+- srcx, srcy, x, y, width, chars, nglyphs);
++ srcx, srcy, x, y, width, chars, j);
+ if (chars != char_local)
+ free (chars);
+ bail1:
+@@ -319,9 +345,10 @@ XftGlyphSpecRender (Display *dpy,
+ g = 0;
+ /*
+ * check to see if the glyph is placed where it would
+- * fall using the normal spacing
++ * fall using the normal spacing and if it would render
++ * as a XRender glyph
+ */
+- if ((glyph = font->glyphs[g]))
++ if ((glyph = font->glyphs[g]) && !glyph->picture)
+ {
+ if (x != glyphs[i].x || y != glyphs[i].y)
+ {
+@@ -335,7 +362,7 @@ XftGlyphSpecRender (Display *dpy,
+ }
+
+ elts = elts_local;
+- if (nelt > NUM_ELT_LOCAL)
++ if (!font->info.color && nelt > NUM_ELT_LOCAL)
+ {
+ elts = malloc ((size_t)nelt * sizeof (XGlyphElt8));
+ if (!elts)
+@@ -343,7 +370,7 @@ XftGlyphSpecRender (Display *dpy,
+ }
+
+ /*
+- * Generate the list of glyph elts
++ * Generate the list of glyph elts or render color glyphs
+ */
+ nelt = 0;
+ x = y = 0;
+@@ -357,6 +384,14 @@ XftGlyphSpecRender (Display *dpy,
+ g = 0;
+ if ((glyph = font->glyphs[g]))
+ {
++ if (glyph->picture)
++ {
++ XRenderComposite(dpy, PictOpOver, glyph->picture, None,
++ dst, 0, 0, 0, 0,
++ glyphs[i].x, glyphs[i].y - glyph->metrics.y,
++ glyph->metrics.width, glyph->metrics.height);
++ continue;
++ }
+ if (!i || x != glyphs[i].x || y != glyphs[i].y)
+ {
+ if (n)
+@@ -589,7 +624,7 @@ XftGlyphFontSpecRender (Display *dpy,
+ * check to see if the glyph is placed where it would
+ * fall using the normal spacing
+ */
+- if ((glyph = font->glyphs[g]))
++ if ((glyph = font->glyphs[g]) && !glyph->picture)
+ {
+ if (pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
+ {
+@@ -614,7 +649,7 @@ XftGlyphFontSpecRender (Display *dpy,
+ }
+
+ /*
+- * Generate the list of glyph elts
++ * Generate the list of glyph elts and render color glyphs
+ */
+ nelt = 0;
+ x = y = 0;
+@@ -632,6 +667,14 @@ XftGlyphFontSpecRender (Display *dpy,
+ g = 0;
+ if ((glyph = font->glyphs[g]))
+ {
++ if (glyph->picture)
++ {
++ XRenderComposite(dpy, PictOpOver, glyph->picture, None,
++ dst, 0, 0, 0, 0,
++ glyphs[i].x, glyphs[i].y - glyph->metrics.y,
++ glyph->metrics.width, glyph->metrics.height);
++ continue;
++ }
+ if (!i || pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
+ {
+ if (n)
+--
+GitLab
+
diff --git a/profiles/eug-vs/patches/x11-misc/dmenu/0001-chore-remove-config.h-on-clean.patch b/profiles/eug-vs/patches/x11-misc/dmenu/0001-chore-remove-config.h-on-clean.patch
new file mode 100644
index 0000000..c0a2a76
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-misc/dmenu/0001-chore-remove-config.h-on-clean.patch
@@ -0,0 +1,25 @@
+From 4005d1054e2df8919e3e2a76ecda61fb4dda43e0 Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Wed, 19 Jan 2022 00:38:19 +0300
+Subject: [PATCH 1/4] chore: remove config.h on clean
+
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index a03a95c..fe864c3 100644
+--- a/Makefile
++++ b/Makefile
+@@ -29,7 +29,7 @@ stest: stest.o
+ $(CC) -o $@ stest.o $(LDFLAGS)
+
+ clean:
+- rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz
++ rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz config.h
+
+ dist: clean
+ mkdir -p dmenu-$(VERSION)
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-misc/dmenu/0002-feat-use-Fira-Code-and-gruvbox-cyan.patch b/profiles/eug-vs/patches/x11-misc/dmenu/0002-feat-use-Fira-Code-and-gruvbox-cyan.patch
new file mode 100644
index 0000000..b8179c8
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-misc/dmenu/0002-feat-use-Fira-Code-and-gruvbox-cyan.patch
@@ -0,0 +1,33 @@
+From b3d2fb0ce001a3fe69bd469613073672f8c935b6 Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Wed, 19 Jan 2022 00:38:44 +0300
+Subject: [PATCH 2/4] feat: use Fira Code and gruvbox cyan
+
+---
+ config.def.h | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1edb647..fe9f5f0 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,14 +3,12 @@
+
+ static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
+ /* -fn option overrides fonts[0]; default X11 font or font set */
+-static const char *fonts[] = {
+- "monospace:size=10"
+-};
++static const char *fonts[] = { "fira code nerd font:pixelsize=12:antialias=true:autohint=true" };
+ static const char *prompt = NULL; /* -p option; prompt to the left of input field */
+ static const char *colors[SchemeLast][2] = {
+ /* fg bg */
+ [SchemeNorm] = { "#bbbbbb", "#222222" },
+- [SchemeSel] = { "#eeeeee", "#005577" },
++ [SchemeSel] = { "#eeeeee", "#689d6a" },
+ [SchemeOut] = { "#000000", "#00ffff" },
+ };
+ /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-misc/dmenu/0003-feat-use-gray-background.patch b/profiles/eug-vs/patches/x11-misc/dmenu/0003-feat-use-gray-background.patch
new file mode 100644
index 0000000..7d3ce7a
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-misc/dmenu/0003-feat-use-gray-background.patch
@@ -0,0 +1,25 @@
+From da5301964aba42e48e15fb7c95614f2fd7e8fed3 Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Sat, 16 Apr 2022 15:57:50 +0300
+Subject: [PATCH 3/4] feat: use gray background
+
+---
+ config.def.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/config.def.h b/config.def.h
+index fe9f5f0..c93f056 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -8,7 +8,7 @@ static const char *prompt = NULL; /* -p option; prompt to the left of
+ static const char *colors[SchemeLast][2] = {
+ /* fg bg */
+ [SchemeNorm] = { "#bbbbbb", "#222222" },
+- [SchemeSel] = { "#eeeeee", "#689d6a" },
++ [SchemeSel] = { "#eeeeee", "#928374" },
+ [SchemeOut] = { "#000000", "#00ffff" },
+ };
+ /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-misc/dmenu/0004-feat-use-classic-background.patch b/profiles/eug-vs/patches/x11-misc/dmenu/0004-feat-use-classic-background.patch
new file mode 100644
index 0000000..59a5918
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-misc/dmenu/0004-feat-use-classic-background.patch
@@ -0,0 +1,25 @@
+From 76039705e8a053cea0ba927a81053cf4fae37a24 Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Mon, 18 Apr 2022 21:28:35 +0300
+Subject: [PATCH 4/4] feat!: use classic background
+
+---
+ config.def.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/config.def.h b/config.def.h
+index c93f056..eb8dc64 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -8,7 +8,7 @@ static const char *prompt = NULL; /* -p option; prompt to the left of
+ static const char *colors[SchemeLast][2] = {
+ /* fg bg */
+ [SchemeNorm] = { "#bbbbbb", "#222222" },
+- [SchemeSel] = { "#eeeeee", "#928374" },
++ [SchemeSel] = { "#eeeeee", "#005577" },
+ [SchemeOut] = { "#000000", "#00ffff" },
+ };
+ /* -l option; if nonzero, dmenu uses vertical list with given number of lines */
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0001-feat-change-MOD-to-SUPER.patch b/profiles/eug-vs/patches/x11-wm/dwm/0001-feat-change-MOD-to-SUPER.patch
new file mode 100644
index 0000000..7d5b27e
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0001-feat-change-MOD-to-SUPER.patch
@@ -0,0 +1,29 @@
+From d458f4d04c1acabeccbcf076f75ecc9ac0e7b89b Mon Sep 17 00:00:00 2001
+From: eug-vs <eug-vs@keemail.me>
+Date: Sat, 27 Mar 2021 14:08:46 +0300
+Subject: [PATCH 01/15] feat: change MOD to SUPER
+
+---
+ config.def.h => config.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+ rename config.def.h => config.h (99%)
+
+diff --git a/config.def.h b/config.h
+similarity index 99%
+rename from config.def.h
+rename to config.h
+index a2ac963..7c1d880 100644
+--- a/config.def.h
++++ b/config.h
+@@ -45,7 +45,7 @@ static const Layout layouts[] = {
+ };
+
+ /* key definitions */
+-#define MODKEY Mod1Mask
++#define MODKEY Mod4Mask
+ #define TAGKEYS(KEY,TAG) \
+ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
+ { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0002-feat-remove-config.h-on-clean-install.patch b/profiles/eug-vs/patches/x11-wm/dwm/0002-feat-remove-config.h-on-clean-install.patch
new file mode 100644
index 0000000..908b403
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0002-feat-remove-config.h-on-clean-install.patch
@@ -0,0 +1,25 @@
+From 3428deb37ae13d50ebcfc28120a29357a638bc37 Mon Sep 17 00:00:00 2001
+From: eug-vs <eug-vs@keemail.me>
+Date: Sat, 27 Mar 2021 14:23:26 +0300
+Subject: [PATCH 02/15] feat: remove config.h on clean install
+
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index 77bcbc0..c05dbdd 100644
+--- a/Makefile
++++ b/Makefile
+@@ -26,7 +26,7 @@ dwm: ${OBJ}
+ ${CC} -o $@ ${OBJ} ${LDFLAGS}
+
+ clean:
+- rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
++ rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz config.h
+
+ dist: clean
+ mkdir -p dwm-${VERSION}
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0003-feat-only-use-config.def.h.patch b/profiles/eug-vs/patches/x11-wm/dwm/0003-feat-only-use-config.def.h.patch
new file mode 100644
index 0000000..49dc81b
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0003-feat-only-use-config.def.h.patch
@@ -0,0 +1,38 @@
+From 3d3a54f278bf5c22b3ead64039b50d1ad187e9f6 Mon Sep 17 00:00:00 2001
+From: eug-vs <eug-vs@keemail.me>
+Date: Sat, 27 Mar 2021 14:23:55 +0300
+Subject: [PATCH 03/15] feat: only use config.def.h
+
+---
+ config.h => config.def.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+ rename config.h => config.def.h (95%)
+
+diff --git a/config.h b/config.def.h
+similarity index 95%
+rename from config.h
+rename to config.def.h
+index 7c1d880..c3e0dbc 100644
+--- a/config.h
++++ b/config.def.h
+@@ -2,6 +2,7 @@
+
+ /* appearance */
+ static const unsigned int borderpx = 1; /* border pixel of windows */
++static const unsigned int gappx = 5; /* gaps between windows */
+ static const unsigned int snap = 32; /* snap pixel */
+ static const int showbar = 1; /* 0 means no bar */
+ static const int topbar = 1; /* 0 means bottom bar */
+@@ -85,6 +86,9 @@ static Key keys[] = {
+ { MODKEY, XK_period, focusmon, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
++ { MODKEY, XK_minus, setgaps, {.i = -1 } },
++ { MODKEY, XK_equal, setgaps, {.i = +1 } },
++ { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } },
+ TAGKEYS( XK_1, 0)
+ TAGKEYS( XK_2, 1)
+ TAGKEYS( XK_3, 2)
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0004-feat-bind-exit-to-E-and-kill-client-to-Q.patch b/profiles/eug-vs/patches/x11-wm/dwm/0004-feat-bind-exit-to-E-and-kill-client-to-Q.patch
new file mode 100644
index 0000000..af9f866
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0004-feat-bind-exit-to-E-and-kill-client-to-Q.patch
@@ -0,0 +1,34 @@
+From cb19e80b91882242475a0d48e0faf0eb44f898f3 Mon Sep 17 00:00:00 2001
+From: eug-vs <eug-vs@keemail.me>
+Date: Sat, 27 Mar 2021 16:06:46 +0300
+Subject: [PATCH 04/15] feat: bind exit to E and kill-client to Q
+
+---
+ config.def.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index c3e0dbc..d89961f 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -74,7 +74,7 @@ static Key keys[] = {
+ { MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY, XK_Return, zoom, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+- { MODKEY|ShiftMask, XK_c, killclient, {0} },
++ { MODKEY|ShiftMask, XK_q, killclient, {0} },
+ { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
+ { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+@@ -98,7 +98,7 @@ static Key keys[] = {
+ TAGKEYS( XK_7, 6)
+ TAGKEYS( XK_8, 7)
+ TAGKEYS( XK_9, 8)
+- { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY|ShiftMask, XK_e, quit, {0} },
+ };
+
+ /* button definitions */
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0005-feat-apply-swallow-patch.patch b/profiles/eug-vs/patches/x11-wm/dwm/0005-feat-apply-swallow-patch.patch
new file mode 100644
index 0000000..a950cb5
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0005-feat-apply-swallow-patch.patch
@@ -0,0 +1,377 @@
+From ea694dbab24d8628f57821fb07d13e6f93571f6c Mon Sep 17 00:00:00 2001
+From: eug-vs <eug-vs@keemail.me>
+Date: Sat, 27 Mar 2021 21:40:35 +0300
+Subject: [PATCH 05/15] feat: apply swallow patch
+
+---
+ config.mk | 2 +-
+ dwm.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 190 insertions(+), 9 deletions(-)
+
+diff --git a/config.mk b/config.mk
+index b6eb7e0..2960227 100644
+--- a/config.mk
++++ b/config.mk
+@@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2
+
+ # includes and libs
+ INCS = -I${X11INC} -I${FREETYPEINC}
+-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
++LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res
+
+ # flags
+ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+diff --git a/dwm.c b/dwm.c
+index a96f33c..1c2dd11 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -40,6 +40,8 @@
+ #include <X11/extensions/Xinerama.h>
+ #endif /* XINERAMA */
+ #include <X11/Xft/Xft.h>
++#include <X11/Xlib-xcb.h>
++#include <xcb/res.h>
+
+ #include "drw.h"
+ #include "util.h"
+@@ -92,9 +94,11 @@ struct Client {
+ int basew, baseh, incw, inch, maxw, maxh, minw, minh;
+ int bw, oldbw;
+ unsigned int tags;
+- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
++ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow;
++ pid_t pid;
+ Client *next;
+ Client *snext;
++ Client *swallowing;
+ Monitor *mon;
+ Window win;
+ };
+@@ -138,6 +142,8 @@ typedef struct {
+ const char *title;
+ unsigned int tags;
+ int isfloating;
++ int isterminal;
++ int noswallow;
+ int monitor;
+ } Rule;
+
+@@ -169,6 +175,7 @@ static void focus(Client *c);
+ static void focusin(XEvent *e);
+ static void focusmon(const Arg *arg);
+ static void focusstack(const Arg *arg);
++static pid_t getparentprocess(pid_t p);
+ static Atom getatomprop(Client *c, Atom prop);
+ static int getrootptr(int *x, int *y);
+ static long getstate(Window w);
+@@ -176,6 +183,7 @@ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
+ static void grabbuttons(Client *c, int focused);
+ static void grabkeys(void);
+ static void incnmaster(const Arg *arg);
++static int isdescprocess(pid_t p, pid_t c);
+ static void keypress(XEvent *e);
+ static void killclient(const Arg *arg);
+ static void manage(Window w, XWindowAttributes *wa);
+@@ -207,8 +215,10 @@ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
++static Client *swallowingclient(Window w);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
++static Client *termforwin(const Client *c);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
+@@ -228,6 +238,7 @@ static void updatetitle(Client *c);
+ static void updatewindowtype(Client *c);
+ static void updatewmhints(Client *c);
+ static void view(const Arg *arg);
++static pid_t winpid(Window w);
+ static Client *wintoclient(Window w);
+ static Monitor *wintomon(Window w);
+ static int xerror(Display *dpy, XErrorEvent *ee);
+@@ -269,6 +280,8 @@ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
+
++static xcb_connection_t *xcon;
++
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+
+@@ -298,6 +311,7 @@ applyrules(Client *c)
+ && (!r->class || strstr(class, r->class))
+ && (!r->instance || strstr(instance, r->instance)))
+ {
++ c->isterminal = r->isterminal;
+ c->isfloating = r->isfloating;
+ c->tags |= r->tags;
+ for (m = mons; m && m->num != r->monitor; m = m->next);
+@@ -414,6 +428,47 @@ attachstack(Client *c)
+ c->mon->stack = c;
+ }
+
++void
++swallow(Client *p, Client *c)
++{
++ if (c->noswallow || c->isterminal)
++ return;
++
++ detach(c);
++ detachstack(c);
++
++ setclientstate(c, WithdrawnState);
++ XUnmapWindow(dpy, p->win);
++
++ p->swallowing = c;
++ c->mon = p->mon;
++
++ Window w = p->win;
++ p->win = c->win;
++ c->win = w;
++ updatetitle(p);
++ arrange(p->mon);
++ XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h);
++ configure(p);
++ updateclientlist();
++}
++
++void
++unswallow(Client *c)
++{
++ c->win = c->swallowing->win;
++
++ free(c->swallowing);
++ c->swallowing = NULL;
++
++ updatetitle(c);
++ arrange(c->mon);
++ XMapWindow(dpy, c->win);
++ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
++ configure(c);
++ setclientstate(c, NormalState);
++}
++
+ void
+ buttonpress(XEvent *e)
+ {
+@@ -479,7 +534,7 @@ cleanup(void)
+ selmon->lt[selmon->sellt] = &foo;
+ for (m = mons; m; m = m->next)
+ while (m->stack)
+- unmanage(m->stack, 0);
++ unmanage(m->stack, 0); // XXX - unmanage swallowing windows too
+ XUngrabKey(dpy, AnyKey, AnyModifier, root);
+ while (mons)
+ cleanupmon(mons);
+@@ -653,6 +708,9 @@ destroynotify(XEvent *e)
+
+ if ((c = wintoclient(ev->window)))
+ unmanage(c, 1);
++
++ else if ((c = swallowingclient(ev->window)))
++ unmanage(c->swallowing, 1);
+ }
+
+ void
+@@ -1021,12 +1079,13 @@ killclient(const Arg *arg)
+ void
+ manage(Window w, XWindowAttributes *wa)
+ {
+- Client *c, *t = NULL;
++ Client *c, *t = NULL, *term = NULL;
+ Window trans = None;
+ XWindowChanges wc;
+
+ c = ecalloc(1, sizeof(Client));
+ c->win = w;
++ c->pid = winpid(w);
+ /* geometry */
+ c->x = c->oldx = wa->x;
+ c->y = c->oldy = wa->y;
+@@ -1041,6 +1100,7 @@ manage(Window w, XWindowAttributes *wa)
+ } else {
+ c->mon = selmon;
+ applyrules(c);
++ term = termforwin(c);
+ }
+
+ if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
+@@ -1077,6 +1137,8 @@ manage(Window w, XWindowAttributes *wa)
+ c->mon->sel = c;
+ arrange(c->mon);
+ XMapWindow(dpy, c->win);
++ if (term)
++ swallow(term, c);
+ focus(NULL);
+ }
+
+@@ -1771,6 +1833,20 @@ unmanage(Client *c, int destroyed)
+ Monitor *m = c->mon;
+ XWindowChanges wc;
+
++ if (c->swallowing) {
++ unswallow(c);
++ return;
++ }
++
++ Client *s = swallowingclient(c->win);
++ if (s) {
++ free(s->swallowing);
++ s->swallowing = NULL;
++ arrange(m);
++ focus(NULL);
++ return;
++ }
++
+ detach(c);
+ detachstack(c);
+ if (!destroyed) {
+@@ -1785,9 +1861,12 @@ unmanage(Client *c, int destroyed)
+ XUngrabServer(dpy);
+ }
+ free(c);
+- focus(NULL);
+- updateclientlist();
+- arrange(m);
++
++ if (!s) {
++ arrange(m);
++ focus(NULL);
++ updateclientlist();
++ }
+ }
+
+ void
+@@ -2050,16 +2129,116 @@ view(const Arg *arg)
+ arrange(selmon);
+ }
+
++pid_t
++winpid(Window w)
++{
++ pid_t result = 0;
++
++ xcb_res_client_id_spec_t spec = {0};
++ spec.client = w;
++ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
++
++ xcb_generic_error_t *e = NULL;
++ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec);
++ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
++
++ if (!r)
++ return (pid_t)0;
++
++ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
++ for (; i.rem; xcb_res_client_id_value_next(&i)) {
++ spec = i.data->spec;
++ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
++ uint32_t *t = xcb_res_client_id_value_value(i.data);
++ result = *t;
++ break;
++ }
++ }
++
++ free(r);
++
++ if (result == (pid_t)-1)
++ result = 0;
++ return result;
++}
++
++pid_t
++getparentprocess(pid_t p)
++{
++ unsigned int v = 0;
++
++#ifdef __linux__
++ FILE *f;
++ char buf[256];
++ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p);
++
++ if (!(f = fopen(buf, "r")))
++ return 0;
++
++ fscanf(f, "%*u %*s %*c %u", &v);
++ fclose(f);
++#endif /* __linux__ */
++
++ return (pid_t)v;
++}
++
++int
++isdescprocess(pid_t p, pid_t c)
++{
++ while (p != c && c != 0)
++ c = getparentprocess(c);
++
++ return (int)c;
++}
++
++Client *
++termforwin(const Client *w)
++{
++ Client *c;
++ Monitor *m;
++
++ if (!w->pid || w->isterminal)
++ return NULL;
++
++ for (m = mons; m; m = m->next) {
++ for (c = m->clients; c; c = c->next) {
++ if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid))
++ return c;
++ }
++ }
++
++ return NULL;
++}
++
++Client *
++swallowingclient(Window w)
++{
++ Client *c;
++ Monitor *m;
++
++ for (m = mons; m; m = m->next) {
++ for (c = m->clients; c; c = c->next) {
++ if (c->swallowing && c->swallowing->win == w)
++ return c;
++ }
++ }
++
++ return NULL;
++}
++
++
+ Client *
+ wintoclient(Window w)
+ {
+ Client *c;
+ Monitor *m;
+
+- for (m = mons; m; m = m->next)
+- for (c = m->clients; c; c = c->next)
++ for (m = mons; m; m = m->next) {
++ for (c = m->clients; c; c = c->next) {
+ if (c->win == w)
+ return c;
++ }
++ }
+ return NULL;
+ }
+
+@@ -2141,6 +2320,8 @@ main(int argc, char *argv[])
+ fputs("warning: no locale support\n", stderr);
+ if (!(dpy = XOpenDisplay(NULL)))
+ die("dwm: cannot open display");
++ if (!(xcon = XGetXCBConnection(dpy)))
++ die("dwm: cannot get xcb connection\n");
+ checkotherwm();
+ setup();
+ #ifdef __OpenBSD__
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0006-feat-swap-h-l-and-behavior.patch b/profiles/eug-vs/patches/x11-wm/dwm/0006-feat-swap-h-l-and-behavior.patch
new file mode 100644
index 0000000..df1917b
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0006-feat-swap-h-l-and-behavior.patch
@@ -0,0 +1,42 @@
+From 8ac957c1f697fe1972e86b25f1db7051a1287ebd Mon Sep 17 00:00:00 2001
+From: eug-vs <eug-vs@keemail.me>
+Date: Tue, 30 Mar 2021 10:30:55 +0300
+Subject: [PATCH 06/15] feat: swap h/l and >/< behavior
+
+---
+ config.def.h | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index d89961f..a04a85c 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -70,8 +70,8 @@ static Key keys[] = {
+ { MODKEY, XK_k, focusstack, {.i = -1 } },
+ { MODKEY, XK_i, incnmaster, {.i = +1 } },
+ { MODKEY, XK_d, incnmaster, {.i = -1 } },
+- { MODKEY, XK_h, setmfact, {.f = -0.05} },
+- { MODKEY, XK_l, setmfact, {.f = +0.05} },
++ { MODKEY, XK_comma, setmfact, {.f = -0.05} },
++ { MODKEY, XK_period, setmfact, {.f = +0.05} },
+ { MODKEY, XK_Return, zoom, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY|ShiftMask, XK_q, killclient, {0} },
+@@ -82,10 +82,10 @@ static Key keys[] = {
+ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
+- { MODKEY, XK_comma, focusmon, {.i = -1 } },
+- { MODKEY, XK_period, focusmon, {.i = +1 } },
+- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
+- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
++ { MODKEY, XK_h, focusmon, {.i = -1 } },
++ { MODKEY, XK_l, focusmon, {.i = +1 } },
++ { MODKEY|ShiftMask, XK_h, tagmon, {.i = -1 } },
++ { MODKEY|ShiftMask, XK_l, tagmon, {.i = +1 } },
+ { MODKEY, XK_minus, setgaps, {.i = -1 } },
+ { MODKEY, XK_equal, setgaps, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } },
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0007-feat-resize-on-MOD-r.patch b/profiles/eug-vs/patches/x11-wm/dwm/0007-feat-resize-on-MOD-r.patch
new file mode 100644
index 0000000..7c29d10
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0007-feat-resize-on-MOD-r.patch
@@ -0,0 +1,24 @@
+From c9cfcb6519b6f731bc0d3b77075eef7a81c9120a Mon Sep 17 00:00:00 2001
+From: eug-vs <eug-vs@keemail.me>
+Date: Thu, 15 Apr 2021 13:58:54 +0300
+Subject: [PATCH 07/15] feat: resize on MOD+r
+
+---
+ config.def.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/config.def.h b/config.def.h
+index a04a85c..b8d9510 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -86,6 +86,7 @@ static Key keys[] = {
+ { MODKEY, XK_l, focusmon, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_h, tagmon, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_l, tagmon, {.i = +1 } },
++ { MODKEY, XK_r, resizemouse, {0} },
+ { MODKEY, XK_minus, setgaps, {.i = -1 } },
+ { MODKEY, XK_equal, setgaps, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } },
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0008-feat-use-Fira-Code.patch b/profiles/eug-vs/patches/x11-wm/dwm/0008-feat-use-Fira-Code.patch
new file mode 100644
index 0000000..6f18046
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0008-feat-use-Fira-Code.patch
@@ -0,0 +1,83 @@
+From 11a83b5b8fb54a2d8decc454c15d198f18ef0022 Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Tue, 18 Jan 2022 23:56:01 +0300
+Subject: [PATCH 08/15] feat: use Fira Code
+
+---
+ config.def.h | 23 ++++++++---------------
+ dwm.c | 2 +-
+ 2 files changed, 9 insertions(+), 16 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index b8d9510..a5914c1 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -2,21 +2,18 @@
+
+ /* appearance */
+ static const unsigned int borderpx = 1; /* border pixel of windows */
+-static const unsigned int gappx = 5; /* gaps between windows */
+ static const unsigned int snap = 32; /* snap pixel */
+ static const int showbar = 1; /* 0 means no bar */
+ static const int topbar = 1; /* 0 means bottom bar */
+-static const char *fonts[] = { "monospace:size=10" };
+-static const char dmenufont[] = "monospace:size=10";
+-static const char col_gray1[] = "#222222";
+-static const char col_gray2[] = "#444444";
+-static const char col_gray3[] = "#bbbbbb";
+-static const char col_gray4[] = "#eeeeee";
+-static const char col_cyan[] = "#005577";
++static const char *fonts[] = { "fira code nerd font:pixelsize=12:antialias=true:autohint=true" };
++static const char col_background[] = "#1d2021";
++static const char col_foreground[] = "#ebdbb2";
++static const char col_primary[] = "#689d6a";
+ static const char *colors[][3] = {
+ /* fg bg border */
+- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
++ [SchemeNorm] = { col_foreground, col_background, "#000000" },
++ [SchemeSel] = { col_foreground, col_primary, col_primary },
++ [SchemeStatus] = { col_foreground, col_background, "#000000" },
+ };
+
+ /* tagging */
+@@ -58,7 +55,7 @@ static const Layout layouts[] = {
+
+ /* commands */
+ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
+-static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
++static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, NULL };
+ static const char *termcmd[] = { "st", NULL };
+
+ static Key keys[] = {
+@@ -87,9 +84,6 @@ static Key keys[] = {
+ { MODKEY|ShiftMask, XK_h, tagmon, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_l, tagmon, {.i = +1 } },
+ { MODKEY, XK_r, resizemouse, {0} },
+- { MODKEY, XK_minus, setgaps, {.i = -1 } },
+- { MODKEY, XK_equal, setgaps, {.i = +1 } },
+- { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } },
+ TAGKEYS( XK_1, 0)
+ TAGKEYS( XK_2, 1)
+ TAGKEYS( XK_3, 2)
+@@ -118,4 +112,3 @@ static Button buttons[] = {
+ { ClkTagBar, MODKEY, Button1, tag, {0} },
+ { ClkTagBar, MODKEY, Button3, toggletag, {0} },
+ };
+-
+diff --git a/dwm.c b/dwm.c
+index 1c2dd11..70d6fd9 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -61,7 +61,7 @@
+
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+-enum { SchemeNorm, SchemeSel }; /* color schemes */
++enum { SchemeNorm, SchemeSel, SchemeStatus }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0009-feat-apply-attachaside-patch.patch b/profiles/eug-vs/patches/x11-wm/dwm/0009-feat-apply-attachaside-patch.patch
new file mode 100644
index 0000000..dcd1d89
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0009-feat-apply-attachaside-patch.patch
@@ -0,0 +1,105 @@
+From c0c1de752e7b1daacbca4c580f1fa8661c50a09b Mon Sep 17 00:00:00 2001
+From: eug-vs <eug-vs@keemail.me>
+Date: Fri, 23 Jul 2021 14:29:16 +0300
+Subject: [PATCH 09/15] feat: apply attachaside patch
+
+Source: https://dwm.suckless.org/patches/attachaside/
+---
+ dwm.c | 32 ++++++++++++++++++++++++++++----
+ 1 file changed, 28 insertions(+), 4 deletions(-)
+
+diff --git a/dwm.c b/dwm.c
+index 70d6fd9..2d5a64d 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -51,7 +51,8 @@
+ #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
+ #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
+ * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
+-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
++#define ISVISIBLEONTAG(C, T) ((C->tags & T))
++#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
+ #define LENGTH(X) (sizeof X / sizeof X[0])
+ #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X) ((X)->w + 2 * (X)->bw)
+@@ -153,6 +154,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac
+ static void arrange(Monitor *m);
+ static void arrangemon(Monitor *m);
+ static void attach(Client *c);
++static void attachaside(Client *c);
+ static void attachstack(Client *c);
+ static void buttonpress(XEvent *e);
+ static void checkotherwm(void);
+@@ -192,6 +194,7 @@ static void maprequest(XEvent *e);
+ static void monocle(Monitor *m);
+ static void motionnotify(XEvent *e);
+ static void movemouse(const Arg *arg);
++static Client *nexttagged(Client *c);
+ static Client *nexttiled(Client *c);
+ static void pop(Client *);
+ static void propertynotify(XEvent *e);
+@@ -421,6 +424,17 @@ attach(Client *c)
+ c->mon->clients = c;
+ }
+
++void
++attachaside(Client *c) {
++ Client *at = nexttagged(c);
++ if(!at) {
++ attach(c);
++ return;
++ }
++ c->next = at->next;
++ at->next = c;
++}
++
+ void
+ attachstack(Client *c)
+ {
+@@ -1126,7 +1140,7 @@ manage(Window w, XWindowAttributes *wa)
+ c->isfloating = c->oldstate = trans != None || c->isfixed;
+ if (c->isfloating)
+ XRaiseWindow(dpy, c->win);
+- attach(c);
++ attachaside(c);
+ attachstack(c);
+ XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
+ (unsigned char *) &(c->win), 1);
+@@ -1258,6 +1272,16 @@ movemouse(const Arg *arg)
+ }
+ }
+
++Client *
++nexttagged(Client *c) {
++ Client *walked = c->mon->clients;
++ for(;
++ walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags));
++ walked = walked->next
++ );
++ return walked;
++}
++
+ Client *
+ nexttiled(Client *c)
+ {
+@@ -1483,7 +1507,7 @@ sendmon(Client *c, Monitor *m)
+ detachstack(c);
+ c->mon = m;
+ c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
+- attach(c);
++ attachaside(c);
+ attachstack(c);
+ focus(NULL);
+ arrange(NULL);
+@@ -1982,7 +2006,7 @@ updategeom(void)
+ m->clients = c->next;
+ detachstack(c);
+ c->mon = mons;
+- attach(c);
++ attachaside(c);
+ attachstack(c);
+ }
+ if (m == selmon)
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0010-feat-change-master-width-to-75.patch b/profiles/eug-vs/patches/x11-wm/dwm/0010-feat-change-master-width-to-75.patch
new file mode 100644
index 0000000..f396534
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0010-feat-change-master-width-to-75.patch
@@ -0,0 +1,25 @@
+From 71cc9e0fcfd02a665d0859888d2ab3e81d2bda2c Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Wed, 19 Jan 2022 00:29:04 +0300
+Subject: [PATCH 10/15] feat: change master width to 75%
+
+---
+ config.def.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/config.def.h b/config.def.h
+index a5914c1..dc10d22 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -30,7 +30,7 @@ static const Rule rules[] = {
+ };
+
+ /* layout(s) */
+-static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
++static const float mfact = 0.75; /* factor of master area size [0.05..0.95] */
+ static const int nmaster = 1; /* number of clients in master area */
+ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
+ static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0011-patch-actual-fullscreen.patch b/profiles/eug-vs/patches/x11-wm/dwm/0011-patch-actual-fullscreen.patch
new file mode 100644
index 0000000..2508f5a
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0011-patch-actual-fullscreen.patch
@@ -0,0 +1,66 @@
+From 4745e69489042e1b33f278809e1f9e831d6704b1 Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Thu, 20 Jan 2022 01:27:31 +0300
+Subject: [PATCH 11/15] patch: actual fullscreen
+
+---
+ config.def.h | 1 +
+ dwm.1 | 3 +++
+ dwm.c | 8 ++++++++
+ 3 files changed, 12 insertions(+)
+
+diff --git a/config.def.h b/config.def.h
+index dc10d22..b7d6205 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -75,6 +75,7 @@ static Key keys[] = {
+ { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
+ { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
+ { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
++ { MODKEY|ShiftMask, XK_m, togglefullscr, {0} },
+ { MODKEY, XK_space, setlayout, {0} },
+ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
+ { MODKEY, XK_0, view, {.ui = ~0 } },
+diff --git a/dwm.1 b/dwm.1
+index ddc8321..3d310ac 100644
+--- a/dwm.1
++++ b/dwm.1
+@@ -116,6 +116,9 @@ Zooms/cycles focused window to/from master area (tiled layouts only).
+ .B Mod1\-Shift\-c
+ Close focused window.
+ .TP
++.B Mod1\-Shift\-f
++Toggle fullscreen for focused window.
++.TP
+ .B Mod1\-Shift\-space
+ Toggle focused window between tiled and floating state.
+ .TP
+diff --git a/dwm.c b/dwm.c
+index 2d5a64d..ea4fa50 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -225,6 +225,7 @@ static Client *termforwin(const Client *c);
+ static void tile(Monitor *);
+ static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void togglefullscr(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -1811,6 +1812,13 @@ togglefloating(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++togglefullscr(const Arg *arg)
++{
++ if(selmon->sel)
++ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
++}
++
+ void
+ toggletag(const Arg *arg)
+ {
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0012-patch-systray.patch b/profiles/eug-vs/patches/x11-wm/dwm/0012-patch-systray.patch
new file mode 100644
index 0000000..04ecbf3
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0012-patch-systray.patch
@@ -0,0 +1,749 @@
+From c5298ee42bbf9dbec0b8d9dc2f57b1f260ea2b45 Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Thu, 20 Jan 2022 01:39:50 +0300
+Subject: [PATCH 12/15] patch: systray
+
+---
+ config.def.h | 5 +
+ dwm.c | 407 +++++++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 386 insertions(+), 26 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index b7d6205..2d2af1a 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,6 +3,11 @@
+ /* appearance */
+ static const unsigned int borderpx = 1; /* border pixel of windows */
+ static const unsigned int snap = 32; /* snap pixel */
++static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
++static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */
++static const unsigned int systrayspacing = 2; /* systray spacing */
++static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
++static const int showsystray = 1; /* 0 means no systray */
+ static const int showbar = 1; /* 0 means no bar */
+ static const int topbar = 1; /* 0 means bottom bar */
+ static const char *fonts[] = { "fira code nerd font:pixelsize=12:antialias=true:autohint=true" };
+diff --git a/dwm.c b/dwm.c
+index ea4fa50..83362ce 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -60,12 +60,30 @@
+ #define TAGMASK ((1 << LENGTH(tags)) - 1)
+ #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+
++#define SYSTEM_TRAY_REQUEST_DOCK 0
++
++/* XEMBED messages */
++#define XEMBED_EMBEDDED_NOTIFY 0
++#define XEMBED_WINDOW_ACTIVATE 1
++#define XEMBED_FOCUS_IN 4
++#define XEMBED_MODALITY_ON 10
++
++#define XEMBED_MAPPED (1 << 0)
++#define XEMBED_WINDOW_ACTIVATE 1
++#define XEMBED_WINDOW_DEACTIVATE 2
++
++#define VERSION_MAJOR 0
++#define VERSION_MINOR 0
++#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
++
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+ enum { SchemeNorm, SchemeSel, SchemeStatus }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
++ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
++enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
+ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
+ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
+ ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+@@ -148,6 +166,12 @@ typedef struct {
+ int monitor;
+ } Rule;
+
++typedef struct Systray Systray;
++struct Systray {
++ Window win;
++ Client *icons;
++};
++
+ /* function declarations */
+ static void applyrules(Client *c);
+ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
+@@ -181,6 +205,7 @@ static pid_t getparentprocess(pid_t p);
+ static Atom getatomprop(Client *c, Atom prop);
+ static int getrootptr(int *x, int *y);
+ static long getstate(Window w);
++static unsigned int getsystraywidth();
+ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
+ static void grabbuttons(Client *c, int focused);
+ static void grabkeys(void);
+@@ -200,13 +225,16 @@ static void pop(Client *);
+ static void propertynotify(XEvent *e);
+ static void quit(const Arg *arg);
+ static Monitor *recttomon(int x, int y, int w, int h);
++static void removesystrayicon(Client *i);
+ static void resize(Client *c, int x, int y, int w, int h, int interact);
++static void resizebarwin(Monitor *m);
+ static void resizeclient(Client *c, int x, int y, int w, int h);
+ static void resizemouse(const Arg *arg);
++static void resizerequest(XEvent *e);
+ static void restack(Monitor *m);
+ static void run(void);
+ static void scan(void);
+-static int sendevent(Client *c, Atom proto);
++static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
+ static void sendmon(Client *c, Monitor *m);
+ static void setclientstate(Client *c, long state);
+ static void setfocus(Client *c);
+@@ -218,6 +246,8 @@ static void seturgent(Client *c, int urg);
+ static void showhide(Client *c);
+ static void sigchld(int unused);
+ static void spawn(const Arg *arg);
++static Monitor *systraytomon(Monitor *m);
++static void mappingnotify(XEvent *e);
+ static Client *swallowingclient(Window w);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+@@ -238,6 +268,9 @@ static int updategeom(void);
+ static void updatenumlockmask(void);
+ static void updatesizehints(Client *c);
+ static void updatestatus(void);
++static void updatesystray(void);
++static void updatesystrayicongeom(Client *i, int w, int h);
++static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
+ static void updatetitle(Client *c);
+ static void updatewindowtype(Client *c);
+ static void updatewmhints(Client *c);
+@@ -245,12 +278,14 @@ static void view(const Arg *arg);
+ static pid_t winpid(Window w);
+ static Client *wintoclient(Window w);
+ static Monitor *wintomon(Window w);
++static Client *wintosystrayicon(Window w);
+ static int xerror(Display *dpy, XErrorEvent *ee);
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+ static void zoom(const Arg *arg);
+
+ /* variables */
++static Systray *systray = NULL;
+ static const char broken[] = "broken";
+ static char stext[256];
+ static int screen;
+@@ -273,9 +308,10 @@ static void (*handler[LASTEvent]) (XEvent *) = {
+ [MapRequest] = maprequest,
+ [MotionNotify] = motionnotify,
+ [PropertyNotify] = propertynotify,
++ [ResizeRequest] = resizerequest,
+ [UnmapNotify] = unmapnotify
+ };
+-static Atom wmatom[WMLast], netatom[NetLast];
++static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
+ static int running = 1;
+ static Cur *cursor[CurLast];
+ static Clr **scheme;
+@@ -510,7 +546,7 @@ buttonpress(XEvent *e)
+ arg.ui = 1 << i;
+ } else if (ev->x < x + blw)
+ click = ClkLtSymbol;
+- else if (ev->x > selmon->ww - (int)TEXTW(stext))
++ else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth())
+ click = ClkStatusText;
+ else
+ click = ClkWinTitle;
+@@ -553,6 +589,11 @@ cleanup(void)
+ XUngrabKey(dpy, AnyKey, AnyModifier, root);
+ while (mons)
+ cleanupmon(mons);
++ if (showsystray) {
++ XUnmapWindow(dpy, systray->win);
++ XDestroyWindow(dpy, systray->win);
++ free(systray);
++ }
+ for (i = 0; i < CurLast; i++)
+ drw_cur_free(drw, cursor[i]);
+ for (i = 0; i < LENGTH(colors); i++)
+@@ -583,9 +624,57 @@ cleanupmon(Monitor *mon)
+ void
+ clientmessage(XEvent *e)
+ {
++ XWindowAttributes wa;
++ XSetWindowAttributes swa;
+ XClientMessageEvent *cme = &e->xclient;
+ Client *c = wintoclient(cme->window);
+
++ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
++ /* add systray icons */
++ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
++ if (!(c = (Client *)calloc(1, sizeof(Client))))
++ die("fatal: could not malloc() %u bytes\n", sizeof(Client));
++ if (!(c->win = cme->data.l[2])) {
++ free(c);
++ return;
++ }
++ c->mon = selmon;
++ c->next = systray->icons;
++ systray->icons = c;
++ if (!XGetWindowAttributes(dpy, c->win, &wa)) {
++ /* use sane defaults */
++ wa.width = bh;
++ wa.height = bh;
++ wa.border_width = 0;
++ }
++ c->x = c->oldx = c->y = c->oldy = 0;
++ c->w = c->oldw = wa.width;
++ c->h = c->oldh = wa.height;
++ c->oldbw = wa.border_width;
++ c->bw = 0;
++ c->isfloating = True;
++ /* reuse tags field as mapped status */
++ c->tags = 1;
++ updatesizehints(c);
++ updatesystrayicongeom(c, wa.width, wa.height);
++ XAddToSaveSet(dpy, c->win);
++ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
++ XReparentWindow(dpy, c->win, systray->win, 0, 0);
++ /* use parents background color */
++ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
++ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa);
++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
++ /* FIXME not sure if I have to send these events, too */
++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
++ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
++ XSync(dpy, False);
++ resizebarwin(selmon);
++ updatesystray();
++ setclientstate(c, NormalState);
++ }
++ return;
++ }
+ if (!c)
+ return;
+ if (cme->message_type == netatom[NetWMState]) {
+@@ -638,7 +727,7 @@ configurenotify(XEvent *e)
+ for (c = m->clients; c; c = c->next)
+ if (c->isfullscreen)
+ resizeclient(c, m->mx, m->my, m->mw, m->mh);
+- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
++ resizebarwin(m);
+ }
+ focus(NULL);
+ arrange(NULL);
+@@ -723,6 +812,11 @@ destroynotify(XEvent *e)
+
+ if ((c = wintoclient(ev->window)))
+ unmanage(c, 1);
++ else if ((c = wintosystrayicon(ev->window))) {
++ removesystrayicon(c);
++ resizebarwin(selmon);
++ updatesystray();
++ }
+
+ else if ((c = swallowingclient(ev->window)))
+ unmanage(c->swallowing, 1);
+@@ -769,22 +863,26 @@ dirtomon(int dir)
+ void
+ drawbar(Monitor *m)
+ {
+- int x, w, tw = 0;
++ int x, w, tw = 0, stw = 0;
+ int boxs = drw->fonts->h / 9;
+ int boxw = drw->fonts->h / 6 + 2;
+ unsigned int i, occ = 0, urg = 0;
+ Client *c;
+
++ if(showsystray && m == systraytomon(m) && !systrayonleft)
++ stw = getsystraywidth();
++
+ if (!m->showbar)
+ return;
+
+ /* draw status first so it can be overdrawn by tags later */
+ if (m == selmon) { /* status is only drawn on selected monitor */
+ drw_setscheme(drw, scheme[SchemeNorm]);
+- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
++ tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px extra right padding */
++ drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0);
+ }
+
++ resizebarwin(m);
+ for (c = m->clients; c; c = c->next) {
+ occ |= c->tags;
+ if (c->isurgent)
+@@ -805,7 +903,7 @@ drawbar(Monitor *m)
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
+
+- if ((w = m->ww - tw - x) > bh) {
++ if ((w = m->ww - tw - stw - x) > bh) {
+ if (m->sel) {
+ drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+@@ -816,7 +914,7 @@ drawbar(Monitor *m)
+ drw_rect(drw, x, 0, w, bh, 1, 1);
+ }
+ }
+- drw_map(drw, m->barwin, 0, 0, m->ww, bh);
++ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
+ }
+
+ void
+@@ -853,8 +951,11 @@ expose(XEvent *e)
+ Monitor *m;
+ XExposeEvent *ev = &e->xexpose;
+
+- if (ev->count == 0 && (m = wintomon(ev->window)))
++ if (ev->count == 0 && (m = wintomon(ev->window))) {
+ drawbar(m);
++ if (m == selmon)
++ updatesystray();
++ }
+ }
+
+ void
+@@ -939,10 +1040,17 @@ getatomprop(Client *c, Atom prop)
+ unsigned long dl;
+ unsigned char *p = NULL;
+ Atom da, atom = None;
++ /* FIXME getatomprop should return the number of items and a pointer to
++ * the stored data instead of this workaround */
++ Atom req = XA_ATOM;
++ if (prop == xatom[XembedInfo])
++ req = xatom[XembedInfo];
+
+- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
++ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
+ &da, &di, &dl, &dl, &p) == Success && p) {
+ atom = *(Atom *)p;
++ if (da == xatom[XembedInfo] && dl == 2)
++ atom = ((Atom *)p)[1];
+ XFree(p);
+ }
+ return atom;
+@@ -976,6 +1084,16 @@ getstate(Window w)
+ return result;
+ }
+
++unsigned int
++getsystraywidth()
++{
++ unsigned int w = 0;
++ Client *i;
++ if(showsystray)
++ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
++ return w ? w + systrayspacing : 1;
++}
++
+ int
+ gettextprop(Window w, Atom atom, char *text, unsigned int size)
+ {
+@@ -1080,7 +1198,7 @@ killclient(const Arg *arg)
+ {
+ if (!selmon->sel)
+ return;
+- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
++ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
+ XGrabServer(dpy);
+ XSetErrorHandler(xerrordummy);
+ XSetCloseDownMode(dpy, DestroyAll);
+@@ -1172,6 +1290,12 @@ maprequest(XEvent *e)
+ {
+ static XWindowAttributes wa;
+ XMapRequestEvent *ev = &e->xmaprequest;
++ Client *i;
++ if ((i = wintosystrayicon(ev->window))) {
++ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
++ resizebarwin(selmon);
++ updatesystray();
++ }
+
+ if (!XGetWindowAttributes(dpy, ev->window, &wa))
+ return;
+@@ -1306,6 +1430,16 @@ propertynotify(XEvent *e)
+ Window trans;
+ XPropertyEvent *ev = &e->xproperty;
+
++ if ((c = wintosystrayicon(ev->window))) {
++ if (ev->atom == XA_WM_NORMAL_HINTS) {
++ updatesizehints(c);
++ updatesystrayicongeom(c, c->w, c->h);
++ }
++ else
++ updatesystrayiconstate(c, ev);
++ resizebarwin(selmon);
++ updatesystray();
++ }
+ if ((ev->window == root) && (ev->atom == XA_WM_NAME))
+ updatestatus();
+ else if (ev->state == PropertyDelete)
+@@ -1356,6 +1490,20 @@ recttomon(int x, int y, int w, int h)
+ return r;
+ }
+
++void
++removesystrayicon(Client *i)
++{
++ Client **ii;
++
++ if (!showsystray || !i)
++ return;
++ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
++ if (ii)
++ *ii = i->next;
++ free(i);
++}
++
++
+ void
+ resize(Client *c, int x, int y, int w, int h, int interact)
+ {
+@@ -1363,6 +1511,14 @@ resize(Client *c, int x, int y, int w, int h, int interact)
+ resizeclient(c, x, y, w, h);
+ }
+
++void
++resizebarwin(Monitor *m) {
++ unsigned int w = m->ww;
++ if (showsystray && m == systraytomon(m) && !systrayonleft)
++ w -= getsystraywidth();
++ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
++}
++
+ void
+ resizeclient(Client *c, int x, int y, int w, int h)
+ {
+@@ -1435,6 +1591,19 @@ resizemouse(const Arg *arg)
+ }
+ }
+
++void
++resizerequest(XEvent *e)
++{
++ XResizeRequestEvent *ev = &e->xresizerequest;
++ Client *i;
++
++ if ((i = wintosystrayicon(ev->window))) {
++ updatesystrayicongeom(i, ev->width, ev->height);
++ resizebarwin(selmon);
++ updatesystray();
++ }
++}
++
+ void
+ restack(Monitor *m)
+ {
+@@ -1524,26 +1693,36 @@ setclientstate(Client *c, long state)
+ }
+
+ int
+-sendevent(Client *c, Atom proto)
++sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4)
+ {
+ int n;
+- Atom *protocols;
++ Atom *protocols, mt;
+ int exists = 0;
+ XEvent ev;
+
+- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
+- while (!exists && n--)
+- exists = protocols[n] == proto;
+- XFree(protocols);
++ if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
++ mt = wmatom[WMProtocols];
++ if (XGetWMProtocols(dpy, w, &protocols, &n)) {
++ while (!exists && n--)
++ exists = protocols[n] == proto;
++ XFree(protocols);
++ }
++ }
++ else {
++ exists = True;
++ mt = proto;
+ }
+ if (exists) {
+ ev.type = ClientMessage;
+- ev.xclient.window = c->win;
+- ev.xclient.message_type = wmatom[WMProtocols];
++ ev.xclient.window = w;
++ ev.xclient.message_type = mt;
+ ev.xclient.format = 32;
+- ev.xclient.data.l[0] = proto;
+- ev.xclient.data.l[1] = CurrentTime;
+- XSendEvent(dpy, c->win, False, NoEventMask, &ev);
++ ev.xclient.data.l[0] = d0;
++ ev.xclient.data.l[1] = d1;
++ ev.xclient.data.l[2] = d2;
++ ev.xclient.data.l[3] = d3;
++ ev.xclient.data.l[4] = d4;
++ XSendEvent(dpy, w, False, mask, &ev);
+ }
+ return exists;
+ }
+@@ -1557,7 +1736,7 @@ setfocus(Client *c)
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *) &(c->win), 1);
+ }
+- sendevent(c, wmatom[WMTakeFocus]);
++ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
+ }
+
+ void
+@@ -1646,6 +1825,10 @@ setup(void)
+ wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
+ netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
+ netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
++ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
++ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
++ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
++ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False);
+ netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
+ netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
+ netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
+@@ -1653,6 +1836,9 @@ setup(void)
+ netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
+ netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+ netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
++ xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
++ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
++ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
+ /* init cursors */
+ cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
+ cursor[CurResize] = drw_cur_create(drw, XC_sizing);
+@@ -1661,6 +1847,8 @@ setup(void)
+ scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
+ for (i = 0; i < LENGTH(colors); i++)
+ scheme[i] = drw_scm_create(drw, colors[i], 3);
++ /* init system tray */
++ updatesystray();
+ /* init bars */
+ updatebars();
+ updatestatus();
+@@ -1794,7 +1982,18 @@ togglebar(const Arg *arg)
+ {
+ selmon->showbar = !selmon->showbar;
+ updatebarpos(selmon);
+- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
++ resizebarwin(selmon);
++ if (showsystray) {
++ XWindowChanges wc;
++ if (!selmon->showbar)
++ wc.y = -bh;
++ else if (selmon->showbar) {
++ wc.y = 0;
++ if (!selmon->topbar)
++ wc.y = selmon->mh - bh;
++ }
++ XConfigureWindow(dpy, systray->win, CWY, &wc);
++ }
+ arrange(selmon);
+ }
+
+@@ -1913,11 +2112,18 @@ unmapnotify(XEvent *e)
+ else
+ unmanage(c, 0);
+ }
++ else if ((c = wintosystrayicon(ev->window))) {
++ /* KLUDGE! sometimes icons occasionally unmap their windows, but do
++ * _not_ destroy them. We map those windows back */
++ XMapRaised(dpy, c->win);
++ updatesystray();
++ }
+ }
+
+ void
+ updatebars(void)
+ {
++ unsigned int w;
+ Monitor *m;
+ XSetWindowAttributes wa = {
+ .override_redirect = True,
+@@ -1928,10 +2134,15 @@ updatebars(void)
+ for (m = mons; m; m = m->next) {
+ if (m->barwin)
+ continue;
+- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
++ w = m->ww;
++ if (showsystray && m == systraytomon(m))
++ w -= getsystraywidth();
++ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen),
+ CopyFromParent, DefaultVisual(dpy, screen),
+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
+ XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
++ if (showsystray && m == systraytomon(m))
++ XMapRaised(dpy, systray->win);
+ XMapRaised(dpy, m->barwin);
+ XSetClassHint(dpy, m->barwin, &ch);
+ }
+@@ -2107,6 +2318,124 @@ updatestatus(void)
+ if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
+ strcpy(stext, "dwm-"VERSION);
+ drawbar(selmon);
++ updatesystray();
++}
++
++void
++updatesystrayicongeom(Client *i, int w, int h)
++{
++ if (i) {
++ i->h = bh;
++ if (w == h)
++ i->w = bh;
++ else if (h == bh)
++ i->w = w;
++ else
++ i->w = (int) ((float)bh * ((float)w / (float)h));
++ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
++ /* force icons into the systray dimensions if they don't want to */
++ if (i->h > bh) {
++ if (i->w == i->h)
++ i->w = bh;
++ else
++ i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
++ i->h = bh;
++ }
++ }
++}
++
++void
++updatesystrayiconstate(Client *i, XPropertyEvent *ev)
++{
++ long flags;
++ int code = 0;
++
++ if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
++ !(flags = getatomprop(i, xatom[XembedInfo])))
++ return;
++
++ if (flags & XEMBED_MAPPED && !i->tags) {
++ i->tags = 1;
++ code = XEMBED_WINDOW_ACTIVATE;
++ XMapRaised(dpy, i->win);
++ setclientstate(i, NormalState);
++ }
++ else if (!(flags & XEMBED_MAPPED) && i->tags) {
++ i->tags = 0;
++ code = XEMBED_WINDOW_DEACTIVATE;
++ XUnmapWindow(dpy, i->win);
++ setclientstate(i, WithdrawnState);
++ }
++ else
++ return;
++ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
++ systray->win, XEMBED_EMBEDDED_VERSION);
++}
++
++void
++updatesystray(void)
++{
++ XSetWindowAttributes wa;
++ XWindowChanges wc;
++ Client *i;
++ Monitor *m = systraytomon(NULL);
++ unsigned int x = m->mx + m->mw;
++ unsigned int sw = TEXTW(stext) - lrpad + systrayspacing;
++ unsigned int w = 1;
++
++ if (!showsystray)
++ return;
++ if (systrayonleft)
++ x -= sw + lrpad / 2;
++ if (!systray) {
++ /* init systray */
++ if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
++ die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
++ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel);
++ wa.event_mask = ButtonPressMask | ExposureMask;
++ wa.override_redirect = True;
++ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
++ XSelectInput(dpy, systray->win, SubstructureNotifyMask);
++ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
++ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1);
++ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa);
++ XMapRaised(dpy, systray->win);
++ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
++ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
++ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
++ XSync(dpy, False);
++ }
++ else {
++ fprintf(stderr, "dwm: unable to obtain system tray.\n");
++ free(systray);
++ systray = NULL;
++ return;
++ }
++ }
++ for (w = 0, i = systray->icons; i; i = i->next) {
++ /* make sure the background color stays the same */
++ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
++ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
++ XMapRaised(dpy, i->win);
++ w += systrayspacing;
++ i->x = w;
++ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
++ w += i->w;
++ if (i->mon != m)
++ i->mon = m;
++ }
++ w = w ? w + systrayspacing : 1;
++ x -= w;
++ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
++ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh;
++ wc.stack_mode = Above; wc.sibling = m->barwin;
++ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc);
++ XMapWindow(dpy, systray->win);
++ XMapSubwindows(dpy, systray->win);
++ /* redraw background */
++ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel);
++ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh);
++ XSync(dpy, False);
+ }
+
+ void
+@@ -2274,6 +2603,16 @@ wintoclient(Window w)
+ return NULL;
+ }
+
++Client *
++wintosystrayicon(Window w) {
++ Client *i = NULL;
++
++ if (!showsystray || !w)
++ return i;
++ for (i = systray->icons; i && i->win != w; i = i->next) ;
++ return i;
++}
++
+ Monitor *
+ wintomon(Window w)
+ {
+@@ -2327,6 +2666,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
+ return -1;
+ }
+
++Monitor *
++systraytomon(Monitor *m) {
++ Monitor *t;
++ int i, n;
++ if(!systraypinning) {
++ if(!m)
++ return selmon;
++ return m == selmon ? m : NULL;
++ }
++ for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
++ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ;
++ if(systraypinningfailfirst && n < systraypinning)
++ return mons;
++ return t;
++}
++
+ void
+ zoom(const Arg *arg)
+ {
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0013-feat-remove-accent-color.patch b/profiles/eug-vs/patches/x11-wm/dwm/0013-feat-remove-accent-color.patch
new file mode 100644
index 0000000..efa5ed3
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0013-feat-remove-accent-color.patch
@@ -0,0 +1,30 @@
+From cad1f11826b0f4a7fe4ee2f8e9328367e10a6140 Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Thu, 31 Mar 2022 17:59:22 +0300
+Subject: [PATCH 13/15] feat: remove accent color
+
+---
+ config.def.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 2d2af1a..41cfc16 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -13,11 +13,11 @@ static const int topbar = 1; /* 0 means bottom bar */
+ static const char *fonts[] = { "fira code nerd font:pixelsize=12:antialias=true:autohint=true" };
+ static const char col_background[] = "#1d2021";
+ static const char col_foreground[] = "#ebdbb2";
+-static const char col_primary[] = "#689d6a";
++static const char col_primary[] = "#928374";
+ static const char *colors[][3] = {
+ /* fg bg border */
+ [SchemeNorm] = { col_foreground, col_background, "#000000" },
+- [SchemeSel] = { col_foreground, col_primary, col_primary },
++ [SchemeSel] = { col_foreground, col_primary, "#000000" },
+ [SchemeStatus] = { col_foreground, col_background, "#000000" },
+ };
+
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0014-fix-add-missing-terminal-flag-to-st.patch b/profiles/eug-vs/patches/x11-wm/dwm/0014-fix-add-missing-terminal-flag-to-st.patch
new file mode 100644
index 0000000..4fdbe78
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0014-fix-add-missing-terminal-flag-to-st.patch
@@ -0,0 +1,37 @@
+From c84ac19422e3cca5e8a2a1898304d7c55883a07b Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Sat, 2 Apr 2022 17:14:16 +0300
+Subject: [PATCH 14/15] fix: add missing terminal flag to st
+
+---
+ config.def.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 41cfc16..f2c79ed 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -22,16 +22,16 @@ static const char *colors[][3] = {
+ };
+
+ /* tagging */
+-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
++static const char *tags[] = { "1", "2", "3", "4", "5" };
+
+ static const Rule rules[] = {
+ /* xprop(1):
+ * WM_CLASS(STRING) = instance, class
+ * WM_NAME(STRING) = title
+ */
+- /* class instance title tags mask isfloating monitor */
+- { "Gimp", NULL, NULL, 0, 1, -1 },
+- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
++ /* class instance title tags mask isfloating isterminal noswallow monitor */
++ { "St", NULL, NULL, 0, 0, 1, 0, -1 },
++ { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
+ };
+
+ /* layout(s) */
+--
+2.35.1
+
diff --git a/profiles/eug-vs/patches/x11-wm/dwm/0015-feat-use-classic-dwm-colors.patch b/profiles/eug-vs/patches/x11-wm/dwm/0015-feat-use-classic-dwm-colors.patch
new file mode 100644
index 0000000..851bd14
--- /dev/null
+++ b/profiles/eug-vs/patches/x11-wm/dwm/0015-feat-use-classic-dwm-colors.patch
@@ -0,0 +1,30 @@
+From e3b2372f384a61f55c66d2c79581f9a0f1f39082 Mon Sep 17 00:00:00 2001
+From: eug-vs <eugene@eug-vs.xyz>
+Date: Mon, 18 Apr 2022 21:20:32 +0300
+Subject: [PATCH 15/15] feat: use classic dwm colors
+
+---
+ config.def.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index f2c79ed..b3ae63e 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -13,11 +13,11 @@ static const int topbar = 1; /* 0 means bottom bar */
+ static const char *fonts[] = { "fira code nerd font:pixelsize=12:antialias=true:autohint=true" };
+ static const char col_background[] = "#1d2021";
+ static const char col_foreground[] = "#ebdbb2";
+-static const char col_primary[] = "#928374";
++static const char col_cyan[] = "#005577";
+ static const char *colors[][3] = {
+ /* fg bg border */
+ [SchemeNorm] = { col_foreground, col_background, "#000000" },
+- [SchemeSel] = { col_foreground, col_primary, "#000000" },
++ [SchemeSel] = { col_foreground, col_cyan, col_cyan },
+ [SchemeStatus] = { col_foreground, col_background, "#000000" },
+ };
+
+--
+2.35.1
+