Merge pull request #5041 from yuukibarns/enable-bar-scroll

feat(niri/workspaces): Add `enable-bar-scroll` option
This commit is contained in:
Alexis Rouillard
2026-07-04 00:10:51 +02:00
committed by GitHub
3 changed files with 51 additions and 0 deletions
+1
View File
@@ -23,6 +23,7 @@ class Workspaces : public AModule, public EventHandler {
void sortWorkspaces(std::vector<Json::Value>& workspaces) const; void sortWorkspaces(std::vector<Json::Value>& workspaces) const;
Gtk::Button& addButton(const Json::Value& ws); Gtk::Button& addButton(const Json::Value& ws);
std::string getIcon(const std::string& value, const Json::Value& ws); std::string getIcon(const std::string& value, const Json::Value& ws);
bool handleScroll(GdkEventScroll* /*unused*/) override;
const Bar& bar_; const Bar& bar_;
Gtk::Box box_; Gtk::Box box_;
+5
View File
@@ -53,6 +53,11 @@ If none of the sorting options are enabled, workspaces keep their output/index o
default: false ++ default: false ++
If set to false, you can click to change workspace. If set to true this behaviour is disabled. If set to false, you can click to change workspace. If set to true this behaviour is disabled.
*enable-bar-scroll*: ++
typeof: bool ++
default: false ++
If set to false, you can't scroll to cycle throughout workspaces from the entire bar. If set to true this behaviour is enabled.
*disable-markup*: ++ *disable-markup*: ++
typeof: bool ++ typeof: bool ++
default: false ++ default: false ++
+45
View File
@@ -46,6 +46,12 @@ Workspaces::Workspaces(const std::string& id, const Bar& bar, const Json::Value&
gIPC->registerForIPC("WorkspaceActiveWindowChanged", this); gIPC->registerForIPC("WorkspaceActiveWindowChanged", this);
gIPC->registerForIPC("WorkspaceUrgencyChanged", this); gIPC->registerForIPC("WorkspaceUrgencyChanged", this);
if (config["enable-bar-scroll"].asBool()) {
auto& window = const_cast<Bar&>(bar_).window;
window.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
window.signal_scroll_event().connect(sigc::mem_fun(*this, &Workspaces::handleScroll));
}
dp.emit(); dp.emit();
} }
@@ -225,6 +231,45 @@ std::string Workspaces::getIcon(const std::string& value, const Json::Value& ws)
return value; return value;
} }
bool Workspaces::handleScroll(GdkEventScroll* e) {
if (gdk_event_get_pointer_emulated((GdkEvent*)e) != 0) {
/**
* Ignore emulated scroll events on window
*/
return false;
}
auto dir = AModule::getScrollDir(e);
if (dir == SCROLL_DIR::NONE) {
return true;
}
try {
Json::Value request(Json::objectValue);
auto& action = (request["Action"] = Json::Value(Json::objectValue));
std::string action_name;
if (dir == SCROLL_DIR::DOWN || dir == SCROLL_DIR::RIGHT) {
action_name = "FocusWorkspaceDown";
} else if (dir == SCROLL_DIR::UP || dir == SCROLL_DIR::LEFT) {
action_name = "FocusWorkspaceUp";
} else {
return true;
}
action[action_name] = Json::Value(Json::objectValue);
IPC::send(request);
} catch (const std::exception& e) {
spdlog::error("Workspaces: {}", e.what());
return false;
}
return true;
}
void Workspaces::sortWorkspaces(std::vector<Json::Value>& workspaces) const { void Workspaces::sortWorkspaces(std::vector<Json::Value>& workspaces) const {
auto get_name = [](const Json::Value& ws) -> std::string { auto get_name = [](const Json::Value& ws) -> std::string {
if (ws["name"]) return ws["name"].asString(); if (ws["name"]) return ws["name"].asString();