Added scratchpads.

This commit is contained in:
vaxerski 2022-04-03 22:02:25 +02:00
parent 0b9a33228b
commit 0da4b298c5
9 changed files with 136 additions and 15 deletions

View file

@ -12,6 +12,7 @@ focus_when_hover=1 # 0 - do not switch the focus when hover (only for tiling)
main_mod=SUPER # For moving, resizing main_mod=SUPER # For moving, resizing
intelligent_transients=1 # keeps transients always on top. intelligent_transients=1 # keeps transients always on top.
no_unmap_saving=1 # disables saving unmapped windows (seems to break sometimes) no_unmap_saving=1 # disables saving unmapped windows (seems to break sometimes)
scratchpad_mon=0 # self-explanatory
# Execs # Execs
# exec-once=/home/me/MyEpicShellScript # will exec the script only when the WM launches # exec-once=/home/me/MyEpicShellScript # will exec the script only when the WM launches
@ -110,6 +111,9 @@ bind=SUPERSHIFT,7,movetoworkspace,7
bind=SUPERSHIFT,8,movetoworkspace,8 bind=SUPERSHIFT,8,movetoworkspace,8
bind=SUPERSHIFT,9,movetoworkspace,9 bind=SUPERSHIFT,9,movetoworkspace,9
bind=SUPERSHIFT,S,movetoworkspace,scratchpad
bind=SUPER,S,scratchpad,
bind=SUPER,SPACE,togglefloating, bind=SUPER,SPACE,togglefloating,
bind=SUPER,equals,splitratio,+ bind=SUPER,equals,splitratio,+

View file

@ -147,6 +147,9 @@ void KeybindManager::movefocus(std::string arg) {
void KeybindManager::movetoworkspace(std::string arg) { void KeybindManager::movetoworkspace(std::string arg) {
try { try {
if (arg == "scratchpad")
g_pWindowManager->moveActiveWindowToWorkspace(SCRATCHPAD_ID);
else
g_pWindowManager->moveActiveWindowToWorkspace(stoi(arg)); g_pWindowManager->moveActiveWindowToWorkspace(stoi(arg));
} catch (...) { } catch (...) {
Debug::log(ERR, "Invalid arg in movetoworkspace, arg: " + arg); Debug::log(ERR, "Invalid arg in movetoworkspace, arg: " + arg);
@ -243,3 +246,16 @@ void KeybindManager::togglePseudoActive(std::string args) {
PWINDOW->setDirty(true); PWINDOW->setDirty(true);
} }
void KeybindManager::toggleScratchpad(std::string args) {
if (g_pWindowManager->getWindowsOnWorkspace(SCRATCHPAD_ID) == 0)
return;
g_pWindowManager->scratchpadActive = !g_pWindowManager->scratchpadActive;
g_pWindowManager->setAllWorkspaceWindowsDirtyByID(SCRATCHPAD_ID);
const auto NEWTOP = g_pWindowManager->findFirstWindowOnWorkspace(SCRATCHPAD_ID);
if (NEWTOP)
g_pWindowManager->setFocusedWindow(NEWTOP->getDrawable());
}

View file

@ -29,4 +29,5 @@ namespace KeybindManager {
void movetoworkspace(std::string args); void movetoworkspace(std::string args);
void changeSplitRatio(std::string args); void changeSplitRatio(std::string args);
void togglePseudoActive(std::string args); void togglePseudoActive(std::string args);
void toggleScratchpad(std::string args);
}; };

View file

@ -19,6 +19,7 @@ void ConfigManager::init() {
configValues["main_mod"].strValue = "SUPER"; configValues["main_mod"].strValue = "SUPER";
configValues["intelligent_transients"].intValue = 1; configValues["intelligent_transients"].intValue = 1;
configValues["no_unmap_saving"].intValue = 1; configValues["no_unmap_saving"].intValue = 1;
configValues["scratchpad_mon"].intValue = 1;
configValues["focus_when_hover"].intValue = 1; configValues["focus_when_hover"].intValue = 1;
@ -126,6 +127,7 @@ void handleBind(const std::string& command, const std::string& value) {
if (HANDLER == "togglefloating") dispatcher = KeybindManager::toggleActiveWindowFloating; if (HANDLER == "togglefloating") dispatcher = KeybindManager::toggleActiveWindowFloating;
if (HANDLER == "splitratio") dispatcher = KeybindManager::changeSplitRatio; if (HANDLER == "splitratio") dispatcher = KeybindManager::changeSplitRatio;
if (HANDLER == "pseudo") dispatcher = KeybindManager::togglePseudoActive; if (HANDLER == "pseudo") dispatcher = KeybindManager::togglePseudoActive;
if (HANDLER == "scratchpad") dispatcher = KeybindManager::toggleScratchpad;
if (dispatcher && KEY != 0) if (dispatcher && KEY != 0)
KeybindManager::keybinds.push_back(Keybind(KeybindManager::modToMask(MOD), KEY, COMMAND, dispatcher)); KeybindManager::keybinds.push_back(Keybind(KeybindManager::modToMask(MOD), KEY, COMMAND, dispatcher));
@ -407,6 +409,14 @@ void ConfigManager::loadConfigLoadVars() {
isFirstLaunch = false; isFirstLaunch = false;
if (ORIGBORDERSIZE != configValues["border_size"].intValue) EWMH::refreshAllExtents(); if (ORIGBORDERSIZE != configValues["border_size"].intValue) EWMH::refreshAllExtents();
// scratchpad mon
if (configValues["scratchpad_mon"].intValue > g_pWindowManager->monitors.size()) {
configValues["scratchpad_mon"].intValue = 0;
Debug::log(ERR, "Invalid scratchpad mon, falling back to 0");
}
if (const auto PSCRATCH = g_pWindowManager->getWorkspaceByID(SCRATCHPAD_ID); PSCRATCH)
PSCRATCH->setMonitor(configValues["scratchpad_mod"].intValue);
} }
void ConfigManager::applyKeybindsToX() { void ConfigManager::applyKeybindsToX() {

View file

@ -99,3 +99,5 @@
#define _NET_MOVERESIZE_WINDOW_Y (1 << 9) #define _NET_MOVERESIZE_WINDOW_Y (1 << 9)
#define _NET_MOVERESIZE_WINDOW_WIDTH (1 << 10) #define _NET_MOVERESIZE_WINDOW_WIDTH (1 << 10)
#define _NET_MOVERESIZE_WINDOW_HEIGHT (1 << 11) #define _NET_MOVERESIZE_WINDOW_HEIGHT (1 << 11)
#define SCRATCHPAD_ID 1337420

View file

@ -539,9 +539,12 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
// Set the parent // Set the parent
// check if lastwindow is on our workspace // check if lastwindow is on our workspace
if (auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); (PLASTWINDOW && PLASTWINDOW->getWorkspaceID() == g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) || wasfloating || (forcemonitor != -1 && forcemonitor != PMONITOR->ID)) { if (auto PLASTWINDOW = g_pWindowManager->getWindowFromDrawable(g_pWindowManager->LastWindow); (PLASTWINDOW && PLASTWINDOW->getWorkspaceID() == g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) || wasfloating || (forcemonitor != -1 && forcemonitor != PMONITOR->ID) || PWINDOWINARR->getWorkspaceID() == SCRATCHPAD_ID) {
// LastWindow is on our workspace, let's make a new split node // LastWindow is on our workspace, let's make a new split node
if (PWINDOWINARR->getWorkspaceID() == SCRATCHPAD_ID)
PLASTWINDOW = g_pWindowManager->findPreferredOnScratchpad();
else {
if (wasfloating || (forcemonitor != -1 && forcemonitor != PMONITOR->ID) || (forcemonitor != -1 && PLASTWINDOW->getWorkspaceID() != g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) || PLASTWINDOW->getIsFloating()) { if (wasfloating || (forcemonitor != -1 && forcemonitor != PMONITOR->ID) || (forcemonitor != -1 && PLASTWINDOW->getWorkspaceID() != g_pWindowManager->activeWorkspaces[CURRENTSCREEN]) || PLASTWINDOW->getIsFloating()) {
// if it's force monitor, find the first on a workspace. // if it's force monitor, find the first on a workspace.
if ((forcemonitor != -1 && forcemonitor != PMONITOR->ID) || (forcemonitor != -1 && PLASTWINDOW->getWorkspaceID() != g_pWindowManager->activeWorkspaces[CURRENTSCREEN])) { if ((forcemonitor != -1 && forcemonitor != PMONITOR->ID) || (forcemonitor != -1 && PLASTWINDOW->getWorkspaceID() != g_pWindowManager->activeWorkspaces[CURRENTSCREEN])) {
@ -551,6 +554,7 @@ CWindow* Events::remapWindow(int windowID, bool wasfloating, int forcemonitor) {
PLASTWINDOW = g_pWindowManager->findWindowAtCursor(); PLASTWINDOW = g_pWindowManager->findWindowAtCursor();
} }
} }
}
if (PLASTWINDOW && PLASTWINDOW->getDrawable() != windowID) { if (PLASTWINDOW && PLASTWINDOW->getDrawable() != windowID) {
CWindow newWindowSplitNode; CWindow newWindowSplitNode;
@ -664,6 +668,13 @@ void Events::eventMapWindow(xcb_generic_event_t* event) {
return; return;
} }
if (g_pWindowManager->scratchpadActive) {
KeybindManager::toggleScratchpad("");
const auto PNEW = g_pWindowManager->findWindowAtCursor();
g_pWindowManager->LastWindow = PNEW ? PNEW->getDrawable() : 0;
}
CWindow window; CWindow window;
window.setDrawable(E->window); window.setDrawable(E->window);
g_pWindowManager->addWindowToVectorSafe(window); g_pWindowManager->addWindowToVectorSafe(window);

View file

@ -98,6 +98,8 @@ void EWMH::updateDesktops() {
int msglen = 0; int msglen = 0;
for (auto& work : workspacesVec) { for (auto& work : workspacesVec) {
if (work.getID() == SCRATCHPAD_ID)
continue;
msglen += strlen(std::to_string(work.getID()).c_str()) + 1; msglen += strlen(std::to_string(work.getID()).c_str()) + 1;
} }
@ -105,6 +107,9 @@ void EWMH::updateDesktops() {
int curpos = 0; int curpos = 0;
for (auto& work : workspacesVec) { for (auto& work : workspacesVec) {
for (int i = 0; i < strlen(std::to_string(work.getID()).c_str()) + 1; ++i) { for (int i = 0; i < strlen(std::to_string(work.getID()).c_str()) + 1; ++i) {
if (work.getID() == SCRATCHPAD_ID)
break;
names[curpos] = std::to_string(work.getID())[i]; names[curpos] = std::to_string(work.getID())[i];
++curpos; ++curpos;
} }

View file

@ -195,6 +195,14 @@ void CWindowManager::setupManager() {
updateRootCursor(); updateRootCursor();
CWorkspace scratchpad;
scratchpad.setID(SCRATCHPAD_ID);
for (long unsigned int i = 0; i < monitors.size(); ++i) {
if (monitors[i].primary)
scratchpad.setMonitor(monitors[i].ID);
}
workspaces.push_back(scratchpad);
Debug::log(LOG, "Finished setup!"); Debug::log(LOG, "Finished setup!");
// TODO: EWMH // TODO: EWMH
@ -942,6 +950,13 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) {
} }
} }
if (pWindow->getWorkspaceID() == SCRATCHPAD_ID) {
TEMPEFFECTIVEPOS = TEMPEFFECTIVEPOS + ((TEMPEFFECTIVESIZE - TEMPEFFECTIVESIZE * 0.75f) * 0.5f);
TEMPEFFECTIVESIZE = TEMPEFFECTIVESIZE * 0.75f;
setAWindowTop(pWindow->getDrawable());
}
pWindow->setEffectivePosition(TEMPEFFECTIVEPOS); pWindow->setEffectivePosition(TEMPEFFECTIVEPOS);
pWindow->setEffectiveSize(TEMPEFFECTIVESIZE); pWindow->setEffectiveSize(TEMPEFFECTIVESIZE);
} }
@ -955,7 +970,7 @@ CWindow* CWindowManager::findWindowAtCursor() {
const auto WORKSPACE = activeWorkspaces[getMonitorFromCursor()->ID]; const auto WORKSPACE = activeWorkspaces[getMonitorFromCursor()->ID];
for (auto& window : windows) { for (auto& window : windows) {
if (window.getWorkspaceID() == WORKSPACE && !window.getIsFloating() && window.getDrawable() > 0 && window.getConstructed()) { if (window.getWorkspaceID() == WORKSPACE && !window.getIsFloating() && window.getDrawable() > 0 && window.getConstructed() && window.getWorkspaceID() != SCRATCHPAD_ID) {
if (cursorPos.x >= window.getPosition().x if (cursorPos.x >= window.getPosition().x
&& cursorPos.x <= window.getPosition().x + window.getSize().x && cursorPos.x <= window.getPosition().x + window.getSize().x
@ -980,6 +995,22 @@ CWindow* CWindowManager::findFirstWindowOnWorkspace(const int& work) {
return nullptr; return nullptr;
} }
CWindow* CWindowManager::findPreferredOnScratchpad() {
Vector2D topSize;
CWindow* pTop = nullptr;
for (auto& w : windows) {
if (w.getWorkspaceID() == SCRATCHPAD_ID && w.getDrawable() > 0 && w.getConstructed()) {
if (w.getSize().x * w.getSize().y > topSize.x * topSize.y) {
topSize = w.getSize();
pTop = &w;
}
}
}
return pTop;
}
void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) { void CWindowManager::calculateNewTileSetOldTile(CWindow* pWindow) {
// Get the parent and both children, one of which will be pWindow // Get the parent and both children, one of which will be pWindow
@ -1304,6 +1335,9 @@ void CWindowManager::closeWindowAllChecks(int64_t id) {
CLOSEDWINDOW->setDead(true); CLOSEDWINDOW->setDead(true);
if (CLOSEDWINDOW->getWorkspaceID() != SCRATCHPAD_ID && scratchpadActive)
scratchpadActive = false;
if (const auto WORKSPACE = getWorkspaceByID(CLOSEDWINDOW->getWorkspaceID()); WORKSPACE && CLOSEDWINDOW->getFullscreen()) if (const auto WORKSPACE = getWorkspaceByID(CLOSEDWINDOW->getWorkspaceID()); WORKSPACE && CLOSEDWINDOW->getFullscreen())
WORKSPACE->setHasFullscreenWindow(false); WORKSPACE->setHasFullscreenWindow(false);
@ -1539,7 +1573,11 @@ void CWindowManager::moveActiveWindowToWorkspace(int workspace) {
PWINDOW = getWindowFromDrawable(LastWindow); PWINDOW = getWindowFromDrawable(LastWindow);
PWINDOW->setDead(false); PWINDOW->setDead(false);
if (const auto WORKSPACE = getWorkspaceByID(PWINDOW->getWorkspaceID()); WORKSPACE && PWINDOW->getFullscreen()) const auto WORKSPACE = getWorkspaceByID(PWINDOW->getWorkspaceID());
auto workspacesBefore = activeWorkspaces;
if (WORKSPACE && PWINDOW->getFullscreen())
WORKSPACE->setHasFullscreenWindow(false); WORKSPACE->setHasFullscreenWindow(false);
changeWorkspaceByID(workspace); changeWorkspaceByID(workspace);
@ -1547,7 +1585,11 @@ void CWindowManager::moveActiveWindowToWorkspace(int workspace) {
// Find new mon // Find new mon
int NEWMONITOR = 0; int NEWMONITOR = 0;
for (long unsigned int i = 0; i < activeWorkspaces.size(); ++i) { for (long unsigned int i = 0; i < activeWorkspaces.size(); ++i) {
if (activeWorkspaces[i] == workspace) { if (workspace == SCRATCHPAD_ID) {
if (monitors[i].ID == ConfigManager::getInt("scratchpad_mon"))
NEWMONITOR = i;
}
else if (activeWorkspaces[i] == workspace) {
NEWMONITOR = i; NEWMONITOR = i;
} }
} }
@ -1561,15 +1603,24 @@ void CWindowManager::moveActiveWindowToWorkspace(int workspace) {
} }
} }
const auto LASTFOCUS = LastWindow;
if (newLastWindow) { if (newLastWindow) {
setFocusedWindow(newLastWindow); setFocusedWindow(newLastWindow);
} }
if (SAVEDFLOATSTATUS) PWINDOW->setConstructed(false);
if (SAVEDFLOATSTATUS && workspace != SCRATCHPAD_ID)
Events::remapFloatingWindow(PWINDOW->getDrawable(), NEWMONITOR); Events::remapFloatingWindow(PWINDOW->getDrawable(), NEWMONITOR);
else else
Events::remapWindow(PWINDOW->getDrawable(), false, NEWMONITOR); Events::remapWindow(PWINDOW->getDrawable(), false, NEWMONITOR);
PWINDOW->setConstructed(true);
// fix for scratchpad
PWINDOW->setWorkspaceID(workspace);
// fix fullscreen status // fix fullscreen status
const auto PWORKSPACE = getWorkspaceByID(workspace); const auto PWORKSPACE = getWorkspaceByID(workspace);
if (PWORKSPACE) { if (PWORKSPACE) {
@ -1578,6 +1629,17 @@ void CWindowManager::moveActiveWindowToWorkspace(int workspace) {
} }
PWINDOW->setDefaultSize(SAVEDDEFAULTSIZE); PWINDOW->setDefaultSize(SAVEDDEFAULTSIZE);
if (workspace == SCRATCHPAD_ID) {
for (int i = 0; i < activeWorkspaces.size(); ++i) {
changeWorkspaceByID(workspacesBefore[i]);
}
changeWorkspaceByID(WORKSPACE->getID());
setFocusedWindow(LASTFOCUS);
}
QueuedPointerWarp = Vector2D(-1,-1);
} }
void CWindowManager::moveActiveWindowTo(char dir) { void CWindowManager::moveActiveWindowTo(char dir) {
@ -1893,6 +1955,9 @@ Vector2D CWindowManager::getCursorPos() {
bool CWindowManager::isWorkspaceVisible(int workspaceID) { bool CWindowManager::isWorkspaceVisible(int workspaceID) {
if (workspaceID == SCRATCHPAD_ID)
return scratchpadActive;
for (auto& workspace : activeWorkspaces) { for (auto& workspace : activeWorkspaces) {
if (workspace == workspaceID) if (workspace == workspaceID)
return true; return true;
@ -1954,6 +2019,9 @@ void CWindowManager::updateBarInfo() {
message.fullscreenOnBar = false; message.fullscreenOnBar = false;
for (auto& workspace : workspaces) { for (auto& workspace : workspaces) {
if (workspace.getID() == SCRATCHPAD_ID)
continue;
message.openWorkspaces.push_back(workspace.getID()); message.openWorkspaces.push_back(workspace.getID());
} }
@ -2155,6 +2223,7 @@ void CWindowManager::refocusWindowOnClosed() {
// No window or last window valid // No window or last window valid
if (!PWINDOW || getWindowFromDrawable(LastWindow)) { if (!PWINDOW || getWindowFromDrawable(LastWindow)) {
setFocusedWindow(Screen->root); //refocus on root setFocusedWindow(Screen->root); //refocus on root
return; return;
} }

View file

@ -38,6 +38,8 @@ public:
Vector2D mouseLastPos = Vector2D(0, 0); Vector2D mouseLastPos = Vector2D(0, 0);
int64_t actingOnWindowFloating = 0; int64_t actingOnWindowFloating = 0;
bool scratchpadActive = false;
uint8_t Depth = 32; uint8_t Depth = 32;
xcb_visualtype_t* VisualType; xcb_visualtype_t* VisualType;
xcb_colormap_t Colormap; xcb_colormap_t Colormap;
@ -116,6 +118,7 @@ public:
CWindow* findWindowAtCursor(); CWindow* findWindowAtCursor();
CWindow* findFirstWindowOnWorkspace(const int&); CWindow* findFirstWindowOnWorkspace(const int&);
CWindow* findPreferredOnScratchpad();
bool shouldBeFloatedOnInit(int64_t); bool shouldBeFloatedOnInit(int64_t);
void doPostCreationChecks(CWindow*); void doPostCreationChecks(CWindow*);