IDEA-106300 Sometimes PhpStorm doesn't exit rectangular selection mode on escape.

This reverts commit 05a1415 and applies a different fix for the original issue (IDEA-53663) -basically, now we just won't invoke 'mouse shortcut'-bound actions when mouse is released after a drag operation.
This commit is contained in:
Dmitry Batrak
2013-12-12 12:31:19 +04:00
parent fec130431b
commit 726132325d
3 changed files with 89 additions and 2 deletions
@@ -17,7 +17,6 @@ package com.intellij.openapi.editor.impl;
import com.intellij.Patches;
import com.intellij.application.options.OptionsConstants;
import com.intellij.codeInsight.daemon.GutterMark;
import com.intellij.codeInsight.hint.DocumentFragmentTooltipRenderer;
import com.intellij.codeInsight.hint.EditorFragmentComponent;
import com.intellij.codeInsight.hint.TooltipController;
@@ -4143,7 +4142,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (isColumnMode() || e.isAltDown()) {
final LogicalPosition blockStart = selectionModel.hasBlockSelection() ? selectionModel.getBlockStart() : oldLogicalCaret;
selectionModel.setBlockSelection(blockStart, getCaretModel().getLogicalPosition());
IdeEventQueue.getInstance().blockNextEvents(e); // don't process action on mouse released (IDEA-53663)
}
else {
if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) {
@@ -56,6 +56,7 @@ public final class IdeMouseEventDispatcher {
private final ArrayList<AnAction> myActions = new ArrayList<AnAction>(1);
private final Map<Container, Integer> myRootPane2BlockedId = new HashMap<Container, Integer>();
private int myLastHorScrolledComponentHash = 0;
private MouseEvent myPreviousMouseEvent;
// Don't compare MouseEvent ids. Swing has wrong sequence of events: first is mouse_clicked(500)
// then mouse_pressed(501), mouse_released(502) etc. Here, mouse events sorted so we can compare
@@ -125,6 +126,9 @@ public final class IdeMouseEventDispatcher {
* to normal event dispatching.
*/
public boolean dispatchMouseEvent(MouseEvent e) {
MouseEvent previousEvent = myPreviousMouseEvent;
myPreviousMouseEvent = e;
Component c = e.getComponent();
//frame activation by mouse click
@@ -160,6 +164,10 @@ public final class IdeMouseEventDispatcher {
ignore = true;
}
if (e.getID() == MOUSE_RELEASED && previousEvent != null && previousEvent.getID() == MOUSE_DRAGGED) {
ignore = true; // we don't want to process action bindings on mouse release at the end of drag operation
}
final JRootPane root = findRoot(e);
if (root != null) {
final Integer lastId = myRootPane2BlockedId.get(root);
@@ -0,0 +1,81 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.keymap.impl;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.MouseShortcut;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.testFramework.LightPlatformTestCase;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
public class IdeMouseEventDispatcherTest extends LightPlatformTestCase {
private static final String OUR_TEST_ACTION = "IdeMouseEventDispatcherTestAction";
private Component myEventSource;
private int myActionExecutionCount;
public void setUp() throws Exception {
super.setUp();
ActionManager.getInstance().registerAction(OUR_TEST_ACTION, new EmptyAction());
KeymapManager.getInstance().getActiveKeymap().addShortcut(OUR_TEST_ACTION, new MouseShortcut(MouseEvent.BUTTON2, 0, 1));
myEventSource = new JPanel();
myEventSource.setSize(1,1);
}
@Override
public void tearDown() throws Exception {
KeymapManager.getInstance().getActiveKeymap().removeShortcut(OUR_TEST_ACTION, new MouseShortcut(MouseEvent.BUTTON2, 0, 1));
ActionManager.getInstance().unregisterAction(OUR_TEST_ACTION);
super.tearDown();
}
public void testActionTriggering() throws Exception {
IdeMouseEventDispatcher dispatcher = new IdeMouseEventDispatcher();
assertFalse(dispatcher.dispatchMouseEvent(new MouseEvent(myEventSource, MouseEvent.MOUSE_PRESSED, 0, 0, 0, 0, 1, false, MouseEvent.BUTTON2)));
assertTrue(dispatcher.dispatchMouseEvent(new MouseEvent(myEventSource, MouseEvent.MOUSE_RELEASED, 0, 0, 0, 0, 1, false, MouseEvent.BUTTON2)));
assertFalse(dispatcher.dispatchMouseEvent(new MouseEvent(myEventSource, MouseEvent.MOUSE_CLICKED, 0, 0, 0, 0, 1, false, MouseEvent.BUTTON2)));
assertEquals(1, myActionExecutionCount);
}
public void testActionSuppressionAfterDrag() throws Exception {
IdeMouseEventDispatcher dispatcher = new IdeMouseEventDispatcher();
assertFalse(dispatcher.dispatchMouseEvent(new MouseEvent(myEventSource, MouseEvent.MOUSE_PRESSED, 0, 0, 0, 0, 1, false, MouseEvent.BUTTON2)));
assertFalse(dispatcher.dispatchMouseEvent(new MouseEvent(myEventSource, MouseEvent.MOUSE_DRAGGED, 0, 0, 0, 0, 0, false, MouseEvent.BUTTON2)));
assertFalse(dispatcher.dispatchMouseEvent(new MouseEvent(myEventSource, MouseEvent.MOUSE_RELEASED, 0, 0, 0, 0, 1, false, MouseEvent.BUTTON2)));
assertEquals(0, myActionExecutionCount);
}
private class EmptyAction extends AnAction {
private EmptyAction() {
setEnabledInModalContext(true);
}
@Override
public void actionPerformed(AnActionEvent e){
myActionExecutionCount++;
}
}
}