File: workspaces.hpp

package info (click to toggle)
waybar 0.15.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,464 kB
  • sloc: cpp: 25,331; xml: 742; python: 146; ansic: 77; makefile: 29
file content (210 lines) | stat: -rw-r--r-- 8,431 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#pragma once

#include <gtkmm/button.h>
#include <gtkmm/enums.h>
#include <gtkmm/label.h>
#include <json/value.h>

#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <regex>
#include <string>
#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;

namespace waybar::modules::hyprland {

class Workspaces;

class Workspaces : public AModule, public EventHandler {
 public:
  Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
  ~Workspaces() override;
  void update() override;
  void init();

  auto allOutputs() const -> bool { return m_allOutputs; }
  auto showSpecial() const -> bool { return m_showSpecial; }
  auto activeOnly() const -> bool { return m_activeOnly; }
  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 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; }

  enum class ActiveWindowPosition { NONE, FIRST, LAST };
  auto activeWindowPosition() const -> ActiveWindowPosition { return m_activeWindowPosition; }

  std::string getRewrite(std::string window_class, std::string window_title);
  std::string& getWindowSeparator() { return m_formatWindowSeparator; }
  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& 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 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& 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);

  // window events
  void onWindowOpened(std::string const& payload);
  void onWindowClosed(std::string const& addr);
  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);

  // 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);

  void initializeWorkspaces();
  void setCurrentMonitorId();
  void loadPersistentWorkspacesFromConfig(Json::Value const& clientsJson);
  void loadPersistentWorkspacesFromWorkspaceRules(const Json::Value& clientsJson);

  bool m_allOutputs = false;
  bool m_showSpecial = false;
  bool m_activeOnly = false;
  bool m_specialVisibleOnly = false;
  bool m_persistentOnly = false;
  bool m_moveToMonitor = 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 across bars (a.k.a `all-outputs` = false)
  std::map<WindowAddress, WindowRepr, std::less<>> m_orphanWindowMap;

  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_formatBefore;
  std::string m_formatAfter;

  std::map<std::string, std::string> m_iconsMap;
  util::RegexCollection m_windowRewriteRules;
  bool m_anyWindowRewriteRuleUsesTitle = false;
  std::string m_formatWindowSeparator;

  bool m_withIcon;
  uint64_t m_monitorId;
  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;

  std::vector<std::regex> m_ignoreWorkspaces;
  std::vector<std::regex> m_ignoreWindows;

  std::mutex m_mutex;
  const Bar& m_bar;
  Gtk::Box m_box;
  IPC& m_ipc;
};

}  // namespace waybar::modules::hyprland