How to show (raise) all windows of an application?
I have an application using multiple windows. How can I quickly bring all the windows of that application to the foreground?
When I scroll through the applications with the scroll-wheel it only shows one window. When going to the next window, the last window is brought to the background again.
When I click on the application icon, I get a full-screen overview of all the windows. I have to select each window manually and move my mouse across half the screen several times.
My best solution so far is minimizing all windows (Ctrl+Super+D) and then show the windows of my application using the scroll-wheel.
Is there a better solution?
Solution 1:
EDIT -new answer-
The answer(s) below is/are still totally valid, and so the suggested options. Ongoing insight however made me add this option to use the indicator below, which is probably the most elegant solution.
As such, it should probably replace option 5 (using a .desktop file).
Simply choose the application from the list, and all windows of the corresponding application (present on the current viewport) will raise:
How to use
from ppa:
sudo add-apt-repository ppa:vlijm/upfront
sudo apt-get update
sudo apt-get install upfront
...or manually:
#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread
import os
import subprocess
import getpass
currpath = os.path.dirname(os.path.realpath(__file__))
class Indicator():
def __init__(self):
self.app = 'raise_apps'
iconpath = os.path.join(currpath, "raise.png")
self.indicator = AppIndicator3.Indicator.new(
self.app, iconpath,
AppIndicator3.IndicatorCategory.OTHER)
self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
self.indicator.set_menu(self.create_menu())
# the thread:
self.update = Thread(target=self.check_recent)
# daemonize the thread to make the indicator stopable
self.update.setDaemon(True)
self.update.start()
def create_menu(self):
# creates the (initial) menu
self.menu = Gtk.Menu()
# separator
initial = Gtk.MenuItem("Fetching list...")
menu_sep = Gtk.SeparatorMenuItem()
self.menu.append(initial)
self.menu.append(menu_sep)
# item_quit.show()
self.menu.show_all()
return self.menu
def raise_wins(self, *args):
index = self.menu.get_children().index(self.menu.get_active())
selection = self.menu_items2[index][1]
for w in selection:
execute(["wmctrl", "-ia", w])
def set_new(self):
# update the list, appearing in the menu
for i in self.menu.get_children():
self.menu.remove(i)
for app in self.menu_items2:
sub = Gtk.MenuItem(app[0])
self.menu.append(sub)
sub.connect('activate', self.raise_wins)
# separator
menu_sep = Gtk.SeparatorMenuItem()
self.menu.append(menu_sep)
# quit
item_quit = Gtk.MenuItem('Quit')
item_quit.connect('activate', self.stop)
self.menu.append(item_quit)
self.menu.show_all()
def get_apps(self):
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split() for l in get(["wmctrl", "-lpG"]).splitlines()]
# windows on current viewport
relevant = [w for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# pids
pids = [l.split() for l in get(["ps", "-u", getpass.getuser()]).splitlines()]
matches = [[p[-1], [w[0] for w in relevant if w[2] == p[0]]] for p in pids]
return [m for m in matches if m[1]]
def check_recent(self):
self.menu_items1 = []
while True:
time.sleep(4)
self.menu_items2 = self.get_apps()
for app in self.menu_items2:
app[0] = "gnome-terminal" if "gnome-terminal" in app[0] else app[0]
if self.menu_items2 != self.menu_items1:
GObject.idle_add(
self.set_new,
priority=GObject.PRIORITY_DEFAULT
)
self.menu_items1 = self.menu_items2
def stop(self, source):
Gtk.main_quit()
def get(command):
return subprocess.check_output(command).decode("utf-8")
def execute(command):
subprocess.Popen(command)
Indicator()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
-
The indicator needs
wmctrl
sudo apt-get wmctrl
Copy the indicator into an empty file, save it as
raise_apps.py
-
Copy the image below, save it exactly named
raise.png
in one and the same directory as the indicator. -
Then simply run it by the command:
python3 /path/to/raise_apps.py
-
Add if you want to Startup Applications:
/bin/bash -c "sleep 10 && python3 /path/to/raise_apps.py"
OLD ANSWER:
About the question
With the right tools, it is not very complicated to "just" raise all windows of an application. It is a bit more complicated to make sure only the windows of the current viewport are raised. The real challenge however is to find a convenient way to make the action available to the user.
Below five options to take care of that, to show how it can be done. All options are ready to be used. The last option however is kind of experimental; it works fine but has a few minor cosmetic downsides, as explained in the description of the option. I added it nevertheless as a concept.
Spreading the windows automatically in a non- overlapping way, as suggested in a comment, seems not a practical idea to me; if you work in an (application-wise) grouped window setup, the script would possibly unwantedly rearrange windows.
How to use
For all options you need to:
-
install
wmctrl
if it is not yet on your system:sudo apt-get install wmctrl
-
create, if it does not exist yet, the directory:
~/bin
(explanation: the directory
~/bin
is in $PATH, so you can run executables by their name) Copy the script, corresponding to the option, paste it into an empty file, save it as
raise_app
(no extension) in~/bin
and make it executable
In the separate options, possible additional steps will be explained.
Option 1: choose the application by entering one or more characters
- Press a key combination, a
zenity
window will appear - Enter one or more characters of the application's name in the entry box
- Press enter
This will make all windows of the matching application (on the current viewport) come to front.
raise all gnome-terminal
windows on the current viewport:
How to use:
- Do the set up as described in "How to use"
-
Test-run it by the command:
raise_app
If all works fine, add it to a shortcut key combination of your choice: Choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command
The script:
#!/usr/bin/env python3
import subprocess
import getpass
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# ask user for first characters
try:
arg = get('zenity --entry --text "first characters" --title "application"').strip()
except subprocess.CalledProcessError:
pass
# raise matching windows
try:
[execute("wmctrl -ia "+item[1]) for item in windows if item[0].startswith(arg)]
except (subprocess.CalledProcessError, NameError):
pass
Option 2: cycle through applications and raise their windows with a key combination:
Let's say I have the script below under a key combination Alt+1. I have several windows open of:
- firefox
- gnome-terminal
- nautilus
The current state:
I press once Alt+1, all nautilus
windows are raised:
I press again Alt+1, all firefox
windows are raised:
I press again Alt+1, all gnome-terminal
windows are raised again, the cycle starts over:
How to use
- Do the set up as described in "How to use"
-
Add it to a shortcut key combination of your choice: Choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command
raise_app
Then cycle through your applications with grouped application windows with your key combination.
The script:
#!/usr/bin/env python3
import subprocess
import getpass
include_single = True # set to False if you only want to cycle through apps with multiple windows
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
def get_frontmost():
cmd = "xprop -root"
frontmost = [l for l in get(cmd).splitlines() if\
"ACTIVE_WINDOW(WINDOW)" in l][0].split()[-1]
return frontmost[:2]+"0"+frontmost[2:]
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# create application list to cycle through
if include_single == False:
pre = [it[0] for it in windows]
apps = sorted(list(set([it for it in pre if pre.count(it) > 1])))
else:
apps = sorted(list(set([it[0] for it in windows])))
if len(apps) == 0:
pass
else:
# get the frontmost window as a last itm in the cycle
front = get_frontmost()
front_pid = [l.split()[2] for l in get("wmctrl -lp").splitlines() if front in l][0]
last_infront = get("ps -u "+getpass.getuser()+" | grep "+front_pid).split()[-1]
# determine next apllication to raise
if not last_infront in apps or last_infront == apps[-1]:
arg = apps[0]
print(arg)
else:
arg = apps[apps.index(last_infront)+1]
# raise matching windows
try:
[execute("wmctrl -ia "+item[1]) for item in windows if item[0] == arg]
except (subprocess.CalledProcessError, NameError):
pass
Option 3: press key combination + click on launcher icon -or- application window to raise all windows on the current viewport
This is probably the option that is closest to what is described in the question / comment.
Let's say I have a messy desktop with three nautilus
windows buried under other windows.
To raise all nautilus windows (example shortcut: Alt+1):
- Press Alt+1, release (!)
-
Within 3 seconds, either:
click on the application's icon in the launcher
or:
click on one of the application's windows
result:
How to use:
- Do the set up as described in "How to use"
-
Test-run it by the command:
raise_app
If all works fine, add it to a shortcut key combination of your choice: Choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command
Then:
-
Press your key combination and within 3 seconds, either:
- click on the application's icon in the launcher
- click on one of the application's windows
The script
#!/usr/bin/env python3
import subprocess
import getpass
import time
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
def get_frontmost():
cmd = "xprop -root"
frontmost = [l for l in get(cmd).splitlines() if\
"ACTIVE_WINDOW(WINDOW)" in l][0].split()[-1]
return frontmost[:2]+"0"+frontmost[2:]
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# get window data for various purposes
w_data = get("wmctrl -lpG").splitlines()
non_windows = sum([[l.split()[0] for l in w_data if it in l]\
for it in ("unity-launcher", "unity-panel", "unity-dash", "Hud")], [])
# get id of current window
curr_window = get_frontmost()
# user gets 3 seconds to pick an application window (or launcher icon)
t = 0
while t < 4:
w_id1 = get_frontmost()
time.sleep(1)
w_id2 = get_frontmost()
if w_id1 == w_id2 or w_id2 in non_windows+[curr_window]:
t = t+1
else:
new_frontmost = w_id2
break
# raise
try:
pid = [l.split()[2] for l in w_data if new_frontmost in l]
wl_data = [l.split() for l in w_data]
raise_windows = [l[0] for l in wl_data if pid[0] == l[2] and\
0 < int(l[3]) < res[0] and 0 < int(l[4]) < res[1]]
[execute("wmctrl -ia "+item) for item in raise_windows]
except NameError:
pass
Option 4: a key combination calls an option list, showing the number of windows per application on the current viewport
This one turned out to be more convenient then I assumed:
Pressing the (again example-) key combination Alt+1 calls a zenity
window, listing all applications and the number of their windows on the current viewport:
Simply pressing the ▴ or ▾ arrows will bring you to the right option. Press Enter and all windows of the chosen application are raised.
How to use:
- Do the set up as described in "How to use"
-
Test-run it by the command:
raise_app
If all works fine, add it to a shortcut key combination of your choice: Choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command
The script
#!/usr/bin/env python3
import subprocess
import getpass
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# preparing zenity optionlist
apps = [item[0] for item in windows]
# prevent multiple zenity windows
if apps.count("zenity") > 1:
pass
elif apps.count("zenity") > 0:
execute('zenity --info --text "Another Zenity window is open already"')
# preventing empty windowlist
elif len(apps) > 0:
applist = [[app, str(apps.count(app))] for app in set(apps)]
applist.sort(key=lambda x: x[1])
# calling zenity window
try:
arg = get('zenity --list --text "Choose an application" '+\
'--title "Current windows" '+\
'--column "application" '+\
'--column "windows" '+\
'--height 250 '+\
'--width 250 '+\
(" ").join(sum(applist, [])))
except subprocess.CalledProcessError:
pass
# raise matching windows
try:
[execute("wmctrl -ia "+item[1]) \
for item in windows if arg.startswith(item[0])]
except (subprocess.CalledProcessError, NameError):
pass
else:
execute('zenity --info --text "No windows to list"')
Option 5: raise windows of running applications from a launcher icon
This option exists of a launcher icon, with the currently running applications in a quicklist. Choose one, and all windows of the applications will be raised.
The launcher is automatically updated when the list of running applications (on the current viewport) changes. The quicklist shows a different list on other viewports, where windows of other applications are opened (will take 1-2 seconds to adapt).
As mentioned, although fully functional, this option is a meant as a concept. It has a few minor cosmetic downsides as it is. The most important:
- The cursor "wheel" keeps spinning for a few seconds after an action. Although it does not effect the functionality, it is a cosmetic downside.
- It takes 1-2 seconds for the applicationlist in the launcher icon to be updated after the list of running applications changes.
Furthermore the setup is slightly more complicated (although explained in detail below):
How to use
Below you will find:
two scripts / an icon / a .desktop
file
- Prepare the setup as in "How to use", save the first (main-) script as
raise_app
in~/bin
-
Save the icon below (right-click, save as) as
raise.png
-
Copy the
.desktop
file into an empty file, edit the lineIcon=/path/to/raise.png
to the real path to the icon (paths with spaces between quotes)
Save it asraise.desktop
in~/.local/share/applications
Drag the
.desktop
file to the launcher to add it- copy the second script, paste it into an empty file, save it as
update_apps
in~/bin
, make it executable. -
Add the following command to your startup applications (Dash > Startup Applications > Add):
update_apps
- Log out and back in to make it work.
The first script
#!/usr/bin/env python3
import subprocess
import getpass
import sys
arg = sys.argv[1]
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
try:
[execute("wmctrl -ia "+item[1]) for item in windows if item[0].startswith(arg)]
except (subprocess.CalledProcessError, NameError):
pass
The second script
#!/usr/bin/env python3
import subprocess
import getpass
import time
import os
dtfile = os.environ["HOME"]+"/.local/share/applications/raise.desktop"
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
def applist():
try:
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
except subprocess.CalledProcessError:
return []
else:
return set([app[0] for app in windows])
def update_dtfile(applications, text):
actionline = "Actions="+(";").join(applications)+";\n"
with open(dtfile) as src:
lines = src.readlines()
lines = lines[:[i for i in range(len(lines)) \
if lines[i].startswith("Actions=")][0]]+[actionline]
for item in text:
for it in item:
lines.append(it)
with open(dtfile, "wt") as out:
for line in lines:
out.write(line)
while True:
apps1 = applist()
time.sleep(1)
apps2 = applist()
if apps1 != apps2:
text = [["[Desktop Action "+it+"]\n", "Name="+it+"\n",
"Exec=raise_app "+it+"\n", "OnlyShowIn=Unity;\n\n",
]for it in apps2]
update_dtfile(apps2, text)
The .desktop file
[Desktop Entry]
Name=Raise application windows
Comment=Raise groups of windows
Icon=/path/to/raise.png
Terminal=false
Type=Application
Version=1.0
Actions=
Brief Explanation
All solutions above use wmctrl
to create a window list, using the wmctrl -lpG
command. This command produces lines, looking like:
0x044000b3 0 3429 65 24 1615 1026 jacob-System-Product-Name unity - How to show all windows of an application? - Ask Ubuntu - Mozilla Firefox
These lines include:
- 1st column: the window's id (that we can use to raise it)
- 3rd column: the pid that owns the window.
- 4th / 5th column: the window's geometry x-y (that we use to see if the window is on the current viewport, i.c.w
xrandr
)
The pid is looked up in the output of ps -u <username>
to get a "user-readable" identification (name) of the application.
Thus we can allocate windows to applications. Subsequently we can raise the windows of a given application in a for
loop with the command wmctrl -ia
.
In option 3
the script starts a 3- second "waiting" loop, using the xprop -root
command repeatedly to see if there is any change in what is the frontmost window; this will happen if the user either clicks on a launcher icon to raise an application's window, or clicks on a window directly. If so, the while- loop breaks and looks up the "new" frontmost application, and subsequently raises all other windows of that application.
Solution 2:
There is Super+W shortcut which will show expo of all the currently open windows, though that will include other applications. This comes by default, and doesn't require any changes, so perhaps it's a simplest option available.
Among other things, you could position windows on right and left halves of the screen with Ctrl+Super+Left/Right buttons, and switch between them with Alt+~ (tilde, the one next to number one key).
Solution 3:
If you press Alt+Tab to cycle through applications, and you get to one with multiple windows, just keep holding the alt key down and after about 1 full second the icon will be replaced with a view of all of the windows for that application.
That may or may not be what you're looking for, but it works for me and is a ton simpler, so I figured I'd share the option!
Solution 4:
I took @JacobVlijm's raise_apps.py script and made some enhancements to it, including making it more robust.
Specifically, I had found that after a day or two, @JacobVlijm's script would stop working, and I'd have to manually restart the script, to get it working again. In retrospect, my best guess is that the numerous calls to xrandr eventually cause issues.
Anyways, I adapted his code, increased the polling frequency from 5 seconds to every 1 second, as it doesn't use much CPU anyways, and made it more robust. I can typically have it running for days/weeks without issues.
One caveat is that I only call xrandr once during startup, to get screen resolution dimensions. So if you change your screen resolution (e.g. from 1920x1080 to some other resolution), you'll probably want to manually restart raise-apps.py so that it will pick up the new resolution. Personally, I never change my screen resolution, so this is a non-issue for me. Additionally, I have strong reason to believe that too many calls to xrandr were what was causing @JacobVlijm's version of the script to stop working after a day or two, so I would strongly recommend not simply putting the numerous calls to xrandr back in..
BTW, you need to place the raise.png image in the /usr/local/icons/ directory. Or if you want to put raise.png in a different directory make the appropriate change to the script, so that the script can find the image file.
Hopefully, Ubuntu will integrate this type of 'raise all windows' functionality into their system sooner than later as it's very useful:
#!/usr/bin/python2
#
# Note to self:
# You need to add raise.png to /usr/local/icons/ directory.
#
# This script was taken from: https://askubuntu.com/questions/446521/how-to-show-raise-all-windows-of-an-application,
# (@JacobVlijm's answer), and then improved to fix some
# issues, that were causing it to stop working after a day or two.
#
#
from __future__ import print_function
from sys import stderr, exit
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject, GLib
import logging
import logging.handlers
import time
import os
import subprocess
import getpass
logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)
log_handler = logging.handlers.SysLogHandler(address='/dev/log')
logger.addHandler(log_handler)
currpath = os.path.dirname(os.path.realpath(__file__))
class Indicator():
def __init__(self):
self.app = 'raise-apps'
iconpath = '/usr/local/icons/raise.png'
self.indicator = AppIndicator3.Indicator.new(
self.app, iconpath,
AppIndicator3.IndicatorCategory.OTHER)
self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
self.prev_menu_item_names = []
self.menu_items = []
res_output = get("xrandr").split()
if (len(res_output) == 0):
logger.error("raise-apps.py: invocation of xrandr failed! Unable to continue..")
exit(-1)
idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
(self.screen_width, self.screen_height) = res
logger.info("raise-apps.py: screen resolution is %s x %s" % (self.screen_width, self.screen_height))
self.indicator.set_menu(self.create_menu())
GLib.timeout_add_seconds(1.0, self.check_recent)
def create_menu(self):
# creates the (initial) menu
self.menu = Gtk.Menu()
# separator
initial = Gtk.MenuItem("Fetching list...")
menu_sep = Gtk.SeparatorMenuItem()
self.menu.append(initial)
self.menu.append(menu_sep)
self.menu.show_all()
return self.menu
def raise_wins(self, *args):
index = self.menu.get_children().index(self.menu.get_active())
selection = self.menu_items[index][1]
for w in selection:
execute(["wmctrl", "-ia", w])
def set_new(self):
# update the list, appearing in the menu
for i in self.menu.get_children():
self.menu.remove(i)
for app in self.menu_items:
sub = Gtk.MenuItem(app[0])
self.menu.append(sub)
sub.connect('activate', self.raise_wins)
# separator
menu_sep = Gtk.SeparatorMenuItem()
self.menu.append(menu_sep)
# quit
item_quit = Gtk.MenuItem('Quit')
item_quit.connect('activate', self.stop)
self.menu.append(item_quit)
self.menu.show_all()
def get_apps(self):
# creating window list on current viewport / id's / application names
w_data = [l.split() for l in get(["wmctrl", "-lpG"]).splitlines()]
# windows on current viewport
relevant = [w for w in w_data if 0 < int(w[3]) < self.screen_width and 0 < int(w[4]) < self.screen_height]
# pids
pids = [l.split() for l in get(["ps", "-u", getpass.getuser()]).splitlines()]
matches = [[p[-1], [w[0] for w in relevant if w[2] == p[0]]] for p in pids]
return [m for m in matches if m[1]]
def check_recent(self):
# print("in check_recent()", file=stderr)
self.menu_items = self.get_apps()
for app in self.menu_items:
app[0] = "gnome-terminal" if "gnome-terminal" in app[0] else app[0]
# check if menu items have changed:
has_changed = len(self.menu_items) != len(self.prev_menu_item_names)
if (not has_changed):
for i in range(len(self.menu_items)):
if self.prev_menu_item_names[i] != self.menu_items[i][0]:
has_changed = True
break
if has_changed:
GObject.idle_add(
self.set_new,
priority=GObject.PRIORITY_DEFAULT)
self.prev_menu_item_names = []
for item in self.menu_items:
self.prev_menu_item_names.append(item[0])
GLib.timeout_add_seconds(1.0, self.check_recent)
def stop(self, source):
Gtk.main_quit()
def recreate_menu(self, *args):
logger.info("in recreate_menu()")
self.prev_menu_item_names = []
self.menu_items = []
self.menu_items = self.get_apps()
for app in self.menu_items:
app[0] = "gnome-terminal" if "gnome-terminal" in app[0] else app[0]
GObject.idle_add(
self.set_new,
priority=GObject.PRIORITY_DEFAULT)
self.prev_menu_item_names = []
for item in self.menu_items:
self.prev_menu_item_names.append(item[0])
def get(command):
# enable to get a feel for what this app is doing..
# print("get", command, file=stderr)
try:
return subprocess.check_output(command).decode("utf-8")
except subprocess.CalledProcessError as e:
logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
return ""
except OSError as e:
logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
return ""
def execute(command):
# enable to get a feel for what this app is doing..
# print("exec", command, file=stderr)
try:
subprocess.call(command)
except subprocess.CalledProcessError as e:
logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
return ""
except OSError as e:
logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
return ""
logger.info("(raise-apps.py is starting up..)")
Indicator()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()