Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 5534)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 5538)
@@ -7,4 +7,5 @@
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.awt.Window;
 import java.awt.event.ComponentEvent;
 import java.awt.event.ComponentListener;
@@ -18,4 +19,5 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
@@ -912,5 +914,5 @@
             synchronized(Main.class) {
                 Iterator<WeakReference<ProjectionChangeListener>> it = listeners.iterator();
-                while(it.hasNext()){
+                while (it.hasNext()){
                     WeakReference<ProjectionChangeListener> wr = it.next();
                     ProjectionChangeListener listener = wr.get();
@@ -930,5 +932,5 @@
 
     /**
-     * Register a projection change listener
+     * Register a projection change listener.
      *
      * @param listener the listener. Ignored if <code>null</code>.
@@ -946,5 +948,5 @@
 
     /**
-     * Removes a projection change listener
+     * Removes a projection change listener.
      *
      * @param listener the listener. Ignored if <code>null</code>.
@@ -954,7 +956,7 @@
         synchronized(Main.class){
             Iterator<WeakReference<ProjectionChangeListener>> it = listeners.iterator();
-            while(it.hasNext()){
+            while (it.hasNext()){
                 WeakReference<ProjectionChangeListener> wr = it.next();
-                // remove the listener - and any other listener which god garbage
+                // remove the listener - and any other listener which got garbage
                 // collected in the meantime
                 if (wr.get() == null || wr.get() == listener) {
@@ -964,3 +966,172 @@
         }
     }
+
+    /**
+     * Listener for window switch events.
+     * 
+     * These are events, when the user activates a window of another application
+     * or comes back to JOSM. Window switches from one JOSM window to another
+     * are not reported.
+     */
+    public static interface WindowSwitchListener {
+        /**
+         * Called when the user activates a window of another application.
+         */
+        void toOtherApplication();
+        /**
+         * Called when the user comes from a window of another application
+         * back to JOSM.
+         */
+        void fromOtherApplication();
+    }
+
+    private static final ArrayList<WeakReference<WindowSwitchListener>> windowSwitchListeners = new ArrayList<WeakReference<WindowSwitchListener>>();
+
+    /**
+     * Register a window switch listener.
+     *
+     * @param listener the listener. Ignored if <code>null</code>.
+     */
+    public static void addWindowSwitchListener(WindowSwitchListener listener) {
+        if (listener == null) return;
+        synchronized (Main.class) {
+            for (WeakReference<WindowSwitchListener> wr : windowSwitchListeners) {
+                // already registered ? => abort
+                if (wr.get() == listener) return;
+            }
+            boolean wasEmpty = windowSwitchListeners.isEmpty();
+            windowSwitchListeners.add(new WeakReference<WindowSwitchListener>(listener));
+            if (wasEmpty) {
+                // The following call will have no effect, when there is no window
+                // at the time. Therefore, MasterWindowListener.setup() will also be
+                // called, as soon as the main window is shown.
+                MasterWindowListener.setup();
+            }
+        }
+    }
+
+    /**
+     * Removes a window switch listener.
+     *
+     * @param listener the listener. Ignored if <code>null</code>.
+     */
+    public static void removeWindowSwitchListener(WindowSwitchListener listener) {
+        if (listener == null) return;
+        synchronized (Main.class){
+            Iterator<WeakReference<WindowSwitchListener>> it = windowSwitchListeners.iterator();
+            while (it.hasNext()){
+                WeakReference<WindowSwitchListener> wr = it.next();
+                // remove the listener - and any other listener which got garbage
+                // collected in the meantime
+                if (wr.get() == null || wr.get() == listener) {
+                    it.remove();
+                }
+            }
+            if (windowSwitchListeners.isEmpty()) {
+                MasterWindowListener.teardown();
+            }
+        }
+    }
+
+    /**
+     * WindowListener, that is registered on all Windows of the application.
+     *
+     * Its purpose is to notify WindowSwitchListeners, that the user switches to
+     * another application, e.g. a browser, or back to JOSM.
+     *
+     * When changing from JOSM to another application and back (e.g. two times
+     * alt+tab), the active Window within JOSM may be different.
+     * Therefore, we need to register listeners to <strong>all</strong> (visible)
+     * Windows in JOSM, and it does not suffice to monitor the one that was
+     * deactivated last.
+     *
+     * This class is only "active" on demand, i.e. when there is at least one
+     * WindowSwitchListener registered.
+     */
+    protected static class MasterWindowListener extends WindowAdapter {
+
+        private static MasterWindowListener INSTANCE;
+
+        public static MasterWindowListener getInstance() {
+            if (INSTANCE == null) {
+                INSTANCE = new MasterWindowListener();
+            }
+            return INSTANCE;
+        }
+
+        /**
+         * Register listeners to all non-hidden windows.
+         *
+         * Windows that are created later, will be cared for in {@link #windowDeactivated(WindowEvent)}.
+         */
+        public static void setup() {
+            if (!windowSwitchListeners.isEmpty()) {
+                for (Window w : Window.getWindows()) {
+                    if (w.isShowing()) {
+                        if (!Arrays.asList(w.getWindowListeners()).contains(getInstance())) {
+                            w.addWindowListener(getInstance());
+                        }
+                    }
+                }
+            }
+        }
+
+        /**
+         * Unregister all listeners.
+         */
+        public static void teardown() {
+            for (Window w : Window.getWindows()) {
+                w.removeWindowListener(getInstance());
+            }
+        }
+
+        @Override
+        public void windowActivated(WindowEvent e) {
+            if (e.getOppositeWindow() == null) { // we come from a window of a different application
+                // fire WindowSwitchListeners
+                synchronized (Main.class) {
+                    Iterator<WeakReference<WindowSwitchListener>> it = windowSwitchListeners.iterator();
+                    while (it.hasNext()){
+                        WeakReference<WindowSwitchListener> wr = it.next();
+                        WindowSwitchListener listener = wr.get();
+                        if (listener == null) {
+                            it.remove();
+                            continue;
+                        }
+                        listener.fromOtherApplication();
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void windowDeactivated(WindowEvent e) {
+            // set up windows that have been created in the meantime
+            for (Window w : Window.getWindows()) {
+                if (!w.isShowing()) {
+                    w.removeWindowListener(getInstance());
+                } else {
+                    if (!Arrays.asList(w.getWindowListeners()).contains(getInstance())) {
+                        w.addWindowListener(getInstance());
+                    }
+                }
+            }
+            if (e.getOppositeWindow() == null) { // we go to a window of a different application
+                // fire WindowSwitchListeners
+                synchronized (Main.class) {
+                    Iterator<WeakReference<WindowSwitchListener>> it = windowSwitchListeners.iterator();
+                    while (it.hasNext()){
+                        WeakReference<WindowSwitchListener> wr = it.next();
+                        WindowSwitchListener listener = wr.get();
+                        if (listener == null) {
+                            it.remove();
+                            continue;
+                        }
+                        listener.toOtherApplication();
+                    }
+                }
+            }
+        }
+    }
+
 }
Index: trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 5534)
+++ trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 5538)
@@ -351,4 +351,5 @@
         splash.dispose();
         mainFrame.setVisible(true);
+        Main.MasterWindowListener.setup();
 
         boolean maximized = Boolean.parseBoolean(Main.pref.get("gui.maximized"));
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java	(revision 5534)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java	(revision 5538)
@@ -78,5 +78,5 @@
 import org.openstreetmap.josm.tools.Utils;
 
-public class MapPaintDialog extends ToggleDialog {
+public class MapPaintDialog extends ToggleDialog implements Main.WindowSwitchListener {
 
     protected StylesTable tblStyles;
@@ -178,67 +178,27 @@
     }
 
-    /**
-     * Reload local styles when they have been changed in an external editor.
-     *
-     * Checks file modification time when an WindowEvent is invoked. Because
-     * any dialog window can get activated, when switching to another app and back,
-     * we have to register listeners to all windows in JOSM.
-     */
-    protected static class ReloadWindowListener extends WindowAdapter {
-
-        private static ReloadWindowListener INSTANCE;
-
-        public static ReloadWindowListener getInstance() {
-            if (INSTANCE == null) {
-                INSTANCE = new ReloadWindowListener();
-            }
-            return INSTANCE;
-        }
-
-        public static void setup() {
-            for (Window w : Window.getWindows()) {
-                if (w.isShowing()) {
-                    w.addWindowListener(getInstance());
+    @Override
+    public void toOtherApplication() {
+        // nothing
+    }
+
+    @Override
+    public void fromOtherApplication() {
+        // Reload local styles when they have been changed in an external editor.
+        // Checks file modification time.
+        List<StyleSource> toReload = new ArrayList<StyleSource>();
+        for (StyleSource s : MapPaintStyles.getStyles().getStyleSources()) {
+            if (s.isLocal()) {
+                File f = new File(s.url);
+                long mtime = f.lastModified();
+                if (mtime > s.getLastMTime()) {
+                    toReload.add(s);
+                    s.setLastMTime(mtime);
                 }
             }
         }
-
-        public static void teardown() {
-            for (Window w : Window.getWindows()) {
-                w.removeWindowListener(getInstance());
-            }
-        }
-
-        @Override
-        public void windowActivated(WindowEvent e) {
-            if (e.getOppositeWindow() == null) { // we come from a native window, e.g. editor
-                // reload local styles, if necessary
-                List<StyleSource> toReload = new ArrayList<StyleSource>();
-                for (StyleSource s : MapPaintStyles.getStyles().getStyleSources()) {
-                    if (s.isLocal()) {
-                        File f = new File(s.url);
-                        long mtime = f.lastModified();
-                        if (mtime > s.getLastMTime()) {
-                            toReload.add(s);
-                            s.setLastMTime(mtime);
-                        }
-                    }
-                }
-                if (!toReload.isEmpty()) {
-                    System.out.println(trn("Reloading {0} map style.", "Reloading {0} map styles.", toReload.size(), toReload.size()));
-                    Main.worker.submit(new MapPaintStyleLoader(toReload));
-                }
-            }
-        }
-
-        @Override
-        public void windowDeactivated(WindowEvent e) {
-            // set up windows that have been created in the meantime
-            for (Window w : Window.getWindows()) {
-                w.removeWindowListener(getInstance());
-                if (w.isShowing()) {
-                    w.addWindowListener(getInstance());
-                }
-            }
+        if (!toReload.isEmpty()) {
+            System.out.println(trn("Reloading {0} map style.", "Reloading {0} map styles.", toReload.size(), toReload.size()));
+            Main.worker.submit(new MapPaintStyleLoader(toReload));
         }
     }
@@ -249,5 +209,5 @@
         Main.main.menu.wireFrameToggleAction.addButtonModel(cbWireframe.getModel());
         if (Main.pref.getBoolean("mappaint.auto_reload_local_styles", true)) {
-            ReloadWindowListener.setup();
+            Main.addWindowSwitchListener(this);
         }
     }
@@ -258,5 +218,5 @@
         MapPaintStyles.removeMapPaintSylesUpdateListener(model);
         if (Main.pref.getBoolean("mappaint.auto_reload_local_styles", true)) {
-            ReloadWindowListener.teardown();
+            Main.removeWindowSwitchListener(this);
         }
     }
