diff options
author | Mikolaj Boc <[email protected]> | 2023-02-22 09:50:54 +0100 |
---|---|---|
committer | Mikolaj Boc <[email protected]> | 2023-06-09 14:05:06 +0200 |
commit | a1704ee6aa07e8bca7a1c4cf965f40a8255ffbc8 (patch) | |
tree | d91d4decfef49233d4e24a4a00e96bf558a26501 | |
parent | 5d12d9846a9436b4ef4e1f8ac42d081d60568ecf (diff) |
Correctly focus WASM windows on show
Since first requestActivate may happen before the window div is
actually displayed on-screen, we need to sync Qt's activation state
with DOM as soon as DOM element becomes visible. Focusing an
invisible element is impossible.
Fixes: QTBUG-79934
Change-Id: I04cf9b4ead006c9b8b135b3b6967d7938c581833
Reviewed-by: Morten Johan Sørvig <[email protected]>
-rw-r--r-- | src/plugins/platforms/wasm/qwasmwindow.cpp | 2 | ||||
-rw-r--r-- | tests/manual/wasm/qwasmwindow/qwasmwindow.py | 41 | ||||
-rw-r--r-- | tests/manual/wasm/qwasmwindow/qwasmwindow_harness.cpp | 37 | ||||
-rw-r--r-- | tests/manual/wasm/qwasmwindow/qwasmwindow_harness.html | 8 |
4 files changed, 86 insertions, 2 deletions
diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index d1582d8801f..755a9ac930a 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -310,6 +310,8 @@ void QWasmWindow::setVisible(bool visible) m_compositor->requestUpdateWindow(this, QWasmCompositor::ExposeEventDelivery); m_qtWindow["style"].set("display", visible ? "block" : "none"); + if (window()->isActive()) + m_canvas.call<void>("focus"); if (visible) applyWindowState(); } diff --git a/tests/manual/wasm/qwasmwindow/qwasmwindow.py b/tests/manual/wasm/qwasmwindow/qwasmwindow.py index a80e394cc22..04e16112209 100644 --- a/tests/manual/wasm/qwasmwindow/qwasmwindow.py +++ b/tests/manual/wasm/qwasmwindow/qwasmwindow.py @@ -29,6 +29,7 @@ class WidgetTestCase(unittest.TestCase): screen = Screen(self._driver, ScreenPosition.FIXED, x=0, y=0, width=600, height=600) window = Window(screen, x=100, y=100, width=200, height=200) + window.set_visible(True) self.assertEqual(window.rect, Rect(x=100, y=100, width=200, height=200)) window.drag(Handle.TOP_LEFT, direction=UP(10) + LEFT(10)) @@ -62,6 +63,7 @@ class WidgetTestCase(unittest.TestCase): screen = Screen(self._driver, ScreenPosition.FIXED, x=200, y=200, width=300, height=300) window = Window(screen, x=300, y=300, width=100, height=100) + window.set_visible(True) self.assertEqual(window.rect, Rect(x=300, y=300, width=100, height=100)) frame_rect_before_resize = window.frame_rect @@ -76,6 +78,7 @@ class WidgetTestCase(unittest.TestCase): screen = Screen(self._driver, ScreenPosition.FIXED, x=200, y=200, width=300, height=300) window = Window(screen, x=300, y=300, width=100, height=100) + window.set_visible(True) self.assertEqual(window.rect, Rect(x=300, y=300, width=100, height=100)) window.drag(Handle.TOP_WINDOW_BAR, direction=UP(30)) @@ -91,6 +94,7 @@ class WidgetTestCase(unittest.TestCase): screen = Screen(self._driver, ScreenPosition.RELATIVE, x=200, y=200, width=300, height=300) window = Window(screen, x=300, y=300, width=100, height=100) + window.set_visible(True) self.assertEqual(window.rect, Rect(x=300, y=300, width=100, height=100)) window.drag(Handle.TOP_WINDOW_BAR, direction=LEFT(300)) @@ -102,6 +106,7 @@ class WidgetTestCase(unittest.TestCase): container_width=500, container_height=7000) screen.scroll_to() window = Window(screen, x=300, y=2100, width=100, height=100) + window.set_visible(True) self.assertEqual(window.rect, Rect(x=300, y=2100, width=100, height=100)) window.drag(Handle.TOP_WINDOW_BAR, direction=LEFT(300)) @@ -111,6 +116,7 @@ class WidgetTestCase(unittest.TestCase): screen = Screen(self._driver, ScreenPosition.RELATIVE, x=200, y=200, width=300, height=300) window = Window(screen, x=300, y=300, width=100, height=100, title='Maximize') + window.set_visible(True) self.assertEqual(window.rect, Rect(x=300, y=300, width=100, height=100)) window.maximize() @@ -122,6 +128,9 @@ class WidgetTestCase(unittest.TestCase): windows = [Window(screen, x=50, y=50, width=100, height=100, title='First'), Window(screen, x=400, y=400, width=100, height=100, title='Second'), Window(screen, x=50, y=400, width=100, height=100, title='Third')] + for window in windows: + window.set_visible(True) + self.assertEqual(windows[0].rect, Rect(x=50, y=50, width=100, height=100)) self.assertEqual(windows[1].rect, Rect(x=400, y=400, width=100, height=100)) self.assertEqual(windows[2].rect, Rect(x=50, y=400, width=100, height=100)) @@ -140,6 +149,9 @@ class WidgetTestCase(unittest.TestCase): windows = [Window(screen, x=50, y=50, width=150, height=150, title='First'), Window(screen, x=400, y=400, width=150, height=150, title='Second'), Window(screen, x=50, y=400, width=150, height=150, title='Third')] + for window in windows: + window.set_visible(True) + self.assertEqual(windows[0].rect, Rect(x=50, y=50, width=150, height=150)) self.assertEqual(windows[1].rect, Rect(x=400, y=400, width=150, height=150)) self.assertEqual(windows[2].rect, Rect(x=50, y=400, width=150, height=150)) @@ -152,6 +164,21 @@ class WidgetTestCase(unittest.TestCase): self.assertEqual(windows[1].rect, Rect(x=400, y=420, width=150, height=130)) self.assertEqual(windows[2].rect, Rect(x=50, y=400, width=170, height=130)) + def test_newly_created_window_gets_keyboard_focus(self): + screen = Screen(self._driver, ScreenPosition.FIXED, + x=0, y=0, width=800, height=800) + window = Window(screen, x=0, y=0, width=800, height=800, title='root') + window.set_visible(True) + + ActionChains(self._driver).key_down('c').key_up('c').perform() + + events = window.events + self.assertEqual(len(events), 2) + self.assertEqual(events[-2]['type'], 'keyPress') + self.assertEqual(events[-2]['key'], 'c') + self.assertEqual(events[-1]['type'], 'keyRelease') + self.assertEqual(events[-1]['key'], 'c') + def tearDown(self): self._driver.quit() @@ -227,6 +254,20 @@ class Window: geo = self.__window_information()["frameGeometry"] return Rect(geo['x'], geo['y'], geo['width'], geo['height']) + @property + def events(self): + events = self.driver.execute_script( + f''' + return testSupport.events(); + ''' + ) + return [*filter(lambda e: e['windowTitle'] == self.title, events)] + + def set_visible(self, visible): + info = self.__window_information() + self.driver.execute_script( + f'''instance.setWindowVisible({info['id']}, {'true' if visible else 'false'});''') + def drag(self, handle, direction): ActionChains(self.driver) \ .move_to_element_with_offset(self.element, *self.at(handle)['offset']) \ diff --git a/tests/manual/wasm/qwasmwindow/qwasmwindow_harness.cpp b/tests/manual/wasm/qwasmwindow/qwasmwindow_harness.cpp index 3a8f0693dfd..eda557e195f 100644 --- a/tests/manual/wasm/qwasmwindow/qwasmwindow_harness.cpp +++ b/tests/manual/wasm/qwasmwindow/qwasmwindow_harness.cpp @@ -2,6 +2,8 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include <QtCore/QEvent> + +#include <QtGui/qevent.h> #include <QtCore/qobject.h> #include <QtCore/qregularexpression.h> #include <QtGui/qscreen.h> @@ -26,6 +28,26 @@ private: Q_UNUSED(ev); delete this; } + + void keyPressEvent(QKeyEvent *event) final + { + auto data = emscripten::val::object(); + data.set("type", emscripten::val("keyPress")); + data.set("windowId", emscripten::val(winId())); + data.set("windowTitle", emscripten::val(title().toStdString())); + data.set("key", emscripten::val(event->text().toStdString())); + emscripten::val::global("window")["testSupport"].call<void>("reportEvent", std::move(data)); + } + + void keyReleaseEvent(QKeyEvent *event) final + { + auto data = emscripten::val::object(); + data.set("type", emscripten::val("keyRelease")); + data.set("windowId", emscripten::val(winId())); + data.set("windowTitle", emscripten::val(title().toStdString())); + data.set("key", emscripten::val(event->text().toStdString())); + emscripten::val::global("window")["testSupport"].call<void>("reportEvent", std::move(data)); + } }; using namespace emscripten; @@ -128,7 +150,19 @@ void createWindow(int x, int y, int w, int h, std::string screenId, std::string window->setTitle(QString::fromLatin1(title)); window->setGeometry(x, y, w, h); window->setScreen(*screen_it); - window->showNormal(); +} + +void setWindowVisible(int windowId, bool visible) { + auto windows = qGuiApp->allWindows(); + auto window_it = std::find_if(windows.begin(), windows.end(), [windowId](QWindow *window) { + return window->winId() == WId(windowId); + }); + if (window_it == windows.end()) { + qWarning() << "No such window: " << windowId; + return; + } + + (*window_it)->setVisible(visible); } EMSCRIPTEN_BINDINGS(qwasmwindow) @@ -136,6 +170,7 @@ EMSCRIPTEN_BINDINGS(qwasmwindow) emscripten::function("screenInformation", &screenInformation); emscripten::function("windowInformation", &windowInformation); emscripten::function("createWindow", &createWindow); + emscripten::function("setWindowVisible", &setWindowVisible); } int main(int argc, char **argv) diff --git a/tests/manual/wasm/qwasmwindow/qwasmwindow_harness.html b/tests/manual/wasm/qwasmwindow/qwasmwindow_harness.html index 9eb82618b9c..8d73160ed82 100644 --- a/tests/manual/wasm/qwasmwindow/qwasmwindow_harness.html +++ b/tests/manual/wasm/qwasmwindow/qwasmwindow_harness.html @@ -11,6 +11,8 @@ testSandbox.id = 'test-sandbox'; document.body.appendChild(testSandbox); + const eventList = []; + const makeSizedDiv = (left, top, width, height) => { const screenDiv = document.createElement('div'); @@ -56,7 +58,11 @@ instance.qtAddContainerElement(screenDiv); return [scrollContainer, screenDiv]; - } + }, + reportEvent: event => { + eventList.push(event); + }, + events: () => eventList }; })(); </script> |