Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

Using 11.04 with the Unity interface and Compiz 3D, via the CompizConfig Settings Manager (ccsm, not installed by default but very useful) I can use the "Place Windows" plug-in to set the default placement of a window, and the "Window Rules" plug-in to set the default size of a window, which is very handy. (Be nice if I didn't have to duplicate the rules, but hey, *nix is all about small pieces working together...)

Is there any way I can set up those rules so that they only apply if the window being opened is the only match for them? E.g., not to the second or third matching window that I open? (Example: The first time I open Chrome, I want it at X,Y with size W,H, but if I hit Ctrl+N, I want that second window placed according to the general rules, not my fixed rule.) Or would I have to fall back to wmctrl and/or Devil's Pie scripts for that sort of thing?

share|improve this question
add comment

1 Answer 1

up vote 1 down vote accepted

Okay, the answer would appear to be no, you can't do this with the "Place Windows" and "Window Rules" plug-ins. Instead, you have to use wmctrl and/or Devil's Pie.

In my case, just by way of example, I removed all of "Place Windows" / "Window Rules" stuff for Chrome and used wmctrl by creating a customized google-chrome.desktop file with some scripts:

  1. Copy the usual google-chrome.desktop file:

    cp /usr/share/applications/google-chrome.desktop ~/.local/share/applications
    
  2. Edit ~/.local/share/applications/google-chrome.desktop

  3. Find the Exec= line and change it to point to a script in a convenient location:

    Exec=/home/tjc/bin/runchrome %U
    

My runchrome script just calls my generalized runandmove script with the arguments I want to use for Chrome:

#!/bin/bash

# For 1440x900:
runandmove "Google Chrome" 0 246 0 1025 875 /opt/google/chrome/google-chrome $*

Those numbers are workspace x y width height.

My runandmove script — no thing of beauty — is:

#!/bin/bash
#
# runandmove looks to see if a program with a given title is already running. If so,
# it raises that program (brings it to the foreground). If not, it runs the program
# in the background (eating all output) and tries to move it to the given position.

# Check we have enough args
if [ $# -lt 7 ]; then
    echo "ERROR: Please supply at least seven arguments."
    echo
    echo "Usage:"
    echo
    echo "    runandmove \"program title\" workspace x y width height \"run command\" {args for command}"
    echo
    echo "Be sure to use quotes around the program title and the run command if they include"
    echo "any spaces (no need if they don't)."
    exit -1
fi

# Get the args
program_title=$1
program_ws=$2
program_x=$3
program_y=$4
program_width=$5
program_height=$6
program_cmd=$7
shift 7

# If the program is already running, bring it to the foreground. If it wasn't, wmctrl will
# return 1 and we'll use that as a flag telling us that we just started it.
wmctrl -a "$program_title"
just_started=$?

# If it isn't running, run it and put it in the right place
if [ $just_started -gt 0 ]; then
    "$program_cmd" $* &> /dev/null &
    wmctrlretry -r "$program_title" -e $program_ws,$program_x,$program_y,$program_width,$program_height
fi

Since there may be a delay after we issue the program command before it shows up in the window manager, note that the above uses wmctrlretry if it starts the program, which is just a simple retry wrapper around wmctrl:

#!/bin/bash

# wmctrl with up to 100 retries; we use this when we've just launched a program
# and it takes a moment to show up in the window manager's list.
counter=0
wmctrl $*
while [ $? -gt 0 ]; do
    counter=$[$counter+1]
    if [ $counter -gt 19 ]; then
        exit -1
    fi
    sleep 0.125
    wmctrl $*
done
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.