bar hide/show commands

This commit is contained in:
Raphael Robatsch 2021-10-27 17:24:47 +02:00
parent 1175bbbc23
commit 57063cb17f
2 changed files with 61 additions and 32 deletions

View file

@ -1,5 +1,5 @@
project('somebar', ['c', 'cpp'], project('somebar', ['c', 'cpp'],
default_options: ['cpp_std=c++17']) default_options: ['cpp_std=c++17', 'cpp_args=-Wno-parentheses'])
wayland_dep = dependency('wayland-client') wayland_dep = dependency('wayland-client')
wayland_cursor_dep = dependency('wayland-cursor') wayland_cursor_dep = dependency('wayland-cursor')

View file

@ -31,6 +31,8 @@ struct Monitor {
wl_unique_ptr<wl_output> wlOutput; wl_unique_ptr<wl_output> wlOutput;
wl_unique_ptr<znet_tapesoftware_dwl_wm_monitor_v1> dwlMonitor; wl_unique_ptr<znet_tapesoftware_dwl_wm_monitor_v1> dwlMonitor;
std::optional<Bar> bar; std::optional<Bar> bar;
bool desiredVisibility {true};
bool hasData;
}; };
struct SeatPointer { struct SeatPointer {
@ -45,13 +47,14 @@ struct Seat {
std::optional<SeatPointer> pointer; std::optional<SeatPointer> pointer;
}; };
static void waylandFlush(); static void updatemon(Monitor &mon);
static void requireGlobal(const void *p, const char *name);
static void setupStatusFifo(); static void setupStatusFifo();
static void onStatus(); static void onStatus();
static void cleanup();
static void requireGlobal(const void *p, const char *name);
static void waylandFlush();
[[noreturn]] static void diesys(const char *why); [[noreturn]] static void diesys(const char *why);
[[noreturn]] static void die(const char *why); [[noreturn]] static void die(const char *why);
static void cleanup();
wl_display *display; wl_display *display;
wl_compositor *compositor; wl_compositor *compositor;
@ -67,6 +70,7 @@ static wl_cursor_image *cursorImage;
static bool ready; static bool ready;
static std::list<Monitor> monitors; static std::list<Monitor> monitors;
static std::list<Seat> seats; static std::list<Seat> seats;
static Monitor *selmon;
static std::string lastStatus; static std::string lastStatus;
static std::string statusFifoName; static std::string statusFifoName;
static int epoll {-1}; static int epoll {-1};
@ -75,10 +79,6 @@ static int statusFifoFd {-1};
static int statusFifoWriter {-1}; static int statusFifoWriter {-1};
static bool quitting {false}; static bool quitting {false};
// Intentionally not inside Monitor, so we can preemptively manage the
// visibility of bars on future outputs.
static std::unordered_map<std::string, bool> barVisibility;
void view(Monitor &m, const Arg &arg) void view(Monitor &m, const Arg &arg)
{ {
znet_tapesoftware_dwl_wm_monitor_v1_set_tags(m.dwlMonitor.get(), arg.ui, 1); znet_tapesoftware_dwl_wm_monitor_v1_set_tags(m.dwlMonitor.get(), arg.ui, 1);
@ -212,6 +212,11 @@ static const struct znet_tapesoftware_dwl_wm_v1_listener dwlWmListener = {
static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorListener { static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorListener {
.selected = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t selected) { .selected = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t selected) {
auto mon = static_cast<Monitor*>(mv); auto mon = static_cast<Monitor*>(mv);
if (selected) {
selmon = mon;
} else if (selmon == mon) {
selmon = nullptr;
}
mon->bar->setSelected(selected); mon->bar->setSelected(selected);
}, },
.tag = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t tag, uint32_t state, uint32_t numClients, int32_t focusedClient) { .tag = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t tag, uint32_t state, uint32_t numClients, int32_t focusedClient) {
@ -228,11 +233,8 @@ static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorLis
}, },
.frame = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*) { .frame = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*) {
auto mon = static_cast<Monitor*>(mv); auto mon = static_cast<Monitor*>(mv);
if (mon->bar->visible()) { mon->hasData = true;
mon->bar->invalidate(); updatemon(*mon);
} else {
mon->bar->show(mon->wlOutput.get());
}
} }
}; };
@ -240,9 +242,23 @@ static void setupMonitor(Monitor &monitor) {
monitor.dwlMonitor.reset(znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, monitor.wlOutput.get())); monitor.dwlMonitor.reset(znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, monitor.wlOutput.get()));
monitor.bar.emplace(&monitor); monitor.bar.emplace(&monitor);
monitor.bar->setStatus(lastStatus); monitor.bar->setStatus(lastStatus);
znet_tapesoftware_dwl_wm_monitor_v1_add_listener(monitor.dwlMonitor.get(), &dwlWmMonitorListener, &monitor);
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);
znet_tapesoftware_dwl_wm_monitor_v1_add_listener(monitor.dwlMonitor.get(), &dwlWmMonitorListener, &monitor);
}
static void updatemon(Monitor &mon)
{
if (!mon.hasData) return;
if (mon.desiredVisibility) {
if (mon.bar->visible()) {
mon.bar->invalidate();
} else {
mon.bar->show(mon.wlOutput.get());
}
} else if (mon.bar->visible()) {
mon.bar->hide();
}
} }
// called after we have received the initial batch of globals // called after we have received the initial batch of globals
@ -305,13 +321,27 @@ static void updateVisibility(const std::string &name, T updater)
{ {
auto isCurrent = name == argCurrent; auto isCurrent = name == argCurrent;
auto isAll = name == argAll; auto isAll = name == argAll;
for (auto& mon : monitors) {
if (isAll ||
isCurrent && &mon == selmon ||
mon.xdgName == name) {
auto newVisibility = updater(mon.desiredVisibility);
if (newVisibility != mon.desiredVisibility) {
mon.desiredVisibility = newVisibility;
updatemon(mon);
}
}
}
} }
static void onStatus() static void onStatus()
{ {
// this doesn't handle cases where there's multiple or partial lines in the buffer
char buffer[512]; char buffer[512];
auto n = read(statusFifoFd, buffer, sizeof(buffer)); auto n = read(statusFifoFd, buffer, sizeof(buffer));
auto str = std::string {buffer, (unsigned long) n}; auto str = std::string {buffer, (unsigned long) n};
auto trailer = str.rfind('\n');
if (trailer != std::string::npos) str.erase(trailer);
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) {
@ -454,24 +484,14 @@ int main(int argc, char **argv)
cleanup(); cleanup();
} }
void die(const char *why) { void requireGlobal(const void *p, const char *name)
fprintf(stderr, "%s\n", why); {
if (p) return;
fprintf(stderr, "Wayland compositor does not export required global %s, aborting.\n", name);
cleanup(); cleanup();
exit(1); exit(1);
} }
void diesys(const char *why) {
perror(why);
cleanup();
exit(1);
}
void cleanup() {
if (!statusFifoName.empty()) {
unlink(statusFifoName.c_str());
}
}
void waylandFlush() void waylandFlush()
{ {
wl_display_dispatch_pending(display); wl_display_dispatch_pending(display);
@ -485,10 +505,19 @@ void waylandFlush()
} }
} }
static void requireGlobal(const void *p, const char *name) void die(const char *why) {
{
if (p) return;
fprintf(stderr, "Wayland compositor does not export required global %s, aborting.\n", name);
cleanup(); cleanup();
exit(1); exit(1);
} }
void diesys(const char *why) {
perror(why);
cleanup();
exit(1);
}
void cleanup() {
if (!statusFifoName.empty()) {
unlink(statusFifoName.c_str());
}
}