Remove old systray, replace with much better version

This commit is contained in:
speediegq 2022-10-02 15:34:11 +02:00
parent 32d3c25bd7
commit 20fcadd6e3
12 changed files with 575 additions and 219 deletions

View file

@ -8,8 +8,7 @@
- Tag previews, Window icons. Can be disabled through editing toggle.mk and toggle.h if you don't want these features.
-- Features --
These are dependencies if you wanna use certain features
NOTE: Do not add any of these to .xinitrc or similar. They are going to be autostarted by speedwm.
These are necessary for certain features. By default speedwm will prevent an installation without them but you can bypass these if you want.
If you want to use an alternative, change it in options.h.
- dmenu
- NOTE: dmenu is required for most scripts included with this build of speedwm. My build is required for proper Pywal support.

View file

@ -62,4 +62,5 @@
- 62 | Remove the scratchpad
- 63 | Reset layout/mfact
- 64 | Reset nmaster
- 65 | Show/Hide systray

View file

@ -49,6 +49,8 @@ static Signal signals[] = {
{ 61, scratchpad_hide, {0} },
{ 62, scratchpad_remove, {0} },
{ 63, reset_layout, {0} },
{ 64, resetnmaster, {0} },
{ 65, togglesystray, {0} },
#if LAYOUT_TILE
{ 1, setlayout, {.v = &layouts[0]} }, /* Tiling layout */

View file

@ -64,7 +64,9 @@ static const Key keys[] = {
{ MODIFIER1|CONTROL|SHIFT, -1, XK_m, spawn, RCMD(TERMINAL EMAIL) },
{ MODIFIER1|CONTROL|SHIFT, -1, XK_f, spawn, RCMD("speedwm_run -configure") },
{ MODIFIER1|CONTROL|SHIFT, -1, XK_r, spawn, RCMD("speedwm_run -r") },
{ MODIFIER1, -1, XK_s, spawn, RCMD("speedwm-core -toggle") },
#if USESYSTRAY
{ MODIFIER1, -1, XK_s, togglesystray, {0} },
#endif
/* Layout keybinds */
{ MODIFIER1|CONTROL|SHIFT, -1, XK_a, cyclelayout, {.i = -1 } },

View file

@ -209,13 +209,22 @@ static int iconspacing = 5; /* spacing between the title
#endif
/* Bar options */
static int barheight = 5; /* Bar height in px, 0 = calculate automatically */
static int barposition = 1; /* Bar position. Top: 0, Bottom: 1 */
static int barpaddingv = 10; /* How much padding to have vertically in pixels */
static int barpaddingh = 10; /* How much padding to have horizontally in pixels */
static int barpaddinggaps = 1; /* Set barpadding to the gaps */
static int barheight = 5; /* Bar height in px, 0 = calculate automatically */
static int barpaddingv = 10; /* Vertical bar padding in px. */
static int barpaddingh = 10; /* Horizontal bar padding in px. */
/* Layout indicator options */
static int layoutposition = 1; /* Layout indicator on the left (1) or on the right (0) */
/* Systray options */
#if USESYSTRAY
static int systraypinning = 0; /* Show systray on focused monitor (1) or (<monitor number>) to pin to a specific monitor */
static int systrayonleft = 0; /* Systray position. Right: 0, Left: 1. */
static int systrayspacing = 2; /* Systray spacing in pixels */
static int showsystray = 0; /* Show systray by default (0) or show (1) */
#endif
/* Tag text options */
static int underline = 0; /* Underline tags (1) or not (0) */
static int underlineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */

View file

@ -39,26 +39,9 @@ else
printf "Error: ${BINDIR}xmodmap was not found\n" && exit 1
fi
# Check if trayer exists
if [ -e "${BINDIR}trayer" ]; then
trayer_exists=true
elif [ -e "${BINDIR}trayer-srg" ]; then
trayer_exists=true
trayer_srg=true
fi
# Check if srg or not.
if [ "$trayer_exists" = "false" ]; then
if [ "$trayer_srg" = "true" ]; then
printf "WARNING: Before trayer-srg can be used instead of trayer, you must edit ~/.config/speedwm-de/systray/config and set USE_SRG to true.\n"
else
printf "WARNING: trayer was not found. This means the systray will not be available.\n"
fi
fi
# Check if dmenu exists
command -v dmenu > /dev/null || printf "\nWARNING: dmenu was not found. This means running applications will potentially be very inconvenient. It also means most bundled scripts will NOT work unless modified to work with rofi. See help for more information"
# Check if slock exists
command -v slock > /dev/null || printf "\nWARNING: slock was not found. This means the shutdown menu can't lock your screen."
result="$(echo "$xrdb_exists$wmctrl_exists$xsetroot_exists$xwallpaper_exists$xmodmap_exists$trayer_exists")"
result="$(echo "$xrdb_exists$wmctrl_exists$xsetroot_exists$xwallpaper_exists$xmodmap_exists")"

View file

@ -1,6 +1,6 @@
#!/bin/sh
# speedwm-core
# This script handles the systray and other things necessary for keybinds.
# This script handles the updating and other things necessary for keybinds.
# Set binary directory if not set already.
if [ -e "/usr/share/speedwm/bindir" ]; then
@ -9,104 +9,8 @@ else
BINDIR="/usr/bin/"
fi
TINT="#222222" # Default tint
EDGE="top" # Part of the screen where your systray will be placed
GET_EDGE_AUTO="true" # Get edge automatically (true/false)
SYSTRAY_COL=1 # When using pywal, set color to background (1) or backgroundmid (0)
USE_SRG=false # Use $SYSTRAY-srg (available in Gentoo repos and AUR as $SYSTRAY-srg-git) instead of $SYSTRAY adding more features (true/false)
USE_DEFAULT_TINT=false # Use default $TINT or use $SYSTRAY_COL
ALPHA=0 # Opacity of the systray (0 is opaque, 255 is fully transparent)
HIDE_BAR_WHEN_SYSTRAY_SHOW=false # Hide the speedwm bar when the systray is running.
ALPHA_BARHIDDEN=255 # Opacity of the systray when the speedwm bar is hidden (0 is opaque, 255 is fully transparent)
TRANSPARENT=true # Transparent or not (true/false)
EXPORTDIR=$HOME/.config/speedwm-de/systray # Config directory
HEIGHT=18 # Height of the systray
WIDTH=30 # Width of the systray
SHOW_SYSTRAY_WHEN_BARPADDING=true # Show systray if vertical barpadding is enabled
mkdir -p $EXPORTDIR
# Load config if available and override settings
if [ -e "$EXPORTDIR/config" ]; then
. $EXPORTDIR/config
else
printf "TINT=$TINT # Tint when pywal is not used." > $EXPORTDIR/config
printf "\nEDGE=$EDGE # Part of the screen where your systray will be placed" >> $EXPORTDIR/config
printf "\nGET_EDGE_AUTO=$GET_EDGE_AUTO # Get edge automatically (true/false)" >> $EXPORTDIR/config
printf "\nSYSTRAY_COL=$SYSTRAY_COL # When using pywal, set color to background (1) or backgroundmid (0)" >> $EXPORTDIR/config
printf "\nALPHA=$ALPHA # Opacity of the systray (0 is opaque, 255 is fully transparent)" >> $EXPORTDIR/config
printf "\nALPHA_BARHIDDEN=$ALPHA_BARHIDDEN # Opacity of the systray when the speedwm bar is hidden (0 is opaque, 255 is fully transparent)" >> $EXPORTDIR/config
printf "\nTRANSPARENT=true # Transparent or not (true/false)" >> $EXPORTDIR/config
printf "\nHIDE_BAR_WHEN_SYSTRAY_SHOW=$HIDE_BAR_WHEN_SYSTRAY_SHOW # Hide the speedwm bar when the systray is running." >> $EXPORTDIR/config
printf "\nUSE_SRG=$USE_SRG # Use $SYSTRAY-srg (available in Gentoo repos and AUR as $SYSTRAY-srg-git) instead of $SYSTRAY adding more features (true/false)" >> $EXPORTDIR/config
printf "\nUSE_DEFAULT_TINT=$USE_DEFAULT_TINT # Use default $TINT or use $SYSTRAY_COL" >> $EXPORTDIR/config
printf "\nSHOW_SYSTRAY_WHEN_BARPADDING=$SHOW_SYSTRAY_WHEN_BARPADDING # Show systray if vertical barpadding is enabled" >> $EXPORTDIR/config
printf "\nHEIGHT=$HEIGHT # Height of the systray" >> $EXPORTDIR/config
printf "\nWIDTH=$WIDTH # Width of the systray\n" >> $EXPORTDIR/config
fi
TINT="$(echo $TINT | sed "s|#||g")"
OPT=$1
# Pywal tint
PYWAL_TINT() {
# Pywal tint
if [ "$USE_DEFAULT_TINT" = "false" ]; then
if [ -e "$HOME/.cache/wal/colors" ]; then
if [ "$SYSTRAY_COL" = "1" ]; then
TINT=$(sed -n 1,1p $HOME/.cache/wal/colors | sed "s|#||g")
elif [ "$SYSTRAY_COL" = "0" ]; then
TINT=$(sed -n 13,13p $HOME/.cache/wal/colors | sed "s|#||g")
fi
fi
fi
}
# Set edge
SETEDGE() {
if [ "$GET_EDGE_AUTO" = "true" ]; then
if [ -e "/usr/share/speedwm/topbar" ]; then
EDGE="top"
else
EDGE="bottom"
fi
fi
}
# Set alpha
SETALPHA() {
if [ "$HIDE_BAR_WHEN_SYSTRAY_SHOW" = "true" ]; then
ALPHA=$ALPHA_BARHIDDEN
else
ALPHA=$ALPHA
fi
}
PYWAL_TINT
SETEDGE
SETALPHA
# Set systray
if [ "$USE_SRG" = "true" ]; then
SYSTRAY=trayer-srg
else
SYSTRAY=trayer
fi
USE() {
echo USE
# Toggle
TOGGLE() {
if [ -e "/tmp/systray-started" ]; then
OPT="-stop"
else
OPT="-start"
fi
}
# Update speedwm
UPDATE() {
# update
UPDATE_SPEEDWM() {
FAIL_SOURCEDOESNOTEXIST() {
echo "The speedwm source code directory could not be located. This means an automatic update cannot be performed. Clone a new build (instructions on https://speedie.gq/speedwm) and update manually."
exit 1
@ -145,48 +49,14 @@ echo USE
echo 'speedwm has been updated!'
exit 0
}
case "$OPT" in
"-toggle") TOGGLE ;;
"-update-speedwm") UPDATE ;;
esac
case "$OPT" in
"-start") $SYSTRAY --edge $EDGE --align right --SetDockType true --SetPartialStrut true --expand true --width $WIDTH --transparent $TRANSPARENT --alpha $ALPHA --tint 0x${TINT} --height $HEIGHT &
touch /tmp/systray-started ; pgrep -x status && pkill -x status ; status &
if [ "$HIDE_BAR_WHEN_SYSTRAY_SHOW" = "true" ]; then
xsetroot -name "fsignal:25"
fi ;;
"-stop") rm -f /tmp/systray-started ; pkill -x $SYSTRAY ; pgrep -x status && pkill -x status ; status &
if [ "$HIDE_BAR_WHEN_SYSTRAY_SHOW" = "true" ]; then
xsetroot -name "fsignal:25"
fi ;;
"") echo "speedwm-core\n-start | Start the systray and restart status\n-stop | Stop the systray and restart status\n-toggle | Toggle systray and restart status\n-update-speedwm | Update speedwm using git\n-curl-weather | Curl wttr.in in a readable format\n-curl-cheatsheet | Ask the user what cheatsheet they want and then curl it." ;;
esac
}
OPT=$1
case "$OPT" in
"-curl-weather") clear ; curl -s wttr.in | head -n 38 | tail -n 37 && sleep 60 ;;
"-curl-cheatsheet") clear ; echo -n "What cheatsheet do you want to view?\nExample: vim\n > " ; read CHEATSHEET ; curl -s cheat.sh/$(echo $CHEATSHEET | tr '[:upper:]' '[:lower:]') > /tmp/cheatsheet
grep "Unknown topic." /tmp/cheatsheet && $0 -curl-cheatsheet && exit 0
less /tmp/cheatsheet ;;
"-update-speedwm") UPDATE_SPEEDWM ;;
esac
OPT=$1
# Start systray
if [ -e "${BINDIR}$SYSTRAY" ]; then
if [ -e "$HOME/.config/speedwm-de/speedwmrc" ]; then
if [ "$SHOW_SYSTRAY_WHEN_BARPADDING" = "true" ]; then
USE
else
grep "barpaddingv" $HOME/.config/speedwm-de/speedwmrc > /tmp/out
grep -q "0" /tmp/out > /dev/null && USE
fi
else
USE
fi
else
echo "Trayer not installed." && USE
fi

View file

@ -129,7 +129,6 @@ CONFIGURE() {
test $HOME/.config/speedwm-de/screenshotutil/config && DOTFILE4="$HOME/.config/speedwm-de/screenshotutil/config"
test $HOME/.config/speedwm-de/status/config && DOTFILE5="$HOME/.config/speedwm-de/status/config"
test $HOME/.config/speedwm-de/swal/config && DOTFILE6="$HOME/.config/speedwm-de/swal/config"
test $HOME/.config/speedwm-de/systray/config && DOTFILE7="$HOME/.config/speedwm-de/systray/config"
test $HOME/.config/speedwm-de/winnav/config && DOTFILE8="$HOME/.config/speedwm-de/winnav/config"
test $HOME/.config/speedwm-de/global/config && DOTFILE9="$HOME/.config/speedwm-de/global/config"

560
speedwm.c
View file

@ -64,6 +64,21 @@
#define RIGHTOF(a,b) (a.y_org > b.y_org) || \
((a.y_org == b.y_org) && (a.x_org > b.x_org))
#if USESYSTRAY
#define SYSTEM_TRAY_REQUEST_DOCK 0
/* XEMBED messages */
#define XEMBED_EMBEDDED_NOTIFY 0
#define XEMBED_WINDOW_ACTIVATE 1
#define XEMBED_FOCUS_IN 4
#define XEMBED_MODALITY_ON 10
#define XEMBED_MAPPED (1 << 0)
#define XEMBED_WINDOW_ACTIVATE 1
#define XEMBED_WINDOW_DEACTIVATE 2
#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
#endif
#define OPAQUE 0xffU
#define TRANSPARENT 0
@ -94,12 +109,19 @@ enum { NetSupported, NetWMName,
NetWMIcon,
#endif
NetWMState, NetWMCheck,
#if USESYSTRAY
NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
#endif
NetWMFullscreen, NetActiveWindow, NetWMWindowType, NetWMWindowTypeDesktop,
NetWMWindowTypeDialog, NetClientList, NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop,
#if USEFADE
NetWMWindowsOpacity,
#endif
NetClientListStacking, NetClientInfo, NetLast }; /* EWMH atoms */
#if USESYSTRAY
enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
#endif
enum { WMClass, WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { DWMTags, DWMLast };
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
@ -257,6 +279,14 @@ typedef struct {
const char scratchkey;
} Rule;
#if USESYSTRAY
typedef struct Systray Systray;
struct Systray {
Window win;
Client *icons;
};
#endif
typedef struct {
const char *cmd;
int id;
@ -357,6 +387,21 @@ static Picture geticonprop(Window w, unsigned int *icw, unsigned int *ich);
#endif
static int getrootptr(int *x, int *y);
static long getstate(Window w);
#if USESYSTRAY
static unsigned int getsystraywidth();
static void removesystrayicon(Client *i);
static void resizebarwin(Monitor *m);
static void resizerequest(XEvent *e);
static Monitor *systraytomon(Monitor *m);
static void updatesystray(void);
static void updatesystrayicongeom(Client *i, int w, int h);
static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
static Client *wintosystrayicon(Window w);
static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
static void togglesystray();
#else
static int sendevent(Client *c, Atom proto);
#endif
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, int focused);
static void hide(const Arg *arg);
@ -416,7 +461,6 @@ static void scratchpad_remove ();
static void scratchpad_show ();
static void scratchpad_show_client (Client * c);
static void scratchpad_show_first (void);
static int sendevent(Client *c, Atom proto);
static void sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state);
static void setclienttagprop(Client *c);
@ -526,6 +570,9 @@ static Client *termforwin(const Client *c);
static pid_t winpid(Window w);
/* variables */
#if USESYSTRAY
static Systray *systray = NULL;
#endif
static const char broken[] = "speedwm";
#if USEMOUSE
static const char *layoutmenu_cmd = "speedwm-utils layout";
@ -565,9 +612,16 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[MapRequest] = maprequest,
[MotionNotify] = motionnotify,
[PropertyNotify] = propertynotify,
#if USESYSTRAY
[ResizeRequest] = resizerequest,
#endif
[UnmapNotify] = unmapnotify
};
#if USESYSTRAY
static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast], dwmatom[DWMLast], motifatom;
#else
static Atom wmatom[WMLast], netatom[NetLast], dwmatom[DWMLast], motifatom;
#endif
#if USEIPC
static int epoll_fd;
static int dpy_fd;
@ -613,6 +667,10 @@ static xcb_connection_t *xcon;
/* Configuration */
#include "options.h" /* Include options */
#if USESYSTRAY
static int systraypinningfailfirst = 1;
#endif
/* Shell command */
#define RCMD(cmd) {.v = (const char*[]){ shell, "-c", cmd, NULL } },
#define SESSION_FILE "/tmp/speedwm-session"
@ -1044,8 +1102,13 @@ buttonpress(XEvent *e)
arg.ui = 1 << i;
} else if (ev->x < x + TEXTW(selmon->ltsymbol) && !layoutposition && !selmon->isreset) // right layout
click = ClkLtSymbol; // right layout
#if USESYSTRAY
else if (ev->x > selmon->ww - statusw + lrpad - 2 - getsystraywidth() && !hidestatus) {
x = selmon->ww - statusw + lrpad - 2 * sp - getsystraywidth() - 2;
#else
else if (ev->x > selmon->ww - statusw + lrpad - 2 && !hidestatus) {
x = selmon->ww - statusw + lrpad - 2;
x = selmon->ww - statusw + lrpad - 2 * sp - 2;
#endif
click = ClkStatusText;
char *text = rawstext;
int i = -1;
@ -1132,6 +1195,15 @@ cleanup(void)
XUngrabKey(dpy, AnyKey, AnyModifier, root);
while (mons)
cleanupmon(mons);
#if USESYSTRAY
if (showsystray) {
XUnmapWindow(dpy, systray->win);
XDestroyWindow(dpy, systray->win);
free(systray);
}
#endif
for (i = 0; i < CurLast; i++)
drw_cur_free(drw, cursor[i]);
for (i = 0; i < LENGTH(colors) + 1; i++)
@ -1192,6 +1264,59 @@ clientmessage(XEvent *e)
{
XClientMessageEvent *cme = &e->xclient;
Client *c = wintoclient(cme->window);
#if USESYSTRAY
XWindowAttributes wa;
XSetWindowAttributes swa;
if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
/* add systray icons */
if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
if (!(c = (Client *)calloc(1, sizeof(Client))))
die("fatal: could not malloc() %u bytes\n", sizeof(Client));
if (!(c->win = cme->data.l[2])) {
free(c);
return;
}
c->mon = selmon;
c->next = systray->icons;
systray->icons = c;
if (!XGetWindowAttributes(dpy, c->win, &wa)) {
/* use sane defaults */
wa.width = bh;
wa.height = bh;
wa.border_width = 0;
}
c->x = c->oldx = c->y = c->oldy = 0;
c->w = c->oldw = wa.width;
c->h = c->oldh = wa.height;
c->oldbw = wa.border_width;
c->bw = 0;
c->isfloating = True;
/* reuse tags field as mapped status */
c->tags = 1;
updatesizehints(c);
updatesystrayicongeom(c, wa.width, wa.height);
XAddToSaveSet(dpy, c->win);
XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
XReparentWindow(dpy, c->win, systray->win, 0, 0);
/* use parents background color */
swa.background_pixel = scheme[SchemeBar][ColBg].pixel;
XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa);
sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
/* FIXME not sure if I have to send these events, too */
sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
XSync(dpy, False);
resizebarwin(selmon);
updatesystray();
setclientstate(c, NormalState);
}
return;
}
#endif
unsigned int i;
if (!c)
@ -1240,7 +1365,6 @@ configurenotify(XEvent *e)
XConfigureEvent *ev = &e->xconfigure;
int dirty;
/* TODO: updategeom handling sucks, needs to be simplified */
if (ev->window == root) {
dirty = (tw != ev->width || sh != ev->height);
tw = ev->width;
@ -1252,7 +1376,11 @@ 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 + sp, m->by + vp, m->ww - 2 * sp, m->bh);
#if USESYSTRAY
resizebarwin(m);
#else
XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh);
#endif
}
focus(NULL);
arrange(NULL);
@ -1454,6 +1582,15 @@ destroynotify(XEvent *e)
if ((c = wintoclient(ev->window)))
unmanage(c, 1);
#if USESYSTRAY
else if ((c = wintosystrayicon(ev->window))) {
removesystrayicon(c);
resizebarwin(selmon);
updatesystray();
}
#endif
else if ((c = swallowingclient(ev->window)))
unmanage(c->swallowing, 1);
@ -1683,7 +1820,12 @@ drawstatusbar(Monitor *m, int bh, char* stext) {
text = p;
w += 2; /* 1px padding on both sides */
#if USESYSTRAY
ret = x = m->ww - w - 2 * sp - getsystraywidth();
#else
ret = x = m->ww - w - 2 * sp;
#endif
drw_setscheme(drw, scheme[LENGTH(colors)]);
drw->scheme[ColFg] = scheme[SchemeStatus][ColFg];
@ -1757,6 +1899,9 @@ void
drawbar(Monitor *m)
{
int x = 0, w = 0, tw = 0, scm;
#if USESYSTRAY
int stw = 0;
#endif
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0, n = 0;
@ -1772,12 +1917,24 @@ drawbar(Monitor *m)
if (altbar)
return;
#if USESYSTRAY
if(showsystray && m == systraytomon(m) && !systrayonleft)
stw = getsystraywidth();
#endif
/* draw status first so it can be overdrawn by tags later */
if (m == selmon || 1) { /* status is only drawn on selected monitor */
char *text, *s, ch;
if (!hidestatus) {
#if USESYSTRAY
tw = statusw = m->ww - drawstatusbar(m, bh, stext) - getsystraywidth();
#else
tw = statusw = m->ww - drawstatusbar(m, bh, stext);
#endif
}
#if USESYSTRAY
resizebarwin(m);
#endif
// for statuscmd
for (text = s = stext; *s; s++) {
@ -1850,7 +2007,11 @@ drawbar(Monitor *m)
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
}
#if USESYSTRAY
if ((w = m->ww - tw - stw - x) > bh) {
#else
if ((w = m->ww - tw - x) > bh) {
#endif
if (n > 0) {
int remainder = w % n;
int tabw = (1.0 / (double)n) * w + 1;
@ -1905,7 +2066,11 @@ drawbar(Monitor *m)
m->bt = n;
m->btw = w;
#if USESYSTRAY
drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
#else
drw_map(drw, m->barwin, 0, 0, m->ww, bh);
#endif
}
void
@ -1944,8 +2109,14 @@ expose(XEvent *e)
Monitor *m;
XExposeEvent *ev = &e->xexpose;
if (ev->count == 0 && (m = wintomon(ev->window)))
if (ev->count == 0 && (m = wintomon(ev->window))) {
drawbar(m);
#if USESYSTRAY
if (m == selmon)
updatesystray();
#endif
}
}
void
@ -2108,9 +2279,22 @@ getatomprop(Client *c, Atom prop)
unsigned char *p = NULL;
Atom da, atom = None;
#if USESYSTRAY
Atom req = XA_ATOM;
if (prop == xatom[XembedInfo])
req = xatom[XembedInfo];
if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
#else
if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
#endif
&da, &di, &dl, &dl, &p) == Success && p) {
atom = *(Atom *)p;
#if USESYSTRAY
if (da == xatom[XembedInfo] && dl == 2)
atom = ((Atom *)p)[1];
#endif
XFree(p);
}
return atom;
@ -2207,6 +2391,30 @@ getstate(Window w)
return result;
}
#if USESYSTRAY
unsigned int
getsystraywidth()
{
unsigned int w = 0;
Client *i;
if(showsystray)
for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
return w ? w + systrayspacing : 1;
}
void
togglesystray()
{
if (showsystray)
XUnmapWindow(dpy, systray->win);
showsystray = !showsystray;
updatesystray();
updatestatus();
}
#endif
int
gettextprop(Window w, Atom atom, char *text, unsigned int size)
{
@ -2535,11 +2743,6 @@ void
togglegaps(const Arg *arg)
{
enablegaps = !enablegaps;
if (barpaddingv != 0 && barpaddingh != 0 && barpaddinggaps && enablegaps) {
updatebarpos(selmon);
}
arrange(selmon);
}
@ -2587,7 +2790,11 @@ killclient(const Arg *arg)
{
if (!selmon->sel || selmon->sel->ispermanent)
return;
#if USESYSTRAY
if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
#else
if (!sendevent(selmon->sel, wmatom[WMDelete])) {
#endif
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll);
@ -2608,7 +2815,11 @@ killunsel(const Arg *arg)
for (i = selmon->clients; i; i = i->next) {
if (ISVISIBLE(i) && i != selmon->sel) {
if (!sendevent(i, wmatom[WMDelete])) {
#if USESYSTRAY
if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
#else
if (!sendevent(selmon->sel, wmatom[WMDelete])) {
#endif
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll);
@ -2839,6 +3050,15 @@ maprequest(XEvent *e)
static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest;
#if USESYSTRAY
Client *i;
if ((i = wintosystrayicon(ev->window))) {
sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
resizebarwin(selmon);
updatesystray();
}
#endif
if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect)
return;
if (!wa.depth)
@ -3413,6 +3633,19 @@ propertynotify(XEvent *e)
Window trans;
XPropertyEvent *ev = &e->xproperty;
#if USESYSTRAY
if ((c = wintosystrayicon(ev->window))) {
if (ev->atom == XA_WM_NORMAL_HINTS) {
updatesizehints(c);
updatesystrayicongeom(c, c->w, c->h);
}
else
updatesystrayiconstate(c, ev);
resizebarwin(selmon);
updatesystray();
}
#endif
if ((ev->window == root) && (ev->atom == XA_WM_NAME)) {
if (!fake_signal())
updatestatus();
@ -3615,6 +3848,42 @@ resetnmaster(const Arg *arg)
arrange(selmon);
}
#if USESYSTRAY
void
removesystrayicon(Client *i)
{
Client **ii;
if (!showsystray || !i)
return;
for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
if (ii)
*ii = i->next;
free(i);
}
void
resizebarwin(Monitor *m) {
unsigned int w = m->ww;
if (showsystray && m == systraytomon(m) && !systrayonleft)
w -= getsystraywidth();
XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh);
}
void
resizerequest(XEvent *e)
{
XResizeRequestEvent *ev = &e->xresizerequest;
Client *i;
if ((i = wintosystrayicon(ev->window))) {
updatesystrayicongeom(i, ev->width, ev->height);
resizebarwin(selmon);
updatesystray();
}
}
#endif
void
resize(Client *c, int x, int y, int w, int h, int interact)
{
@ -3926,26 +4195,60 @@ setdesktopnames(void)
}
int
#if USESYSTRAY
sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4)
#else
sendevent(Client *c, Atom proto)
#endif
{
int n;
#if USESYSTRAY
Atom *protocols, mt;
#else
Atom *protocols;
#endif
int exists = 0;
XEvent ev;
#if USESYSTRAY
if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
mt = wmatom[WMProtocols];
#endif
#if USESYSTRAY
if (XGetWMProtocols(dpy, w, &protocols, &n)) {
#else
if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
#endif
while (!exists && n--)
exists = protocols[n] == proto;
XFree(protocols);
}
#if USESYSTRAY
} else {
exists = True;
mt = proto;
}
#endif
if (exists) {
ev.type = ClientMessage;
ev.xclient.format = 32;
#if USESYSTRAY
ev.xclient.window = w;
ev.xclient.message_type = mt;
ev.xclient.data.l[0] = d0;
ev.xclient.data.l[1] = d1;
ev.xclient.data.l[2] = d2;
ev.xclient.data.l[3] = d3;
ev.xclient.data.l[4] = d4;
XSendEvent(dpy, w, False, mask, &ev);
#else
ev.xclient.window = c->win;
ev.xclient.message_type = wmatom[WMProtocols];
ev.xclient.format = 32;
ev.xclient.data.l[0] = proto;
ev.xclient.data.l[1] = CurrentTime;
XSendEvent(dpy, c->win, False, NoEventMask, &ev);
#endif
}
return exists;
}
@ -3965,7 +4268,11 @@ setfocus(Client *c)
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &(c->win), 1);
}
#if USESYSTRAY
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
#else
sendevent(c, wmatom[WMTakeFocus]);
#endif
}
void
@ -4096,6 +4403,7 @@ setup(void)
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
bh = altbar ? 0 : drw->fonts->h + barheight;
// barpadding
sp = barpaddingh;
vp = (barposition == 1) ? barpaddingv : - barpaddingv;
updategeom();
@ -4110,6 +4418,12 @@ setup(void)
wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
#if USESYSTRAY
netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False);
#endif
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
#if USEWINICON
netatom[NetWMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False);
@ -4135,6 +4449,11 @@ setup(void)
netatom[NetCurrentDesktop] = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
netatom[NetDesktopNames] = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False);
motifatom = XInternAtom(dpy, "_MOTIF_WM_HINTS", False);
#if USESYSTRAY
xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
#endif
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
@ -4149,6 +4468,9 @@ setup(void)
tagscheme = ecalloc(LENGTH(tagsel), sizeof(Clr *));
for (i = 0; i < LENGTH(tagsel); i++)
tagscheme[i] = drw_scm_create(drw, tagsel[i], tagalpha, 2);
#if USESYSTRAY
updatesystray();
#endif
/* init bars */
updatebars();
updatestatus();
@ -4323,9 +4645,9 @@ takepreview(void)
else
imlib_copy_drawable_to_image(0, selmon->mx, selmon->my, selmon->mw ,selmon->mh, 0, 0, 1);
selmon->tagmap[i] = XCreatePixmap(dpy, selmon->tagwin, selmon->mw + tagpreviewpaddingh / scalepreview, selmon->mh + 1 * sp + tagpreviewpaddingv / scalepreview, depth);
selmon->tagmap[i] = XCreatePixmap(dpy, selmon->tagwin, selmon->mw + tagpreviewpaddingh / scalepreview, selmon->mh + tagpreviewpaddingv / scalepreview, depth);
imlib_context_set_drawable(selmon->tagmap[i]);
imlib_render_image_part_on_drawable_at_size(0, 0, selmon->mw + tagpreviewpaddingh, selmon->mh + 1 * sp, 0, 0 + tagpreviewpaddingv + 1 * sp, selmon->mw / scalepreview, selmon->mh / scalepreview);
imlib_render_image_part_on_drawable_at_size(0, 0, selmon->mw + tagpreviewpaddingh, selmon->mh, 0, 0 + tagpreviewpaddingv, selmon->mw / scalepreview, selmon->mh / scalepreview);
imlib_free_image();
}
}
@ -4464,9 +4786,23 @@ togglebar(const Arg *arg)
selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, selmon->bh);
XMoveResizeWindow(dpy, selmon->traywin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, selmon->bh);
#if USESYSTRAY
resizebarwin(selmon);
if (showsystray) {
XWindowChanges wc;
if (!selmon->showbar)
wc.y = -bh;
else if (selmon->showbar) {
wc.y = 0;
if (!selmon->barposition)
wc.y = selmon->mh - bh;
}
XConfigureWindow(dpy, systray->win, CWY, &wc);
}
#else
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, selmon->bh);
XMoveResizeWindow(dpy, selmon->traywin, selmon->wx, selmon->by, selmon->ww, selmon->bh);
#endif
if (altbar)
XMoveResizeWindow(dpy, selmon->traywin, selmon->tx, selmon->by, selmon->tw, selmon->bh);
arrange(selmon);
@ -4639,7 +4975,17 @@ unmapnotify(XEvent *e)
setclientstate(c, WithdrawnState);
else
unmanage(c, 0);
} else if (altbar && (m = wintomon(ev->window)) && m->barwin == ev->window)
}
#if USESYSTRAY
else if ((c = wintosystrayicon(ev->window))) {
/* KLUDGE! sometimes icons occasionally unmap their windows, but do
* _not_ destroy them. We map those windows back */
XMapRaised(dpy, c->win);
updatesystray();
}
#endif
else if (altbar && (m = wintomon(ev->window)) && m->barwin == ev->window)
unmanagealtbar(ev->window);
else if (altbar && m->traywin == ev->window)
unmanagetray(ev->window);
@ -4651,6 +4997,9 @@ updatebars(void)
if (altbar)
return;
#if USESYSTRAY
unsigned int w;
#endif
Monitor *m;
XSetWindowAttributes wa = {
.override_redirect = True,
@ -4672,10 +5021,22 @@ updatebars(void)
#endif
if (m->barwin)
continue;
#if USESYSTRAY
w = m->ww;
if (showsystray && m == systraytomon(m))
w -= getsystraywidth();
#endif
m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh, 0, depth,
//m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh, 0, DefaultDepth(dpy, screen),
InputOutput, visual,
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
#if USESYSTRAY
if (showsystray && m == systraytomon(m))
XMapRaised(dpy, systray->win);
#endif
XMapRaised(dpy, m->barwin);
XSetClassHint(dpy, m->barwin, &ch);
}
@ -4686,15 +5047,12 @@ updatebarpos(Monitor *m)
{
m->wy = m->my;
m->wh = m->mh;
if (barpaddingv != 0 && barpaddingh != 0 && barpaddinggaps && enablegaps) {
barpaddingv = gappov;
barpaddingh = gappoh;
} if (m->showbar) {
m->wh = m->wh - barpaddingv - m->bh;
if (m->showbar) {
m->wh = m->wh - barpaddingv - bh;
m->by = m->barposition ? m->wy : m->wy + m->wh + barpaddingv;
m->wy = m->barposition ? m->wy + m->bh + vp : m->wy;
m->wy = m->barposition ? m->wy + bh + vp : m->wy;
} else
m->by = -m->bh - vp;
m->by = -bh - vp;
}
void
@ -4948,6 +5306,10 @@ updatestatus(void)
} else {
drawbar(selmon);
}
#if USESYSTRAY
updatesystray();
#endif
}
void
@ -5307,6 +5669,154 @@ swallowingclient(Window w)
return NULL;
}
#if USESYSTRAY
void
updatesystrayicongeom(Client *i, int w, int h)
{
if (i) {
i->h = bh;
if (w == h)
i->w = bh;
else if (h == bh)
i->w = w;
else
i->w = (int) ((float)bh * ((float)w / (float)h));
applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
/* force icons into the systray dimensions if they don't want to */
if (i->h > bh) {
if (i->w == i->h)
i->w = bh;
else
i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
i->h = bh;
}
}
}
void
updatesystrayiconstate(Client *i, XPropertyEvent *ev)
{
long flags;
int code = 0;
if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
!(flags = getatomprop(i, xatom[XembedInfo])))
return;
if (flags & XEMBED_MAPPED && !i->tags) {
i->tags = 1;
code = XEMBED_WINDOW_ACTIVATE;
XMapRaised(dpy, i->win);
setclientstate(i, NormalState);
}
else if (!(flags & XEMBED_MAPPED) && i->tags) {
i->tags = 0;
code = XEMBED_WINDOW_DEACTIVATE;
XUnmapWindow(dpy, i->win);
setclientstate(i, WithdrawnState);
}
else
return;
sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
systray->win, XEMBED_EMBEDDED_VERSION);
}
void
updatesystray(void)
{
XSetWindowAttributes wa;
XWindowChanges wc;
Client *i;
Monitor *m = systraytomon(NULL);
unsigned int x = m->mx + m->mw - sp;
unsigned int y = m->by + vp;
unsigned int sw = TEXTW(stext) - lrpad + systrayspacing;
unsigned int w = 1;
if (!showsystray)
return;
if (systrayonleft)
x -= sw + lrpad / 2;
if (!systray) {
/* init systray */
if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
systray->win = XCreateSimpleWindow(dpy, root, x, y, w, bh, 0, 0, scheme[SchemeSelTitle][ColBg].pixel);
wa.event_mask = ButtonPressMask | ExposureMask;
wa.override_redirect = True;
wa.background_pixel = scheme[SchemeBar][ColBg].pixel;
XSelectInput(dpy, systray->win, SubstructureNotifyMask);
XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1);
XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa);
XMapRaised(dpy, systray->win);
XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
XSync(dpy, False);
}
else {
fprintf(stderr, "dwm: unable to obtain system tray.\n");
free(systray);
systray = NULL;
return;
}
}
for (w = 0, i = systray->icons; i; i = i->next) {
/* make sure the background color stays the same */
wa.background_pixel = scheme[SchemeBar][ColBg].pixel;
XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
XMapRaised(dpy, i->win);
w += systrayspacing;
i->x = w;
XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
w += i->w;
if (i->mon != m)
i->mon = m;
}
w = w ? w + systrayspacing : 1;
x -= w;
XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
wc.x = x; wc.y = y; wc.width = w; wc.height = bh;
wc.stack_mode = Above; wc.sibling = m->barwin;
XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc);
XMapWindow(dpy, systray->win);
XMapSubwindows(dpy, systray->win);
/* redraw background */
XSetForeground(dpy, drw->gc, scheme[SchemeBar][ColBg].pixel);
//XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); // Without alpha
XFillRectangle(dpy, systray->win, XCreateGC(dpy, root, 0 , NULL), 0, 0, w, bh); // With alpha
XSync(dpy, False);
}
Client *
wintosystrayicon(Window w) {
Client *i = NULL;
if (!showsystray || !w)
return i;
for (i = systray->icons; i && i->win != w; i = i->next) ;
return i;
}
Monitor *
systraytomon(Monitor *m) {
Monitor *t;
int i, n;
if(!systraypinning) {
if(!m)
return selmon;
return m == selmon ? m : NULL;
}
for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ;
if(systraypinningfailfirst && n < systraypinning)
return mons;
return t;
}
#endif
Client *
wintoclient(Window w)
{

36
status
View file

@ -117,11 +117,6 @@ ITEM11_DISCHARGING_TEXT="Not charging" # Text when not charging (text)
ITEM11_CHARGING_TEXT="Charging" # Text when charging (text)
ITEM11_FULL_TEXT="Fully charged" # Text when fully charged (text)
# Systray options
HIDE_STATUS_SYSTRAY=true # Hide the status when a systray is running (true/false)
SYSTRAY="trayer" # Systray to use (<systray executable>).
STATUS_WHEN_HIDDEN="" # Status to print when status is hidden (text)
#########################################################################
PRINT() {
@ -233,9 +228,6 @@ else
printf "\n\n# Battery item options\nITEM11_SHOW_CHARGING_STATUS=$ITEM11_SHOW_CHARGING_STATUS # Show 'Charging', 'Not charging' or 'Fully charged' status after the percentage. (true/false)" >> $HOME/.config/speedwm-de/status/config
printf "\nITEM11_CHARGING_TEXT='$ITEM11_CHARGING_TEXT' # Text when charging (text)" >> $HOME/.config/speedwm-de/status/config
printf "\nITEM11_FULL_TEXT='$ITEM11_FULL_TEXT' # Text when fully charged (text)" >> $HOME/.config/speedwm-de/status/config
printf "\n\n# Systray options\n# Requires trayer or trayer-srg to work.\nHIDE_STATUS_SYSTRAY=$HIDE_STATUS_SYSTRAY # Hide the status when a systray is running (true/false)" >> $HOME/.config/speedwm-de/status/config
printf "\nSYSTRAY=$SYSTRAY # Systray to use (<systray executable>)" >> $HOME/.config/speedwm-de/status/config
printf "\nSTATUS_WHEN_HIDDEN=$STATUS_WHEN_HIDDEN # Status to print when status is hidden (text)" >> $HOME/.config/speedwm-de/status/config
printf "\n\n# Color options\nCOLORFG=$COLORFG # Color foreground (true/false)" >> $HOME/.config/speedwm-de/status/config
printf "\nCOLORBG=$COLORBG # Color background (true/false)" >> $HOME/.config/speedwm-de/status/config
printf "\n\n# End of configuration file." >> $HOME/.config/speedwm-de/status/config
@ -248,18 +240,7 @@ case "$BINDIR" in
esac
# Systray stuff
PRINT_SYSTRAY() {
if [ "$SYSTRAY" = "trayer" ]; then
grep -q "USE_SRG=true" $HOME/.config/speedwm-de/systray/config && SYSTRAY="trayer-srg"
fi
if [ "$HIDE_STATUS_SYSTRAY" = "true" ]; then
pgrep -x $SYSTRAY > /dev/null && SYSTRAYRUNNING=true
case "$SYSTRAYRUNNING" in
"true") $SETMETHOD "$STATUS_WHEN_HIDDEN" && exit 0 ;;
esac
fi
PRINT_TEXT() {
# Output of commands
# We're doing this so we can manipulate them easily for various reasons.
ITEMCMD1="$(echo "$(ITEM1)" | sed ':a;N;$!ba;s/\n//g')"
@ -366,15 +347,8 @@ PRINT_SYSTRAY() {
fi
fi
if [ "$HIDE_SYSTEM_SYSTRAY" = "true" ]; then
if [ "$SYSTRAYRUNNING" != "true" ]; then
PRINT
pgrep -x speedwm > /dev/null || exit 1
fi
else
PRINT
pgrep -x speedwm > /dev/null || exit 1
fi
PRINT
pgrep -x speedwm > /dev/null || exit 1
}
# RAM usage
@ -657,14 +631,14 @@ ITEM11() {
# base
BASE() {
PRINT_SYSTRAY
PRINT_TEXT
sleep $REFRESHDELAY
BASE
}
LOADCONFIG
SETCOLORS_CMD
PRINT_SYSTRAY
PRINT_TEXT
BASE
echo "status: Stopped printing."

View file

@ -19,6 +19,7 @@ Not compatible with BSDs so for those, set this to 0. */
/* Miscellanious
*/
#define USESYSTRAY 1 /* Whether or not to use the systray */
#define USEROUNDCORNERS 1 /* Whether or not to use rounded corners */
#define USEMEDIA 1 /* Whether or not to use media keys */
#define USEMOUSE 1 /* Whether or not to use mouse binds */

View file

@ -118,9 +118,9 @@ ResourcePref resources[] = {
{ "decorhints", INTEGER, &decorhints },
{ "swallowclients", INTEGER, &swallowclients },
{ "swallowfloating", INTEGER, &swallowfloating },
{ "barheight", INTEGER, &barheight },
{ "barpaddingv", INTEGER, &barpaddingv },
{ "barpaddingh", INTEGER, &barpaddingh },
{ "barheight", INTEGER, &barheight },
{ "centerfloating", INTEGER, &centerfloating },
{ "savefloat", INTEGER, &savefloat },
{ "warpcursor", INTEGER, &warpcursor },
@ -161,6 +161,12 @@ ResourcePref resources[] = {
{ "mfact", FLOAT, &mfact },
{ "lowestmfact", FLOAT, &lowestmfact },
#if USESYSTRAY
{ "systraypinning", INTEGER, &systraypinning },
{ "systrayonleft", INTEGER, &systrayonleft },
{ "systrayspacing", INTEGER, &systrayspacing },
{ "showsystray", INTEGER, &showsystray },
#endif
#if LAYOUT_MONOCLE
{ "monocleformat", STRING, &monocleformat },
{ "monocleclientcount", INTEGER, &monocleclientcount },