There are several caveats in what you tried to do. I already mentioned the danger introduced by your approach:
Next time nautilus is going to be updated, your dolphin gets overwritten (as your link points there). Same goes for gnome-terminal.
So we figured, this was not a good idea :)
But there are some ways to try working around, so "x" gets run when "z" was requested -- but I'm not aware of any as soon not "z", but "/full/path/to/z" gets called. As long as it is just "z":
- creating an alias for z, like
alias z=x
(works on a per-user-level -- or globally, depending on where it was defined)
- creating a "replacement" for z in a location mentioned in the PATH before the location the real z resides in
A little more details on the second approach. Taking your original problem, you want to have dolphin executed whenever nautilus is called upon. You already found nautilus at /usr/bin/nautilus
. Now let's (probably correctly) assume your $PATH
contains (in this order) /usr/local/bin:/usr/bin
-- so you see /usr/local/bin
would be searched before /usr/bin
. So we simply create a shell script /usr/local/bin/nautilus
with the following content:
#!/bin/bash
/usr/bin/dolphin %$@
So what will happen? If you (or some script/program/daemon/...) invokes nautilus
, this will execute /usr/local/bin/nautilus
(as this is the first "nautilus" found in the PATH), which simply starts /usr/bin/dolphin
-- voila! But if the "whatever" uses the full path, this won't work.
So you say: Hey, why didn't Izzy say "just do a ln -s /usr/bin/dolphin /usr/local/bin/nautilus
?" Sure you can do that -- and it will work the same. But using a script as shown may come in handy if you need to introduce additional parameters which are not passed with the original call. With above script, dolphin simply gets passed the same parameters the original call used (%$@
). But you can play around with things in the script, replace parameters, etc. As for your current problem, the link would be enough (as long as nautilus doesn't get called with the full path).
What you will run into
If you want to first call an application and, subsequently, place its window on a specific position and size, the time between calling the application and the moment the window actually appears, is unpredictable. If your system is occupied, it can be significantly longer than if it is idle.
You need a "smart" way to make sure the positioning/resizing is done (immediately) after the window appears.
Script to call an application, wait for it to appear and position it on the screen
With the script below, you can call an application and set the position and size it should appear on with the command:
<script> <application> <x-position> <y-position> <h-size> <v-size>
An few examples:
To call gnome-terminal
and resize its window to 50% and place it on the right half:
<script> gnome-terminal 840 0 50 100
To call gedit
, place its window on the left and call gnome-terminal
, place it on the right (setting its v-size
46% to give it a little space between the windows):
<script> gedit 0 0 46 100&&<script> gnome-terminal 860 0 46 100
To call Inkscape, place its window in the left/upper quarter of the screen:
<script> inkscape 0 0 50 50
The script and how to use it
install both xdotool
and wmctrl
. I used both since resizing with wmctrl
can cause some peculiarities on (specifically) Unity
.
sudo apt-get install wmctrl
sudo apt-get install xdotool
- Copy the script below into an empty file, save it as
setwindow
(no extension) in ~/bin
; create the directory if necessary.
- Make the script executable (!)
- If you just created
~bin
, run: source ~/.profile
Test-run the script with the command (e.g.)
setwindow gnome-terminal 0 0 50 100
In other words:
setwindow <application> <horizontal-position> <vertical-position> <horizontal-size (%)> <vertical-size (%)>
If all works fine, use the command wherever you need it.
The script
#!/usr/bin/env python3
import subprocess
import time
import sys
app = sys.argv[1]
get = lambda x: subprocess.check_output(["/bin/bash", "-c", x]).decode("utf-8")
ws1 = get("wmctrl -lp"); t = 0
subprocess.Popen(["/bin/bash", "-c", app])
while t < 30:
ws2 = [w.split()[0:3] for w in get("wmctrl -lp").splitlines() if not w in ws1]
procs = [[(p, w[0]) for p in get("ps -e ww").splitlines() \
if app in p and w[2] in p] for w in ws2]
if len(procs) > 0:
w_id = procs[0][0][1]
cmd1 = "wmctrl -ir "+w_id+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w_id+" -b remove,maximized_vert"
cmd3 = "xdotool windowsize --sync "+procs[0][0][1]+" "+sys.argv[4]+"% "+sys.argv[5]+"%"
cmd4 = "xdotool windowmove "+procs[0][0][1]+" "+sys.argv[2]+" "+sys.argv[3]
for cmd in [cmd1, cmd2, cmd3, cmd4]:
subprocess.call(["/bin/bash", "-c", cmd])
break
time.sleep(0.5)
t = t+1
What it does
When the script is called, it:
- starts up the application
- keeps an eye on the window list (using
wmctrl -lp
)
- if a new window appears, it checks if the new window belongs to the called application (using
ps -ef ww
, comparing the pid of the window to the pid of the application)
- if so, it sets the size and position, according to your arguments.
In case an application does not "show up" within appr. 15 seconds, the script assumes the application will not run due to an error. The script then terminates to prevent waiting for the new window infinitely.
Minor issue
In Unity, when you (re-)position and (re-)size a window with either wmctrl
or xdotool
, the window will always keep a small marge to the borders of your screen, unless you set it to 100%. You can see that in the image (3) above; while the inkscape
window was placed on x
position 0, you can still see a minor marge between the Unity Launcher and the inkscape
window.
Best Answer
Keeping track of the
PID
and killing it from the shellscript works for me in a live system of Ubuntu 16.04.1 LTS with the Xenial kernel and also in an up to date installed system with Ubuntu 16.04 LTS (and the Xenial kernel).Edit:
It works, when killed like this, but when closed with the x control button, the process is still alive, which is a problem with Nautilus.
But if you use Thunar instead of Nautilus, the process will be killed, when the window is closed with the x button. So I suggest to switch file browser for this task,