refactor: don't wrap Bar in an optional

This commit is contained in:
Raphael Robatsch 2021-11-02 19:15:24 +01:00
parent 2f79dbd9fb
commit 945a93ed64
3 changed files with 41 additions and 40 deletions

View File

@ -66,13 +66,12 @@ void BarComponent::setText(const std::string& text)
pango_layout_set_text(pangoLayout.get(), _text->c_str(), _text->size()); pango_layout_set_text(pangoLayout.get(), _text->c_str(), _text->size());
} }
Bar::Bar(Monitor* mon) Bar::Bar()
{ {
_mon = mon;
_pangoContext.reset(pango_font_map_create_context(pango_cairo_font_map_get_default())); _pangoContext.reset(pango_font_map_create_context(pango_cairo_font_map_get_default()));
if (!_pangoContext) die("pango_font_map_create_context"); if (!_pangoContext) die("pango_font_map_create_context");
for (auto i=0u; i<tagNames.size(); i++) { for (const auto& tagName : tagNames) {
_tags.push_back({ TagState::None, 0, 0, createComponent(tagNames[i]) }); _tags.push_back({ TagState::None, 0, 0, createComponent(tagName) });
} }
_layoutCmp = createComponent(); _layoutCmp = createComponent();
_titleCmp = createComponent(); _titleCmp = createComponent();
@ -128,7 +127,7 @@ void Bar::invalidate()
wl_surface_commit(_surface.get()); wl_surface_commit(_surface.get());
} }
void Bar::click(int x, int, int btn) void Bar::click(Monitor* mon, int x, int, int btn)
{ {
Arg arg = {0}; Arg arg = {0};
Arg* argp = nullptr; Arg* argp = nullptr;
@ -150,7 +149,7 @@ void Bar::click(int x, int, int btn)
for (auto i = 0u; i < sizeof(buttons)/sizeof(buttons[0]); i++) { for (auto i = 0u; i < sizeof(buttons)/sizeof(buttons[0]); i++) {
const auto& button = buttons[i]; const auto& button = buttons[i];
if (button.control == control && button.btn == btn) { if (button.control == control && button.btn == btn) {
button.func(*_mon, *(argp ? argp : &button.arg)); button.func(*mon, *(argp ? argp : &button.arg));
return; return;
} }
} }

View File

@ -36,7 +36,6 @@ class Bar {
wl_unique_ptr<wl_surface> _surface; wl_unique_ptr<wl_surface> _surface;
wl_unique_ptr<zwlr_layer_surface_v1> _layerSurface; wl_unique_ptr<zwlr_layer_surface_v1> _layerSurface;
wl_unique_ptr<PangoContext> _pangoContext; wl_unique_ptr<PangoContext> _pangoContext;
Monitor* _mon;
std::optional<ShmBuffer> _bufs; std::optional<ShmBuffer> _bufs;
std::vector<Tag> _tags; std::vector<Tag> _tags;
BarComponent _layoutCmp, _titleCmp, _statusCmp; BarComponent _layoutCmp, _titleCmp, _statusCmp;
@ -60,7 +59,7 @@ class Bar {
void renderComponent(BarComponent& component); void renderComponent(BarComponent& component);
BarComponent createComponent(const std::string& initial = {}); BarComponent createComponent(const std::string& initial = {});
public: public:
Bar(Monitor *mon); Bar();
const wl_surface* surface() const; const wl_surface* surface() const;
bool visible() const; bool visible() const;
void show(wl_output* output); void show(wl_output* output);
@ -71,5 +70,5 @@ public:
void setTitle(const std::string& title); void setTitle(const std::string& title);
void setStatus(const std::string& status); void setStatus(const std::string& status);
void invalidate(); void invalidate();
void click(int x, int y, int btn); void click(Monitor* mon, int x, int y, int btn);
}; };

View File

@ -6,6 +6,7 @@
#include <sstream> #include <sstream>
#include <list> #include <list>
#include <optional> #include <optional>
#include <utility>
#include <vector> #include <vector>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
@ -30,7 +31,7 @@ struct Monitor {
uint32_t registryName; uint32_t registryName;
std::string xdgName; std::string xdgName;
wl_unique_ptr<wl_output> wlOutput; wl_unique_ptr<wl_output> wlOutput;
std::optional<Bar> bar; Bar bar;
bool desiredVisibility {true}; bool desiredVisibility {true};
bool hasData; bool hasData;
uint32_t tags; uint32_t tags;
@ -38,7 +39,7 @@ struct Monitor {
struct SeatPointer { struct SeatPointer {
wl_unique_ptr<wl_pointer> wlPointer; wl_unique_ptr<wl_pointer> wlPointer;
Bar* focusedBar; Monitor* focusedMonitor;
int x, y; int x, y;
std::vector<int> btns; std::vector<int> btns;
}; };
@ -48,8 +49,8 @@ struct Seat {
std::optional<SeatPointer> pointer; std::optional<SeatPointer> pointer;
}; };
static Bar* barFromSurface(const wl_surface* surface); static Monitor* monitorFromSurface(const wl_surface* surface);
static void setupMonitor(Monitor& monitor); static void setupMonitor(uint32_t name, wl_output* output);
static void updatemon(Monitor &mon); static void updatemon(Monitor &mon);
static void onReady(); static void onReady();
static void setupStatusFifo(); static void setupStatusFifo();
@ -74,6 +75,7 @@ static wl_surface* cursorSurface;
static wl_cursor_image* cursorImage; static wl_cursor_image* cursorImage;
static bool ready; static bool ready;
static std::list<Monitor> monitors; static std::list<Monitor> monitors;
static std::vector<std::pair<uint32_t, wl_output*>> uninitializedOutputs;
static std::list<Seat> seats; static std::list<Seat> seats;
static Monitor* selmon; static Monitor* selmon;
static std::string lastStatus; static std::string lastStatus;
@ -114,19 +116,19 @@ static const struct zxdg_output_v1_listener xdgOutputListener = {
.description = [](void*, zxdg_output_v1*, const char*) { }, .description = [](void*, zxdg_output_v1*, const char*) { },
}; };
Bar* barFromSurface(const wl_surface* surface) Monitor* monitorFromSurface(const wl_surface* surface)
{ {
auto mon = std::find_if(begin(monitors), end(monitors), [surface](const Monitor& mon) { auto mon = std::find_if(begin(monitors), end(monitors), [surface](const Monitor& mon) {
return mon.bar && mon.bar->surface() == surface; return mon.bar.surface() == surface;
}); });
return mon != end(monitors) && mon->bar ? &*mon->bar : nullptr; return mon != end(monitors) ? &*mon : nullptr;
} }
static const struct wl_pointer_listener pointerListener = { static const struct wl_pointer_listener pointerListener = {
.enter = [](void* sp, wl_pointer* pointer, uint32_t serial, .enter = [](void* sp, wl_pointer* pointer, uint32_t serial,
wl_surface* surface, wl_fixed_t x, wl_fixed_t y) wl_surface* surface, wl_fixed_t x, wl_fixed_t y)
{ {
auto& seat = *static_cast<Seat*>(sp); auto& seat = *static_cast<Seat*>(sp);
seat.pointer->focusedBar = barFromSurface(surface); seat.pointer->focusedMonitor = monitorFromSurface(surface);
if (!cursorImage) { if (!cursorImage) {
auto cursorTheme = wl_cursor_theme_load(nullptr, 24, shm); auto cursorTheme = wl_cursor_theme_load(nullptr, 24, shm);
cursorImage = wl_cursor_theme_get_cursor(cursorTheme, "left_ptr")->images[0]; cursorImage = wl_cursor_theme_get_cursor(cursorTheme, "left_ptr")->images[0];
@ -139,7 +141,7 @@ static const struct wl_pointer_listener pointerListener = {
}, },
.leave = [](void* sp, wl_pointer*, uint32_t serial, wl_surface*) { .leave = [](void* sp, wl_pointer*, uint32_t serial, wl_surface*) {
auto& seat = *static_cast<Seat*>(sp); auto& seat = *static_cast<Seat*>(sp);
seat.pointer->focusedBar = nullptr; seat.pointer->focusedMonitor = nullptr;
}, },
.motion = [](void* sp, wl_pointer*, uint32_t, wl_fixed_t x, wl_fixed_t y) { .motion = [](void* sp, wl_pointer*, uint32_t, wl_fixed_t x, wl_fixed_t y) {
auto& seat = *static_cast<Seat*>(sp); auto& seat = *static_cast<Seat*>(sp);
@ -158,9 +160,11 @@ static const struct wl_pointer_listener pointerListener = {
.axis = [](void* sp, wl_pointer*, uint32_t, uint32_t, wl_fixed_t) { }, .axis = [](void* sp, wl_pointer*, uint32_t, uint32_t, wl_fixed_t) { },
.frame = [](void* sp, wl_pointer*) { .frame = [](void* sp, wl_pointer*) {
auto& seat = *static_cast<Seat*>(sp); auto& seat = *static_cast<Seat*>(sp);
if (!seat.pointer->focusedBar) return; auto mon = seat.pointer->focusedMonitor;
if (!mon)
return;
for (auto btn : seat.pointer->btns) { for (auto btn : seat.pointer->btns) {
seat.pointer->focusedBar->click(seat.pointer->x, seat.pointer->y, btn); mon->bar.click(mon, seat.pointer->x, seat.pointer->y, btn);
} }
seat.pointer->btns.clear(); seat.pointer->btns.clear();
}, },
@ -185,9 +189,9 @@ static const struct wl_seat_listener seatListener = {
.name = [](void*, wl_seat*, const char *name) { } .name = [](void*, wl_seat*, const char *name) { }
}; };
void setupMonitor(Monitor& monitor) { void setupMonitor(uint32_t name, wl_output* output) {
monitor.bar.emplace(&monitor); auto& monitor = monitors.emplace_back(Monitor {name, {}, wl_unique_ptr<wl_output> {output}});
monitor.bar->setStatus(lastStatus); monitor.bar.setStatus(lastStatus);
auto xdgOutput = zxdg_output_manager_v1_get_xdg_output(xdgOutputManager, monitor.wlOutput.get()); auto xdgOutput = zxdg_output_manager_v1_get_xdg_output(xdgOutputManager, monitor.wlOutput.get());
zxdg_output_v1_add_listener(xdgOutput, &xdgOutputListener, &monitor); zxdg_output_v1_add_listener(xdgOutput, &xdgOutputListener, &monitor);
} }
@ -196,13 +200,13 @@ void updatemon(Monitor& mon)
{ {
if (!mon.hasData) return; if (!mon.hasData) return;
if (mon.desiredVisibility) { if (mon.desiredVisibility) {
if (mon.bar->visible()) { if (mon.bar.visible()) {
mon.bar->invalidate(); mon.bar.invalidate();
} else { } else {
mon.bar->show(mon.wlOutput.get()); mon.bar.show(mon.wlOutput.get());
} }
} else if (mon.bar->visible()) { } else if (mon.bar.visible()) {
mon.bar->hide(); mon.bar.hide();
} }
} }
@ -217,8 +221,8 @@ void onReady()
wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc. wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc.
ready = true; ready = true;
for (auto& monitor : monitors) { for (auto output : uninitializedOutputs) {
setupMonitor(monitor); setupMonitor(output.first, output.second);
} }
wl_display_roundtrip(display); // wait for xdg_output names before we read stdin wl_display_roundtrip(display); // wait for xdg_output names before we read stdin
} }
@ -283,11 +287,11 @@ static void handleStdin(const std::string& line)
if (command == "title") { if (command == "title") {
auto title = std::string {}; auto title = std::string {};
std::getline(stream, title); std::getline(stream, title);
mon->bar->setTitle(title); mon->bar.setTitle(title);
} else if (command == "selmon") { } else if (command == "selmon") {
uint32_t selected; uint32_t selected;
stream >> selected; stream >> selected;
mon->bar->setSelected(selected); mon->bar.setSelected(selected);
if (selected) { if (selected) {
selmon = &*mon; selmon = &*mon;
} else if (selmon == &*mon) { } else if (selmon == &*mon) {
@ -303,13 +307,13 @@ static void handleStdin(const std::string& line)
state |= TagState::Active; state |= TagState::Active;
if (urgent & tagMask) if (urgent & tagMask)
state |= TagState::Urgent; state |= TagState::Urgent;
mon->bar->setTag(i, state, occupied & tagMask ? 1 : 0, clientTags & tagMask ? 0 : -1); mon->bar.setTag(i, state, occupied & tagMask ? 1 : 0, clientTags & tagMask ? 0 : -1);
} }
mon->tags = tags; mon->tags = tags;
} else if (command == "layout") { } else if (command == "layout") {
auto layout = std::string {}; auto layout = std::string {};
std::getline(stream, layout); std::getline(stream, layout);
mon->bar->setLayout(layout); mon->bar.setLayout(layout);
} }
mon->hasData = true; mon->hasData = true;
updatemon(*mon); updatemon(*mon);
@ -334,10 +338,8 @@ void onStatus()
if (str.rfind(prefixStatus, 0) == 0) { if (str.rfind(prefixStatus, 0) == 0) {
lastStatus = str.substr(prefixStatus.size()); lastStatus = str.substr(prefixStatus.size());
for (auto &monitor : monitors) { for (auto &monitor : monitors) {
if (monitor.bar) { monitor.bar.setStatus(lastStatus);
monitor.bar->setStatus(lastStatus); monitor.bar.invalidate();
monitor.bar->invalidate();
}
} }
} else if (str.rfind(prefixShow, 0) == 0) { } else if (str.rfind(prefixShow, 0) == 0) {
updateVisibility(str.substr(prefixShow.size()), [](bool) { return true; }); updateVisibility(str.substr(prefixShow.size()), [](bool) { return true; });
@ -395,9 +397,10 @@ void onGlobalAdd(void*, wl_registry* registry, uint32_t name, const char* interf
return; return;
} }
if (wl_output *output; reg.handle(output, wl_output_interface, 1)) { if (wl_output *output; reg.handle(output, wl_output_interface, 1)) {
auto& m = monitors.emplace_back(Monitor {name, {}, wl_unique_ptr<wl_output> {output}});
if (ready) { if (ready) {
setupMonitor(m); setupMonitor(name, output);
} else {
uninitializedOutputs.push_back({name, output});
} }
return; return;
} }