add FakeAccessibleInterface to fix crash of Youdao Dict

This commit is contained in:
Le Tan 2021-12-09 21:11:05 +08:00
parent b369612070
commit 301dace730
9 changed files with 181 additions and 6 deletions

View File

@ -12,4 +12,3 @@ For more information, please visit [**VNote's Home Page**](https://vnotex.github
### Windows Users
* if VNote hangs frequently or behaves unexpectedly in interface, please check the **OpenGL** option. [Details here](https://github.com/vnotex/vnote/issues/853).
* Please close *Youdao Dict* or disable its fetching-word feature.

View File

@ -12,4 +12,3 @@
## Windows用户
* 如果VNote经常卡顿或无响应或者界面异常请检查**OpenGL**选项。[详情](https://github.com/vnotex/vnote/issues/853)。
* 请关闭*有道词典*或者禁用其取词翻译功能。

106
src/fakeaccessible.cpp Normal file
View File

@ -0,0 +1,106 @@
#include "fakeaccessible.h"
#include <QAccessible>
#include <QDebug>
using namespace vnotex;
QAccessibleInterface *FakeAccessible::accessibleFactory(const QString &p_className, QObject *p_obj)
{
// Try to fix non-responsible issue caused by Youdao Dict.
if (p_className == QLatin1String("vnotex::LineEdit")
|| p_className == QLatin1String("vnotex::TitleBar")
|| p_className == QLatin1String("vnotex::NotebookSelector")
|| p_className == QLatin1String("vnotex::TagExplorer")
|| p_className == QLatin1String("vnotex::SearchPanel")
|| p_className == QLatin1String("vnotex::SnippetPanel")
|| p_className == QLatin1String("vnotex::OutlineViewer")
|| p_className == QLatin1String("vnotex::TitleToolBar")
|| p_className == QLatin1String("vnotex::MainWindow")
|| p_className == QLatin1String("vnotex::ViewArea")
|| p_className == QLatin1String("vte::VTextEdit")
|| p_className == QLatin1String("vte::IndicatorsBorder")
|| p_className == QLatin1String("vte::MarkdownEditor")
|| p_className == QLatin1String("vte::VMarkdownEditor")
|| p_className == QLatin1String("vte::VTextEditor")
|| p_className == QLatin1String("vte::ViStatusBar")
|| p_className == QLatin1String("vte::StatusIndicator")
|| p_className == QLatin1String("vte::ScrollBar")) {
return new FakeAccessibleInterface(p_obj);
}
return nullptr;
}
FakeAccessibleInterface::FakeAccessibleInterface(QObject *p_obj)
: m_object(p_obj)
{
}
QAccessibleInterface *FakeAccessibleInterface::child(int p_index) const
{
Q_UNUSED(p_index);
return nullptr;
}
QAccessibleInterface *FakeAccessibleInterface::childAt(int p_x, int p_y) const
{
Q_UNUSED(p_x);
Q_UNUSED(p_y);
return nullptr;
}
int FakeAccessibleInterface::childCount() const
{
return 0;
}
int FakeAccessibleInterface::indexOfChild(const QAccessibleInterface *p_child) const
{
Q_UNUSED(p_child);
return -1;
}
bool FakeAccessibleInterface::isValid() const
{
return false;
}
QObject *FakeAccessibleInterface::object() const
{
return m_object;
}
QAccessibleInterface *FakeAccessibleInterface::parent() const
{
return nullptr;
}
QRect FakeAccessibleInterface::rect() const
{
return QRect();
}
QAccessible::Role FakeAccessibleInterface::role() const
{
return QAccessible::NoRole;
}
void FakeAccessibleInterface::setText(QAccessible::Text p_t, const QString &p_text)
{
Q_UNUSED(p_t);
Q_UNUSED(p_text);
}
QAccessible::State FakeAccessibleInterface::state() const
{
QAccessible::State state;
state.disabled = true;
return state;
}
QString FakeAccessibleInterface::text(QAccessible::Text p_t) const
{
Q_UNUSED(p_t);
return QString();
}

53
src/fakeaccessible.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef FAKEACCESSIBLE_H
#define FAKEACCESSIBLE_H
#include <QAccessibleInterface>
class QObject;
class QString;
namespace vnotex
{
class FakeAccessible
{
public:
FakeAccessible() = delete;
static QAccessibleInterface *accessibleFactory(const QString &p_className, QObject *p_obj);
};
class FakeAccessibleInterface : public QAccessibleInterface
{
public:
FakeAccessibleInterface(QObject *p_obj);
QAccessibleInterface *child(int p_index) const Q_DECL_OVERRIDE;
QAccessibleInterface *childAt(int p_x, int p_y) const Q_DECL_OVERRIDE;
int childCount() const Q_DECL_OVERRIDE;
int indexOfChild(const QAccessibleInterface *p_child) const Q_DECL_OVERRIDE;
bool isValid() const Q_DECL_OVERRIDE;
QObject *object() const Q_DECL_OVERRIDE;
QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
QRect rect() const Q_DECL_OVERRIDE;
QAccessible::Role role() const Q_DECL_OVERRIDE;
void setText(QAccessible::Text p_t, const QString &p_text) Q_DECL_OVERRIDE;
QAccessible::State state() const Q_DECL_OVERRIDE;
QString text(QAccessible::Text p_t) const Q_DECL_OVERRIDE;
private:
QObject *m_object = nullptr;
};
}
#endif // FAKEACCESSIBLE_H

View File

@ -10,6 +10,7 @@
#include <QProcess>
#include <QWebEngineSettings>
#include <QWindow>
#include <QAccessible>
#include <core/configmgr.h>
#include <core/mainconfig.h>
@ -24,6 +25,7 @@
#include <widgets/messageboxhelper.h>
#include "commandlineoptions.h"
#include "application.h"
#include "fakeaccessible.h"
using namespace vnotex;
@ -74,6 +76,8 @@ int main(int argc, char *argv[])
initWebEngineSettings();
QAccessible::installFactory(&FakeAccessible::accessibleFactory);
{
const QString iconPath = ":/vnotex/data/core/icons/vnote.ico";
// Make sense only on Windows.

View File

@ -35,6 +35,7 @@ TRANSLATIONS += \
SOURCES += \
application.cpp \
commandlineoptions.cpp \
fakeaccessible.cpp \
main.cpp
INCLUDEPATH *= $$PWD
@ -151,4 +152,5 @@ unix:!macx {
HEADERS += \
application.h \
commandlineoptions.h
commandlineoptions.h \
fakeaccessible.h

View File

@ -103,7 +103,6 @@ bool ImportNotebookDialog::validateRootFolderInput(QString &p_msg)
tr("Not a valid (%1) root folder (%2).").arg(factory->getDisplayName(), rootFolderPath));
return false;
}
}
return true;

View File

@ -260,7 +260,7 @@ bool ManageNotebooksDialog::closeNotebook(const Notebook *p_notebook)
int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Question,
tr("Close notebook (%1)?")
.arg(p_notebook->getName()),
tr("The notebook could be opened by VNote again."),
tr("The notebook could be opened by VNote again via \"Open Other Notebooks\" operation."),
tr("Notebook location: %1").arg(p_notebook->getRootFolderAbsolutePath()),
this);
if (ret != QMessageBox::Ok) {

View File

@ -101,9 +101,10 @@ bool NewNotebookFromFolderDialog::validateRootFolderInput(QString &p_msg)
return false;
}
auto &notebookMgr = VNoteX::getInst().getNotebookMgr();
// Check if there already exists one notebook with the same root folder.
{
auto &notebookMgr = VNoteX::getInst().getNotebookMgr();
auto notebook = notebookMgr.findNotebookByRootFolderPath(rootFolderPath);
if (notebook) {
Utils::appendMsg(p_msg,
@ -112,6 +113,18 @@ bool NewNotebookFromFolderDialog::validateRootFolderInput(QString &p_msg)
}
}
// Warn if it is a valid bundle notebook root folder.
{
auto factory = notebookMgr.getBundleNotebookFactory();
auto backend = notebookMgr.createNotebookBackend(QStringLiteral("local.vnotex"), rootFolderPath);
if (factory->checkRootFolder(backend)) {
Utils::appendMsg(p_msg,
tr("The folder is likely to be the root folder of a valid bundle notebook. "
"You may want to use \"Open Other Notebooks\" to open it. "
"If continue, all existing information of the notebook may be lost."));
}
}
return true;
}