Skip to content

feat: implement multi-seat support#758

Open
Dami-star wants to merge 1 commit intolinuxdeepin:masterfrom
Dami-star:multi-seat-new
Open

feat: implement multi-seat support#758
Dami-star wants to merge 1 commit intolinuxdeepin:masterfrom
Dami-star:multi-seat-new

Conversation

@Dami-star
Copy link
Collaborator

Core features:

  • Add WSeatManager for seat configuration management
  • Extend WSeat with device rule matching capabilities

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Dami-star, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot
Copy link

[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.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@Dami-star Dami-star marked this pull request as draft March 3, 2026 08:34
@wineee wineee requested a review from Copilot March 3, 2026 08:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 WSeatManager to create/manage seats and apply regex rules for auto-assigning input devices.
  • Extend WSeat/WInputDevice with 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 SeatSurfaceContainer and 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.

@Dami-star Dami-star force-pushed the multi-seat-new branch 2 times, most recently from 879d306 to 935ccd2 Compare March 4, 2026 06:44
@Dami-star Dami-star marked this pull request as ready for review March 4, 2026 06:53
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Dami-star, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@wineee wineee requested a review from Copilot March 4, 2026 07:06
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 8 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 8 comments.

Copy link
Member

@zccrs zccrs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还没看完

}
m_seat = defaultSeat;
m_seatManager->addDeviceRule("seat0", "1:.*"); // Keyboard devices
m_seatManager->addDeviceRule("seat0", "2:.*"); // Pointer devices
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这些1 2 3 是啥意思?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,即触摸屏) + 匹配所有名称 (.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不好理解,写成 QString::number(static_cast(WInputDevice::Keyboard)) 好了

Core features:
  - Add WSeatManager for seat configuration management
  - Extend WSeat with device rule matching capabilities
@deepin-bot
Copy link

deepin-bot bot commented Mar 6, 2026

TAG Bot

New tag: 0.8.5
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #771

@Dami-star Dami-star requested a review from zccrs March 9, 2026 01:30
}
m_seat = defaultSeat;
m_seatManager->addDeviceRule("seat0", "1:.*"); // Keyboard devices
m_seatManager->addDeviceRule("seat0", "2:.*"); // Pointer devices
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不好理解,写成 QString::number(static_cast(WInputDevice::Keyboard)) 好了

activateSurface(nullptr, Qt::OtherFocusReason);
WSeat *eventSeat = getSeatForEvent(event);
if (eventSeat) {
if (auto *seatContainer = m_rootSurfaceContainer->getSeatContainer(eventSeat)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不同的seat是用的不同的container吗?

}

if (m_activatedSurface)
if (m_activatedSurface && m_activatedSurface->shellSurface())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为什么不在 setActivate里判断shellSurface

QString deviceName = device->name();
WInputDevice::Type deviceType = device->type();

if (deviceType == WInputDevice::Type::Pointer && deviceName.contains("Keyboard", Qt::CaseInsensitive)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是啥情况?

}

if (deviceType == WInputDevice::Type::Keyboard &&
(deviceName.contains("Mouse", Qt::CaseInsensitive) || deviceName.contains("Touchpad", Qt::CaseInsensitive))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

}
}

QList<WOutput*> WSeat::outputs() const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

单纯在这里放个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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::as_const,搜一下这个pr里所有用到for的地方,逐个检查这个问题,我没办法每一个都标注出来。

WSeatManager::~WSeatManager()
{
QList<WSeat*> seatsToDelete = m_seats.values();
m_seats.clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不要这样,用 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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

只是为了有一个seat是default的吗?这样的话这个属性不应该存到 WSeat里,应该在WSeatManager里有个 defaultSeat 的方法自己管理起来。


class WInputDevice;

class WAYLIB_SERVER_EXPORT WSeatManager : public QObject, public WServerInterface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个类看着在waylib里并没有用到?是不是可以放到treeland里,waylib里不用把多seat的能力做多少封装,只要waylib的实现够灵活,不阻塞treeland实现多seat的功能就行。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants