17

Which files are involved in generating the window title? For example, if you open Rhythmbox, you see the program name as the window title. But it’s not generated by the .desktop file. Which file(s) do I need to edit to add text to the title of an application? I want the changes to be permanent

I use Ubuntu GNOME 15.04 with GNOME 3.16.

  • Hi Maud. I loved your question, and it has lead to a very nice solution. I cannot resist however to mention one thing to keep in mind for future questions: please do not drastically change the question's meaning after answers have been posted. It makes answers, originally adequately posted on the first version of the question, seemingly misplaced on the edited version. I think that is what actually happened with my answer. I would suggest posting a new question instead, more specifically to your real question if re- think your question. – Jacob Vlijm May 21 '15 at 18:15
  • 1
    I understand your opinion and I certainly will do that with future questions as I can see how it may be quite confusing for people. I certainly do not underestimate your contribution to the thread, let that be clear. I wanted the title to be more specific as the original title didn't actually cover my real question and raised a bit uncertainty about what my goal was with this thread. Thanks for your help! :) – Maud Kon May 21 '15 at 18:33
21

The initial name is usually set by the (code within) the application itself. You can however change it, e.g. by using xdotool, which you would have to install first:

sudo apt-get install xdotool

Then, once it is installed, you can set another window name by (e.g.) the command:

xdotool search --name "Unity LauncherSwitcher" set_window --name "Monkey"

This will change:

enter image description here

into:

enter image description here

Note

As you can see, the command exists of:

xdotool search --name "<current_name>" set_window --name "<new_name>"

The <current_name> has to match exactly.


Edit alternatively

From your comment, I understand the command above did not work. I tested it with different applications, and it worked...

But for a reason I do not understand, NOT with Rhytmbox(!! might be a bug)

An alternative is to use wmctrl, which you also would have to install:

sudo apt-get install wmctrl

Then use the command:

xprop -id "$(wmctrl -l | grep 'Rhythmbox' | awk '{ print $1 }')" -set WM_NAME "Music"

I succesfully tested it on Rhythmbox:

enter image description here

enter image description here

Make the changes permanent?

As mentioned, the default window name is defined in the code of the application.

Changing the default window title would need to change the code. That can be done if the code is available, would need recompiling in many cases and depends on the used language, among other things. A general instruction would be quite impossible and beyond (outside) the scope of AU in my opinion.


EDIT 2

Flexibly manage/set custom window names per application from a single file

In your original question, you were wondering if there was some kind of a file to set the title of new windows of a specific application. As explained, that is not the case, however, it can be created.

In the setup below, you can very easily define on a per application base how new windows are named. Simply create a file in ~ (your home directory), named window_names.txt. For each of the applications you want to set a specific windowname for, add a line of, subsequenty, the application and the desired window name:

A textfile, defining window names per application

gnome-terminal Monkey eats
gedit Banana
rhythmbox if he runs out of peanuts

enter image description here

Explanation

The setup exists of a simple background script. The script is very light, so it won't have any noticable effect on the performance whatsoever.

Once the script starts, it reads the file ~/window_names.txt and loads the settings per application. Then it keeps an eye on newly created windows. If a window appears that belongs to one of the applications, definied in the file, it sets the window name accordingly.

How to set up

  1. The script uses both wmctrl and xdotool:

    sudo apt-get install wmctrl
    sudo apt-get install xdotool
    
  2. Copy the script into an empty file save it as setwindowname.py

  3. Create the file ~/window_names.txt (exactly named window_names.txt), add your applications in the format:

    <application> <window_name>
    

    e.g.

    gedit Text editor
    

    The window name may include spaces.

  4. Test-run the script from the terminal by the command:

    python3 /path/to/setwindowname.py
    
  5. If all works as expected, add it to startup applications: Dash > Startup Applications > Add

    Note that in some cases, a script might break if it starts when the desktop is not fully loaded yet. If that migh be the case, the command to add to startup applications would be:

    /bin/bash -c "sleep 15&&python3 /path/to/setwindowname.py"
    

The script

#!/usr/bin/env python3
import subprocess
import time
import os

f = os.environ["HOME"]+"/"+"window_names.txt"

change = []
lines = open(f).read().splitlines()
for l in lines:
    try:
        change.append([l.split()[0], (" ").join(l.split()[1:])])
    except IndexError:
        pass

get = lambda cmd: subprocess.check_output(cmd).decode("utf-8").strip()
curr_1 = []

while True:
    try:
        curr_2 = get(["wmctrl", "-lp"]).splitlines()
        new = [w for w in curr_2 if not w in curr_1]
        for item in new:
            line = item.split(); pid = line[2]
            procs = get(["ps", "-e"]).splitlines()
            match = [l for l in procs if pid in l][0]
            for app in [app for app in change if app[0] in match]:
                subprocess.Popen(["xdotool", "set_window", "--name", app[1], line[0]])
        curr_1 = curr_2
        time.sleep(0.3)
    except:
        pass

Notes

  • If the file ~/window_names.txt is edited, the script needs to be restarted.
  • It works no matter how an application is started; it also works when applications are run from the terminal / and or with sudo.
  • It does not interefere with the the right-click option of any application.
  • The script also "maintains" the window name; if another process changes the window name afterwards (opening tabs, change directories e.g.) the script sees the window as a "new window" and maintains the window name of your choice.
  • I'm sorry, this didn't work for me. – Maud Kon May 21 '15 at 13:06
  • xdotool search --name "Rhythmbox" set_window --name "Music" I did the command with the application open, closed and did a restart (alt+f2+r) to check if it worked, but it still shows the same window title. – Maud Kon May 21 '15 at 13:41
  • Wow! This time I'm really impressed! I'll give it a try first thing in the morning. I must say, this looks very promosing :) thanks for your hard work and posting this, Jacob! – Maud Kon May 23 '15 at 0:27
  • 1
    YOU ARE A FREAKIN' HERO!!! This works perfectly! Thank you so, so, so much! Now I can finally sleep at night ;) – Maud Kon May 23 '15 at 12:38
  • 1
    @MaudKon You must have edited the settings file, and unintenionally added one or more whitelines, probably at the end. I "immunized" the script for that. You can use as many whitelines as you like now :) – Jacob Vlijm May 25 '15 at 19:41
9

The title is generated by the application executable and there isn't a easy way to edit it.


Changing the title of a application once it's open:

  • Install xdotool with sudo apt-get install xdotool
  • Get the pid of the application with pgrep myapp (i.e. pgrep rythmbox)
  • Change the window title (replacing HERE_THE_PID with the process id of the application):

    xdotool search --onlyvisible --pid HERE_THE_PID --name "\a\b\c" set_window --name "$new_name"
    

Making a script to launch any application with a custom title:

  • Create a bash script called change-title with these contents:

    #!/bin/bash
    
    ## The new name of the window is the first argument passed to the script:
    new_name="${1}"
    
    ## application is all arguments but the first (the title)
    application=${@:2}
    
    ## Run the app in background and in quiet mode:
    $application &> /dev/null &
    
    ## Get the pid of the app:
    app_pid=$!
    
    ## Wait until the window appears:
    until xdotool search --onlyvisible --pid $app_pid &> /dev/null; do sleep 0.01; done
    
    ## Change the window name:
    xdotool \
             search \
                    --onlyvisible \
                    --pid $app_pid \
                    --name "\a\b\c" \
             set_window \
                    --name "$new_name"
    
    ## Comment this line to run the app in background:
    wait $app_pid
    
  • Make it executable with chmod a+x change-title

  • Run it with ./change-title "NewTitle" theapp --its-arguments

To make the change permanent:

  • Run gksudo gedit /usr/local/bin/custom-title (fx. user/local/bin/music)
  • On the text editor paste the above script and save it.
  • Run sudo chmod a+x /usr/local/bin/custom-title
  • Run gksudo gedit /usr/share/applications/rhythmbox.desktop
  • On this file, there is a line (the line number is 35 on mine) that says:

    Exec=rhythmbox %U
    
  • Replace it with this with the name of the created file:

    Exec=custom title (fx. Exec=music)
    
  • Save the file as a new custom-name.desktop fx. music.desktop. Be careful that you do not overwrite the original file!

To make the change effective for the "open with" function

  • Run gksudo gedit /usr/share/applications/rhythmbox-device.desktop
  • Change rhythmbox to the name used in the previous .desktop file.
  • Save the file.
  • Kill active processes of rhythmbox with system monitor or with sudo kill rhythmbox
  • Plugin your phone/music player and press "Open with (Music application)" to see if it worked.

(Summary) Overview of the files you should have

To make the application fully functional, you should have 3 .desktop files in /usr/share/applications when finished:

  1. music.desktop or the name you gave the application

    with Exec=music and Hidden=true (add the last one if not present)

  2. rhythmbox.desktop

    with Exec=rhythmbox %U and Hidden=true

  3. rhythmbox-device.desktop

    with Exec=music --select-source %U and WITHOUT the Hidden entry

This means that you always open the last file and the title is always as it should. The only way is resets itself is when you refresh your session with ALT+F2+R.

  1. And you should have the bash script in /usr/local/bin ofcourse.

Final notes:

  • When I'm using --name "\a\b\c" is to fix a bug, don't replace with the application name!
  • If do you uncomment the last line of the script, the script will not end until the app is closed.
  • Explaination of ${@:2} in the code requested by @Maud Kon:

    1. $@ is an array that stores all the positional parameters.
    2. ${@:2} means: All the positional parameters but the first
    3. Let's say that I call a program this way:

      awesome-program foo bar baz fooz
      
      • ${@:1} would be foo bar baz fooz
      • ${@:2} would be bar baz fooz
      • ${@:3} would be baz fooz
      • ${@:4} would be fooz
      • ${@:5} is empty because there aren't more positional parameters.
    4. $@, ${@} and ${@:1} are the same thing: All the positional parameters.

    5. Learn more about this topic here: http://wiki.bash-hackers.org/scripting/posparams
  • I've tried both manners (also the one down here) and your bash script works partially. It launches a new window with the new name, but if I launch it again from overview, it still has the old entry... am I doing something wrong? – Maud Kon May 21 '15 at 12:52
  • @MaudKon: What's the overview? Try the script now. If do you call "Overview" to the dash (big panel with many apps), I'll say you that my script doesn't makes a permanent change. – Helio May 21 '15 at 12:53
  • I mean the applications overview, i've already hidden dash itself, haha. Hmm, yeah, than your script works. Is there anyway to make the change permanent? Like editing an executable file with fx. GHex? Or changing the executable in the .desktop file? – Maud Kon May 21 '15 at 13:02
  • Try now. Use the new script and follow the method under the section To make the change permanent. Now I understood that you're making a camouflage of your Ubuntu ;-) – Helio May 21 '15 at 14:27
  • 1
    @Helio I updated your post with the steps that worked for me. I also added the process to make the "open with" function work. – Maud Kon May 21 '15 at 15:29
2

Just use the translation file!

I ran into this very problem challenge with Thunar: It became annoying when Compiz Scale displayed the Thunar window title as "AnyFolder - File Manager" and comsumed space with unnecessary information.

I tried the above mentioned ways with xdotool and wmctrl but they were not permanent since Thunar changes its window title every time I go to another folder. And it felt exaggerated to have a script sitting around in the background to change the title back every time Thunar alters it.

An easier solution was to use the translation file which comes with every application. You simply need to re-compile the translation source file with a tool called msgfmt included in the gettext package. I just did this for gThumb -just for fun- and there it works, too.

1. Get source code for the concerned application.
Type $ sudo apt-get source APPLICATION or head over to http://packages.ubuntu.com, get the source and look for for a folder called po: it contains plain-text language files. Look for your language. Let's say you're from Brazil, that file would be pt_BR.po

2. Alter the file to your needs
Look for the exact! window title that you want to get rid off or change. In Thunar's case it was "File Manager" and in pt_BR.po I found

:. set window title
: ../thunar/thunar-window.c:3154 ../Thunar.desktop.in.in.h:3
: ../thunar/thunar-settings.desktop.in.h:1
msgid "File Manager"
msgstr "Gerenciador de arquivos"

where msgid is the signal the application sends and msgstr what the langpack translates it to.
Change msgstr to whatever you like, i.e. msgstr "o_-".
I learned that if you leave the translation empty like this msgstr "" the application will fall back to msgid. If you want it to be "empty" use whitespace. Or a dot. Or any funky ASCII symbol.

3. Get the compiler
As mentioned you need msgfmt from gettext package, so you need to type
$ sudo apt-get install gettext

4. Compile
Open a terminal, go to the folder with your altered pt_BR.po and let msgfmt check the file for errors:
$ msgfmt --check --check-accelerators=_ -o /dev/null pt_BR.po
If it's fine, go ahead and compile it:
$ msgfmt -c -o pt_BR.mo pt_BR.po

5. Place file
Have a look how the original translation in /usr/share/locale/YOUR_LANGUAGE/LC_MESSAGES/ or /usr/share/locale-langpack/YOUR_LANGUAGE/LC_MESSAGES/ is named and place your file there. If it doesn't exist in both places, put it in one of them and experiment a little with the file name: lowercase, Camelcase or something like , i.e. gthumb.mo or YOUR-APP.mo.
Make a backup of the original first:
$ sudo cp /usr/share/locale/YOUR_LANGUAGE/LC_MESSAGES/YOUR-APP.mo /usr/share/locale/YOUR_LANGUAGE/LC_MESSAGES/YOUR-APP.mo.BAK
then copy your new translation there
$ sudo cp pt_BR.mo /usr/share/locale/YOUR_LANGUAGE/LC_MESSAGES/YOUR-APP.mo

If YOUR_APP is running, close all instances of it.
Test It!

Hint If you're running Ubuntu with EN localisation like I am, just use any *.po, delete or comment all unchanged msgid/msgstr couples from it and put it in /usr/share/locale/en/LC_MESSAGES/.

Sources:
http://wiki.xfce.org/translations/translation_guidance_in_xfce

  • Just for the record; I doubt you actually tried the script, since it maintains the name, as mentioned in the answer. – Jacob Vlijm Dec 19 '15 at 4:58
  • You're right, I didn't try this script but a similiar (simpler) one from somewhere else, and the tricks with xdotool and wmctrl. As mentioned, for me it feels like shooting sparrows with a cannon, compared to changing one line in a source file. Nevertheless, one can learn a lot from the scripts. – ronso0 Dec 19 '15 at 5:13
  • I'm curious what happens if the application is upgraded. Are *.desktop files and localisation files overwritten? – ronso0 Dec 19 '15 at 5:21
  • As explained here askubuntu.com/a/703942/72216, I don't share the fobia for a background script, if it is well written and does add important functionality. About .desktop files: again, you must confuse my answer with another one you might have read. The answer does not edit .desktop files and no action is needed when an application is reinstalled. – Jacob Vlijm Dec 19 '15 at 5:25
  • This was a general question as answer #2 modifies .desktop files and I do so wih translation files. Do you know it? And I may give ANY script solution a second chance since I now read i.e. "mu__Incoming - " where I had "mu__Incoming - File Manager". For applications which have a static window title without any "path/to/folder" my solutions works fine. – ronso0 Dec 20 '15 at 18:43
1

Replace (parts of) window titles with wmctrl

Since my own answer using the application's translation file wasn't sufficient for several cases for me, I built upon Jacob Vlijm's solution and modified his script to replace certain strings in window titles. I hope it's okay to post this a separate answer. Credits go to Jacob Vlijm for the idea and setting up the script!

For example, I like to read Some fancy website instead of Some fancy website - Mozilla Firefox. Compiz scale plugin is much clearer now as I also removed - File manager and other strings.

Changes I made:

  1. use // as separator in window_names.txt to allow white-spaces
  2. use wmctrl instead of xdotool to modify the window title (since xdotool doesn't handle non-ASCII characters very well): wmctrl -i -r [WindowIdentifier] -N 'new Title'
  3. some extra lines in the script to do the string replacement etc.

The modified window_names.txt is structured like this:
[process name]//[exact text to replace]//[replacement text]

firefox// - Mozilla Firefox// (whitespace!)
thunar// - File Manager// ° xyz
gedit// - gedit// - 123

The pimped script:

#!/usr/bin/env python3
import subprocess
import time
import os

f = os.environ["HOME"]+"window_names.txt"

change = []
lines = open(f).read().splitlines()
for l in lines:
    try:
        change.append(l.split("//"))
    except IndexError:
        pass

get = lambda cmd: subprocess.check_output(cmd).decode("utf-8").strip()
curr_1 = []

while True:
    try:
        curr_2 = get(["wmctrl", "-lp"]).splitlines()
        new = [w for w in curr_2 if not w in curr_1]

        for item in new:
            line = item.split(None, 4)
            winID = line[0] ; pid = line[2] ; currentTitle = line[4]
            procs = get(["ps", "-e"]).splitlines()
            match = [l for l in procs if pid in l][0]
            for app in [app for app in change if app[0] in match]:
                newTitle = str.replace(currentTitle, app[1], app[2])
                subprocess.Popen(["wmctrl", "-i", "-r", winID, "-N", newTitle])
        curr_1 = curr_2
        time.sleep(0.3)
    except:
        pass

Again: Credits go to Jacob Vlijm for the idea and setting up the script!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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