wasm: Qt::WA_ShowWithoutActivating was not respected
The Qt::WA_ShowWithoutActivating flag was not respected Added test in the part of the code that calls requestActivateWindow Added selenium focus test Fixes: QTBUG-122776 Change-Id: I1a248ed4352f86376d615a4cb7022e7ea095d4e7 Reviewed-by: Piotr Wierciński <piotr.wiercinski@qt.io>
This commit is contained in:
parent
edb8bac39b
commit
0737fca6b2
@ -39,8 +39,12 @@ void QWasmWindowTreeNode::onSubtreeChanged(QWasmWindowTreeNodeChangeType changeT
|
||||
QWasmWindowTreeNode *parent, QWasmWindow *child)
|
||||
{
|
||||
if (changeType == QWasmWindowTreeNodeChangeType::NodeInsertion && parent == this
|
||||
&& m_childStack.topWindow()) {
|
||||
m_childStack.topWindow()->requestActivateWindow();
|
||||
&& m_childStack.topWindow()
|
||||
&& m_childStack.topWindow()->window()) {
|
||||
|
||||
const QVariant showWithoutActivating = m_childStack.topWindow()->window()->property("_q_showWithoutActivating");
|
||||
if (!showWithoutActivating.isValid() || !showWithoutActivating.toBool())
|
||||
m_childStack.topWindow()->requestActivateWindow();
|
||||
}
|
||||
|
||||
if (parentNode())
|
||||
|
@ -12,6 +12,7 @@ qt_internal_add_test(tst_qwasmwindow_harness
|
||||
LIBRARIES
|
||||
Qt::Core
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
||||
|
||||
if(CMAKE_HOST_WIN32)
|
||||
|
@ -27,9 +27,45 @@ class WidgetTestCase(unittest.TestCase):
|
||||
self.addTypeEqualityFunc(Color, assert_colors_equal)
|
||||
self.addTypeEqualityFunc(Rect, assert_rects_equal)
|
||||
|
||||
def test_hasFocus_returnsFalse_whenSetNoFocusShowWasCalled(self):
|
||||
screen = Screen(self._driver, ScreenPosition.FIXED,
|
||||
x=0, y=0, width=600, height=1200)
|
||||
|
||||
w0 = Widget(self._driver, "w0")
|
||||
w0.show()
|
||||
self.assertEqual(w0.hasFocus(), True)
|
||||
|
||||
w1 = Widget(self._driver, "w1")
|
||||
w1.setNoFocusShow()
|
||||
w1.show()
|
||||
self.assertEqual(w0.hasFocus(), True)
|
||||
self.assertEqual(w1.hasFocus(), False)
|
||||
|
||||
w2 = Widget(self._driver, "w2")
|
||||
w2.show()
|
||||
self.assertEqual(w0.hasFocus(), False)
|
||||
self.assertEqual(w1.hasFocus(), False)
|
||||
self.assertEqual(w2.hasFocus(), True)
|
||||
|
||||
w3 = Widget(self._driver, "w3")
|
||||
w3.setNoFocusShow()
|
||||
w3.show()
|
||||
self.assertEqual(w0.hasFocus(), False)
|
||||
self.assertEqual(w1.hasFocus(), False)
|
||||
self.assertEqual(w2.hasFocus(), True)
|
||||
self.assertEqual(w3.hasFocus(), False)
|
||||
w3.activate();
|
||||
self.assertEqual(w0.hasFocus(), False)
|
||||
self.assertEqual(w1.hasFocus(), False)
|
||||
self.assertEqual(w2.hasFocus(), False)
|
||||
self.assertEqual(w3.hasFocus(), True)
|
||||
|
||||
clearWidgets(self._driver)
|
||||
|
||||
def test_window_resizing(self):
|
||||
screen = Screen(self._driver, ScreenPosition.FIXED,
|
||||
x=0, y=0, width=600, height=600)
|
||||
|
||||
window = Window(parent=screen, rect=Rect(x=100, y=100, width=200, height=200))
|
||||
self.assertEqual(window.rect, Rect(x=100, y=100, width=200, height=200))
|
||||
|
||||
@ -527,6 +563,48 @@ class Screen:
|
||||
shadow_container = self.element.find_element(By.CSS_SELECTOR, f'#qt-shadow-container')
|
||||
return shadow_container.shadow_root.find_element(method, query)
|
||||
|
||||
def clearWidgets(driver):
|
||||
driver.execute_script(
|
||||
f'''
|
||||
instance.clearWidgets();
|
||||
'''
|
||||
)
|
||||
|
||||
class Widget:
|
||||
def __init__(self, driver, name):
|
||||
self.name=name
|
||||
self.driver=driver
|
||||
|
||||
self.driver.execute_script(
|
||||
f'''
|
||||
instance.createWidget('{self.name}');
|
||||
'''
|
||||
)
|
||||
|
||||
def setNoFocusShow(self):
|
||||
self.driver.execute_script(
|
||||
f'''
|
||||
instance.setWidgetNoFocusShow('{self.name}');
|
||||
'''
|
||||
)
|
||||
|
||||
def show(self):
|
||||
self.driver.execute_script(
|
||||
f'''
|
||||
instance.showWidget('{self.name}');
|
||||
'''
|
||||
)
|
||||
def hasFocus(self):
|
||||
focus = call_instance_function_arg(self.driver, 'hasWidgetFocus', self.name)
|
||||
return focus
|
||||
|
||||
def activate(self):
|
||||
self.driver.execute_script(
|
||||
f'''
|
||||
instance.activateWidget('{self.name}');
|
||||
'''
|
||||
)
|
||||
|
||||
|
||||
class Window:
|
||||
def __init__(self, parent=None, rect=None, title=None, element=None, visible=True):
|
||||
@ -815,6 +893,13 @@ def call_instance_function(driver, name):
|
||||
instance.{name}();
|
||||
return eval(result);''')
|
||||
|
||||
def call_instance_function_arg(driver, name, arg):
|
||||
return driver.execute_script(
|
||||
f'''let result;
|
||||
window.{name}Callback = data => result = data;
|
||||
instance.{name}('{arg}');
|
||||
return eval(result);''')
|
||||
|
||||
def wait_for_animation_frame(driver):
|
||||
driver.execute_script(
|
||||
'''
|
||||
|
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtWidgets/qwidget.h>
|
||||
|
||||
#include <QtGui/qevent.h>
|
||||
#include <QtCore/qobject.h>
|
||||
@ -11,6 +12,10 @@
|
||||
#include <QtGui/qscreen.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtWidgets/qlineedit.h>
|
||||
#include <QApplication>
|
||||
#include <QDialog>
|
||||
#include <QSysInfo>
|
||||
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/bind.h>
|
||||
@ -20,6 +25,12 @@
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
class TestWidget : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
};
|
||||
|
||||
|
||||
class TestWindow : public QRasterWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -76,6 +87,71 @@ TestWindow *findWindowByTitle(const std::string &title)
|
||||
});
|
||||
return window_it == windows.end() ? nullptr : static_cast<TestWindow *>(*window_it);
|
||||
}
|
||||
|
||||
class WidgetStorage
|
||||
{
|
||||
private:
|
||||
~WidgetStorage()
|
||||
{
|
||||
}
|
||||
public:
|
||||
static WidgetStorage *getInstance()
|
||||
{
|
||||
if (!s_instance)
|
||||
{
|
||||
s_instance = new WidgetStorage();
|
||||
}
|
||||
return s_instance;
|
||||
}
|
||||
static void clearInstance()
|
||||
{
|
||||
delete s_instance;
|
||||
s_instance = nullptr;
|
||||
}
|
||||
|
||||
TestWidget *findWidget(const std::string &name)
|
||||
{
|
||||
auto it = m_widgets.find(name);
|
||||
if (it != m_widgets.end())
|
||||
return it->second.get();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QLineEdit *findEdit(const std::string &name)
|
||||
{
|
||||
auto it = m_lineEdits.find(name);
|
||||
if (it != m_lineEdits.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void make(const std::string &name)
|
||||
{
|
||||
auto widget = std::make_shared<TestWidget>();
|
||||
auto *lineEdit = new QLineEdit(widget.get());
|
||||
|
||||
widget->setMinimumSize(200, 200);
|
||||
widget->setMaximumSize(200, 200);
|
||||
widget->setGeometry(0, m_widgetY, 200, 200);
|
||||
m_widgetY += 200;
|
||||
|
||||
lineEdit->setText("Hello world");
|
||||
|
||||
m_widgets[name] = widget;
|
||||
m_lineEdits[name] = lineEdit;
|
||||
}
|
||||
|
||||
private:
|
||||
using TestWidgetPtr = std::shared_ptr<TestWidget>;
|
||||
|
||||
static WidgetStorage * s_instance;
|
||||
std::map<std::string, TestWidgetPtr> m_widgets;
|
||||
std::map<std::string, QLineEdit *> m_lineEdits;
|
||||
int m_widgetY = 0;
|
||||
};
|
||||
|
||||
WidgetStorage *WidgetStorage::s_instance = nullptr;
|
||||
|
||||
} // namespace
|
||||
|
||||
using namespace emscripten;
|
||||
@ -161,8 +237,50 @@ void screenInformation()
|
||||
emscripten::val(toJSArray(screensAsJsObjects)));
|
||||
}
|
||||
|
||||
void createWindow(int x, int y, int w, int h, std::string parentType, std::string parentId,
|
||||
std::string title)
|
||||
void createWidget(const std::string &name)
|
||||
{
|
||||
WidgetStorage::getInstance()->make(name);
|
||||
}
|
||||
|
||||
void setWidgetNoFocusShow(const std::string &name)
|
||||
{
|
||||
auto w = WidgetStorage::getInstance()->findWidget(name);
|
||||
if (w)
|
||||
w->setAttribute(Qt::WA_ShowWithoutActivating);
|
||||
}
|
||||
|
||||
void showWidget(const std::string &name)
|
||||
{
|
||||
auto w = WidgetStorage::getInstance()->findWidget(name);
|
||||
if (w)
|
||||
w->show();
|
||||
}
|
||||
|
||||
void hasWidgetFocus(const std::string &name)
|
||||
{
|
||||
bool focus = false;
|
||||
auto le = WidgetStorage::getInstance()->findEdit(name);
|
||||
if (le)
|
||||
focus = le->hasFocus();
|
||||
|
||||
emscripten::val::global("window").call<void>("hasWidgetFocusCallback",
|
||||
emscripten::val(focus));
|
||||
}
|
||||
|
||||
void activateWidget(const std::string &name)
|
||||
{
|
||||
auto w = WidgetStorage::getInstance()->findWidget(name);
|
||||
if (w)
|
||||
w->activateWindow();
|
||||
}
|
||||
|
||||
void clearWidgets()
|
||||
{
|
||||
WidgetStorage::clearInstance();
|
||||
}
|
||||
|
||||
void createWindow(int x, int y, int w, int h, const std::string &parentType, const std::string &parentId,
|
||||
const std::string &title)
|
||||
{
|
||||
QScreen *parentScreen = nullptr;
|
||||
QWindow *parentWindow = nullptr;
|
||||
@ -202,7 +320,7 @@ void createWindow(int x, int y, int w, int h, std::string parentType, std::strin
|
||||
window->setParent(parentWindow);
|
||||
}
|
||||
|
||||
void setWindowBackgroundColor(std::string title, int r, int g, int b)
|
||||
void setWindowBackgroundColor(const std::string &title, int r, int g, int b)
|
||||
{
|
||||
auto *window = findWindowByTitle(title);
|
||||
if (!window) {
|
||||
@ -225,7 +343,7 @@ void setWindowVisible(int windowId, bool visible) {
|
||||
(*window_it)->setVisible(visible);
|
||||
}
|
||||
|
||||
void setWindowParent(std::string windowTitle, std::string parentTitle)
|
||||
void setWindowParent(const std::string &windowTitle, const std::string &parentTitle)
|
||||
{
|
||||
QWindow *window = findWindowByTitle(windowTitle);
|
||||
if (!window) {
|
||||
@ -242,7 +360,7 @@ void setWindowParent(std::string windowTitle, std::string parentTitle)
|
||||
window->setParent(parent);
|
||||
}
|
||||
|
||||
bool closeWindow(std::string title)
|
||||
bool closeWindow(const std::string &title)
|
||||
{
|
||||
QWindow *window = findWindowByTitle(title);
|
||||
return window ? window->close() : false;
|
||||
@ -252,16 +370,24 @@ EMSCRIPTEN_BINDINGS(qwasmwindow)
|
||||
{
|
||||
emscripten::function("screenInformation", &screenInformation);
|
||||
emscripten::function("windowInformation", &windowInformation);
|
||||
|
||||
emscripten::function("createWindow", &createWindow);
|
||||
emscripten::function("setWindowVisible", &setWindowVisible);
|
||||
emscripten::function("setWindowParent", &setWindowParent);
|
||||
emscripten::function("closeWindow", &closeWindow);
|
||||
emscripten::function("setWindowBackgroundColor", &setWindowBackgroundColor);
|
||||
|
||||
emscripten::function("createWidget", &createWidget);
|
||||
emscripten::function("setWidgetNoFocusShow", &setWidgetNoFocusShow);
|
||||
emscripten::function("showWidget", &showWidget);
|
||||
emscripten::function("activateWidget", &activateWidget);
|
||||
emscripten::function("hasWidgetFocus", &hasWidgetFocus);
|
||||
emscripten::function("clearWidgets", &clearWidgets);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
QApplication app(argc, argv);
|
||||
|
||||
app.exec();
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user