@@ -275,70 +275,93 @@ WaylandClipboard::WaylandClipboard(Clipboard *clipboard, std::string name,
275275 globalConn_ = display_->globalCreated ().connect (
276276 [this ](const std::string &interface, const std::shared_ptr<void > &ptr) {
277277 if (interface == wayland::ExtDataControlManagerV1::interface) {
278- if (ptr != ext_manager_ ) {
279- deviceMap_ .clear ();
280- ext_manager_ =
278+ if (ptr != extManager_ ) {
279+ extDeviceMap_ .clear ();
280+ extManager_ =
281281 display_->getGlobal <wayland::ExtDataControlManagerV1>();
282282 }
283- refreshSeat ();
283+ parent_->instance ()->eventDispatcher ().schedule (
284+ [this ]() { refreshSeat (); });
285+ deferRefreshSeat ();
284286 } else if (interface ==
285287 wayland::ZwlrDataControlManagerV1::interface) {
286- if (ptr != wlr_manager_ ) {
287- deviceMap_ .clear ();
288- wlr_manager_ =
288+ if (ptr != wlrManager_ ) {
289+ wlrDeviceMap_ .clear ();
290+ wlrManager_ =
289291 display_
290292 ->getGlobal <wayland::ZwlrDataControlManagerV1>();
291293 }
292- refreshSeat ();
294+ deferRefreshSeat ();
293295 } else if (interface == wayland::WlSeat::interface) {
294- refreshSeat ();
296+ deferRefreshSeat ();
295297 }
296298 });
297299 globalRemoveConn_ = display_->globalRemoved ().connect (
298300 [this ](const std::string &interface, const std::shared_ptr<void > &ptr) {
299- if (interface == wayland::ZwlrDataControlManagerV1::interface) {
300- deviceMap_.clear ();
301- if (wlr_manager_ == ptr) {
302- wlr_manager_.reset ();
301+ if (interface == wayland::ExtDataControlManagerV1::interface) {
302+ extDeviceMap_.clear ();
303+ if (extManager_ == ptr) {
304+ extManager_.reset ();
305+ }
306+ } else if (interface ==
307+ wayland::ZwlrDataControlManagerV1::interface) {
308+ wlrDeviceMap_.clear ();
309+ if (wlrManager_ == ptr) {
310+ wlrManager_.reset ();
303311 }
304312 } else if (interface == wayland::WlSeat::interface) {
305- deviceMap_.erase (static_cast <wayland::WlSeat *>(ptr.get ()));
313+ wlrDeviceMap_.erase (static_cast <wayland::WlSeat *>(ptr.get ()));
314+ extDeviceMap_.erase (static_cast <wayland::WlSeat *>(ptr.get ()));
306315 }
307316 });
308317
309318 if (auto manager =
310319 display_->getGlobal <wayland::ZwlrDataControlManagerV1>()) {
311- wlr_manager_ = std::move (manager);
320+ wlrManager_ = std::move (manager);
312321 }
313322 refreshSeat ();
314323}
315324
325+ void WaylandClipboard::deferRefreshSeat () {
326+ // The initial global registration update is more likely happen in one
327+ // message loop, so we defer so we can decide to only initialize ext or wlr.
328+ parent_->instance ()->eventDispatcher ().scheduleWithContext (
329+ watch (), [this ]() { refreshSeat (); });
330+ }
331+
316332void WaylandClipboard::refreshSeat () {
317- if (!wlr_manager_ && !ext_manager_ ) {
333+ if (!wlrManager_ && !extManager_ ) {
318334 return ;
319335 }
320336
321337 auto seats = display_->getGlobals <wayland::WlSeat>();
322338 for (const auto &seat : seats) {
323- if (deviceMap_.contains (seat.get ())) {
324- continue ;
325- }
326-
327- if (ext_manager_) {
328- auto *device = ext_manager_->getDataDevice (seat.get ());
329- deviceMap_.emplace (
339+ if (extManager_) {
340+ if (extDeviceMap_.contains (seat.get ())) {
341+ continue ;
342+ }
343+ auto *device = extManager_->getDataDevice (seat.get ());
344+ extDeviceMap_.emplace (
330345 seat.get (),
331346 std::make_unique<DataDevice<wayland::ExtDataControlDeviceV1>>(
332347 this , device));
333348 continue ;
334- } else if (wlr_manager_) {
335- auto *device = wlr_manager_->getDataDevice (seat.get ());
336- deviceMap_.emplace (
349+ } else if (wlrManager_) {
350+ if (wlrDeviceMap_.contains (seat.get ())) {
351+ continue ;
352+ }
353+ auto *device = wlrManager_->getDataDevice (seat.get ());
354+ wlrDeviceMap_.emplace (
337355 seat.get (),
338356 std::make_unique<DataDevice<wayland::ZwlrDataControlDeviceV1>>(
339357 this , device));
340358 }
341359 }
360+
361+ // If both are available, prefer ext.
362+ if (extManager_ && wlrManager_) {
363+ wlrDeviceMap_.clear ();
364+ }
342365}
343366
344367void WaylandClipboard::setClipboard (const std::string &str, bool password) {
0 commit comments