feat: implement multi-seat support#758
Conversation
There was a problem hiding this comment.
Sorry @Dami-star, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Dami-star The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Pull request overview
This PR introduces multi-seat support across Waylib and Treeland, adding a seat manager + rule-based device assignment and updating focus/move-resize/event routing to be seat-aware.
Changes:
- Add
WSeatManagerto create/manage seats and apply regex rules for auto-assigning input devices. - Extend
WSeat/WInputDevicewith fallback/output tracking and device-identification helpers (name/path) used by matching. - Refactor Treeland surface focus and move/resize handling to maintain per-seat state via
SeatSurfaceContainerand per-seat event processing.
中文概述:
该 PR 为 Waylib 与 Treeland 引入多 seat 支持,新增 seat 管理与基于规则的设备分配,并将焦点、移动/缩放与事件处理改造成按 seat 维度管理。
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
waylib/src/server/protocols/winputmethodhelper.cpp |
Gate text-input enter by seat to avoid cross-seat focus delivery. |
waylib/src/server/kernel/wseatmanager.h |
New WSeatManager API for seat/config/rules. |
waylib/src/server/kernel/wseatmanager.cpp |
WSeatManager implementation (seat lifecycle, rule matching, config I/O). |
waylib/src/server/kernel/wseat.h |
Add fallback/output properties and device rule matching hooks. |
waylib/src/server/kernel/wseat.cpp |
Implement fallback/outputs/matching; harden handle null-paths. |
waylib/src/server/kernel/winputdevice.h |
Expose name() and devicePath() for rule matching. |
waylib/src/server/kernel/winputdevice.cpp |
Implement name() and devicePath() (libinput/udev + /proc fallback). |
waylib/src/server/kernel/wcursor.cpp |
Route pointer notifications to the device’s seat when available. |
waylib/src/server/kernel/private/wcursor_p.h |
Add helper for resolving device seat. |
waylib/src/server/kernel/device_info_parser.h |
New parser interface for /proc/bus/input/devices. |
waylib/src/server/kernel/device_info_parser.cpp |
Implementation of /proc parsing cache for physical path lookup. |
waylib/src/server/kernel/WSeatManager |
Public include wrapper for WSeatManager. |
waylib/src/server/CMakeLists.txt |
Build integration for new seat manager + device info parser sources/headers. |
src/surface/seatsurfacecontainer.h |
New per-seat surface state container (focus, move/resize, meta state). |
src/surface/seatsurfacecontainer.cpp |
Implement per-seat activation/focus/move-resize state transitions. |
src/seat/helper.h |
Add multi-seat APIs, caches, and new seat-related helpers. |
src/seat/helper.cpp |
Wire in WSeatManager, seat config load/save, per-seat focus/event routing. |
src/input/inputdevice.cpp |
Add null checks before touchpad initialization. |
src/core/rootsurfacecontainer.h |
Introduce per-seat container map + per-seat move/resize/activation APIs. |
src/core/rootsurfacecontainer.cpp |
Implement per-seat state management and per-seat request handlers. |
src/CMakeLists.txt |
Add new SeatSurfaceContainer sources to the QML module build. |
879d306 to
935ccd2
Compare
There was a problem hiding this comment.
Sorry @Dami-star, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
95a903b to
1f42846
Compare
1f42846 to
c9a86a6
Compare
| } | ||
| m_seat = defaultSeat; | ||
| m_seatManager->addDeviceRule("seat0", "1:.*"); // Keyboard devices | ||
| m_seatManager->addDeviceRule("seat0", "2:.*"); // Pointer devices |
There was a problem hiding this comment.
enum class Type {
Unknow, // 0
Keyboard, // 1
Pointer, // 2
Touch, // 3
Tablet, // 4
TabletPad, // 5
Switch // 6
};
"1:." = Keyboard 设备 (类型1) + 匹配所有名称 (.)
"2:." = Pointer 设备 (类型2,即鼠标/触摸板) + 匹配所有名称 (.)
"3:." = Touch 设备 (类型3,即触摸屏) + 匹配所有名称 (.)
There was a problem hiding this comment.
不好理解,写成 QString::number(static_cast(WInputDevice::Keyboard)) 好了
Core features: - Add WSeatManager for seat configuration management - Extend WSeat with device rule matching capabilities
c9a86a6 to
bc5864d
Compare
|
TAG Bot New tag: 0.8.5 |
| } | ||
| m_seat = defaultSeat; | ||
| m_seatManager->addDeviceRule("seat0", "1:.*"); // Keyboard devices | ||
| m_seatManager->addDeviceRule("seat0", "2:.*"); // Pointer devices |
There was a problem hiding this comment.
不好理解,写成 QString::number(static_cast(WInputDevice::Keyboard)) 好了
| activateSurface(nullptr, Qt::OtherFocusReason); | ||
| WSeat *eventSeat = getSeatForEvent(event); | ||
| if (eventSeat) { | ||
| if (auto *seatContainer = m_rootSurfaceContainer->getSeatContainer(eventSeat)) { |
| } | ||
|
|
||
| if (m_activatedSurface) | ||
| if (m_activatedSurface && m_activatedSurface->shellSurface()) |
| QString deviceName = device->name(); | ||
| WInputDevice::Type deviceType = device->type(); | ||
|
|
||
| if (deviceType == WInputDevice::Type::Pointer && deviceName.contains("Keyboard", Qt::CaseInsensitive)) { |
| } | ||
|
|
||
| if (deviceType == WInputDevice::Type::Keyboard && | ||
| (deviceName.contains("Mouse", Qt::CaseInsensitive) || deviceName.contains("Touchpad", Qt::CaseInsensitive))) { |
| } | ||
| } | ||
|
|
||
| QList<WOutput*> WSeat::outputs() const |
There was a problem hiding this comment.
单纯在这里放个outputs仅仅作为存储没有意义呀,真实对outputs有控制权的是WOoutputRenderWindow,这个seat只处理input设备就行了,不要做成了完成多seat业务逻辑的类,把哪些input和output设备集合到一个seat里,应该在上层(比如treeland)自己完成。
这里的wseat其实是个 input seat的概念,woutputrenderwindow则对应output seat,把input seat 和 output seat 关联到一起时treeland的事情,再怎么样也不应该是wseat的事情。
| m_seats.clear(); | ||
| m_deviceRules.clear(); | ||
|
|
||
| for (WSeat* seat : seatsToDelete) { |
There was a problem hiding this comment.
std::as_const,搜一下这个pr里所有用到for的地方,逐个检查这个问题,我没办法每一个都标注出来。
| WSeatManager::~WSeatManager() | ||
| { | ||
| QList<WSeat*> seatsToDelete = m_seats.values(); | ||
| m_seats.clear(); |
There was a problem hiding this comment.
不要这样,用 seatsToDelete.swap(m_seats);
| m_fallbackSeatName = name; | ||
| for (auto it = m_seats.begin(); it != m_seats.end(); ++it) { | ||
| if (it.key() != name && it.value()->isFallback()) { | ||
| it.value()->setIsFallback(false); |
There was a problem hiding this comment.
只是为了有一个seat是default的吗?这样的话这个属性不应该存到 WSeat里,应该在WSeatManager里有个 defaultSeat 的方法自己管理起来。
|
|
||
| class WInputDevice; | ||
|
|
||
| class WAYLIB_SERVER_EXPORT WSeatManager : public QObject, public WServerInterface |
There was a problem hiding this comment.
这个类看着在waylib里并没有用到?是不是可以放到treeland里,waylib里不用把多seat的能力做多少封装,只要waylib的实现够灵活,不阻塞treeland实现多seat的功能就行。
Core features: