The beautiful desktop experience provided by compiz-fusion represents a significant aesthetic contribution to the pleasure of using Linux. Besides, it makes it really easy to impress even the most committed Apple disciple. The same is true for the cool gl screensavers written for xscreensavers. Unfortunately, these two don’t really work together (my computer freezes everytime xscreensaver comes up while running compiz-fusion) and although the screensaver plugin for compiz-fusion shows great potential, the gl collection for xscreensaver is still a bit ahead and has a lot more variety, so I really wanted to make them work together.
Here is what I did:
- You can use
xscreensaver-command -watchto monitor xscreensaver events, so you can actually run a program when xscreensaver is activated (for example, to disable compiz-fusion), and another one when it is deactivated (to bring compiz-fusion back). I modified the following script available from the xscreensaver man pages and saved it as~/bin/fixscreensaver:#!/usr/bin/perl # Fixes xscreensaver when compiz is running my $blanked = 0; open (IN, "xscreensaver-command -watch |"); while () { if (m/^(BLANK|LOCK)/) { if (!$blanked) { system "usemetacity"; $blanked = 1; } } elsif (m/^UNBLANK/) { system "usecompiz"; $blanked = 0; } } - As you can see, the script above calls
usemetacitywhen xscreensaver is activated andusecompizwhen it is deactivated. Save the following script as~/bin/usemetacity:#!/bin/bash #killall gkrellm metacity --replace & #sleep 1 #gkrellm &
- Now save this one as
~/bin/usecompiz:#!/bin/bash #killall gkrellm compiz --replace & #sleep 2 #gkrellm & #windowranger
- Add
~/bin/fixscreensaverto the list of startup applications (System > Preferences > Sessions > Startup programs) and also make sure that~/bin/is in your $PATH environment variable. - Optional: If you use gkrellm, you should uncomment the corresponding lines in the scripts above. Those lines will prevent metacity (the default gnome window manager) and compiz-fusion from changing the position of the gkrellm window, which happens everytime you switch between the two because these window managers use different ways to describe desktop geometry.
- Optional: You can also use the
usecompizandusemetacityscripts to manage any other application that misbehaves when metacity or compiz-fusion take over your desktop. In fact, I use thewindowrangerscript below to automatically put windows back into their corresponding viewports since everything gets shoved into the first viewport once you go back into compiz from metacity (thanks for pointing it out darken). You will needwmctrlfor this to work properly:#!/usr/bin/python import os, time, wnck, sys def dec2hex(n): #"""return the hexadecimal string representation of integer n"""# return "%X" % n def hex2dec(s): #"""return the integer value of a hexadecimal string s"""# return int(s, 16) def MoveWindow(wID, wtitle, xpos, ypos): time.sleep(0.2) os.system('wmctrl -i -r ' + wID + ' -e 0,'+str(xpos)+','+str(ypos)+',-1,-1') #time.sleep(0.4) #os.system('wmctrl -i -a ' + wID) if DEBUG: print "Moved to", xpos, ypos, 'n' def Place(x, y, wID, wclass, wtitle): fin,dout = os.popen4('wmctrl -d') # output desktop geometry for line in dout: line = line[line.find('VP: ') + 4:len(line)] # get current viewport offset line = line[0:line.find(' ')] offset = line.split(',') # split in x,y viewport offset coordinates vpxpos = int(offset[0]) # convert into integer vpypos = int(offset[1]) # convert into integer absxpos = vpxpos+x # absolute window position (x) absypos = vpypos+y # absolute window position (y) wxpos = absxpos wypos = absypos while wxpos >= width: wxpos = wxpos - width # relative window position (x) while wypos >= height: wypos = wypos - height # relative window position (y) if (wxpos >= 0)&(wxpos <= 2): wxpos = 0 if (wypos >= 0)&(wypos <= 2): wypos = 0 dout.close() # close command output if DEBUG: print 'Position:', absxpos, 'x', absypos #Send Firefox to viewport 1 if wclass.find('Firefox') != -1: # Flash fullscreen windows are titled 'Firefox' so we need to ignore them... if wtitle != 'Firefox': MoveWindow(wID, wtitle, wxpos - vpxpos + vpx1, wypos - vpypos + vpy1) #Send GYachI to viewport 2 elif wclass.find('GYachI') != -1: MoveWindow(wID, wtitle, wxpos - vpxpos + vpx2, wypos - vpypos + vpy2) #Send VirtualBox to viewport 5 elif wclass.find('VirtualBox') != -1: MoveWindow(wID, wtitle, wxpos - vpxpos + vpx5, wypos - vpypos + vpy5) #Send Amarok to viewport 6 elif wclass.find('Amarokapp') != -1: MoveWindow(wID, wtitle, wxpos - vpxpos + vpx6, wypos - vpypos + vpy6) #Send Azureus to viewport 6 elif wclass.find('SWT') != -1: MoveWindow(wID, wtitle, wxpos - vpxpos + vpx6, wypos - vpypos + vpy6) #Send Qbittorrent to viewport 6 elif wclass.find('Qbittorrent') != -1: MoveWindow(wID, wtitle, wxpos - vpxpos + vpx6, wypos - vpypos + vpy6) #Send Pidgin to viewport 7 elif wclass.find('Pidgin') != -1: MoveWindow(wID, wtitle, wxpos - vpxpos + vpx7, wypos - vpypos + vpy7) #Send Skype to viewport 7 elif wclass.find('Skype') != -1: MoveWindow(wID, wtitle, wxpos - vpxpos + vpx7, wypos - vpypos + vpy7) #Send Thunderbird to viewport 8 elif wclass.find('Thunderbird-bin') != -1: MoveWindow(wID, wtitle, wxpos - vpxpos + vpx8, wypos - vpypos + vpy8) #Send all other windows in viewport 1 to viewport 2 elif (wclass.find('Gnome-panel')==-1)&(wtitle != 'Desktop')&(wclass.find('Gkrellm')==-1)&(wclass.find('Launcher')==-1)&(absxpos < width)&(absypos <= height): MoveWindow(wID, wtitle, wxpos - vpxpos + vpx2, wypos - vpypos + vpy2) else: if DEBUG: print 'Ignoredn' #---------------------------- MAIN ------------------------------------- s = wnck.screen_get_default() width = s.get_width() height = s.get_height() vpx1 = (width * 0);vpy1 = (height * 0) vpx2 = (width * 1);vpy2 = (height * 0) vpx3 = (width * 2);vpy3 = (height * 0) vpx4 = (width * 3);vpy4 = (height * 0) vpx5 = (width * 0);vpy5 = (height * 1) vpx6 = (width * 1);vpy6 = (height * 1) vpx7 = (width * 2);vpy7 = (height * 1) vpx8 = (width * 3);vpy8 = (height * 1) DEBUG = False; for arg in sys.argv: if arg=='--debug': DEBUG=True; if DEBUG: print 'Viewport geometry:', width, 'x', height, 'n' fin,wout = os.popen4('wmctrl -lGx') for line in wout: wID = line[0:line.find(' ')] # get the window ID line = line[line.find(' '):len(line)] line = line.lstrip() wdesk = line[0:line.find(' ')] # get the window desktop line = line[line.find(' '):len(line)] line = line.lstrip() wxoffset = line[0:line.find(' ')] # get the window x offset wxoffset = (int(wxoffset) / 2) line = line[line.find(' '):len(line)] line = line.lstrip() wyoffset = line[0:line.find(' ')] # get the window y offset wyoffset = (int(wyoffset) / 2) - 24 line = line[line.find(' '):len(line)] line = line.lstrip() wwidth = line[0:line.find(' ')] # get the window width line = line[line.find(' '):len(line)] line = line.lstrip() wheight = line[0:line.find(' ')] # get the window height line = line[line.find(' '):len(line)] line = line.lstrip() wclass = line[0:line.find(' jsilva')] # get the window class line = line[line.find(' jsilva'):len(line)] line = line.lstrip() whost = line[0:line.find(' ')] # get the window host line = line[line.find(' '):len(line)] line = line.lstrip() wtitle = line[0:len(line) - 1] # get the window title if DEBUG: print 'Class:', wclass print 'Host:', whost print 'Title:', wtitle Place(wxoffset,wyoffset,wID,wclass,wtitle) # place window wout.close() - Enjoy!














5 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.
Hmm.. I don’t know if this is really a solution.. don’t all the windows you have open across all your desktops get put into 1 workspace when compiz is closed? I don’t want to drag windows out into different workspaces everytime I come back to the PC.
Good point darken! I modified step number 6 above to include a quick fix for this
I used a similary script as follows, I like it more since its just one bash script, just prepend with sh and add to your session
#!/bin/bash
if [ -f fixscreensaver.out ]; then rm fixscreensaver.out; fi
xscreensaver-command -watch >> fixscreensaver.out &
while true; do
if tail –lines=1 fixscreensaver.out | grep -w UNBLANK; then
echo ” >> fixscreensaver.out;
compiz –replace –sm-disable –ignore-desktop-hints ccp –loose-binding &
fi
if tail –lines=1 fixscreensaver.out | grep -w BLANK; then
echo ” >> fixscreensaver.out;
metacity –replace &
fi
sleep .1;
done;
this makes it easier to see
#!/bin/bash
if [ -f fixscreensaver.out ]; then rm fixscreensaver.out; fi
xscreensaver-command -watch >> fixscreensaver.out &
while true; do
if tail –lines=1 fixscreensaver.out | grep -w UNBLANK; then
echo ” >> fixscreensaver.out;
compiz –replace –sm-disable –ignore-desktop-hints ccp –loose-binding &
fi
if tail –lines=1 fixscreensaver.out | grep -w BLANK; then
echo ” >> fixscreensaver.out;
metacity –replace &
fi
sleep .1;
done;
maybe this will work, textarea isn’t supported
#!/bin/bash
if [ -f fixscreensaver.out ]; then rm fixscreensaver.out; fi
xscreensaver-command -watch >> fixscreensaver.out &
while true; do
if tail --lines=1 fixscreensaver.out | grep -w UNBLANK; then
echo '' >> fixscreensaver.out;
compiz --replace --sm-disable --ignore-desktop-hints ccp --loose-binding &
fi
if tail --lines=1 fixscreensaver.out | grep -w BLANK; then
echo '' >> fixscreensaver.out;
metacity --replace &
fi
sleep .1;
done;