Remove old systray, replace with much better version
This commit is contained in:
parent
32d3c25bd7
commit
20fcadd6e3
|
@ -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.
|
||||
|
|
|
@ -62,4 +62,5 @@
|
|||
- 62 | Remove the scratchpad
|
||||
- 63 | Reset layout/mfact
|
||||
- 64 | Reset nmaster
|
||||
- 65 | Show/Hide systray
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 } },
|
||||
|
|
17
options.h
17
options.h
|
@ -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 */
|
||||
|
|
|
@ -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")"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
560
speedwm.c
|
@ -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
36
status
|
@ -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."
|
||||
|
|
1
toggle.h
1
toggle.h
|
@ -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 */
|
||||
|
|
|
@ -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, ¢erfloating },
|
||||
{ "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 },
|
||||
|
|
Loading…
Reference in a new issue