diff --git a/README b/README index e3f462f..dd1af47 100644 --- a/README +++ b/README @@ -10,6 +10,9 @@ a minimum and maximum duration which can be changed. This means it can no longer happen that Neko wakes up just to go to sleep immediately again and makes Neko being awake something you can look forward to. +It also adds support for multiple monitor setups as you can now specify the +used output via the `--output` flag. + Refer to the man page or `--help` command to see how to use this fork and which options are new or no longer available. diff --git a/wayneko.1 b/wayneko.1 index b976cb8..19c35d9 100644 --- a/wayneko.1 +++ b/wayneko.1 @@ -1,4 +1,4 @@ -.TH WAYNEKO 1 2024-03-24 "git.sr.ht/~leon_plickat/wayneko" "General Commands Manual" +.TH WAYNEKO 1 2024-03-24 "copeberg.org/virt/wayneko" "General Commands Manual" . .SH NAME .P @@ -21,6 +21,7 @@ wayneko \- Neko on Wayland but with phases .OP \-\-awake-phase seconds-seconds .OP \-\-currently awake|asleep|random .OP \-\-layer background|bottom|top|overlay +.OP \-\-output name .OP \-\-survive\-close .YS . @@ -102,6 +103,14 @@ Background may conflict with wallpaper clients. .RE . .P +\fB\-\-output\fR \fIname\fR +.RS +Sets the output where neko will live. Expects an output name (e.g. `eDP-1`) +and will fall back to the currently selected output if the monitor does not +exist. Defaults to the currently selected monitor. +.RE +. +.P \fB\-\-survive\-close\fR .RS If this flag is used, wayneko will recreate the surface after it has been closed. @@ -116,7 +125,7 @@ close the surface for a different reason. \fBSIGUSR1\fR .RS You can send `wayneko` this signal to wake Neko up spontaneously. Neko won't notice -anything it she is already awake. Example: `pkill -10 wayneko` +anything it she is already awake. Example usage: `pkill -10 wayneko` .RE . . diff --git a/wayneko.c b/wayneko.c index 72da222..e9c28b7 100644 --- a/wayneko.c +++ b/wayneko.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #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]);