Can I set Hot Corners to run custom commands in Unity?
Solution 1:
CCSM
-
Install CompizConfig Settings Manager (CCSM). Run in terminal:
sudo apt-get install compizconfig-settings-manager
Open CCSM.
- Go to "Commands"
-
Enter your desired command in one of the slots. E.g:
Go to "Edge Bindings" tab
-
Click "None" and set your desired hot corner (or edge), which corresponds to the command you just set
Move your mouse to the corner
-
Now your command is run!
Confirmed working on 14.04.
Solution 2:
Custom commands
If you are using Unity and have ccsm installed, wjandrea's answer is your answer of course. If not, or to use on other distros, a light weight alternative might be useful.
With the script below, you can set any command, specific to each of your hotcorners.
As an example, I made the following setup:
- Top Left No action
- Top Right Run Gedit
- Bottom Left No action
- Bottom RightRun Gnome-terminal
Of course you can also make the commands run external scripts.
Furthermore, you can set the size of the hot corner in the line:
cornersize = 10
Simply change the value (pixels). The script sets (square) areas to trigger your commands:
The script
#!/usr/bin/env python3
import subprocess
import time
cornersize = 20
commands = [
None,
"gedit",
None,
"gnome-terminal",
]
def get(cmd):
return subprocess.check_output(cmd).decode("utf-8").strip()
def get_pos():
return [int(s.split(":")[1]) for s in get(["xdotool", "getmouselocation"]).split()[:2]]
scrdata = get("xrandr").split(); resindex = scrdata.index("connected")+2
res = [int(n) for n in scrdata[resindex].split("+")[0].split("x")]
match1 = None
while True:
time.sleep(1)
xy = get_pos()
x = xy[0]; y = xy[1]
test = [
[x < cornersize, y < cornersize],
[x > res[0]-cornersize, y < cornersize],
[x < cornersize, y > res[1]-cornersize],
[x > res[0]-cornersize, y > res[1]-cornersize],
]
match2 = [i for i, p in enumerate(test) if all(p)]
if match2 != match1:
if match2:
cmd = commands[match2[0]]
if cmd:
subprocess.Popen(["/bin/bash", "-c", cmd])
match1 = match2
Set up
-
The script needs
xdotool
sudo apt install xdotool
- Copy the script into an empty file, save i as
hotcorners2.py
-
In the head of the script, set your commands (mind the quotes)
commands = [ None, "gedit", None, "gnome-terminal", ]
(subsequently top left/righ, bottom left/right)
-
Test- run the script:
python3 /path/to/hotcorners2.py
-
If all works fine, add to Startup Applications: Dash > Startup Applications > Add. Add the command:
/bin/bash -c "sleep 5 && python3 /path/to/hotcorners2.py"
Notes
- The script currently runs on on (the first) screen. It can be easily edited to take care of multiple screens, even do different things in different screens, please mention.
- If a few people like it, we can add a gui and a ppa for convenient usage and easy installation.
EDIT
If we use a bit more advanced computing, we can use a radius instead of a square area to trigger the commands (thanks to good old @pythagoras):
Small difference, but just for fun:
The script
#!/usr/bin/env python3
import subprocess
import math
import time
# set distance (hotcorner sensitivity)
radius = 20
# top-left, top-right, bottom-left, bottom-right
commands = [
None,
"gedit",
None,
"gnome-terminal",
]
def get(cmd):
return subprocess.check_output(cmd).decode("utf-8").strip()
def get_pos():
return [int(s.split(":")[1]) for s in get(["xdotool", "getmouselocation"]).split()[:2]]
# get the resolution
scrdata = get("xrandr").split(); resindex = scrdata.index("connected")+2
res = [int(n) for n in scrdata[resindex].split("+")[0].split("x")]
# list the corners, could be more elegant no doubt
corners = [[0, 0], [res[0], 0], [0, res[1]], [res[0], res[1]]]
match1 = None
while True:
time.sleep(1)
pos = get_pos()
# get the current difference from the mousepointer to each of the corner (radius)
diff = [int(math.sqrt(sum([(c[i]-pos[i])**2 for i, n in enumerate(res)])))\
for c in corners]
# see if any of the corners is "approached" within the radius
match2 = [diff.index(n) for n in diff if n < radius]
# if so, and the corresponding command is not set to None, run it.
if all([match2 != match1, match2]):
cmd = commands[match2[0]]
if cmd:
subprocess.Popen(["/bin/bash", "-c", cmd])
match1 = match2
Usage
Is pretty much the same. Set your commands, and the radius to trigger, in the head section of the script.
Solution 3:
NOTE:
wjandrea's answer is the most suitable answer for someone who uses default Ubuntu or Ubuntu Kylin ( or has compiz as their display manager ), thus it gets my upvote and respect. The answer provided below, can be used on Unity as well, but probably would be slightly redundant. However, on desktop environments that don't have compiz, one can use the indicator presented below. I've tested it briefly in Lubuntu 16.04 VM , so I know it works there, and made it compatible with Kylin 14.04 as well. For GNOME and MATE desktops, you will need have support for AppIndicators enabled first in order to use any indicator.
Introduction
I've implemented indicator-edger
which allows triggering user-defined commands based on mouse position anywhere along the 4 edges of the screen. Original version was done within one day, in approximately 7 hours, thus it is fairly minimalistic but does the job.
The indicator is controlled via ~/.edger-commands.json
file , obviously in json
format. It can be written manually by the user, or set via indicator's DEFINE COMMANDS
option. The enable/disable triggering option is remembered and written automatically to file for user's convenience. Sample configuration file would be like so:
{
"right": "gnome-terminal",
"top": "firefox",
"left": "",
"bottom": "gnome-screenshot",
"enabled": true
}
Note the "left"
entry in the file. That edge is unset, but due to json
syntax it requires having an empty string there, i.e. quotes ""
.
Once the indicator detects that user has placed the mouse along any of the edges (with ~3 pixel margin), the indicator will send a bubble notification and run the appropriate command (if defined). Activation of the trigger won't repeat unless the user moves the mouse away from the edge.
As you can see from the screenshot above, the indicator also has debugging output in the command-line. If you find any bugs, feel free to run it from the terminal, find out what error occurs, and submit appropriate bug report on issues page of the project's GitHub.
Currently there is no support for corners (only edges) and it was built for one-monitor setup (obviously, one cannot cover all the bases within 7 hours of creation), but those features might be available eventually in the future.
Installation and source code
The source code is available at the projects GitHub page or via Launchpad. Installation is performed via the following commands in terminal:
sudo add-apt-repository ppa:1047481448-2/sergkolo
sudo apt-get update
sudo apt-get install indicator-edger