Skip to content

Commit

Permalink
wayland: Fix pointer not being drawn on second VNC connect. (#418)
Browse files Browse the repository at this point in the history
Use global_remove event to clean-up seat map.

Signed-off-by: Ómar Högni Guðmarsson <ohg@skaginn3x.com>
  • Loading branch information
Ómar Högni Guðmarsson authored May 28, 2024
1 parent 434d509 commit d73e35a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -289,31 +289,34 @@ const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = {
ELINUX_LOG(TRACE) << "wl_seat_listener.capabilities";

auto self = reinterpret_cast<ELinuxWindowWayland*>(data);
auto [iter_inputs, _] =
self->seat_inputs_map_.emplace(seat, seat_inputs());
auto& inputs = iter_inputs->second;
auto seat_iter = self->seat_inputs_map_.find(seat);
if (seat_iter == self->seat_inputs_map_.end()) {
ELINUX_LOG(ERROR) << "Failed to find the seat";
return;
}
auto& inputs = seat_iter->second;

if ((caps & WL_SEAT_CAPABILITY_POINTER) && !inputs.pointer) {
inputs.pointer = wl_seat_get_pointer(seat);
wl_pointer_add_listener(inputs.pointer, &kWlPointerListener, self);
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && inputs.pointer) {
wl_pointer_destroy(inputs.pointer);
wl_pointer_release(inputs.pointer);
inputs.pointer = nullptr;
}

if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !inputs.touch) {
inputs.touch = wl_seat_get_touch(seat);
wl_touch_add_listener(inputs.touch, &kWlTouchListener, self);
} else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && inputs.touch) {
wl_touch_destroy(inputs.touch);
wl_touch_release(inputs.touch);
inputs.touch = nullptr;
}

if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !inputs.keyboard) {
inputs.keyboard = wl_seat_get_keyboard(seat);
wl_keyboard_add_listener(inputs.keyboard, &kWlKeyboardListener, self);
} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && inputs.keyboard) {
wl_keyboard_destroy(inputs.keyboard);
wl_keyboard_release(inputs.keyboard);
inputs.keyboard = nullptr;
}
},
Expand Down Expand Up @@ -347,6 +350,11 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = {
self->pointer_x_ = x_px;
self->pointer_y_ = y_px;
}

// Force redraw even though it is the same cursor name
auto copy = self->cursor_info_.cursor_name;
self->cursor_info_.cursor_name.clear();
self->UpdateFlutterCursor(copy);
},
.leave = [](void* data,
wl_pointer* pointer,
Expand Down Expand Up @@ -1513,16 +1521,6 @@ void ELinuxWindowWayland::UpdateVirtualKeyboardStatus(const bool show) {

void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) {
if (view_properties_.use_mouse_cursor) {
wl_pointer* pointer = nullptr;
for (auto& [_, inputs] : seat_inputs_map_) {
if (inputs.pointer != nullptr) {
pointer = inputs.pointer;
break;
}
}
if (!pointer) {
return;
}
if (cursor_name.compare(cursor_info_.cursor_name) == 0) {
return;
}
Expand Down Expand Up @@ -1644,6 +1642,7 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry,
wl_registry, name, &wl_seat_interface,
std::min(kMaxVersion, version))),
seat_inputs());
registry_names_to_seat_ptr_.emplace(name, inserted->first);
wl_seat_add_listener(inserted->first, &kWlSeatListener, this);
return;
}
Expand Down Expand Up @@ -1720,7 +1719,35 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry,
}

void ELinuxWindowWayland::WlUnRegistryHandler(wl_registry* wl_registry,
uint32_t name) {}
uint32_t name) {
// Just remove seats for now, as we don't need to do anything else.
// But there is also no interface name here.
auto seat_iter = registry_names_to_seat_ptr_.find(name);
if (seat_iter != registry_names_to_seat_ptr_.end()) {
auto seat = seat_iter->second;
auto seat_inputs_iter = seat_inputs_map_.find(seat);
if (seat_inputs_iter != seat_inputs_map_.end()) {
auto& inputs = seat_inputs_iter->second;
if (inputs.pointer) {
wl_pointer_release(inputs.pointer);
inputs.pointer = nullptr;
}
if (inputs.touch) {
wl_touch_release(inputs.touch);
inputs.touch = nullptr;
}
if (inputs.keyboard) {
wl_keyboard_release(inputs.keyboard);
inputs.keyboard = nullptr;
}
seat_inputs_map_.erase(seat_inputs_iter);
}
if (seat) {
wl_seat_destroy(seat);
}
registry_names_to_seat_ptr_.erase(name);
}
}

bool ELinuxWindowWayland::LoadCursorTheme(uint32_t size) {
if (!wl_shm_) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler {
wl_output* wl_output_;
wl_shm* wl_shm_;
std::unordered_map<wl_seat*, seat_inputs> seat_inputs_map_;
std::unordered_map<uint32_t, wl_seat*> registry_names_to_seat_ptr_;
wl_surface* wl_cursor_surface_;
xdg_wm_base* xdg_wm_base_;
xdg_surface* xdg_surface_;
Expand Down

0 comments on commit d73e35a

Please sign in to comment.