Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've got an alias set up to launch my text editor in a way that keeps it local to the specific desktop I'm working on in Gnome Shell:

alias geany="geany --socket-file=/tmp/geany-sock-$(xprop -root _NET_CURRENT_DESKTOP | awk '{print $3}') ${1+"$@"}"

I'd like to emulate this with the actual Gnome Shell launcher. As it stands, I have the launcher command set to:

geany --socket-file=/tmp/geany-sock-$(xprop -root _NET_CURRENT_DESKTOP | awk '{print $3}') %F

Which will point to the open Geany session in the current window if one is already open, but it won't launch a new session. I'll get a spinner, and then it just quits rather than launching the app. Is there any way to do this?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

Shell parameter and variable expansion in .desktop files is neither supported nor documented. The usual workaround is (like Avlmd said) to create a shell script and point the .desktop file to that executable.

When it comes to launching applications from dash, gnome-shell defaults to activating the application instead of launching it if another instance is already running (as long as you don't use Ctrl + click to actually launch a new instance).
gnome-shell behavior can be altered via shell extensions, so in your particular case an extension overriding onActivate from /usr/share/gnome-shell/js/ui/appDisplay.js should do what you want:

  • Create extension folder:

mkdir -p ~/.local/share/gnome-shell/extensions/geany-launcher@blahblah.blah

  • Add these two files inside:

metadata.json:

{
    "shell-version": ["3.6.3.1"], 
    "uuid": "geany-launcher@blahblah.blah", 
    "name": "Geany Launcher", 
    "description": "Fire up new window if no instance on current workspace"
}

extension.js:

const Clutter = imports.gi.Clutter;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const AppDisplay = imports.ui.appDisplay;

var _onActivateOriginal = null;

function  _onActivate(event) {
        this.emit('launching');
        let modifiers = event.get_state();
        let cTRL = Clutter.ModifierType.CONTROL_MASK;
        let rUN = Shell.AppState.RUNNING;
        let crtW = global.screen.get_active_workspace();
        if (this._onActivateOverride) {
            this._onActivateOverride(event);
        } else {
            if (this.app.get_id() == "geany.desktop") {
                if (this.app.state == rUN && ((modifiers & cTRL) || !this.app.is_on_workspace(crtW))) {
                    this.app.open_new_window(-1);
                } else {
                    this.app.activate();
                    } 
            } else {
                if (modifiers & cTRL && this.app.state == rUN) {
                    this.app.open_new_window(-1);
                } else {
                    this.app.activate();
                    }
                }
            }
        Main.overview.hide();
}

function init() {
  _onActivateOriginal = AppDisplay.AppWellIcon.prototype._onActivate;
}

function enable() {
  AppDisplay.AppWellIcon.prototype._onActivate = _onActivate;
}

function disable() {
  AppDisplay.AppWellIcon.prototype._onActivate = _onActivateOriginal;
}
  • Restart shell with Alt + F2, r, Enter. Then enable the extension with gnome-tweak-tool (you might need to restart the shell one more time to enable the extension).

This works with gnome-shell-3.6.3.1, if you have another version edit metadata.json and change this line to reflect your shell version (no guarantee it would work with older shell versions like 3.4.x or future versions like 3.8.x):

"shell-version": ["3.6.3.1"],

Note that the extension only overrides shell behavior, if you (double) click files in Nautilusto open them with Geany it would still activate the primary window on another desktop so you will also have to resort to the shell script trick to get a consistent behavior: open a new window only if no instance is on current desktop otherwise activate the existing one. I don't have xprop installed but this works on my system:

  • Create a new executable somewhere in my $PATH (like /usr/local/bin/djinni):
#!/bin/sh

geany --socket-file /tmp/geany-sock-$(xdotool get_desktop) ${1+"$@"}
  • Point the launcher (/usr/share/applications/geany.desktop) to the newly created script:

    Exec=djinni %F

share|improve this answer
    
Thank you! This is apparently what I've been looking for. The piece I added is in my .bashrc I've aliased geany to point to my new executable (alias geany=/usr/local/bin/geany2), which appears to be more reliable for some reason than aliasing to the original ---socket-file command. –  ND Geek Apr 4 '13 at 14:45

One possible workaround is to save your command to ~/bin/geany:

mkdir -p ~/bin
cat > ~/bin/geany
/usr/bin/geany --socket-file=/tmp/geany-sock-$(xprop -root _NET_CURRENT_DESKTOP | awk '{print $3}') $1
^d
chmod 755 ~/bin/geany

executable and make .desktop launcher like this: /home/$USER/bin/geany %F.

share|improve this answer

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.