Merge remote-tracking branch 'origin/master' into pr-3017
# Conflicts: # include/modules/hyprland/workspaces.hpp # man/waybar-hyprland-workspaces.5.scd # src/modules/hyprland/workspaces.cpp
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <filesystem>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
#include "util/json.hpp"
|
||||
@@ -16,25 +19,50 @@ class EventHandler {
|
||||
virtual ~EventHandler() = default;
|
||||
};
|
||||
|
||||
/// If you want to use the Hyprland IPC, simply use IPC::inst() to get the singleton instance.
|
||||
/// Do not create multiple instances.
|
||||
class IPC {
|
||||
protected:
|
||||
IPC(); // use IPC::inst() instead.
|
||||
|
||||
public:
|
||||
IPC() { startIPC(); }
|
||||
~IPC();
|
||||
static IPC& inst();
|
||||
|
||||
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
|
||||
void unregisterForIPC(EventHandler* handler);
|
||||
|
||||
static std::string getSocket1Reply(const std::string& rq);
|
||||
Json::Value getSocket1JsonReply(const std::string& rq);
|
||||
static std::filesystem::path getSocketFolder(const char* instanceSig);
|
||||
|
||||
/// Dispatch a Hyprland command. Automatically uses the correct protocol
|
||||
/// (legacy text or Lua-based) depending on the running Hyprland version.
|
||||
static std::string dispatch(const std::string& dispatcher, const std::string& arg);
|
||||
|
||||
/// Build a Lua-format dispatch command string.
|
||||
static std::string buildLuaDispatch(const std::string& dispatcher, const std::string& arg);
|
||||
|
||||
protected:
|
||||
static std::filesystem::path socketFolder_;
|
||||
|
||||
/// Detect whether the running Hyprland uses the Lua-based IPC protocol.
|
||||
/// Returns true for Hyprland >= 0.54 (Lua config), false for older versions.
|
||||
static bool isLuaProtocol();
|
||||
|
||||
static std::optional<bool> s_luaProtocolDetected_; // cached detection result
|
||||
|
||||
private:
|
||||
void startIPC();
|
||||
void socketListener();
|
||||
void parseIPC(const std::string&);
|
||||
|
||||
std::thread ipcThread_;
|
||||
std::mutex callbackMutex_;
|
||||
std::mutex socketMutex_;
|
||||
util::JsonParser parser_;
|
||||
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
||||
int socketfd_ = -1; // the hyprland socket file descriptor
|
||||
pid_t socketOwnerPid_ = -1;
|
||||
std::atomic<bool> running_ = true; // the ipcThread will stop running when this is false
|
||||
};
|
||||
|
||||
inline std::unique_ptr<IPC> gIPC;
|
||||
inline bool modulesReady = false;
|
||||
}; // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -30,6 +30,8 @@ class Language : public waybar::ALabel, public EventHandler {
|
||||
std::string short_description;
|
||||
};
|
||||
|
||||
auto removeXkbLayoutCssClass() -> void;
|
||||
auto addXkbLayoutCssClass() -> void;
|
||||
static auto getLayout(const std::string&) -> Layout;
|
||||
|
||||
std::mutex mutex_;
|
||||
@@ -37,6 +39,8 @@ class Language : public waybar::ALabel, public EventHandler {
|
||||
util::JsonParser parser_;
|
||||
|
||||
Layout layout_;
|
||||
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -19,12 +19,20 @@ class Submap : public waybar::ALabel, public EventHandler {
|
||||
auto update() -> void override;
|
||||
|
||||
private:
|
||||
auto parseConfig(const Json::Value&) -> void;
|
||||
void onEvent(const std::string& ev) override;
|
||||
|
||||
std::mutex mutex_;
|
||||
const Bar& bar_;
|
||||
util::JsonParser parser_;
|
||||
std::string submap_;
|
||||
std::string icon_;
|
||||
std::string prev_submap_;
|
||||
bool always_on_ = false;
|
||||
std::string default_submap_ = "Default";
|
||||
std::unordered_map<std::string, std::string> icons_;
|
||||
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -20,8 +20,8 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
||||
|
||||
private:
|
||||
struct Workspace {
|
||||
int id;
|
||||
int windows;
|
||||
int id = 0;
|
||||
int windows = 0;
|
||||
std::string last_window;
|
||||
std::string last_window_title;
|
||||
|
||||
@@ -29,14 +29,14 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
||||
};
|
||||
|
||||
struct WindowData {
|
||||
bool floating;
|
||||
bool floating = false;
|
||||
int monitor = -1;
|
||||
std::string class_name;
|
||||
std::string initial_class_name;
|
||||
std::string title;
|
||||
std::string initial_title;
|
||||
bool fullscreen;
|
||||
bool grouped;
|
||||
bool fullscreen = false;
|
||||
bool grouped = false;
|
||||
|
||||
static auto parse(const Json::Value&) -> WindowData;
|
||||
};
|
||||
@@ -47,7 +47,7 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
||||
void queryActiveWorkspace();
|
||||
void setClass(const std::string&, bool enable);
|
||||
|
||||
bool separateOutputs_;
|
||||
bool separateOutputs_ = false;
|
||||
std::mutex mutex_;
|
||||
const Bar& bar_;
|
||||
util::JsonParser parser_;
|
||||
@@ -55,11 +55,13 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
||||
Workspace workspace_;
|
||||
std::string soloClass_;
|
||||
std::string lastSoloClass_;
|
||||
bool solo_;
|
||||
bool allFloating_;
|
||||
bool swallowing_;
|
||||
bool fullscreen_;
|
||||
bool focused_;
|
||||
bool solo_ = false;
|
||||
bool allFloating_ = false;
|
||||
bool swallowing_ = false;
|
||||
bool fullscreen_ = false;
|
||||
bool focused_ = false;
|
||||
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "AAppIconLabel.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/hyprland/backend.hpp"
|
||||
|
||||
namespace waybar::modules::hyprland {
|
||||
|
||||
class WindowCount : public waybar::AAppIconLabel, public EventHandler {
|
||||
public:
|
||||
WindowCount(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||
~WindowCount() override;
|
||||
|
||||
auto update() -> void override;
|
||||
|
||||
private:
|
||||
struct Workspace {
|
||||
int id;
|
||||
int windows;
|
||||
bool hasfullscreen;
|
||||
static auto parse(const Json::Value& value) -> Workspace;
|
||||
};
|
||||
|
||||
auto getActiveWorkspace(const std::string&) -> Workspace;
|
||||
auto getActiveWorkspace() -> Workspace;
|
||||
void onEvent(const std::string& ev) override;
|
||||
void queryActiveWorkspace();
|
||||
void setClass(const std::string&, bool enable);
|
||||
|
||||
bool separateOutputs_;
|
||||
std::mutex mutex_;
|
||||
const Bar& bar_;
|
||||
Workspace workspace_;
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
@@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtkmm/button.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <json/value.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "AModule.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/hyprland/backend.hpp"
|
||||
#include "util/enum.hpp"
|
||||
#include "util/regex_collection.hpp"
|
||||
|
||||
using WindowAddress = std::string;
|
||||
|
||||
namespace waybar::modules::hyprland {
|
||||
|
||||
class Workspaces;
|
||||
|
||||
struct WindowRepr {
|
||||
std::string address;
|
||||
std::string window_class;
|
||||
std::string window_title;
|
||||
std::string repr_rewrite;
|
||||
bool isActive = false;
|
||||
|
||||
public:
|
||||
bool empty() const { return address.empty(); }
|
||||
void setActive(bool value) { isActive = value; }
|
||||
};
|
||||
|
||||
class WindowCreationPayload {
|
||||
public:
|
||||
WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
|
||||
WindowRepr window_repr);
|
||||
WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
|
||||
const std::string& window_class, const std::string& window_title,
|
||||
bool is_active);
|
||||
WindowCreationPayload(Json::Value const& client_data);
|
||||
|
||||
int incrementTimeSpentUncreated();
|
||||
bool isEmpty(Workspaces& workspace_manager);
|
||||
bool reprIsReady() const { return std::holds_alternative<Repr>(m_window); }
|
||||
WindowRepr repr(Workspaces& workspace_manager);
|
||||
void setActive(bool value) { m_isActive = value; }
|
||||
|
||||
std::string getWorkspaceName() const { return m_workspaceName; }
|
||||
WindowAddress getAddress() const { return m_windowAddress; }
|
||||
|
||||
void moveToWorkspace(std::string& new_workspace_name);
|
||||
|
||||
private:
|
||||
void clearAddr();
|
||||
void clearWorkspaceName();
|
||||
|
||||
using Repr = WindowRepr;
|
||||
using ClassAndTitle = std::pair<std::string, std::string>;
|
||||
std::variant<Repr, ClassAndTitle> m_window;
|
||||
|
||||
WindowAddress m_windowAddress;
|
||||
std::string m_workspaceName;
|
||||
bool m_isActive = false;
|
||||
|
||||
int m_timeSpentUncreated = 0;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
@@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtkmm/button.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <json/value.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "AModule.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/hyprland/backend.hpp"
|
||||
#include "modules/hyprland/windowcreationpayload.hpp"
|
||||
#include "util/enum.hpp"
|
||||
#include "util/regex_collection.hpp"
|
||||
|
||||
using WindowAddress = std::string;
|
||||
|
||||
namespace waybar::modules::hyprland {
|
||||
|
||||
class Workspaces;
|
||||
class Workspace {
|
||||
public:
|
||||
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
|
||||
const Json::Value& clients_data = Json::Value::nullRef);
|
||||
~Workspace();
|
||||
std::string& selectString(std::map<std::string, std::string>& string_map);
|
||||
Gtk::Button& button() { return m_button; };
|
||||
|
||||
int id() const { return m_id; };
|
||||
std::string name() const { return m_name; };
|
||||
std::string output() const { return m_output; };
|
||||
bool isActive() const { return m_isActive; };
|
||||
bool isSpecial() const { return m_isSpecial; };
|
||||
bool isPersistent() const { return m_isPersistentRule || m_isPersistentConfig; };
|
||||
bool isPersistentConfig() const { return m_isPersistentConfig; };
|
||||
bool isPersistentRule() const { return m_isPersistentRule; };
|
||||
bool isVisible() const { return m_isVisible; };
|
||||
bool isUrgent() const { return m_isUrgent; };
|
||||
|
||||
bool handleClicked(GdkEventButton* bt) const;
|
||||
|
||||
bool handleEnter(GdkEventCrossing* event);
|
||||
bool handleLeave(GdkEventCrossing* event);
|
||||
|
||||
void startHoverCheck();
|
||||
void stopHoverCheck();
|
||||
bool syncHoverClass();
|
||||
bool pointerInsideButton();
|
||||
|
||||
void setActive(bool value = true) { m_isActive = value; };
|
||||
void setPersistentRule(bool value = true) { m_isPersistentRule = value; };
|
||||
void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; };
|
||||
void setUrgent(bool value = true) { m_isUrgent = value; };
|
||||
void setVisible(bool value = true) { m_isVisible = value; };
|
||||
void setWindows(uint value) { m_windows = value; };
|
||||
void setName(std::string const& value) { m_name = value; };
|
||||
void setOutput(std::string const& value) { m_output = value; };
|
||||
bool containsWindow(WindowAddress const& addr) const {
|
||||
return std::ranges::any_of(m_windowMap,
|
||||
[&addr](const auto& window) { return window.address == addr; });
|
||||
};
|
||||
void insertWindow(WindowCreationPayload create_window_payload);
|
||||
void initializeWindowMap(const Json::Value& clients_data);
|
||||
void setActiveWindow(WindowAddress const& addr);
|
||||
|
||||
bool onWindowOpened(WindowCreationPayload const& create_window_payload);
|
||||
std::optional<WindowRepr> closeWindow(WindowAddress const& addr);
|
||||
|
||||
void update(const std::string& workspace_icon, const std::string& workspace_tooltip);
|
||||
|
||||
private:
|
||||
Workspaces& m_workspaceManager;
|
||||
|
||||
int m_id;
|
||||
std::string m_name;
|
||||
std::string m_prevNameClass;
|
||||
std::string m_output;
|
||||
uint m_windows;
|
||||
bool m_isActive = false;
|
||||
bool m_isSpecial = false;
|
||||
bool m_isPersistentRule = false; // represents the persistent state in hyprland
|
||||
bool m_isPersistentConfig = false; // represents the persistent state in the Waybar config
|
||||
bool m_isUrgent = false;
|
||||
bool m_isVisible = false;
|
||||
|
||||
sigc::connection m_hoverCheckConnection;
|
||||
|
||||
std::vector<WindowRepr> m_windowMap;
|
||||
|
||||
Gtk::Button m_button;
|
||||
Gtk::Box m_content;
|
||||
Gtk::Label m_labelBefore;
|
||||
Gtk::Label m_labelAfter;
|
||||
|
||||
bool isEmpty() const;
|
||||
void updateTaskbar(const std::string& workspace_icon);
|
||||
bool handleClick(const GdkEventButton* event_button, WindowAddress const& addr) const;
|
||||
bool shouldSkipWindow(const WindowRepr& window_repr) const;
|
||||
IPC& m_ipc;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
@@ -1,23 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtkmm/button.h>
|
||||
#include <gtkmm/enums.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <json/value.h>
|
||||
#include <sigc++/connection.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "AModule.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/hyprland/backend.hpp"
|
||||
#include "modules/hyprland/windowcreationpayload.hpp"
|
||||
#include "modules/hyprland/workspace.hpp"
|
||||
#include "util/enum.hpp"
|
||||
#include "util/icon_loader.hpp"
|
||||
#include "util/regex_collection.hpp"
|
||||
|
||||
using WindowAddress = std::string;
|
||||
@@ -26,97 +29,6 @@ namespace waybar::modules::hyprland {
|
||||
|
||||
class Workspaces;
|
||||
|
||||
class WindowCreationPayload {
|
||||
public:
|
||||
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
||||
std::string window_repr);
|
||||
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
||||
std::string window_class, std::string window_title);
|
||||
WindowCreationPayload(Json::Value const& client_data);
|
||||
|
||||
int incrementTimeSpentUncreated();
|
||||
bool isEmpty(Workspaces& workspace_manager);
|
||||
bool reprIsReady() const { return std::holds_alternative<Repr>(m_window); }
|
||||
std::string repr(Workspaces& workspace_manager);
|
||||
|
||||
std::string getWorkspaceName() const { return m_workspaceName; }
|
||||
WindowAddress getAddress() const { return m_windowAddress; }
|
||||
|
||||
void moveToWorksace(std::string& new_workspace_name);
|
||||
|
||||
private:
|
||||
void clearAddr();
|
||||
void clearWorkspaceName();
|
||||
|
||||
using Repr = std::string;
|
||||
using ClassAndTitle = std::pair<std::string, std::string>;
|
||||
std::variant<Repr, ClassAndTitle> m_window;
|
||||
|
||||
WindowAddress m_windowAddress;
|
||||
std::string m_workspaceName;
|
||||
|
||||
int m_timeSpentUncreated = 0;
|
||||
};
|
||||
|
||||
class Workspace {
|
||||
public:
|
||||
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
|
||||
const Json::Value& clients_data = Json::Value::nullRef);
|
||||
std::string& selectString(std::map<std::string, std::string>& string_map);
|
||||
Gtk::Button& button() { return m_button; };
|
||||
|
||||
int id() const { return m_id; };
|
||||
std::string name() const { return m_name; };
|
||||
std::string output() const { return m_output; };
|
||||
bool isActive() const { return m_isActive; };
|
||||
bool isSpecial() const { return m_isSpecial; };
|
||||
bool isPersistent() const { return m_isPersistentRule || m_isPersistentConfig; };
|
||||
bool isPersistentConfig() const { return m_isPersistentConfig; };
|
||||
bool isPersistentRule() const { return m_isPersistentRule; };
|
||||
bool isVisible() const { return m_isVisible; };
|
||||
bool isEmpty() const { return m_windows == 0; };
|
||||
bool isUrgent() const { return m_isUrgent; };
|
||||
|
||||
bool handleClicked(GdkEventButton* bt) const;
|
||||
void setActive(bool value = true) { m_isActive = value; };
|
||||
void setPersistentRule(bool value = true) { m_isPersistentRule = value; };
|
||||
void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; };
|
||||
void setUrgent(bool value = true) { m_isUrgent = value; };
|
||||
void setVisible(bool value = true) { m_isVisible = value; };
|
||||
void setWindows(uint value) { m_windows = value; };
|
||||
void setName(std::string const& value) { m_name = value; };
|
||||
void setOutput(std::string const& value) { m_output = value; };
|
||||
bool containsWindow(WindowAddress const& addr) const { return m_windowMap.contains(addr); }
|
||||
void insertWindow(WindowCreationPayload create_window_paylod);
|
||||
std::string removeWindow(WindowAddress const& addr);
|
||||
void initializeWindowMap(const Json::Value& clients_data);
|
||||
|
||||
bool onWindowOpened(WindowCreationPayload const& create_window_paylod);
|
||||
std::optional<std::string> closeWindow(WindowAddress const& addr);
|
||||
|
||||
void update(const std::string& format, const std::string& icon, const std::string &tooltipFormat);
|
||||
|
||||
private:
|
||||
Workspaces& m_workspaceManager;
|
||||
|
||||
int m_id;
|
||||
std::string m_name;
|
||||
std::string m_output;
|
||||
uint m_windows;
|
||||
bool m_isActive = false;
|
||||
bool m_isSpecial = false;
|
||||
bool m_isPersistentRule = false; // represents the persistent state in hyprland
|
||||
bool m_isPersistentConfig = false; // represents the persistent state in the Waybar config
|
||||
bool m_isUrgent = false;
|
||||
bool m_isVisible = false;
|
||||
|
||||
std::map<WindowAddress, std::string> m_windowMap;
|
||||
|
||||
Gtk::Button m_button;
|
||||
Gtk::Box m_content;
|
||||
Gtk::Label m_label;
|
||||
};
|
||||
|
||||
class Workspaces : public AModule, public EventHandler {
|
||||
public:
|
||||
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||
@@ -127,34 +39,74 @@ class Workspaces : public AModule, public EventHandler {
|
||||
auto allOutputs() const -> bool { return m_allOutputs; }
|
||||
auto showSpecial() const -> bool { return m_showSpecial; }
|
||||
auto activeOnly() const -> bool { return m_activeOnly; }
|
||||
auto hideActive() const -> bool { return m_hideActive; }
|
||||
auto specialVisibleOnly() const -> bool { return m_specialVisibleOnly; }
|
||||
auto persistentOnly() const -> bool { return m_persistentOnly; }
|
||||
auto moveToMonitor() const -> bool { return m_moveToMonitor; }
|
||||
auto enableTaskbar() const -> bool { return m_enableTaskbar; }
|
||||
auto taskbarWithIcon() const -> bool { return m_taskbarWithIcon; }
|
||||
auto barScroll() const -> bool { return m_barScroll; }
|
||||
|
||||
auto getBarOutput() const -> std::string { return m_bar.output->name; }
|
||||
auto formatBefore() const -> std::string { return m_formatBefore; }
|
||||
auto formatAfter() const -> std::string { return m_formatAfter; }
|
||||
auto taskbarFormatBefore() const -> std::string { return m_taskbarFormatBefore; }
|
||||
auto taskbarFormatAfter() const -> std::string { return m_taskbarFormatAfter; }
|
||||
auto taskbarIconSize() const -> int { return m_taskbarIconSize; }
|
||||
auto taskbarOrientation() const -> Gtk::Orientation { return m_taskbarOrientation; }
|
||||
auto taskbarReverseDirection() const -> bool { return m_taskbarReverseDirection; }
|
||||
auto onClickWindow() const -> std::string { return m_onClickWindow; }
|
||||
auto getIgnoredWindows() const -> std::vector<std::regex> { return m_ignoreWindows; }
|
||||
auto maxWindows() const -> int { return m_maxWindows; }
|
||||
|
||||
std::string getRewrite(std::string window_class, std::string window_title);
|
||||
enum class ActiveWindowPosition { NONE, FIRST, LAST };
|
||||
auto activeWindowPosition() const -> ActiveWindowPosition { return m_activeWindowPosition; }
|
||||
|
||||
std::string getRewrite(const std::string& window_class, const std::string& window_title);
|
||||
std::string& getWindowSeparator() { return m_formatWindowSeparator; }
|
||||
auto windowRewriteGroupThreshold() const -> int { return m_windowRewriteGroupThreshold; }
|
||||
auto const& getWindowRewriteGroupFormat() const { return m_windowRewriteGroupFormat; }
|
||||
bool isWorkspaceIgnored(std::string const& workspace_name);
|
||||
|
||||
bool windowRewriteConfigUsesTitle() const { return m_anyWindowRewriteRuleUsesTitle; }
|
||||
const IconLoader& iconLoader() const { return m_iconLoader; }
|
||||
|
||||
private:
|
||||
void onEvent(const std::string& e) override;
|
||||
void updateWindowCount();
|
||||
void sortSpecialCentered();
|
||||
void sortWorkspaces();
|
||||
void createWorkspace(Json::Value const& workspaceData,
|
||||
Json::Value const& clientsData = Json::Value::nullRef);
|
||||
void removeWorkspace(std::string const& name);
|
||||
void createWorkspace(Json::Value const& workspace_data,
|
||||
Json::Value const& clients_data = Json::Value::nullRef);
|
||||
|
||||
static Json::Value createMonitorWorkspaceData(std::string const& name,
|
||||
std::string const& monitor);
|
||||
void removeWorkspace(std::string const& workspaceString);
|
||||
void setUrgentWorkspace(std::string const& windowaddress);
|
||||
|
||||
// Config
|
||||
void parseConfig(const Json::Value& config);
|
||||
auto populateIconsMap(const Json::Value& formatIcons) -> void;
|
||||
static auto populateBoolConfig(const Json::Value& config, const std::string& key, bool& member)
|
||||
-> void;
|
||||
auto populateSortByConfig(const Json::Value& config) -> void;
|
||||
auto populateIgnoreWorkspacesConfig(const Json::Value& config) -> void;
|
||||
auto populateFormatWindowSeparatorConfig(const Json::Value& config) -> void;
|
||||
auto populateWindowRewriteConfig(const Json::Value& config) -> void;
|
||||
auto populateMaxWindowsConfig(const Json::Value& config) -> void;
|
||||
auto populateWorkspaceTaskbarConfig(const Json::Value& config) -> void;
|
||||
|
||||
void registerIpc();
|
||||
|
||||
// workspace events
|
||||
void onWorkspaceActivated(std::string const& payload);
|
||||
void onSpecialWorkspaceActivated(std::string const& payload);
|
||||
void onWorkspaceDestroyed(std::string const& payload);
|
||||
void onWorkspaceCreated(std::string const& workspaceName,
|
||||
void onWorkspaceCreated(std::string const& payload,
|
||||
Json::Value const& clientsData = Json::Value::nullRef);
|
||||
void onWorkspaceMoved(std::string const& payload);
|
||||
void onWorkspaceRenamed(std::string const& payload);
|
||||
static std::optional<int> parseWorkspaceId(std::string const& workspaceIdStr);
|
||||
|
||||
// monitor events
|
||||
void onMonitorFocused(std::string const& payload);
|
||||
@@ -165,12 +117,28 @@ class Workspaces : public AModule, public EventHandler {
|
||||
void onWindowMoved(std::string const& payload);
|
||||
|
||||
void onWindowTitleEvent(std::string const& payload);
|
||||
void onActiveWindowChanged(WindowAddress const& payload);
|
||||
|
||||
void onConfigReloaded();
|
||||
|
||||
int windowRewritePriorityFunction(std::string const& window_rule);
|
||||
|
||||
// event payload management
|
||||
template <typename... Args>
|
||||
static std::string makePayload(Args const&... args);
|
||||
static std::pair<std::string, std::string> splitDoublePayload(std::string const& payload);
|
||||
static std::tuple<std::string, std::string, std::string> splitTriplePayload(
|
||||
std::string const& payload);
|
||||
// scroll events
|
||||
bool handleScroll(GdkEventScroll* e) override;
|
||||
|
||||
// Update methods
|
||||
void doUpdate();
|
||||
void removeWorkspacesToRemove();
|
||||
void createWorkspacesToCreate();
|
||||
static std::vector<int> getVisibleWorkspaces();
|
||||
void updateWorkspaceStates();
|
||||
bool updateWindowsToCreate();
|
||||
|
||||
void extendOrphans(int workspaceId, Json::Value const& clientsJson);
|
||||
void registerOrphanWindow(WindowCreationPayload create_window_payload);
|
||||
@@ -183,45 +151,80 @@ class Workspaces : public AModule, public EventHandler {
|
||||
bool m_allOutputs = false;
|
||||
bool m_showSpecial = false;
|
||||
bool m_activeOnly = false;
|
||||
bool m_hideActive = false;
|
||||
bool m_specialVisibleOnly = false;
|
||||
bool m_persistentOnly = false;
|
||||
bool m_moveToMonitor = false;
|
||||
bool m_barScroll = false;
|
||||
Json::Value m_persistentWorkspaceConfig;
|
||||
|
||||
// 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;
|
||||
// and doesn't share windows across bars (a.k.a `all-outputs` = false)
|
||||
std::map<WindowAddress, WindowRepr, std::less<>> m_orphanWindowMap;
|
||||
|
||||
enum class SortMethod { ID, NAME, NUMBER, DEFAULT };
|
||||
enum class SortMethod { ID, NAME, NUMBER, SPECIAL_CENTERED, DEFAULT };
|
||||
util::EnumParser<SortMethod> m_enumParser;
|
||||
SortMethod m_sortBy = SortMethod::DEFAULT;
|
||||
std::map<std::string, SortMethod> m_sortMap = {{"ID", SortMethod::ID},
|
||||
{"NAME", SortMethod::NAME},
|
||||
{"NUMBER", SortMethod::NUMBER},
|
||||
{"SPECIAL-CENTERED", SortMethod::SPECIAL_CENTERED},
|
||||
{"DEFAULT", SortMethod::DEFAULT}};
|
||||
|
||||
std::string m_format;
|
||||
|
||||
std::map<std::string, std::string> m_tooltipMap;
|
||||
bool m_withTooltip;
|
||||
std::string m_formatBefore;
|
||||
std::string m_formatAfter;
|
||||
|
||||
std::map<std::string, std::string> m_iconsMap;
|
||||
std::map<std::string, std::string> m_tooltipMap;
|
||||
bool m_withTooltip = false;
|
||||
util::RegexCollection m_windowRewriteRules;
|
||||
bool m_anyWindowRewriteRuleUsesTitle = false;
|
||||
std::string m_formatWindowSeparator;
|
||||
int m_windowRewriteGroupThreshold = 0;
|
||||
std::string m_windowRewriteGroupFormat = "{icon}×{count}";
|
||||
|
||||
bool m_withIcon;
|
||||
uint64_t m_monitorId;
|
||||
std::string m_activeWorkspaceName;
|
||||
int m_activeWorkspaceId;
|
||||
std::string m_activeSpecialWorkspaceName;
|
||||
std::vector<std::unique_ptr<Workspace>> m_workspaces;
|
||||
std::vector<std::pair<Json::Value, Json::Value>> m_workspacesToCreate;
|
||||
std::vector<std::string> m_workspacesToRemove;
|
||||
std::vector<WindowCreationPayload> m_windowsToCreate;
|
||||
|
||||
IconLoader m_iconLoader;
|
||||
bool m_enableTaskbar = false;
|
||||
bool m_updateActiveWindow = false;
|
||||
bool m_taskbarWithIcon = false;
|
||||
bool m_taskbarWithTitle = false;
|
||||
std::string m_taskbarFormatBefore;
|
||||
std::string m_taskbarFormatAfter;
|
||||
int m_taskbarIconSize = 16;
|
||||
Gtk::Orientation m_taskbarOrientation = Gtk::ORIENTATION_HORIZONTAL;
|
||||
bool m_taskbarReverseDirection = false;
|
||||
util::EnumParser<ActiveWindowPosition> m_activeWindowEnumParser;
|
||||
ActiveWindowPosition m_activeWindowPosition = ActiveWindowPosition::NONE;
|
||||
std::map<std::string, ActiveWindowPosition> m_activeWindowPositionMap = {
|
||||
{"NONE", ActiveWindowPosition::NONE},
|
||||
{"FIRST", ActiveWindowPosition::FIRST},
|
||||
{"LAST", ActiveWindowPosition::LAST},
|
||||
};
|
||||
std::string m_onClickWindow;
|
||||
std::string m_currentActiveWindowAddress;
|
||||
int m_maxWindows = 0;
|
||||
|
||||
std::vector<std::regex> m_ignoreWorkspaces;
|
||||
std::vector<std::regex> m_ignoreWindows;
|
||||
|
||||
std::mutex m_mutex;
|
||||
const Bar& m_bar;
|
||||
Gtk::Box m_box;
|
||||
sigc::connection m_scrollEventConnection_;
|
||||
IPC& m_ipc;
|
||||
|
||||
sigc::connection m_debounceTimer;
|
||||
bool m_updatePending = false;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
||||
Reference in New Issue
Block a user