=== modified file 'src/com/goldencode/p2j/ui/client/WindowManager.java' --- src/com/goldencode/p2j/ui/client/WindowManager.java 2016-09-26 10:00:26 +0000 +++ src/com/goldencode/p2j/ui/client/WindowManager.java 2016-11-02 17:13:28 +0000 @@ -77,6 +77,11 @@ ** 040 HC 20160712 Prevented an NPE when last DIALOG-BOX closed. ** 041 SBI 20160811 The alert box owner should be CURRENT-WINDOW. ** 042 HC 20160926 Removed disabling of window input events during server processing. +** 043 HC 20160825 Fixed window activation when window A being deactivated and B being +** activated while A and B having the same parent window with shared actvation +** state. +** Window activation events coming from GUI drivers are dispatched on the +** event queue to ensure correct event ordering. */ package com.goldencode.p2j.ui.client; @@ -1100,6 +1105,58 @@ } /** + * Enable OS events for the specified windows. Note that + * the method will not enable OS events for windows silenced + * due to an active modal window. + *

+ * This method can only be called in GUI mode. + * + * @param windowIds + * The window IDs which need to be processed. + */ + public static void enableOSEvents(int[] windowIds) + { + WorkArea wa = work.get(); + + List toEnable = new LinkedList<>(); + for (int id : windowIds) + { + toEnable.add(id); + } + + // do not enable events for silenced windows + for (TopLevelWindow wnd : wa.silencedWindows) + { + toEnable.remove(new Integer(wnd.getId().asInt())); + } + + if (toEnable.isEmpty()) + { + return; + } + + GuiDriver driver = (GuiDriver) OutputManager.getDriver(); + + int[] enableArray = Utils.integerCollectionToPrimitive(toEnable); + + driver.enableEvents(enableArray, true); + } + + /** + * Disable OS events for the specified windows. + *

+ * This method can only be called in GUI mode. + * + * @param windowIds + * The window IDs which need to be processed. + */ + public static void disableOSEvents(int[] windowIds) + { + GuiDriver driver = (GuiDriver) OutputManager.getDriver(); + driver.enableEvents(windowIds, false); + } + + /** * Turn the passed-in window into a modal window. The method * disables event input for all application top-level windows * except the passed-in window. @@ -1279,8 +1336,10 @@ } /** - * Called by the UI subsystem (GUI driver for example) when a top-leve window + * Called by the UI subsystem (GUI driver for example) when a top-level window * is activated. + * The method logic is pushed on the OS event queue and carried out later, + * this ensures a correct event ordering. *

* For more information of the concept of active windows, see * {@link #forEachActiveWindow(TopLevelWindow, Predicate)}. @@ -1292,26 +1351,31 @@ */ public static void windowActivated(int windowId, boolean fromNativeWindow) { - TopLevelWindow window = WindowManager.findWindow(windowId); - if (window == null) - { - // when window is hidden/destroyed, the de-activation event from - // the driver may arrive after the window is unregistered from - // WindowManager, so just ignore this - return; - } - - if (window == activeDriverWindow.get()) - { - // for now ignore activation of already activated window - return; - } - - processWindowActivated(window, fromNativeWindow); + ThinClient.getInstance().invokeLater(() -> + { + TopLevelWindow window = WindowManager.findWindow(windowId); + if (window == null) + { + // when window is hidden/destroyed, the de-activation event from + // the driver may arrive after the window is unregistered from + // WindowManager, so just ignore this + return; + } + + if (window == activeDriverWindow.get()) + { + // for now ignore activation of already activated window + return; + } + + processWindowActivated(window, fromNativeWindow); + }); } /** * Called by the driver when a top-leve window is deactivated. + * The method logic is pushed on the OS event queue and carried out later, + * this ensures a correct event ordering. *

* For more information of the concept of active windows, see * {@link #forEachActiveWindow(TopLevelWindow, Predicate)}. @@ -1323,25 +1387,28 @@ */ public static void windowDeactivated(int windowId, boolean toNativeWindow) { - TopLevelWindow deactivatedWindow = WindowManager.findWindow(windowId); - if (deactivatedWindow == null) - { - // the window being deactivated may be already gone, for example - // when window is hidden and destroyed right after - return; - } - - if (activeDriverWindow.get() != deactivatedWindow) - { - throw new RuntimeException( - "GUI driver sent deactivation event for window not previously activated!"); - } - - // process activation of non-p2j window - if (toNativeWindow) - { - processWindowActivated(null, true); - } + ThinClient.getInstance().invokeLater(() -> + { + TopLevelWindow deactivatedWindow = WindowManager.findWindow(windowId); + if (deactivatedWindow == null) + { + // the window being deactivated may be already gone, for example + // when window is hidden and destroyed right after + return; + } + + if (activeDriverWindow.get() != deactivatedWindow) + { + throw new RuntimeException( + "GUI driver sent deactivation event for window not previously activated!"); + } + + // process activation of non-p2j window + if (toNativeWindow) + { + processWindowActivated(null, true); + } + }); } /** @@ -1479,7 +1546,15 @@ // is also the new driver-active window. return false; } - + + // if activating a window that shares activation state with one of the parents + // of the window being deactivated, deactivate only up to the window that + // shares activation state with the window being activated + if (activated != null && isSharedActivationState(w, activated)) + { + return false; + } + ThinClient.getInstance().postOSEvent(new WindowActivated(w, false, activated == null)); // continue iteration === modified file 'src/com/goldencode/p2j/ui/client/widget/AbstractWidget.java' --- src/com/goldencode/p2j/ui/client/widget/AbstractWidget.java 2016-10-17 19:17:48 +0000 +++ src/com/goldencode/p2j/ui/client/widget/AbstractWidget.java 2016-11-02 17:13:28 +0000 @@ -103,6 +103,7 @@ ** never have a paint event raised. ** 057 SBI 20160914 Fixed a possible NPE. ** 058 SVL 20161014 Added clearWidget function. +** 059 VIG 20160729 Fixed requestFocus for the case when ansector() returns null. */ package com.goldencode.p2j.ui.client.widget; @@ -2567,4 +2568,4 @@ return FontManager.getTextHeight(txt, window, font, screen().getInstanceDriver()); } } -} \ No newline at end of file +}