capture xdg-output names
This commit is contained in:
parent
5e5c04af47
commit
1175bbbc23
2 changed files with 56 additions and 8 deletions
|
@ -13,6 +13,7 @@ wayland_scanner_client = generator(
|
||||||
|
|
||||||
wayland_xmls = [
|
wayland_xmls = [
|
||||||
wl_protocol_dir + '/stable/xdg-shell/xdg-shell.xml',
|
wl_protocol_dir + '/stable/xdg-shell/xdg-shell.xml',
|
||||||
|
wl_protocol_dir + '/unstable/xdg-output/xdg-output-unstable-v1.xml',
|
||||||
'wlr-layer-shell-unstable-v1.xml',
|
'wlr-layer-shell-unstable-v1.xml',
|
||||||
'net-tapesoftware-dwl-wm-unstable-v1.xml',
|
'net-tapesoftware-dwl-wm-unstable-v1.xml',
|
||||||
]
|
]
|
||||||
|
|
55
src/main.cpp
55
src/main.cpp
|
@ -19,17 +19,20 @@
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <wayland-cursor.h>
|
#include <wayland-cursor.h>
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
|
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||||
#include "xdg-shell-client-protocol.h"
|
#include "xdg-shell-client-protocol.h"
|
||||||
#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h"
|
#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h"
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
|
|
||||||
struct Monitor {
|
struct Monitor {
|
||||||
uint32_t name;
|
uint32_t registryName;
|
||||||
|
std::string xdgName;
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SeatPointer {
|
struct SeatPointer {
|
||||||
wl_unique_ptr<wl_pointer> wlPointer;
|
wl_unique_ptr<wl_pointer> wlPointer;
|
||||||
Bar *focusedBar;
|
Bar *focusedBar;
|
||||||
|
@ -58,6 +61,7 @@ znet_tapesoftware_dwl_wm_v1 *dwlWm;
|
||||||
std::vector<std::string> tagNames;
|
std::vector<std::string> tagNames;
|
||||||
std::vector<std::string> layoutNames;
|
std::vector<std::string> layoutNames;
|
||||||
static xdg_wm_base *xdgWmBase;
|
static xdg_wm_base *xdgWmBase;
|
||||||
|
static zxdg_output_manager_v1 *xdgOutputManager;
|
||||||
static wl_surface *cursorSurface;
|
static wl_surface *cursorSurface;
|
||||||
static wl_cursor_image *cursorImage;
|
static wl_cursor_image *cursorImage;
|
||||||
static bool ready;
|
static bool ready;
|
||||||
|
@ -71,6 +75,10 @@ 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);
|
||||||
|
@ -109,6 +117,18 @@ static const struct xdg_wm_base_listener xdgWmBaseListener = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct zxdg_output_v1_listener xdgOutputListener = {
|
||||||
|
.logical_position = [](void*, zxdg_output_v1*, int, int) { },
|
||||||
|
.logical_size = [](void*, zxdg_output_v1*, int, int) { },
|
||||||
|
.done = [](void*, zxdg_output_v1*) { },
|
||||||
|
.name = [](void *mp, zxdg_output_v1 *xdgOutput, const char *name) {
|
||||||
|
auto& monitor = *static_cast<Monitor*>(mp);
|
||||||
|
monitor.xdgName = name;
|
||||||
|
zxdg_output_v1_destroy(xdgOutput);
|
||||||
|
},
|
||||||
|
.description = [](void*, zxdg_output_v1*, const char*) { },
|
||||||
|
};
|
||||||
|
|
||||||
static Bar* barFromSurface(const wl_surface *surface)
|
static Bar* barFromSurface(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) {
|
||||||
|
@ -221,6 +241,8 @@ static void setupMonitor(Monitor &monitor) {
|
||||||
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);
|
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());
|
||||||
|
zxdg_output_v1_add_listener(xdgOutput, &xdgOutputListener, &monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// called after we have received the initial batch of globals
|
// called after we have received the initial batch of globals
|
||||||
|
@ -229,6 +251,7 @@ static void onReady()
|
||||||
requireGlobal(compositor, "wl_compositor");
|
requireGlobal(compositor, "wl_compositor");
|
||||||
requireGlobal(shm, "wl_shm");
|
requireGlobal(shm, "wl_shm");
|
||||||
requireGlobal(wlrLayerShell, "zwlr_layer_shell_v1");
|
requireGlobal(wlrLayerShell, "zwlr_layer_shell_v1");
|
||||||
|
requireGlobal(xdgOutputManager, "zxdg_output_manager_v1");
|
||||||
requireGlobal(dwlWm, "znet_tapesoftware_dwl_wm_v1");
|
requireGlobal(dwlWm, "znet_tapesoftware_dwl_wm_v1");
|
||||||
setupStatusFifo();
|
setupStatusFifo();
|
||||||
wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc.
|
wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc.
|
||||||
|
@ -270,17 +293,40 @@ static void setupStatusFifo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string prefixStatus = "status ";
|
||||||
|
const std::string prefixShow = "show ";
|
||||||
|
const std::string prefixHide = "hide ";
|
||||||
|
const std::string prefixToggle = "toggle ";
|
||||||
|
const std::string argAll = "all";
|
||||||
|
const std::string argCurrent = "current";
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void updateVisibility(const std::string &name, T updater)
|
||||||
|
{
|
||||||
|
auto isCurrent = name == argCurrent;
|
||||||
|
auto isAll = name == argAll;
|
||||||
|
}
|
||||||
|
|
||||||
static void onStatus()
|
static void onStatus()
|
||||||
{
|
{
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
auto n = read(statusFifoFd, buffer, sizeof(buffer));
|
auto n = read(statusFifoFd, buffer, sizeof(buffer));
|
||||||
lastStatus = {buffer, (unsigned long) n};
|
auto str = std::string {buffer, (unsigned long) n};
|
||||||
|
if (str.rfind(prefixStatus, 0) == 0) {
|
||||||
|
lastStatus = str.substr(prefixStatus.size());
|
||||||
for (auto &monitor : monitors) {
|
for (auto &monitor : monitors) {
|
||||||
if (monitor.bar) {
|
if (monitor.bar) {
|
||||||
monitor.bar->setStatus(lastStatus);
|
monitor.bar->setStatus(lastStatus);
|
||||||
monitor.bar->invalidate();
|
monitor.bar->invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (str.rfind(prefixShow, 0) == 0) {
|
||||||
|
updateVisibility(str.substr(prefixShow.size()), [](bool) { return true; });
|
||||||
|
} else if (str.rfind(prefixHide, 0) == 0) {
|
||||||
|
updateVisibility(str.substr(prefixHide.size()), [](bool) { return false; });
|
||||||
|
} else if (str.rfind(prefixToggle, 0) == 0) {
|
||||||
|
updateVisibility(str.substr(prefixToggle.size()), [](bool vis) { return !vis; });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HandleGlobalHelper {
|
struct HandleGlobalHelper {
|
||||||
|
@ -301,6 +347,7 @@ static void registryHandleGlobal(void*, wl_registry *registry, uint32_t name, co
|
||||||
if (reg.handle(compositor, wl_compositor_interface, 4)) return;
|
if (reg.handle(compositor, wl_compositor_interface, 4)) return;
|
||||||
if (reg.handle(shm, wl_shm_interface, 1)) return;
|
if (reg.handle(shm, wl_shm_interface, 1)) return;
|
||||||
if (reg.handle(wlrLayerShell, zwlr_layer_shell_v1_interface, 4)) return;
|
if (reg.handle(wlrLayerShell, zwlr_layer_shell_v1_interface, 4)) return;
|
||||||
|
if (reg.handle(xdgOutputManager, zxdg_output_manager_v1_interface, 3)) return;
|
||||||
if (reg.handle(xdgWmBase, xdg_wm_base_interface, 2)) {
|
if (reg.handle(xdgWmBase, xdg_wm_base_interface, 2)) {
|
||||||
xdg_wm_base_add_listener(xdgWmBase, &xdgWmBaseListener, nullptr);
|
xdg_wm_base_add_listener(xdgWmBase, &xdgWmBaseListener, nullptr);
|
||||||
return;
|
return;
|
||||||
|
@ -315,7 +362,7 @@ static void registryHandleGlobal(void*, wl_registry *registry, uint32_t name, co
|
||||||
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}});
|
auto& m = monitors.emplace_back(Monitor {name, {}, wl_unique_ptr<wl_output> {output}});
|
||||||
if (ready) {
|
if (ready) {
|
||||||
setupMonitor(m);
|
setupMonitor(m);
|
||||||
}
|
}
|
||||||
|
@ -324,7 +371,7 @@ static void registryHandleGlobal(void*, wl_registry *registry, uint32_t name, co
|
||||||
}
|
}
|
||||||
static void registryHandleRemove(void*, wl_registry *registry, uint32_t name)
|
static void registryHandleRemove(void*, wl_registry *registry, uint32_t name)
|
||||||
{
|
{
|
||||||
monitors.remove_if([name](const Monitor &mon) { return mon.name == name; });
|
monitors.remove_if([name](const Monitor &mon) { return mon.registryName == name; });
|
||||||
seats.remove_if([name](const Seat &seat) { return seat.name == name; });
|
seats.remove_if([name](const Seat &seat) { return seat.name == name; });
|
||||||
}
|
}
|
||||||
static const struct wl_registry_listener registry_listener = {
|
static const struct wl_registry_listener registry_listener = {
|
||||||
|
|
Loading…
Reference in a new issue