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

3
README
View file

@ -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 longer happen that Neko wakes up just to go to sleep immediately again and
makes Neko being awake something you can look forward to. 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 Refer to the man page or `--help` command to see how to use this fork and which
options are new or no longer available. options are new or no longer available.

View file

@ -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 .SH NAME
.P .P
@ -21,6 +21,7 @@ wayneko \- Neko on Wayland but with phases
.OP \-\-awake-phase seconds-seconds .OP \-\-awake-phase seconds-seconds
.OP \-\-currently awake|asleep|random .OP \-\-currently awake|asleep|random
.OP \-\-layer background|bottom|top|overlay .OP \-\-layer background|bottom|top|overlay
.OP \-\-output name
.OP \-\-survive\-close .OP \-\-survive\-close
.YS .YS
. .
@ -102,6 +103,14 @@ Background may conflict with wallpaper clients.
.RE .RE
. .
.P .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 \fB\-\-survive\-close\fR
.RS .RS
If this flag is used, wayneko will recreate the surface after it has been closed. 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 \fBSIGUSR1\fR
.RS .RS
You can send `wayneko` this signal to wake Neko up spontaneously. Neko won't notice 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 .RE
. .
. .

View file

@ -12,6 +12,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <wayland-client-protocol.h>
#include <wayland-client.h> #include <wayland-client.h>
#ifdef __linux__ #ifdef __linux__
@ -37,6 +38,7 @@ const char usage[] =
" --awake-phase seconds-seconds\n" " --awake-phase seconds-seconds\n"
" --currently awake|asleep|random\n" " --currently awake|asleep|random\n"
" --layer background|bottom|top|overlay\n" " --layer background|bottom|top|overlay\n"
" --output name\n"
" --survive-close\n" " --survive-close\n"
"\n"; "\n";
@ -101,6 +103,12 @@ uint32_t phase_awake_max = 600;
bool wakeup_shock = false; /* will force a shock, used when woken up */ 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 Seat
{ {
struct wl_list link; struct wl_list link;
@ -1204,7 +1212,7 @@ static void surface_create (void)
surface.layer_surface = zwlr_layer_shell_v1_get_layer_surface( surface.layer_surface = zwlr_layer_shell_v1_get_layer_surface(
layer_shell, layer_shell,
surface.wl_surface, surface.wl_surface,
NULL, output,
layer, layer,
"wayneko" "wayneko"
); );
@ -1233,11 +1241,33 @@ static void surface_create (void)
wl_surface_commit(surface.wl_surface); 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 * * 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, static void registry_handle_global (void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version) 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); wl_shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
else if ( strcmp(interface, ext_idle_notifier_v1_interface.name) == 0 ) else if ( strcmp(interface, ext_idle_notifier_v1_interface.name) == 0 )
idle_notifier = wl_registry_bind(registry, name, &ext_idle_notifier_v1_interface, 1); 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); struct wl_seat *wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 7);
seat_new(wl_seat, name); 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 = { static const struct wl_callback_listener sync_callback_listener = {
@ -1531,6 +1565,14 @@ int main (int argc, char *argv[])
if (current_phase == PHASE_AWAKE) if (current_phase == PHASE_AWAKE)
current_neko = NEKO_SLEEP_1; 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 else
{ {
fprintf(stderr, "ERROR: Unknown option: %s\n", argv[i]); fprintf(stderr, "ERROR: Unknown option: %s\n", argv[i]);