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,7 +39,11 @@ void QWasmWindowTreeNode::onSubtreeChanged(QWasmWindowTreeNodeChangeType changeT
|
|||||||
QWasmWindowTreeNode *parent, QWasmWindow *child)
|
QWasmWindowTreeNode *parent, QWasmWindow *child)
|
||||||
{
|
{
|
||||||
if (changeType == QWasmWindowTreeNodeChangeType::NodeInsertion && parent == this
|
if (changeType == QWasmWindowTreeNodeChangeType::NodeInsertion && parent == this
|
||||||
&& m_childStack.topWindow()) {
|
&& 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();
|
m_childStack.topWindow()->requestActivateWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ qt_internal_add_test(tst_qwasmwindow_harness
|
|||||||
LIBRARIES
|
LIBRARIES
|
||||||
Qt::Core
|
Qt::Core
|
||||||
Qt::Gui
|
Qt::Gui
|
||||||
|
Qt::Widgets
|
||||||
)
|
)
|
||||||
|
|
||||||
if(CMAKE_HOST_WIN32)
|
if(CMAKE_HOST_WIN32)
|
||||||
|
@ -27,9 +27,45 @@ class WidgetTestCase(unittest.TestCase):
|
|||||||
self.addTypeEqualityFunc(Color, assert_colors_equal)
|
self.addTypeEqualityFunc(Color, assert_colors_equal)
|
||||||
self.addTypeEqualityFunc(Rect, assert_rects_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):
|
def test_window_resizing(self):
|
||||||
screen = Screen(self._driver, ScreenPosition.FIXED,
|
screen = Screen(self._driver, ScreenPosition.FIXED,
|
||||||
x=0, y=0, width=600, height=600)
|
x=0, y=0, width=600, height=600)
|
||||||
|
|
||||||
window = Window(parent=screen, rect=Rect(x=100, y=100, width=200, height=200))
|
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))
|
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')
|
shadow_container = self.element.find_element(By.CSS_SELECTOR, f'#qt-shadow-container')
|
||||||
return shadow_container.shadow_root.find_element(method, query)
|
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:
|
class Window:
|
||||||
def __init__(self, parent=None, rect=None, title=None, element=None, visible=True):
|
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}();
|
instance.{name}();
|
||||||
return eval(result);''')
|
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):
|
def wait_for_animation_frame(driver):
|
||||||
driver.execute_script(
|
driver.execute_script(
|
||||||
'''
|
'''
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
#include <QtCore/QEvent>
|
#include <QtCore/QEvent>
|
||||||
|
#include <QtWidgets/qwidget.h>
|
||||||
|
|
||||||
#include <QtGui/qevent.h>
|
#include <QtGui/qevent.h>
|
||||||
#include <QtCore/qobject.h>
|
#include <QtCore/qobject.h>
|
||||||
@ -11,6 +12,10 @@
|
|||||||
#include <QtGui/qscreen.h>
|
#include <QtGui/qscreen.h>
|
||||||
#include <QtGui/qwindow.h>
|
#include <QtGui/qwindow.h>
|
||||||
#include <QtGui/qguiapplication.h>
|
#include <QtGui/qguiapplication.h>
|
||||||
|
#include <QtWidgets/qlineedit.h>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QSysInfo>
|
||||||
|
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
#include <emscripten/bind.h>
|
#include <emscripten/bind.h>
|
||||||
@ -20,6 +25,12 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class TestWidget : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class TestWindow : public QRasterWindow
|
class TestWindow : public QRasterWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -76,6 +87,71 @@ TestWindow *findWindowByTitle(const std::string &title)
|
|||||||
});
|
});
|
||||||
return window_it == windows.end() ? nullptr : static_cast<TestWindow *>(*window_it);
|
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
|
} // namespace
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
@ -161,8 +237,50 @@ void screenInformation()
|
|||||||
emscripten::val(toJSArray(screensAsJsObjects)));
|
emscripten::val(toJSArray(screensAsJsObjects)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void createWindow(int x, int y, int w, int h, std::string parentType, std::string parentId,
|
void createWidget(const std::string &name)
|
||||||
std::string title)
|
{
|
||||||
|
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;
|
QScreen *parentScreen = nullptr;
|
||||||
QWindow *parentWindow = 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);
|
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);
|
auto *window = findWindowByTitle(title);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
@ -225,7 +343,7 @@ void setWindowVisible(int windowId, bool visible) {
|
|||||||
(*window_it)->setVisible(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);
|
QWindow *window = findWindowByTitle(windowTitle);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
@ -242,7 +360,7 @@ void setWindowParent(std::string windowTitle, std::string parentTitle)
|
|||||||
window->setParent(parent);
|
window->setParent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool closeWindow(std::string title)
|
bool closeWindow(const std::string &title)
|
||||||
{
|
{
|
||||||
QWindow *window = findWindowByTitle(title);
|
QWindow *window = findWindowByTitle(title);
|
||||||
return window ? window->close() : false;
|
return window ? window->close() : false;
|
||||||
@ -252,16 +370,24 @@ EMSCRIPTEN_BINDINGS(qwasmwindow)
|
|||||||
{
|
{
|
||||||
emscripten::function("screenInformation", &screenInformation);
|
emscripten::function("screenInformation", &screenInformation);
|
||||||
emscripten::function("windowInformation", &windowInformation);
|
emscripten::function("windowInformation", &windowInformation);
|
||||||
|
|
||||||
emscripten::function("createWindow", &createWindow);
|
emscripten::function("createWindow", &createWindow);
|
||||||
emscripten::function("setWindowVisible", &setWindowVisible);
|
emscripten::function("setWindowVisible", &setWindowVisible);
|
||||||
emscripten::function("setWindowParent", &setWindowParent);
|
emscripten::function("setWindowParent", &setWindowParent);
|
||||||
emscripten::function("closeWindow", &closeWindow);
|
emscripten::function("closeWindow", &closeWindow);
|
||||||
emscripten::function("setWindowBackgroundColor", &setWindowBackgroundColor);
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
QGuiApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
app.exec();
|
app.exec();
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user