24

When opening programs like GIMP, I find having background windows open distracting because GIMP has three separate windows associated with it.

It's a burden to have to go to every other non-Gimp window manually to minimize it. What I need is a keyboard shortcut in Ubuntu that matches Windows' Super + Home shortcut. One that minimizes all windows except the active one.

Is it possible to achieve this behavior in Ubuntu?

Aditya
  • 13,416
Chad
  • 241
  • Interesting idea! Have a look at the 1st answer here for pointers: http://askubuntu.com/questions/13709/is-there-a-keybind-to-minimize-all-windows-without-a-toggle That post is about adding a function to minimize all. From looking at it adding a line 'maximize previous current active' or changing it to 'minimize except current active one' after it would do the trick(?) – Rinzwind May 04 '11 at 14:08
  • any chance the developers will add a "Minimize All But The Active Window" option in the Keyboard Shortcut menu in future Ubuntu versions? This way this bind is "ready and waiting" to be configured when users install Ubuntu? – Chad May 04 '11 at 14:31

5 Answers5

21

It is possible to achieve this with a python script. The script requires python-wnck and python-gtk to be installed in order to work, although I think these are installed by default anyway.

Copy and paste this into a text editor and save in a sensible place (eg. as minimise.py in your home folder):

#!/usr/bin/env python
import wnck
import gtk

screen = wnck.screen_get_default()

while gtk.events_pending():
    gtk.main_iteration()

windows = screen.get_windows()
active = screen.get_active_window()

for w in windows:
    if not w == active:
        w.minimize()

You can then set up the keyboard shortcut by opening Keyboard Shortcuts.

Keyboard Shortcuts in Dash

Click on Add to create a new shortcut.

Keyboard Shortcuts window

Use the command bash -c 'python ~/minimise.py' (this is assuming you saved it as minimise.py in your home folder).

create shortcut

You can then assign your preferred keyboard combination to this action.

The script will minimise all non-active windows. I don't think this is very useful for your use case because you will want to have all of the Gimp windows open. You can use a slightly different script to minimise all windows that aren't from the current application instead:

#!/usr/bin/env python
import wnck
import gtk

screen = wnck.screen_get_default()

while gtk.events_pending():
    gtk.main_iteration()

windows = screen.get_windows()
active_app = screen.get_active_window().get_application()

for w in windows:
    if not w.get_application() == active_app:
        w.minimize()
Aditya
  • 13,416
dv3500ea
  • 37,204
  • 4
    +1! This is why I love Linux! Excellent. @chad: if the multiple windows of gimp is a problem there seems to be a way to have gimp act as 1 window. Oops: it seems to be the default from 2.6 (go figure; I haven't used gimp for a long time). – Rinzwind May 04 '11 at 17:50
  • This is why I love Python - it has a module for everything! – dv3500ea May 04 '11 at 17:51
  • 1
    python-wnck had to be installed on my system, 14.04. Question though, inside the python shell it works ok without the gtk.main_loop part, but without it inside the script, it doesnt. So basically to make the script workable from a .py file, the gtk.main_loop part is a must. Can someone explain why ? – Sergiy Kolodyazhnyy Feb 03 '16 at 03:44
  • Why bash -c 'python... and not just python ...? – Michael Campbell Jul 31 '19 at 15:30
5

Here's a pretty simple approach using wmctrl

wmctrl -k on; wmctrl -R :ACTIVE:

The first command shows the desktop (i.e. minimizes all windows) and the second command raises the "active" window which is whatever was active before the minimizing. I put this in a one-line bash script and then set a keyboard shortcut to that script.

edit: restore all windows using:

wmctrl -l | cut -d' ' -f 1 | xargs -n1 wmctrl -i -a

  • This is so good! So easy to use. Is there a way I could do the reverse of this? – Frank Fu May 26 '20 at 14:18
  • @FrankFu by reverse do you mean restore all the windows that were shown prior to running these two commands? If so, I can't find a straight forward way to do this....wmctrl -k off will invert the first command above (i.e. show all the previous windows) but after you run the second second command, it seems that the "memory" of what was shown/minimized is lost. If you want to restore ALL windows you can do something like wmctrl -l | cut -d\ -f 1 | xargs -n1 wmctrl -i -a – brotherJ4mes May 27 '20 at 15:15
  • Yep that's what I meant. Trying your second command it gives me an error message saying "cut: the delimiter must be a single character. Try 'cut --help' for more information. wmctrl: option requires an argument -- 'a' " – Frank Fu May 28 '20 at 05:35
  • Ah, I forgot an additional space after -d\. You could also use -d' ' This flag tells cut what the delimiter is so it knows how to break up the fields (columns). The way this command chain works is wmctrl lists all the windows | cut grabs just the first column which has the window ids | xargs passes each window id back to wmctrl which activates (unminimizes) them one by one. – brotherJ4mes May 28 '20 at 14:55
  • Thanks brotherJ4ames! I appreciate the explanation as well. wmctrl -l | cut -d' ' -f 1 | xargs -n1 wmctrl -i -a worked for me ;) – Frank Fu May 28 '20 at 16:52
  • Thanks for that solution. This was one of the features I missed the most from MacOS (CMD+Shift+H). – Paidhi Nov 28 '20 at 16:21
  • this solution isn't working in Xfce DE, don't know why – folivore May 29 '23 at 04:33
  • Actually isn't that so that first command should make all the windows minimized hence inactive hence the second command doesn't have a window to operate on? – folivore May 29 '23 at 04:47
  • @folivore: That's a logical concern but somehow (at least on my system) wmctrl is able to "remember" which window was active last and it restores it every time. – brotherJ4mes Jun 02 '23 at 13:19
  • @brotherJ4mes well, in my case wmctrl doesn't remember a thing ), though the solution with using xdotool works ok for my configuration. and I must say it actually looks more reasonable for me too because it actually minimizes all the other windows and not minimizes all the windows and then restores one of them back as in this solution with wmctrl. It looks as if this solution is based on some kind of bug of wmctrl or of a DE in question. – folivore Jul 04 '23 at 02:19
3

bash script using xdotool:

currentwindowid=$(xdotool getactivewindow)
currentdesktopid=$(xdotool get_desktop)

for w in $(xdotool search --all --maxdepth 3 --desktop $currentdesktopid --name ".*"); do
  if [ $w -ne $currentwindowid ] ; then
    xdotool windowminimize "$w"
  fi
done

it minimizes only windows on the current desktop.

To minimize windows on all desktops:

currentwindowid=$(xdotool getactivewindow)

for w in $(xdotool search --all --maxdepth 3 --name ".*"); do
  if [ $w -ne $currentwindowid ] ; then
    xdotool windowminimize "$w"
  fi
done
1

Since python-wnck is no longer in the apt repository (Kubuntu 18.04 Bionic), below is the modified python code (from the answer above by @Aditya and @dv3500ea).

From python3 onwards wnck is part of the GObject Introspection API (source). So, syntax for importing wnck (and Gtk objects) has changed.

#!/usr/bin/env python

# import necessary objects
import gi
gi.require_version('Wnck', '3.0') # specify Wnck version
from gi.repository import Wnck

from gi.repository import Gtk


# the script itself
screen = Wnck.Screen.get_default()

while Gtk.events_pending():
    Gtk.main_iteration()

windows = screen.get_windows()
active = screen.get_active_window()

for w in windows:
    if not w == active:
        w.minimize()

then assign the shortcut to the python script: (in Kubuntu) kmenueditor -> create a new item -> script bash -c 'python path_to_the_python_script.py' -> assign a desired shortcut

UPDATE (May'19):

At Kubuntu 19.04 I needed to install gir1.2-wnck-3.0 module to make the script above work.

$ python -V
Python 2.7.16
$ sudo apt-get install python3-gi gir1.2-wnck-3.0
0

Ubuntu 21.10 is running Wayland and I want this functionality on my new monitor. This is the solution that works for me, it's a bash script I bind to a custom key combination.

#!/bin/bash
gdbus call \
  --session \
  --dest org.gnome.Shell \
  --object-path /org/gnome/Shell \
  --method org.gnome.Shell.Eval \
  "global
      .get_window_actors()
      .filter(w=>w.meta_window.has_focus()===false)
      .forEach(w=>w.meta_window.minimize())"