mirror of
https://github.com/vale981/spectrwm
synced 2025-03-05 09:51:38 -05:00
Add new configurable status bar workspace list indicator.
Enable by adding +L to bar_format. Add new bar_format character sequence: +L Add new conf option: workspace_indicator Closes #113 and closes #170
This commit is contained in:
parent
d781d4e881
commit
6331a294b3
3 changed files with 176 additions and 0 deletions
31
spectrwm.1
31
spectrwm.1
|
@ -211,6 +211,7 @@ It may contain the following character sequences:
|
||||||
.It Li "+D" Ta "Workspace name"
|
.It Li "+D" Ta "Workspace name"
|
||||||
.It Li "+F" Ta "Floating indicator"
|
.It Li "+F" Ta "Floating indicator"
|
||||||
.It Li "+I" Ta "Workspace index"
|
.It Li "+I" Ta "Workspace index"
|
||||||
|
.It Li "+L" Ta "Workspace list indicator"
|
||||||
.It Li "+M" Ta "Number of iconic (minimized) windows in workspace"
|
.It Li "+M" Ta "Number of iconic (minimized) windows in workspace"
|
||||||
.It Li "+N" Ta "Screen number"
|
.It Li "+N" Ta "Screen number"
|
||||||
.It Li "+P" Ta "Window class and instance separated by a colon"
|
.It Li "+P" Ta "Window class and instance separated by a colon"
|
||||||
|
@ -517,6 +518,36 @@ Enable by setting to 1.
|
||||||
Centers the pointer on the focused window when using bindings to change focus,
|
Centers the pointer on the focused window when using bindings to change focus,
|
||||||
switch workspaces, change regions, etc.
|
switch workspaces, change regions, etc.
|
||||||
Enable by setting to 1.
|
Enable by setting to 1.
|
||||||
|
.It Ic workspace_indicator
|
||||||
|
Configure the status bar workspace indicator.
|
||||||
|
One or more of the following options may be specified in a comma-separated
|
||||||
|
list:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "markcurrentXXX" -offset indent -compact
|
||||||
|
.It Ar listcurrent
|
||||||
|
Include the current workspace.
|
||||||
|
.It Ar listactive
|
||||||
|
Include workspaces with windows.
|
||||||
|
.It Ar listempty
|
||||||
|
Include empty workspaces.
|
||||||
|
.It Ar listnamed
|
||||||
|
Include named workspaces.
|
||||||
|
.It Ar listurgent
|
||||||
|
Include workspaces with urgent window(s).
|
||||||
|
.It Ar listall
|
||||||
|
Include all workspaces.
|
||||||
|
.It Ar hidecurrent
|
||||||
|
Always exclude the current workspace from the list.
|
||||||
|
.It Ar markcurrent
|
||||||
|
Indicate the current workspace if it is in the list.
|
||||||
|
.It Ar markurgent
|
||||||
|
Indicate workspaces in the list that contain urgent window(s).
|
||||||
|
.It Ar printnames
|
||||||
|
Display the names of named workspaces in the list.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The default is
|
||||||
|
.Ar listcurrent , Ns Ar listactive , Ns Ar markcurrent , Ns Ar printnames
|
||||||
.It Ic workspace_limit
|
.It Ic workspace_limit
|
||||||
Set the total number of workspaces available.
|
Set the total number of workspaces available.
|
||||||
Minimum is 1, maximum is 22, default is 10.
|
Minimum is 1, maximum is 22, default is 10.
|
||||||
|
|
144
spectrwm.c
144
spectrwm.c
|
@ -271,6 +271,19 @@ uint32_t swm_debug = 0
|
||||||
#define SWM_CK_FALLBACK (0x4)
|
#define SWM_CK_FALLBACK (0x4)
|
||||||
#define SWM_CK_REGION (0x8)
|
#define SWM_CK_REGION (0x8)
|
||||||
|
|
||||||
|
#define SWM_WSI_LISTCURRENT (0x001)
|
||||||
|
#define SWM_WSI_LISTACTIVE (0x002)
|
||||||
|
#define SWM_WSI_LISTEMPTY (0x004)
|
||||||
|
#define SWM_WSI_LISTNAMED (0x008)
|
||||||
|
#define SWM_WSI_LISTURGENT (0x010)
|
||||||
|
#define SWM_WSI_LISTALL (0x0ff)
|
||||||
|
#define SWM_WSI_HIDECURRENT (0x100)
|
||||||
|
#define SWM_WSI_MARKCURRENT (0x200)
|
||||||
|
#define SWM_WSI_MARKURGENT (0x400)
|
||||||
|
#define SWM_WSI_PRINTNAMES (0x800)
|
||||||
|
#define SWM_WSI_DEFAULT (SWM_WSI_LISTCURRENT | SWM_WSI_LISTACTIVE | \
|
||||||
|
SWM_WSI_MARKCURRENT | SWM_WSI_PRINTNAMES)
|
||||||
|
|
||||||
#define SWM_CONF_DEFAULT (0)
|
#define SWM_CONF_DEFAULT (0)
|
||||||
#define SWM_CONF_KEYMAPPING (1)
|
#define SWM_CONF_KEYMAPPING (1)
|
||||||
|
|
||||||
|
@ -386,6 +399,7 @@ char *clock_format = NULL;
|
||||||
bool window_class_enabled = false;
|
bool window_class_enabled = false;
|
||||||
bool window_instance_enabled = false;
|
bool window_instance_enabled = false;
|
||||||
bool window_name_enabled = false;
|
bool window_name_enabled = false;
|
||||||
|
uint32_t workspace_indicator = SWM_WSI_DEFAULT;
|
||||||
int focus_mode = SWM_FOCUS_DEFAULT;
|
int focus_mode = SWM_FOCUS_DEFAULT;
|
||||||
int focus_close = SWM_STACK_BELOW;
|
int focus_close = SWM_STACK_BELOW;
|
||||||
bool focus_close_wrap = true;
|
bool focus_close_wrap = true;
|
||||||
|
@ -1007,6 +1021,7 @@ void bar_window_float(char *, size_t, struct swm_region *);
|
||||||
void bar_window_instance(char *, size_t, struct swm_region *);
|
void bar_window_instance(char *, size_t, struct swm_region *);
|
||||||
void bar_window_name(char *, size_t, struct swm_region *);
|
void bar_window_name(char *, size_t, struct swm_region *);
|
||||||
void bar_window_state(char *, size_t, struct swm_region *);
|
void bar_window_state(char *, size_t, struct swm_region *);
|
||||||
|
void bar_workspace_indicator(char *, size_t, struct swm_region *);
|
||||||
void bar_workspace_name(char *, size_t, struct swm_region *);
|
void bar_workspace_name(char *, size_t, struct swm_region *);
|
||||||
int binding_cmp(struct binding *, struct binding *);
|
int binding_cmp(struct binding *, struct binding *);
|
||||||
void binding_insert(uint16_t, enum binding_type, uint32_t, enum actionid,
|
void binding_insert(uint16_t, enum binding_type, uint32_t, enum actionid,
|
||||||
|
@ -1146,6 +1161,7 @@ int parse_rgb(const char *, uint16_t *, uint16_t *, uint16_t *);
|
||||||
int parsebinding(const char *, uint16_t *, enum binding_type *, uint32_t *,
|
int parsebinding(const char *, uint16_t *, enum binding_type *, uint32_t *,
|
||||||
uint32_t *);
|
uint32_t *);
|
||||||
int parsequirks(const char *, uint32_t *, int *);
|
int parsequirks(const char *, uint32_t *, int *);
|
||||||
|
int parse_workspace_indicator(const char *, uint32_t *);
|
||||||
void pressbutton(struct binding *, struct swm_region *, union arg *);
|
void pressbutton(struct binding *, struct swm_region *, union arg *);
|
||||||
void priorws(struct binding *, struct swm_region *, union arg *);
|
void priorws(struct binding *, struct swm_region *, union arg *);
|
||||||
#ifdef SWM_DEBUG
|
#ifdef SWM_DEBUG
|
||||||
|
@ -2437,6 +2453,69 @@ bar_urgent(char *s, size_t sz)
|
||||||
s[strlen(s) - 1] = 0;
|
s[strlen(s) - 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bar_workspace_indicator(char *s, size_t sz, struct swm_region *r)
|
||||||
|
{
|
||||||
|
struct ws_win *w;
|
||||||
|
struct workspace *ws;
|
||||||
|
int i, count = 0;
|
||||||
|
char tmp[SWM_BAR_MAX], *mark;
|
||||||
|
bool current, active, named, urgent, collapse;
|
||||||
|
|
||||||
|
if (r == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < workspace_limit; i++) {
|
||||||
|
ws = &r->s->ws[i];
|
||||||
|
|
||||||
|
current = (ws == r->ws);
|
||||||
|
named = (ws->name != NULL);
|
||||||
|
urgent = false;
|
||||||
|
active = false;
|
||||||
|
TAILQ_FOREACH(w, &ws->winlist, entry) {
|
||||||
|
active = true;
|
||||||
|
/* Only get urgent if needed. */
|
||||||
|
if (!(workspace_indicator & SWM_WSI_LISTURGENT ||
|
||||||
|
workspace_indicator & SWM_WSI_MARKURGENT) ||
|
||||||
|
(urgent = get_urgent(w)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse = !(workspace_indicator & SWM_WSI_MARKCURRENT ||
|
||||||
|
workspace_indicator & SWM_WSI_MARKURGENT);
|
||||||
|
|
||||||
|
if (!(current && workspace_indicator & SWM_WSI_HIDECURRENT) &&
|
||||||
|
((current && workspace_indicator & SWM_WSI_LISTCURRENT) ||
|
||||||
|
(active && workspace_indicator & SWM_WSI_LISTACTIVE) ||
|
||||||
|
(!active && workspace_indicator & SWM_WSI_LISTEMPTY) ||
|
||||||
|
(urgent && workspace_indicator & SWM_WSI_LISTURGENT) ||
|
||||||
|
(named && workspace_indicator & SWM_WSI_LISTNAMED))) {
|
||||||
|
if (count > 0)
|
||||||
|
strlcat(s, " ", sz);
|
||||||
|
|
||||||
|
if (current &&
|
||||||
|
workspace_indicator & SWM_WSI_MARKCURRENT)
|
||||||
|
mark = "*";
|
||||||
|
else if (urgent && workspace_indicator &
|
||||||
|
SWM_WSI_MARKURGENT)
|
||||||
|
mark = "!";
|
||||||
|
else if (!collapse)
|
||||||
|
mark = " ";
|
||||||
|
else
|
||||||
|
mark = "";
|
||||||
|
strlcat(s, mark, sz);
|
||||||
|
|
||||||
|
if (named && workspace_indicator & SWM_WSI_PRINTNAMES)
|
||||||
|
snprintf(tmp, sizeof tmp, "%d:%s", ws->idx + 1,
|
||||||
|
ws->name);
|
||||||
|
else
|
||||||
|
snprintf(tmp, sizeof tmp, "%d", ws->idx + 1);
|
||||||
|
strlcat(s, tmp, sz);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bar_workspace_name(char *s, size_t sz, struct swm_region *r)
|
bar_workspace_name(char *s, size_t sz, struct swm_region *r)
|
||||||
{
|
{
|
||||||
|
@ -2581,6 +2660,9 @@ bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep,
|
||||||
case 'I':
|
case 'I':
|
||||||
snprintf(tmp, sizeof tmp, "%d", r->ws->idx + 1);
|
snprintf(tmp, sizeof tmp, "%d", r->ws->idx + 1);
|
||||||
break;
|
break;
|
||||||
|
case 'L':
|
||||||
|
bar_workspace_indicator(tmp, sizeof tmp, r);
|
||||||
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
count = 0;
|
count = 0;
|
||||||
TAILQ_FOREACH(w, &r->ws->winlist, entry)
|
TAILQ_FOREACH(w, &r->ws->winlist, entry)
|
||||||
|
@ -8650,6 +8732,62 @@ grabbuttons(void)
|
||||||
DNPRINTF(SWM_D_MOUSE, "done\n");
|
DNPRINTF(SWM_D_MOUSE, "done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wsi_flag {
|
||||||
|
char *name;
|
||||||
|
uint32_t mask;
|
||||||
|
} wsiflags[] = {
|
||||||
|
{"listcurrent", SWM_WSI_LISTCURRENT},
|
||||||
|
{"listactive", SWM_WSI_LISTACTIVE},
|
||||||
|
{"listempty", SWM_WSI_LISTEMPTY},
|
||||||
|
{"listnamed", SWM_WSI_LISTNAMED},
|
||||||
|
{"listurgent", SWM_WSI_LISTURGENT},
|
||||||
|
{"listall", SWM_WSI_LISTALL},
|
||||||
|
{"hidecurrent", SWM_WSI_HIDECURRENT},
|
||||||
|
{"markcurrent", SWM_WSI_MARKCURRENT},
|
||||||
|
{"markurgent", SWM_WSI_MARKURGENT},
|
||||||
|
{"printnames", SWM_WSI_PRINTNAMES},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SWM_FLAGS_DELIM ","
|
||||||
|
#define SWM_FLAGS_WHITESPACE " \t\n"
|
||||||
|
int
|
||||||
|
parse_workspace_indicator(const char *str, uint32_t *mode)
|
||||||
|
{
|
||||||
|
char *tmp, *cp, *name;
|
||||||
|
size_t len;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (str == NULL || mode == NULL)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
if ((cp = tmp = strdup(str)) == NULL)
|
||||||
|
err(1, "parse_workspace_indicator: strdup");
|
||||||
|
|
||||||
|
*mode = 0;
|
||||||
|
while ((name = strsep(&cp, SWM_FLAGS_DELIM)) != NULL) {
|
||||||
|
if (cp)
|
||||||
|
cp += (long)strspn(cp, SWM_FLAGS_WHITESPACE);
|
||||||
|
name += strspn(name, SWM_FLAGS_WHITESPACE);
|
||||||
|
len = strcspn(name, SWM_FLAGS_WHITESPACE);
|
||||||
|
|
||||||
|
for (i = 0; i < LENGTH(wsiflags); i++) {
|
||||||
|
if (strncasecmp(name, wsiflags[i].name, len) == 0) {
|
||||||
|
DNPRINTF(SWM_D_CONF, "flag: [%s]\n", name);
|
||||||
|
*mode |= wsiflags[i].mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i >= LENGTH(wsiflags)) {
|
||||||
|
DNPRINTF(SWM_D_CONF, "invalid flag: [%s]\n", name);
|
||||||
|
free(tmp);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tmp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
const char *quirkname[] = {
|
const char *quirkname[] = {
|
||||||
"NONE", /* config string for "no value" */
|
"NONE", /* config string for "no value" */
|
||||||
"FLOAT",
|
"FLOAT",
|
||||||
|
@ -9001,6 +9139,7 @@ enum {
|
||||||
SWM_S_WINDOW_NAME_ENABLED,
|
SWM_S_WINDOW_NAME_ENABLED,
|
||||||
SWM_S_WORKSPACE_CLAMP,
|
SWM_S_WORKSPACE_CLAMP,
|
||||||
SWM_S_WORKSPACE_LIMIT,
|
SWM_S_WORKSPACE_LIMIT,
|
||||||
|
SWM_S_WORKSPACE_INDICATOR,
|
||||||
SWM_S_WORKSPACE_NAME,
|
SWM_S_WORKSPACE_NAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9229,6 +9368,10 @@ setconfvalue(const char *selector, const char *value, int flags)
|
||||||
|
|
||||||
ewmh_update_desktops();
|
ewmh_update_desktops();
|
||||||
break;
|
break;
|
||||||
|
case SWM_S_WORKSPACE_INDICATOR:
|
||||||
|
if (parse_workspace_indicator(value, &workspace_indicator))
|
||||||
|
errx(1, "invalid workspace_indicator");
|
||||||
|
break;
|
||||||
case SWM_S_WORKSPACE_NAME:
|
case SWM_S_WORKSPACE_NAME:
|
||||||
if (getenv("SWM_STARTED") != NULL)
|
if (getenv("SWM_STARTED") != NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -9576,6 +9719,7 @@ struct config_option configopt[] = {
|
||||||
{ "window_name_enabled", setconfvalue, SWM_S_WINDOW_NAME_ENABLED },
|
{ "window_name_enabled", setconfvalue, SWM_S_WINDOW_NAME_ENABLED },
|
||||||
{ "workspace_clamp", setconfvalue, SWM_S_WORKSPACE_CLAMP },
|
{ "workspace_clamp", setconfvalue, SWM_S_WORKSPACE_CLAMP },
|
||||||
{ "workspace_limit", setconfvalue, SWM_S_WORKSPACE_LIMIT },
|
{ "workspace_limit", setconfvalue, SWM_S_WORKSPACE_LIMIT },
|
||||||
|
{ "workspace_indicator", setconfvalue, SWM_S_WORKSPACE_INDICATOR },
|
||||||
{ "name", setconfvalue, SWM_S_WORKSPACE_NAME },
|
{ "name", setconfvalue, SWM_S_WORKSPACE_NAME },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
# bar_action = baraction.sh
|
# bar_action = baraction.sh
|
||||||
# bar_justify = left
|
# bar_justify = left
|
||||||
# bar_format = +N:+I +S <+D>+4<%a %b %d %R %Z %Y+8<+A+4<+V
|
# bar_format = +N:+I +S <+D>+4<%a %b %d %R %Z %Y+8<+A+4<+V
|
||||||
|
# workspace_indicator = listcurrent,listactive,markcurrent,printnames
|
||||||
# bar_at_bottom = 1
|
# bar_at_bottom = 1
|
||||||
# stack_enabled = 1
|
# stack_enabled = 1
|
||||||
# clock_enabled = 1
|
# clock_enabled = 1
|
||||||
|
|
Loading…
Add table
Reference in a new issue