New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: a bit of interop with trayer [filling xmobar with empty space] #239

Open
Fuco1 opened this Issue Aug 2, 2015 · 8 comments

Comments

Projects
None yet
5 participants
@Fuco1

Fuco1 commented Aug 2, 2015

So, I suppose many people would like to use xmobar and trayer (or other system dock) together. You sort of can now, but the problem is that xmobar can't shrink/expand when the system tray expands, so you either have to allocate fixed space, which looks really awkward (plus it can overflow if tray grows too much) or possibly use the tray on different display (not everyone has 2+ monitors).

I have "developed" a hack to make the shrinking part as good as it gets, here is the basic idea:

  1. Have a (shell) program which can detect and print number of spaces (as in the ascii-code 32 characters) the trayer takes (approximatelly). The script I use is in footnote.
  2. Add xmobar monitor to the very right (or left, wherever you position your trayer) which runs this code every second and prints that many spaces. You need to adjust the number of spaces based on your font (for me, 1 icon is roughly 3 spaces).

What I would like to have is simply a way to make an "n pixels wide padding" monitor, so I could fit the trayer precisely and not rely on whitespace calculations (as this is not portable and just a bit wacky in general). Ideally, the monitor could take stdout of some program or some other way to calculate the width dynamically.

I don't know how difficult this might be, but if you give me some hints on how to do this "pixel filling" output I could try to work it together. I already wrote one experimental plugin myself (for pulse audio) but that only output text, so I roughly understands the architecture.


I run trayer like so:

trayer --edge top --align right --SetDockType true --SetPartialStrut false --expand true --height 17 --transparent true --alpha 0 --tint 0x000000 --widthtype request --monitor 1 &

The space-printing code

#!/bin/bash

width=$(xprop -name panel | grep 'program specified minimum size' | cut -d ' ' -f 5)
spaces=$(((width / 5) - 2))
echo -n ''
for i in $(seq 1 $spaces)
do
    echo -n ' '
done

My xmobarrc is here: https://github.com/Fuco1/dotfiles/blob/master/xmonad/.xmonad/xmobarrc

@Fuco1

This comment has been minimized.

Fuco1 commented Aug 2, 2015

Here's how it looks:

xmobar and trayer

You can see the extra black space, that's the error which accumulated when the 5th icon was added. I could of course correct for that but it would get quite messy, and you are always only down to the resolution of one space (which is some 8 pixels or so)

@jaor

This comment has been minimized.

Owner

jaor commented Aug 5, 2015

hmmm. perhaps the simplest way of accomplishing what you want would be
to generate an xmp file externally (a line of the desired length), and
just use an <icon> tag, extending its implementation if needed to
accept dynamic images (IIRC, it's not needed).

it's still a hack. if trayer supported X11's XEmbed protocols, we
could try to implement an xmobar plugin that simply embeds an external
X11 app (that would moreover be generally useful)... a very raw
alternative is to implement a plugin that uses XReparentWindow() to
swallow an external window, but that can well be too rough and conflict
with some window managers.

of course the best way would be to implement a system dock plugin
natively in haskell :)

@Fuco1

This comment has been minimized.

Fuco1 commented Aug 6, 2015

Thanks for the pointers. I'll first try the icon thing as it seems the simplest. I'm not very versed in the whole "X thing" :D so that's probably way over my head.

By system dock in haskell you mean to make it part of xmobar, or a different program? (or as a library)? Xmobar is pretty lightweight and I guess people like that, adding docks into it, dunno how much dependencies would that pull in.

@jaor

This comment has been minimized.

Owner

jaor commented Aug 7, 2015

yes, i meant implementing a dock using X APIs directly within xmobar.
probably can be done without lots of deps, and anyway it can be an
optional feature, so that people can still compile a lean and mean
xmobar (we already do that with lots of other capabilities). but well,
it's not a trivial undertaking!

@mkoskar

This comment has been minimized.

mkoskar commented Mar 7, 2016

What about integrating with https://hackage.haskell.org/package/gtk-traymanager-0.1.6? From what I read it is based on trayer and is used by taffybar (https://github.com/travitch/taffybar/tree/master/src/System/Taffybar/Systray.hs) from the same author.

@jaor jaor added the feature request label May 4, 2016

@jonascj

This comment has been minimized.

jonascj commented Jul 17, 2016

I implemented joar's idea of an dynamically generated, transparent XPM icon for padding. If someone find this feature request when searching for dynamic xmobar width, like I did, they might find it useful.

trayer-padding-icon.sh
#!/bin/sh
# Detects the width of running trayer-srg window (xprop name 'panel')
# and creates an XPM icon of that width, 1px height, and transparent.
# Outputs an <icon>-tag for use in xmobar to display the generated
# XPM icon. 
#
# Run script from xmobar:
# `Run Com "/where/ever/trayer-padding-icon.sh" [] "trayerpad" 10`
# and use `%trayerpad%` in your template.


# Function to create a transparent Wx1 px XPM icon
create_xpm_icon () {
timestamp=$(date)
pixels=$(for i in `seq $1`; do echo -n "."; done)

cat << EOF > "$2"
/* XPM *
static char * trayer_pad_xpm[] = {
/* This XPM icon is used for padding in xmobar to */
/* leave room for trayer-srg. It is dynamically   */
/* updated by by trayer-pad-icon.sh which is run  */
/* by xmobar.                                     */
/* Created: ${timestamp} */
/* <w/cols>  <h/rows>  <colors>  <chars per pixel> */
"$1 1 1 1",
/* Colors (none: transparent) */
". c none",
/* Pixels */
"$pixels"
};
EOF
}

# Width of the trayer window
width=$(xprop -name panel | grep 'program specified minimum size' | cut -d ' ' -f 5)

# Icon file name
iconfile="/tmp/trayer-padding-${width}px.xpm"

# If the desired icon does not exist create it
if [ ! -f $iconfile ]
then
    create_xpm_icon $width $iconfile
fi

# Output the icon tag for xmobar
echo "<icon=${iconfile}/>"
@Fuco1

This comment has been minimized.

Fuco1 commented Jul 17, 2016

@jonascj rad! love it.

@crocket

This comment has been minimized.

crocket commented Apr 16, 2017

According to https://wiki.archlinux.org/index.php/stalonetray,
stalonetray supports XEMBED protocol.

If you didn't want to deal with manual adjustment of system tray size, you could use taffybar.
I think xmobar should support XEMBED protocol.

jfly added a commit to jfly/dotfiles that referenced this issue Mar 19, 2018

jfly added a commit to jfly/dotfiles that referenced this issue Mar 19, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment