wasm: Fix tooltip visible

Fixes a problem where tooltips only worked for the first instance
activated.

(cherry picked from commit d69348ed4d659f9408ce74f3b08ee7e9104dde00)
Fixes: QTBUG-129234
Change-Id: I45619b1ca8001b74b148b98a8795000630dcacf7
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Even Oscar Andersen 2024-10-02 13:12:22 +02:00 committed by Morten Johan Sørvig
parent 9e22cd089e
commit 2bd01602dc
3 changed files with 136 additions and 12 deletions

View File

@ -42,10 +42,14 @@ void QWasmWindowTreeNode::onSubtreeChanged(QWasmWindowTreeNodeChangeType changeT
&& m_childStack.topWindow()
&& m_childStack.topWindow()->window()) {
const auto flags = m_childStack.topWindow()->window()->flags();
const bool notToolOrPopup = ((flags & Qt::ToolTip) != Qt::ToolTip) && ((flags & Qt::Popup) != Qt::Popup);
const QVariant showWithoutActivating = m_childStack.topWindow()->window()->property("_q_showWithoutActivating");
if (!showWithoutActivating.isValid() || !showWithoutActivating.toBool())
if (!showWithoutActivating.isValid() || !showWithoutActivating.toBool()) {
if (notToolOrPopup)
m_childStack.topWindow()->requestActivateWindow();
}
}
if (parentNode())
parentNode()->onSubtreeChanged(changeType, parent, child);

View File

@ -34,6 +34,13 @@ class WidgetTestCase(unittest.TestCase):
w0 = Widget(self._driver, "w0")
w0.show()
w0.showToolTip()
#
# Wait for tooltip to disappear
#
time.sleep(60)
#time.sleep(3600)
self.assertEqual(w0.hasFocus(), True)
w1 = Widget(self._driver, "w1")
@ -63,6 +70,35 @@ class WidgetTestCase(unittest.TestCase):
clearWidgets(self._driver)
#Looks weird, no asserts, the test is that
#the test itself finishes
def test_showContextMenu_doesNotDeadlock(self):
screen = Screen(self._driver, ScreenPosition.FIXED,
x=0, y=0, width=600, height=1200)
w0 = Widget(self._driver, "w0")
w0.show()
w0.showToolTip()
w1 = Widget(self._driver, "w1")
w1.setNoFocusShow()
w1.show()
w1.showToolTip()
w2 = Widget(self._driver, "w2")
w2.show()
w2.showToolTip()
w3 = Widget(self._driver, "w3")
w3.setNoFocusShow()
w3.show()
w3.showToolTip()
w3.activate();
w3.showToolTip();
clearWidgets(self._driver)
def test_window_resizing(self):
screen = Screen(self._driver, ScreenPosition.FIXED,
x=0, y=0, width=600, height=600)
@ -641,6 +677,19 @@ class Widget:
'''
)
def showContextMenu(self):
self.driver.execute_script(
f'''
instance.showContextMenuWidget('{self.name}');
'''
)
def showToolTip(self):
self.driver.execute_script(
f'''
instance.showToolTipWidget('{self.name}');
'''
)
class Window:
def __init__(self, parent=None, rect=None, title=None, element=None, visible=True, opengl=0):

View File

@ -16,6 +16,12 @@
#include <QApplication>
#include <QDialog>
#include <QSysInfo>
#include <QTreeView>
#include <QFileSystemModel>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QSpinBox>
#include <QToolTip>
#include <QOpenGLWindow>
#include <QOpenGLFunctions>
@ -46,6 +52,25 @@ class TestWidget : public QDialog
Q_OBJECT
};
// We override to be able to test that the contextMenu
// calls popup and not exec. Calling exec locks the
// test.
class TestSpinBox : public QSpinBox
{
Q_OBJECT
public:
TestSpinBox(QWidget *parent = nullptr) : QSpinBox(parent) { }
void ShowContextMenu()
{
QContextMenuEvent event(QContextMenuEvent::Reason::Mouse, QPoint(0, geometry().bottom()),
mapToGlobal(QPoint(0, geometry().bottom())), Qt::NoModifier);
contextMenuEvent(&event);
}
};
class TestWindow : public QRasterWindow, public TestWindowBase
{
Q_OBJECT
@ -378,10 +403,10 @@ public:
return nullptr;
}
QLineEdit *findEdit(const std::string &name)
TestSpinBox *findSpinBox(const std::string &name)
{
auto it = m_lineEdits.find(name);
if (it != m_lineEdits.end())
auto it = m_spinBoxes.find(name);
if (it != m_spinBoxes.end())
return it->second;
return nullptr;
}
@ -389,17 +414,45 @@ public:
void make(const std::string &name)
{
auto widget = std::make_shared<TestWidget>();
auto *lineEdit = new QLineEdit(widget.get());
widget->setWindowTitle("Dialog");
auto spinBox = new TestSpinBox(widget.get());
spinBox->setToolTip(QString(u"A ToolTip"));
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_spinBoxes[name] = spinBox;
}
void showContextMenu(const std::string &name)
{
TestSpinBox *spinBox = findSpinBox(name);
if (spinBox)
spinBox->ShowContextMenu();
}
void showToolTip(const std::string &name)
{
TestSpinBox *spinBox = findSpinBox(name);
if (spinBox)
QToolTip::showText(spinBox->mapToGlobal(QPoint(0, 0)), spinBox->toolTip());
}
void makeNative(const std::string &name)
{
auto widget = std::make_shared<TestWidget>();
widget->setWindowTitle("Dialog");
auto spinBox = new TestSpinBox(widget.get());
spinBox->setToolTip(QString(u"A ToolTip"));
widget->setMinimumSize(200, 200);
widget->setMaximumSize(200, 200);
widget->setGeometry(0, m_widgetY, 200, 200);
m_widgetY += 200;
m_widgets[name] = widget;
m_lineEdits[name] = lineEdit;
m_spinBoxes[name] = spinBox;
}
private:
@ -407,7 +460,7 @@ private:
static WidgetStorage * s_instance;
std::map<std::string, TestWidgetPtr> m_widgets;
std::map<std::string, QLineEdit *> m_lineEdits;
std::map<std::string, TestSpinBox *> m_spinBoxes;
int m_widgetY = 0;
};
@ -503,6 +556,21 @@ void createWidget(const std::string &name)
WidgetStorage::getInstance()->make(name);
}
void createNativeWidget(const std::string &name)
{
WidgetStorage::getInstance()->makeNative(name);
}
void showContextMenuWidget(const std::string &name)
{
WidgetStorage::getInstance()->showContextMenu(name);
}
void showToolTipWidget(const std::string &name)
{
WidgetStorage::getInstance()->showToolTip(name);
}
void setWidgetNoFocusShow(const std::string &name)
{
auto w = WidgetStorage::getInstance()->findWidget(name);
@ -520,9 +588,9 @@ void showWidget(const std::string &name)
void hasWidgetFocus(const std::string &name)
{
bool focus = false;
auto le = WidgetStorage::getInstance()->findEdit(name);
if (le)
focus = le->hasFocus();
auto spinBox = WidgetStorage::getInstance()->findSpinBox(name);
if (spinBox)
focus = spinBox->hasFocus();
emscripten::val::global("window").call<void>("hasWidgetFocusCallback",
emscripten::val(focus));
@ -678,6 +746,9 @@ EMSCRIPTEN_BINDINGS(qwasmwindow)
emscripten::function("getOpenGLColorAt_0_0", &getOpenGLColorAt_0_0);
emscripten::function("createWidget", &createWidget);
emscripten::function("createNativeWidget", &createNativeWidget);
emscripten::function("showContextMenuWidget", &showContextMenuWidget);
emscripten::function("showToolTipWidget", &showToolTipWidget);
emscripten::function("setWidgetNoFocusShow", &setWidgetNoFocusShow);
emscripten::function("showWidget", &showWidget);
emscripten::function("activateWidget", &activateWidget);