How can my shell script control the placement of a zenity window? - shell

I'm using zenity to post a simple notification when my spam-filter daemon filters a group of messages. Currently this message is posted to the middle of the screen, which is obtrusive. I want to post it to the upper left corner. However, zenity does not honor the -geometry option which is supposed to be standard for all X applications, and its documentation gives options for controlling window height and width, but not placement.
Is there a way to control the (x,y) coordinate at which a zenity window is posted?
If not, is there a way to solve this problem by tinkering with X resources or the window manager (I'm using the fvwm)?
EDIT: The following do not work in ~/.fvwm2rc (fvwm version 2.5.26):
Style "Information" PositionPlacement -0 -0
Style "Zenity" PositionPlacement -0 -0
They also don't work with the -0 -0 dropped, as suggested in the man page.
(The window title for zenity --info is "Information".)
Interestingly, zenity was ignoring my earlier window-manager directive that windows should be placed manually by default.
EDIT:
Among many other fascinating pieces of information, xprop(1) reports this about the zenity window:
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DIALOG
WM_NORMAL_HINTS(WM_SIZE_HINTS):
program specified location: 0, 0
program specified minimum size: 307 by 128
program specified maximum size: 307 by 128
window gravity: NorthWest
WM_CLASS(STRING) = "zenity", "Zenity"
WM_ICON_NAME(STRING) = "Information"
WM_NAME(STRING) = "Information"
Despite this apparently encouraging report, the window is not in fact posted at the location 0,0 :-(
I know the Style command is taking effect because I added the !Borders option, and sure enough the zenity window posts without borders... but still in the center of the damn screen!

I do it by using wmctrl in a subshell. Example:
((sleep .4;wmctrl -r TeaTimer -R TeaTimer -e 0,50,20,-1,-1)
for ((a=$LIMIT; a > 0; a--)); do
# for loop generates text, not shown
done
wmctrl -R TeaTimer
) | zenity --progress --title="TeaTimer" --percentage=0
First wmctrl moves zenity to upper left, second moves it to
current workspace. See a full example.

You could try using the "old" way of doing this, using FvwmEvent.
AddToFunc StartFunction I Module FvwmEvent FvwmEvent-MoveWindow
DestroyModuleConfig FvwmEvent-MoveWindow: *
*FvwmEvent-MoveWindow: Cmd Function
*FvwmEvent-MoveWindow: add_window MoveZenity
DestroyFunc MoveZenity
AddToFunc MoveZenity
+ I ThisWindow ("zenity") Move -0 -0
If this still doesn't work (or you are determined to get it working using PositionPlacement) you could try
BugOpts ExplainWindowPlacement
Fvwm will then write debugging output to it's logfile (or to the console, depending on your setup) explaining how it is placing windows (and why it is doing so).
Also just fyi, if you want to get information about a window you can use the FvwmIdent module to get this information (instead of xprop, though both work fine).

Yes, it is definitely possible with the proper help from window manager. For example, with xmonad it would be one line of code...
My fvwm is little rusty, but it seems like something along the lines of:
Style "zenity" PositionPlacement -0 -0
in your fvwm2rc should do the trick.
EDIT: Notice the lowercase "zenity" since, according to the docs, it should match not only window title, but window class as well (which you can find out using "xprop" utility: launch it and point to window in question).
According to xprop, zenity window has two interesting properties:
It has _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DIALOG, indicating that it is a dialog window
It has WM_TRANSIENT_FOR(WINDOW): window id # <some window id here>, indicating the main window for which it is a dialog (in my case - xterm window)
So, if my suggestion does not work, then it is almost certainly because fvwm handles dialogs in a special way - either due to configuration or due to hardcoded behavoir.
You can try adding "EWMHIgnoreWindowType" to the style of zenity windows, which should hopefuly made fvwm ignore those hints

Try devilspie: http://burtonini.com/blog/computers/devilspie/

You can use wmctrl to get the windowid, then xdotool to place it wherever you want. Simple and adaptable to many types of environments.
## Arg 1 - Pid of window to move.
## Arg 2 - X-Coord.
## Arg 3 - Y-Coord.
function move_win() {
xdotool windowmove $(wmctrl -lp | grep ${1} | cut -d' ' -f1) ${2} ${3}
}
E.g. $> move_win $(pidof zenity) 0 0

Related

GNU Screen tab titles all just 'zsh'

OK, so I want to start by first explaining my setup. I have a windows desktop at home, and I am SSH'ing into an Amazon EC2 instance (via PuTTY) running Amazon Linux. I have zsh as my default shell, and oh-my-zsh installed as well. This "cloud developer desktop" model works well for me, but I am having one problem that I have poured more time into than I care to admit: GNU screen only shows 'zsh' as the title of every tab. This is despite using oh-my-zsh's screen plugin (which I think isn't doing anything). Anyone able to help me out? I'd love to have something more descriptive in the tab, perhaps just the last x characters of the current directory (or an open file name if one is open in vim).
Like many screen users, I've had what I'm asking for before, but on a new rig now and don't fully understand everything in my .screenrc:
# Many settings from https://gist.github.com/azitabh/7427682 and
# https://gist.github.com/joaopizani/2718397 and
# https://gist.github.com/ChrisWills/1337178
# Allow bold colors - necessary for some reason
attrcolor b ".I"
# Tell screen how to set colors. AB = background, AF=foreground
termcapinfo xterm "Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm"
# Erase background with current bg color
defbce "on"
# Cache 30000 lines for scroll back
defscrollback 30000
# add tabs on bottom
caption always "%{= bb}%{+b w}%n %t %h %=%l %H %c"
# Very nice tabbed colored hardstatus line
#hardstatus string '%{= Kd} %{= Kd}%-w%{= Kr}[%{= KW}%n %t%{= Kr}]%{= Kd}%+w %-= %{KG} %H%{KW}|%{KY}%101`%{KW}|%D %M %d %Y%{= Kc} %C%A%{-}'
hardstatus alwayslastline "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%<"
#Remove vim buffer from scrollback history after quitting
altscreen on
# special xterm hardstatus: use the window title.
#termcapinfo xterm 'hs:ts=\E]2;:fs=\007:ds=\E]2;screen\007'
#termcapinfo xterm 'hs:ts=\E]2;:fs=\007:ds=\E]1;screen\007'
# Enable 256 color term
term xterm-256color
# Enables use of shift-PgUp and shift-PgDn
termcapinfo xterm|xterms|xs|rxvt ti#:te#
# tell screen that xterm can switch to dark background and has function keys.
termcapinfo xterm 'VR=\E[?5h:VN=\E[?5l'
termcapinfo xterm 'k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~'
termcapinfo xterm 'kh=\E[1~:kI=\E[2~:kD=\E[3~:kH=\E[4~:kP=\E[H:kN=\E[6~'
# window numbering starts at 1 not 0
bind c screen 1
bind 0 select 10
screen 1
#allow mouse scrolling in screen
termcapinfo xterm* ti#:te#
# Automatically detach on hangup.
autodetach on
I also tried adding this to my .zshrc, and it helps, but isn't quite what I want, as if you run ls, now your title is ls. Ie, not very informative. But maybe editing here is actually the right way to go:
# So screen tabs receive running process title
# preexec () {
# echo -ne "\ek${1%% *}\e\\"
# }
Thanks in advance for your help!
Answering my own question a bit here:
Replacing the line in the preexec () function above with this helps:
echo -ne "\ek$(pwd)\e\\"
Would still be best to only grab the characters from the x-to-last '/' to the end though, replacing the initial string with '...'

Possible to get bash input while user is at prompt? (Essentially an event listener)

Old stuff:
Background:
- Ultimate goal is to put a script in my .bash_profile that warns me by changing text color if I'm typing a commit message and it gets too
long (yes I'm aware vim has something like this).
Progress:
- I found the read -n option which led me to write this:
while true; do
# This hits at the 53rd character
read -rn53 input
# I have commit aliased to gc so the if is just checking if I'm writing a commit
if [ "${input:0:2}" = "gc" ]; then
printf "\nMessage getting long"
fi
done
Question:
- However, running this takes the user out of the bash prompt. I need a way to do something like this while at a normal prompt. I can't find
information on anything like this. Does that mean it's not possible?
Or am I just going about it the wrong way?
New progress:
I found the bind -x option which led me to write this:
check_commit() {
if [ "${READLINE_LINE:0:13}" == 'git commit -m' ] && [ ${#READLINE_LINE} -gt 87 ]; then
echo "Commit is $((${#READLINE_LINE} - 87)) characters too long!"
fi
READLINE_LINE="$READLINE_LINE$1"
READLINE_POINT=$(($READLINE_POINT+1))
}
bind -x '"\"": check_commit "\""'
It listens for a double quote and if I'm writing a long commit message tells me how many characters I am over the limit. Also puts the character I typed into the current line since it is eaten by the bind.
New question:
Now I just need a way to put in a regex, character list or at least a variable instead of \" so I can listen on more keys (Yes, I'm aware bind -x probably wasn't intended to be used this way. I can check performance/footprint/stability myself). I tried "$char", "${char}", "$(char)" and a few other things, but none seem to work. What is the correct approach here ?
AFAIK, not possible in a sane way if you want this to happen during your normal prompt (when PROMPT_COMMAND and PS1 are evaluated). That would involved binding a custom compiled readline function for every insert-self and alike.
If you want this to happen in a script using prompt builtin, this is crudely possible with a loop of
read -e -i $(munge_buf $buf) -n $(buf_warn_len $buf) -p $(buf_warning $buf) buf
like commands. This will allow you to create munge_buf() to alter the currently typed text if needed, buf_warn_len() to calculate a new len to warn at (which may be very large if warning was already displayed), and buf_warn_msg() to derive a warning message based upon the buffer.

Discovering remote Terminal for Terminal Escape Codes? (DECDHL in this case)

I am trying to determine WHAT console I am running in. (Exceptionally hard based on the research I have done so far.) The latest feature that I discovered that would be useful is Double High, Double Wide for a couple of scenarios.
The setup is a Kubuntu 15.04 machine with native (lower) and remote access via Terminal.app on OS X 10.10.4.
Based on vt100.net Apple is doing the right thing.
#!/bin/bash
# Cool effect with OS X Terminal.app
# Not as much on others (Like Konsole)
function embiggen()
{
# Yellow (Darker) foreground
# | Black backround
# | |
printf "\x1b[38;5;226m\x1b[48;5;0m"
# Double high 'top anchor'
# | line down
# | | Start of line
# | | |
printf "\x1b#3$1\x1b[B\x1b[G"
# Yellow (Bright) foreground
# | Red background
# | (Bright) |
printf "\x1b[38;5;229m\x1b[48;5;196m"
# Double high 'bottom anchor'
# | line down
# | | Start of line
# | | |
printf "\x1b#4$1\x1b[B\x1b[G\n\n"
}
clear
embiggen "Hello, World"
With Konsole
With Konsole the rendering seems to be controlled from bottom to top. i.e. each line is drawn bottom to top basically topmost line wins. However, repaints are less than predictable.
Is it remotely possible to use some of the extended features in a reasonably gracefully degraded way when the terminal doesn't support extended formating?
Best 'solution' I have thought of is using a custom entry point with
ssh -i ... usr#svr.dom bash --init-file osx_remote -i
The short answer, is "no" - this is not possible using just escape sequences.
You cannot tell whether the terminal actually displays double-sized characters. Using the cursor-position report, you can tell (except for buggy implementations) if the terminal used two cells on the screen to represent a double-width character. xterm did that long ago; other terminals do that.
Double-sized characters are a VT100 feature, so they are not listed in a device attributes response either. That would be of limited use, since some terminal emulator developers simply cut/paste responses to make them satisfy applications which check for specific features.
If you were running locally (rather than via ssh), conceivably you could write a program which did an X Window dump and analyzed that picture.

Bash, Always display colored bar at top of screen

Is there anyway to modify the bash profile scripts to always display a colored bar at top of screen. I have a requirement to show a colored hostname, username, and ipaddress on the screen at all times, but i don't want to overload PS1 as it would make the prompt take up over half of the default console width.
Not perfect, but this shows you how to fix part of your prompt on the first row of the screen:
PS1='\w \[\e[s\e[1;1H\e[42m\]\h \u ipaddress\[\e[0m\e[u\]\$ '
A breakdown:
\e[s - save the current cursor position
\e[1;1H - move the cursor to row 1, column 1 (numbered from the upper left-hand corner
\e[u - restore the cursor to the previously saved position
\e42m - make the background green
\e0m - restore the default foreground/background colors
\[...\] - enclose the various non-printing characters so that bash can correctly compute the length of the prompt.
Wikipedia lists other escape codes. The two things missing from this answer are how to extend the bar all the way across the string and how to set the correct IP address.
Update: I believe this covers the changes that ruckc made:
PS1='\[\e[s\e[1;1H\e[42m\e[K\h \u ipaddress\e[0m\e[u\]\w \$ '
How about add a \n inside your PS1, so that you always use a new line with full width?
if you are looking for something less hacky (but maybe overkill), consider byobu
https://en.wikipedia.org/wiki/Byobu_(software)
Alternatively, if you are using xterms, you could set the xterm title instead:
export PS1="\[\033]0;\u $(host $(hostname))\007\]\u#\h:\w\$ "
This sets your xterm title, and sets your prompt to contain username#host:pwd.
My .bashrc contains something like this so PS1 is set correctly depending on whether we're in an xterm or not:
if [[ -n "$TERM" ]] ; then
if ( echo $TERM | $GREP -q xterm ) ; then
export PS1="\[\033]0;\u#\h:\w\007\]\u#\h:\w\$ "
else
export PS1="\u#\h:\w\$ "
fi
fi

How do people make the fancy titles displayed when bash script its run

How can I make bash script have a cool title
Currently I am just using echo to give the name arg cliccker to my script
instead of having one boring line
how do i make fnacy bash sript logos
like this below:
Take a look at tput commands. tput is used to alter the terminal characteristics.
e.g
tput bold
tput setaf 3
tput setab 4
tput reset
There are some website that can do it.
Check out this website:
http://www.kammerl.de/ascii/AsciiSignature.php
Try installing 'boxes' - From the man page:
DESCRIPTION Boxes is a text filter which can draw any kind of box
around its input text. Box design choices range from simple boxes to
complex ASCII art. A box can also be removed and repaired, even if it
has been badly damaged by editing of the text inside. Since boxes may
be open on any side, boxes can also be used to create regional
comments in any programming language. New box designs of all sorts
can easily be added and shared by appending to a free format
configuration file. boxes was originally intended to be used with the
vim(1) text editor, but it can be tied to any text editor which
supports filters, as well as called from the command line as a
standalone tool.
$ boxes -h
boxes - draws any kind of box around your text (and removes it)
(c) Thomas Jensen <boxes#thomasjensen.com>
Web page: http://boxes.thomasjensen.com/
Usage: boxes [options] [infile [outfile]]
-a fmt alignment/positioning of text inside box [default: hlvt]
-c str use single shape box design where str is the W shape
-d name box design [default: first one in file]
-f file configuration file
-h print usage information
-i mode indentation mode [default: box]
-k bool leading/trailing blank line retention on removal
-l list available box designs w/ samples
-m mend box, i.e. remove it and redraw it afterwards
-p fmt padding [default: none]
-r remove box
-s wxh box size (width w and/or height h)
-t str tab stop distance and expansion [default: 8e]
-v print version information
:)
Dale

Resources