diff --git a/include/bar.hpp b/include/bar.hpp
index 6f3dfcf97..030e1e35b 100644
--- a/include/bar.hpp
+++ b/include/bar.hpp
@@ -59,7 +59,13 @@ class Bar {
   ~Bar() = default;
 
   void setVisible(bool visible);
+  void setHiddenClass(bool value) const;
+  void setBottomLayerClass(bool value) const;
+  void moveToTopLayer() const;
+  void moveToBottomLayer() const;
+  void moveToConfiguredLayer() const;
   void toggle();
+  void setExclusive(bool value);
   void handleSignal(int);
 
   struct waybar_output *output;
diff --git a/include/factory.hpp b/include/factory.hpp
index 4b9f32aa9..79a08f3f4 100644
--- a/include/factory.hpp
+++ b/include/factory.hpp
@@ -10,6 +10,7 @@
 #include "modules/sway/mode.hpp"
 #include "modules/sway/window.hpp"
 #include "modules/sway/workspaces.hpp"
+#include "modules/sway/hide.hpp"
 #include "modules/sway/language.hpp"
 #endif
 #ifdef HAVE_WLR
diff --git a/include/modules/sway/hide.hpp b/include/modules/sway/hide.hpp
new file mode 100644
index 000000000..90a054d88
--- /dev/null
+++ b/include/modules/sway/hide.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <fmt/format.h>
+#include <tuple>
+#include <mutex>
+#include "ALabel.hpp"
+#include "bar.hpp"
+#include "client.hpp"
+#include "modules/sway/ipc/client.hpp"
+#include "util/json.hpp"
+#include "util/sleeper_thread.hpp"
+
+namespace waybar::modules::sway {
+
+class Hide : public ALabel, public sigc::trackable {
+ public:
+  Hide(const std::string&, const waybar::Bar&, const Json::Value&);
+  ~Hide() = default;
+  auto update() -> void;
+
+ private:
+  void onEvent(const struct Ipc::ipc_response&);
+  void worker();
+
+  std::string      current_mode_;
+  bool             visible_by_modifier_;
+  const Bar&       bar_;
+  std::string      window_;
+  int              windowId_;
+  util::JsonParser parser_;
+
+  util::SleeperThread thread_;
+  std::mutex          mutex_;
+  Ipc                 ipc_;
+};
+
+}  // namespace waybar::modules::sway
diff --git a/meson.build b/meson.build
index c09fbb617..f7d87059d 100644
--- a/meson.build
+++ b/meson.build
@@ -180,7 +180,8 @@ src_files += [
     'src/modules/sway/mode.cpp',
     'src/modules/sway/language.cpp',
     'src/modules/sway/window.cpp',
-    'src/modules/sway/workspaces.cpp'
+    'src/modules/sway/workspaces.cpp',
+    'src/modules/sway/hide.cpp',
 ]
 
 if true
diff --git a/src/bar.cpp b/src/bar.cpp
index a8b230e1e..08adde8a6 100644
--- a/src/bar.cpp
+++ b/src/bar.cpp
@@ -536,23 +536,6 @@ void waybar::Bar::onMap(GdkEventAny*) {
   surface = gdk_wayland_window_get_wl_surface(gdk_window);
 }
 
-void waybar::Bar::setVisible(bool value) {
-  visible = value;
-  if (!visible) {
-    window.get_style_context()->add_class("hidden");
-    window.set_opacity(0);
-    surface_impl_->setLayer(bar_layer::BOTTOM);
-  } else {
-    window.get_style_context()->remove_class("hidden");
-    window.set_opacity(1);
-    surface_impl_->setLayer(layer_);
-  }
-  surface_impl_->setExclusiveZone(exclusive && visible);
-  surface_impl_->commit();
-}
-
-void waybar::Bar::toggle() { setVisible(!visible); }
-
 // Converting string to button code rn as to avoid doing it later
 void waybar::Bar::setupAltFormatKeyForModule(const std::string& module_name) {
   if (config.isMember(module_name)) {
@@ -614,6 +597,62 @@ void waybar::Bar::handleSignal(int signal) {
   }
 }
 
+void waybar::Bar::setVisible(bool value) {
+  visible = value;
+  if (!visible) {
+    window.get_style_context()->add_class("hidden");
+    window.set_opacity(0);
+    surface_impl_->setLayer(bar_layer::BOTTOM);
+  } else {
+    window.get_style_context()->remove_class("hidden");
+    window.set_opacity(1);
+    surface_impl_->setLayer(layer_);
+  }
+  surface_impl_->setExclusiveZone(exclusive && visible);
+  surface_impl_->commit();
+}
+
+void waybar::Bar::setHiddenClass(bool value) const {
+  if (value) {
+    window.get_style_context()->add_class("hidden");
+  } else {
+    window.get_style_context()->remove_class("hidden");
+  }
+}
+
+void waybar::Bar::setBottomLayerClass(bool value) const {
+  if (value) {
+    window.get_style_context()->add_class("bottom-layer");
+  } else {
+    window.get_style_context()->remove_class("bottom-layer");
+  }
+}
+
+void waybar::Bar::moveToTopLayer() const {
+  surface_impl_->setLayer(bar_layer::TOP);
+  surface_impl_->commit();
+}
+
+void waybar::Bar::moveToBottomLayer() const {
+  surface_impl_->setLayer(bar_layer::BOTTOM);
+  surface_impl_->commit();
+}
+
+void waybar::Bar::moveToConfiguredLayer() const {
+  surface_impl_->setLayer(layer_);
+  surface_impl_->commit();
+}
+
+void waybar::Bar::setExclusive(bool value) {
+  exclusive = value;
+  surface_impl_->setExclusiveZone(exclusive && visible);
+  surface_impl_->commit();
+}
+
+void waybar::Bar::toggle() {
+  return setVisible(!visible);
+}
+
 void waybar::Bar::getModules(const Factory& factory, const std::string& pos) {
   if (config[pos].isArray()) {
     for (const auto& name : config[pos]) {
diff --git a/src/factory.cpp b/src/factory.cpp
index 983635450..02b981813 100644
--- a/src/factory.cpp
+++ b/src/factory.cpp
@@ -22,6 +22,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const {
     if (ref == "sway/window") {
       return new waybar::modules::sway::Window(id, bar_, config_[name]);
     }
+    if (ref == "sway/hide") {
+      return new waybar::modules::sway::Hide(id, bar_, config_[name]);
+    }
     if (ref == "sway/language") {
         return new waybar::modules::sway::Language(id, config_[name]);
     }
diff --git a/src/modules/sway/hide.cpp b/src/modules/sway/hide.cpp
new file mode 100644
index 000000000..c5984e2db
--- /dev/null
+++ b/src/modules/sway/hide.cpp
@@ -0,0 +1,83 @@
+#include "modules/sway/hide.hpp"
+#include <spdlog/spdlog.h>
+#include "client.hpp"
+#include "wlr-layer-shell-unstable-v1-client-protocol.h"
+
+namespace waybar::modules::sway {
+
+Hide::Hide(const std::string& id, const Bar& bar, const Json::Value& config)
+    : ALabel(config, "hide", id, "{}", 0, true), bar_(bar), windowId_(-1) {
+  ipc_.subscribe(R"(["bar_state_update","barconfig_update"])");
+  ipc_.signal_event.connect(sigc::mem_fun(*this, &Hide::onEvent));
+
+  // override mode to "hide"
+  auto &bar_local = const_cast<Bar &>(bar_);
+  bar_local.config["mode"] = "hide";
+  bar_local.setExclusive(false);
+
+  if (config_["hide-on-startup"].asBool()) {
+    spdlog::debug("sway/hide: Hiding on startup enabled!");
+    bar_local.setHiddenClass(true);
+    bar_local.moveToConfiguredLayer();
+  } else {
+    bar_local.moveToTopLayer();
+  }
+
+  ipc_.setWorker([this] {
+    try {
+      ipc_.handleEvent();
+    } catch (const std::exception& e) {
+      spdlog::error("Hide: {}", e.what());
+    }
+  });
+}
+
+void Hide::onEvent(const struct Ipc::ipc_response& res) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  auto payload = parser_.parse(res.payload);
+  auto &bar = const_cast<Bar &>(bar_);
+
+  if (payload.isMember("mode")) {
+    auto mode = payload["mode"].asString();
+    if (mode == "hide") {
+      // Hide the bars when configuring the "hide" bar
+      spdlog::debug("sway/hide: hiding bar(s)");
+      bar.setVisible(false);
+      bar.setExclusive(false);
+    } else if (mode == "dock") { // enables toggling the bar using killall -USR2 waybar
+      spdlog::debug("sway/hide: showing bar(s)");
+      bar.setVisible(true);
+      bar.setExclusive(true);
+    }
+    return;
+  }
+
+  if (payload.isMember("visible_by_modifier")) {
+    visible_by_modifier_ = payload["visible_by_modifier"].asBool();
+    spdlog::debug("sway/hide: visible by modifier: {}", visible_by_modifier_);
+
+    if (visible_by_modifier_) {
+      bar.setHiddenClass(false);
+      bar.setBottomLayerClass(false);
+      bar.moveToTopLayer();
+      return;
+    }
+
+    bool hide_to_bottom_layer_ = config_["hide-to-bottom-layer"].asBool();
+    if (hide_to_bottom_layer_) {
+      spdlog::debug("sway/hide: Moving bar to bottom layer instead of hiding.");
+      bar.setBottomLayerClass(true);
+      bar.moveToBottomLayer();
+      return;
+    }
+
+    bar.setBottomLayerClass(false);
+    bar.setHiddenClass(true);
+    bar.moveToConfiguredLayer();
+  }
+}
+
+auto Hide::update() -> void {
+}
+
+}  // namespace waybar::modules::sway