QGuiApplication的实现类QGuiApplicationPrivate方法processWindowSystemEvent处理window系统事件
static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
在QWindowSystemInterface的处理事件方法中会调用上面的processWindowSystemEvent方法
flushWindowSystemEvents发送消息
QT_DEFINE_QPA_EVENT_HANDLER
定义为
#define QT_DEFINE_QPA_EVENT_HANDLER(ReturnType, HandlerName, ...) \
template Q_GUI_EXPORT ReturnType QWindowSystemInterface::HandlerName<QWindowSystemInterface::DefaultDelivery>(__VA_ARGS__); \
template Q_GUI_EXPORT ReturnType QWindowSystemInterface::HandlerName<QWindowSystemInterface::SynchronousDelivery>(__VA_ARGS__); \
template Q_GUI_EXPORT ReturnType QWindowSystemInterface::HandlerName<QWindowSystemInterface::AsynchronousDelivery>(__VA_ARGS__); \
template<typename Delivery> ReturnType QWindowSystemInterface::HandlerName(__VA_ARGS__)
QGuiApplication初始化时会加载QGeneralPlugin
- 键盘对应 QEvdevKeyboardPlugin,创建QEvdevKeyboardManager
QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specification, QObject *parent)
: QObject(parent), m_x(0), m_y(0), m_xoffset(0), m_yoffset(0)
{
Q_UNUSED(key);
QString spec = QString::fromLocal8Bit(qgetenv("QT_QPA_EVDEV_MOUSE_PARAMETERS"));
if (spec.isEmpty())
spec = specification;
auto parsed = QEvdevUtil::parseSpecification(spec);
m_spec = std::move(parsed.spec);
for (const QStringRef &arg : qAsConst(parsed.args)) {
if (arg.startsWith(QLatin1String("xoffset="))) {
m_xoffset = arg.mid(8).toInt();
} else if (arg.startsWith(QLatin1String("yoffset="))) {
m_yoffset = arg.mid(8).toInt();
}
}
// add all mice for devices specified in the argument list
for (const QString &device : qAsConst(parsed.devices))
addMouse(device);
if (parsed.devices.isEmpty()) {
qCDebug(qLcEvdevMouse, "evdevmouse: Using device discovery");
if (auto deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse | QDeviceDiscovery::Device_Touchpad, this)) {
// scan and add already connected keyboards
const QStringList devices = deviceDiscovery->scanConnectedDevices();
for (const QString &device : devices)
addMouse(device);
connect(deviceDiscovery, &QDeviceDiscovery::deviceDetected,
this, &QEvdevMouseManager::addMouse);
connect(deviceDiscovery, &QDeviceDiscovery::deviceRemoved,
this, &QEvdevMouseManager::removeMouse);
}
}
QInputDeviceManager *manager = QGuiApplicationPrivate::inputDeviceManager();
connect(manager, &QInputDeviceManager::cursorPositionChangeRequested, [this](const QPoint &pos) {
m_x = pos.x();
m_y = pos.y();
clampPosition();
});
}
addMouse会创建QEvdevMouseHandler打开设备,并且根据文件描述符创建QSocketNotifier注册到事件分发器中
将QEvdevMouseHandler的鼠标信号与QEvdevMouseManager对应的槽函数建立联系,信号触发时,对应的槽函数会调用,执行QWindowSystemInterface的事件处理函数,将事件转化为QEvent
- 鼠标对应 QEvdevMousePlugin
QPA
qt的平台抽象,window实现代码在plugins/platforms/window下
判断window的事件函数为
QtWindows::WindowEventType windowEventType(UINT message, WPARAM wParam, LPARAM lParam);
QWindowsContext的windowsProc处理事件,其实现类为QWindowsContextPrivate
struct QWindowsContextPrivate {
QWindowsContextPrivate();
unsigned m_systemInfo = 0;
QSet<QString> m_registeredWindowClassNames;
HandleBaseWindowHash m_windows;
HDC m_displayContext = nullptr;
int m_defaultDPI = 96;
QWindowsKeyMapper m_keyMapper;
QWindowsMouseHandler m_mouseHandler;
QWindowsPointerHandler m_pointerHandler;
QWindowsMimeConverter m_mimeConverter;
QWindowsScreenManager m_screenManager;
QSharedPointer<QWindowCreationContext> m_creationContext;
#if QT_CONFIG(tabletevent)
QScopedPointer<QWindowsTabletSupport> m_tabletSupport;
#endif
const HRESULT m_oleInitializeResult;
QWindow *m_lastActiveWindow = nullptr;
bool m_asyncExpose = false;
HPOWERNOTIFY m_powerNotification = nullptr;
HWND m_powerDummyWindow = nullptr;
};
m_mouseHandler:将windows事件转换为Qt的鼠标事件