Will the Unity launcher in 10.10 UNE have gnome-do style keyboard shortcuts?
i.e. Super+Spacebar for quick search and application launch
If not, can it be customized to allow this?
10.10shortcut-keysubuntu-netbookunity
Will the Unity launcher in 10.10 UNE have gnome-do style keyboard shortcuts?
i.e. Super+Spacebar for quick search and application launch
If not, can it be customized to allow this?
This extension emulates the Unity behavior in Gnome Shell: https://extensions.gnome.org/extension/413/dash-hotkeys/
Does exactly what is expected and adds some more key bindings, like opening a new window for the application with Super+Shift+[1-9]
. Confirmed working in Ubuntu 14.04.2 and Gnome Shell 3.10.4.
While It's not as user-friendly to setup and manage, you can get this kind of functionality in many environments, by using wmctrl
and xbindkeys
.
Xbindkeys can set to start at login. It will monitor a file called .xbindkeysrc
, which can contain lines like this:
#Launch or switch to E-mail
"wmctrl -xa Thunderbird || thunderbird"
Alt + 2
#Launch or switch to Konsole
"wmctrl -xa Konsole || konsole"
Alt + 3
#Launch or switch to IRC client
"wmctrl -xa Xchat || xchat"
Alt + 4
Like Unity, with this recipe you set up a key to switch to an application if it is running, or launch it if is not. I used Alt
here, but you could use Mod4
instead, I think.
Something similar is to assign keyboard shortcuts that switch to specific desktops (or "Workspace"). If you run one application per workspace, then the shortcut effectively switches to that application. Look under Keyboard: Shortcuts: Navigation
for the place to set the workspace-switching shortcuts.
After installing this Gnome extension, in overlay mode you can hold the ALT key and see a number assigned to each window. You can then press the number to switch the window. More here, including installation instructions.
The script below will disable specific key shortcuts when an arbitrary application's window is active.
Although you mentioned""I'd be willing to run a script every time I launch the application.", There is no reason to kill the script afterwards, it is extremely low on juice.
#!/usr/bin/env python3
import subprocess
import time
import os
app = "gedit"
f = os.path.join(os.environ["HOME"], "keylist")
def run(cmd):
subprocess.Popen(cmd)
def get(cmd):
try:
return subprocess.check_output(cmd).decode("utf-8").strip()
except:
pass
def getactive():
return get(["xdotool", "getactivewindow"])
def setkeys(val):
# --- add the keys to be disabled below
keys = [
["org.gnome.settings-daemon.plugins.media-keys", "logout"],
["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
]
# ---
writelist = []
if not val:
try:
values = open(f).read().splitlines()
except FileNotFoundError:
values = []
for i, key in enumerate(keys):
try:
cmd = ["gsettings", "set"]+key+[values[i]]
except IndexError:
cmd = ["gsettings", "reset"]+key
run(cmd)
else:
for key in keys:
cmd = ["gsettings", "set"]+key+["['']"]
read = get(["gsettings", "get"]+key)
writelist.append(read)
run(cmd)
if writelist:
open(f, "wt").write("\n".join(writelist))
front1 = None
while True:
time.sleep(1)
pid = get(["pgrep", app])
if pid:
try:
active = get(["xdotool", "getactivewindow"])
relevant = get(["xdotool", "search", "--all", "--pid", pid]).splitlines()
front2 = active in relevant
except AttributeError:
front2 = front1
else:
front2 = False
if front2 != front1:
if front2:
setkeys(True)
else:
setkeys(False)
front1 = front2
The script needs xdotool
:
sudo apt-get install xdotool
Copy the script into an empty file, save it as disable_shortcuts.py
In the head of the script, replace in the line:
app = "gedit"
"gedit" by your application, meaning: the process name that owns the window.
Test-run the script by the command:
python3 /path/to/disable_shortcuts.py
If all works fine, add it to Startup Applications: Dash > Startup Applications > Add. Add the command:
/bin/bash -c "sleep 15 && python3 /path/to/disable_shortcuts.py"
As an example, I added the shortcut you mentioned: CTRL + ALT + L. Shortcuts are set in the dconf
database, and can be set or disabled using gsettings
.
In the script, these gsettings
entries are set in the function: setkeys()
def setkeys(val):
# --- add the keys to be disabled below
keys = [
["org.gnome.settings-daemon.plugins.media-keys", "screensaver"]
]
# ---
An example to add (disabling) the log out shortcut:
dconf watch /
Re-set the shortcut to itself. In the terminal, you can see the gsettings
key that belongs to the shortcut:
Now we have to add the found key (in a slightly different appearance):
["org.gnome.settings-daemon.plugins.media-keys", "logout"]
...to the "keys" list in our function:
def setkeys(val):
# --- add the keys to be disabled below
keys = [
["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
["org.gnome.settings-daemon.plugins.media-keys", "logout"],
]
Now both CTRL + ALT + L and CTRL + ALT + Delete are disabled if your application is in front.
As mentioned, shortcuts, like the ones you mention, are set in the dconf
database. In the example CTRL + ALT + L, the key to set or edit the schortcut is:
org.gnome.settings-daemon.plugins.media-keys screensaver
To disable the key, the command is:
gsettings set org.gnome.settings-daemon.plugins.media-keys screensaver ""
To reset the key to its default value:
gsettings reset org.gnome.settings-daemon.plugins.media-keys screensaver
The script looks once per second if:
again (only) if so, it disables the shortcuts, listed in
# --- add the keys to be disabled below
keys = [
["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
["org.gnome.settings-daemon.plugins.media-keys", "logout"],
]
...waiting for the next change in state.
If the active window is not one of your application any more, the keys, mentioned in the list, are reset to default.
As mentioned earlier, the additional burden to the processor of the script is nihil. You could very well run it on startup, as explained in "How to use".
As discussed in comments, in OP's specific case, it is useful to apply disabling shortcuts on a group of applications, all residing in one directory.
Below a version to apply this on all applications of which the output of
pgrep -f
will include a specific directory. In my example, I set the /opt
directory, so if the active window is one of any of the applications in /opt
, the set shortcuts will be disabled.
bringing a window of one of the applications in /opt to front will disable the logout shortcut
re- enabling the shortcut if another window gets focus
#!/usr/bin/env python3
import subprocess
import time
import os
appdir = "/opt"
f = os.path.join(os.environ["HOME"], "keylist")
def run(cmd):
subprocess.call(cmd)
def get(cmd):
try:
return subprocess.check_output(cmd).decode("utf-8").strip()
except:
pass
def getactive():
return get(["xdotool", "getactivewindow"])
def setkeys(val):
# --- add the keys to be disabled below
keys = [
["org.gnome.settings-daemon.plugins.media-keys", "logout"],
["org.gnome.settings-daemon.plugins.media-keys", "screensaver"],
["org.gnome.desktop.wm.keybindings", "begin-move"],
]
# ---
writelist = []
if not val:
try:
values = open(f).read().splitlines()
except FileNotFoundError:
values = []
# for key in keys:
for i, key in enumerate(keys):
try:
cmd = ["gsettings", "set"]+key+[values[i]]
except IndexError:
cmd = ["gsettings", "reset"]+key
run(cmd)
else:
for key in keys:
cmd = ["gsettings", "set"]+key+["['']"]
read = get(["gsettings", "get"]+key)
writelist.append(read)
run(cmd)
if writelist:
open(f, "wt").write("\n".join(writelist))
front1 = None
while True:
time.sleep(1)
# check if any of the apps runs at all
checkpids = get(["pgrep", "-f", appdir])
# if so:
if checkpids:
checkpids = checkpids.splitlines()
active = getactive()
# get pid frontmost (doesn't work on pid 0)
match = [l for l in get(["xprop", "-id", active]).splitlines()\
if "_NET_WM_PID(CARDINAL)" in l]
if match:
# check if pid is of any of the relevant apps
pid = match[0].split("=")[1].strip()
front2 = True if pid in checkpids else False
else:
front2 = False
else:
front2 = False
if front2 != front1:
if front2:
setkeys(True)
else:
setkeys(False)
front1 = front2
Like the first script, xdotool
needs to be installed:
sudo apt-get install xdotool
Copy the script into an empty file, save it as disable_shortcuts.py
In the head of the script, replace in the line:
appdir = "/opt"
"/opt" by the directory your applications are.
Test-run the script by the command:
python3 /path/to/disable_shortcuts.py
If all works fine, add it to Startup Applications: Dash > Startup Applications > Add. Add the command:
/bin/bash -c "sleep 15 && python3 /path/to/disable_shortcuts.py"
Adding other shortcuts to the list works exactly similar to version 1 of the script.
In your answer, you mention:
xprop does not reveal PIDs for all windows. Failing example: stopwatch.
Windows with pid 0 (like tkinter windows, including Idle), have no window- id in the output of xprop -id
. Idle
does not have any clashing shortcuts though in my experience. If you run into any application with pid 0 that would require disabling specific shortcuts, please mention.
In that case, a possible escape would be to convert the output of
xdotool getactivewindow
to hex, the format wmctrl
uses, and subsequently look up the corresponding pid
in the output of
wmctrl -lp
Although that seemed the most obvious thing to do to start with, I didn't use it in the script to keep the script as light-weight as possible.
Best Answer
Edit: As of Ubuntu 11.04, this answer is wrong. See What are Unity's keyboard and mouse shortcuts? for a large number of keyboard shortcuts, including an Alt+F2 launcher.
As far as I'm aware this is currently not possible.
One of the requirements for switching to Unity on the desktop is that it needs accessibility work. A part of this work will be to ensure that Unity can be driven by the keyboard, so I would expect that this will be possible in the Ubuntu 11.04 release.
What I use for Do-style keyboard shortcuts in Unity is Do; it's a great complement to the Unity shell. The main problem is that Unity eats
win
keypresses, so the default Do shortcut is not available. It's easy to change the Do keybinding to something else, though.