internal: Unify input handling on decorations (#4280)

* Unify input handling on decorations

* Make input methods private

* Optional data
This commit is contained in:
dranull 2023-12-28 22:54:41 +00:00 committed by GitHub
parent cedf5f1fca
commit 8321d6be46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 104 additions and 109 deletions

View File

@ -222,6 +222,24 @@ void CWindow::removeWindowDeco(IHyprWindowDecoration* deco) {
g_pLayoutManager->getCurrentLayout()->recalculateWindow(this);
}
bool CWindow::checkInputOnDecos(const eInputType type, const Vector2D& mouseCoords, std::any data) {
if (type != INPUT_TYPE_DRAG_END && hasPopupAt(mouseCoords))
return false;
for (auto& wd : m_dWindowDecorations) {
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (!g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(mouseCoords))
continue;
if (wd->onInputOnDeco(type, mouseCoords, data))
return true;
}
return false;
}
pid_t CWindow::getPID() {
pid_t PID = -1;
if (!m_bIsX11) {

View File

@ -348,6 +348,7 @@ class CWindow {
void addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco);
void updateWindowDecos();
void removeWindowDeco(IHyprWindowDecoration* deco);
bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {});
pid_t getPID();
IHyprWindowDecoration* getDecorationByType(eDecorationType);
void removeDecorationByType(eDecorationType);

View File

@ -316,16 +316,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
}
if (!m_vOverrideFocalPoint && g_pInputManager->m_bWasDraggingWindow) {
for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) {
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(MOUSECOORDS)) {
if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS))
return;
break;
}
}
if (OPENINGON->pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, pWindow))
return;
}
// if it's a group, add the window

View File

@ -271,16 +271,8 @@ void IHyprLayout::onEndDragWindow() {
CWindow* pWindow = g_pCompositor->vectorToWindowIdeal(MOUSECOORDS, DRAGGINGWINDOW);
if (pWindow && pWindow->m_bIsFloating) {
for (auto& wd : pWindow->m_dWindowDecorations) {
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(MOUSECOORDS)) {
if (!wd->onEndWindowDragOnDeco(DRAGGINGWINDOW, MOUSECOORDS))
return;
break;
}
}
if (pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, DRAGGINGWINDOW))
return;
if (pWindow->m_sGroupData.pNextWindow && DRAGGINGWINDOW->canBeGroupedInto(pWindow)) {
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;

View File

@ -102,16 +102,8 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
if (g_pInputManager->m_bWasDraggingWindow && OPENINGON) {
for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) {
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(MOUSECOORDS)) {
if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS))
return;
break;
}
}
if (OPENINGON->pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_END, MOUSECOORDS, pWindow))
return;
}
// if it's a group, add the window

View File

@ -1840,17 +1840,8 @@ void CKeybindManager::mouse(std::string args) {
const auto mouseCoords = g_pInputManager->getMouseCoordsInternal();
CWindow* pWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
if (pWindow && !pWindow->m_bIsFullscreen && !pWindow->hasPopupAt(mouseCoords)) {
for (auto& wd : pWindow->m_dWindowDecorations) {
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(mouseCoords)) {
wd->onBeginWindowDragOnDeco(mouseCoords);
break;
}
}
}
if (pWindow && !pWindow->m_bIsFullscreen)
pWindow->checkInputOnDecos(INPUT_TYPE_DRAG_START, mouseCoords);
if (!g_pInputManager->currentlyDraggedWindow)
g_pInputManager->currentlyDraggedWindow = pWindow;

View File

@ -606,17 +606,8 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
const auto mouseCoords = g_pInputManager->getMouseCoordsInternal();
const auto w = g_pCompositor->vectorToWindowIdeal(mouseCoords);
if (w && !w->m_bIsFullscreen && !m_bLastFocusOnLS && !w->hasPopupAt(mouseCoords)) {
for (auto& wd : w->m_dWindowDecorations) {
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
continue;
if (g_pDecorationPositioner->getWindowDecorationBox(wd.get()).containsPoint(mouseCoords)) {
wd->onMouseButtonOnDeco(mouseCoords, e);
return;
}
}
}
if (w && !w->m_bIsFullscreen && !m_bLastFocusOnLS && w->checkInputOnDecos(INPUT_TYPE_BUTTON, mouseCoords, e))
return;
// clicking on border triggers resize
// TODO detect click on LS properly
@ -624,6 +615,7 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
if (w && !w->m_bIsFullscreen) {
const CBox real = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
const CBox grab = {real.x - BORDER_GRAB_AREA, real.y - BORDER_GRAB_AREA, real.width + 2 * BORDER_GRAB_AREA, real.height + 2 * BORDER_GRAB_AREA};
if ((grab.containsPoint(mouseCoords) && (!real.containsPoint(mouseCoords) || w->isInCurvedCorner(mouseCoords.x, mouseCoords.y))) && !w->hasPopupAt(mouseCoords)) {
g_pKeybindManager->resizeWithBorder(e);
return;
@ -686,8 +678,7 @@ void CInputManager::processMouseDownKill(wlr_pointer_button_event* e) {
}
void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) {
static auto* const PSCROLLFACTOR = &g_pConfigManager->getConfigValuePtr("input:touchpad:scroll_factor")->floatValue;
static auto* const PGROUPBARSCROLLING = &g_pConfigManager->getConfigValuePtr("group:groupbar:scrolling")->intValue;
static auto* const PSCROLLFACTOR = &g_pConfigManager->getConfigValuePtr("input:touchpad:scroll_factor")->floatValue;
auto factor = (*PSCROLLFACTOR <= 0.f || e->source != WLR_AXIS_SOURCE_FINGER ? 1.f : *PSCROLLFACTOR);
@ -702,18 +693,10 @@ void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) {
return;
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
const auto pWindow = g_pCompositor->vectorToWindowIdeal(MOUSECOORDS);
const auto PWINDOW = g_pCompositor->vectorToWindowIdeal(MOUSECOORDS);
if (*PGROUPBARSCROLLING && pWindow && !pWindow->m_bIsFullscreen && !pWindow->hasPopupAt(MOUSECOORDS) && pWindow->m_sGroupData.pNextWindow) {
const CBox box = g_pDecorationPositioner->getWindowDecorationBox(pWindow->getDecorationByType(DECORATION_GROUPBAR));
if (box.containsPoint(MOUSECOORDS)) {
if (e->delta > 0)
pWindow->setGroupCurrent(pWindow->m_sGroupData.pNextWindow);
else
pWindow->setGroupCurrent(pWindow->getGroupPrevious());
return;
}
}
if (PWINDOW && PWINDOW->checkInputOnDecos(INPUT_TYPE_AXIS, MOUSECOORDS, e))
return;
wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, e->time_msec, e->orientation, factor * e->delta, std::round(factor * e->delta_discrete), e->source);
}

View File

@ -32,6 +32,14 @@ enum eBorderIconDirection {
BORDERICON_DOWN_RIGHT,
};
enum eInputType {
INPUT_TYPE_AXIS = 0,
INPUT_TYPE_BUTTON,
INPUT_TYPE_DRAG_START,
INPUT_TYPE_DRAG_END,
INPUT_TYPE_MOTION
};
struct STouchData {
CWindow* touchFocusWindow = nullptr;
SLayerSurface* touchFocusLS = nullptr;

View File

@ -300,10 +300,35 @@ void refreshGroupBarGradients() {
renderGradientTo(m_tGradientLockedInactive, ((CGradientValueData*)PGROUPCOLINACTIVELOCKED->get())->m_vColors[0]);
}
bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D& pos) {
bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x;
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth)
return false;
CWindow* pWindow = m_pWindow->getGroupWindowByIndex(WINDOWINDEX);
// hack
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow);
if (!pWindow->m_bIsFloating) {
const bool GROUPSLOCKEDPREV = g_pKeybindManager->m_bGroupsLocked;
g_pKeybindManager->m_bGroupsLocked = true;
g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow);
g_pKeybindManager->m_bGroupsLocked = GROUPSLOCKEDPREV;
}
g_pInputManager->currentlyDraggedWindow = pWindow;
if (!g_pCompositor->isWindowActive(pWindow))
g_pCompositor->focusWindow(pWindow);
return true;
}
bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(const Vector2D& pos, CWindow* pDraggedWindow) {
if (!pDraggedWindow->canBeGroupedInto(m_pWindow))
return true;
return false;
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x - m_fBarWidth / 2;
const int WINDOWINDEX = BARRELATIVEX < 0 ? -1 : (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
@ -357,12 +382,12 @@ bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, con
if (!pDraggedWindow->getDecorationByType(DECORATION_GROUPBAR))
pDraggedWindow->addWindowDeco(std::make_unique<CHyprGroupBarDecoration>(pDraggedWindow));
return false;
return true;
}
void CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_pointer_button_event* e) {
bool CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_pointer_button_event* e) {
if (e->state != WLR_BUTTON_PRESSED)
return;
return false;
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x;
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
@ -370,7 +395,7 @@ void CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_point
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth) {
if (!g_pCompositor->isWindowActive(m_pWindow))
g_pCompositor->focusWindow(m_pWindow);
return;
return true;
}
CWindow* pWindow = m_pWindow->getGroupWindowByIndex(WINDOWINDEX);
@ -380,30 +405,33 @@ void CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_point
if (!g_pCompositor->isWindowActive(pWindow))
g_pCompositor->focusWindow(pWindow);
return true;
}
void CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x;
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
bool CHyprGroupBarDecoration::onScrollOnDeco(const Vector2D& pos, wlr_pointer_axis_event* e) {
static auto* const PGROUPBARSCROLLING = &g_pConfigManager->getConfigValuePtr("group:groupbar:scrolling")->intValue;
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth)
return;
CWindow* pWindow = m_pWindow->getGroupWindowByIndex(WINDOWINDEX);
// hack
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow);
if (!pWindow->m_bIsFloating) {
const bool GROUPSLOCKEDPREV = g_pKeybindManager->m_bGroupsLocked;
g_pKeybindManager->m_bGroupsLocked = true;
g_pLayoutManager->getCurrentLayout()->onWindowCreated(pWindow);
g_pKeybindManager->m_bGroupsLocked = GROUPSLOCKEDPREV;
if (!*PGROUPBARSCROLLING || !m_pWindow->m_sGroupData.pNextWindow) {
return false;
}
g_pInputManager->currentlyDraggedWindow = pWindow;
if (e->delta > 0)
m_pWindow->setGroupCurrent(m_pWindow->m_sGroupData.pNextWindow);
else
m_pWindow->setGroupCurrent(m_pWindow->getGroupPrevious());
if (!g_pCompositor->isWindowActive(pWindow))
g_pCompositor->focusWindow(pWindow);
return true;
}
bool CHyprGroupBarDecoration::onInputOnDeco(const eInputType type, const Vector2D& mouseCoords, std::any data) {
switch (type) {
case INPUT_TYPE_AXIS: return onScrollOnDeco(mouseCoords, std::any_cast<wlr_pointer_axis_event*>(data));
case INPUT_TYPE_BUTTON: return onMouseButtonOnDeco(mouseCoords, std::any_cast<wlr_pointer_button_event*>(data));
case INPUT_TYPE_DRAG_START: return onBeginWindowDragOnDeco(mouseCoords);
case INPUT_TYPE_DRAG_END: return onEndWindowDragOnDeco(mouseCoords, std::any_cast<CWindow*>(data));
default: return false;
}
}
eDecorationLayer CHyprGroupBarDecoration::getDecorationLayer() {

View File

@ -35,11 +35,7 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration {
virtual void damageEntire();
virtual void onBeginWindowDragOnDeco(const Vector2D&);
virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&);
virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
virtual bool onInputOnDeco(const eInputType, const Vector2D&, std::any = {});
virtual eDecorationLayer getDecorationLayer();
@ -63,6 +59,11 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration {
CBox assignedBoxGlobal();
bool onBeginWindowDragOnDeco(const Vector2D&);
bool onEndWindowDragOnDeco(const Vector2D&, CWindow*);
bool onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
bool onScrollOnDeco(const Vector2D&, wlr_pointer_axis_event*);
struct STitleTexs {
// STitleTexs* overriden = nullptr; // TODO: make shit shared in-group to decrease VRAM usage.
std::deque<std::unique_ptr<CTitleTex>> titleTexs;

View File

@ -8,16 +8,8 @@ IHyprWindowDecoration::IHyprWindowDecoration(CWindow* pWindow) {
IHyprWindowDecoration::~IHyprWindowDecoration() {}
void IHyprWindowDecoration::onBeginWindowDragOnDeco(const Vector2D&) {
;
}
bool IHyprWindowDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&) {
return true;
}
void IHyprWindowDecoration::onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*) {
;
bool IHyprWindowDecoration::onInputOnDeco(const eInputType, const Vector2D&, std::any) {
return false;
}
eDecorationLayer IHyprWindowDecoration::getDecorationLayer() {

View File

@ -2,6 +2,7 @@
#include "../../defines.hpp"
#include "../../helpers/Region.hpp"
#include "../../managers/input/InputManager.hpp"
#include "DecorationPositioner.hpp"
enum eDecorationType {
@ -46,11 +47,7 @@ class IHyprWindowDecoration {
virtual void damageEntire() = 0; // should be ignored by non-absolute decos
virtual void onBeginWindowDragOnDeco(const Vector2D&); // called when the user calls the "movewindow" mouse dispatcher on the deco
virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&); // returns true if the window should be placed by the layout
virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
virtual bool onInputOnDeco(const eInputType, const Vector2D&, std::any = {});
virtual eDecorationLayer getDecorationLayer();