Add option to hide trailing workspaces

Potentially implements https://github.com/scorpion-26/gBar/issues/106
This commit is contained in:
scorpion-26 2024-08-01 22:58:11 +02:00
parent 81b97f94b6
commit fae1913f6c
8 changed files with 56 additions and 1 deletions

View file

@ -94,6 +94,9 @@ WorkspaceScrollInvert: false
# Number of workspaces to display. Displayed workspace IDs are 1-n (Default: 1-9) # Number of workspaces to display. Displayed workspace IDs are 1-n (Default: 1-9)
NumWorkspaces: 9 NumWorkspaces: 9
# Hide trailing unused workspaces (by ID). A workspace is considered unused, if it has no window on it
WorkspaceHideUnused: true
# Use Hyprland IPC instead of the ext_workspace protocol for workspace polling. # Use Hyprland IPC instead of the ext_workspace protocol for workspace polling.
# Hyprland IPC is *slightly* less performant (+0.1% one core), but way less bug prone, # Hyprland IPC is *slightly* less performant (+0.1% one core), but way less bug prone,
# since the protocol is not as feature complete as Hyprland IPC. # since the protocol is not as feature complete as Hyprland IPC.

View file

@ -450,8 +450,15 @@ namespace Bar
TimerResult UpdateWorkspaces(Box&) TimerResult UpdateWorkspaces(Box&)
{ {
System::PollWorkspaces(monitor, workspaces.size()); System::PollWorkspaces(monitor, workspaces.size());
uint32_t maxWorkspace = Config::Get().workspaceHideUnused ? System::GetMaxUsedWorkspace() : 0;
for (size_t i = 0; i < workspaces.size(); i++) for (size_t i = 0; i < workspaces.size(); i++)
{ {
if (Config::Get().workspaceHideUnused)
{
// Only show ws's, who are before the max used ws
workspaces[i]->SetVisible(i < maxWorkspace);
}
switch (System::GetWorkspaceStatus(i + 1)) switch (System::GetWorkspaceStatus(i + 1))
{ {
case System::WorkspaceStatus::Dead: workspaces[i]->SetClass("ws-dead"); break; case System::WorkspaceStatus::Dead: workspaces[i]->SetClass("ws-dead"); break;

View file

@ -292,6 +292,7 @@ void Config::Load(const std::string& overrideConfigLocation)
AddConfigVar("NetworkWidget", config.networkWidget, lineView, foundProperty); AddConfigVar("NetworkWidget", config.networkWidget, lineView, foundProperty);
AddConfigVar("WorkspaceScrollOnMonitor", config.workspaceScrollOnMonitor, lineView, foundProperty); AddConfigVar("WorkspaceScrollOnMonitor", config.workspaceScrollOnMonitor, lineView, foundProperty);
AddConfigVar("WorkspaceScrollInvert", config.workspaceScrollInvert, lineView, foundProperty); AddConfigVar("WorkspaceScrollInvert", config.workspaceScrollInvert, lineView, foundProperty);
AddConfigVar("WorkspaceHideUnused", config.workspaceHideUnused, lineView, foundProperty);
AddConfigVar("UseHyprlandIPC", config.useHyprlandIPC, lineView, foundProperty); AddConfigVar("UseHyprlandIPC", config.useHyprlandIPC, lineView, foundProperty);
AddConfigVar("EnableSNI", config.enableSNI, lineView, foundProperty); AddConfigVar("EnableSNI", config.enableSNI, lineView, foundProperty);
AddConfigVar("SensorTooltips", config.sensorTooltips, lineView, foundProperty); AddConfigVar("SensorTooltips", config.sensorTooltips, lineView, foundProperty);

View file

@ -63,6 +63,7 @@ public:
bool networkWidget = true; bool networkWidget = true;
bool workspaceScrollOnMonitor = true; // Scroll through workspaces on monitor instead of all bool workspaceScrollOnMonitor = true; // Scroll through workspaces on monitor instead of all
bool workspaceScrollInvert = false; // Up = +1, instead of Up = -1 bool workspaceScrollInvert = false; // Up = +1, instead of Up = -1
bool workspaceHideUnused = false; // Only display necessary workspaces (i.e. trailing empty workspaces)
bool useHyprlandIPC = true; // Use Hyprland IPC instead of ext_workspaces protocol (Less buggy, but also less performant) bool useHyprlandIPC = true; // Use Hyprland IPC instead of ext_workspaces protocol (Less buggy, but also less performant)
bool enableSNI = true; // Enable tray icon bool enableSNI = true; // Enable tray icon
bool sensorTooltips = false; // Use tooltips instead of sliders for the sensors bool sensorTooltips = false; // Use tooltips instead of sliders for the sensors

View file

@ -502,6 +502,10 @@ namespace System
{ {
return Workspaces::GetStatus(workspace); return Workspaces::GetStatus(workspace);
} }
uint32_t GetMaxUsedWorkspace()
{
return Workspaces::GetMaxUsedWorkspace();
}
void GotoWorkspace(uint32_t workspace) void GotoWorkspace(uint32_t workspace)
{ {
return Workspaces::Goto(workspace); return Workspaces::Goto(workspace);

View file

@ -99,6 +99,7 @@ namespace System
}; };
void PollWorkspaces(const std::string& monitor, uint32_t numWorkspaces); void PollWorkspaces(const std::string& monitor, uint32_t numWorkspaces);
WorkspaceStatus GetWorkspaceStatus(uint32_t workspace); WorkspaceStatus GetWorkspaceStatus(uint32_t workspace);
uint32_t GetMaxUsedWorkspace();
void GotoWorkspace(uint32_t workspace); void GotoWorkspace(uint32_t workspace);
// direction: + or - // direction: + or -
void GotoNextWorkspace(char direction); void GotoNextWorkspace(char direction);

View file

@ -65,6 +65,18 @@ namespace Workspaces
return System::WorkspaceStatus::Dead; return System::WorkspaceStatus::Dead;
} }
uint32_t GetMaxUsedWorkspace()
{
uint32_t maxUsedWorkspace = 0;
for (auto& workspace : ::Wayland::GetWorkspaces())
{
if (workspace.second.id > maxUsedWorkspace)
{
maxUsedWorkspace = workspace.second.id;
}
}
return maxUsedWorkspace;
}
} }
#ifdef WITH_HYPRLAND #ifdef WITH_HYPRLAND
@ -169,6 +181,7 @@ namespace Workspaces
} }
static std::vector<System::WorkspaceStatus> workspaceStati; static std::vector<System::WorkspaceStatus> workspaceStati;
static uint32_t maxUsedWorkspace = 0;
void PollStatus(const std::string& monitor, uint32_t numWorkspaces) void PollStatus(const std::string& monitor, uint32_t numWorkspaces)
{ {
@ -179,6 +192,7 @@ namespace Workspaces
} }
workspaceStati.clear(); workspaceStati.clear();
workspaceStati.resize(numWorkspaces, System::WorkspaceStatus::Dead); workspaceStati.resize(numWorkspaces, System::WorkspaceStatus::Dead);
maxUsedWorkspace = 0;
size_t parseIdx = 0; size_t parseIdx = 0;
// First parse workspaces // First parse workspaces
@ -197,6 +211,9 @@ namespace Workspaces
// WS is at least inactive // WS is at least inactive
workspaceStati[wsId - 1] = System::WorkspaceStatus::Inactive; workspaceStati[wsId - 1] = System::WorkspaceStatus::Inactive;
} }
// Update maxUsedWorkspace
if (wsId > 0 && (uint32_t)wsId > maxUsedWorkspace)
maxUsedWorkspace = wsId;
parseIdx = endWSNum; parseIdx = endWSNum;
} }
@ -244,6 +261,9 @@ namespace Workspaces
workspaceStati[wsId - 1] = System::WorkspaceStatus::Visible; workspaceStati[wsId - 1] = System::WorkspaceStatus::Visible;
} }
} }
// Update maxUsedWorkspace
if (wsId > 0 && (uint32_t)wsId > maxUsedWorkspace)
maxUsedWorkspace = wsId;
} }
} }
@ -257,6 +277,11 @@ namespace Workspaces
ASSERT(workspaceId > 0 && workspaceId <= workspaceStati.size(), "Invalid workspaceId, you need to poll the workspace first!"); ASSERT(workspaceId > 0 && workspaceId <= workspaceStati.size(), "Invalid workspaceId, you need to poll the workspace first!");
return workspaceStati[workspaceId - 1]; return workspaceStati[workspaceId - 1];
} }
uint32_t GetMaxUsedWorkspace()
{
return maxUsedWorkspace;
}
} }
#endif #endif
@ -294,6 +319,17 @@ namespace Workspaces
return Wayland::GetStatus(workspaceId); return Wayland::GetStatus(workspaceId);
} }
uint32_t GetMaxUsedWorkspace()
{
#ifdef WITH_HYPRLAND
if (Config::Get().useHyprlandIPC)
{
return Hyprland::GetMaxUsedWorkspace();
}
#endif
return Wayland::GetMaxUsedWorkspace();
}
void Shutdown() {} void Shutdown() {}
} }
#endif #endif

View file

@ -20,6 +20,8 @@ namespace Workspaces
System::WorkspaceStatus GetStatus(uint32_t workspaceId); System::WorkspaceStatus GetStatus(uint32_t workspaceId);
uint32_t GetMaxUsedWorkspace();
void Shutdown(); void Shutdown();
// TODO: Use ext_workspaces for this, if applicable // TODO: Use ext_workspaces for this, if applicable