=== modified file 'src/com/goldencode/p2j/ui/chui/ThinClient.java' --- src/com/goldencode/p2j/ui/chui/ThinClient.java 2016-03-04 13:31:54 +0000 +++ src/com/goldencode/p2j/ui/chui/ThinClient.java 2016-03-18 13:32:53 +0000 @@ -3091,7 +3091,7 @@ */ public synchronized void refreshHover() { - Window wnd = WindowManager.getActiveWindow(); + TopLevelWindow wnd = WindowManager.getActiveWindow(); if (recentlyHovered != null && recentlyHovered.windowId() == wnd.getId().asInt()) { recentlyHovered.updateCursor(); @@ -19018,7 +19018,7 @@ independentEventDrawingBracket(activeDropDown, activeDropDown.deactivateCode()); } - Window wnd = WindowManager.getActiveWindow(); + TopLevelWindow wnd = WindowManager.getActiveWindow(); if (wnd != null) { try === modified file 'src/com/goldencode/p2j/ui/client/TopLevelWindow.java' --- src/com/goldencode/p2j/ui/client/TopLevelWindow.java 2016-03-04 13:51:02 +0000 +++ src/com/goldencode/p2j/ui/client/TopLevelWindow.java 2016-03-18 13:32:53 +0000 @@ -726,64 +726,80 @@ WindowManager.setActiveWindow(tlw); } } - else if ((oldActive != this && !(oldActive != null && oldActive.isOverlay())) || - activated.withNativeWindow()) + else { - // the ACTIVE-WINDOW handle is updated before the LEAVE/ENTRY events are sent - // if LEAVE event returns NO-APPLY, ENTRY is no longer sent - - TopLevelWindow owner = getOwner(); - if (owner != null) - { - // this is a window connected to an owner, move the owner to top - WindowManager.moveToTop(owner); - - // and also all the other dialogs owned by the owner, make sure - // the z-order is preserved - int oId = owner.getId().asInt(); - WindowManager.getModalsOwnedBy(oId, true).stream() - .forEach(w -> WindowManager.moveToTop(w)); - - // and finally move us to top - WindowManager.moveToTop(this); - } - else - { - // this is a main window, move us to top - WindowManager.moveToTop(this); - - // move to top the modal windows owned by this window, preserve z-order - WindowManager.getModalsOwnedBy(getId().asInt(), true).stream() - .forEach(w -> WindowManager.moveToTop(w)); - } - - // the active-window handle is set BEFORE executing the LEAVE/ENTRY triggers - WindowManager.setActiveWindow(owner != null ? owner : this); + boolean oldNotOverlay = !(oldActive != null && oldActive.isOverlay()); + boolean needRebuildZorder = (oldActive != this && oldNotOverlay) || + activated.withNativeWindow(); + if (needRebuildZorder) + { + // the ACTIVE-WINDOW handle is updated before the LEAVE/ENTRY events are sent + // if LEAVE event returns NO-APPLY, ENTRY is no longer sent + + TopLevelWindow owner = getOwner(); + if (owner != null) + { + // this is a window connected to an owner, move the owner to top + WindowManager.moveToTop(owner); + + // and also all the other dialogs owned by the owner, make sure + // the z-order is preserved + int oId = owner.getId().asInt(); + WindowManager.getModalsOwnedBy(oId, true).stream() + .forEach(w -> WindowManager.moveToTop(w)); + + // and finally move us to top + WindowManager.moveToTop(this); + } + else + { + // this is a main window, move us to top + WindowManager.moveToTop(this); + + // move to top the modal windows owned by this window, preserve z-order + WindowManager.getModalsOwnedBy(getId().asInt(), true).stream() + .forEach(w -> WindowManager.moveToTop(w)); + } + + // the active-window handle is set BEFORE executing the LEAVE/ENTRY triggers + WindowManager.setActiveWindow(owner != null ? owner : this); + } + else if (!isOverlay()) + { + WindowManager.setActiveWindow(this); + } // do not use the top-level window here as it may not be the active one // (consider the TOP-ONLY attribute) TopLevelWindow actualActive = WindowManager.getActiveWindow(); - if (oldActive != actualActive) + if (needRebuildZorder || !isOverlay()) { final boolean[] entry = new boolean[1]; - // send leave, only if prev focus was within P2J - ThinClient.getInstance().independentEventDrawingBracket(oldActive, new Runnable() + if (oldActive != actualActive) { - @Override - public void run() + // send leave, only if prev focus was within P2J + ThinClient.getInstance().independentEventDrawingBracket(oldActive, new Runnable() { - // old top receives LEAVE event - entry[0] = activated.withNativeWindow() || - ThinClient.getInstance().sendLeave(oldActive); - EventManager.postEvent(new FocusEvent(oldActive, EventType.FOCUS_LOST)); - oldActive.repaint(); - if (oldActive.currentFocus() != null) + @Override + public void run() { - oldActive.currentFocus().repaint(); + // old top receives LEAVE event + entry[0] = activated.withNativeWindow() || + ThinClient.getInstance().sendLeave(oldActive); + EventManager.postEvent(new FocusEvent(oldActive, EventType.FOCUS_LOST)); + oldActive.repaint(); + if (oldActive.currentFocus() != null) + { + oldActive.currentFocus().repaint(); + } } - } - }); + }); + } + else + { + entry[0] = true; + } if (entry[0]) { @@ -796,10 +812,7 @@ } } } - } - else if (!isOverlay()) - { - WindowManager.setActiveWindow(this); + } // title repaint should be done after activation change === modified file 'src/com/goldencode/p2j/ui/client/WindowManager.java' --- src/com/goldencode/p2j/ui/client/WindowManager.java 2016-03-04 13:51:02 +0000 +++ src/com/goldencode/p2j/ui/client/WindowManager.java 2016-03-18 13:36:48 +0000 @@ -325,6 +325,12 @@ throw new NullPointerException("The window can not be null!"); } + if (!window.isRealized()) + { + // window is derigistered + return; + } + // move window to top WorkArea wa = work.get(); synchronized (wa.windows) @@ -514,13 +520,13 @@ * @return See above. */ @SuppressWarnings("unchecked") - public static > Window getActiveWindow() + public static > TopLevelWindow getActiveWindow() { TopLevelWindow active = (TopLevelWindow) activeWnd.get(); // if the top-level active window is not the main window, return its // main window owner - return active == null ? null : active.window(); + return active == null ? null : active; } /** @@ -531,7 +537,7 @@ */ public static void setActiveWindow(TopLevelWindow window) { - // overlay window can not be cinsidered as active one + // overlay window can not be considered as active one if (window != null && window.isOverlay()) { return;