X11: waiting until a window is visible? - x11

I'm running X across a slow network connection. How can I tell when a window has become visible? I need to wait so that I can perform another operation on the visible window.
xterm -T foo &
# how to flush the display, or wait until the window is visible?
# polling the visibility would be acceptable as well
xmovewindow foo 10 20
update: Thanks to Jim Lewis, here's a quick shell function that does the trick.
function xwait() {
while ! xwininfo -name $1|grep 'Map State: IsViewable';do sleep 1;done
}
xterm -T foo &
xwait foo
xmovewindow foo 10 20

You probably want to know when the remote X server has mapped your application's main window. The xwininfo command will let you query the X server by window name -- I think it's part of the standard X11 install. But you'd have to do the polling yourself, rerunning the command until the "Map State" property comes back "IsViewable"
Jonathan Leffler also mentioned Sun's toolwait utility (documentation here). toolwait launches a process (in this case, your xterm command), and returns when the application has mapped a top-level window...it does the polling for you. There's a package that purports to be a Linux clone of toolwait in the X11/xutils directory at www.ibiblio.org (here).
toolwait dates all the way back to OpenWindows -- now that's some old school X window programming, man! I have in front of me a Solaris man page dated 1994, which states "The OpenWindows environment may no longer be supported in a future release. You may want to migrate to CDE, the Common Desktop Environment..."

Related

Why does Fastscripts work with this but Platypus doesn't

Mac running Catalina. This code
#!/bin/bash
pbpaste|pbcopy
pbpaste>/tmp/tmp$$
open -W -a macvim /tmp/tmp$$
while [ `ps -A|grep MacVim|wc -l` -gt 1 ]
do sleep 1
done
cat /tmp/tmp$$|pbcopy
rm -f /tmp/tmp$$
is intended to plain-text the paste buffer then call up a terminal running macvim so I can use vi with less faff then put the result back in the clipboard. Its a way to speed-up editing when using various tools other tools and I just want to edit a section with vi.
I works well when called from Fastscripts or just plain execution but it won't work when I use Platypus to build a menubar app so its one fast click to use it - or rather, it works sometimes. Sometimes it hangs because it cannot connect input to the window in which macvim runs. I have to kill it from Activity Monitor to regain any control of input to other windows such as terminal. I've tried connecting stdin in the "open" command but still only works sometimes. And it shouldn't be standin anyway.
How is Fastscripts launching it and how can I do the same inside the script ?
I'd like very much to be able to launch it with a single click from the menubar but I don't know how to. I can build the platypus app if I know what to put in the shell script.
Thanks
andy

How can I tell my bash prompt to indicate whether there's a backgrounded emacsclient session exists

I'm using, OS X, and mainly terminal and emacsclient.
When I do shell stuff, I background my emacsclient with Control-Z
Someties I forget whether i've done that, and end up spawning additional emacsclient sessions, which I don;t want to do.
It would be cool if the bash prompt can tell me whether emacsclient jobs up in the jobs output
Minimal example for bash, using sleep instead of emacsclient.
PS1="\`if jobs | grep -q sleep; then echo 'sleep jobs' ; else echo 'no sleep jobs' ; fi\`\\\$ "
You might want to filter on stopped jobs (jobs -s).
You can get fancier by echoing escape sequences instead of just strings to colorize it.
While I think #jpkota provides a workable answer, I wonder if maybe your worrying too much. Provided emacsclient is working OK, there is no problem with having multiple emacsclient sessions running at once - in fact, it is sort of designed to do that. The emacsclient connections are light-weight and if there is a chance you might need to use the same file/buffer again, you may as well keep them around and just open new ones when needed and get rid of the ones you don't think you will need. The whole benefit of emacscleint is that opening new windows/buffers is really fast and if you use the GUI verison, they just pop up in their own window.
There is also a package in elpa which may be useful called osx-pseudo-daemon, which addresses a problem that can occur if you close all emacsclient windows which prevents the main emacs from responding (this is when yu run emacs from launchctl.
What I tend to do is run emacsclient in GUI mode rather than inside a terminal. When I run emacsclient I put it in the background so that it doesn't block my terminal and use the -c flag.(I actually have a shell script which makes this easy - see http://emacsformacosx.com/tips for some ideas. I leave the emacsclient window open and just switch to it if I need to do some emacs editing etc.

make a program reload an already opened file on file change

I need to play a .swf file then when the file is changed to reload the player with new content. Sadly, my program of choice does not do monitor files for changes. I came up with a bit convoluted solution:
sudo apt-get install incron gtk-gnash
echo "my_username" | sudo tee -a /etc/incron.allow # allow my_username to run incron
incrontab -e
add the following to incrontab:
/home/my_username/path/myfile.swf IN_MODIFY /home/my_username/path/run.sh
and the run.sh contains: ( also chmod 700 run.sh)
#!/bin/sh
killall gtk-gnash
gtk-gnash /home/my_username/path/myfile.swf
As you can see this is far from elegant. How else could I go about this?
This is on Ubuntu 12.04 if that matters for you. This is a duplicate of my own question on askubuntu
EDIT: clarification, I chose to use gtk-gnash, a standalone player, this is not required, a web browser would do too but seems not necessary
What you're describing is the job of a File Alteration Monitor.
First off, your existing "incrontab" solution is a good starting point, given that you're launching things from shell. The fact that incrontab is an inotify(7)-based solution is a huge plus. It means that you aren't polling, which saves CPU.
You're asking for shell and system-level solutions, and I'm not a Flash programmer, so I'll stick to your question, though I think a better solution would be to create a Flash "wrapper" that perhaps uses an AS3 Loader class to suck in your existing SWF and receive notifications from something launched by incrontab. Flash programming is way out of scope for this answer, though it might provide a more elegant solution.
So...
Your current method consists of a launch script that first kills any existing gtk-gnash process then runs a new one. It gets relaunched from scratch when incrontab sees a change to the file. That's a viable solution if you trust that your flash application will never crash and quit, and if you always have perfect timing. One problem with it is that you've got an unknown delay between the death of one process and the start of the next. Your killall sends a signal, which gtk-gnash may respond to immediately, or after a pause. With a short pause, you might find yourself launching the SWF before the old one is fully gone. With a longer pause, you may briefly show your desktop.
A better solution might be simply to launch the SWF within a loop:
#!/bin/sh
while true; do
date '+[%Y-%m-%d %T] myfile.swf relaunched' >> /var/log/swf.log
gtk-gnash /home/my_username/path/myfile.swf
done
Then have incrontab merely kill the existing process:
/home/my_username/path/myfile.swf IN_MODIFY killall gtk-gnash
By separating the killall from the launch, you make sure that the new instance of gtk-gnash does not start until the old one has actually quit and returned control to the shell script wrapping it.
Of course, instead of using incrontab, you could alternatively install the inotify-tools package and leave a loop running:
#!/bin/sh
while inotifywait -e modify /home/my_username/path/myfile.swf; do
killall gtk-gnash
done
Same syscalls, same effect, different front-end.
If you want to be über-careful about what process you're killing, you can also store the pid of gtk-gnash in a temporary file. Here's another take on the flash player wrapper:
#!/bin/sh
while true; do
date '+[%Y-%m-%d %T] myfile.swf relaunched' >> /var/log/swf.log
gtk-gnash /home/my_username/path/myfile.swf &
echo $! > /var/run/gtk-gnash.pid
wait
done
And the incrontab line:
/home/my_username/path/myfile.swf IN_MODIFY xargs kill < /var/run/gtk-gnash.pid
Another strategy you might employ to reduce the visible effect of the kill/restart, is to take a screenshot of myfile.swf while it is running with minimal or no content, then use that as the desktop wallpaper on the player. (Or equivalent. I don't know how you're set up.) I did something similar for a digital signage solution I set up a few years ago -- from time to time we needed to kill and restart a standalone player, so we made just the "frame" of the first page that shows up. When we killed the flashplayer process, the system "seemed" to reset with no content in its boxes ... and then, a second later, content would show up. (Yes, it's a hack.)
One other tip: I've always found Adobe's stand-alone Flash player ("Projector") to be more reliable and more compatible than gtk-gnash. You can find Adobe's stand-alone player at the Adobe Support Centre Download Page, which is different from their standard Flash Player download page.

Working on multiple terminals

I am using ubuntu terminal for my project and at times I need more than 5 terminals to be open at the same time and kind of juggle between them to see outputs of multiple programs running simultaneously. I am having hard time toggling between the terminals. Is there something that will hold all terminals together in one window and make my life simpler? I read somewhere that konsole does that for me, but I cannot bring up konsole for some reason and I am getting an error : bash: konsole: command not found.
Any kind of info/help is greatly appreciated.
Use tmux (and eventually, tmuxinator). It may have a slight learning curve but it'll be worth it, once you have it mastered!
Here's what an example session looks like.
If you want to try Konsole, try installing it first. It's part of KDE if that helps.
http://konsole.kde.org/
Ubuntu comes with gnome iirc. It has gnome-terminal as jasonspiro pointed out.
Have you tried using multiple workspaces? I'm using ubuntu 11 and if I find that I have a terminal layout I like to keep intact I simply place all of those terminals on a 2nd workspace. This can me done by right clicking on the terminal and clicking "Move to another workspace".
Use gnome-terminal instead. http://packages.ubuntu.com/ubuntu-desktop indicates to me that it comes with Ubuntu. It lets you open multiple tabs. Press Ctrl+Shift+T or click the appropriate menu command to open a new tab.
First, consider switching to ubuntu classic desktop. In clasic desktop you can move and resize windows like in um, windows, and then have multiple terminals visible at once.
Second, consider creating new terminals in the one terminal window. This can be done with CTRLSHIFTT
Third, alhough not much more useful for your purposes than the previous suggestion, have a look at screen(1), which is old, featureful, and no longer maintained, or tmux(1), which is still maintained. Either one can be run from a terminal. Both are installable from Software Center or synaptic.
You can use gnome-terminal. The script below will open 3 tabs running the respective commands..
tab="--tab"
cmd01="bash -c 'command in 1st terminal';bash"
cmd02="bash -c 'command in 2nd terminal';bash"
cmd03="bash -c 'command in 3rd terminal';bash"
foo=""
foo+=($tab -e "$cmd01")
foo+=($tab -e "$cmd02")
foo+=($tab -e "$cmd03")
gnome-terminal "${foo[#]}"
exit 0

Can I get terminal title? (or otherwise restore old one)

Setting terminal title is easy with echo -e "\e]0;some title\007". Works with pretty much every terminal program.
What I want is to set terminal title when some program starts - and restore old one when it finishes. Is this possible?
On xterm, the terminal control sequences 22 and 23 work fine, as in
#!/bin/sh
/bin/echo -ne '\033[22;0t' # Save title on stack
/bin/echo -ne "\033]0;$(date)\007"
sleep 1
/bin/echo -ne '\033[23;0t' # Restore title from stack
It looks like this isn't supported in the Mac OS X Terminal.App though.
There are some terminal programs that supporting it (xterm has compile time options for that, as mentioned by RWS), but most terminal programs simply lack such feature, including in particular Terminal.app.
Yes, that is possible indeed. See a xterm reference manual (like this for example) and wander your way through it. xterm even has a build in stack for this, so you don't have to store the title manually.
My solution was to set the window title during my script, then unset the window title when I completed. Unsetting the title reverted to the original value. Specifically, I did the following:
# Set the terminal title
printf "\e]2;%s\a" "running my script"
# Do whatever processing is required.
...
# Restore terminal title
printf "\e]2;\a"

Resources