mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-14 04:25:57 +01:00
Rework candidate finding on close window
This commit is contained in:
parent
1d0d350fc3
commit
c04563734e
5 changed files with 79 additions and 16 deletions
|
@ -723,6 +723,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||||
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
|
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","});
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr);
|
||||||
|
|
||||||
m_pLastFocus = nullptr;
|
m_pLastFocus = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -774,6 +776,8 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||||
// Send an event
|
// Send an event
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle});
|
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle});
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow);
|
||||||
|
|
||||||
if (pWindow->m_phForeignToplevel)
|
if (pWindow->m_phForeignToplevel)
|
||||||
wlr_foreign_toplevel_handle_v1_set_activated(pWindow->m_phForeignToplevel, true);
|
wlr_foreign_toplevel_handle_v1_set_activated(pWindow->m_phForeignToplevel, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ public:
|
||||||
|
|
||||||
const char* m_szWLDisplaySocket;
|
const char* m_szWLDisplaySocket;
|
||||||
std::string m_szInstanceSignature = "";
|
std::string m_szInstanceSignature = "";
|
||||||
std::string m_szCurrentSplash = "error";
|
std::string m_szCurrentSplash = "error";
|
||||||
|
|
||||||
std::vector<std::shared_ptr<CMonitor>> m_vMonitors;
|
std::vector<std::shared_ptr<CMonitor>> m_vMonitors;
|
||||||
std::vector<std::shared_ptr<CMonitor>> m_vRealMonitors; // for all monitors, even those turned off
|
std::vector<std::shared_ptr<CMonitor>> m_vRealMonitors; // for all monitors, even those turned off
|
||||||
|
@ -90,17 +90,17 @@ public:
|
||||||
void startCompositor();
|
void startCompositor();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
wlr_surface* m_pLastFocus = nullptr;
|
wlr_surface* m_pLastFocus = nullptr;
|
||||||
CWindow* m_pLastWindow = nullptr;
|
CWindow* m_pLastWindow = nullptr;
|
||||||
CMonitor* m_pLastMonitor = nullptr;
|
CMonitor* m_pLastMonitor = nullptr;
|
||||||
|
|
||||||
SSeat m_sSeat;
|
SSeat m_sSeat;
|
||||||
|
|
||||||
bool m_bReadyToProcess = false;
|
bool m_bReadyToProcess = false;
|
||||||
bool m_bSessionActive = true;
|
bool m_bSessionActive = true;
|
||||||
bool m_bDPMSStateON = true;
|
bool m_bDPMSStateON = true;
|
||||||
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
|
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
|
||||||
bool m_bIsShuttingDown = false;
|
bool m_bIsShuttingDown = false;
|
||||||
std::deque<uint64_t> m_dProcessPIDsOnShutdown; // stores PIDs of apps to kill later when shutting down
|
std::deque<uint64_t> m_dProcessPIDsOnShutdown; // stores PIDs of apps to kill later when shutting down
|
||||||
|
|
||||||
// ------------------------------------------------- //
|
// ------------------------------------------------- //
|
||||||
|
|
|
@ -548,13 +548,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||||
|
|
||||||
// refocus on a new window if needed
|
// refocus on a new window if needed
|
||||||
if (wasLastWindow) {
|
if (wasLastWindow) {
|
||||||
auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowIdeal(PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.f);
|
const auto PWINDOWCANDIDATE = g_pLayoutManager->getCurrentLayout()->getNextWindowCandidate(PWINDOW);
|
||||||
|
|
||||||
if (PWORKSPACE->m_bHasFullscreenWindow && ((!PWINDOWCANDIDATE || !PWINDOWCANDIDATE->m_bCreatedOverFullscreen) || !PWINDOW->m_bIsFloating))
|
|
||||||
PWINDOWCANDIDATE = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
|
||||||
|
|
||||||
if (!PWINDOWCANDIDATE || PWINDOW == PWINDOWCANDIDATE || !PWINDOWCANDIDATE->m_bIsMapped || PWINDOWCANDIDATE->isHidden() || PWINDOWCANDIDATE->m_bX11ShouldntFocus || PWINDOWCANDIDATE->m_iX11Type == 2 || PWINDOWCANDIDATE->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)
|
|
||||||
PWINDOWCANDIDATE = nullptr;
|
|
||||||
|
|
||||||
Debug::log(LOG, "On closed window, new focused candidate is %x", PWINDOWCANDIDATE);
|
Debug::log(LOG, "On closed window, new focused candidate is %x", PWINDOWCANDIDATE);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,9 @@ void IHyprLayout::onWindowRemoved(CWindow* pWindow) {
|
||||||
} else {
|
} else {
|
||||||
onWindowRemovedTiling(pWindow);
|
onWindowRemovedTiling(pWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pWindow == m_pLastTiledWindow)
|
||||||
|
m_pLastTiledWindow = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IHyprLayout::onWindowRemovedFloating(CWindow* pWindow) {
|
void IHyprLayout::onWindowRemovedFloating(CWindow* pWindow) {
|
||||||
|
@ -311,6 +314,9 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||||
|
|
||||||
// fix pseudo leaving artifacts
|
// fix pseudo leaving artifacts
|
||||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||||
|
|
||||||
|
if (pWindow == g_pCompositor->m_pLastWindow)
|
||||||
|
m_pLastTiledWindow = pWindow;
|
||||||
} else {
|
} else {
|
||||||
pWindow->m_vSize = pWindow->m_vRealSize.vec();
|
pWindow->m_vSize = pWindow->m_vRealSize.vec();
|
||||||
pWindow->m_vPosition = pWindow->m_vRealPosition.vec();
|
pWindow->m_vPosition = pWindow->m_vRealPosition.vec();
|
||||||
|
@ -325,6 +331,9 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||||
|
|
||||||
pWindow->m_sSpecialRenderData.rounding = true;
|
pWindow->m_sSpecialRenderData.rounding = true;
|
||||||
|
|
||||||
|
if (pWindow == m_pLastTiledWindow)
|
||||||
|
m_pLastTiledWindow = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
|
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
|
||||||
|
@ -347,3 +356,47 @@ void IHyprLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) {
|
||||||
|
|
||||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IHyprLayout::onWindowFocusChange(CWindow* pNewFocus) {
|
||||||
|
m_pLastTiledWindow = pNewFocus && !pNewFocus->m_bIsFloating ? pNewFocus : m_pLastTiledWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWindow* IHyprLayout::getNextWindowCandidate(CWindow* pWindow) {
|
||||||
|
// although we don't expect nullptrs here, let's verify jic
|
||||||
|
if (!pWindow)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
|
// first of all, if this is a fullscreen workspace,
|
||||||
|
if (PWORKSPACE->m_bHasFullscreenWindow)
|
||||||
|
return g_pCompositor->getFullscreenWindowOnWorkspace(pWindow->m_iWorkspaceID);
|
||||||
|
|
||||||
|
if (pWindow->m_bIsFloating) {
|
||||||
|
// the window was floating, let's try the last tiled window.
|
||||||
|
|
||||||
|
if (m_pLastTiledWindow && m_pLastTiledWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID)
|
||||||
|
return m_pLastTiledWindow;
|
||||||
|
|
||||||
|
// if we don't, let's try to find any window that is in the middle
|
||||||
|
if (const auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowIdeal(pWindow->m_vRealPosition.goalv() + pWindow->m_vRealSize.goalv() / 2.f); PWINDOWCANDIDATE)
|
||||||
|
return PWINDOWCANDIDATE;
|
||||||
|
|
||||||
|
// if not, floating window
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (w->m_bIsMapped && !w->isHidden() && w->m_bIsFloating && w->m_iX11Type != 2 && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && !w->m_bX11ShouldntFocus)
|
||||||
|
return w.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is no candidate, too bad
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it was a tiled window, we first try to find the window that will replace it.
|
||||||
|
const auto PWINDOWCANDIDATE = g_pCompositor->vectorToWindowIdeal(pWindow->m_vRealPosition.goalv() + pWindow->m_vRealSize.goalv() / 2.f);
|
||||||
|
|
||||||
|
if (!PWINDOWCANDIDATE || pWindow == PWINDOWCANDIDATE || !PWINDOWCANDIDATE->m_bIsMapped || PWINDOWCANDIDATE->isHidden() || PWINDOWCANDIDATE->m_bX11ShouldntFocus || PWINDOWCANDIDATE->m_iX11Type == 2 || PWINDOWCANDIDATE->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return PWINDOWCANDIDATE;
|
||||||
|
}
|
||||||
|
|
|
@ -123,10 +123,22 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual std::string getLayoutName() = 0;
|
virtual std::string getLayoutName() = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Called for getting the next candidate for a focus
|
||||||
|
*/
|
||||||
|
virtual CWindow* getNextWindowCandidate(CWindow*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Internal: called when window focus changes
|
||||||
|
*/
|
||||||
|
virtual void onWindowFocusChange(CWindow*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector2D m_vBeginDragXY;
|
Vector2D m_vBeginDragXY;
|
||||||
Vector2D m_vLastDragXY;
|
Vector2D m_vLastDragXY;
|
||||||
Vector2D m_vBeginDragPositionXY;
|
Vector2D m_vBeginDragPositionXY;
|
||||||
Vector2D m_vBeginDragSizeXY;
|
Vector2D m_vBeginDragSizeXY;
|
||||||
int m_iGrabbedCorner = 0;
|
int m_iGrabbedCorner = 0;
|
||||||
|
|
||||||
|
CWindow* m_pLastTiledWindow = nullptr;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue