diff --git a/app/src/main/java/io/xpipe/app/comp/base/TerminalViewDockComp.java b/app/src/main/java/io/xpipe/app/comp/base/TerminalViewDockComp.java index 5ea657e96..e4a107859 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/TerminalViewDockComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/TerminalViewDockComp.java @@ -23,6 +23,9 @@ public class TerminalViewDockComp extends SimpleComp { stack.boundsInParentProperty().addListener((observable, oldValue, newValue) -> { update(stack); }); + stack.sceneProperty().addListener((observable, oldValue, newValue) -> { + update(stack); + }); var s = AppMainWindow.getInstance().getStage(); s.xProperty().addListener((observable, oldValue, newValue) -> { update(stack); @@ -50,7 +53,10 @@ public class TerminalViewDockComp extends SimpleComp { TerminalView.get().onFocusLost(); } }); - s.addEventFilter(WindowEvent.WINDOW_HIDDEN,event -> { + s.addEventFilter(WindowEvent.WINDOW_SHOWN,event -> { + update(stack); + }); + s.addEventFilter(WindowEvent.WINDOW_HIDING,event -> { TerminalView.get().onClose(); }); stack.setOnMouseClicked(event -> { diff --git a/app/src/main/java/io/xpipe/app/core/window/NativeWinWindowControl.java b/app/src/main/java/io/xpipe/app/core/window/NativeWinWindowControl.java index c3cb376a6..cd93f5fa7 100644 --- a/app/src/main/java/io/xpipe/app/core/window/NativeWinWindowControl.java +++ b/app/src/main/java/io/xpipe/app/core/window/NativeWinWindowControl.java @@ -72,7 +72,7 @@ public class NativeWinWindowControl { } public void close() { - User32.INSTANCE.CloseWindow(windowHandle); + User32.INSTANCE.PostMessage(windowHandle, User32.WM_CLOSE, null, null); } public void minimize() { @@ -83,6 +83,12 @@ public class NativeWinWindowControl { User32.INSTANCE.SetWindowPos(windowHandle, null, bounds.getX(), bounds.getY(), bounds.getW(), bounds.getH(), User32.SWP_NOACTIVATE); } + public Rect getBounds() { + var rect = new WinDef.RECT(); + User32.INSTANCE.GetWindowRect(windowHandle, rect); + return new Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); + } + public boolean setWindowAttribute(int attribute, boolean attributeValue) { var r = Dwm.INSTANCE.DwmSetWindowAttribute( windowHandle, attribute, new WinDef.BOOLByReference(new WinDef.BOOL(attributeValue)), WinDef.BOOL.SIZE); diff --git a/app/src/main/java/io/xpipe/app/util/TerminalView.java b/app/src/main/java/io/xpipe/app/util/TerminalView.java index 80953d772..d54aff3de 100644 --- a/app/src/main/java/io/xpipe/app/util/TerminalView.java +++ b/app/src/main/java/io/xpipe/app/util/TerminalView.java @@ -98,7 +98,7 @@ public class TerminalView { @Override public Rect queryBounds() { - return null; + return control.getBounds(); } } @@ -151,10 +151,6 @@ public class TerminalView { TrackEvent.withTrace("Terminal session is dead").tag("pid", terminalInstance.getTerminal().pid()).handle(); } } - - terminalInstances.forEach(terminalInstance -> { - terminalInstance.updateBoundsState(); - }); } public synchronized void toggleView(boolean active) { @@ -178,15 +174,37 @@ public class TerminalView { } public synchronized void onMinimize() { - terminalInstances.forEach(terminalInstance -> terminalInstance.minimize()); + terminalInstances.forEach(terminalInstance -> { + terminalInstance.updateBoundsState(); + if (terminalInstance.isCustomBounds()) { + return; + } + + + terminalInstance.minimize(); + }); } public synchronized void onClose() { - terminalInstances.forEach(terminalInstance -> terminalInstance.close()); + terminalInstances.forEach(terminalInstance -> { + terminalInstance.updateBoundsState(); + if (terminalInstance.isCustomBounds()) { + return; + } + + terminalInstance.close(); + }); } private void updatePositions() { - terminalInstances.forEach(terminalInstance -> terminalInstance.updatePosition(viewBounds)); + terminalInstances.forEach(terminalInstance -> { + terminalInstance.updateBoundsState(); + if (terminalInstance.isCustomBounds()) { + return; + } + + terminalInstance.updatePosition(viewBounds); + }); } public void resizeView(int x, int y, int w, int h) { @@ -197,7 +215,7 @@ public class TerminalView { } public void clickView() { - updatePositions(); + terminalInstances.forEach(terminalInstance -> terminalInstance.updatePosition(viewBounds)); } private static TerminalView INSTANCE; diff --git a/lang/app/strings/translations_en.properties b/lang/app/strings/translations_en.properties index d5c8ea7c5..1c2962d1d 100644 --- a/lang/app/strings/translations_en.properties +++ b/lang/app/strings/translations_en.properties @@ -530,3 +530,4 @@ dontAllowTerminalRestart=Don't allow terminal restart dontAllowTerminalRestartDescription=By default, terminal sessions can be restarted after they ended from within the terminal. To allow this, XPipe will accept these external requests from the terminal to launch the session again\n\nXPipe doesn't have any control over the terminal and where this call comes from, so malicious local applications can use this functionality as well to launch connections through XPipe. Disabling this functionality prevents this scenario. openDocumentation=Open documentation openDocumentationDescription=Visit the XPipe docs page for this issue +clickToDock=Click to dock terminal