Give that a try first.
Are you registering the myapp
scheme or the myprotocol
scheme?
You mention both of these, and it's somewhat confusing exactly what URLs you want to open.
I will assume you want to use the myprotocol
scheme,
e.g. myprotocol://abcd
.
The "Exec" entry of your desktop file.
Exec=sh -c "$HOME/.my-handler.sh %u"
The $HOME/
is not necessary if .my-handler.sh
is in your $PATH
.
The sh -c
is not necessary if your script is executable,
since it has the shebang line at the top.
This also adds another layer of complexity,
since any URLs will be expanded by the shell
before they get to your URL handler script.
The shebang line lists it as a bash script (#!/bin/bash
),
but you are using sh
to execute it instead.
I don't see any part of the script where that will make a difference,
but by default sh
is dash
,
a different shell from bash
.
$ type -a sh
sh is /bin/sh
$ file /bin/sh
/bin/sh: symbolic link to dash
The .my-handler.sh
script.
You don't need to make it a hidden file;
a filename like my-handler.sh
will be fine.
Since I doubt that your home directory is in $PATH
,
there is no advantage to putting it in your home directory
other than making the absolute path a little shorter.
(See more about $PATH
below.)
Your shebang will work on Ubuntu:
$ type -a bash
bash is /bin/bash
but it's a good habit to use #!/usr/bin/env bash
for portability.
You are using an uninitialized variable "$code"
and appending it to a file called file
.
What is the purpose of this?
Since file
is a relative path,
this will depend on the working directory,
which is probably not what you want.
(For URLs launched from Firefox,
this will depend on what directory the browser was launched from,
which might be the home directory, but could be almost anywhere else, too.)
Your script never uses "$1"
or any other arguments.
This means it is essentially discarding the URL it is passed
and opening https://redirect.site.com
instead.
But maybe this is just a placeholder script and this was intentional?
If so, I would suggest this test script instead:
$ cat .my-handler.sh
#! /usr/bin/env bash
URL="$1"
zenity --info --text "URL: ${URL}\nPWD=${PWD}"
so you can see the URL passed and directory it's being run from.
We'll address this issue below.
Check if the protocol is already registered.
$ gio mime x-scheme-handler/myprotocol
No default applications for “x-scheme-handler/myprotocol”
In my case, the protocol is not already registered.
Test the script directly.
You may need to make it executable, like this:
$ chmod +x ~/.my-handler.sh
Then use an example URL:
$ ~/.my-handler.sh 'myprotocol://abcd'
Fix any problems here before continuing on.
Add the script to your $PATH
so the desktop file can find it.
This step is optional,
but it is a good habit to get into.
Putting scripts into $PATH
means you will not have to include the full absolute path in your desktop file,
so your desktop file will not need to be changed
if the path to your script changes.
I use a bin
directory like this:
$ mkdir ~/bin/
and add this to ~/.profile
(note you will need to log out and log in again to see changes):
PATH="$HOME/bin:$PATH"
and finally either copy or symlink the script to ~/bin
:
$ ln -s $PWD/.my-handler.sh ~/bin/
If you did this properly, you should something similar to this:
$ type -a .my-handler.sh
.my-handler.sh is /home/nathaniel/bin/.my-handler.sh
not this:
$ type -a .my-handler.sh
bash: type: .my-handler.sh: not found
Install the desktop file.
It looks like you have done this already,
but for future reference you can use the desktop-file-install
command from the desktop-file-utils
package:
$ desktop-file-install --dir=$HOME/.local/share/applications/ myprotocol-handler.desktop
These are the most important lines in the desktop file:
Exec=.my-handler.sh %u
MimeType=x-scheme-handler/myprotocol
Make sure the desktop file is executable.
Do this like so:
$ chmod +x ~/.local/share/applications/myprotocol-handler.desktop
This is necessary as a security measure.
Register the desktop file with the
x-scheme-handler/myprotocol
mimetype.
$ gio mime x-scheme-handler/myprotocol myprotocol-handler.desktop
Set myprotocol-handler.desktop as the default for x-scheme-handler/myprotocol
All this really does is change lines in ~/.config/mimeapps.list
under the [Default Applications]
group
so it says this:
x-scheme-handler/myprotocol=myprotocol-handler-desktop
Some older applications use ~/.local/share/application/mimeapps.list
,
but this is officially deprecated.
However, the xdg-mime
command uses this location anyway:
$ xdg-mime default myprotocol-handler.desktop x-scheme-handler/myprotocol
There is also an even older deprecated file
called defaults.list
that is still used by some applications.
Edit this file with a text editor:
$ edit ~/.local/share/applications/defaults.list
and manually add these lines:
x-scheme-handler/myprotocol=myprotocol-handler.desktop
under the [Default Applications]
group.
Check if it was successfully registered.
$ gio mime x-scheme-handler/myprotocol
Default application for “x-scheme-handler/myprotocol”: myprotocol-handler.desktop
Registered applications:
myprotocol-handler.desktop
Recommended applications:
myprotocol-handler.desktop
Check xdg-mime
also.
$ xdg-mime query default x-scheme-handler/myprotocol
myprotocol-handler.desktop
Test some URLs from the command line.
$ gio open 'myprotocol://abcd'
Now test the same URL with xdg-open
:
$ xdg-open 'myprotocol://abcd'
Update the mimeinfo cache.
Some applications read ~/.local/share/applications/mimeinfo.cache
instead of ~/.config/mimeapps.list
.
So update the cache:
$ update-desktop-database ~/.local/share/applications/
Test it in the browser with a local HTML file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example URL</title>
</head>
<body>
<a href="myprotocol://abcd">myprotocol://abcd</a>
</body>
</html>
The first time you open the link,
Firefox will prompt you to find the desktop file.

Navigate to ~/.local/share/applications/
and click myprotocol-handler.desktop
.
Also tick the box that says "Remember my choice for myprotocol links."

It should look like this when you're done.

Test it in the browser with a remote HTML file.
There are some security differences between local and remote HTML files,
so it's good to check both.
You could set up some hosting for this,
or just use Github or similar, but that's outside the scope of this question.
handlers.json
file under~/.mozilla/firefox/i00uyhbs.default/handlers.json
? – Venkatesh Marepalli Oct 05 '17 at 21:17