With this patch a modal window is always given focus on opening and in the situation when an above-lying window is closed. Change-Id: Ie13869830df13f411e4f14340745d501a1aabafatags/7.5.0.beta1
@@ -558,6 +558,21 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, | |||
w.bringToFrontSequence = -1; | |||
} | |||
} | |||
focusTopmostModalWindow(); | |||
} | |||
private static void focusTopmostModalWindow() { | |||
// If we call focus() directly without scheduling, it does not work in | |||
// IE and FF. | |||
Scheduler.get().scheduleDeferred(new ScheduledCommand() { | |||
@Override | |||
public void execute() { | |||
VWindow topmost = getTopmostWindow(); | |||
if ((topmost != null) && (topmost.vaadinModality)) { | |||
topmost.focus(); | |||
} | |||
} | |||
}); | |||
} | |||
@Override | |||
@@ -690,6 +705,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, | |||
while (curIndex < windowOrder.size()) { | |||
windowOrder.get(curIndex).setWindowOrder(curIndex++); | |||
} | |||
focusTopmostModalWindow(); | |||
} | |||
private void fixIE8FocusCaptureIssue() { |
@@ -0,0 +1,74 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* 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.vaadin.tests.components.window; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
import com.vaadin.ui.HorizontalLayout; | |||
import com.vaadin.ui.Window; | |||
public class ModalWindowFocus extends AbstractTestUI { | |||
@Override | |||
protected void setup(VaadinRequest req) { | |||
Button button = new Button("Open windows"); | |||
button.setId("firstButton"); | |||
addComponent(button); | |||
button.addClickListener(new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
Window w = new Window("This is first window"); | |||
w.setModal(true); | |||
addWindow(w); | |||
Window w2 = new Window("This is second window"); | |||
w2.setModal(true); | |||
addWindow(w2); | |||
HorizontalLayout lay = new HorizontalLayout(); | |||
Button buttonInWindow = new Button("Open window"); | |||
buttonInWindow.setId("windowButton"); | |||
lay.addComponent(buttonInWindow); | |||
w2.setContent(lay); | |||
buttonInWindow.addClickListener(new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent e) { | |||
Window w3 = new Window("This is third window"); | |||
w3.setModal(true); | |||
w3.setId("window3"); | |||
addWindow(w3); | |||
} | |||
}); | |||
} | |||
}); | |||
} | |||
@Override | |||
protected String getTestDescription() { | |||
return "Topmost modal window should be focused on opening " | |||
+ "and on closing an overlying window"; | |||
} | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 17021; | |||
} | |||
} |
@@ -0,0 +1,102 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* 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.vaadin.tests.components.window; | |||
import static org.junit.Assert.assertTrue; | |||
import java.io.IOException; | |||
import org.junit.Test; | |||
import org.openqa.selenium.Keys; | |||
import org.openqa.selenium.WebElement; | |||
import org.openqa.selenium.interactions.Actions; | |||
import com.vaadin.testbench.By; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
/** | |||
* Tests that a modal window is focused on creation and that on closing a window | |||
* focus is given to underlying modal window | |||
* | |||
* @author Vaadin Ltd | |||
*/ | |||
public class ModalWindowFocusTest extends MultiBrowserTest { | |||
@Override | |||
public void setup() throws Exception { | |||
super.setup(); | |||
openTestURL(); | |||
} | |||
/** | |||
* First scenario: press button -> two windows appear, press Esc two times | |||
* -> all windows should be closed | |||
*/ | |||
@Test | |||
public void testModalWindowFocusTwoWindows() throws IOException { | |||
waitForElementPresent(By.id("firstButton")); | |||
WebElement button = findElement(By.id("firstButton")); | |||
button.click(); | |||
waitForElementPresent(By.id("windowButton")); | |||
assertTrue("Second window should be opened", | |||
findElements(By.id("windowButton")).size() == 1); | |||
pressEscAndWait(); | |||
pressEscAndWait(); | |||
assertTrue("All windows should be closed", | |||
findElements(By.className("v-window")).size() == 0); | |||
} | |||
/** | |||
* Second scenario: press button -> two windows appear, press button in the | |||
* 2nd window -> 3rd window appears on top, press Esc three times -> all | |||
* windows should be closed | |||
*/ | |||
@Test | |||
public void testModalWindowFocusPressButtonInWindow() throws IOException { | |||
waitForElementPresent(By.id("firstButton")); | |||
WebElement button = findElement(By.id("firstButton")); | |||
button.click(); | |||
waitForElementPresent(By.id("windowButton")); | |||
WebElement buttonInWindow = findElement(By.id("windowButton")); | |||
buttonInWindow.click(); | |||
waitForElementPresent(By.id("window3")); | |||
assertTrue("Third window should be opened", | |||
findElements(By.id("window3")).size() == 1); | |||
pressEscAndWait(); | |||
pressEscAndWait(); | |||
pressEscAndWait(); | |||
assertTrue("All windows should be closed", | |||
findElements(By.className("v-window")).size() == 0); | |||
} | |||
private void pressEscAndWait() { | |||
new Actions(driver).sendKeys(Keys.ESCAPE).build().perform(); | |||
try { | |||
sleep(100); | |||
} catch (InterruptedException e) { | |||
} | |||
} | |||
} |