input: handle mouse on decorations (#3560)

This commit is contained in:
MightyPlaza 2023-10-29 20:14:47 +00:00 committed by GitHub
parent 7a5234a0cc
commit 9abfa9efc6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 165 additions and 65 deletions

View file

@ -312,6 +312,19 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
return;
}
if (!m_vOverrideFocalPoint && g_pInputManager->m_bWasDraggingWindow) {
for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) {
if (!wd->allowsInput())
continue;
if (wd->getWindowDecorationRegion().containsPoint(MOUSECOORDS)) {
if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS))
return;
break;
}
}
}
// if it's a group, add the window
if (OPENINGON->pWindow->m_sGroupData.pNextWindow // target is group
&& !g_pKeybindManager->m_bGroupsLocked // global group lock disengaged
@ -327,18 +340,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
m_lDwindleNodesData.remove(*PNODE);
const wlr_box box = OPENINGON->pWindow->getDecorationByType(DECORATION_GROUPBAR)->getWindowDecorationRegion().getExtents();
if (wlr_box_contains_point(&box, MOUSECOORDS.x, MOUSECOORDS.y)) { // TODO: Deny when not using mouse
const int SIZE = OPENINGON->pWindow->getGroupSize();
const int INDEX = (int)((MOUSECOORDS.x - box.x) * 2 * SIZE / box.width + 1) / 2 - 1;
CWindow* pWindowInsertAfter = OPENINGON->pWindow->getGroupWindowByIndex(INDEX);
pWindowInsertAfter->insertWindowToGroup(pWindow);
if (INDEX == -1)
std::swap(pWindow->m_sGroupData.pNextWindow->m_sGroupData.head, pWindow->m_sGroupData.head);
} else {
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
(*USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow);
}
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
(*USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow);
OPENINGON->pWindow->setGroupCurrent(pWindow);
pWindow->applyGroupRules();

View file

@ -254,6 +254,7 @@ void IHyprLayout::onEndDragWindow() {
g_pInputManager->unsetCursorImage();
g_pInputManager->currentlyDraggedWindow = nullptr;
g_pInputManager->m_bWasDraggingWindow = true;
if (DRAGGINGWINDOW->m_bDraggingTiled) {
DRAGGINGWINDOW->m_bIsFloating = false;
@ -265,6 +266,8 @@ void IHyprLayout::onEndDragWindow() {
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
g_pCompositor->focusWindow(DRAGGINGWINDOW);
g_pInputManager->m_bWasDraggingWindow = false;
}
void IHyprLayout::onMouseMove(const Vector2D& mousePos) {

View file

@ -94,6 +94,19 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
if (g_pInputManager->m_bWasDraggingWindow) {
for (auto& wd : OPENINGON->pWindow->m_dWindowDecorations) {
if (!wd->allowsInput())
continue;
if (wd->getWindowDecorationRegion().containsPoint(MOUSECOORDS)) {
if (!wd->onEndWindowDragOnDeco(pWindow, MOUSECOORDS))
return;
break;
}
}
}
// if it's a group, add the window
if (OPENINGON && OPENINGON != PNODE && OPENINGON->pWindow->m_sGroupData.pNextWindow // target is group
&& !g_pKeybindManager->m_bGroupsLocked // global group lock disengaged
@ -109,18 +122,8 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
m_lMasterNodesData.remove(*PNODE);
const wlr_box box = OPENINGON->pWindow->getDecorationByType(DECORATION_GROUPBAR)->getWindowDecorationRegion().getExtents();
if (wlr_box_contains_point(&box, MOUSECOORDS.x, MOUSECOORDS.y)) { // TODO: Deny when not using mouse
const int SIZE = OPENINGON->pWindow->getGroupSize();
const int INDEX = (int)((MOUSECOORDS.x - box.x) * 2 * SIZE / box.width + 1) / 2 - 1;
CWindow* pWindowInsertAfter = OPENINGON->pWindow->getGroupWindowByIndex(INDEX);
pWindowInsertAfter->insertWindowToGroup(pWindow);
if (INDEX == -1)
std::swap(pWindow->m_sGroupData.pNextWindow->m_sGroupData.head, pWindow->m_sGroupData.head);
} else {
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
(*USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow);
}
static const auto* USECURRPOS = &g_pConfigManager->getConfigValuePtr("group:insert_after_current")->intValue;
(*USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow);
OPENINGON->pWindow->setGroupCurrent(pWindow);
pWindow->applyGroupRules();

View file

@ -1839,25 +1839,22 @@ 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) && pWindow->m_sGroupData.pNextWindow) {
const wlr_box box = pWindow->getDecorationByType(DECORATION_GROUPBAR)->getWindowDecorationRegion().getExtents();
if (wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y)) {
const int SIZE = pWindow->getGroupSize();
pWindow = pWindow->getGroupWindowByIndex((mouseCoords.x - box.x) * SIZE / box.width);
if (pWindow && !pWindow->m_bIsFullscreen && !pWindow->hasPopupAt(mouseCoords)) {
for (auto& wd : pWindow->m_dWindowDecorations) {
if (!wd->allowsInput())
continue;
// 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 (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) {
wd->onBeginWindowDragOnDeco(mouseCoords);
break;
}
}
}
g_pInputManager->currentlyDraggedWindow = pWindow;
g_pInputManager->dragMode = MBIND_MOVE;
if (!g_pInputManager->currentlyDraggedWindow)
g_pInputManager->currentlyDraggedWindow = pWindow;
g_pInputManager->dragMode = MBIND_MOVE;
g_pLayoutManager->getCurrentLayout()->onBeginDragWindow();
} else {
g_pKeybindManager->m_bIsMouseBindActive = false;

View file

@ -583,16 +583,15 @@ 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 && !w->hasPopupAt(mouseCoords) && w->m_sGroupData.pNextWindow) {
const wlr_box box = w->getDecorationByType(DECORATION_GROUPBAR)->getWindowDecorationRegion().getExtents();
if (wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y)) {
if (e->state == WLR_BUTTON_PRESSED) {
const int SIZE = w->getGroupSize();
CWindow* pWindow = w->getGroupWindowByIndex((mouseCoords.x - box.x) * SIZE / box.width);
if (w != pWindow)
w->setGroupCurrent(pWindow);
if (w && !w->m_bIsFullscreen && !w->hasPopupAt(mouseCoords)) {
for (auto& wd : w->m_dWindowDecorations) {
if (!wd->allowsInput())
continue;
if (wd->getWindowDecorationRegion().containsPoint(mouseCoords)) {
wd->onMouseButtonOnDeco(mouseCoords, e);
return;
}
return;
}
}
@ -1625,7 +1624,7 @@ void CInputManager::setCursorIconOnBorder(CWindow* w) {
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
eBorderIconDirection direction = BORDERICON_NONE;
wlr_box boxFullGrabInput = {box.x - *PEXTENDBORDERGRAB - BORDERSIZE, box.y - *PEXTENDBORDERGRAB - BORDERSIZE, box.width + 2 * (*PEXTENDBORDERGRAB + BORDERSIZE),
box.height + 2 * (*PEXTENDBORDERGRAB + BORDERSIZE)};
box.height + 2 * (*PEXTENDBORDERGRAB + BORDERSIZE)};
if (!wlr_box_contains_point(&boxFullGrabInput, mouseCoords.x, mouseCoords.y) || (!m_lCurrentlyHeldButtons.empty() && !currentlyDraggedWindow)) {
direction = BORDERICON_NONE;

View file

@ -7,14 +7,12 @@
#include "../../helpers/Timer.hpp"
#include "InputMethodRelay.hpp"
enum eClickBehaviorMode
{
enum eClickBehaviorMode {
CLICKMODE_DEFAULT = 0,
CLICKMODE_KILL
};
enum eMouseBindMode
{
enum eMouseBindMode {
MBIND_INVALID = -1,
MBIND_MOVE = 0,
MBIND_RESIZE = 1,
@ -22,8 +20,7 @@ enum eMouseBindMode
MBIND_RESIZE_FORCE_RATIO = 3
};
enum eBorderIconDirection
{
enum eBorderIconDirection {
BORDERICON_NONE,
BORDERICON_UP,
BORDERICON_DOWN,
@ -118,6 +115,7 @@ class CInputManager {
// for dragging floating windows
CWindow* currentlyDraggedWindow = nullptr;
eMouseBindMode dragMode = MBIND_INVALID;
bool m_bWasDraggingWindow = false;
// for refocus to be forced
CWindow* m_pForcedFocus = nullptr;

View file

@ -24,6 +24,7 @@ eDecorationType CHyprGroupBarDecoration::getDecorationType() {
constexpr int BAR_INDICATOR_HEIGHT = 3;
constexpr int BAR_PADDING_OUTER_VERT = 2;
constexpr int BAR_TEXT_PAD = 2;
constexpr int BAR_HORIZONTAL_PADDING = 2;
//
@ -93,15 +94,13 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
if (!m_pWindow->m_sSpecialRenderData.decorate)
return;
const int PAD = 2; //2px
m_fBarWidth = (m_vLastWindowSize.x - BAR_HORIZONTAL_PADDING * (barsToDraw - 1)) / barsToDraw;
const int BARW = (m_vLastWindowSize.x - PAD * (barsToDraw - 1)) / barsToDraw;
int xoff = 0;
int xoff = 0;
for (int i = 0; i < barsToDraw; ++i) {
wlr_box rect = {m_vLastWindowPos.x + xoff - pMonitor->vecPosition.x + offset.x,
m_vLastWindowPos.y - BAR_PADDING_OUTER_VERT - BORDERSIZE - BAR_INDICATOR_HEIGHT - pMonitor->vecPosition.y + offset.y, BARW, BAR_INDICATOR_HEIGHT};
m_vLastWindowPos.y - BAR_PADDING_OUTER_VERT - BORDERSIZE - BAR_INDICATOR_HEIGHT - pMonitor->vecPosition.y + offset.y, m_fBarWidth, BAR_INDICATOR_HEIGHT};
if (rect.width <= 0 || rect.height <= 0)
break;
@ -127,15 +126,15 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
CTitleTex* pTitleTex = textureFromTitle(m_dwGroupMembers[i]->m_szTitle);
if (!pTitleTex)
pTitleTex =
m_sTitleTexs.titleTexs
.emplace_back(std::make_unique<CTitleTex>(m_dwGroupMembers[i], Vector2D{BARW * pMonitor->scale, (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale}))
.get();
pTitleTex = m_sTitleTexs.titleTexs
.emplace_back(std::make_unique<CTitleTex>(m_dwGroupMembers[i],
Vector2D{m_fBarWidth * pMonitor->scale, (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * pMonitor->scale}))
.get();
rect.height = (*PTITLEFONTSIZE + 2 * BAR_TEXT_PAD) * 0.8 * pMonitor->scale;
rect.y -= rect.height;
rect.width = BARW * pMonitor->scale;
rect.width = m_fBarWidth * pMonitor->scale;
refreshGradients();
@ -148,7 +147,7 @@ void CHyprGroupBarDecoration::draw(CMonitor* pMonitor, float a, const Vector2D&
g_pHyprOpenGL->renderTexture(pTitleTex->tex, &rect, 1.f);
}
xoff += PAD + BARW;
xoff += BAR_HORIZONTAL_PADDING + m_fBarWidth;
}
if (*PRENDERTITLES)
@ -305,3 +304,79 @@ void CHyprGroupBarDecoration::refreshGradients() {
bool CHyprGroupBarDecoration::allowsInput() {
return true;
}
bool CHyprGroupBarDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D& pos) {
if (!(!g_pKeybindManager->m_bGroupsLocked // global group lock disengaged
&& ((pDraggedWindow->m_eGroupRules & GROUP_INVADE && pDraggedWindow->m_bFirstMap) // window ignore local group locks, or
|| (!m_pWindow->getGroupHead()->m_sGroupData.locked // target unlocked
&& !(pDraggedWindow->m_sGroupData.pNextWindow && pDraggedWindow->getGroupHead()->m_sGroupData.locked))) // source unlocked or isn't group
&& !pDraggedWindow->m_sGroupData.deny // source is not denied entry
&& !(pDraggedWindow->m_eGroupRules & GROUP_BARRED && pDraggedWindow->m_bFirstMap))) // group rule doesn't prevent adding window
return true;
const float BARRELATIVEX = pos.x - m_vLastWindowPos.x - m_fBarWidth / 2;
const int WINDOWINDEX = BARRELATIVEX < 0 ? -1 : (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
CWindow* pWindowInsertAfter = m_pWindow->getGroupWindowByIndex(WINDOWINDEX);
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pDraggedWindow);
pWindowInsertAfter->insertWindowToGroup(pDraggedWindow);
if (WINDOWINDEX == -1)
std::swap(pDraggedWindow->m_sGroupData.head, pDraggedWindow->m_sGroupData.pNextWindow->m_sGroupData.head);
m_pWindow->setGroupCurrent(pDraggedWindow);
pDraggedWindow->applyGroupRules();
pDraggedWindow->updateWindowDecos();
g_pLayoutManager->getCurrentLayout()->recalculateWindow(pDraggedWindow);
return false;
}
void CHyprGroupBarDecoration::onMouseButtonOnDeco(const Vector2D& pos, wlr_pointer_button_event* e) {
if (e->state != WLR_BUTTON_PRESSED)
return;
const float BARRELATIVEX = pos.x - m_vLastWindowPos.x;
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
if (BARRELATIVEX - (m_fBarWidth + BAR_HORIZONTAL_PADDING) * WINDOWINDEX > m_fBarWidth) {
if (!g_pCompositor->isWindowActive(m_pWindow))
g_pCompositor->focusWindow(m_pWindow);
return;
}
CWindow* pWindow = m_pWindow->getGroupWindowByIndex(WINDOWINDEX);
if (pWindow != m_pWindow)
pWindow->setGroupCurrent(pWindow);
if (!g_pCompositor->isWindowActive(pWindow))
g_pCompositor->focusWindow(pWindow);
}
void CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
const float BARRELATIVEX = pos.x - m_vLastWindowPos.x;
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
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;
}
g_pInputManager->currentlyDraggedWindow = pWindow;
if (!g_pCompositor->isWindowActive(pWindow))
g_pCompositor->focusWindow(pWindow);
}

View file

@ -35,6 +35,12 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration {
virtual bool allowsInput();
virtual void onBeginWindowDragOnDeco(const Vector2D&);
virtual bool onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&);
virtual void onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*);
private:
SWindowDecorationExtents m_seExtents;
@ -45,6 +51,8 @@ class CHyprGroupBarDecoration : public IHyprWindowDecoration {
std::deque<CWindow*> m_dwGroupMembers;
float m_fBarWidth;
CTitleTex* textureFromTitle(const std::string&);
void invalidateTextures();

View file

@ -28,3 +28,11 @@ CRegion IHyprWindowDecoration::getWindowDecorationRegion() {
bool IHyprWindowDecoration::allowsInput() {
return false;
}
void IHyprWindowDecoration::onBeginWindowDragOnDeco(const Vector2D&) {}
bool IHyprWindowDecoration::onEndWindowDragOnDeco(CWindow* pDraggedWindow, const Vector2D&) {
return true;
}
void IHyprWindowDecoration::onMouseButtonOnDeco(const Vector2D&, wlr_pointer_button_event*) {}

View file

@ -39,6 +39,12 @@ class IHyprWindowDecoration {
virtual bool allowsInput();
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*);
private:
CWindow* m_pWindow = nullptr;
};