input: properly track mouse focus on drag operations

This commit is contained in:
vaxerski 2023-09-23 01:21:59 +01:00
parent 1b48642fd1
commit fb80cbe415
5 changed files with 49 additions and 8 deletions

View file

@ -830,6 +830,34 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
return PSURFACE->surface; return PSURFACE->surface;
} }
Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, CWindow* pWindow, wlr_surface* pSurface) {
if (!windowValidMapped(pWindow))
return {};
if (pWindow->m_bIsX11)
return vec - pWindow->m_vRealPosition.goalv();
const auto PSURFACE = pWindow->m_uSurface.xdg;
std::tuple<wlr_surface*, int, int> iterData = {pSurface, -1337, -1337};
wlr_xdg_surface_for_each_surface(
PSURFACE,
[](wlr_surface* surf, int x, int y, void* data) {
const auto PDATA = (std::tuple<wlr_surface*, int, int>*)data;
if (surf == std::get<0>(*PDATA)) {
std::get<1>(*PDATA) = x;
std::get<2>(*PDATA) = y;
}
},
&iterData);
if (std::get<1>(iterData) == -1337 && std::get<2>(iterData) == -1337)
return vec - pWindow->m_vRealPosition.goalv();
return vec - pWindow->m_vRealPosition.goalv() - Vector2D{std::get<1>(iterData), std::get<2>(iterData)};
}
CMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) { CMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) {
for (auto& m : m_vMonitors) { for (auto& m : m_vMonitors) {
if (m->output == out) { if (m->output == out) {

View file

@ -28,7 +28,8 @@
#include "hyprerror/HyprError.hpp" #include "hyprerror/HyprError.hpp"
#include "plugins/PluginSystem.hpp" #include "plugins/PluginSystem.hpp"
enum eManagersInitStage { enum eManagersInitStage
{
STAGE_PRIORITY = 0, STAGE_PRIORITY = 0,
STAGE_LATE STAGE_LATE
}; };
@ -138,6 +139,7 @@ class CCompositor {
CWindow* vectorToWindowTiled(const Vector2D&); CWindow* vectorToWindowTiled(const Vector2D&);
wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector<std::unique_ptr<SLayerSurface>>*, Vector2D*, SLayerSurface**); wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector<std::unique_ptr<SLayerSurface>>*, Vector2D*, SLayerSurface**);
wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl); wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl);
Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*);
CWindow* windowFromCursor(); CWindow* windowFromCursor();
CWindow* windowFloatingFromCursor(); CWindow* windowFloatingFromCursor();
CMonitor* getMonitorFromOutput(wlr_output*); CMonitor* getMonitorFromOutput(wlr_output*);

View file

@ -36,6 +36,8 @@ void CWLSurface::destroy() {
if (g_pCompositor->m_pLastFocus == m_pWLRSurface) if (g_pCompositor->m_pLastFocus == m_pWLRSurface)
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus = nullptr;
if (g_pInputManager->m_pLastMouseSurface == m_pWLRSurface)
g_pInputManager->m_pLastMouseSurface = nullptr;
m_pWLRSurface = nullptr; m_pWLRSurface = nullptr;

View file

@ -201,10 +201,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
pFoundLayerSurface = nullptr; pFoundLayerSurface = nullptr;
} }
} else if (g_pCompositor->m_pLastWindow) { } else if (g_pCompositor->m_pLastWindow) {
foundSurface = g_pCompositor->m_pLastFocus; foundSurface = m_pLastMouseSurface;
pFoundWindow = g_pCompositor->m_pLastWindow; pFoundWindow = g_pCompositor->m_pLastWindow;
surfacePos = g_pCompositor->m_pLastWindow->m_vRealPosition.vec(); surfaceCoords = g_pCompositor->vectorToSurfaceLocal(mouseCoords, pFoundWindow, foundSurface);
m_bFocusHeldByButtons = true; m_bFocusHeldByButtons = true;
m_bRefocusHeldByButtons = refocus; m_bRefocusHeldByButtons = refocus;
@ -389,14 +389,17 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
// enter if change floating style // enter if change floating style
if (FOLLOWMOUSE != 3 && allowKeyboardRefocus) if (FOLLOWMOUSE != 3 && allowKeyboardRefocus)
g_pCompositor->focusWindow(pFoundWindow, foundSurface); g_pCompositor->focusWindow(pFoundWindow, foundSurface);
m_pLastMouseSurface = foundSurface;
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
} else if (FOLLOWMOUSE == 2 || FOLLOWMOUSE == 3) { } else if (FOLLOWMOUSE == 2 || FOLLOWMOUSE == 3) {
m_pLastMouseSurface = foundSurface;
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
} }
if (pFoundWindow == g_pCompositor->m_pLastWindow) { if (pFoundWindow == g_pCompositor->m_pLastWindow) {
if (foundSurface != g_pCompositor->m_pLastFocus || m_bLastFocusOnLS) { if (foundSurface != g_pCompositor->m_pLastFocus || m_bLastFocusOnLS) {
// ^^^ changed the subsurface ^^^ came back from a LS // ^^^ changed the subsurface ^^^ came back from a LS
m_pLastMouseSurface = foundSurface;
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
} }
} }
@ -430,6 +433,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
m_bLastFocusOnLS = true; m_bLastFocusOnLS = true;
} }
m_pLastMouseSurface = foundSurface;
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y); wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y); wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
} }
@ -581,7 +585,8 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
if (*PFOLLOWMOUSE == 3) // don't refocus on full loose if (*PFOLLOWMOUSE == 3) // don't refocus on full loose
break; break;
if (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint) { if ((!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint) /* No constraints */
&& (!g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow != w) /* window should change */) {
// a bit hacky // a bit hacky
// if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus // if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus
if (m_lCurrentlyHeldButtons.size() == 1) { if (m_lCurrentlyHeldButtons.size() == 1) {

View file

@ -7,12 +7,14 @@
#include "../../helpers/Timer.hpp" #include "../../helpers/Timer.hpp"
#include "InputMethodRelay.hpp" #include "InputMethodRelay.hpp"
enum eClickBehaviorMode { enum eClickBehaviorMode
{
CLICKMODE_DEFAULT = 0, CLICKMODE_DEFAULT = 0,
CLICKMODE_KILL CLICKMODE_KILL
}; };
enum eMouseBindMode { enum eMouseBindMode
{
MBIND_INVALID = -1, MBIND_INVALID = -1,
MBIND_MOVE = 0, MBIND_MOVE = 0,
MBIND_RESIZE = 1, MBIND_RESIZE = 1,
@ -20,7 +22,8 @@ enum eMouseBindMode {
MBIND_RESIZE_FORCE_RATIO = 3 MBIND_RESIZE_FORCE_RATIO = 3
}; };
enum eBorderIconDirection { enum eBorderIconDirection
{
BORDERICON_NONE, BORDERICON_NONE,
BORDERICON_UP, BORDERICON_UP,
BORDERICON_DOWN, BORDERICON_DOWN,
@ -182,6 +185,7 @@ class CInputManager {
// for tracking mouse refocus // for tracking mouse refocus
CWindow* m_pLastMouseFocus = nullptr; CWindow* m_pLastMouseFocus = nullptr;
wlr_surface* m_pLastMouseSurface = nullptr;
private: private:
bool m_bCursorImageOverridden = false; bool m_bCursorImageOverridden = false;