Update with latest config
This commit is contained in:
parent
76ad418a06
commit
9193f2e502
40 changed files with 2685 additions and 222 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,3 +3,6 @@ dwm/dwm
|
||||||
st/st
|
st/st
|
||||||
st/config.h
|
st/config.h
|
||||||
dwm/config.h
|
dwm/config.h
|
||||||
|
dmenu/config.h
|
||||||
|
dmenu/dmenu
|
||||||
|
dmenu/stest
|
||||||
|
|
15
README.md
Normal file
15
README.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# rice
|
||||||
|
|
||||||
|
I will refactor this soon. Sorry for how weird everything is.
|
||||||
|
|
||||||
|
# usage
|
||||||
|
|
||||||
|
**If you want polybar**: you need the `waffle` and `castella` fonts installed from here: https://addy-dclxvi.github.io/post/bitmap-fonts/ as well as polybar-dwm-module (https://github.com/mihirlad55/polybar-dwm-module)
|
||||||
|
|
||||||
|
**If you get unexpected colors/fonts**: make sure you applied the Xresources file from this repo.
|
||||||
|
|
||||||
|
**GTK Theme I use**: https://github.com/TheGreatMcPain/gruvbox-material-gtk
|
||||||
|
|
||||||
|
**Color scheme**: Gruvbox material dark medium
|
||||||
|
|
||||||
|
**st font I use**: JetBrainsMono Nerd Font (see Xresources file)
|
106
dmenu/applied_patches/dmenu-lineheight-5.0.diff
Normal file
106
dmenu/applied_patches/dmenu-lineheight-5.0.diff
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
From ba103e38ea4ab07f9a3ee90627714b9bea17c329 Mon Sep 17 00:00:00 2001
|
||||||
|
From: pskry <peter@skrypalle.dk>
|
||||||
|
Date: Sun, 8 Nov 2020 22:04:22 +0100
|
||||||
|
Subject: [PATCH] Add an option which defines the lineheight
|
||||||
|
|
||||||
|
Despite both the panel and dmenu using the same font (a Terminus 12),
|
||||||
|
dmenu is shorter and the panel is visible from under the dmenu bar.
|
||||||
|
The appearance can be even more distracting when using similar colors
|
||||||
|
for background and selections. With the option added by this patch,
|
||||||
|
dmenu can be launched with a '-h 24', thus completely covering the panel.
|
||||||
|
---
|
||||||
|
config.def.h | 3 +++
|
||||||
|
dmenu.1 | 5 +++++
|
||||||
|
dmenu.c | 11 ++++++++---
|
||||||
|
3 files changed, 16 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1edb647..4394dec 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -15,6 +15,9 @@ static const char *colors[SchemeLast][2] = {
|
||||||
|
};
|
||||||
|
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
|
||||||
|
static unsigned int lines = 0;
|
||||||
|
+/* -h option; minimum height of a menu line */
|
||||||
|
+static unsigned int lineheight = 0;
|
||||||
|
+static unsigned int min_lineheight = 8;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Characters not considered part of a word while deleting words
|
||||||
|
diff --git a/dmenu.1 b/dmenu.1
|
||||||
|
index 323f93c..f2a82b4 100644
|
||||||
|
--- a/dmenu.1
|
||||||
|
+++ b/dmenu.1
|
||||||
|
@@ -6,6 +6,8 @@ dmenu \- dynamic menu
|
||||||
|
.RB [ \-bfiv ]
|
||||||
|
.RB [ \-l
|
||||||
|
.IR lines ]
|
||||||
|
+.RB [ \-h
|
||||||
|
+.IR height ]
|
||||||
|
.RB [ \-m
|
||||||
|
.IR monitor ]
|
||||||
|
.RB [ \-p
|
||||||
|
@@ -50,6 +52,9 @@ dmenu matches menu items case insensitively.
|
||||||
|
.BI \-l " lines"
|
||||||
|
dmenu lists items vertically, with the given number of lines.
|
||||||
|
.TP
|
||||||
|
+.BI \-h " height"
|
||||||
|
+dmenu uses a menu line of at least 'height' pixels tall, but no less than 8.
|
||||||
|
+.TP
|
||||||
|
.BI \-m " monitor"
|
||||||
|
dmenu is displayed on the monitor number supplied. Monitor numbers are starting
|
||||||
|
from 0.
|
||||||
|
diff --git a/dmenu.c b/dmenu.c
|
||||||
|
index 65f25ce..f2a4047 100644
|
||||||
|
--- a/dmenu.c
|
||||||
|
+++ b/dmenu.c
|
||||||
|
@@ -131,7 +131,7 @@ drawmenu(void)
|
||||||
|
{
|
||||||
|
unsigned int curpos;
|
||||||
|
struct item *item;
|
||||||
|
- int x = 0, y = 0, w;
|
||||||
|
+ int x = 0, y = 0, fh = drw->fonts->h, w;
|
||||||
|
|
||||||
|
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||||
|
drw_rect(drw, 0, 0, mw, mh, 1, 1);
|
||||||
|
@@ -148,7 +148,7 @@ drawmenu(void)
|
||||||
|
curpos = TEXTW(text) - TEXTW(&text[cursor]);
|
||||||
|
if ((curpos += lrpad / 2 - 1) < w) {
|
||||||
|
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||||
|
- drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
|
||||||
|
+ drw_rect(drw, x + curpos, 2 + (bh - fh) / 2, 2, fh - 4, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lines > 0) {
|
||||||
|
@@ -609,6 +609,7 @@ setup(void)
|
||||||
|
|
||||||
|
/* calculate menu geometry */
|
||||||
|
bh = drw->fonts->h + 2;
|
||||||
|
+ bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */
|
||||||
|
lines = MAX(lines, 0);
|
||||||
|
mh = (lines + 1) * bh;
|
||||||
|
#ifdef XINERAMA
|
||||||
|
@@ -689,7 +690,7 @@ setup(void)
|
||||||
|
static void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
|
||||||
|
+ fputs("usage: dmenu [-bfiv] [-l lines] [-h height] [-p prompt] [-fn font] [-m monitor]\n"
|
||||||
|
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
@@ -717,6 +718,10 @@ main(int argc, char *argv[])
|
||||||
|
/* these options take one argument */
|
||||||
|
else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
|
||||||
|
lines = atoi(argv[++i]);
|
||||||
|
+ else if (!strcmp(argv[i], "-h")) { /* minimum height of one menu line */
|
||||||
|
+ lineheight = atoi(argv[++i]);
|
||||||
|
+ lineheight = MAX(lineheight, min_lineheight);
|
||||||
|
+ }
|
||||||
|
else if (!strcmp(argv[i], "-m"))
|
||||||
|
mon = atoi(argv[++i]);
|
||||||
|
else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */
|
||||||
|
--
|
||||||
|
2.29.2
|
||||||
|
|
126
dmenu/applied_patches/dmenu-xresources-4.9.diff
Normal file
126
dmenu/applied_patches/dmenu-xresources-4.9.diff
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
diff '--color=auto' -up ../dmenu-4.9/dmenu.c ./dmenu.c
|
||||||
|
--- ../dmenu-4.9/dmenu.c 2019-02-02 13:55:02.000000000 +0100
|
||||||
|
+++ ./dmenu.c 2020-05-24 00:27:58.038586112 +0200
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
#endif
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
+#include <X11/Xresource.h>
|
||||||
|
|
||||||
|
#include "drw.h"
|
||||||
|
#include "util.h"
|
||||||
|
@@ -53,6 +54,10 @@ static XIC xic;
|
||||||
|
static Drw *drw;
|
||||||
|
static Clr *scheme[SchemeLast];
|
||||||
|
|
||||||
|
+/* Temporary arrays to allow overriding xresources values */
|
||||||
|
+static char *colortemp[4];
|
||||||
|
+static char *tempfonts;
|
||||||
|
+
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
|
||||||
|
@@ -596,8 +601,13 @@ setup(void)
|
||||||
|
int a, di, n, area = 0;
|
||||||
|
#endif
|
||||||
|
/* init appearance */
|
||||||
|
- for (j = 0; j < SchemeLast; j++)
|
||||||
|
- scheme[j] = drw_scm_create(drw, colors[j], 2);
|
||||||
|
+ for (j = 0; j < SchemeLast; j++) {
|
||||||
|
+ scheme[j] = drw_scm_create(drw, (const char**)colors[j], 2);
|
||||||
|
+ }
|
||||||
|
+ for (j = 0; j < SchemeOut; ++j) {
|
||||||
|
+ for (i = 0; i < 2; ++i)
|
||||||
|
+ free(colors[j][i]);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
clip = XInternAtom(dpy, "CLIPBOARD", False);
|
||||||
|
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
|
||||||
|
@@ -687,6 +697,41 @@ usage(void)
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+readxresources(void) {
|
||||||
|
+ XrmInitialize();
|
||||||
|
+
|
||||||
|
+ char* xrm;
|
||||||
|
+ if ((xrm = XResourceManagerString(drw->dpy))) {
|
||||||
|
+ char *type;
|
||||||
|
+ XrmDatabase xdb = XrmGetStringDatabase(xrm);
|
||||||
|
+ XrmValue xval;
|
||||||
|
+
|
||||||
|
+ if (XrmGetResource(xdb, "dmenu.font", "*", &type, &xval))
|
||||||
|
+ fonts[0] = strdup(xval.addr);
|
||||||
|
+ else
|
||||||
|
+ fonts[0] = strdup(fonts[0]);
|
||||||
|
+ if (XrmGetResource(xdb, "dmenu.background", "*", &type, &xval))
|
||||||
|
+ colors[SchemeNorm][ColBg] = strdup(xval.addr);
|
||||||
|
+ else
|
||||||
|
+ colors[SchemeNorm][ColBg] = strdup(colors[SchemeNorm][ColBg]);
|
||||||
|
+ if (XrmGetResource(xdb, "dmenu.foreground", "*", &type, &xval))
|
||||||
|
+ colors[SchemeNorm][ColFg] = strdup(xval.addr);
|
||||||
|
+ else
|
||||||
|
+ colors[SchemeNorm][ColFg] = strdup(colors[SchemeNorm][ColFg]);
|
||||||
|
+ if (XrmGetResource(xdb, "dmenu.selbackground", "*", &type, &xval))
|
||||||
|
+ colors[SchemeSel][ColBg] = strdup(xval.addr);
|
||||||
|
+ else
|
||||||
|
+ colors[SchemeSel][ColBg] = strdup(colors[SchemeSel][ColBg]);
|
||||||
|
+ if (XrmGetResource(xdb, "dmenu.selforeground", "*", &type, &xval))
|
||||||
|
+ colors[SchemeSel][ColFg] = strdup(xval.addr);
|
||||||
|
+ else
|
||||||
|
+ colors[SchemeSel][ColFg] = strdup(colors[SchemeSel][ColFg]);
|
||||||
|
+
|
||||||
|
+ XrmDestroyDatabase(xdb);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
@@ -715,15 +760,15 @@ main(int argc, char *argv[])
|
||||||
|
else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */
|
||||||
|
prompt = argv[++i];
|
||||||
|
else if (!strcmp(argv[i], "-fn")) /* font or font set */
|
||||||
|
- fonts[0] = argv[++i];
|
||||||
|
+ tempfonts = argv[++i];
|
||||||
|
else if (!strcmp(argv[i], "-nb")) /* normal background color */
|
||||||
|
- colors[SchemeNorm][ColBg] = argv[++i];
|
||||||
|
+ colortemp[0] = argv[++i];
|
||||||
|
else if (!strcmp(argv[i], "-nf")) /* normal foreground color */
|
||||||
|
- colors[SchemeNorm][ColFg] = argv[++i];
|
||||||
|
+ colortemp[1] = argv[++i];
|
||||||
|
else if (!strcmp(argv[i], "-sb")) /* selected background color */
|
||||||
|
- colors[SchemeSel][ColBg] = argv[++i];
|
||||||
|
+ colortemp[2] = argv[++i];
|
||||||
|
else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
|
||||||
|
- colors[SchemeSel][ColFg] = argv[++i];
|
||||||
|
+ colortemp[3] = argv[++i];
|
||||||
|
else if (!strcmp(argv[i], "-w")) /* embedding window id */
|
||||||
|
embed = argv[++i];
|
||||||
|
else
|
||||||
|
@@ -743,8 +788,23 @@ main(int argc, char *argv[])
|
||||||
|
die("could not get embedding window attributes: 0x%lx",
|
||||||
|
parentwin);
|
||||||
|
drw = drw_create(dpy, screen, root, wa.width, wa.height);
|
||||||
|
- if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||||
|
+ readxresources();
|
||||||
|
+ /* Now we check whether to override xresources with commandline parameters */
|
||||||
|
+ if ( tempfonts )
|
||||||
|
+ fonts[0] = strdup(tempfonts);
|
||||||
|
+ if ( colortemp[0])
|
||||||
|
+ colors[SchemeNorm][ColBg] = strdup(colortemp[0]);
|
||||||
|
+ if ( colortemp[1])
|
||||||
|
+ colors[SchemeNorm][ColFg] = strdup(colortemp[1]);
|
||||||
|
+ if ( colortemp[2])
|
||||||
|
+ colors[SchemeSel][ColBg] = strdup(colortemp[2]);
|
||||||
|
+ if ( colortemp[3])
|
||||||
|
+ colors[SchemeSel][ColFg] = strdup(colortemp[3]);
|
||||||
|
+
|
||||||
|
+ if (!drw_fontset_create(drw, (const char**)fonts, LENGTH(fonts)))
|
||||||
|
die("no fonts could be loaded.");
|
||||||
|
+
|
||||||
|
+ free(fonts[0]);
|
||||||
|
lrpad = drw->fonts->h;
|
||||||
|
|
||||||
|
#ifdef __OpenBSD__
|
|
@ -1,29 +1,31 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
/* Default settings; can be overriden by command line. */
|
/* Default settings; can be overriden by command line. */
|
||||||
|
|
||||||
// gruvbox
|
|
||||||
static const char col_gruvbox0_hard[] = "#1d2021"; // Background (black)
|
|
||||||
static const char col_gruvbox0_medium[] = "#282828";
|
|
||||||
static const char col_gruvbox0_soft[] = "#32302f";
|
|
||||||
|
|
||||||
static const char col_gruvbox7[] = "#a89984"; // White
|
static const char bg1[] = "#1c1e26";
|
||||||
static const char col_gruvbox8[] = "#928374";
|
static const char bg2[] = "#2e303e";
|
||||||
static const char col_gruvbox15[] = "#ebdbb2"; // White
|
|
||||||
|
static const char fg1[] = "#9da0a2";
|
||||||
|
static const char fg2[] = "#dcdfe4";
|
||||||
|
|
||||||
|
|
||||||
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
|
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
|
||||||
/* -fn option overrides fonts[0]; default X11 font or font set */
|
/* -fn option overrides fonts[0]; default X11 font or font set */
|
||||||
static const char *fonts[] = {
|
static const char *fonts[] = {
|
||||||
"monospace:size=10"
|
"castella:size=12"
|
||||||
};
|
};
|
||||||
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
|
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
|
||||||
static const char *colors[SchemeLast][2] = {
|
static const char *colors[SchemeLast][2] = {
|
||||||
/* fg bg */
|
/* fg bg */
|
||||||
[SchemeNorm] = { col_gruvbox7, col_gruvbox0_hard },
|
[SchemeNorm] = { fg1, bg1 },
|
||||||
[SchemeSel] = { col_gruvbox15, col_gruvbox0_medium },
|
[SchemeSel] = { fg2, bg2 },
|
||||||
[SchemeOut] = { "#000000", "#00ffff" },
|
[SchemeOut] = { "#000000", "#00ffff" },
|
||||||
};
|
};
|
||||||
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
|
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
|
||||||
static unsigned int lines = 0;
|
static unsigned int lines = 0;
|
||||||
|
/* -h option; minimum height of a menu line */
|
||||||
|
static unsigned int lineheight = 28;
|
||||||
|
static unsigned int min_lineheight = 8;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Characters not considered part of a word while deleting words
|
* Characters not considered part of a word while deleting words
|
||||||
|
|
|
@ -1,29 +1,31 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
/* Default settings; can be overriden by command line. */
|
/* Default settings; can be overriden by command line. */
|
||||||
|
|
||||||
// gruvbox
|
|
||||||
static const char col_gruvbox0_hard[] = "#1d2021"; // Background (black)
|
|
||||||
static const char col_gruvbox0_medium[] = "#282828";
|
|
||||||
static const char col_gruvbox0_soft[] = "#32302f";
|
|
||||||
|
|
||||||
static const char col_gruvbox7[] = "#a89984"; // White
|
static const char bg1[] = "#1c1e26";
|
||||||
static const char col_gruvbox8[] = "#928374";
|
static const char bg2[] = "#2e303e";
|
||||||
static const char col_gruvbox15[] = "#ebdbb2"; // White
|
|
||||||
|
static const char fg1[] = "#9da0a2";
|
||||||
|
static const char fg2[] = "#dcdfe4";
|
||||||
|
|
||||||
|
|
||||||
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
|
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
|
||||||
/* -fn option overrides fonts[0]; default X11 font or font set */
|
/* -fn option overrides fonts[0]; default X11 font or font set */
|
||||||
static const char *fonts[] = {
|
static const char *fonts[] = {
|
||||||
"monospace:size=10"
|
"castella:size=12"
|
||||||
};
|
};
|
||||||
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
|
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
|
||||||
static const char *colors[SchemeLast][2] = {
|
static const char *colors[SchemeLast][2] = {
|
||||||
/* fg bg */
|
/* fg bg */
|
||||||
[SchemeNorm] = { col_gruvbox7, col_gruvbox0_hard },
|
[SchemeNorm] = { fg1, bg1 },
|
||||||
[SchemeSel] = { col_gruvbox15, col_gruvbox0_medium },
|
[SchemeSel] = { fg2, bg2 },
|
||||||
[SchemeOut] = { "#000000", "#00ffff" },
|
[SchemeOut] = { "#000000", "#00ffff" },
|
||||||
};
|
};
|
||||||
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
|
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
|
||||||
static unsigned int lines = 0;
|
static unsigned int lines = 0;
|
||||||
|
/* -h option; minimum height of a menu line */
|
||||||
|
static unsigned int lineheight = 28;
|
||||||
|
static unsigned int min_lineheight = 8;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Characters not considered part of a word while deleting words
|
* Characters not considered part of a word while deleting words
|
||||||
|
|
|
@ -6,6 +6,8 @@ dmenu \- dynamic menu
|
||||||
.RB [ \-bfiv ]
|
.RB [ \-bfiv ]
|
||||||
.RB [ \-l
|
.RB [ \-l
|
||||||
.IR lines ]
|
.IR lines ]
|
||||||
|
.RB [ \-h
|
||||||
|
.IR height ]
|
||||||
.RB [ \-m
|
.RB [ \-m
|
||||||
.IR monitor ]
|
.IR monitor ]
|
||||||
.RB [ \-p
|
.RB [ \-p
|
||||||
|
@ -50,6 +52,9 @@ dmenu matches menu items case insensitively.
|
||||||
.BI \-l " lines"
|
.BI \-l " lines"
|
||||||
dmenu lists items vertically, with the given number of lines.
|
dmenu lists items vertically, with the given number of lines.
|
||||||
.TP
|
.TP
|
||||||
|
.BI \-h " height"
|
||||||
|
dmenu uses a menu line of at least 'height' pixels tall, but no less than 8.
|
||||||
|
.TP
|
||||||
.BI \-m " monitor"
|
.BI \-m " monitor"
|
||||||
dmenu is displayed on the monitor number supplied. Monitor numbers are starting
|
dmenu is displayed on the monitor number supplied. Monitor numbers are starting
|
||||||
from 0.
|
from 0.
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <X11/extensions/Xinerama.h>
|
#include <X11/extensions/Xinerama.h>
|
||||||
#endif
|
#endif
|
||||||
#include <X11/Xft/Xft.h>
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <X11/Xresource.h>
|
||||||
|
|
||||||
#include "drw.h"
|
#include "drw.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -53,6 +54,10 @@ static XIC xic;
|
||||||
static Drw *drw;
|
static Drw *drw;
|
||||||
static Clr *scheme[SchemeLast];
|
static Clr *scheme[SchemeLast];
|
||||||
|
|
||||||
|
/* Temporary arrays to allow overriding xresources values */
|
||||||
|
static char *colortemp[4];
|
||||||
|
static char *tempfonts;
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
|
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
|
||||||
|
@ -131,7 +136,7 @@ drawmenu(void)
|
||||||
{
|
{
|
||||||
unsigned int curpos;
|
unsigned int curpos;
|
||||||
struct item *item;
|
struct item *item;
|
||||||
int x = 0, y = 0, w;
|
int x = 0, y = 0, fh = drw->fonts->h, w;
|
||||||
|
|
||||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||||
drw_rect(drw, 0, 0, mw, mh, 1, 1);
|
drw_rect(drw, 0, 0, mw, mh, 1, 1);
|
||||||
|
@ -148,7 +153,7 @@ drawmenu(void)
|
||||||
curpos = TEXTW(text) - TEXTW(&text[cursor]);
|
curpos = TEXTW(text) - TEXTW(&text[cursor]);
|
||||||
if ((curpos += lrpad / 2 - 1) < w) {
|
if ((curpos += lrpad / 2 - 1) < w) {
|
||||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||||
drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
|
drw_rect(drw, x + curpos, 2 + (bh - fh) / 2, 2, fh - 4, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lines > 0) {
|
if (lines > 0) {
|
||||||
|
@ -601,14 +606,20 @@ setup(void)
|
||||||
int a, di, n, area = 0;
|
int a, di, n, area = 0;
|
||||||
#endif
|
#endif
|
||||||
/* init appearance */
|
/* init appearance */
|
||||||
for (j = 0; j < SchemeLast; j++)
|
for (j = 0; j < SchemeLast; j++) {
|
||||||
scheme[j] = drw_scm_create(drw, colors[j], 2);
|
scheme[j] = drw_scm_create(drw, (const char**)colors[j], 2);
|
||||||
|
}
|
||||||
|
for (j = 0; j < SchemeOut; ++j) {
|
||||||
|
for (i = 0; i < 2; ++i)
|
||||||
|
free(colors[j][i]);
|
||||||
|
}
|
||||||
|
|
||||||
clip = XInternAtom(dpy, "CLIPBOARD", False);
|
clip = XInternAtom(dpy, "CLIPBOARD", False);
|
||||||
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
|
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
|
||||||
|
|
||||||
/* calculate menu geometry */
|
/* calculate menu geometry */
|
||||||
bh = drw->fonts->h + 2;
|
bh = drw->fonts->h + 2;
|
||||||
|
bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */
|
||||||
lines = MAX(lines, 0);
|
lines = MAX(lines, 0);
|
||||||
mh = (lines + 1) * bh;
|
mh = (lines + 1) * bh;
|
||||||
#ifdef XINERAMA
|
#ifdef XINERAMA
|
||||||
|
@ -689,11 +700,46 @@ setup(void)
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
|
fputs("usage: dmenu [-bfiv] [-l lines] [-h height] [-p prompt] [-fn font] [-m monitor]\n"
|
||||||
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
|
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
readxresources(void) {
|
||||||
|
XrmInitialize();
|
||||||
|
|
||||||
|
char* xrm;
|
||||||
|
if ((xrm = XResourceManagerString(drw->dpy))) {
|
||||||
|
char *type;
|
||||||
|
XrmDatabase xdb = XrmGetStringDatabase(xrm);
|
||||||
|
XrmValue xval;
|
||||||
|
|
||||||
|
if (XrmGetResource(xdb, "dmenu.font", "*", &type, &xval))
|
||||||
|
fonts[0] = strdup(xval.addr);
|
||||||
|
else
|
||||||
|
fonts[0] = strdup(fonts[0]);
|
||||||
|
if (XrmGetResource(xdb, "dmenu.background", "*", &type, &xval))
|
||||||
|
colors[SchemeNorm][ColBg] = strdup(xval.addr);
|
||||||
|
else
|
||||||
|
colors[SchemeNorm][ColBg] = strdup(colors[SchemeNorm][ColBg]);
|
||||||
|
if (XrmGetResource(xdb, "dmenu.foreground", "*", &type, &xval))
|
||||||
|
colors[SchemeNorm][ColFg] = strdup(xval.addr);
|
||||||
|
else
|
||||||
|
colors[SchemeNorm][ColFg] = strdup(colors[SchemeNorm][ColFg]);
|
||||||
|
if (XrmGetResource(xdb, "dmenu.selbackground", "*", &type, &xval))
|
||||||
|
colors[SchemeSel][ColBg] = strdup(xval.addr);
|
||||||
|
else
|
||||||
|
colors[SchemeSel][ColBg] = strdup(colors[SchemeSel][ColBg]);
|
||||||
|
if (XrmGetResource(xdb, "dmenu.selforeground", "*", &type, &xval))
|
||||||
|
colors[SchemeSel][ColFg] = strdup(xval.addr);
|
||||||
|
else
|
||||||
|
colors[SchemeSel][ColFg] = strdup(colors[SchemeSel][ColFg]);
|
||||||
|
|
||||||
|
XrmDestroyDatabase(xdb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -717,20 +763,24 @@ main(int argc, char *argv[])
|
||||||
/* these options take one argument */
|
/* these options take one argument */
|
||||||
else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
|
else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
|
||||||
lines = atoi(argv[++i]);
|
lines = atoi(argv[++i]);
|
||||||
|
else if (!strcmp(argv[i], "-h")) { /* minimum height of one menu line */
|
||||||
|
lineheight = atoi(argv[++i]);
|
||||||
|
lineheight = MAX(lineheight, min_lineheight);
|
||||||
|
}
|
||||||
else if (!strcmp(argv[i], "-m"))
|
else if (!strcmp(argv[i], "-m"))
|
||||||
mon = atoi(argv[++i]);
|
mon = atoi(argv[++i]);
|
||||||
else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */
|
else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */
|
||||||
prompt = argv[++i];
|
prompt = argv[++i];
|
||||||
else if (!strcmp(argv[i], "-fn")) /* font or font set */
|
else if (!strcmp(argv[i], "-fn")) /* font or font set */
|
||||||
fonts[0] = argv[++i];
|
tempfonts = argv[++i];
|
||||||
else if (!strcmp(argv[i], "-nb")) /* normal background color */
|
else if (!strcmp(argv[i], "-nb")) /* normal background color */
|
||||||
colors[SchemeNorm][ColBg] = argv[++i];
|
colortemp[0] = argv[++i];
|
||||||
else if (!strcmp(argv[i], "-nf")) /* normal foreground color */
|
else if (!strcmp(argv[i], "-nf")) /* normal foreground color */
|
||||||
colors[SchemeNorm][ColFg] = argv[++i];
|
colortemp[1] = argv[++i];
|
||||||
else if (!strcmp(argv[i], "-sb")) /* selected background color */
|
else if (!strcmp(argv[i], "-sb")) /* selected background color */
|
||||||
colors[SchemeSel][ColBg] = argv[++i];
|
colortemp[2] = argv[++i];
|
||||||
else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
|
else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
|
||||||
colors[SchemeSel][ColFg] = argv[++i];
|
colortemp[3] = argv[++i];
|
||||||
else if (!strcmp(argv[i], "-w")) /* embedding window id */
|
else if (!strcmp(argv[i], "-w")) /* embedding window id */
|
||||||
embed = argv[++i];
|
embed = argv[++i];
|
||||||
else
|
else
|
||||||
|
@ -748,8 +798,23 @@ main(int argc, char *argv[])
|
||||||
die("could not get embedding window attributes: 0x%lx",
|
die("could not get embedding window attributes: 0x%lx",
|
||||||
parentwin);
|
parentwin);
|
||||||
drw = drw_create(dpy, screen, root, wa.width, wa.height);
|
drw = drw_create(dpy, screen, root, wa.width, wa.height);
|
||||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
readxresources();
|
||||||
|
/* Now we check whether to override xresources with commandline parameters */
|
||||||
|
if ( tempfonts )
|
||||||
|
fonts[0] = strdup(tempfonts);
|
||||||
|
if ( colortemp[0])
|
||||||
|
colors[SchemeNorm][ColBg] = strdup(colortemp[0]);
|
||||||
|
if ( colortemp[1])
|
||||||
|
colors[SchemeNorm][ColFg] = strdup(colortemp[1]);
|
||||||
|
if ( colortemp[2])
|
||||||
|
colors[SchemeSel][ColBg] = strdup(colortemp[2]);
|
||||||
|
if ( colortemp[3])
|
||||||
|
colors[SchemeSel][ColFg] = strdup(colortemp[3]);
|
||||||
|
|
||||||
|
if (!drw_fontset_create(drw, (const char**)fonts, LENGTH(fonts)))
|
||||||
die("no fonts could be loaded.");
|
die("no fonts could be loaded.");
|
||||||
|
|
||||||
|
free(fonts[0]);
|
||||||
lrpad = drw->fonts->h;
|
lrpad = drw->fonts->h;
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
|
|
62
dots/.Xresources
Normal file
62
dots/.Xresources
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
! Gruvbox Material Dark
|
||||||
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
*background: #282828
|
||||||
|
! medium
|
||||||
|
! *background: #282828
|
||||||
|
! soft
|
||||||
|
! *background: #32302f
|
||||||
|
|
||||||
|
*foreground: #d4be98
|
||||||
|
|
||||||
|
! Black + DarkGrey
|
||||||
|
*color0: #32302f
|
||||||
|
*color8: #32302f
|
||||||
|
! DarkRed + Red
|
||||||
|
*color1: #ea6962
|
||||||
|
*color9: #ea6962
|
||||||
|
! DarkGreen + Green
|
||||||
|
*color2: #a9b665
|
||||||
|
*color10: #a9b665
|
||||||
|
! DarkYellow + Yellow
|
||||||
|
*color3: #e78a4e
|
||||||
|
*color11: #e78a4e
|
||||||
|
! DarkBlue + Blue
|
||||||
|
*color4: #7daea3
|
||||||
|
*color12: #7daea3
|
||||||
|
! DarkMagenta + Magenta
|
||||||
|
*color5: #d3869b
|
||||||
|
*color13: #d3869b
|
||||||
|
! DarkCyan + Cyan
|
||||||
|
*color6: #89b482
|
||||||
|
*color14: #89b482
|
||||||
|
! LightGrey + White
|
||||||
|
*color7: #d4be98
|
||||||
|
*color15: #d4be98
|
||||||
|
|
||||||
|
st.font: JetBrainsMono Nerd Font:pixelsize=15:antialias=true:autohint=true
|
||||||
|
st.color0: #282828
|
||||||
|
st.color1: #ea6962
|
||||||
|
st.color2: #a9b665
|
||||||
|
st.color3: #d8a657
|
||||||
|
st.color4: #7daea3
|
||||||
|
st.color5: #d3869b
|
||||||
|
st.color6: #89b482
|
||||||
|
st.color7: #d4be98
|
||||||
|
st.color8: #928374
|
||||||
|
st.color9: #ef938e
|
||||||
|
st.color10: #bbc585
|
||||||
|
st.color11: #e1bb7e
|
||||||
|
st.color12: #9dc2ba
|
||||||
|
st.color13: #e1acbb
|
||||||
|
st.color14: #a7c7a2
|
||||||
|
st.color15: #e2d3ba
|
||||||
|
|
||||||
|
dwm.normbgcolor: #282828
|
||||||
|
dwm.normbordercolor: #282828
|
||||||
|
dwm.normfgcolor: #d4be98
|
||||||
|
dwm.selbgcolor: #32302f
|
||||||
|
dwm.selbordercolor: #32302f
|
||||||
|
dwm.selfgcolor: #d4be98
|
||||||
|
|
||||||
|
*selbackground: #32302f
|
115
dots/.config/polybar/config
Normal file
115
dots/.config/polybar/config
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
[colors]
|
||||||
|
bg = ${xrdb:background}
|
||||||
|
fg = ${xrdb:foreground}
|
||||||
|
|
||||||
|
red = ${xrdb:color1}
|
||||||
|
orange = ${xrdb:color9}
|
||||||
|
blue = ${xrdb:color4}
|
||||||
|
purple = ${xrdb:color5}
|
||||||
|
reddish = ${xrdb:color1}
|
||||||
|
|
||||||
|
[bar/top]
|
||||||
|
monitor = "HDMI-A-0"
|
||||||
|
bottom = false
|
||||||
|
background = ${colors.bg}
|
||||||
|
foreground = ${colors.fg}
|
||||||
|
font-0 = "castella:size=12;2"
|
||||||
|
font-1 = "waffle:size=12;2"
|
||||||
|
modules-left = ewmh separator title
|
||||||
|
modules-center = date
|
||||||
|
modules-right = pulseaudio
|
||||||
|
padding = 1
|
||||||
|
height = 28
|
||||||
|
module-margin = 1
|
||||||
|
|
||||||
|
[module/separator]
|
||||||
|
type = custom/text
|
||||||
|
content = |
|
||||||
|
content-foreground = ${colors.fg}
|
||||||
|
|
||||||
|
[module/ewmh]
|
||||||
|
type = internal/xworkspaces
|
||||||
|
|
||||||
|
icon-0 = 1;
|
||||||
|
icon-1 = 2;
|
||||||
|
icon-2 = 3;
|
||||||
|
icon-3 = 4;
|
||||||
|
icon-4 = 5;
|
||||||
|
icon-default =
|
||||||
|
|
||||||
|
format = <label-state>
|
||||||
|
|
||||||
|
label-monitor = %name%
|
||||||
|
|
||||||
|
label-active = " "
|
||||||
|
label-active-foreground = ${colors.red}
|
||||||
|
label-active-background = ${colors.bg}
|
||||||
|
|
||||||
|
label-occupied = " "
|
||||||
|
label-occupied-foreground = ${colors.orange}
|
||||||
|
label-occupied-background = ${colors.bg}
|
||||||
|
|
||||||
|
label-urgent = "%icon% "
|
||||||
|
label-urgent-foreground = ${colors.reddish}
|
||||||
|
label-urgent-background = ${colors.bg}
|
||||||
|
|
||||||
|
label-empty = "%icon% "
|
||||||
|
label-empty-foreground = ${colors.fg}
|
||||||
|
label-empty-background = ${colors.bg}
|
||||||
|
|
||||||
|
label-active-padding = 0
|
||||||
|
label-urgent-padding = 0
|
||||||
|
label-occupied-padding = 0
|
||||||
|
label-empty-padding = 0
|
||||||
|
|
||||||
|
[module/date]
|
||||||
|
type = internal/date
|
||||||
|
|
||||||
|
; Seconds to sleep between updates
|
||||||
|
interval = 1.0
|
||||||
|
|
||||||
|
; See "http://en.cppreference.com/w/cpp/io/manip/put_time" for details on how to format the date string
|
||||||
|
; NOTE: if you want to use syntax tags here you need to use %%{...}
|
||||||
|
date = %A, %d %B
|
||||||
|
|
||||||
|
; Optional time format
|
||||||
|
time = %I:%M
|
||||||
|
|
||||||
|
; if `date-alt` or `time-alt` is defined, clicking
|
||||||
|
; the module will toggle between formats
|
||||||
|
date-alt = "%A, %d %B %Y"
|
||||||
|
time-alt = "%k:%M:%S"
|
||||||
|
|
||||||
|
format = <label>
|
||||||
|
format-prefix = " "
|
||||||
|
format-prefix-foreground = ${colors.blue}
|
||||||
|
label = %date% %time%
|
||||||
|
|
||||||
|
[module/pulseaudio]
|
||||||
|
type = internal/pulseaudio
|
||||||
|
interval = 5
|
||||||
|
|
||||||
|
format-volume = <ramp-volume> <label-volume>
|
||||||
|
|
||||||
|
format-muted-prefix =
|
||||||
|
format-muted-prefix-foreground = ${colors.red}
|
||||||
|
label-muted = "muted"
|
||||||
|
label-muted-foreground = ${colors.fg}
|
||||||
|
|
||||||
|
ramp-volume-0 =
|
||||||
|
ramp-volume-1 =
|
||||||
|
ramp-volume-2 =
|
||||||
|
|
||||||
|
click-right = pavucontrol
|
||||||
|
|
||||||
|
[module/title]
|
||||||
|
type = internal/xwindow
|
||||||
|
|
||||||
|
format-prefix = " "
|
||||||
|
format-prefix-foreground = ${colors.purple}
|
||||||
|
|
||||||
|
[module/mymotd]
|
||||||
|
type = custom/script
|
||||||
|
label = %output%
|
||||||
|
exec = cat ~/.motd
|
||||||
|
click-left = st -T todo -e less ~/todo
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Recursively search my code folder for a specific folder
|
|
||||||
|
|
||||||
cf() {
|
|
||||||
cd $(find ~/code -maxdepth 4 -type d -name "$1" -print | sed 1q)
|
|
||||||
}
|
|
12
dwm/applied_patches/dwm-alwayscenter-20200625-f04cac6.diff
Normal file
12
dwm/applied_patches/dwm-alwayscenter-20200625-f04cac6.diff
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
diff -up dwm/dwm.c dwmmod/dwm.c
|
||||||
|
--- dwm/dwm.c 2020-06-25 00:21:30.383692180 -0300
|
||||||
|
+++ dwmmod/dwm.c 2020-06-25 00:20:35.643692330 -0300
|
||||||
|
@@ -1057,6 +1057,8 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
|
updatewindowtype(c);
|
||||||
|
updatesizehints(c);
|
||||||
|
updatewmhints(c);
|
||||||
|
+ c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
|
||||||
|
+ c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
|
||||||
|
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||||
|
grabbuttons(c, 0);
|
||||||
|
if (!c->isfloating)
|
335
dwm/applied_patches/dwm-anybar-20200810-bb2e722.diff
Normal file
335
dwm/applied_patches/dwm-anybar-20200810-bb2e722.diff
Normal file
|
@ -0,0 +1,335 @@
|
||||||
|
From 782f63d8f858b1c14df38aaf623438d7ea2f75e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: mihirlad55 <mihirlad55@gmail.com>
|
||||||
|
Date: Mon, 10 Aug 2020 01:39:35 +0000
|
||||||
|
Subject: [PATCH] Add support for managing external status bars
|
||||||
|
|
||||||
|
This patch allows dwm to manage other status bars such as
|
||||||
|
polybar/lemonbar without them needing to set override-redirect. For
|
||||||
|
all intents and purposes, DWM treats this bar as if it were its own
|
||||||
|
and as a result helps the status bar and DWM live in harmony.
|
||||||
|
|
||||||
|
This has a few advantages
|
||||||
|
* The bar does not block fullscreen windows
|
||||||
|
* DWM makes room for the status bar, so windows do not overlap the bar
|
||||||
|
* The bar can be hidden/killed and DWM will not keep an unsightly gap
|
||||||
|
where the bar was
|
||||||
|
* DWM receives EnterNotify events when your cursor enters the bar
|
||||||
|
|
||||||
|
To use another status bar, set usealtbar to 1 in your config.h and set
|
||||||
|
altbarclass to the class name (can be found using xprop) to the class
|
||||||
|
name of your status bar. Also make sure that if your status bar will
|
||||||
|
be displayed on top, topbar is set to 1 in your config, and if it will
|
||||||
|
be displayed on bottom, topbar is set to 0. This patch does not
|
||||||
|
support bars that are not docked at the top or at the bottom of your
|
||||||
|
monitor.
|
||||||
|
|
||||||
|
The patch is developed at https://github.com/mihirlad55/dwm-anybar
|
||||||
|
---
|
||||||
|
config.def.h | 3 ++
|
||||||
|
dwm.c | 114 ++++++++++++++++++++++++++++++++++++++++++++-------
|
||||||
|
2 files changed, 103 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..d0d60aa 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -5,6 +5,9 @@ static const unsigned int borderpx = 1; /* border pixel of 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 int usealtbar = 1; /* 1 means use non-dwm status bar */
|
||||||
|
+static const char *altbarclass = "Polybar"; /* Alternate bar class name */
|
||||||
|
+static const char *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */
|
||||||
|
static const char *fonts[] = { "monospace:size=10" };
|
||||||
|
static const char dmenufont[] = "monospace:size=10";
|
||||||
|
static const char col_gray1[] = "#222222";
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 9fd0286..f149ab4 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -47,8 +47,8 @@
|
||||||
|
/* macros */
|
||||||
|
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
||||||
|
#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 INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - MAX((x),(m)->mx)) \
|
||||||
|
+ * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - MAX((y),(m)->my)))
|
||||||
|
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
||||||
|
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||||
|
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||||
|
@@ -116,7 +116,7 @@ struct Monitor {
|
||||||
|
float mfact;
|
||||||
|
int nmaster;
|
||||||
|
int num;
|
||||||
|
- int by; /* bar geometry */
|
||||||
|
+ int by, bh; /* bar geometry */
|
||||||
|
int mx, my, mw, mh; /* screen size */
|
||||||
|
int wx, wy, ww, wh; /* window area */
|
||||||
|
unsigned int seltags;
|
||||||
|
@@ -179,6 +179,7 @@ static void incnmaster(const Arg *arg);
|
||||||
|
static void keypress(XEvent *e);
|
||||||
|
static void killclient(const Arg *arg);
|
||||||
|
static void manage(Window w, XWindowAttributes *wa);
|
||||||
|
+static void managealtbar(Window win, XWindowAttributes *wa);
|
||||||
|
static void mappingnotify(XEvent *e);
|
||||||
|
static void maprequest(XEvent *e);
|
||||||
|
static void monocle(Monitor *m);
|
||||||
|
@@ -207,6 +208,7 @@ static void seturgent(Client *c, int urg);
|
||||||
|
static void showhide(Client *c);
|
||||||
|
static void sigchld(int unused);
|
||||||
|
static void spawn(const Arg *arg);
|
||||||
|
+static void spawnbar();
|
||||||
|
static void tag(const Arg *arg);
|
||||||
|
static void tagmon(const Arg *arg);
|
||||||
|
static void tile(Monitor *);
|
||||||
|
@@ -216,6 +218,7 @@ static void toggletag(const Arg *arg);
|
||||||
|
static void toggleview(const Arg *arg);
|
||||||
|
static void unfocus(Client *c, int setfocus);
|
||||||
|
static void unmanage(Client *c, int destroyed);
|
||||||
|
+static void unmanagealtbar(Window w);
|
||||||
|
static void unmapnotify(XEvent *e);
|
||||||
|
static void updatebarpos(Monitor *m);
|
||||||
|
static void updatebars(void);
|
||||||
|
@@ -230,6 +233,7 @@ static void updatewmhints(Client *c);
|
||||||
|
static void view(const Arg *arg);
|
||||||
|
static Client *wintoclient(Window w);
|
||||||
|
static Monitor *wintomon(Window w);
|
||||||
|
+static int wmclasscontains(Window win, const char *class, const char *name);
|
||||||
|
static int xerror(Display *dpy, XErrorEvent *ee);
|
||||||
|
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||||
|
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||||
|
@@ -505,8 +509,10 @@ cleanupmon(Monitor *mon)
|
||||||
|
for (m = mons; m && m->next != mon; m = m->next);
|
||||||
|
m->next = mon->next;
|
||||||
|
}
|
||||||
|
- XUnmapWindow(dpy, mon->barwin);
|
||||||
|
- XDestroyWindow(dpy, mon->barwin);
|
||||||
|
+ if (!usealtbar) {
|
||||||
|
+ XUnmapWindow(dpy, mon->barwin);
|
||||||
|
+ XDestroyWindow(dpy, mon->barwin);
|
||||||
|
+ }
|
||||||
|
free(mon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -568,7 +574,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);
|
||||||
|
+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, m->bh);
|
||||||
|
}
|
||||||
|
focus(NULL);
|
||||||
|
arrange(NULL);
|
||||||
|
@@ -639,6 +645,7 @@ createmon(void)
|
||||||
|
m->nmaster = nmaster;
|
||||||
|
m->showbar = showbar;
|
||||||
|
m->topbar = topbar;
|
||||||
|
+ m->bh = bh;
|
||||||
|
m->lt[0] = &layouts[0];
|
||||||
|
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||||
|
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||||
|
@@ -649,10 +656,13 @@ void
|
||||||
|
destroynotify(XEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
+ Monitor *m;
|
||||||
|
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
||||||
|
|
||||||
|
if ((c = wintoclient(ev->window)))
|
||||||
|
unmanage(c, 1);
|
||||||
|
+ else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
|
||||||
|
+ unmanagealtbar(ev->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -696,6 +706,9 @@ dirtomon(int dir)
|
||||||
|
void
|
||||||
|
drawbar(Monitor *m)
|
||||||
|
{
|
||||||
|
+ if (usealtbar)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
int x, w, tw = 0;
|
||||||
|
int boxs = drw->fonts->h / 9;
|
||||||
|
int boxw = drw->fonts->h / 6 + 2;
|
||||||
|
@@ -1077,6 +1090,25 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
|
focus(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+managealtbar(Window win, XWindowAttributes *wa)
|
||||||
|
+{
|
||||||
|
+ Monitor *m;
|
||||||
|
+ if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ m->barwin = win;
|
||||||
|
+ m->by = wa->y;
|
||||||
|
+ bh = m->bh = wa->height;
|
||||||
|
+ updatebarpos(m);
|
||||||
|
+ arrange(m);
|
||||||
|
+ XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||||
|
+ XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height);
|
||||||
|
+ XMapWindow(dpy, win);
|
||||||
|
+ XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
|
||||||
|
+ (unsigned char *) &win, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
mappingnotify(XEvent *e)
|
||||||
|
{
|
||||||
|
@@ -1097,7 +1129,9 @@ maprequest(XEvent *e)
|
||||||
|
return;
|
||||||
|
if (wa.override_redirect)
|
||||||
|
return;
|
||||||
|
- if (!wintoclient(ev->window))
|
||||||
|
+ if (wmclasscontains(ev->window, altbarclass, ""))
|
||||||
|
+ managealtbar(ev->window, &wa);
|
||||||
|
+ else if (!wintoclient(ev->window))
|
||||||
|
manage(ev->window, &wa);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1393,7 +1427,9 @@ scan(void)
|
||||||
|
if (!XGetWindowAttributes(dpy, wins[i], &wa)
|
||||||
|
|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
|
||||||
|
continue;
|
||||||
|
- if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
|
||||||
|
+ if (wmclasscontains(wins[i], altbarclass, ""))
|
||||||
|
+ managealtbar(wins[i], &wa);
|
||||||
|
+ else if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
|
||||||
|
manage(wins[i], &wa);
|
||||||
|
}
|
||||||
|
for (i = 0; i < num; i++) { /* now the transients */
|
||||||
|
@@ -1546,7 +1582,7 @@ setup(void)
|
||||||
|
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||||
|
die("no fonts could be loaded.");
|
||||||
|
lrpad = drw->fonts->h;
|
||||||
|
- bh = drw->fonts->h + 2;
|
||||||
|
+ bh = usealtbar ? 0 : drw->fonts->h + 2;
|
||||||
|
updategeom();
|
||||||
|
/* init atoms */
|
||||||
|
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
|
||||||
|
@@ -1595,6 +1631,7 @@ setup(void)
|
||||||
|
XSelectInput(dpy, root, wa.event_mask);
|
||||||
|
grabkeys();
|
||||||
|
focus(NULL);
|
||||||
|
+ spawnbar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1653,6 +1690,13 @@ spawn(const Arg *arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+spawnbar()
|
||||||
|
+{
|
||||||
|
+ if (*altbarcmd)
|
||||||
|
+ system(altbarcmd);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
tag(const Arg *arg)
|
||||||
|
{
|
||||||
|
@@ -1704,7 +1748,7 @@ togglebar(const Arg *arg)
|
||||||
|
{
|
||||||
|
selmon->showbar = !selmon->showbar;
|
||||||
|
updatebarpos(selmon);
|
||||||
|
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
||||||
|
+ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, selmon->bh);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1787,10 +1831,26 @@ unmanage(Client *c, int destroyed)
|
||||||
|
arrange(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+unmanagealtbar(Window w)
|
||||||
|
+{
|
||||||
|
+ Monitor *m = wintomon(w);
|
||||||
|
+
|
||||||
|
+ if (!m)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ m->barwin = 0;
|
||||||
|
+ m->by = 0;
|
||||||
|
+ m->bh = 0;
|
||||||
|
+ updatebarpos(m);
|
||||||
|
+ arrange(m);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
unmapnotify(XEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
+ Monitor *m;
|
||||||
|
XUnmapEvent *ev = &e->xunmap;
|
||||||
|
|
||||||
|
if ((c = wintoclient(ev->window))) {
|
||||||
|
@@ -1798,12 +1858,16 @@ unmapnotify(XEvent *e)
|
||||||
|
setclientstate(c, WithdrawnState);
|
||||||
|
else
|
||||||
|
unmanage(c, 0);
|
||||||
|
- }
|
||||||
|
+ } else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
|
||||||
|
+ unmanagealtbar(ev->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
updatebars(void)
|
||||||
|
{
|
||||||
|
+ if (usealtbar)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
Monitor *m;
|
||||||
|
XSetWindowAttributes wa = {
|
||||||
|
.override_redirect = True,
|
||||||
|
@@ -1829,11 +1893,11 @@ updatebarpos(Monitor *m)
|
||||||
|
m->wy = m->my;
|
||||||
|
m->wh = m->mh;
|
||||||
|
if (m->showbar) {
|
||||||
|
- m->wh -= bh;
|
||||||
|
+ m->wh -= m->bh;
|
||||||
|
m->by = m->topbar ? m->wy : m->wy + m->wh;
|
||||||
|
- m->wy = m->topbar ? m->wy + bh : m->wy;
|
||||||
|
+ m->wy = m->topbar ? m->wy + m->bh : m->wy;
|
||||||
|
} else
|
||||||
|
- m->by = -bh;
|
||||||
|
+ m->by = -m->bh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -2077,6 +2141,28 @@ wintomon(Window w)
|
||||||
|
return selmon;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int
|
||||||
|
+wmclasscontains(Window win, const char *class, const char *name)
|
||||||
|
+{
|
||||||
|
+ XClassHint ch = { NULL, NULL };
|
||||||
|
+ int res = 1;
|
||||||
|
+
|
||||||
|
+ if (XGetClassHint(dpy, win, &ch)) {
|
||||||
|
+ if (ch.res_name && strstr(ch.res_name, name) == NULL)
|
||||||
|
+ res = 0;
|
||||||
|
+ if (ch.res_class && strstr(ch.res_class, class) == NULL)
|
||||||
|
+ res = 0;
|
||||||
|
+ } else
|
||||||
|
+ res = 0;
|
||||||
|
+
|
||||||
|
+ if (ch.res_class)
|
||||||
|
+ XFree(ch.res_class);
|
||||||
|
+ if (ch.res_name)
|
||||||
|
+ XFree(ch.res_name);
|
||||||
|
+
|
||||||
|
+ return res;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* There's no way to check accesses to destroyed windows, thus those cases are
|
||||||
|
* ignored (especially on UnmapNotify's). Other types of errors call Xlibs
|
||||||
|
* default error handler, which may call exit. */
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
161
dwm/applied_patches/dwm-ewmhtags-6.2.diff
Normal file
161
dwm/applied_patches/dwm-ewmhtags-6.2.diff
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
From e5f0eefa921e6bad1e6f75faced0c3ae519995b3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ryan Kes <alrayyes@gmail.com>
|
||||||
|
Date: Thu, 28 Mar 2019 14:49:28 +0100
|
||||||
|
Subject: [PATCH] dwm-ewhmtags-6.2
|
||||||
|
|
||||||
|
---
|
||||||
|
dwm.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 48 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..92022a1 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -55,6 +55,7 @@
|
||||||
|
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||||
|
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||||
|
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||||
|
+#define TAGSLENGTH (LENGTH(tags))
|
||||||
|
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||||
|
|
||||||
|
/* enums */
|
||||||
|
@@ -62,7 +63,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||||
|
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
||||||
|
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
||||||
|
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
||||||
|
- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
|
||||||
|
+ NetWMWindowTypeDialog, NetClientList, NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop, NetLast }; /* EWMH atoms */
|
||||||
|
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
|
||||||
|
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
||||||
|
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
|
||||||
|
@@ -197,11 +198,15 @@ static void scan(void);
|
||||||
|
static int sendevent(Client *c, Atom proto);
|
||||||
|
static void sendmon(Client *c, Monitor *m);
|
||||||
|
static void setclientstate(Client *c, long state);
|
||||||
|
+static void setcurrentdesktop(void);
|
||||||
|
+static void setdesktopnames(void);
|
||||||
|
static void setfocus(Client *c);
|
||||||
|
static void setfullscreen(Client *c, int fullscreen);
|
||||||
|
static void setlayout(const Arg *arg);
|
||||||
|
static void setmfact(const Arg *arg);
|
||||||
|
+static void setnumdesktops(void);
|
||||||
|
static void setup(void);
|
||||||
|
+static void setviewport(void);
|
||||||
|
static void seturgent(Client *c, int urg);
|
||||||
|
static void showhide(Client *c);
|
||||||
|
static void sigchld(int unused);
|
||||||
|
@@ -216,6 +221,7 @@ static void toggleview(const Arg *arg);
|
||||||
|
static void unfocus(Client *c, int setfocus);
|
||||||
|
static void unmanage(Client *c, int destroyed);
|
||||||
|
static void unmapnotify(XEvent *e);
|
||||||
|
+static void updatecurrentdesktop(void);
|
||||||
|
static void updatebarpos(Monitor *m);
|
||||||
|
static void updatebars(void);
|
||||||
|
static void updateclientlist(void);
|
||||||
|
@@ -1431,6 +1437,16 @@ setclientstate(Client *c, long state)
|
||||||
|
XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
|
||||||
|
PropModeReplace, (unsigned char *)data, 2);
|
||||||
|
}
|
||||||
|
+void
|
||||||
|
+setcurrentdesktop(void){
|
||||||
|
+ long data[] = { 0 };
|
||||||
|
+ XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
|
||||||
|
+}
|
||||||
|
+void setdesktopnames(void){
|
||||||
|
+ XTextProperty text;
|
||||||
|
+ Xutf8TextListToTextProperty(dpy, tags, TAGSLENGTH, XUTF8StringStyle, &text);
|
||||||
|
+ XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]);
|
||||||
|
+}
|
||||||
|
|
||||||
|
int
|
||||||
|
sendevent(Client *c, Atom proto)
|
||||||
|
@@ -1457,6 +1473,12 @@ sendevent(Client *c, Atom proto)
|
||||||
|
return exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+setnumdesktops(void){
|
||||||
|
+ long data[] = { TAGSLENGTH };
|
||||||
|
+ XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
setfocus(Client *c)
|
||||||
|
{
|
||||||
|
@@ -1562,6 +1584,10 @@ 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);
|
||||||
|
+ netatom[NetDesktopViewport] = XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False);
|
||||||
|
+ netatom[NetNumberOfDesktops] = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
|
||||||
|
+ netatom[NetCurrentDesktop] = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
|
||||||
|
+ netatom[NetDesktopNames] = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False);
|
||||||
|
/* init cursors */
|
||||||
|
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
|
||||||
|
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
|
||||||
|
@@ -1584,6 +1610,10 @@ setup(void)
|
||||||
|
/* EWMH support per view */
|
||||||
|
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
|
||||||
|
PropModeReplace, (unsigned char *) netatom, NetLast);
|
||||||
|
+ setnumdesktops();
|
||||||
|
+ setcurrentdesktop();
|
||||||
|
+ setdesktopnames();
|
||||||
|
+ setviewport();
|
||||||
|
XDeleteProperty(dpy, root, netatom[NetClientList]);
|
||||||
|
/* select events */
|
||||||
|
wa.cursor = cursor[CurNormal]->cursor;
|
||||||
|
@@ -1595,6 +1625,11 @@ setup(void)
|
||||||
|
grabkeys();
|
||||||
|
focus(NULL);
|
||||||
|
}
|
||||||
|
+void
|
||||||
|
+setviewport(void){
|
||||||
|
+ long data[] = { 0, 0 };
|
||||||
|
+ XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2);
|
||||||
|
+}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -1732,6 +1767,7 @@ toggletag(const Arg *arg)
|
||||||
|
focus(NULL);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
+ updatecurrentdesktop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -1744,6 +1780,7 @@ toggleview(const Arg *arg)
|
||||||
|
focus(NULL);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
+ updatecurrentdesktop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -1846,6 +1883,15 @@ updateclientlist()
|
||||||
|
XA_WINDOW, 32, PropModeAppend,
|
||||||
|
(unsigned char *) &(c->win), 1);
|
||||||
|
}
|
||||||
|
+void updatecurrentdesktop(void){
|
||||||
|
+ long rawdata[] = { selmon->tagset[selmon->seltags] };
|
||||||
|
+ int i=0;
|
||||||
|
+ while(*rawdata >> i+1){
|
||||||
|
+ i++;
|
||||||
|
+ }
|
||||||
|
+ long data[] = { i };
|
||||||
|
+ XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
|
||||||
|
+}
|
||||||
|
|
||||||
|
int
|
||||||
|
updategeom(void)
|
||||||
|
@@ -2042,6 +2088,7 @@ view(const Arg *arg)
|
||||||
|
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
||||||
|
focus(NULL);
|
||||||
|
arrange(selmon);
|
||||||
|
+ updatecurrentdesktop();
|
||||||
|
}
|
||||||
|
|
||||||
|
Client *
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
190
dwm/applied_patches/dwm-functionalgaps-6.2.diff
Normal file
190
dwm/applied_patches/dwm-functionalgaps-6.2.diff
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
diff -pur dwm.git/config.def.h dwm.mygaps/config.def.h
|
||||||
|
--- dwm.git/config.def.h 2021-02-27 21:17:53.862314811 -0600
|
||||||
|
+++ dwm.mygaps/config.def.h 2021-02-28 00:06:39.066149441 -0600
|
||||||
|
@@ -2,6 +2,8 @@
|
||||||
|
|
||||||
|
/* appearance */
|
||||||
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
|
+static const int startwithgaps = 0; /* 1 means gaps are used by default */
|
||||||
|
+static const unsigned int gappx = 10; /* default gap between windows in pixels */
|
||||||
|
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 */
|
||||||
|
@@ -84,6 +86,10 @@ 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 = -5 } },
|
||||||
|
+ { MODKEY, XK_equal, setgaps, {.i = +5 } },
|
||||||
|
+ { MODKEY|ShiftMask, XK_minus, setgaps, {.i = GAP_RESET } },
|
||||||
|
+ { MODKEY|ShiftMask, XK_equal, setgaps, {.i = GAP_TOGGLE} },
|
||||||
|
TAGKEYS( XK_1, 0)
|
||||||
|
TAGKEYS( XK_2, 1)
|
||||||
|
TAGKEYS( XK_3, 2)
|
||||||
|
diff -pur dwm.git/dwm.c dwm.mygaps/dwm.c
|
||||||
|
--- dwm.git/dwm.c 2021-02-27 21:17:53.862314811 -0600
|
||||||
|
+++ dwm.mygaps/dwm.c 2021-02-28 00:23:19.232865766 -0600
|
||||||
|
@@ -57,6 +57,9 @@
|
||||||
|
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||||
|
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||||
|
|
||||||
|
+#define GAP_TOGGLE 100
|
||||||
|
+#define GAP_RESET 0
|
||||||
|
+
|
||||||
|
/* enums */
|
||||||
|
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||||
|
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
||||||
|
@@ -119,6 +122,8 @@ struct Monitor {
|
||||||
|
int by; /* bar geometry */
|
||||||
|
int mx, my, mw, mh; /* screen size */
|
||||||
|
int wx, wy, ww, wh; /* window area */
|
||||||
|
+ int gappx; /* gaps between windows */
|
||||||
|
+ int drawwithgaps; /* toggle gaps */
|
||||||
|
unsigned int seltags;
|
||||||
|
unsigned int sellt;
|
||||||
|
unsigned int tagset[2];
|
||||||
|
@@ -200,6 +205,7 @@ static void sendmon(Client *c, Monitor *
|
||||||
|
static void setclientstate(Client *c, long state);
|
||||||
|
static void setfocus(Client *c);
|
||||||
|
static void setfullscreen(Client *c, int fullscreen);
|
||||||
|
+static void setgaps(const Arg *arg);
|
||||||
|
static void setlayout(const Arg *arg);
|
||||||
|
static void setmfact(const Arg *arg);
|
||||||
|
static void setup(void);
|
||||||
|
@@ -639,6 +645,8 @@ createmon(void)
|
||||||
|
m->nmaster = nmaster;
|
||||||
|
m->showbar = showbar;
|
||||||
|
m->topbar = topbar;
|
||||||
|
+ m->gappx = gappx;
|
||||||
|
+ m->drawwithgaps = startwithgaps;
|
||||||
|
m->lt[0] = &layouts[0];
|
||||||
|
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||||
|
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||||
|
@@ -797,6 +805,12 @@ focus(Client *c)
|
||||||
|
attachstack(c);
|
||||||
|
grabbuttons(c, 1);
|
||||||
|
XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
|
||||||
|
+ if (!selmon->drawwithgaps && !c->isfloating) {
|
||||||
|
+ XWindowChanges wc;
|
||||||
|
+ wc.sibling = selmon->barwin;
|
||||||
|
+ wc.stack_mode = Below;
|
||||||
|
+ XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
|
||||||
|
+ }
|
||||||
|
setfocus(c);
|
||||||
|
} else {
|
||||||
|
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
||||||
|
@@ -1113,7 +1127,10 @@ monocle(Monitor *m)
|
||||||
|
if (n > 0) /* override layout symbol */
|
||||||
|
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
|
||||||
|
for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
||||||
|
- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
|
||||||
|
+ if (selmon->drawwithgaps)
|
||||||
|
+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
|
||||||
|
+ else
|
||||||
|
+ resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -1283,6 +1300,15 @@ resizeclient(Client *c, int x, int y, in
|
||||||
|
c->oldw = c->w; c->w = wc.width = w;
|
||||||
|
c->oldh = c->h; c->h = wc.height = h;
|
||||||
|
wc.border_width = c->bw;
|
||||||
|
+ if (!selmon->drawwithgaps && /* this is the noborderfloatingfix patch, slightly modified so that it will work if, and only if, gaps are disabled. */
|
||||||
|
+ (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) /* these two first lines are the only ones changed. if you are manually patching and have noborder installed already, just change these lines; or conversely, just remove this section if the noborder patch is not desired ;) */
|
||||||
|
+ || &monocle == c->mon->lt[c->mon->sellt]->arrange))
|
||||||
|
+ && !c->isfullscreen && !c->isfloating
|
||||||
|
+ && NULL != c->mon->lt[c->mon->sellt]->arrange) {
|
||||||
|
+ c->w = wc.width += c->bw * 2;
|
||||||
|
+ c->h = wc.height += c->bw * 2;
|
||||||
|
+ wc.border_width = 0;
|
||||||
|
+ }
|
||||||
|
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
||||||
|
configure(c);
|
||||||
|
XSync(dpy, False);
|
||||||
|
@@ -1499,6 +1525,26 @@ setfullscreen(Client *c, int fullscreen)
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
+setgaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ switch(arg->i)
|
||||||
|
+ {
|
||||||
|
+ case GAP_TOGGLE:
|
||||||
|
+ selmon->drawwithgaps = !selmon->drawwithgaps;
|
||||||
|
+ break;
|
||||||
|
+ case GAP_RESET:
|
||||||
|
+ selmon->gappx = gappx;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ if (selmon->gappx + arg->i < 0)
|
||||||
|
+ selmon->gappx = 0;
|
||||||
|
+ else
|
||||||
|
+ selmon->gappx += arg->i;
|
||||||
|
+ }
|
||||||
|
+ arrange(selmon);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
setlayout(const Arg *arg)
|
||||||
|
{
|
||||||
|
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
|
||||||
|
@@ -1680,23 +1726,42 @@ tile(Monitor *m)
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
-
|
||||||
|
- if (n > m->nmaster)
|
||||||
|
- mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||||
|
- else
|
||||||
|
- mw = m->ww;
|
||||||
|
- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
- if (i < m->nmaster) {
|
||||||
|
- h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||||
|
- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
|
||||||
|
- if (my + HEIGHT(c) < m->wh)
|
||||||
|
- my += HEIGHT(c);
|
||||||
|
- } else {
|
||||||
|
- h = (m->wh - ty) / (n - i);
|
||||||
|
- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
|
||||||
|
- if (ty + HEIGHT(c) < m->wh)
|
||||||
|
- ty += HEIGHT(c);
|
||||||
|
- }
|
||||||
|
+ if (m->drawwithgaps) { /* draw with fullgaps logic */
|
||||||
|
+ if (n > m->nmaster)
|
||||||
|
+ mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||||
|
+ else
|
||||||
|
+ mw = m->ww - m->gappx;
|
||||||
|
+ for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
+ if (i < m->nmaster) {
|
||||||
|
+ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx;
|
||||||
|
+ resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0);
|
||||||
|
+ if (my + HEIGHT(c) + m->gappx < m->wh)
|
||||||
|
+ my += HEIGHT(c) + m->gappx;
|
||||||
|
+ } else {
|
||||||
|
+ h = (m->wh - ty) / (n - i) - m->gappx;
|
||||||
|
+ resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0);
|
||||||
|
+ if (ty + HEIGHT(c) + m->gappx < m->wh)
|
||||||
|
+ ty += HEIGHT(c) + m->gappx;
|
||||||
|
+ }
|
||||||
|
+ } else { /* draw with singularborders logic */
|
||||||
|
+ if (n > m->nmaster)
|
||||||
|
+ mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||||
|
+ else
|
||||||
|
+ mw = m->ww;
|
||||||
|
+ for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
+ if (i < m->nmaster) {
|
||||||
|
+ h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||||
|
+ if (n == 1)
|
||||||
|
+ resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
|
||||||
|
+ else
|
||||||
|
+ resize(c, m->wx - c->bw, m->wy + my, mw - c->bw, h - c->bw, False);
|
||||||
|
+ my += HEIGHT(c) - c->bw;
|
||||||
|
+ } else {
|
||||||
|
+ h = (m->wh - ty) / (n - i);
|
||||||
|
+ resize(c, m->wx + mw - c->bw, m->wy + ty, m->ww - mw, h - c->bw, False);
|
||||||
|
+ ty += HEIGHT(c) - c->bw;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
242
dwm/applied_patches/dwm-xresources-20210314.diff
Normal file
242
dwm/applied_patches/dwm-xresources-20210314.diff
Normal file
|
@ -0,0 +1,242 @@
|
||||||
|
From d28a26439326d7566a43459e1ef00b5b7c7f5b11 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David JULIEN <swy7ch@protonmail.com>
|
||||||
|
Date: Sun, 14 Mar 2021 18:19:17 +0100
|
||||||
|
Subject: [PATCH] [PATCH] feat: manage font through xrdb
|
||||||
|
|
||||||
|
add font management to the dwm-resources patch, enabling to manage fonts
|
||||||
|
by sourcing $XRESOURCES
|
||||||
|
---
|
||||||
|
config.def.h | 61 ++++++++++++++++++++++++++++++--------------
|
||||||
|
drw.c | 2 +-
|
||||||
|
drw.h | 2 +-
|
||||||
|
dwm.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 116 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..db7b7bb 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -1,21 +1,23 @@
|
||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
|
/* appearance */
|
||||||
|
-static const unsigned int borderpx = 1; /* border pixel of 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 *colors[][3] = {
|
||||||
|
- /* fg bg border */
|
||||||
|
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||||
|
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||||
|
+static unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
|
+static unsigned int snap = 32; /* snap pixel */
|
||||||
|
+static int showbar = 1; /* 0 means no bar */
|
||||||
|
+static int topbar = 1; /* 0 means bottom bar */
|
||||||
|
+static char font[] = "monospace:size=10";
|
||||||
|
+static char dmenufont[] = "monospace:size=10";
|
||||||
|
+static const char *fonts[] = { font };
|
||||||
|
+static char normbgcolor[] = "#222222";
|
||||||
|
+static char normbordercolor[] = "#444444";
|
||||||
|
+static char normfgcolor[] = "#bbbbbb";
|
||||||
|
+static char selfgcolor[] = "#eeeeee";
|
||||||
|
+static char selbordercolor[] = "#005577";
|
||||||
|
+static char selbgcolor[] = "#005577";
|
||||||
|
+static char *colors[][3] = {
|
||||||
|
+ /* fg bg border */
|
||||||
|
+ [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor },
|
||||||
|
+ [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* tagging */
|
||||||
|
@@ -32,9 +34,9 @@ static const Rule rules[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* layout(s) */
|
||||||
|
-static const float mfact = 0.55; /* 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 float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
||||||
|
+static int nmaster = 1; /* number of clients in master area */
|
||||||
|
+static int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||||
|
|
||||||
|
static const Layout layouts[] = {
|
||||||
|
/* symbol arrange function */
|
||||||
|
@@ -56,9 +58,30 @@ 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, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL };
|
||||||
|
static const char *termcmd[] = { "st", NULL };
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Xresources preferences to load at startup
|
||||||
|
+ */
|
||||||
|
+ResourcePref resources[] = {
|
||||||
|
+ { "font", STRING, &font },
|
||||||
|
+ { "dmenufont", STRING, &dmenufont },
|
||||||
|
+ { "normbgcolor", STRING, &normbgcolor },
|
||||||
|
+ { "normbordercolor", STRING, &normbordercolor },
|
||||||
|
+ { "normfgcolor", STRING, &normfgcolor },
|
||||||
|
+ { "selbgcolor", STRING, &selbgcolor },
|
||||||
|
+ { "selbordercolor", STRING, &selbordercolor },
|
||||||
|
+ { "selfgcolor", STRING, &selfgcolor },
|
||||||
|
+ { "borderpx", INTEGER, &borderpx },
|
||||||
|
+ { "snap", INTEGER, &snap },
|
||||||
|
+ { "showbar", INTEGER, &showbar },
|
||||||
|
+ { "topbar", INTEGER, &topbar },
|
||||||
|
+ { "nmaster", INTEGER, &nmaster },
|
||||||
|
+ { "resizehints", INTEGER, &resizehints },
|
||||||
|
+ { "mfact", FLOAT, &mfact },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static Key keys[] = {
|
||||||
|
/* modifier key function argument */
|
||||||
|
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||||
|
diff --git a/drw.c b/drw.c
|
||||||
|
index 4cdbcbe..8f1059e 100644
|
||||||
|
--- a/drw.c
|
||||||
|
+++ b/drw.c
|
||||||
|
@@ -208,7 +208,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||||
|
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||||
|
* returned color scheme when done using it. */
|
||||||
|
Clr *
|
||||||
|
-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||||
|
+drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
Clr *ret;
|
||||||
|
diff --git a/drw.h b/drw.h
|
||||||
|
index 4bcd5ad..42b04ce 100644
|
||||||
|
--- a/drw.h
|
||||||
|
+++ b/drw.h
|
||||||
|
@@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
|
||||||
|
|
||||||
|
/* Colorscheme abstraction */
|
||||||
|
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||||
|
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||||
|
+Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
|
||||||
|
|
||||||
|
/* Cursor abstraction */
|
||||||
|
Cur *drw_cur_create(Drw *drw, int shape);
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 664c527..17bb21e 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -36,6 +36,7 @@
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xproto.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
+#include <X11/Xresource.h>
|
||||||
|
#ifdef XINERAMA
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
#endif /* XINERAMA */
|
||||||
|
@@ -141,6 +142,19 @@ typedef struct {
|
||||||
|
int monitor;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
|
+/* Xresources preferences */
|
||||||
|
+enum resource_type {
|
||||||
|
+ STRING = 0,
|
||||||
|
+ INTEGER = 1,
|
||||||
|
+ FLOAT = 2
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct {
|
||||||
|
+ char *name;
|
||||||
|
+ enum resource_type type;
|
||||||
|
+ void *dst;
|
||||||
|
+} ResourcePref;
|
||||||
|
+
|
||||||
|
/* function declarations */
|
||||||
|
static void applyrules(Client *c);
|
||||||
|
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
|
||||||
|
@@ -234,6 +248,8 @@ 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);
|
||||||
|
+static void load_xresources(void);
|
||||||
|
+static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
|
||||||
|
|
||||||
|
/* variables */
|
||||||
|
static const char broken[] = "broken";
|
||||||
|
@@ -2127,6 +2143,60 @@ zoom(const Arg *arg)
|
||||||
|
pop(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
|
||||||
|
+{
|
||||||
|
+ char *sdst = NULL;
|
||||||
|
+ int *idst = NULL;
|
||||||
|
+ float *fdst = NULL;
|
||||||
|
+
|
||||||
|
+ sdst = dst;
|
||||||
|
+ idst = dst;
|
||||||
|
+ fdst = dst;
|
||||||
|
+
|
||||||
|
+ char fullname[256];
|
||||||
|
+ char *type;
|
||||||
|
+ XrmValue ret;
|
||||||
|
+
|
||||||
|
+ snprintf(fullname, sizeof(fullname), "%s.%s", "dwm", name);
|
||||||
|
+ fullname[sizeof(fullname) - 1] = '\0';
|
||||||
|
+
|
||||||
|
+ XrmGetResource(db, fullname, "*", &type, &ret);
|
||||||
|
+ if (!(ret.addr == NULL || strncmp("String", type, 64)))
|
||||||
|
+ {
|
||||||
|
+ switch (rtype) {
|
||||||
|
+ case STRING:
|
||||||
|
+ strcpy(sdst, ret.addr);
|
||||||
|
+ break;
|
||||||
|
+ case INTEGER:
|
||||||
|
+ *idst = strtoul(ret.addr, NULL, 10);
|
||||||
|
+ break;
|
||||||
|
+ case FLOAT:
|
||||||
|
+ *fdst = strtof(ret.addr, NULL);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+load_xresources(void)
|
||||||
|
+{
|
||||||
|
+ Display *display;
|
||||||
|
+ char *resm;
|
||||||
|
+ XrmDatabase db;
|
||||||
|
+ ResourcePref *p;
|
||||||
|
+
|
||||||
|
+ display = XOpenDisplay(NULL);
|
||||||
|
+ resm = XResourceManagerString(display);
|
||||||
|
+ if (!resm)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ db = XrmGetStringDatabase(resm);
|
||||||
|
+ for (p = resources; p < resources + LENGTH(resources); p++)
|
||||||
|
+ resource_load(db, p->name, p->type, p->dst);
|
||||||
|
+ XCloseDisplay(display);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
@@ -2139,6 +2209,8 @@ main(int argc, char *argv[])
|
||||||
|
if (!(dpy = XOpenDisplay(NULL)))
|
||||||
|
die("dwm: cannot open display");
|
||||||
|
checkotherwm();
|
||||||
|
+ XrmInitialize();
|
||||||
|
+ load_xresources();
|
||||||
|
setup();
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
if (pledge("stdio rpath proc exec", NULL) == -1)
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
|
|
208
dwm/config.def.h
208
dwm/config.def.h
|
@ -1,35 +1,30 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
/* appearance */
|
/* appearance */
|
||||||
static const unsigned int borderpx = 2; /* border pixel of windows */
|
static const int startwithgaps = 0; /* 1 means gaps are used by default */
|
||||||
static const unsigned int snap = 32; /* snap pixel */
|
static const unsigned int gappx = 10;
|
||||||
static const int showbar = 1; /* 0 means no bar */
|
static unsigned int borderpx = 2; /* border pixel of windows */
|
||||||
static const int topbar = 1; /* 0 means bottom bar */
|
static unsigned int snap = 32; /* snap pixel */
|
||||||
static const char *fonts[] = { "monospace:size=10" };
|
static int showbar = 1; /* 0 means no bar */
|
||||||
static const char dmenufont[] = "monospace:size=10";
|
static int topbar = 1; /* 0 means bottom bar */
|
||||||
static const char col_gray1[] = "#222222";
|
static const int usealtbar = 1; /* 1 means use non-dwm status bar */
|
||||||
static const char col_gray2[] = "#444444";
|
static const char *altbarclass = "Polybar"; /* Alternate bar class name */
|
||||||
static const char col_gray3[] = "#bbbbbb";
|
static const char *altbarcmd = "$HOME/.scripts/polybar"; /* Alternate bar launch command */
|
||||||
static const char col_gray4[] = "#eeeeee";
|
static char font[] = "castella:size=12";
|
||||||
static const char col_cyan[] = "#005577";
|
static const char *fonts[] = {font};
|
||||||
|
static char dmenufont[] = "castella:size=12";
|
||||||
// gruvbox
|
static char normbgcolor[] = "#222222";
|
||||||
static const char col_gruvbox0_hard[] = "#1d2021"; // Background (black)
|
static char normbordercolor[] = "#444444";
|
||||||
static const char col_gruvbox0_medium[] = "#282828";
|
static char normfgcolor[] = "#bbbbbb";
|
||||||
static const char col_gruvbox0_soft[] = "#32302f";
|
static char selfgcolor[] = "#eeeeee";
|
||||||
|
static char selbordercolor[] = "#005577";
|
||||||
static const char col_gruvbox7[] = "#a89984"; // White
|
static char selbgcolor[] = "#005577";
|
||||||
static const char col_gruvbox8[] = "#928374";
|
static char *colors[][3] = {
|
||||||
static const char col_gruvbox15[] = "#ebdbb2"; // White
|
/* fg bg border */
|
||||||
|
[SchemeNorm] = {normfgcolor, normbgcolor, normbordercolor},
|
||||||
static const char *colors[][3] = {
|
[SchemeSel] = {selfgcolor, selbgcolor, selbordercolor},
|
||||||
/* fg bg border */
|
|
||||||
[SchemeNorm] = { col_gruvbox7, col_gruvbox0_hard, col_gruvbox0_medium },
|
|
||||||
[SchemeSel] = { col_gruvbox15, col_gruvbox0_medium, col_gruvbox0_soft },
|
|
||||||
};
|
};
|
||||||
|
static char *tags[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"};
|
||||||
/* tagging */
|
|
||||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
|
||||||
|
|
||||||
static const Rule rules[] = {
|
static const Rule rules[] = {
|
||||||
/* xprop(1):
|
/* xprop(1):
|
||||||
|
@ -37,94 +32,117 @@ static const Rule rules[] = {
|
||||||
* WM_NAME(STRING) = title
|
* WM_NAME(STRING) = title
|
||||||
*/
|
*/
|
||||||
/* class instance title tags mask isfloating monitor */
|
/* class instance title tags mask isfloating monitor */
|
||||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
{"Gimp", NULL, NULL, 0, 1, -1},
|
||||||
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
{"Firefox", NULL, NULL, 1 << 8, 0, -1},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* layout(s) */
|
/* layout(s) */
|
||||||
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
static float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
||||||
static const int nmaster = 1; /* number of clients in master area */
|
static int nmaster = 1; /* number of clients in master area */
|
||||||
static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
|
static int resizehints = 0; /* 1 means respect size hints in tiled resizals */
|
||||||
|
|
||||||
|
#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */
|
||||||
|
|
||||||
static const Layout layouts[] = {
|
static const Layout layouts[] = {
|
||||||
/* symbol arrange function */
|
/* symbol arrange function */
|
||||||
{ "[]=", tile }, /* first entry is default */
|
{"[]=", tile}, /* first entry is default */
|
||||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
{"[M]", monocle},
|
||||||
{ "[M]", monocle },
|
{"><>", NULL}, /* no layout function means floating behavior */
|
||||||
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* key definitions */
|
/* key definitions */
|
||||||
#define MODKEY Mod1Mask
|
#define MODKEY Mod1Mask
|
||||||
#define TAGKEYS(KEY,TAG) \
|
#define TAGKEYS(KEY, TAG) \
|
||||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
{MODKEY, KEY, view, {.ui = 1 << TAG}}, \
|
||||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
{MODKEY | ControlMask, KEY, toggleview, {.ui = 1 << TAG}}, \
|
||||||
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
|
{MODKEY | ShiftMask, KEY, tag, {.ui = 1 << TAG}}, \
|
||||||
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
{MODKEY | ControlMask | ShiftMask, KEY, toggletag, {.ui = 1 << TAG}},
|
||||||
|
|
||||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
|
||||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
|
||||||
|
|
||||||
/* commands */
|
/* commands */
|
||||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||||
static const char *dmenucmd[] = { "dmenu_run", "-p", "run", "-m", dmenumon, NULL };
|
static const char *dmenucmd[] = {"dmenu_run", "-p", "run", "-m", dmenumon, NULL};
|
||||||
static const char *termcmd[] = { "st", NULL };
|
static const char *termcmd[] = {"st", NULL};
|
||||||
|
|
||||||
static const char *screenshotscript[] = { "/bin/sh", "-c", "~/.scripts/dwmscreenshot", NULL };
|
/*
|
||||||
static const char *calcscript[] = { "/bin/sh", "-c", "~/.scripts/dmenucalc", NULL };
|
* Xresources preferences to load at startup
|
||||||
|
*/
|
||||||
|
ResourcePref resources[] = {
|
||||||
|
{"font", STRING, &font},
|
||||||
|
{"dmenufont", STRING, &dmenufont},
|
||||||
|
{"normbgcolor", STRING, &normbgcolor},
|
||||||
|
{"normbordercolor", STRING, &normbordercolor},
|
||||||
|
{"normfgcolor", STRING, &normfgcolor},
|
||||||
|
{"selbgcolor", STRING, &selbgcolor},
|
||||||
|
{"selbordercolor", STRING, &selbordercolor},
|
||||||
|
{"selfgcolor", STRING, &selfgcolor},
|
||||||
|
{"borderpx", INTEGER, &borderpx},
|
||||||
|
{"snap", INTEGER, &snap},
|
||||||
|
{"showbar", INTEGER, &showbar},
|
||||||
|
{"topbar", INTEGER, &topbar},
|
||||||
|
{"nmaster", INTEGER, &nmaster},
|
||||||
|
{"resizehints", INTEGER, &resizehints},
|
||||||
|
{"mfact", FLOAT, &mfact},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *screenshotscript[] = {"/bin/sh", "-c", "~/.scripts/dwmscreenshot", NULL};
|
||||||
|
static const char *calcscript[] = {"/bin/sh", "-c", "~/.scripts/dmenucalc", NULL};
|
||||||
|
|
||||||
static Key keys[] = {
|
static Key keys[] = {
|
||||||
/* modifier key function argument */
|
/* modifier key function argument */
|
||||||
{ MODKEY|ShiftMask, XK_o, spawn, { .v = calcscript } },
|
{MODKEY | ShiftMask, XK_o, spawn, {.v = calcscript}},
|
||||||
{ MODKEY|ShiftMask, XK_p, spawn, { .v = screenshotscript } },
|
{MODKEY | ShiftMask, XK_p, spawn, {.v = screenshotscript}},
|
||||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
{MODKEY, XK_p, spawn, {.v = dmenucmd}},
|
||||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
{MODKEY | ShiftMask, XK_Return, spawn, {.v = termcmd}},
|
||||||
{ MODKEY, XK_b, togglebar, {0} },
|
{MODKEY, XK_b, togglebar, {0}},
|
||||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
{MODKEY, XK_j, focusstack, {.i = +1}},
|
||||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
{MODKEY, XK_k, focusstack, {.i = -1}},
|
||||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
{MODKEY, XK_i, incnmaster, {.i = +1}},
|
||||||
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
|
{MODKEY, XK_d, incnmaster, {.i = -1}},
|
||||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
{MODKEY, XK_h, setmfact, {.f = -0.05}},
|
||||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
{MODKEY, XK_l, setmfact, {.f = +0.05}},
|
||||||
{ MODKEY, XK_Return, zoom, {0} },
|
{MODKEY, XK_Return, zoom, {0}},
|
||||||
{ MODKEY, XK_Tab, view, {0} },
|
{MODKEY, XK_Tab, view, {0}},
|
||||||
{ MODKEY, XK_c, killclient, {0} },
|
{MODKEY, XK_c, killclient, {0}},
|
||||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
{MODKEY, XK_t, setlayout, {.v = &layouts[0]}},
|
||||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
{MODKEY, XK_f, setlayout, {.v = &layouts[1]}},
|
||||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
{MODKEY, XK_m, setlayout, {.v = &layouts[2]}},
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
{MODKEY, XK_space, setlayout, {0}},
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
{MODKEY | ShiftMask, XK_space, togglefloating, {0}},
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
{MODKEY, XK_0, view, {.ui = ~0}},
|
||||||
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
|
{MODKEY | ShiftMask, XK_0, tag, {.ui = ~0}},
|
||||||
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
|
{MODKEY, XK_comma, focusmon, {.i = -1}},
|
||||||
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
{MODKEY, XK_period, focusmon, {.i = +1}},
|
||||||
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
{MODKEY | ShiftMask, XK_comma, tagmon, {.i = -1}},
|
||||||
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
{MODKEY | ShiftMask, XK_period, tagmon, {.i = +1}},
|
||||||
TAGKEYS( XK_1, 0)
|
{MODKEY, XK_minus, setgaps, {.i = -5}},
|
||||||
TAGKEYS( XK_2, 1)
|
{MODKEY, XK_equal, setgaps, {.i = +5}},
|
||||||
TAGKEYS( XK_3, 2)
|
{MODKEY | ShiftMask, XK_minus, setgaps, {.i = GAP_RESET}},
|
||||||
TAGKEYS( XK_4, 3)
|
{MODKEY | ShiftMask, XK_equal, setgaps, {.i = GAP_TOGGLE}},
|
||||||
TAGKEYS( XK_5, 4)
|
TAGKEYS(XK_1, 0)
|
||||||
TAGKEYS( XK_6, 5)
|
TAGKEYS(XK_2, 1)
|
||||||
TAGKEYS( XK_7, 6)
|
TAGKEYS(XK_3, 2)
|
||||||
TAGKEYS( XK_8, 7)
|
TAGKEYS(XK_4, 3)
|
||||||
TAGKEYS( XK_9, 8)
|
TAGKEYS(XK_5, 4)
|
||||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
TAGKEYS(XK_6, 5)
|
||||||
|
TAGKEYS(XK_7, 6)
|
||||||
|
TAGKEYS(XK_8, 7)
|
||||||
|
TAGKEYS(XK_9, 8){MODKEY | ShiftMask, XK_q, quit, {0}},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* button definitions */
|
/* button definitions */
|
||||||
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
|
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
|
||||||
static Button buttons[] = {
|
static Button buttons[] = {
|
||||||
/* click event mask button function argument */
|
/* click event mask button function argument */
|
||||||
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
|
{ClkLtSymbol, 0, Button1, setlayout, {0}},
|
||||||
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
|
{ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]}},
|
||||||
{ ClkWinTitle, 0, Button2, zoom, {0} },
|
{ClkWinTitle, 0, Button2, zoom, {0}},
|
||||||
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
|
{ClkStatusText, 0, Button2, spawn, {.v = termcmd}},
|
||||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
{ClkClientWin, MODKEY, Button1, movemouse, {0}},
|
||||||
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
|
{ClkClientWin, MODKEY, Button2, togglefloating, {0}},
|
||||||
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
|
{ClkClientWin, MODKEY, Button3, resizemouse, {0}},
|
||||||
{ ClkTagBar, 0, Button1, view, {0} },
|
{ClkTagBar, 0, Button1, view, {0}},
|
||||||
{ ClkTagBar, 0, Button3, toggleview, {0} },
|
{ClkTagBar, 0, Button3, toggleview, {0}},
|
||||||
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
{ClkTagBar, MODKEY, Button1, tag, {0}},
|
||||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
{ClkTagBar, MODKEY, Button3, toggletag, {0}},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||||
* returned color scheme when done using it. */
|
* returned color scheme when done using it. */
|
||||||
Clr *
|
Clr *
|
||||||
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
Clr *ret;
|
Clr *ret;
|
||||||
|
|
|
@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
|
||||||
|
|
||||||
/* Colorscheme abstraction */
|
/* Colorscheme abstraction */
|
||||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||||
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
|
||||||
|
|
||||||
/* Cursor abstraction */
|
/* Cursor abstraction */
|
||||||
Cur *drw_cur_create(Drw *drw, int shape);
|
Cur *drw_cur_create(Drw *drw, int shape);
|
||||||
|
|
340
dwm/dwm.c
340
dwm/dwm.c
|
@ -36,6 +36,7 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xproto.h>
|
#include <X11/Xproto.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xresource.h>
|
||||||
#ifdef XINERAMA
|
#ifdef XINERAMA
|
||||||
#include <X11/extensions/Xinerama.h>
|
#include <X11/extensions/Xinerama.h>
|
||||||
#endif /* XINERAMA */
|
#endif /* XINERAMA */
|
||||||
|
@ -47,22 +48,26 @@
|
||||||
/* macros */
|
/* macros */
|
||||||
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
||||||
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
#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)) \
|
#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - MAX((x),(m)->mx)) \
|
||||||
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
* MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - MAX((y),(m)->my)))
|
||||||
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
||||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||||
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||||
|
#define TAGSLENGTH (LENGTH(tags))
|
||||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||||
|
|
||||||
|
#define GAP_TOGGLE 100
|
||||||
|
#define GAP_RESET 0
|
||||||
|
|
||||||
/* enums */
|
/* enums */
|
||||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||||
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
||||||
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
||||||
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
||||||
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
|
NetWMWindowTypeDialog, NetClientList, NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop, NetLast }; /* EWMH atoms */
|
||||||
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
|
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
|
||||||
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
||||||
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
|
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
|
||||||
|
@ -116,9 +121,11 @@ struct Monitor {
|
||||||
float mfact;
|
float mfact;
|
||||||
int nmaster;
|
int nmaster;
|
||||||
int num;
|
int num;
|
||||||
int by; /* bar geometry */
|
int by, bh; /* bar geometry */
|
||||||
int mx, my, mw, mh; /* screen size */
|
int mx, my, mw, mh; /* screen size */
|
||||||
int wx, wy, ww, wh; /* window area */
|
int wx, wy, ww, wh; /* window area */
|
||||||
|
int gappx; /* gaps between windows */
|
||||||
|
int drawwithgaps; /* toggle gaps */
|
||||||
unsigned int seltags;
|
unsigned int seltags;
|
||||||
unsigned int sellt;
|
unsigned int sellt;
|
||||||
unsigned int tagset[2];
|
unsigned int tagset[2];
|
||||||
|
@ -141,6 +148,19 @@ typedef struct {
|
||||||
int monitor;
|
int monitor;
|
||||||
} Rule;
|
} Rule;
|
||||||
|
|
||||||
|
/* Xresources preferences */
|
||||||
|
enum resource_type {
|
||||||
|
STRING = 0,
|
||||||
|
INTEGER = 1,
|
||||||
|
FLOAT = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
enum resource_type type;
|
||||||
|
void *dst;
|
||||||
|
} ResourcePref;
|
||||||
|
|
||||||
/* function declarations */
|
/* function declarations */
|
||||||
static void applyrules(Client *c);
|
static void applyrules(Client *c);
|
||||||
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
|
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
|
||||||
|
@ -179,6 +199,7 @@ static void incnmaster(const Arg *arg);
|
||||||
static void keypress(XEvent *e);
|
static void keypress(XEvent *e);
|
||||||
static void killclient(const Arg *arg);
|
static void killclient(const Arg *arg);
|
||||||
static void manage(Window w, XWindowAttributes *wa);
|
static void manage(Window w, XWindowAttributes *wa);
|
||||||
|
static void managealtbar(Window win, XWindowAttributes *wa);
|
||||||
static void mappingnotify(XEvent *e);
|
static void mappingnotify(XEvent *e);
|
||||||
static void maprequest(XEvent *e);
|
static void maprequest(XEvent *e);
|
||||||
static void monocle(Monitor *m);
|
static void monocle(Monitor *m);
|
||||||
|
@ -198,15 +219,21 @@ static void scan(void);
|
||||||
static int sendevent(Client *c, Atom proto);
|
static int sendevent(Client *c, Atom proto);
|
||||||
static void sendmon(Client *c, Monitor *m);
|
static void sendmon(Client *c, Monitor *m);
|
||||||
static void setclientstate(Client *c, long state);
|
static void setclientstate(Client *c, long state);
|
||||||
|
static void setcurrentdesktop(void);
|
||||||
|
static void setdesktopnames(void);
|
||||||
static void setfocus(Client *c);
|
static void setfocus(Client *c);
|
||||||
static void setfullscreen(Client *c, int fullscreen);
|
static void setfullscreen(Client *c, int fullscreen);
|
||||||
|
static void setgaps(const Arg *arg);
|
||||||
static void setlayout(const Arg *arg);
|
static void setlayout(const Arg *arg);
|
||||||
static void setmfact(const Arg *arg);
|
static void setmfact(const Arg *arg);
|
||||||
|
static void setnumdesktops(void);
|
||||||
static void setup(void);
|
static void setup(void);
|
||||||
|
static void setviewport(void);
|
||||||
static void seturgent(Client *c, int urg);
|
static void seturgent(Client *c, int urg);
|
||||||
static void showhide(Client *c);
|
static void showhide(Client *c);
|
||||||
static void sigchld(int unused);
|
static void sigchld(int unused);
|
||||||
static void spawn(const Arg *arg);
|
static void spawn(const Arg *arg);
|
||||||
|
static void spawnbar();
|
||||||
static void tag(const Arg *arg);
|
static void tag(const Arg *arg);
|
||||||
static void tagmon(const Arg *arg);
|
static void tagmon(const Arg *arg);
|
||||||
static void tile(Monitor *);
|
static void tile(Monitor *);
|
||||||
|
@ -216,7 +243,9 @@ static void toggletag(const Arg *arg);
|
||||||
static void toggleview(const Arg *arg);
|
static void toggleview(const Arg *arg);
|
||||||
static void unfocus(Client *c, int setfocus);
|
static void unfocus(Client *c, int setfocus);
|
||||||
static void unmanage(Client *c, int destroyed);
|
static void unmanage(Client *c, int destroyed);
|
||||||
|
static void unmanagealtbar(Window w);
|
||||||
static void unmapnotify(XEvent *e);
|
static void unmapnotify(XEvent *e);
|
||||||
|
static void updatecurrentdesktop(void);
|
||||||
static void updatebarpos(Monitor *m);
|
static void updatebarpos(Monitor *m);
|
||||||
static void updatebars(void);
|
static void updatebars(void);
|
||||||
static void updateclientlist(void);
|
static void updateclientlist(void);
|
||||||
|
@ -230,10 +259,13 @@ static void updatewmhints(Client *c);
|
||||||
static void view(const Arg *arg);
|
static void view(const Arg *arg);
|
||||||
static Client *wintoclient(Window w);
|
static Client *wintoclient(Window w);
|
||||||
static Monitor *wintomon(Window w);
|
static Monitor *wintomon(Window w);
|
||||||
|
static int wmclasscontains(Window win, const char *class, const char *name);
|
||||||
static int xerror(Display *dpy, XErrorEvent *ee);
|
static int xerror(Display *dpy, XErrorEvent *ee);
|
||||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||||
static void zoom(const Arg *arg);
|
static void zoom(const Arg *arg);
|
||||||
|
static void load_xresources(void);
|
||||||
|
static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
static const char broken[] = "broken";
|
static const char broken[] = "broken";
|
||||||
|
@ -505,8 +537,10 @@ cleanupmon(Monitor *mon)
|
||||||
for (m = mons; m && m->next != mon; m = m->next);
|
for (m = mons; m && m->next != mon; m = m->next);
|
||||||
m->next = mon->next;
|
m->next = mon->next;
|
||||||
}
|
}
|
||||||
XUnmapWindow(dpy, mon->barwin);
|
if (!usealtbar) {
|
||||||
XDestroyWindow(dpy, mon->barwin);
|
XUnmapWindow(dpy, mon->barwin);
|
||||||
|
XDestroyWindow(dpy, mon->barwin);
|
||||||
|
}
|
||||||
free(mon);
|
free(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +602,7 @@ configurenotify(XEvent *e)
|
||||||
for (c = m->clients; c; c = c->next)
|
for (c = m->clients; c; c = c->next)
|
||||||
if (c->isfullscreen)
|
if (c->isfullscreen)
|
||||||
resizeclient(c, m->mx, m->my, m->mw, m->mh);
|
resizeclient(c, m->mx, m->my, m->mw, m->mh);
|
||||||
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
|
XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, m->bh);
|
||||||
}
|
}
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
arrange(NULL);
|
arrange(NULL);
|
||||||
|
@ -639,6 +673,9 @@ createmon(void)
|
||||||
m->nmaster = nmaster;
|
m->nmaster = nmaster;
|
||||||
m->showbar = showbar;
|
m->showbar = showbar;
|
||||||
m->topbar = topbar;
|
m->topbar = topbar;
|
||||||
|
m->bh = bh;
|
||||||
|
m->gappx = gappx;
|
||||||
|
m->drawwithgaps = startwithgaps;
|
||||||
m->lt[0] = &layouts[0];
|
m->lt[0] = &layouts[0];
|
||||||
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||||
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||||
|
@ -649,10 +686,13 @@ void
|
||||||
destroynotify(XEvent *e)
|
destroynotify(XEvent *e)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
|
Monitor *m;
|
||||||
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
||||||
|
|
||||||
if ((c = wintoclient(ev->window)))
|
if ((c = wintoclient(ev->window)))
|
||||||
unmanage(c, 1);
|
unmanage(c, 1);
|
||||||
|
else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
|
||||||
|
unmanagealtbar(ev->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -696,6 +736,9 @@ dirtomon(int dir)
|
||||||
void
|
void
|
||||||
drawbar(Monitor *m)
|
drawbar(Monitor *m)
|
||||||
{
|
{
|
||||||
|
if (usealtbar)
|
||||||
|
return;
|
||||||
|
|
||||||
int x, w, tw = 0;
|
int x, w, tw = 0;
|
||||||
int boxs = drw->fonts->h / 9;
|
int boxs = drw->fonts->h / 9;
|
||||||
int boxw = drw->fonts->h / 6 + 2;
|
int boxw = drw->fonts->h / 6 + 2;
|
||||||
|
@ -797,6 +840,12 @@ focus(Client *c)
|
||||||
attachstack(c);
|
attachstack(c);
|
||||||
grabbuttons(c, 1);
|
grabbuttons(c, 1);
|
||||||
XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
|
XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
|
||||||
|
if (!selmon->drawwithgaps && !c->isfloating) {
|
||||||
|
XWindowChanges wc;
|
||||||
|
wc.sibling = selmon->barwin;
|
||||||
|
wc.stack_mode = Below;
|
||||||
|
XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
|
||||||
|
}
|
||||||
setfocus(c);
|
setfocus(c);
|
||||||
} else {
|
} else {
|
||||||
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
||||||
|
@ -835,7 +884,7 @@ focusstack(const Arg *arg)
|
||||||
{
|
{
|
||||||
Client *c = NULL, *i;
|
Client *c = NULL, *i;
|
||||||
|
|
||||||
if (!selmon->sel)
|
if (!selmon->sel || selmon->sel->isfullscreen)
|
||||||
return;
|
return;
|
||||||
if (arg->i > 0) {
|
if (arg->i > 0) {
|
||||||
for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
|
for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
|
||||||
|
@ -1057,6 +1106,8 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
updatewindowtype(c);
|
updatewindowtype(c);
|
||||||
updatesizehints(c);
|
updatesizehints(c);
|
||||||
updatewmhints(c);
|
updatewmhints(c);
|
||||||
|
c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
|
||||||
|
c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
|
||||||
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||||
grabbuttons(c, 0);
|
grabbuttons(c, 0);
|
||||||
if (!c->isfloating)
|
if (!c->isfloating)
|
||||||
|
@ -1077,6 +1128,25 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
managealtbar(Window win, XWindowAttributes *wa)
|
||||||
|
{
|
||||||
|
Monitor *m;
|
||||||
|
if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m->barwin = win;
|
||||||
|
m->by = wa->y;
|
||||||
|
bh = m->bh = wa->height;
|
||||||
|
updatebarpos(m);
|
||||||
|
arrange(m);
|
||||||
|
XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||||
|
XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height);
|
||||||
|
XMapWindow(dpy, win);
|
||||||
|
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
|
||||||
|
(unsigned char *) &win, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mappingnotify(XEvent *e)
|
mappingnotify(XEvent *e)
|
||||||
{
|
{
|
||||||
|
@ -1097,7 +1167,9 @@ maprequest(XEvent *e)
|
||||||
return;
|
return;
|
||||||
if (wa.override_redirect)
|
if (wa.override_redirect)
|
||||||
return;
|
return;
|
||||||
if (!wintoclient(ev->window))
|
if (wmclasscontains(ev->window, altbarclass, ""))
|
||||||
|
managealtbar(ev->window, &wa);
|
||||||
|
else if (!wintoclient(ev->window))
|
||||||
manage(ev->window, &wa);
|
manage(ev->window, &wa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,7 +1185,10 @@ monocle(Monitor *m)
|
||||||
if (n > 0) /* override layout symbol */
|
if (n > 0) /* override layout symbol */
|
||||||
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
|
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
|
||||||
for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
||||||
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
|
if (selmon->drawwithgaps)
|
||||||
|
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
|
||||||
|
else
|
||||||
|
resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1283,6 +1358,15 @@ resizeclient(Client *c, int x, int y, int w, int h)
|
||||||
c->oldw = c->w; c->w = wc.width = w;
|
c->oldw = c->w; c->w = wc.width = w;
|
||||||
c->oldh = c->h; c->h = wc.height = h;
|
c->oldh = c->h; c->h = wc.height = h;
|
||||||
wc.border_width = c->bw;
|
wc.border_width = c->bw;
|
||||||
|
if (!selmon->drawwithgaps && /* this is the noborderfloatingfix patch, slightly modified so that it will work if, and only if, gaps are disabled. */
|
||||||
|
(((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) /* these two first lines are the only ones changed. if you are manually patching and have noborder installed already, just change these lines; or conversely, just remove this section if the noborder patch is not desired ;) */
|
||||||
|
|| &monocle == c->mon->lt[c->mon->sellt]->arrange))
|
||||||
|
&& !c->isfullscreen && !c->isfloating
|
||||||
|
&& NULL != c->mon->lt[c->mon->sellt]->arrange) {
|
||||||
|
c->w = wc.width += c->bw * 2;
|
||||||
|
c->h = wc.height += c->bw * 2;
|
||||||
|
wc.border_width = 0;
|
||||||
|
}
|
||||||
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
||||||
configure(c);
|
configure(c);
|
||||||
XSync(dpy, False);
|
XSync(dpy, False);
|
||||||
|
@ -1393,7 +1477,9 @@ scan(void)
|
||||||
if (!XGetWindowAttributes(dpy, wins[i], &wa)
|
if (!XGetWindowAttributes(dpy, wins[i], &wa)
|
||||||
|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
|
|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
|
||||||
continue;
|
continue;
|
||||||
if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
|
if (wmclasscontains(wins[i], altbarclass, ""))
|
||||||
|
managealtbar(wins[i], &wa);
|
||||||
|
else if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
|
||||||
manage(wins[i], &wa);
|
manage(wins[i], &wa);
|
||||||
}
|
}
|
||||||
for (i = 0; i < num; i++) { /* now the transients */
|
for (i = 0; i < num; i++) { /* now the transients */
|
||||||
|
@ -1432,6 +1518,16 @@ setclientstate(Client *c, long state)
|
||||||
XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
|
XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
|
||||||
PropModeReplace, (unsigned char *)data, 2);
|
PropModeReplace, (unsigned char *)data, 2);
|
||||||
}
|
}
|
||||||
|
void
|
||||||
|
setcurrentdesktop(void){
|
||||||
|
long data[] = { 0 };
|
||||||
|
XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
|
||||||
|
}
|
||||||
|
void setdesktopnames(void){
|
||||||
|
XTextProperty text;
|
||||||
|
Xutf8TextListToTextProperty(dpy, tags, TAGSLENGTH, XUTF8StringStyle, &text);
|
||||||
|
XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sendevent(Client *c, Atom proto)
|
sendevent(Client *c, Atom proto)
|
||||||
|
@ -1458,6 +1554,12 @@ sendevent(Client *c, Atom proto)
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setnumdesktops(void){
|
||||||
|
long data[] = { TAGSLENGTH };
|
||||||
|
XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setfocus(Client *c)
|
setfocus(Client *c)
|
||||||
{
|
{
|
||||||
|
@ -1498,6 +1600,26 @@ setfullscreen(Client *c, int fullscreen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setgaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
switch(arg->i)
|
||||||
|
{
|
||||||
|
case GAP_TOGGLE:
|
||||||
|
selmon->drawwithgaps = !selmon->drawwithgaps;
|
||||||
|
break;
|
||||||
|
case GAP_RESET:
|
||||||
|
selmon->gappx = gappx;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (selmon->gappx + arg->i < 0)
|
||||||
|
selmon->gappx = 0;
|
||||||
|
else
|
||||||
|
selmon->gappx += arg->i;
|
||||||
|
}
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setlayout(const Arg *arg)
|
setlayout(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
@ -1546,7 +1668,7 @@ setup(void)
|
||||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||||
die("no fonts could be loaded.");
|
die("no fonts could be loaded.");
|
||||||
lrpad = drw->fonts->h;
|
lrpad = drw->fonts->h;
|
||||||
bh = drw->fonts->h + 2;
|
bh = usealtbar ? 0 : drw->fonts->h + 2;
|
||||||
updategeom();
|
updategeom();
|
||||||
/* init atoms */
|
/* init atoms */
|
||||||
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
|
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
|
||||||
|
@ -1563,6 +1685,10 @@ setup(void)
|
||||||
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
|
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
|
||||||
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||||
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
|
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
|
||||||
|
netatom[NetDesktopViewport] = XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False);
|
||||||
|
netatom[NetNumberOfDesktops] = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
|
||||||
|
netatom[NetCurrentDesktop] = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
|
||||||
|
netatom[NetDesktopNames] = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False);
|
||||||
/* init cursors */
|
/* init cursors */
|
||||||
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
|
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
|
||||||
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
|
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
|
||||||
|
@ -1585,6 +1711,10 @@ setup(void)
|
||||||
/* EWMH support per view */
|
/* EWMH support per view */
|
||||||
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
|
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
|
||||||
PropModeReplace, (unsigned char *) netatom, NetLast);
|
PropModeReplace, (unsigned char *) netatom, NetLast);
|
||||||
|
setnumdesktops();
|
||||||
|
setcurrentdesktop();
|
||||||
|
setdesktopnames();
|
||||||
|
setviewport();
|
||||||
XDeleteProperty(dpy, root, netatom[NetClientList]);
|
XDeleteProperty(dpy, root, netatom[NetClientList]);
|
||||||
/* select events */
|
/* select events */
|
||||||
wa.cursor = cursor[CurNormal]->cursor;
|
wa.cursor = cursor[CurNormal]->cursor;
|
||||||
|
@ -1595,6 +1725,12 @@ setup(void)
|
||||||
XSelectInput(dpy, root, wa.event_mask);
|
XSelectInput(dpy, root, wa.event_mask);
|
||||||
grabkeys();
|
grabkeys();
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
|
spawnbar();
|
||||||
|
}
|
||||||
|
void
|
||||||
|
setviewport(void){
|
||||||
|
long data[] = { 0, 0 };
|
||||||
|
XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1653,6 +1789,13 @@ spawn(const Arg *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spawnbar()
|
||||||
|
{
|
||||||
|
if (*altbarcmd)
|
||||||
|
system(altbarcmd);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tag(const Arg *arg)
|
tag(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
@ -1680,23 +1823,42 @@ tile(Monitor *m)
|
||||||
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return;
|
return;
|
||||||
|
if (m->drawwithgaps) { /* draw with fullgaps logic */
|
||||||
if (n > m->nmaster)
|
if (n > m->nmaster)
|
||||||
mw = m->nmaster ? m->ww * m->mfact : 0;
|
mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||||
else
|
else
|
||||||
mw = m->ww;
|
mw = m->ww - m->gappx;
|
||||||
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
if (i < m->nmaster) {
|
if (i < m->nmaster) {
|
||||||
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx;
|
||||||
resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
|
resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0);
|
||||||
if (my + HEIGHT(c) < m->wh)
|
if (my + HEIGHT(c) + m->gappx < m->wh)
|
||||||
my += HEIGHT(c);
|
my += HEIGHT(c) + m->gappx;
|
||||||
} else {
|
} else {
|
||||||
h = (m->wh - ty) / (n - i);
|
h = (m->wh - ty) / (n - i) - m->gappx;
|
||||||
resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
|
resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0);
|
||||||
if (ty + HEIGHT(c) < m->wh)
|
if (ty + HEIGHT(c) + m->gappx < m->wh)
|
||||||
ty += HEIGHT(c);
|
ty += HEIGHT(c) + m->gappx;
|
||||||
}
|
}
|
||||||
|
} else { /* draw with singularborders logic */
|
||||||
|
if (n > m->nmaster)
|
||||||
|
mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||||
|
else
|
||||||
|
mw = m->ww;
|
||||||
|
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||||
|
if (n == 1)
|
||||||
|
resize(c, m->wx - c->bw, m->wy, m->ww, m->wh, False);
|
||||||
|
else
|
||||||
|
resize(c, m->wx - c->bw, m->wy + my, mw - c->bw, h - c->bw, False);
|
||||||
|
my += HEIGHT(c) - c->bw;
|
||||||
|
} else {
|
||||||
|
h = (m->wh - ty) / (n - i);
|
||||||
|
resize(c, m->wx + mw - c->bw, m->wy + ty, m->ww - mw, h - c->bw, False);
|
||||||
|
ty += HEIGHT(c) - c->bw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1704,7 +1866,7 @@ togglebar(const Arg *arg)
|
||||||
{
|
{
|
||||||
selmon->showbar = !selmon->showbar;
|
selmon->showbar = !selmon->showbar;
|
||||||
updatebarpos(selmon);
|
updatebarpos(selmon);
|
||||||
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, selmon->bh);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1735,6 +1897,7 @@ toggletag(const Arg *arg)
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
updatecurrentdesktop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1747,6 +1910,7 @@ toggleview(const Arg *arg)
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
updatecurrentdesktop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1787,10 +1951,26 @@ unmanage(Client *c, int destroyed)
|
||||||
arrange(m);
|
arrange(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unmanagealtbar(Window w)
|
||||||
|
{
|
||||||
|
Monitor *m = wintomon(w);
|
||||||
|
|
||||||
|
if (!m)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m->barwin = 0;
|
||||||
|
m->by = 0;
|
||||||
|
m->bh = 0;
|
||||||
|
updatebarpos(m);
|
||||||
|
arrange(m);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
unmapnotify(XEvent *e)
|
unmapnotify(XEvent *e)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
|
Monitor *m;
|
||||||
XUnmapEvent *ev = &e->xunmap;
|
XUnmapEvent *ev = &e->xunmap;
|
||||||
|
|
||||||
if ((c = wintoclient(ev->window))) {
|
if ((c = wintoclient(ev->window))) {
|
||||||
|
@ -1798,12 +1978,16 @@ unmapnotify(XEvent *e)
|
||||||
setclientstate(c, WithdrawnState);
|
setclientstate(c, WithdrawnState);
|
||||||
else
|
else
|
||||||
unmanage(c, 0);
|
unmanage(c, 0);
|
||||||
}
|
} else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
|
||||||
|
unmanagealtbar(ev->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updatebars(void)
|
updatebars(void)
|
||||||
{
|
{
|
||||||
|
if (usealtbar)
|
||||||
|
return;
|
||||||
|
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
XSetWindowAttributes wa = {
|
XSetWindowAttributes wa = {
|
||||||
.override_redirect = True,
|
.override_redirect = True,
|
||||||
|
@ -1829,11 +2013,11 @@ updatebarpos(Monitor *m)
|
||||||
m->wy = m->my;
|
m->wy = m->my;
|
||||||
m->wh = m->mh;
|
m->wh = m->mh;
|
||||||
if (m->showbar) {
|
if (m->showbar) {
|
||||||
m->wh -= bh;
|
m->wh -= m->bh;
|
||||||
m->by = m->topbar ? m->wy : m->wy + m->wh;
|
m->by = m->topbar ? m->wy : m->wy + m->wh;
|
||||||
m->wy = m->topbar ? m->wy + bh : m->wy;
|
m->wy = m->topbar ? m->wy + m->bh : m->wy;
|
||||||
} else
|
} else
|
||||||
m->by = -bh;
|
m->by = -m->bh;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1849,6 +2033,15 @@ updateclientlist()
|
||||||
XA_WINDOW, 32, PropModeAppend,
|
XA_WINDOW, 32, PropModeAppend,
|
||||||
(unsigned char *) &(c->win), 1);
|
(unsigned char *) &(c->win), 1);
|
||||||
}
|
}
|
||||||
|
void updatecurrentdesktop(void){
|
||||||
|
long rawdata[] = { selmon->tagset[selmon->seltags] };
|
||||||
|
int i=0;
|
||||||
|
while(*rawdata >> (i+1)){
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
long data[] = { i };
|
||||||
|
XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
updategeom(void)
|
updategeom(void)
|
||||||
|
@ -2045,6 +2238,7 @@ view(const Arg *arg)
|
||||||
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
||||||
focus(NULL);
|
focus(NULL);
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
|
updatecurrentdesktop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Client *
|
Client *
|
||||||
|
@ -2077,6 +2271,28 @@ wintomon(Window w)
|
||||||
return selmon;
|
return selmon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
wmclasscontains(Window win, const char *class, const char *name)
|
||||||
|
{
|
||||||
|
XClassHint ch = { NULL, NULL };
|
||||||
|
int res = 1;
|
||||||
|
|
||||||
|
if (XGetClassHint(dpy, win, &ch)) {
|
||||||
|
if (ch.res_name && strstr(ch.res_name, name) == NULL)
|
||||||
|
res = 0;
|
||||||
|
if (ch.res_class && strstr(ch.res_class, class) == NULL)
|
||||||
|
res = 0;
|
||||||
|
} else
|
||||||
|
res = 0;
|
||||||
|
|
||||||
|
if (ch.res_class)
|
||||||
|
XFree(ch.res_class);
|
||||||
|
if (ch.res_name)
|
||||||
|
XFree(ch.res_name);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/* There's no way to check accesses to destroyed windows, thus those cases are
|
/* There's no way to check accesses to destroyed windows, thus those cases are
|
||||||
* ignored (especially on UnmapNotify's). Other types of errors call Xlibs
|
* ignored (especially on UnmapNotify's). Other types of errors call Xlibs
|
||||||
* default error handler, which may call exit. */
|
* default error handler, which may call exit. */
|
||||||
|
@ -2127,6 +2343,60 @@ zoom(const Arg *arg)
|
||||||
pop(c);
|
pop(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
|
||||||
|
{
|
||||||
|
char *sdst = NULL;
|
||||||
|
int *idst = NULL;
|
||||||
|
float *fdst = NULL;
|
||||||
|
|
||||||
|
sdst = dst;
|
||||||
|
idst = dst;
|
||||||
|
fdst = dst;
|
||||||
|
|
||||||
|
char fullname[256];
|
||||||
|
char *type;
|
||||||
|
XrmValue ret;
|
||||||
|
|
||||||
|
snprintf(fullname, sizeof(fullname), "%s.%s", "dwm", name);
|
||||||
|
fullname[sizeof(fullname) - 1] = '\0';
|
||||||
|
|
||||||
|
XrmGetResource(db, fullname, "*", &type, &ret);
|
||||||
|
if (!(ret.addr == NULL || strncmp("String", type, 64)))
|
||||||
|
{
|
||||||
|
switch (rtype) {
|
||||||
|
case STRING:
|
||||||
|
strcpy(sdst, ret.addr);
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
*idst = strtoul(ret.addr, NULL, 10);
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
*fdst = strtof(ret.addr, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
load_xresources(void)
|
||||||
|
{
|
||||||
|
Display *display;
|
||||||
|
char *resm;
|
||||||
|
XrmDatabase db;
|
||||||
|
ResourcePref *p;
|
||||||
|
|
||||||
|
display = XOpenDisplay(NULL);
|
||||||
|
resm = XResourceManagerString(display);
|
||||||
|
if (!resm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
db = XrmGetStringDatabase(resm);
|
||||||
|
for (p = resources; p < resources + LENGTH(resources); p++)
|
||||||
|
resource_load(db, p->name, p->type, p->dst);
|
||||||
|
XCloseDisplay(display);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -2139,6 +2409,8 @@ main(int argc, char *argv[])
|
||||||
if (!(dpy = XOpenDisplay(NULL)))
|
if (!(dpy = XOpenDisplay(NULL)))
|
||||||
die("dwm: cannot open display");
|
die("dwm: cannot open display");
|
||||||
checkotherwm();
|
checkotherwm();
|
||||||
|
XrmInitialize();
|
||||||
|
load_xresources();
|
||||||
setup();
|
setup();
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
if (pledge("stdio rpath proc exec", NULL) == -1)
|
if (pledge("stdio rpath proc exec", NULL) == -1)
|
||||||
|
|
10
dwm/test.sh
10
dwm/test.sh
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# This script is a dirty hack, just so I can test my config quicky.
|
|
||||||
|
|
||||||
rm config.h
|
|
||||||
make
|
|
||||||
|
|
||||||
Xephyr -br -ac -noreset -screen 1280x800 :1 &
|
|
||||||
sleep 0.6
|
|
||||||
DISPLAY=:1 ./dwm &
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
SRC = st.c x.c
|
SRC = st.c x.c hb.c
|
||||||
OBJ = $(SRC:.c=.o)
|
OBJ = $(SRC:.c=.o)
|
||||||
|
|
||||||
all: options st
|
all: options st
|
||||||
|
@ -22,7 +22,8 @@ config.h:
|
||||||
$(CC) $(STCFLAGS) -c $<
|
$(CC) $(STCFLAGS) -c $<
|
||||||
|
|
||||||
st.o: config.h st.h win.h
|
st.o: config.h st.h win.h
|
||||||
x.o: arg.h config.h st.h win.h
|
x.o: arg.h config.h st.h win.h hb.h
|
||||||
|
hb.o: st.h
|
||||||
|
|
||||||
$(OBJ): config.h config.mk
|
$(OBJ): config.h config.mk
|
||||||
|
|
||||||
|
|
184
st/applied_patches/st-xresources-20200604-9ba7ecf.diff
Normal file
184
st/applied_patches/st-xresources-20200604-9ba7ecf.diff
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
From 2752a599ee01305a435729bfacf43b1dde7cf0ef Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benji Encalada Mora <benji@encalada.dev>
|
||||||
|
Date: Thu, 4 Jun 2020 00:41:10 -0500
|
||||||
|
Subject: [PATCH] fix: replace xfps and actionfps variables
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 36 ++++++++++++++++++++++++
|
||||||
|
x.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||||
|
2 files changed, 110 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 6f05dce..9b99782 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -168,6 +168,42 @@ static unsigned int defaultattr = 11;
|
||||||
|
*/
|
||||||
|
static uint forcemousemod = ShiftMask;
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Xresources preferences to load at startup
|
||||||
|
+ */
|
||||||
|
+ResourcePref resources[] = {
|
||||||
|
+ { "font", STRING, &font },
|
||||||
|
+ { "color0", STRING, &colorname[0] },
|
||||||
|
+ { "color1", STRING, &colorname[1] },
|
||||||
|
+ { "color2", STRING, &colorname[2] },
|
||||||
|
+ { "color3", STRING, &colorname[3] },
|
||||||
|
+ { "color4", STRING, &colorname[4] },
|
||||||
|
+ { "color5", STRING, &colorname[5] },
|
||||||
|
+ { "color6", STRING, &colorname[6] },
|
||||||
|
+ { "color7", STRING, &colorname[7] },
|
||||||
|
+ { "color8", STRING, &colorname[8] },
|
||||||
|
+ { "color9", STRING, &colorname[9] },
|
||||||
|
+ { "color10", STRING, &colorname[10] },
|
||||||
|
+ { "color11", STRING, &colorname[11] },
|
||||||
|
+ { "color12", STRING, &colorname[12] },
|
||||||
|
+ { "color13", STRING, &colorname[13] },
|
||||||
|
+ { "color14", STRING, &colorname[14] },
|
||||||
|
+ { "color15", STRING, &colorname[15] },
|
||||||
|
+ { "background", STRING, &colorname[256] },
|
||||||
|
+ { "foreground", STRING, &colorname[257] },
|
||||||
|
+ { "cursorColor", STRING, &colorname[258] },
|
||||||
|
+ { "termname", STRING, &termname },
|
||||||
|
+ { "shell", STRING, &shell },
|
||||||
|
+ { "minlatency", INTEGER, &minlatency },
|
||||||
|
+ { "maxlatency", INTEGER, &maxlatency },
|
||||||
|
+ { "blinktimeout", INTEGER, &blinktimeout },
|
||||||
|
+ { "bellvolume", INTEGER, &bellvolume },
|
||||||
|
+ { "tabspaces", INTEGER, &tabspaces },
|
||||||
|
+ { "borderpx", INTEGER, &borderpx },
|
||||||
|
+ { "cwscale", FLOAT, &cwscale },
|
||||||
|
+ { "chscale", FLOAT, &chscale },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Internal mouse shortcuts.
|
||||||
|
* Beware that overloading Button1 will disable the selection.
|
||||||
|
diff --git a/x.c b/x.c
|
||||||
|
index 210f184..76f167f 100644
|
||||||
|
--- a/x.c
|
||||||
|
+++ b/x.c
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
+#include <X11/Xresource.h>
|
||||||
|
|
||||||
|
char *argv0;
|
||||||
|
#include "arg.h"
|
||||||
|
@@ -45,6 +46,19 @@ typedef struct {
|
||||||
|
signed char appcursor; /* application cursor */
|
||||||
|
} Key;
|
||||||
|
|
||||||
|
+/* Xresources preferences */
|
||||||
|
+enum resource_type {
|
||||||
|
+ STRING = 0,
|
||||||
|
+ INTEGER = 1,
|
||||||
|
+ FLOAT = 2
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct {
|
||||||
|
+ char *name;
|
||||||
|
+ enum resource_type type;
|
||||||
|
+ void *dst;
|
||||||
|
+} ResourcePref;
|
||||||
|
+
|
||||||
|
/* X modifiers */
|
||||||
|
#define XK_ANY_MOD UINT_MAX
|
||||||
|
#define XK_NO_MOD 0
|
||||||
|
@@ -828,8 +842,8 @@ xclear(int x1, int y1, int x2, int y2)
|
||||||
|
void
|
||||||
|
xhints(void)
|
||||||
|
{
|
||||||
|
- XClassHint class = {opt_name ? opt_name : termname,
|
||||||
|
- opt_class ? opt_class : termname};
|
||||||
|
+ XClassHint class = {opt_name ? opt_name : "st",
|
||||||
|
+ opt_class ? opt_class : "St"};
|
||||||
|
XWMHints wm = {.flags = InputHint, .input = 1};
|
||||||
|
XSizeHints *sizeh;
|
||||||
|
|
||||||
|
@@ -1104,8 +1118,6 @@ xinit(int cols, int rows)
|
||||||
|
pid_t thispid = getpid();
|
||||||
|
XColor xmousefg, xmousebg;
|
||||||
|
|
||||||
|
- if (!(xw.dpy = XOpenDisplay(NULL)))
|
||||||
|
- die("can't open display\n");
|
||||||
|
xw.scr = XDefaultScreen(xw.dpy);
|
||||||
|
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
||||||
|
|
||||||
|
@@ -1964,6 +1976,59 @@ run(void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+int
|
||||||
|
+resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
|
||||||
|
+{
|
||||||
|
+ char **sdst = dst;
|
||||||
|
+ int *idst = dst;
|
||||||
|
+ float *fdst = dst;
|
||||||
|
+
|
||||||
|
+ char fullname[256];
|
||||||
|
+ char fullclass[256];
|
||||||
|
+ char *type;
|
||||||
|
+ XrmValue ret;
|
||||||
|
+
|
||||||
|
+ snprintf(fullname, sizeof(fullname), "%s.%s",
|
||||||
|
+ opt_name ? opt_name : "st", name);
|
||||||
|
+ snprintf(fullclass, sizeof(fullclass), "%s.%s",
|
||||||
|
+ opt_class ? opt_class : "St", name);
|
||||||
|
+ fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
|
||||||
|
+
|
||||||
|
+ XrmGetResource(db, fullname, fullclass, &type, &ret);
|
||||||
|
+ if (ret.addr == NULL || strncmp("String", type, 64))
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ switch (rtype) {
|
||||||
|
+ case STRING:
|
||||||
|
+ *sdst = ret.addr;
|
||||||
|
+ break;
|
||||||
|
+ case INTEGER:
|
||||||
|
+ *idst = strtoul(ret.addr, NULL, 10);
|
||||||
|
+ break;
|
||||||
|
+ case FLOAT:
|
||||||
|
+ *fdst = strtof(ret.addr, NULL);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+config_init(void)
|
||||||
|
+{
|
||||||
|
+ char *resm;
|
||||||
|
+ XrmDatabase db;
|
||||||
|
+ ResourcePref *p;
|
||||||
|
+
|
||||||
|
+ XrmInitialize();
|
||||||
|
+ resm = XResourceManagerString(xw.dpy);
|
||||||
|
+ if (!resm)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ db = XrmGetStringDatabase(resm);
|
||||||
|
+ for (p = resources; p < resources + LEN(resources); p++)
|
||||||
|
+ resource_load(db, p->name, p->type, p->dst);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
@@ -2037,6 +2102,11 @@ run:
|
||||||
|
|
||||||
|
setlocale(LC_CTYPE, "");
|
||||||
|
XSetLocaleModifiers("");
|
||||||
|
+
|
||||||
|
+ if(!(xw.dpy = XOpenDisplay(NULL)))
|
||||||
|
+ die("Can't open display\n");
|
||||||
|
+
|
||||||
|
+ config_init();
|
||||||
|
cols = MAX(cols, 1);
|
||||||
|
rows = MAX(rows, 1);
|
||||||
|
tnew(cols, rows);
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
*
|
*
|
||||||
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
|
||||||
*/
|
*/
|
||||||
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
|
static char *font = "castella:size=14";
|
||||||
static int borderpx = 2;
|
static int borderpx = 4;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* What program is execed by st depends of these precedence rules:
|
* What program is execed by st depends of these precedence rules:
|
||||||
|
@ -95,36 +95,29 @@ unsigned int tabspaces = 8;
|
||||||
|
|
||||||
/* Terminal colors (16 first used in escape sequence) */
|
/* Terminal colors (16 first used in escape sequence) */
|
||||||
static const char *colorname[] = {
|
static const char *colorname[] = {
|
||||||
/* 8 normal colors */
|
"#1C1E26",
|
||||||
[0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */
|
"#232530",
|
||||||
[1] = "#cc241d", /* red */
|
"#2E303E",
|
||||||
[2] = "#98971a", /* green */
|
"#6F6F70",
|
||||||
[3] = "#d79921", /* yellow */
|
"#9DA0A2",
|
||||||
[4] = "#458588", /* blue */
|
"#CBCED0",
|
||||||
[5] = "#b16286", /* magenta */
|
"#DCDFE4",
|
||||||
[6] = "#689d6a", /* cyan */
|
"#E3E6EE",
|
||||||
[7] = "#a89984", /* white */
|
"#E95678",
|
||||||
|
"#FAB795",
|
||||||
/* 8 bright colors */
|
"#FAC29A",
|
||||||
[8] = "#928374", /* black */
|
"#29D398",
|
||||||
[9] = "#fb4934", /* red */
|
"#59E1E3",
|
||||||
[10] = "#b8bb26", /* green */
|
"#26BBD9",
|
||||||
[11] = "#fabd2f", /* yellow */
|
"#EE64AC",
|
||||||
[12] = "#83a598", /* blue */
|
"#F09383"
|
||||||
[13] = "#d3869b", /* magenta */
|
|
||||||
[14] = "#8ec07c", /* cyan */
|
|
||||||
[15] = "#ebdbb2", /* white */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned int defaultfg = 7;
|
||||||
/*
|
|
||||||
* Default colors (colorname index)
|
|
||||||
* foreground, background, cursor, reverse cursor
|
|
||||||
*/
|
|
||||||
static unsigned int defaultcs = 15;
|
|
||||||
static unsigned int defaultrcs = 257;
|
|
||||||
unsigned int defaultfg = 15;
|
|
||||||
unsigned int defaultbg = 0;
|
unsigned int defaultbg = 0;
|
||||||
|
static unsigned int defaultcs = 13;
|
||||||
|
static unsigned int defaultrcs = 0;
|
||||||
|
|
||||||
static const int resizehints = 0;
|
static const int resizehints = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -170,6 +163,42 @@ static unsigned int defaultattr = 11;
|
||||||
*/
|
*/
|
||||||
static uint forcemousemod = ShiftMask;
|
static uint forcemousemod = ShiftMask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Xresources preferences to load at startup
|
||||||
|
*/
|
||||||
|
ResourcePref resources[] = {
|
||||||
|
{ "font", STRING, &font },
|
||||||
|
{ "color0", STRING, &colorname[0] },
|
||||||
|
{ "color1", STRING, &colorname[1] },
|
||||||
|
{ "color2", STRING, &colorname[2] },
|
||||||
|
{ "color3", STRING, &colorname[3] },
|
||||||
|
{ "color4", STRING, &colorname[4] },
|
||||||
|
{ "color5", STRING, &colorname[5] },
|
||||||
|
{ "color6", STRING, &colorname[6] },
|
||||||
|
{ "color7", STRING, &colorname[7] },
|
||||||
|
{ "color8", STRING, &colorname[8] },
|
||||||
|
{ "color9", STRING, &colorname[9] },
|
||||||
|
{ "color10", STRING, &colorname[10] },
|
||||||
|
{ "color11", STRING, &colorname[11] },
|
||||||
|
{ "color12", STRING, &colorname[12] },
|
||||||
|
{ "color13", STRING, &colorname[13] },
|
||||||
|
{ "color14", STRING, &colorname[14] },
|
||||||
|
{ "color15", STRING, &colorname[15] },
|
||||||
|
{ "background", STRING, &colorname[256] },
|
||||||
|
{ "foreground", STRING, &colorname[257] },
|
||||||
|
{ "cursorColor", STRING, &colorname[258] },
|
||||||
|
{ "termname", STRING, &termname },
|
||||||
|
{ "shell", STRING, &shell },
|
||||||
|
{ "minlatency", INTEGER, &minlatency },
|
||||||
|
{ "maxlatency", INTEGER, &maxlatency },
|
||||||
|
{ "blinktimeout", INTEGER, &blinktimeout },
|
||||||
|
{ "bellvolume", INTEGER, &bellvolume },
|
||||||
|
{ "tabspaces", INTEGER, &tabspaces },
|
||||||
|
{ "borderpx", INTEGER, &borderpx },
|
||||||
|
{ "cwscale", FLOAT, &cwscale },
|
||||||
|
{ "chscale", FLOAT, &chscale },
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal mouse shortcuts.
|
* Internal mouse shortcuts.
|
||||||
* Beware that overloading Button1 will disable the selection.
|
* Beware that overloading Button1 will disable the selection.
|
||||||
|
|
|
@ -15,10 +15,12 @@ PKG_CONFIG = pkg-config
|
||||||
# includes and libs
|
# includes and libs
|
||||||
INCS = -I$(X11INC) \
|
INCS = -I$(X11INC) \
|
||||||
`$(PKG_CONFIG) --cflags fontconfig` \
|
`$(PKG_CONFIG) --cflags fontconfig` \
|
||||||
`$(PKG_CONFIG) --cflags freetype2`
|
`$(PKG_CONFIG) --cflags freetype2` \
|
||||||
|
`$(PKG_CONFIG) --cflags harfbuzz`
|
||||||
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
|
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
|
||||||
`$(PKG_CONFIG) --libs fontconfig` \
|
`$(PKG_CONFIG) --libs fontconfig` \
|
||||||
`$(PKG_CONFIG) --libs freetype2`
|
`$(PKG_CONFIG) --libs freetype2` \
|
||||||
|
`$(PKG_CONFIG) --libs harfbuzz`
|
||||||
|
|
||||||
# flags
|
# flags
|
||||||
STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
|
STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
|
||||||
|
|
136
st/hb.c
Normal file
136
st/hb.c
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <hb.h>
|
||||||
|
#include <hb-ft.h>
|
||||||
|
|
||||||
|
#include "st.h"
|
||||||
|
|
||||||
|
void hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length);
|
||||||
|
hb_font_t *hbfindfont(XftFont *match);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
XftFont *match;
|
||||||
|
hb_font_t *font;
|
||||||
|
} HbFontMatch;
|
||||||
|
|
||||||
|
static int hbfontslen = 0;
|
||||||
|
static HbFontMatch *hbfontcache = NULL;
|
||||||
|
|
||||||
|
void
|
||||||
|
hbunloadfonts()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < hbfontslen; i++) {
|
||||||
|
hb_font_destroy(hbfontcache[i].font);
|
||||||
|
XftUnlockFace(hbfontcache[i].match);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hbfontcache != NULL) {
|
||||||
|
free(hbfontcache);
|
||||||
|
hbfontcache = NULL;
|
||||||
|
}
|
||||||
|
hbfontslen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_font_t *
|
||||||
|
hbfindfont(XftFont *match)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < hbfontslen; i++) {
|
||||||
|
if (hbfontcache[i].match == match)
|
||||||
|
return hbfontcache[i].font;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Font not found in cache, caching it now. */
|
||||||
|
hbfontcache = realloc(hbfontcache, sizeof(HbFontMatch) * (hbfontslen + 1));
|
||||||
|
FT_Face face = XftLockFace(match);
|
||||||
|
hb_font_t *font = hb_ft_font_create(face, NULL);
|
||||||
|
if (font == NULL)
|
||||||
|
die("Failed to load Harfbuzz font.");
|
||||||
|
|
||||||
|
hbfontcache[hbfontslen].match = match;
|
||||||
|
hbfontcache[hbfontslen].font = font;
|
||||||
|
hbfontslen += 1;
|
||||||
|
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hbtransform(XftGlyphFontSpec *specs, const Glyph *glyphs, size_t len, int x, int y)
|
||||||
|
{
|
||||||
|
int start = 0, length = 1, gstart = 0;
|
||||||
|
hb_codepoint_t *codepoints = calloc(len, sizeof(hb_codepoint_t));
|
||||||
|
|
||||||
|
for (int idx = 1, specidx = 1; idx < len; idx++) {
|
||||||
|
if (glyphs[idx].mode & ATTR_WDUMMY) {
|
||||||
|
length += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (specs[specidx].font != specs[start].font || ATTRCMP(glyphs[gstart], glyphs[idx]) || selected(x + idx, y) != selected(x + gstart, y)) {
|
||||||
|
hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length);
|
||||||
|
|
||||||
|
/* Reset the sequence. */
|
||||||
|
length = 1;
|
||||||
|
start = specidx;
|
||||||
|
gstart = idx;
|
||||||
|
} else {
|
||||||
|
length += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
specidx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOL. */
|
||||||
|
hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length);
|
||||||
|
|
||||||
|
/* Apply the transformation to glyph specs. */
|
||||||
|
for (int i = 0, specidx = 0; i < len; i++) {
|
||||||
|
if (glyphs[i].mode & ATTR_WDUMMY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (codepoints[i] != specs[specidx].glyph)
|
||||||
|
((Glyph *)glyphs)[i].mode |= ATTR_LIGA;
|
||||||
|
|
||||||
|
specs[specidx++].glyph = codepoints[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
free(codepoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length)
|
||||||
|
{
|
||||||
|
hb_font_t *font = hbfindfont(xfont);
|
||||||
|
if (font == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Rune rune;
|
||||||
|
ushort mode = USHRT_MAX;
|
||||||
|
hb_buffer_t *buffer = hb_buffer_create();
|
||||||
|
hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
|
||||||
|
|
||||||
|
/* Fill buffer with codepoints. */
|
||||||
|
for (int i = start; i < (start+length); i++) {
|
||||||
|
rune = string[i].u;
|
||||||
|
mode = string[i].mode;
|
||||||
|
if (mode & ATTR_WDUMMY)
|
||||||
|
rune = 0x0020;
|
||||||
|
hb_buffer_add_codepoints(buffer, &rune, 1, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shape the segment. */
|
||||||
|
hb_shape(font, buffer, NULL, 0);
|
||||||
|
|
||||||
|
/* Get new glyph info. */
|
||||||
|
hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, NULL);
|
||||||
|
|
||||||
|
/* Write new codepoints. */
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
hb_codepoint_t gid = info[i].codepoint;
|
||||||
|
codepoints[start+i] = gid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cleanup. */
|
||||||
|
hb_buffer_destroy(buffer);
|
||||||
|
}
|
7
st/hb.h
Normal file
7
st/hb.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <hb.h>
|
||||||
|
#include <hb-ft.h>
|
||||||
|
|
||||||
|
void hbunloadfonts();
|
||||||
|
void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int);
|
||||||
|
|
307
st/st-ligatures-scrollback-20200430-0.8.3.diff
Normal file
307
st/st-ligatures-scrollback-20200430-0.8.3.diff
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 470ac86..38240da 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
|
||||||
|
include config.mk
|
||||||
|
|
||||||
|
-SRC = st.c x.c
|
||||||
|
+SRC = st.c x.c hb.c
|
||||||
|
OBJ = $(SRC:.c=.o)
|
||||||
|
|
||||||
|
all: options st
|
||||||
|
@@ -22,7 +22,8 @@ config.h:
|
||||||
|
$(CC) $(STCFLAGS) -c $<
|
||||||
|
|
||||||
|
st.o: config.h st.h win.h
|
||||||
|
-x.o: arg.h config.h st.h win.h
|
||||||
|
+x.o: arg.h config.h st.h win.h hb.h
|
||||||
|
+hb.o: st.h
|
||||||
|
|
||||||
|
$(OBJ): config.h config.mk
|
||||||
|
|
||||||
|
diff --git a/config.mk b/config.mk
|
||||||
|
index beafc35..3df5c83 100644
|
||||||
|
--- a/config.mk
|
||||||
|
+++ b/config.mk
|
||||||
|
@@ -15,10 +15,12 @@ PKG_CONFIG = pkg-config
|
||||||
|
# includes and libs
|
||||||
|
INCS = -I$(X11INC) \
|
||||||
|
`$(PKG_CONFIG) --cflags fontconfig` \
|
||||||
|
- `$(PKG_CONFIG) --cflags freetype2`
|
||||||
|
+ `$(PKG_CONFIG) --cflags freetype2` \
|
||||||
|
+ `$(PKG_CONFIG) --cflags harfbuzz`
|
||||||
|
LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
|
||||||
|
`$(PKG_CONFIG) --libs fontconfig` \
|
||||||
|
- `$(PKG_CONFIG) --libs freetype2`
|
||||||
|
+ `$(PKG_CONFIG) --libs freetype2` \
|
||||||
|
+ `$(PKG_CONFIG) --libs harfbuzz`
|
||||||
|
|
||||||
|
# flags
|
||||||
|
STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
|
||||||
|
diff --git a/hb.c b/hb.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..7df2828
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/hb.c
|
||||||
|
@@ -0,0 +1,136 @@
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <math.h>
|
||||||
|
+#include <X11/Xft/Xft.h>
|
||||||
|
+#include <hb.h>
|
||||||
|
+#include <hb-ft.h>
|
||||||
|
+
|
||||||
|
+#include "st.h"
|
||||||
|
+
|
||||||
|
+void hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length);
|
||||||
|
+hb_font_t *hbfindfont(XftFont *match);
|
||||||
|
+
|
||||||
|
+typedef struct {
|
||||||
|
+ XftFont *match;
|
||||||
|
+ hb_font_t *font;
|
||||||
|
+} HbFontMatch;
|
||||||
|
+
|
||||||
|
+static int hbfontslen = 0;
|
||||||
|
+static HbFontMatch *hbfontcache = NULL;
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+hbunloadfonts()
|
||||||
|
+{
|
||||||
|
+ for (int i = 0; i < hbfontslen; i++) {
|
||||||
|
+ hb_font_destroy(hbfontcache[i].font);
|
||||||
|
+ XftUnlockFace(hbfontcache[i].match);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (hbfontcache != NULL) {
|
||||||
|
+ free(hbfontcache);
|
||||||
|
+ hbfontcache = NULL;
|
||||||
|
+ }
|
||||||
|
+ hbfontslen = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+hb_font_t *
|
||||||
|
+hbfindfont(XftFont *match)
|
||||||
|
+{
|
||||||
|
+ for (int i = 0; i < hbfontslen; i++) {
|
||||||
|
+ if (hbfontcache[i].match == match)
|
||||||
|
+ return hbfontcache[i].font;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Font not found in cache, caching it now. */
|
||||||
|
+ hbfontcache = realloc(hbfontcache, sizeof(HbFontMatch) * (hbfontslen + 1));
|
||||||
|
+ FT_Face face = XftLockFace(match);
|
||||||
|
+ hb_font_t *font = hb_ft_font_create(face, NULL);
|
||||||
|
+ if (font == NULL)
|
||||||
|
+ die("Failed to load Harfbuzz font.");
|
||||||
|
+
|
||||||
|
+ hbfontcache[hbfontslen].match = match;
|
||||||
|
+ hbfontcache[hbfontslen].font = font;
|
||||||
|
+ hbfontslen += 1;
|
||||||
|
+
|
||||||
|
+ return font;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+hbtransform(XftGlyphFontSpec *specs, const Glyph *glyphs, size_t len, int x, int y)
|
||||||
|
+{
|
||||||
|
+ int start = 0, length = 1, gstart = 0;
|
||||||
|
+ hb_codepoint_t *codepoints = calloc(len, sizeof(hb_codepoint_t));
|
||||||
|
+
|
||||||
|
+ for (int idx = 1, specidx = 1; idx < len; idx++) {
|
||||||
|
+ if (glyphs[idx].mode & ATTR_WDUMMY) {
|
||||||
|
+ length += 1;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (specs[specidx].font != specs[start].font || ATTRCMP(glyphs[gstart], glyphs[idx]) || selected(x + idx, y) != selected(x + gstart, y)) {
|
||||||
|
+ hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length);
|
||||||
|
+
|
||||||
|
+ /* Reset the sequence. */
|
||||||
|
+ length = 1;
|
||||||
|
+ start = specidx;
|
||||||
|
+ gstart = idx;
|
||||||
|
+ } else {
|
||||||
|
+ length += 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ specidx++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* EOL. */
|
||||||
|
+ hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length);
|
||||||
|
+
|
||||||
|
+ /* Apply the transformation to glyph specs. */
|
||||||
|
+ for (int i = 0, specidx = 0; i < len; i++) {
|
||||||
|
+ if (glyphs[i].mode & ATTR_WDUMMY)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (codepoints[i] != specs[specidx].glyph)
|
||||||
|
+ ((Glyph *)glyphs)[i].mode |= ATTR_LIGA;
|
||||||
|
+
|
||||||
|
+ specs[specidx++].glyph = codepoints[i];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free(codepoints);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length)
|
||||||
|
+{
|
||||||
|
+ hb_font_t *font = hbfindfont(xfont);
|
||||||
|
+ if (font == NULL)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ Rune rune;
|
||||||
|
+ ushort mode = USHRT_MAX;
|
||||||
|
+ hb_buffer_t *buffer = hb_buffer_create();
|
||||||
|
+ hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
|
||||||
|
+
|
||||||
|
+ /* Fill buffer with codepoints. */
|
||||||
|
+ for (int i = start; i < (start+length); i++) {
|
||||||
|
+ rune = string[i].u;
|
||||||
|
+ mode = string[i].mode;
|
||||||
|
+ if (mode & ATTR_WDUMMY)
|
||||||
|
+ rune = 0x0020;
|
||||||
|
+ hb_buffer_add_codepoints(buffer, &rune, 1, 0, 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Shape the segment. */
|
||||||
|
+ hb_shape(font, buffer, NULL, 0);
|
||||||
|
+
|
||||||
|
+ /* Get new glyph info. */
|
||||||
|
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, NULL);
|
||||||
|
+
|
||||||
|
+ /* Write new codepoints. */
|
||||||
|
+ for (int i = 0; i < length; i++) {
|
||||||
|
+ hb_codepoint_t gid = info[i].codepoint;
|
||||||
|
+ codepoints[start+i] = gid;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Cleanup. */
|
||||||
|
+ hb_buffer_destroy(buffer);
|
||||||
|
+}
|
||||||
|
diff --git a/hb.h b/hb.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..b3e02d0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/hb.h
|
||||||
|
@@ -0,0 +1,7 @@
|
||||||
|
+#include <X11/Xft/Xft.h>
|
||||||
|
+#include <hb.h>
|
||||||
|
+#include <hb-ft.h>
|
||||||
|
+
|
||||||
|
+void hbunloadfonts();
|
||||||
|
+void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int);
|
||||||
|
+
|
||||||
|
diff --git a/st.c b/st.c
|
||||||
|
index 641edc0..14a0b66 100644
|
||||||
|
--- a/st.c
|
||||||
|
+++ b/st.c
|
||||||
|
@@ -2670,7 +2670,8 @@ draw(void)
|
||||||
|
drawregion(0, 0, term.col, term.row);
|
||||||
|
if (term.scr == 0)
|
||||||
|
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
|
||||||
|
- term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
|
||||||
|
+ term.ocx, term.ocy, term.line[term.ocy][term.ocx],
|
||||||
|
+ term.line[term.ocy], term.col);
|
||||||
|
term.ocx = cx;
|
||||||
|
term.ocy = term.c.y;
|
||||||
|
xfinishdraw();
|
||||||
|
diff --git a/st.h b/st.h
|
||||||
|
index b9a4eeb..b49b84a 100644
|
||||||
|
--- a/st.h
|
||||||
|
+++ b/st.h
|
||||||
|
@@ -11,7 +11,8 @@
|
||||||
|
#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
|
||||||
|
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
|
||||||
|
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
|
||||||
|
-#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \
|
||||||
|
+#define ATTRCMP(a, b) (((a).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) != ((b).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) || \
|
||||||
|
+ (a).fg != (b).fg || \
|
||||||
|
(a).bg != (b).bg)
|
||||||
|
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
|
||||||
|
(t1.tv_nsec-t2.tv_nsec)/1E6)
|
||||||
|
@@ -33,6 +34,7 @@ enum glyph_attribute {
|
||||||
|
ATTR_WRAP = 1 << 8,
|
||||||
|
ATTR_WIDE = 1 << 9,
|
||||||
|
ATTR_WDUMMY = 1 << 10,
|
||||||
|
+ ATTR_LIGA = 1 << 11,
|
||||||
|
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/win.h b/win.h
|
||||||
|
index a6ef1b9..bc0d180 100644
|
||||||
|
--- a/win.h
|
||||||
|
+++ b/win.h
|
||||||
|
@@ -25,7 +25,7 @@ enum win_mode {
|
||||||
|
|
||||||
|
void xbell(void);
|
||||||
|
void xclipcopy(void);
|
||||||
|
-void xdrawcursor(int, int, Glyph, int, int, Glyph);
|
||||||
|
+void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int);
|
||||||
|
void xdrawline(Line, int, int, int);
|
||||||
|
void xfinishdraw(void);
|
||||||
|
void xloadcols(void);
|
||||||
|
diff --git a/x.c b/x.c
|
||||||
|
index e5f1737..3334a83 100644
|
||||||
|
--- a/x.c
|
||||||
|
+++ b/x.c
|
||||||
|
@@ -19,6 +19,7 @@ char *argv0;
|
||||||
|
#include "arg.h"
|
||||||
|
#include "st.h"
|
||||||
|
#include "win.h"
|
||||||
|
+#include "hb.h"
|
||||||
|
|
||||||
|
/* types used in config.h */
|
||||||
|
typedef struct {
|
||||||
|
@@ -1031,6 +1032,9 @@ xunloadfont(Font *f)
|
||||||
|
void
|
||||||
|
xunloadfonts(void)
|
||||||
|
{
|
||||||
|
+ /* Clear Harfbuzz font cache. */
|
||||||
|
+ hbunloadfonts();
|
||||||
|
+
|
||||||
|
/* Free the loaded fonts in the font cache. */
|
||||||
|
while (frclen > 0)
|
||||||
|
XftFontClose(xw.dpy, frc[--frclen].font);
|
||||||
|
@@ -1229,7 +1233,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
||||||
|
mode = glyphs[i].mode;
|
||||||
|
|
||||||
|
/* Skip dummy wide-character spacing. */
|
||||||
|
- if (mode == ATTR_WDUMMY)
|
||||||
|
+ if (mode & ATTR_WDUMMY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Determine font for glyph if different from previous glyph. */
|
||||||
|
@@ -1336,6 +1340,9 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
||||||
|
numspecs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Harfbuzz transformation for ligatures. */
|
||||||
|
+ hbtransform(specs, glyphs, len, x, y);
|
||||||
|
+
|
||||||
|
return numspecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1485,14 +1492,17 @@ xdrawglyph(Glyph g, int x, int y)
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
-xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
|
||||||
|
+xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len)
|
||||||
|
{
|
||||||
|
Color drawcol;
|
||||||
|
|
||||||
|
/* remove the old cursor */
|
||||||
|
if (selected(ox, oy))
|
||||||
|
og.mode ^= ATTR_REVERSE;
|
||||||
|
- xdrawglyph(og, ox, oy);
|
||||||
|
+
|
||||||
|
+ /* Redraw the line where cursor was previously.
|
||||||
|
+ * It will restore the ligatures broken by the cursor. */
|
||||||
|
+ xdrawline(line, 0, oy, len);
|
||||||
|
|
||||||
|
if (IS_SET(MODE_HIDE))
|
||||||
|
return;
|
3
st/st.c
3
st/st.c
|
@ -2660,7 +2660,8 @@ draw(void)
|
||||||
drawregion(0, 0, term.col, term.row);
|
drawregion(0, 0, term.col, term.row);
|
||||||
if (term.scr == 0)
|
if (term.scr == 0)
|
||||||
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
|
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
|
||||||
term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
|
term.ocx, term.ocy, term.line[term.ocy][term.ocx],
|
||||||
|
term.line[term.ocy], term.col);
|
||||||
term.ocx = cx;
|
term.ocx = cx;
|
||||||
term.ocy = term.c.y;
|
term.ocy = term.c.y;
|
||||||
xfinishdraw();
|
xfinishdraw();
|
||||||
|
|
4
st/st.h
4
st/st.h
|
@ -11,7 +11,8 @@
|
||||||
#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
|
#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
|
||||||
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
|
#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
|
||||||
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
|
#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
|
||||||
#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \
|
#define ATTRCMP(a, b) (((a).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) != ((b).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) || \
|
||||||
|
(a).fg != (b).fg || \
|
||||||
(a).bg != (b).bg)
|
(a).bg != (b).bg)
|
||||||
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
|
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
|
||||||
(t1.tv_nsec-t2.tv_nsec)/1E6)
|
(t1.tv_nsec-t2.tv_nsec)/1E6)
|
||||||
|
@ -33,6 +34,7 @@ enum glyph_attribute {
|
||||||
ATTR_WRAP = 1 << 8,
|
ATTR_WRAP = 1 << 8,
|
||||||
ATTR_WIDE = 1 << 9,
|
ATTR_WIDE = 1 << 9,
|
||||||
ATTR_WDUMMY = 1 << 10,
|
ATTR_WDUMMY = 1 << 10,
|
||||||
|
ATTR_LIGA = 1 << 11,
|
||||||
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
|
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
2
st/win.h
2
st/win.h
|
@ -25,7 +25,7 @@ enum win_mode {
|
||||||
|
|
||||||
void xbell(void);
|
void xbell(void);
|
||||||
void xclipcopy(void);
|
void xclipcopy(void);
|
||||||
void xdrawcursor(int, int, Glyph, int, int, Glyph);
|
void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int);
|
||||||
void xdrawline(Line, int, int, int);
|
void xdrawline(Line, int, int, int);
|
||||||
void xfinishdraw(void);
|
void xfinishdraw(void);
|
||||||
void xloadcols(void);
|
void xloadcols(void);
|
||||||
|
|
94
st/x.c
94
st/x.c
|
@ -14,11 +14,13 @@
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <X11/Xft/Xft.h>
|
#include <X11/Xft/Xft.h>
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
|
#include <X11/Xresource.h>
|
||||||
|
|
||||||
char *argv0;
|
char *argv0;
|
||||||
#include "arg.h"
|
#include "arg.h"
|
||||||
#include "st.h"
|
#include "st.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
#include "hb.h"
|
||||||
|
|
||||||
/* types used in config.h */
|
/* types used in config.h */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -45,6 +47,19 @@ typedef struct {
|
||||||
signed char appcursor; /* application cursor */
|
signed char appcursor; /* application cursor */
|
||||||
} Key;
|
} Key;
|
||||||
|
|
||||||
|
/* Xresources preferences */
|
||||||
|
enum resource_type {
|
||||||
|
STRING = 0,
|
||||||
|
INTEGER = 1,
|
||||||
|
FLOAT = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name;
|
||||||
|
enum resource_type type;
|
||||||
|
void *dst;
|
||||||
|
} ResourcePref;
|
||||||
|
|
||||||
/* X modifiers */
|
/* X modifiers */
|
||||||
#define XK_ANY_MOD UINT_MAX
|
#define XK_ANY_MOD UINT_MAX
|
||||||
#define XK_NO_MOD 0
|
#define XK_NO_MOD 0
|
||||||
|
@ -831,8 +846,8 @@ xclear(int x1, int y1, int x2, int y2)
|
||||||
void
|
void
|
||||||
xhints(void)
|
xhints(void)
|
||||||
{
|
{
|
||||||
XClassHint class = {opt_name ? opt_name : termname,
|
XClassHint class = {opt_name ? opt_name : "st",
|
||||||
opt_class ? opt_class : termname};
|
opt_class ? opt_class : "St"};
|
||||||
XWMHints wm = {.flags = InputHint, .input = 1};
|
XWMHints wm = {.flags = InputHint, .input = 1};
|
||||||
XSizeHints *sizeh;
|
XSizeHints *sizeh;
|
||||||
|
|
||||||
|
@ -1034,6 +1049,9 @@ xunloadfont(Font *f)
|
||||||
void
|
void
|
||||||
xunloadfonts(void)
|
xunloadfonts(void)
|
||||||
{
|
{
|
||||||
|
/* Clear Harfbuzz font cache. */
|
||||||
|
hbunloadfonts();
|
||||||
|
|
||||||
/* Free the loaded fonts in the font cache. */
|
/* Free the loaded fonts in the font cache. */
|
||||||
while (frclen > 0)
|
while (frclen > 0)
|
||||||
XftFontClose(xw.dpy, frc[--frclen].font);
|
XftFontClose(xw.dpy, frc[--frclen].font);
|
||||||
|
@ -1107,8 +1125,6 @@ xinit(int cols, int rows)
|
||||||
pid_t thispid = getpid();
|
pid_t thispid = getpid();
|
||||||
XColor xmousefg, xmousebg;
|
XColor xmousefg, xmousebg;
|
||||||
|
|
||||||
if (!(xw.dpy = XOpenDisplay(NULL)))
|
|
||||||
die("can't open display\n");
|
|
||||||
xw.scr = XDefaultScreen(xw.dpy);
|
xw.scr = XDefaultScreen(xw.dpy);
|
||||||
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
xw.vis = XDefaultVisual(xw.dpy, xw.scr);
|
||||||
|
|
||||||
|
@ -1233,7 +1249,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
||||||
mode = glyphs[i].mode;
|
mode = glyphs[i].mode;
|
||||||
|
|
||||||
/* Skip dummy wide-character spacing. */
|
/* Skip dummy wide-character spacing. */
|
||||||
if (mode == ATTR_WDUMMY)
|
if (mode & ATTR_WDUMMY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Determine font for glyph if different from previous glyph. */
|
/* Determine font for glyph if different from previous glyph. */
|
||||||
|
@ -1340,6 +1356,9 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
|
||||||
numspecs++;
|
numspecs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Harfbuzz transformation for ligatures. */
|
||||||
|
hbtransform(specs, glyphs, len, x, y);
|
||||||
|
|
||||||
return numspecs;
|
return numspecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1489,14 +1508,17 @@ xdrawglyph(Glyph g, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
|
xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len)
|
||||||
{
|
{
|
||||||
Color drawcol;
|
Color drawcol;
|
||||||
|
|
||||||
/* remove the old cursor */
|
/* remove the old cursor */
|
||||||
if (selected(ox, oy))
|
if (selected(ox, oy))
|
||||||
og.mode ^= ATTR_REVERSE;
|
og.mode ^= ATTR_REVERSE;
|
||||||
xdrawglyph(og, ox, oy);
|
|
||||||
|
/* Redraw the line where cursor was previously.
|
||||||
|
* It will restore the ligatures broken by the cursor. */
|
||||||
|
xdrawline(line, 0, oy, len);
|
||||||
|
|
||||||
if (IS_SET(MODE_HIDE))
|
if (IS_SET(MODE_HIDE))
|
||||||
return;
|
return;
|
||||||
|
@ -2002,6 +2024,59 @@ run(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
|
||||||
|
{
|
||||||
|
char **sdst = dst;
|
||||||
|
int *idst = dst;
|
||||||
|
float *fdst = dst;
|
||||||
|
|
||||||
|
char fullname[256];
|
||||||
|
char fullclass[256];
|
||||||
|
char *type;
|
||||||
|
XrmValue ret;
|
||||||
|
|
||||||
|
snprintf(fullname, sizeof(fullname), "%s.%s",
|
||||||
|
opt_name ? opt_name : "st", name);
|
||||||
|
snprintf(fullclass, sizeof(fullclass), "%s.%s",
|
||||||
|
opt_class ? opt_class : "St", name);
|
||||||
|
fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
|
||||||
|
|
||||||
|
XrmGetResource(db, fullname, fullclass, &type, &ret);
|
||||||
|
if (ret.addr == NULL || strncmp("String", type, 64))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch (rtype) {
|
||||||
|
case STRING:
|
||||||
|
*sdst = ret.addr;
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
*idst = strtoul(ret.addr, NULL, 10);
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
*fdst = strtof(ret.addr, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
config_init(void)
|
||||||
|
{
|
||||||
|
char *resm;
|
||||||
|
XrmDatabase db;
|
||||||
|
ResourcePref *p;
|
||||||
|
|
||||||
|
XrmInitialize();
|
||||||
|
resm = XResourceManagerString(xw.dpy);
|
||||||
|
if (!resm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
db = XrmGetStringDatabase(resm);
|
||||||
|
for (p = resources; p < resources + LEN(resources); p++)
|
||||||
|
resource_load(db, p->name, p->type, p->dst);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
|
@ -2075,6 +2150,11 @@ run:
|
||||||
|
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
XSetLocaleModifiers("");
|
XSetLocaleModifiers("");
|
||||||
|
|
||||||
|
if(!(xw.dpy = XOpenDisplay(NULL)))
|
||||||
|
die("Can't open display\n");
|
||||||
|
|
||||||
|
config_init();
|
||||||
cols = MAX(cols, 1);
|
cols = MAX(cols, 1);
|
||||||
rows = MAX(rows, 1);
|
rows = MAX(rows, 1);
|
||||||
tnew(cols, rows);
|
tnew(cols, rows);
|
||||||
|
|
Loading…
Reference in a new issue