mirror of
https://github.com/hyprwm/Hyprland
synced 2025-01-11 00:29:49 +01:00
parent
3cba4ba44e
commit
9f7a96b997
5 changed files with 45 additions and 19 deletions
|
@ -14,8 +14,7 @@ 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)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
CSeatManager::SSeatResourceContainer::SSeatResourceContainer(SP<CWLSeatResource> res) {
|
CSeatManager::SSeatResourceContainer::SSeatResourceContainer(SP<CWLSeatResource> res) : resource(res) {
|
||||||
resource = res;
|
|
||||||
listeners.destroy = res->events.destroy.registerListener(
|
listeners.destroy = res->events.destroy.registerListener(
|
||||||
[this](std::any data) { std::erase_if(g_pSeatManager->seatResources, [this](const auto& e) { return e->resource.expired() || e->resource == resource; }); });
|
[this](std::any data) { std::erase_if(g_pSeatManager->seatResources, [this](const auto& e) { return e->resource.expired() || e->resource == resource; }); });
|
||||||
}
|
}
|
||||||
|
@ -192,8 +191,12 @@ void CSeatManager::setPointerFocus(SP<CWLSurfaceResource> surf, const Vector2D&
|
||||||
if (state.pointerFocus == surf)
|
if (state.pointerFocus == surf)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (PROTO::data->dndActive() && surf) {
|
if (PROTO::data->dndActive()) {
|
||||||
Debug::log(LOG, "[seatmgr] Refusing pointer focus during an active dnd");
|
if (state.dndPointerFocus == surf)
|
||||||
|
return;
|
||||||
|
Debug::log(LOG, "[seatmgr] Refusing pointer focus during an active dnd, but setting dndPointerFocus");
|
||||||
|
state.dndPointerFocus = surf;
|
||||||
|
events.dndPointerFocusChange.emit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +224,7 @@ void CSeatManager::setPointerFocus(SP<CWLSurfaceResource> surf, const Vector2D&
|
||||||
|
|
||||||
auto lastPointerFocusResource = state.pointerFocusResource;
|
auto lastPointerFocusResource = state.pointerFocusResource;
|
||||||
|
|
||||||
|
state.dndPointerFocus.reset();
|
||||||
state.pointerFocusResource.reset();
|
state.pointerFocusResource.reset();
|
||||||
state.pointerFocus = surf;
|
state.pointerFocus = surf;
|
||||||
|
|
||||||
|
@ -230,6 +234,8 @@ void CSeatManager::setPointerFocus(SP<CWLSurfaceResource> surf, const Vector2D&
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.dndPointerFocus = surf;
|
||||||
|
|
||||||
auto client = surf->client();
|
auto client = surf->client();
|
||||||
for (auto const& r : seatResources | std::views::reverse) {
|
for (auto const& r : seatResources | std::views::reverse) {
|
||||||
if (r->resource->client() != client)
|
if (r->resource->client() != client)
|
||||||
|
@ -252,6 +258,7 @@ void CSeatManager::setPointerFocus(SP<CWLSurfaceResource> surf, const Vector2D&
|
||||||
listeners.pointerSurfaceDestroy = surf->events.destroy.registerListener([this](std::any d) { setPointerFocus(nullptr, {}); });
|
listeners.pointerSurfaceDestroy = surf->events.destroy.registerListener([this](std::any d) { setPointerFocus(nullptr, {}); });
|
||||||
|
|
||||||
events.pointerFocusChange.emit();
|
events.pointerFocusChange.emit();
|
||||||
|
events.dndPointerFocusChange.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSeatManager::sendPointerMotion(uint32_t timeMs, const Vector2D& local) {
|
void CSeatManager::sendPointerMotion(uint32_t timeMs, const Vector2D& local) {
|
||||||
|
|
|
@ -95,6 +95,8 @@ class CSeatManager {
|
||||||
|
|
||||||
WP<CWLSurfaceResource> touchFocus;
|
WP<CWLSurfaceResource> touchFocus;
|
||||||
WP<CWLSeatResource> touchFocusResource;
|
WP<CWLSeatResource> touchFocusResource;
|
||||||
|
|
||||||
|
WP<CWLSurfaceResource> dndPointerFocus;
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
struct SSetCursorEvent {
|
struct SSetCursorEvent {
|
||||||
|
@ -105,6 +107,7 @@ class CSeatManager {
|
||||||
struct {
|
struct {
|
||||||
CSignal keyboardFocusChange;
|
CSignal keyboardFocusChange;
|
||||||
CSignal pointerFocusChange;
|
CSignal pointerFocusChange;
|
||||||
|
CSignal dndPointerFocusChange;
|
||||||
CSignal touchFocusChange;
|
CSignal touchFocusChange;
|
||||||
CSignal setCursor; // SSetCursorEvent
|
CSignal setCursor; // SSetCursorEvent
|
||||||
CSignal setSelection;
|
CSignal setSelection;
|
||||||
|
|
|
@ -374,8 +374,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||||
if (g_pPointerManager->softwareLockedFor(PMONITOR->self.lock()) > 0 && !skipFrameSchedule)
|
if (g_pPointerManager->softwareLockedFor(PMONITOR->self.lock()) > 0 && !skipFrameSchedule)
|
||||||
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_pLastMonitor.lock(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
|
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_pLastMonitor.lock(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_MOVE);
|
||||||
|
|
||||||
// grabs
|
// FIXME: This will be disabled during DnD operations because we do not exactly follow the spec
|
||||||
if (g_pSeatManager->seatGrab && !g_pSeatManager->seatGrab->accepts(foundSurface)) {
|
// xdg-popup grabs should be keyboard-only, while they are absolute in our case...
|
||||||
|
if (g_pSeatManager->seatGrab && !g_pSeatManager->seatGrab->accepts(foundSurface) && !PROTO::data->dndActive()) {
|
||||||
if (m_bHardInput || refocus) {
|
if (m_bHardInput || refocus) {
|
||||||
g_pSeatManager->setGrab(nullptr);
|
g_pSeatManager->setGrab(nullptr);
|
||||||
return; // setGrab will refocus
|
return; // setGrab will refocus
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "../../managers/SeatManager.hpp"
|
#include "../../managers/SeatManager.hpp"
|
||||||
#include "../../managers/PointerManager.hpp"
|
#include "../../managers/PointerManager.hpp"
|
||||||
|
#include "../../managers/eventLoop/EventLoopManager.hpp"
|
||||||
#include "../../Compositor.hpp"
|
#include "../../Compositor.hpp"
|
||||||
#include "Seat.hpp"
|
#include "Seat.hpp"
|
||||||
#include "Compositor.hpp"
|
#include "Compositor.hpp"
|
||||||
|
@ -342,7 +343,10 @@ bool CWLDataDeviceManagerResource::good() {
|
||||||
}
|
}
|
||||||
|
|
||||||
CWLDataDeviceProtocol::CWLDataDeviceProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
CWLDataDeviceProtocol::CWLDataDeviceProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||||
;
|
g_pEventLoopManager->doLater([this]() {
|
||||||
|
listeners.onKeyboardFocusChange = g_pSeatManager->events.keyboardFocusChange.registerListener([this](std::any d) { onKeyboardFocus(); });
|
||||||
|
listeners.onDndPointerFocusChange = g_pSeatManager->events.dndPointerFocusChange.registerListener([this](std::any d) { onDndPointerFocus(); });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWLDataDeviceProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
void CWLDataDeviceProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||||
|
@ -355,10 +359,6 @@ void CWLDataDeviceProtocol::bindManager(wl_client* client, void* data, uint32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGM(LOG, "New datamgr resource bound at {:x}", (uintptr_t)RESOURCE.get());
|
LOGM(LOG, "New datamgr resource bound at {:x}", (uintptr_t)RESOURCE.get());
|
||||||
|
|
||||||
// we need to do it here because protocols come before seatMgr
|
|
||||||
if (!listeners.onKeyboardFocusChange)
|
|
||||||
listeners.onKeyboardFocusChange = g_pSeatManager->events.keyboardFocusChange.registerListener([this](std::any d) { this->onKeyboardFocus(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWLDataDeviceProtocol::destroyResource(CWLDataDeviceManagerResource* seat) {
|
void CWLDataDeviceProtocol::destroyResource(CWLDataDeviceManagerResource* seat) {
|
||||||
|
@ -461,10 +461,21 @@ void CWLDataDeviceProtocol::updateSelection() {
|
||||||
|
|
||||||
void CWLDataDeviceProtocol::onKeyboardFocus() {
|
void CWLDataDeviceProtocol::onKeyboardFocus() {
|
||||||
for (auto const& o : m_vOffers) {
|
for (auto const& o : m_vOffers) {
|
||||||
|
if (o->source && o->source->hasDnd())
|
||||||
|
continue;
|
||||||
o->dead = true;
|
o->dead = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSelection();
|
updateSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWLDataDeviceProtocol::onDndPointerFocus() {
|
||||||
|
for (auto const& o : m_vOffers) {
|
||||||
|
if (o->source && !o->source->hasDnd())
|
||||||
|
continue;
|
||||||
|
o->dead = true;
|
||||||
|
}
|
||||||
|
|
||||||
updateDrag();
|
updateDrag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,8 +526,8 @@ void CWLDataDeviceProtocol::initiateDrag(WP<CWLDataSourceResource> currentSource
|
||||||
|
|
||||||
dnd.mouseMove = g_pHookSystem->hookDynamic("mouseMove", [this](void* self, SCallbackInfo& info, std::any e) {
|
dnd.mouseMove = g_pHookSystem->hookDynamic("mouseMove", [this](void* self, SCallbackInfo& info, std::any e) {
|
||||||
auto V = std::any_cast<const Vector2D>(e);
|
auto V = std::any_cast<const Vector2D>(e);
|
||||||
if (dnd.focusedDevice && g_pSeatManager->state.keyboardFocus) {
|
if (dnd.focusedDevice && g_pSeatManager->state.dndPointerFocus) {
|
||||||
auto surf = CWLSurface::fromResource(g_pSeatManager->state.keyboardFocus.lock());
|
auto surf = CWLSurface::fromResource(g_pSeatManager->state.dndPointerFocus.lock());
|
||||||
|
|
||||||
if (!surf)
|
if (!surf)
|
||||||
return;
|
return;
|
||||||
|
@ -536,8 +547,8 @@ void CWLDataDeviceProtocol::initiateDrag(WP<CWLDataSourceResource> currentSource
|
||||||
|
|
||||||
dnd.touchMove = g_pHookSystem->hookDynamic("touchMove", [this](void* self, SCallbackInfo& info, std::any e) {
|
dnd.touchMove = g_pHookSystem->hookDynamic("touchMove", [this](void* self, SCallbackInfo& info, std::any e) {
|
||||||
auto E = std::any_cast<ITouch::SMotionEvent>(e);
|
auto E = std::any_cast<ITouch::SMotionEvent>(e);
|
||||||
if (dnd.focusedDevice && g_pSeatManager->state.keyboardFocus) {
|
if (dnd.focusedDevice && g_pSeatManager->state.dndPointerFocus) {
|
||||||
auto surf = CWLSurface::fromResource(g_pSeatManager->state.keyboardFocus.lock());
|
auto surf = CWLSurface::fromResource(g_pSeatManager->state.dndPointerFocus.lock());
|
||||||
|
|
||||||
if (!surf)
|
if (!surf)
|
||||||
return;
|
return;
|
||||||
|
@ -555,7 +566,9 @@ void CWLDataDeviceProtocol::initiateDrag(WP<CWLDataSourceResource> currentSource
|
||||||
// unfocus the pointer from the surface, this is part of """standard""" wayland procedure and gtk will freak out if this isn't happening.
|
// unfocus the pointer from the surface, this is part of """standard""" wayland procedure and gtk will freak out if this isn't happening.
|
||||||
// BTW, the spec does NOT require this explicitly...
|
// BTW, the spec does NOT require this explicitly...
|
||||||
// Fuck you gtk.
|
// Fuck you gtk.
|
||||||
|
const auto LASTDNDFOCUS = g_pSeatManager->state.dndPointerFocus;
|
||||||
g_pSeatManager->setPointerFocus(nullptr, {});
|
g_pSeatManager->setPointerFocus(nullptr, {});
|
||||||
|
g_pSeatManager->state.dndPointerFocus = LASTDNDFOCUS;
|
||||||
|
|
||||||
// make a new offer, etc
|
// make a new offer, etc
|
||||||
updateDrag();
|
updateDrag();
|
||||||
|
@ -568,10 +581,10 @@ void CWLDataDeviceProtocol::updateDrag() {
|
||||||
if (dnd.focusedDevice)
|
if (dnd.focusedDevice)
|
||||||
dnd.focusedDevice->sendLeave();
|
dnd.focusedDevice->sendLeave();
|
||||||
|
|
||||||
if (!g_pSeatManager->state.keyboardFocusResource)
|
if (!g_pSeatManager->state.dndPointerFocus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dnd.focusedDevice = dataDeviceForClient(g_pSeatManager->state.keyboardFocusResource->client());
|
dnd.focusedDevice = dataDeviceForClient(g_pSeatManager->state.dndPointerFocus->client());
|
||||||
|
|
||||||
if (!dnd.focusedDevice)
|
if (!dnd.focusedDevice)
|
||||||
return;
|
return;
|
||||||
|
@ -590,8 +603,8 @@ void CWLDataDeviceProtocol::updateDrag() {
|
||||||
|
|
||||||
dnd.focusedDevice->sendDataOffer(OFFER);
|
dnd.focusedDevice->sendDataOffer(OFFER);
|
||||||
OFFER->sendData();
|
OFFER->sendData();
|
||||||
dnd.focusedDevice->sendEnter(wl_display_next_serial(g_pCompositor->m_sWLDisplay), g_pSeatManager->state.keyboardFocus.lock(),
|
dnd.focusedDevice->sendEnter(wl_display_next_serial(g_pCompositor->m_sWLDisplay), g_pSeatManager->state.dndPointerFocus.lock(),
|
||||||
g_pSeatManager->state.keyboardFocus->current.size / 2.F, OFFER);
|
g_pSeatManager->state.dndPointerFocus->current.size / 2.F, OFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWLDataDeviceProtocol::resetDndState() {
|
void CWLDataDeviceProtocol::resetDndState() {
|
||||||
|
|
|
@ -155,6 +155,7 @@ class CWLDataDeviceProtocol : public IWaylandProtocol {
|
||||||
void sendSelectionToDevice(SP<CWLDataDeviceResource> dev, SP<IDataSource> sel);
|
void sendSelectionToDevice(SP<CWLDataDeviceResource> dev, SP<IDataSource> sel);
|
||||||
void updateSelection();
|
void updateSelection();
|
||||||
void onKeyboardFocus();
|
void onKeyboardFocus();
|
||||||
|
void onDndPointerFocus();
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
WP<CWLDataDeviceResource> focusedDevice;
|
WP<CWLDataDeviceResource> focusedDevice;
|
||||||
|
@ -191,6 +192,7 @@ class CWLDataDeviceProtocol : public IWaylandProtocol {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CHyprSignalListener onKeyboardFocusChange;
|
CHyprSignalListener onKeyboardFocusChange;
|
||||||
|
CHyprSignalListener onDndPointerFocusChange;
|
||||||
} listeners;
|
} listeners;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue