Commit 2b7b399c authored by Anton Tarasov's avatar Anton Tarasov
Browse files

[followup] Support out of EDT move/resize for custom-decorated mode.

parent c230af58
Branches unavailable Tags unavailable
No related merge requests found
Showing with 76 additions and 39 deletions
+76 -39
......@@ -362,7 +362,7 @@ public class DarculaRootPaneUI extends BasicRootPaneUI {
JComponent titlePane = createTitlePane(root);
setTitlePane(root, titlePane);
installWindowListeners(root, root.getParent());
//installWindowListeners(root, root.getParent()); // installed on ancestor change
installLayout(root);
if (myWindow != null) {
root.revalidate();
......@@ -372,7 +372,7 @@ public class DarculaRootPaneUI extends BasicRootPaneUI {
private void uninstallClientDecorations(JRootPane root) {
uninstallBorder(root);
uninstallWindowListeners(root);
//uninstallWindowListeners(root);
setTitlePane(root, null);
uninstallLayout(root);
int style = root.getWindowDecorationStyle();
......@@ -455,7 +455,7 @@ public class DarculaRootPaneUI extends BasicRootPaneUI {
}
if (propertyName.equals("ancestor")) {
uninstallWindowListeners(myRootPane);
if (((JRootPane)e.getSource()).getWindowDecorationStyle() != JRootPane.NONE) {
if (e.getNewValue() != null && ((JRootPane)e.getSource()).getWindowDecorationStyle() != JRootPane.NONE) {
installWindowListeners(myRootPane, myRootPane.getParent());
}
}
......
......@@ -23,11 +23,12 @@ import com.intellij.util.MethodInvocator;
import com.intellij.util.ui.UIUtil;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.MouseInputListener;
import java.awt.*;
import java.awt.event.*;
import java.awt.peer.ComponentPeer;
import static java.awt.Cursor.*;
......@@ -113,6 +114,7 @@ abstract class WindowMouseListener extends MouseAdapter implements MouseInputLis
Component view = getView(content);
if (view != null) {
myType = isDisabled(view) ? CUSTOM_CURSOR : getCursorType(view, event.getLocationOnScreen());
//noinspection MagicConstant
setCursor(content, getPredefinedCursor(myType == CUSTOM_CURSOR ? DEFAULT_CURSOR : myType));
if (start && myType != CUSTOM_CURSOR) {
myLocation = event.getLocationOnScreen();
......@@ -210,8 +212,8 @@ abstract class WindowMouseListener extends MouseAdapter implements MouseInputLis
* @author tav
*/
@ApiStatus.Experimental
public class ToolkitListenerHelper {
private WindowMouseListener myListener;
public static class ToolkitListenerHelper {
private final WindowMouseListener myListener;
private Class classWComponentPeer;
private MethodInvocator reshapeInvocator;
......@@ -254,14 +256,14 @@ abstract class WindowMouseListener extends MouseAdapter implements MouseInputLis
}
}
public void setCursor(Component content, Cursor cursor, Runnable defaultAction) {
public void setCursor(Component content, @SuppressWarnings("unused") Cursor cursor, Runnable defaultAction) {
PotemkinProgress.invokeLaterNotBlocking(content, defaultAction);
}
public void setBounds(Component comp, Rectangle bounds, Runnable defaultAction) {
if (classWComponentPeer != null && classWComponentPeer.isInstance(comp.getPeer())) {
// emulate native set bounds
reshapeInvocator.invoke(comp.getPeer(), bounds.x, bounds.y, bounds.width, bounds.height);
if (classWComponentPeer != null && classWComponentPeer.isInstance(getPeer(comp))) {
// emulate native awt move/resize
reshapeInvocator.invoke(getPeer(comp), bounds.x, bounds.y, bounds.width, bounds.height);
xAccessor.set(comp, bounds.x);
yAccessor.set(comp, bounds.y);
widthAccessor.set(comp, bounds.width);
......@@ -272,39 +274,54 @@ abstract class WindowMouseListener extends MouseAdapter implements MouseInputLis
}
public void addTo(Component comp) {
final Window window = comp instanceof Window ? (Window)comp : SwingUtilities.getWindowAncestor(comp);
if (window.getPeer() != null) {
addToImpl(window);
return;
}
if (methodsNotAvailable()) return;
final Window window = UIUtil.getWindow(comp);
if (window == null) return;
final boolean wasShown = getPeer(window) != null;
if (wasShown) addToImpl(window);
window.removeComponentListener(pendingListener);
window.addComponentListener(pendingListener = new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent event) {
window.removeComponentListener(pendingListener);
addToImpl(window);
if (!wasShown) addToImpl(window);
}
@Override
public void componentHidden(ComponentEvent e) {
window.removeComponentListener(this);
removeFrom(window);
}
});
}
public void removeFrom(Component comp) {
comp = comp instanceof Window ? comp : SwingUtilities.getWindowAncestor(comp);
if (comp.getPeer() != null) {
if (removeMouseListenerMethod == null || removeMouseMotionListenerMethod == null) return;
if (methodsNotAvailable()) return;
removeMouseListenerMethod.invoke(comp.getPeer(), myListener);
removeMouseMotionListenerMethod.invoke(comp.getPeer(), myListener);
}
else if (pendingListener != null){
comp.removeComponentListener(pendingListener);
comp = UIUtil.getWindow(comp);
if (getPeer(comp) != null) {
removeMouseListenerMethod.invoke(getPeer(comp), myListener);
removeMouseMotionListenerMethod.invoke(getPeer(comp), myListener);
}
if (comp != null) comp.removeComponentListener(pendingListener);
}
private void addToImpl(Component comp) {
if (addMouseListenerMethod == null || addMouseMotionListenerMethod == null) return;
if (methodsNotAvailable()) return;
addMouseListenerMethod.invoke(getPeer(comp), myListener);
addMouseMotionListenerMethod.invoke(getPeer(comp), myListener);
}
private boolean methodsNotAvailable() {
return removeMouseListenerMethod == null || removeMouseMotionListenerMethod == null;
}
addMouseListenerMethod.invoke(comp.getPeer(), myListener);
addMouseMotionListenerMethod.invoke(comp.getPeer(), myListener);
@Nullable
public static ComponentPeer getPeer(@Nullable Component comp) {
//noinspection deprecation
return comp == null ? null : comp.getPeer();
}
}
}
......@@ -19,7 +19,6 @@ package com.intellij.ui;
import com.intellij.openapi.progress.util.PotemkinProgress;
import org.jetbrains.annotations.ApiStatus;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
......@@ -74,13 +73,11 @@ public class WindowMoveListener extends WindowMouseListener {
*/
@ApiStatus.Experimental
public static class ToolkitListener extends WindowMoveListener {
private ToolkitListenerHelper myHelper;
private Window myAncestor;
private final ToolkitListenerHelper myHelper;
public ToolkitListener(Component content) {
super(content);
myHelper = new ToolkitListenerHelper(this);
myAncestor = SwingUtilities.getWindowAncestor(content);
}
@Override
......@@ -119,11 +116,7 @@ public class WindowMoveListener extends WindowMouseListener {
}
private boolean hitTest(MouseEvent e) {
Rectangle bounds = myContent.getBounds();
//bounds = SwingUtilities.convertRectangle(myContent, bounds, myAncestor); // [tav] todo: takes tree lock !!!
Point onScreen = myAncestor.getPeer().getLocationOnScreen();
Point inParent = ((JFrame)myAncestor).getRootPane().getLocation(); // temp
bounds.setLocation(onScreen.x + inParent.x, onScreen.y + inParent.y);
Rectangle bounds = getScreenBounds(myContent);
return bounds.contains(e.getLocationOnScreen());
}
......@@ -144,5 +137,17 @@ public class WindowMoveListener extends WindowMouseListener {
public void removeFrom(Component comp) {
myHelper.removeFrom(comp);
}
// tree lock free
private static Rectangle getScreenBounds(Component comp) {
Rectangle bounds = comp.getBounds();
Component ancestor = comp.getParent();
while (ancestor != null) {
Point loc = ancestor.getLocation();
bounds.setLocation(bounds.x + loc.x, bounds.y + loc.y);
ancestor = ancestor.getParent();
}
return bounds;
}
}
}
......@@ -17,10 +17,13 @@
package com.intellij.ui;
import com.intellij.util.ui.JBInsets;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.ApiStatus;
import javax.swing.Icon;
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.util.concurrent.atomic.AtomicReference;
import static java.awt.Cursor.*;
......@@ -172,13 +175,25 @@ public class WindowResizeListener extends WindowMouseListener {
*/
@ApiStatus.Experimental
public static class ToolkitListener extends WindowResizeListener {
private ToolkitListenerHelper myHelper;
private AtomicReference<Dimension> myMinSize = new AtomicReference<>(); // [tav] todo: update from EDT
private final ToolkitListenerHelper myHelper;
private final AtomicReference<Dimension> myMinSize = new AtomicReference<>();
public ToolkitListener(Component content, Insets border, Icon corner) {
super(content, border, corner);
myHelper = new ToolkitListenerHelper(this);
myMinSize.set(content.getMinimumSize());
Window window = UIUtil.getWindow(content);
if (window != null) window.addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent e) {
if (e.getID() == HierarchyEvent.HIERARCHY_CHANGED) {
myMinSize.set(content.getMinimumSize());
}
else if (e.getID() == HierarchyEvent.SHOWING_CHANGED && !window.isShowing()) {
window.removeHierarchyListener(this);
}
}
});
}
@Override
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment