diff --git a/config/config.lua b/config/config.lua
index 59ec301..731d5cf 100644
--- a/config/config.lua
+++ b/config/config.lua
@@ -109,12 +109,17 @@ local function render_workspaces(displayName)
wsbox(label{label=" " .. zen.u.html_escape(workspace.name) .. " "}, boxcolor),
wsbox(label{label=zen.u.html_escape(app_name)}, boxcolor),
},
+ tag = workspace.name
}
table.insert(workspaces, workspace)
end
return { type = "flex", direction = "column", padding = { left = 10, bottom = 10 }, items = workspaces }
end
+local function click_workspace(tag)
+ os.execute("swaymsg workspace '" .. tag .. "'")
+end
+
local function render_time()
local t = os.time()
local markup = os.date("%H:%M\n%Y-%m-%d")
@@ -192,7 +197,7 @@ return {
{
anchor = "left",
widgets = {
- { sources = {'displays'}, padding = {left = 10 }, on_render = render_workspaces },
+ { sources = {'displays'}, padding = {left = 10 }, on_render = render_workspaces, on_click = click_workspace },
},
},
{
diff --git a/src/Configuration.h b/src/Configuration.h
index b6d76a8..2a282c0 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -46,11 +46,16 @@ struct Border {
enum class Anchor { Left, Right, Top, Bottom };
+struct Target {
+ Rect position;
+ std::string tag;
+};
+
struct Renderable {
Renderable() : computed{} {}
virtual ~Renderable() {}
virtual void Compute(cairo_t*) {}
- virtual void Draw(cairo_t*, int /*x*/, int /*y*/) const {}
+ virtual void Draw(cairo_t*, int /*x*/, int /*y*/, std::vector& /*targets*/) const {}
Size computed;
};
@@ -60,7 +65,7 @@ struct Markup : public Renderable {
if (m_layout) g_object_unref(m_layout);
}
void Compute(cairo_t* cr) override;
- void Draw(cairo_t* cr, int x, int y) const override;
+ void Draw(cairo_t* cr, int x, int y, std::vector& targets) const override;
private:
const std::string string;
@@ -71,29 +76,31 @@ struct MarkupBox : public Renderable {
MarkupBox(const std::string& string)
: Renderable(), markup(string), color({}), border({}), radius(0), padding({}) {}
void Compute(cairo_t* cr) override;
- void Draw(cairo_t* cr, int x, int y) const override;
+ void Draw(cairo_t* cr, int x, int y, std::vector& targets) const override;
Markup markup;
RGBA color;
Border border;
uint8_t radius;
Padding padding;
+ std::string tag;
};
struct FlexContainer : public Renderable {
FlexContainer() : Renderable(), isColumn(false), padding({}) {}
void Compute(cairo_t* cr) override;
- void Draw(cairo_t* cr, int x, int y) const override;
+ void Draw(cairo_t* cr, int x, int y, std::vector& targets) const override;
bool isColumn;
Padding padding;
std::vector> children;
+ std::string tag;
};
struct WidgetConfig {
WidgetConfig() : padding({}) {}
std::function(const std::string& outputName)> render;
- std::function click;
+ std::function click;
std::set sources;
Padding padding;
};
@@ -101,7 +108,7 @@ struct WidgetConfig {
struct Widget {
Widget() : computed({}), m_renderable(nullptr), m_paddingX(0), m_paddingY(0) {}
void Compute(const WidgetConfig& config, const std::string& outputName, cairo_t* cr);
- void Draw(cairo_t* cr, int x, int y) const;
+ void Draw(cairo_t* cr, int x, int y, std::vector& targets) const;
Size computed;
private:
diff --git a/src/Draw.cpp b/src/Draw.cpp
index 8cabc71..55b2401 100644
--- a/src/Draw.cpp
+++ b/src/Draw.cpp
@@ -23,7 +23,7 @@ void Markup::Compute(cairo_t* cr) {
LogComputed(computed, ("Markup " + string).c_str());
}
-void Markup::Draw(cairo_t* cr, int x, int y) const {
+void Markup::Draw(cairo_t* cr, int x, int y, std::vector& targets) const {
LogDraw("Markup", x, y);
cairo_move_to(cr, x, y);
pango_cairo_show_layout(cr, m_layout);
@@ -54,7 +54,7 @@ void MarkupBox::Compute(cairo_t* cr) {
LogComputed(computed, "MarkupBox ");
}
-void MarkupBox::Draw(cairo_t* cr, int x, int y) const {
+void MarkupBox::Draw(cairo_t* cr, int x, int y, std::vector& targets) const {
LogDraw("MarkupBox", x, y);
BeginRectangleSubPath(cr, x + border.width, y + border.width, computed.cx - (2 * border.width),
computed.cy - (2 * border.width), radius);
@@ -78,7 +78,11 @@ void MarkupBox::Draw(cairo_t* cr, int x, int y) const {
cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
cairo_fill(cr);
// Inner
- markup.Draw(cr, x + padding.left + border.width, y + padding.top + border.width);
+ markup.Draw(cr, x + padding.left + border.width, y + padding.top + border.width, targets);
+ if (tag != "") {
+ targets.push_back(Target{
+ .position = Rect{.x = x, .y = y, .cx = computed.cx, .cy = computed.cy}, .tag = tag});
+ }
}
void FlexContainer::Compute(cairo_t* cr) {
@@ -97,23 +101,30 @@ void FlexContainer::Compute(cairo_t* cr) {
LogComputed(computed, "FlexContainer");
}
-void FlexContainer::Draw(cairo_t* cr, int x, int y) const {
+void FlexContainer::Draw(cairo_t* cr, int x, int y, std::vector& targets) const {
LogDraw("FlexBox", x, y);
+ const int startx = x;
+ const int starty = y;
if (isColumn) {
for (const auto& r : children) {
y += padding.top;
- r->Draw(cr, x + padding.left, y);
+ r->Draw(cr, x + padding.left, y, targets);
y += r->computed.cy + padding.bottom;
}
} else {
y += padding.top;
for (const auto& r : children) {
x += padding.left;
- r->Draw(cr, x, y);
+ r->Draw(cr, x, y, targets);
x += r->computed.cx + padding.right;
}
y += padding.bottom;
}
+ if (tag != "") {
+ targets.push_back(
+ Target{.position = Rect{.x = startx, .y = starty, .cx = computed.cx, .cy = computed.cy},
+ .tag = tag});
+ }
}
void Widget::Compute(const WidgetConfig& config, const std::string& outputName, cairo_t* cr) {
@@ -134,13 +145,13 @@ void Widget::Compute(const WidgetConfig& config, const std::string& outputName,
m_renderable = std::move(item);
}
-void Widget::Draw(cairo_t* cr, int x, int y) const {
+void Widget::Draw(cairo_t* cr, int x, int y, std::vector& targets) const {
if (!m_renderable) {
// Lua render failed previously
return;
}
cairo_save(cr);
- m_renderable->Draw(cr, x + m_paddingX, y + m_paddingY);
+ m_renderable->Draw(cr, x + m_paddingX, y + m_paddingY, targets);
cairo_restore(cr);
}
@@ -171,6 +182,7 @@ bool Draw::Panel(const PanelConfig& panelConfig, const std::string& outputName,
cx += widget.computed.cx;
cy += widget.computed.cy;
}
+ std::vector targets;
Align align;
int xfac = 0, yfac = 0;
if (panelConfig.isColumn) {
@@ -225,9 +237,10 @@ bool Draw::Panel(const PanelConfig& panelConfig, const std::string& outputName,
y = (maxCy - widget.computed.cy) / 2;
break;
}
- widget.Draw(cr, x, y);
+ widget.Draw(cr, x, y, targets);
drawn.widgets.push_back(
- DrawnWidget{.position = {x, y, widget.computed.cx, widget.computed.cy}});
+ DrawnWidget{.position = {x, y, widget.computed.cx, widget.computed.cy},
+ .targets = std::move(targets)});
x += widget.computed.cx * xfac;
y += widget.computed.cy * yfac;
}
diff --git a/src/Draw.h b/src/Draw.h
index f026b34..74c74ea 100644
--- a/src/Draw.h
+++ b/src/Draw.h
@@ -10,6 +10,7 @@
struct DrawnWidget {
Rect position;
+ std::vector targets;
};
struct DrawnPanel {
diff --git a/src/ScriptContext.cpp b/src/ScriptContext.cpp
index 1498683..1cb978b 100644
--- a/src/ScriptContext.cpp
+++ b/src/ScriptContext.cpp
@@ -36,6 +36,11 @@ Padding PaddingFromProperty(const sol::table& t, const char* name) {
return o ? PaddingFromTable(*o) : Padding{};
}
+std::string TagFromTable(const sol::table& t) {
+ const sol::optional optionalTag = t["tag"];
+ return optionalTag ? *optionalTag : "";
+}
+
static std::unique_ptr MarkupBoxFromTable(const sol::table& t) {
const sol::optional optionalMarkup = t["markup"];
const std::string markup = optionalMarkup ? *optionalMarkup : "";
@@ -44,6 +49,7 @@ static std::unique_ptr MarkupBoxFromTable(const sol::table& t) {
box->border = BorderFromProperty(t, "border");
box->color = RGBAFromProperty(t, "color");
box->padding = PaddingFromProperty(t, "padding");
+ box->tag = TagFromTable(t);
return box;
}
@@ -71,6 +77,7 @@ static std::unique_ptr FlexContainerFromTable(const sol::table& t) {
if (children) {
FromChildTable(*children, f.children);
}
+ f.tag = TagFromTable(t);
return std::unique_ptr(new FlexContainer(std::move(f)));
}
@@ -128,7 +135,10 @@ static void ParseWidgetConfig(const sol::table& table, std::vector
sol::optional maybeClickFunction = table["on_click"];
if (maybeClickFunction) {
auto clickFunction = *maybeClickFunction;
- widget.click = [clickFunction]() { clickFunction(); };
+ widget.click = [clickFunction](std::string_view tag) {
+ clickFunction(tag);
+ return true;
+ };
}
widget.padding = PaddingFromProperty(table, "padding");
widgets.push_back(std::move(widget));
diff --git a/src/ShellSurface.cpp b/src/ShellSurface.cpp
index b28c00c..88c64c2 100644
--- a/src/ShellSurface.cpp
+++ b/src/ShellSurface.cpp
@@ -55,12 +55,21 @@ bool ShellSurface::ClickSurface(wl_surface *surface, int x, int y) {
}
// Check what widget
int i = 0;
- for (const auto w : m_drawn.widgets) {
+ for (const auto &w : m_drawn.widgets) {
if (w.position.Contains(x, y)) {
- spdlog::trace("Found widget click target");
auto &widget = m_panelConfig.widgets.at(i);
if (widget.click) {
- widget.click();
+ // Widget has a click handler. There might be inner more
+ // specific targets, find the tag of the correct one.
+ std::string tag = "";
+ for (const auto &t : w.targets) {
+ if (t.position.Contains(x, y)) {
+ tag = t.tag;
+ break;
+ }
+ }
+ spdlog::debug("Click in widget, tag: {}", tag);
+ widget.click(tag);
}
break;
}