feat: add orphan windows attribute to workspaces
this attribute will keep every window that doesn't have an associated workspace in the current barpull/2817/head
parent
748fc809b5
commit
512c6fb127
|
@ -163,10 +163,18 @@ class Workspaces : public AModule, public EventHandler {
|
||||||
|
|
||||||
void doUpdate();
|
void doUpdate();
|
||||||
|
|
||||||
|
void extendOrphans(int workspaceId, Json::Value const& clientsJson);
|
||||||
|
void registerOrphanWindow(WindowCreationPayload create_window_paylod);
|
||||||
|
|
||||||
bool m_allOutputs = false;
|
bool m_allOutputs = false;
|
||||||
bool m_showSpecial = false;
|
bool m_showSpecial = false;
|
||||||
bool m_activeOnly = false;
|
bool m_activeOnly = false;
|
||||||
|
|
||||||
|
// Map for windows stored in workspaces not present in the current bar.
|
||||||
|
// This happens when the user has multiple monitors (hence, multiple bars)
|
||||||
|
// and doesn't share windows accross bars (a.k.a `all-outputs` = false)
|
||||||
|
std::map<WindowAddress, std::string> m_orphanWindowMap;
|
||||||
|
|
||||||
enum class SortMethod { ID, NAME, NUMBER, DEFAULT };
|
enum class SortMethod { ID, NAME, NUMBER, DEFAULT };
|
||||||
util::EnumParser<SortMethod> m_enumParser;
|
util::EnumParser<SortMethod> m_enumParser;
|
||||||
SortMethod m_sortBy = SortMethod::DEFAULT;
|
SortMethod m_sortBy = SortMethod::DEFAULT;
|
||||||
|
|
|
@ -128,6 +128,12 @@ auto Workspaces::parseConfig(const Json::Value &config) -> void {
|
||||||
[this](std::string &window_rule) { return windowRewritePriorityFunction(window_rule); });
|
[this](std::string &window_rule) { return windowRewritePriorityFunction(window_rule); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Workspaces::registerOrphanWindow(WindowCreationPayload create_window_paylod) {
|
||||||
|
if (!create_window_paylod.isEmpty(*this)) {
|
||||||
|
m_orphanWindowMap[create_window_paylod.getAddress()] = create_window_paylod.repr(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto Workspaces::registerIpc() -> void {
|
auto Workspaces::registerIpc() -> void {
|
||||||
gIPC->registerForIPC("workspace", this);
|
gIPC->registerForIPC("workspace", this);
|
||||||
gIPC->registerForIPC("createworkspace", this);
|
gIPC->registerForIPC("createworkspace", this);
|
||||||
|
@ -215,6 +221,8 @@ void Workspaces::doUpdate() {
|
||||||
static auto const WINDOW_CREATION_TIMEOUT = 2;
|
static auto const WINDOW_CREATION_TIMEOUT = 2;
|
||||||
if (windowPayload.incrementTimeSpentUncreated() < WINDOW_CREATION_TIMEOUT) {
|
if (windowPayload.incrementTimeSpentUncreated() < WINDOW_CREATION_TIMEOUT) {
|
||||||
notCreated.push_back(windowPayload);
|
notCreated.push_back(windowPayload);
|
||||||
|
} else {
|
||||||
|
registerOrphanWindow(windowPayload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,18 +410,35 @@ void Workspaces::onWindowMoved(std::string const &payload) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...and add it to the new workspace
|
// ...if it was empty, check if the window is an orphan...
|
||||||
|
if (windowRepr.empty() && m_orphanWindowMap.contains(windowAddress)) {
|
||||||
|
windowRepr = m_orphanWindowMap[windowAddress];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...and then add it to the new workspace
|
||||||
if (!windowRepr.empty()) {
|
if (!windowRepr.empty()) {
|
||||||
m_windowsToCreate.emplace_back(workspaceName, windowAddress, windowRepr);
|
m_windowsToCreate.emplace_back(workspaceName, windowAddress, windowRepr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspaces::onWindowTitleEvent(std::string const &payload) {
|
void Workspaces::onWindowTitleEvent(std::string const &payload) {
|
||||||
auto windowWorkspace =
|
std::optional<std::function<void(WindowCreationPayload)>> inserter;
|
||||||
std::find_if(m_workspaces.begin(), m_workspaces.end(),
|
|
||||||
[payload](auto &workspace) { return workspace->containsWindow(payload); });
|
|
||||||
|
|
||||||
if (windowWorkspace != m_workspaces.end()) {
|
if (m_orphanWindowMap.contains(payload)) {
|
||||||
|
inserter = [this](WindowCreationPayload wcp) { this->registerOrphanWindow(std::move(wcp)); };
|
||||||
|
} else {
|
||||||
|
auto windowWorkspace =
|
||||||
|
std::find_if(m_workspaces.begin(), m_workspaces.end(),
|
||||||
|
[payload](auto &workspace) { return workspace->containsWindow(payload); });
|
||||||
|
|
||||||
|
if (windowWorkspace != m_workspaces.end()) {
|
||||||
|
inserter = [windowWorkspace](WindowCreationPayload wcp) {
|
||||||
|
(*windowWorkspace)->insertWindow(std::move(wcp));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inserter.has_value()) {
|
||||||
Json::Value clientsData = gIPC->getSocket1JsonReply("clients");
|
Json::Value clientsData = gIPC->getSocket1JsonReply("clients");
|
||||||
std::string jsonWindowAddress = fmt::format("0x{}", payload);
|
std::string jsonWindowAddress = fmt::format("0x{}", payload);
|
||||||
|
|
||||||
|
@ -423,7 +448,7 @@ void Workspaces::onWindowTitleEvent(std::string const &payload) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!client->empty()) {
|
if (!client->empty()) {
|
||||||
(*windowWorkspace)->insertWindow({*client});
|
(*inserter)({*client});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -605,6 +630,14 @@ void Workspaces::createPersistentWorkspaces() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Workspaces::extendOrphans(int workspaceId, Json::Value const &clientsJson) {
|
||||||
|
for (const auto &client : clientsJson) {
|
||||||
|
if (client["workspace"]["id"].asInt() == workspaceId) {
|
||||||
|
registerOrphanWindow({client});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Workspaces::init() {
|
void Workspaces::init() {
|
||||||
m_activeWorkspaceName = (gIPC->getSocket1JsonReply("activeworkspace"))["name"].asString();
|
m_activeWorkspaceName = (gIPC->getSocket1JsonReply("activeworkspace"))["name"].asString();
|
||||||
|
|
||||||
|
@ -625,10 +658,13 @@ void Workspaces::init() {
|
||||||
|
|
||||||
for (Json::Value workspaceJson : workspacesJson) {
|
for (Json::Value workspaceJson : workspacesJson) {
|
||||||
std::string workspaceName = workspaceJson["name"].asString();
|
std::string workspaceName = workspaceJson["name"].asString();
|
||||||
|
spdlog::info("initing workpsace {}:{}", workspaceJson["id"], workspaceJson["name"]);
|
||||||
if ((allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) &&
|
if ((allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) &&
|
||||||
(!workspaceName.starts_with("special") || showSpecial()) &&
|
(!workspaceName.starts_with("special") || showSpecial()) &&
|
||||||
!isWorkspaceIgnored(workspaceName)) {
|
!isWorkspaceIgnored(workspaceName)) {
|
||||||
createWorkspace(workspaceJson, clientsJson);
|
createWorkspace(workspaceJson, clientsJson);
|
||||||
|
} else {
|
||||||
|
extendOrphans(workspaceJson["id"].asInt(), clientsJson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue