add support for multi monitor setups

yes, this patch is probably highly dubious as I honestly don't
have much clue about the wayland event loop. but hey, it seems
to work just fine
This commit is contained in:
Virt 2025-03-09 14:06:57 +01:00
commit 5f1da28f96
3 changed files with 60 additions and 6 deletions

View file

@ -12,6 +12,7 @@
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <wayland-client-protocol.h>
#include <wayland-client.h>
#ifdef __linux__
@ -37,6 +38,7 @@ const char usage[] =
" --awake-phase seconds-seconds\n"
" --currently awake|asleep|random\n"
" --layer background|bottom|top|overlay\n"
" --output name\n"
" --survive-close\n"
"\n";
@ -101,6 +103,12 @@ uint32_t phase_awake_max = 600;
bool wakeup_shock = false; /* will force a shock, used when woken up */
char* output_name = NULL;
struct wl_output* output = NULL;
uint32_t required_hits = 1; /* we at least need the sync */
uint32_t found_hits = 0;
struct Seat
{
struct wl_list link;
@ -1204,7 +1212,7 @@ static void surface_create (void)
surface.layer_surface = zwlr_layer_shell_v1_get_layer_surface(
layer_shell,
surface.wl_surface,
NULL,
output,
layer,
"wayneko"
);
@ -1233,11 +1241,33 @@ static void surface_create (void)
wl_surface_commit(surface.wl_surface);
}
static void attempt_surface_creation (void) {
// waits until we have seen all outputs
if (required_hits <= ++found_hits) surface_create();
}
/**********
* *
* Main *
* *
**********/
static void handle_output_name(void *data, struct wl_output *wl_output, const char *name) {
if (strcmp(name, output_name) == 0) {
output = wl_output;
}
attempt_surface_creation();
}
static const struct wl_output_listener output_listener = {
.name = handle_output_name,
.geometry = noop,
.mode = noop,
.done = noop,
.scale = noop,
.description = noop
};
static void registry_handle_global (void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version)
{
@ -1249,10 +1279,14 @@ static void registry_handle_global (void *data, struct wl_registry *registry,
wl_shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
else if ( strcmp(interface, ext_idle_notifier_v1_interface.name) == 0 )
idle_notifier = wl_registry_bind(registry, name, &ext_idle_notifier_v1_interface, 1);
else if ( strcmp(interface, wl_seat_interface.name) == 0 )
{
else if ( strcmp(interface, wl_seat_interface.name) == 0 ) {
struct wl_seat *wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 7);
seat_new(wl_seat, name);
} else if ( strcmp(interface, wl_output_interface.name) == 0 && output_name != NULL) {
struct wl_output* output = wl_registry_bind(registry, name, &wl_output_interface, version);
required_hits++; // we want to wait for this monitor to be checked before surface creation
wl_output_add_listener(output, &output_listener, NULL);
}
}
@ -1308,7 +1342,7 @@ static void sync_handle_done (void *data, struct wl_callback *wl_callback, uint3
}
}
surface_create();
attempt_surface_creation();
}
static const struct wl_callback_listener sync_callback_listener = {
@ -1531,6 +1565,14 @@ int main (int argc, char *argv[])
if (current_phase == PHASE_AWAKE)
current_neko = NEKO_SLEEP_1;
}
else if ( strcmp(argv[i], "--output") == 0 )
{
char *t = get_argument(argc, argv, &i);
if ( t == NULL )
return EXIT_FAILURE;
output_name = t;
}
else
{
fprintf(stderr, "ERROR: Unknown option: %s\n", argv[i]);