Skip to content

Commit

Permalink
layerSurface: focus last window when keyboard exclusivity is dropped
Browse files Browse the repository at this point in the history
  • Loading branch information
outfoxxed committed Jun 10, 2024
1 parent 1d02a2f commit 0f92514
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 38 deletions.
42 changes: 6 additions & 36 deletions src/desktop/LayerSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,37 +211,7 @@ void CLayerSurface::onUnmap() {
return;

// refocus if needed
if (WASLASTFOCUS) {
g_pInputManager->releaseAllMouseButtons();

Vector2D surfaceCoords;
PHLLS pFoundLayerSurface;
SP<CWLSurfaceResource> foundSurface = nullptr;

g_pCompositor->m_pLastFocus.reset();

// try to focus the last exclusive ls first
if (!g_pInputManager->m_dExclusiveLSes.empty())
g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[g_pInputManager->m_dExclusiveLSes.size() - 1]->surface->resource());

// find LS-es to focus
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
&surfaceCoords, &pFoundLayerSurface);

if (!foundSurface)
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
&surfaceCoords, &pFoundLayerSurface);

if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->m_pWorkspace)) {
// if there isn't any, focus the last window
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock();
g_pCompositor->focusWindow(nullptr);
g_pCompositor->focusWindow(PLASTWINDOW);
} else {
// otherwise, full refocus
g_pInputManager->refocus();
}
}
if (WASLASTFOCUS) g_pInputManager->refocusLastWindow(PMONITOR);

CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
g_pHyprRenderer->damageBox(&geomFixed);
Expand Down Expand Up @@ -326,11 +296,11 @@ void CLayerSurface::onCommit() {
else if (WASEXCLUSIVE && !ISEXCLUSIVE)
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });

// if the surface was focused and interactive but now isn't, refocus
if (WASLASTFOCUS && !layerSurface->current.interactivity) {
g_pInputManager->refocus();
} else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) {
// if not focused last and exclusive or accepting input + unconstrained
// if the surface was focused and interactive but now isn't, refocus
if (WASLASTFOCUS && !layerSurface->current.interactivity) {
g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID));
} else if (!WASLASTFOCUS && (ISEXCLUSIVE || (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())))) {
// if not focused last and exclusive or accepting input + unconstrained
g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons();
g_pCompositor->focusSurface(surface->resource());
Expand Down
37 changes: 37 additions & 0 deletions src/managers/input/InputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,43 @@ void CInputManager::refocus() {
mouseMoveUnified(0, true);
}

void CInputManager::refocusLastWindow(CMonitor* pMonitor) {
if (!pMonitor) {
refocus();
return;
}

Vector2D surfaceCoords;
PHLLS pFoundLayerSurface;
SP<CWLSurfaceResource> foundSurface = nullptr;

g_pInputManager->releaseAllMouseButtons();
g_pCompositor->m_pLastFocus.reset();

// first try for an exclusive layer
if (!m_dExclusiveLSes.empty())
foundSurface = m_dExclusiveLSes[m_dExclusiveLSes.size() - 1]->surface->resource();

// then any surfaces above windows on the same monitor
if (!foundSurface)
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
&surfaceCoords, &pFoundLayerSurface);

if (!foundSurface)
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
&surfaceCoords, &pFoundLayerSurface);

if (!foundSurface && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->isWorkspaceVisible(g_pCompositor->m_pLastWindow->m_pWorkspace)) {
// then the last focused window if we're on the same workspace as it
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow.lock();
g_pCompositor->focusWindow(nullptr);
g_pCompositor->focusWindow(PLASTWINDOW);
} else {
// otherwise fall back to a normal refocus.
refocus();
}
}

void CInputManager::unconstrainMouse() {
if (g_pSeatManager->mouse.expired())
return;
Expand Down
5 changes: 3 additions & 2 deletions src/managers/input/InputManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ class CInputManager {
bool isConstrained();

Vector2D getMouseCoordsInternal();
void refocus();
void simulateMouseMovement();
void refocus();
void refocusLastWindow(CMonitor* pMonitor);
void simulateMouseMovement();
void sendMotionEventsToFocused();

void setKeyboardLayout();
Expand Down

0 comments on commit 0f92514

Please sign in to comment.