mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-23 05:09:49 +01:00
keybinds: Add dispatcher for xmonad/qtile-style workspace switching (#4439)
* feat: implement xmonad/qtile-style workspace switching Implements the focusWorkspaceOnCurrentMonitor dispatcher and function, which implements XMonad/Qtile-style workspace switching. When called, focusWorkspaceOnCurrentMonitor will: 1. Send the requested workspace to the current monitor, 2. If the workspace was previously active on a different monitor, replace it with the workspace that was previously active on the current monitor, 3. Focus the workspace on the current monitor. * fix: address PR comments
This commit is contained in:
parent
f14c5ea5c5
commit
3c964a9fdc
6 changed files with 109 additions and 64 deletions
|
@ -2114,7 +2114,7 @@ CMonitor* CCompositor::getMonitorFromString(const std::string& name) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMonitor) {
|
||||
void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMonitor, bool noWarpCursor) {
|
||||
|
||||
// We trust the workspace and monitor to be correct.
|
||||
|
||||
|
@ -2200,7 +2200,8 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
|
|||
|
||||
pWorkspace->startAnim(true, true, true);
|
||||
|
||||
wlr_cursor_warp(m_sWLRCursor, nullptr, pMonitor->vecPosition.x + pMonitor->vecTransformedSize.x / 2, pMonitor->vecPosition.y + pMonitor->vecTransformedSize.y / 2);
|
||||
if (!noWarpCursor)
|
||||
wlr_cursor_warp(m_sWLRCursor, nullptr, pMonitor->vecPosition.x + pMonitor->vecTransformedSize.x / 2, pMonitor->vecPosition.y + pMonitor->vecTransformedSize.y / 2);
|
||||
|
||||
g_pInputManager->sendMotionEventsToFocused();
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ class CCompositor {
|
|||
void updateWorkspaceWindows(const int64_t& id);
|
||||
void updateWindowAnimatedDecorationValues(CWindow*);
|
||||
int getNextAvailableMonitorID(std::string const& name);
|
||||
void moveWorkspaceToMonitor(CWorkspace*, CMonitor*);
|
||||
void moveWorkspaceToMonitor(CWorkspace*, CMonitor*, bool noWarpCursor = false);
|
||||
void swapActiveWorkspaces(CMonitor*, CMonitor*);
|
||||
CMonitor* getMonitorFromString(const std::string&);
|
||||
bool workspaceIDOutOfBounds(const int64_t&);
|
||||
|
|
|
@ -502,7 +502,7 @@ float CMonitor::getDefaultScale() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal, bool noMouseMove) {
|
||||
void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal, bool noMouseMove, bool noFocus) {
|
||||
if (!pWorkspace)
|
||||
return;
|
||||
|
||||
|
@ -533,7 +533,7 @@ void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal, bool
|
|||
}
|
||||
}
|
||||
|
||||
if (!g_pCompositor->m_pLastMonitor->specialWorkspaceID) {
|
||||
if (!noFocus && !g_pCompositor->m_pLastMonitor->specialWorkspaceID) {
|
||||
static auto* const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||
CWindow* pWindow = pWorkspace->getLastFocusedWindow();
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ class CMonitor {
|
|||
void setMirror(const std::string&);
|
||||
bool isMirror();
|
||||
float getDefaultScale();
|
||||
void changeWorkspace(CWorkspace* const pWorkspace, bool internal = false, bool noMouseMove = false);
|
||||
void changeWorkspace(CWorkspace* const pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
||||
void changeWorkspace(const int& id, bool internal = false);
|
||||
void setSpecialWorkspace(CWorkspace* const pWorkspace);
|
||||
void setSpecialWorkspace(const int& id);
|
||||
|
|
|
@ -19,64 +19,65 @@
|
|||
CKeybindManager::CKeybindManager() {
|
||||
// initialize all dispatchers
|
||||
|
||||
m_mDispatchers["exec"] = spawn;
|
||||
m_mDispatchers["execr"] = spawnRaw;
|
||||
m_mDispatchers["killactive"] = killActive;
|
||||
m_mDispatchers["closewindow"] = kill;
|
||||
m_mDispatchers["togglefloating"] = toggleActiveFloating;
|
||||
m_mDispatchers["workspace"] = changeworkspace;
|
||||
m_mDispatchers["renameworkspace"] = renameWorkspace;
|
||||
m_mDispatchers["fullscreen"] = fullscreenActive;
|
||||
m_mDispatchers["fakefullscreen"] = fakeFullscreenActive;
|
||||
m_mDispatchers["movetoworkspace"] = moveActiveToWorkspace;
|
||||
m_mDispatchers["movetoworkspacesilent"] = moveActiveToWorkspaceSilent;
|
||||
m_mDispatchers["pseudo"] = toggleActivePseudo;
|
||||
m_mDispatchers["movefocus"] = moveFocusTo;
|
||||
m_mDispatchers["movewindow"] = moveActiveTo;
|
||||
m_mDispatchers["swapwindow"] = swapActive;
|
||||
m_mDispatchers["centerwindow"] = centerWindow;
|
||||
m_mDispatchers["togglegroup"] = toggleGroup;
|
||||
m_mDispatchers["changegroupactive"] = changeGroupActive;
|
||||
m_mDispatchers["movegroupwindow"] = moveGroupWindow;
|
||||
m_mDispatchers["togglesplit"] = toggleSplit;
|
||||
m_mDispatchers["splitratio"] = alterSplitRatio;
|
||||
m_mDispatchers["focusmonitor"] = focusMonitor;
|
||||
m_mDispatchers["movecursortocorner"] = moveCursorToCorner;
|
||||
m_mDispatchers["movecursor"] = moveCursor;
|
||||
m_mDispatchers["workspaceopt"] = workspaceOpt;
|
||||
m_mDispatchers["exit"] = exitHyprland;
|
||||
m_mDispatchers["movecurrentworkspacetomonitor"] = moveCurrentWorkspaceToMonitor;
|
||||
m_mDispatchers["moveworkspacetomonitor"] = moveWorkspaceToMonitor;
|
||||
m_mDispatchers["togglespecialworkspace"] = toggleSpecialWorkspace;
|
||||
m_mDispatchers["forcerendererreload"] = forceRendererReload;
|
||||
m_mDispatchers["resizeactive"] = resizeActive;
|
||||
m_mDispatchers["moveactive"] = moveActive;
|
||||
m_mDispatchers["cyclenext"] = circleNext;
|
||||
m_mDispatchers["focuswindowbyclass"] = focusWindow;
|
||||
m_mDispatchers["focuswindow"] = focusWindow;
|
||||
m_mDispatchers["submap"] = setSubmap;
|
||||
m_mDispatchers["pass"] = pass;
|
||||
m_mDispatchers["layoutmsg"] = layoutmsg;
|
||||
m_mDispatchers["toggleopaque"] = toggleOpaque;
|
||||
m_mDispatchers["dpms"] = dpms;
|
||||
m_mDispatchers["movewindowpixel"] = moveWindow;
|
||||
m_mDispatchers["resizewindowpixel"] = resizeWindow;
|
||||
m_mDispatchers["swapnext"] = swapnext;
|
||||
m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces;
|
||||
m_mDispatchers["pin"] = pinActive;
|
||||
m_mDispatchers["mouse"] = mouse;
|
||||
m_mDispatchers["bringactivetotop"] = bringActiveToTop;
|
||||
m_mDispatchers["alterzorder"] = alterZOrder;
|
||||
m_mDispatchers["focusurgentorlast"] = focusUrgentOrLast;
|
||||
m_mDispatchers["focuscurrentorlast"] = focusCurrentOrLast;
|
||||
m_mDispatchers["lockgroups"] = lockGroups;
|
||||
m_mDispatchers["lockactivegroup"] = lockActiveGroup;
|
||||
m_mDispatchers["moveintogroup"] = moveIntoGroup;
|
||||
m_mDispatchers["moveoutofgroup"] = moveOutOfGroup;
|
||||
m_mDispatchers["movewindoworgroup"] = moveWindowOrGroup;
|
||||
m_mDispatchers["setignoregrouplock"] = setIgnoreGroupLock;
|
||||
m_mDispatchers["denywindowfromgroup"] = denyWindowFromGroup;
|
||||
m_mDispatchers["global"] = global;
|
||||
m_mDispatchers["exec"] = spawn;
|
||||
m_mDispatchers["execr"] = spawnRaw;
|
||||
m_mDispatchers["killactive"] = killActive;
|
||||
m_mDispatchers["closewindow"] = kill;
|
||||
m_mDispatchers["togglefloating"] = toggleActiveFloating;
|
||||
m_mDispatchers["workspace"] = changeworkspace;
|
||||
m_mDispatchers["renameworkspace"] = renameWorkspace;
|
||||
m_mDispatchers["fullscreen"] = fullscreenActive;
|
||||
m_mDispatchers["fakefullscreen"] = fakeFullscreenActive;
|
||||
m_mDispatchers["movetoworkspace"] = moveActiveToWorkspace;
|
||||
m_mDispatchers["movetoworkspacesilent"] = moveActiveToWorkspaceSilent;
|
||||
m_mDispatchers["pseudo"] = toggleActivePseudo;
|
||||
m_mDispatchers["movefocus"] = moveFocusTo;
|
||||
m_mDispatchers["movewindow"] = moveActiveTo;
|
||||
m_mDispatchers["swapwindow"] = swapActive;
|
||||
m_mDispatchers["centerwindow"] = centerWindow;
|
||||
m_mDispatchers["togglegroup"] = toggleGroup;
|
||||
m_mDispatchers["changegroupactive"] = changeGroupActive;
|
||||
m_mDispatchers["movegroupwindow"] = moveGroupWindow;
|
||||
m_mDispatchers["togglesplit"] = toggleSplit;
|
||||
m_mDispatchers["splitratio"] = alterSplitRatio;
|
||||
m_mDispatchers["focusmonitor"] = focusMonitor;
|
||||
m_mDispatchers["movecursortocorner"] = moveCursorToCorner;
|
||||
m_mDispatchers["movecursor"] = moveCursor;
|
||||
m_mDispatchers["workspaceopt"] = workspaceOpt;
|
||||
m_mDispatchers["exit"] = exitHyprland;
|
||||
m_mDispatchers["movecurrentworkspacetomonitor"] = moveCurrentWorkspaceToMonitor;
|
||||
m_mDispatchers["focusworkspaceoncurrentmonitor"] = focusWorkspaceOnCurrentMonitor;
|
||||
m_mDispatchers["moveworkspacetomonitor"] = moveWorkspaceToMonitor;
|
||||
m_mDispatchers["togglespecialworkspace"] = toggleSpecialWorkspace;
|
||||
m_mDispatchers["forcerendererreload"] = forceRendererReload;
|
||||
m_mDispatchers["resizeactive"] = resizeActive;
|
||||
m_mDispatchers["moveactive"] = moveActive;
|
||||
m_mDispatchers["cyclenext"] = circleNext;
|
||||
m_mDispatchers["focuswindowbyclass"] = focusWindow;
|
||||
m_mDispatchers["focuswindow"] = focusWindow;
|
||||
m_mDispatchers["submap"] = setSubmap;
|
||||
m_mDispatchers["pass"] = pass;
|
||||
m_mDispatchers["layoutmsg"] = layoutmsg;
|
||||
m_mDispatchers["toggleopaque"] = toggleOpaque;
|
||||
m_mDispatchers["dpms"] = dpms;
|
||||
m_mDispatchers["movewindowpixel"] = moveWindow;
|
||||
m_mDispatchers["resizewindowpixel"] = resizeWindow;
|
||||
m_mDispatchers["swapnext"] = swapnext;
|
||||
m_mDispatchers["swapactiveworkspaces"] = swapActiveWorkspaces;
|
||||
m_mDispatchers["pin"] = pinActive;
|
||||
m_mDispatchers["mouse"] = mouse;
|
||||
m_mDispatchers["bringactivetotop"] = bringActiveToTop;
|
||||
m_mDispatchers["alterzorder"] = alterZOrder;
|
||||
m_mDispatchers["focusurgentorlast"] = focusUrgentOrLast;
|
||||
m_mDispatchers["focuscurrentorlast"] = focusCurrentOrLast;
|
||||
m_mDispatchers["lockgroups"] = lockGroups;
|
||||
m_mDispatchers["lockactivegroup"] = lockActiveGroup;
|
||||
m_mDispatchers["moveintogroup"] = moveIntoGroup;
|
||||
m_mDispatchers["moveoutofgroup"] = moveOutOfGroup;
|
||||
m_mDispatchers["movewindoworgroup"] = moveWindowOrGroup;
|
||||
m_mDispatchers["setignoregrouplock"] = setIgnoreGroupLock;
|
||||
m_mDispatchers["denywindowfromgroup"] = denyWindowFromGroup;
|
||||
m_mDispatchers["global"] = global;
|
||||
|
||||
m_tScrollTimer.reset();
|
||||
|
||||
|
@ -1504,6 +1505,48 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
|||
g_pCompositor->moveWorkspaceToMonitor(PWORKSPACE, PMONITOR);
|
||||
}
|
||||
|
||||
void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) {
|
||||
std::string workspaceName;
|
||||
const int WORKSPACEID = getWorkspaceIDFromString(args, workspaceName);
|
||||
|
||||
if (WORKSPACEID == WORKSPACE_INVALID) {
|
||||
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor invalid workspace!");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PCURRMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||
|
||||
if (!PCURRMONITOR) {
|
||||
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor monitor doesn't exist!");
|
||||
return;
|
||||
}
|
||||
|
||||
auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||
|
||||
if (!PWORKSPACE) {
|
||||
PWORKSPACE = g_pCompositor->createNewWorkspace(WORKSPACEID, PCURRMONITOR->ID);
|
||||
// we can skip the moving, since it's already on the current monitor
|
||||
changeworkspace(PWORKSPACE->getConfigName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (PWORKSPACE->m_iMonitorID != PCURRMONITOR->ID) {
|
||||
const auto POLDMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
if (!POLDMONITOR) { // wat
|
||||
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor old monitor doesn't exist!");
|
||||
return;
|
||||
}
|
||||
if (POLDMONITOR->activeWorkspace == WORKSPACEID) {
|
||||
g_pCompositor->swapActiveWorkspaces(POLDMONITOR, PCURRMONITOR);
|
||||
return;
|
||||
} else {
|
||||
g_pCompositor->moveWorkspaceToMonitor(PWORKSPACE, PCURRMONITOR, true);
|
||||
}
|
||||
}
|
||||
|
||||
changeworkspace(PWORKSPACE->getConfigName());
|
||||
}
|
||||
|
||||
void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
||||
|
||||
static auto* const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||
|
|
|
@ -134,6 +134,7 @@ class CKeybindManager {
|
|||
static void exitHyprland(std::string);
|
||||
static void moveCurrentWorkspaceToMonitor(std::string);
|
||||
static void moveWorkspaceToMonitor(std::string);
|
||||
static void focusWorkspaceOnCurrentMonitor(std::string);
|
||||
static void toggleSpecialWorkspace(std::string);
|
||||
static void forceRendererReload(std::string);
|
||||
static void resizeActive(std::string);
|
||||
|
|
Loading…
Reference in a new issue