mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-10-09 03:26:26 +00:00
seat: send enter/leave events to all bound wl_seats for a client
fixes #6069 Will not send anything beyond enter/leave. If you depend on multiple seats sending you motion, button, etc, events, fix your app.
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../devices/IKeyboard.hpp"
|
#include "../devices/IKeyboard.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
CSeatManager::CSeatManager() {
|
CSeatManager::CSeatManager() {
|
||||||
listeners.newSeatResource = PROTO::seat->events.newSeatResource.registerListener([this](std::any res) { onNewSeatResource(std::any_cast<SP<CWLSeatResource>>(res)); });
|
listeners.newSeatResource = PROTO::seat->events.newSeatResource.registerListener([this](std::any res) { onNewSeatResource(std::any_cast<SP<CWLSeatResource>>(res)); });
|
||||||
@@ -104,13 +105,25 @@ void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
|
|||||||
hyprListener_keyboardSurfaceDestroy.removeCallback();
|
hyprListener_keyboardSurfaceDestroy.removeCallback();
|
||||||
|
|
||||||
if (state.keyboardFocusResource) {
|
if (state.keyboardFocusResource) {
|
||||||
for (auto& k : state.keyboardFocusResource->keyboards) {
|
// we will iterate over all bound wl_seat
|
||||||
|
// resources here, because some idiotic apps (e.g. those based on smithay)
|
||||||
|
// tend to bind wl_seat twice.
|
||||||
|
// I can't be arsed to actually pass all events to all seat resources, so we will
|
||||||
|
// only pass enter and leave.
|
||||||
|
// If you have an issue with that, fix your app.
|
||||||
|
auto client = state.keyboardFocusResource->client();
|
||||||
|
for (auto& s : seatResources) {
|
||||||
|
if (s->resource->client() != client)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto& k : s->resource->keyboards) {
|
||||||
if (!k)
|
if (!k)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
k->sendLeave();
|
k->sendLeave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state.keyboardFocusResource.reset();
|
state.keyboardFocusResource.reset();
|
||||||
state.keyboardFocus = surf;
|
state.keyboardFocus = surf;
|
||||||
@@ -121,19 +134,18 @@ void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto client = wl_resource_get_client(surf->resource);
|
auto client = wl_resource_get_client(surf->resource);
|
||||||
for (auto& r : seatResources) {
|
for (auto& r : seatResources | std::views::reverse) {
|
||||||
if (r->resource->client() == client) {
|
if (r->resource->client() != client)
|
||||||
|
continue;
|
||||||
|
|
||||||
state.keyboardFocusResource = r->resource;
|
state.keyboardFocusResource = r->resource;
|
||||||
for (auto& k : state.keyboardFocusResource->keyboards) {
|
for (auto& k : r->resource->keyboards) {
|
||||||
if (!k)
|
if (!k)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
k->sendEnter(surf);
|
k->sendEnter(surf);
|
||||||
k->sendMods(keyboard->wlr()->modifiers.depressed, keyboard->wlr()->modifiers.latched, keyboard->wlr()->modifiers.locked, keyboard->wlr()->modifiers.group);
|
k->sendMods(keyboard->wlr()->modifiers.depressed, keyboard->wlr()->modifiers.latched, keyboard->wlr()->modifiers.locked, keyboard->wlr()->modifiers.group);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hyprListener_keyboardSurfaceDestroy.initCallback(
|
hyprListener_keyboardSurfaceDestroy.initCallback(
|
||||||
@@ -178,13 +190,19 @@ void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
|
|||||||
hyprListener_pointerSurfaceDestroy.removeCallback();
|
hyprListener_pointerSurfaceDestroy.removeCallback();
|
||||||
|
|
||||||
if (state.pointerFocusResource) {
|
if (state.pointerFocusResource) {
|
||||||
for (auto& p : state.pointerFocusResource->pointers) {
|
auto client = state.pointerFocusResource->client();
|
||||||
|
for (auto& s : seatResources) {
|
||||||
|
if (s->resource->client() != client)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto& p : s->resource->pointers) {
|
||||||
if (!p)
|
if (!p)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p->sendLeave();
|
p->sendLeave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto lastPointerFocusResource = state.pointerFocusResource;
|
auto lastPointerFocusResource = state.pointerFocusResource;
|
||||||
|
|
||||||
@@ -198,18 +216,17 @@ void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto client = wl_resource_get_client(surf->resource);
|
auto client = wl_resource_get_client(surf->resource);
|
||||||
for (auto& r : seatResources) {
|
for (auto& r : seatResources | std::views::reverse) {
|
||||||
if (r->resource->client() == client) {
|
if (r->resource->client() != client)
|
||||||
|
continue;
|
||||||
|
|
||||||
state.pointerFocusResource = r->resource;
|
state.pointerFocusResource = r->resource;
|
||||||
for (auto& p : state.pointerFocusResource->pointers) {
|
for (auto& p : r->resource->pointers) {
|
||||||
if (!p)
|
if (!p)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p->sendEnter(surf, local);
|
p->sendEnter(surf, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.pointerFocusResource != lastPointerFocusResource)
|
if (state.pointerFocusResource != lastPointerFocusResource)
|
||||||
@@ -290,13 +307,19 @@ void CSeatManager::sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id,
|
|||||||
hyprListener_touchSurfaceDestroy.removeCallback();
|
hyprListener_touchSurfaceDestroy.removeCallback();
|
||||||
|
|
||||||
if (state.touchFocusResource) {
|
if (state.touchFocusResource) {
|
||||||
for (auto& t : state.touchFocusResource->touches) {
|
auto client = state.touchFocusResource->client();
|
||||||
|
for (auto& s : seatResources) {
|
||||||
|
if (s->resource->client() != client)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto& t : s->resource->touches) {
|
||||||
if (!t)
|
if (!t)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
t->sendUp(timeMs, id);
|
t->sendUp(timeMs, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state.touchFocusResource.reset();
|
state.touchFocusResource.reset();
|
||||||
state.touchFocus = surf;
|
state.touchFocus = surf;
|
||||||
@@ -307,18 +330,17 @@ void CSeatManager::sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto client = wl_resource_get_client(surf->resource);
|
auto client = wl_resource_get_client(surf->resource);
|
||||||
for (auto& r : seatResources) {
|
for (auto& r : seatResources | std::views::reverse) {
|
||||||
if (r->resource->client() == client) {
|
if (r->resource->client() != client)
|
||||||
|
continue;
|
||||||
|
|
||||||
state.touchFocusResource = r->resource;
|
state.touchFocusResource = r->resource;
|
||||||
for (auto& t : state.touchFocusResource->touches) {
|
for (auto& t : r->resource->touches) {
|
||||||
if (!t)
|
if (!t)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
t->sendDown(surf, timeMs, id, local);
|
t->sendDown(surf, timeMs, id, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hyprListener_touchSurfaceDestroy.initCallback(
|
hyprListener_touchSurfaceDestroy.initCallback(
|
||||||
|
Reference in New Issue
Block a user